diff --git a/configs/open5gs/pcf.yaml.in b/configs/open5gs/pcf.yaml.in index 5f9fedc54..c79038485 100644 --- a/configs/open5gs/pcf.yaml.in +++ b/configs/open5gs/pcf.yaml.in @@ -200,10 +200,20 @@ tls: # o Don't use SCP server => App fails if no NRF available. # delegated: no # +# +# +# o Metrics Server(http://:9090) +# metrics: +# - addr: 0.0.0.0 +# port: 9090 +# pcf: sbi: - addr: 127.0.0.13 port: 7777 + metrics: + - addr: 127.0.0.13 + port: 9090 # # scp: diff --git a/configs/sample.yaml.in b/configs/sample.yaml.in index fd5920e17..5eb6304fc 100644 --- a/configs/sample.yaml.in +++ b/configs/sample.yaml.in @@ -263,6 +263,9 @@ pcf: sbi: - addr: 127.0.0.13 port: 7777 + metrics: + - addr: 127.0.0.13 + port: 9090 nssf: sbi: diff --git a/configs/slice.yaml.in b/configs/slice.yaml.in index 75c606834..267dfcc91 100644 --- a/configs/slice.yaml.in +++ b/configs/slice.yaml.in @@ -228,6 +228,9 @@ pcf: sbi: - addr: 127.0.0.13 port: 7777 + metrics: + - addr: 127.0.0.13 + port: 9090 nssf: sbi: diff --git a/configs/srslte.yaml.in b/configs/srslte.yaml.in index 3c4aa1f2e..d5765d615 100644 --- a/configs/srslte.yaml.in +++ b/configs/srslte.yaml.in @@ -224,6 +224,9 @@ pcf: sbi: - addr: 127.0.0.13 port: 7777 + metrics: + - addr: 127.0.0.13 + port: 9090 nssf: sbi: diff --git a/configs/volte.yaml.in b/configs/volte.yaml.in index 600d2234a..1adcf0b5a 100644 --- a/configs/volte.yaml.in +++ b/configs/volte.yaml.in @@ -231,6 +231,9 @@ pcf: sbi: - addr: 127.0.0.13 port: 7777 + metrics: + - addr: 127.0.0.13 + port: 9090 nssf: sbi: diff --git a/configs/vonr.yaml.in b/configs/vonr.yaml.in index 60e488868..19ab3d9e4 100644 --- a/configs/vonr.yaml.in +++ b/configs/vonr.yaml.in @@ -234,6 +234,9 @@ pcf: sbi: - addr: 127.0.0.13 port: 7777 + metrics: + - addr: 127.0.0.13 + port: 9090 nssf: sbi: diff --git a/lib/sbi/conv.c b/lib/sbi/conv.c index 7f231a72d..db1fa4939 100644 --- a/lib/sbi/conv.c +++ b/lib/sbi/conv.c @@ -939,3 +939,17 @@ void ogs_sbi_free_qos_data(OpenAPI_qos_data_t *QosData) ogs_free(QosData); } + +char *ogs_sbi_s_nssai_to_string_plain(ogs_s_nssai_t *s_nssai) +{ + ogs_assert(s_nssai); + if (s_nssai->sd.v != + OGS_S_NSSAI_NO_SD_VALUE) { + return ogs_msprintf("%d%06x", + s_nssai->sst, + s_nssai->sd.v); + } else { + return ogs_msprintf("%d", + s_nssai->sst); + } +} diff --git a/lib/sbi/conv.h b/lib/sbi/conv.h index d53a127d2..d1ba5f80a 100644 --- a/lib/sbi/conv.h +++ b/lib/sbi/conv.h @@ -88,6 +88,7 @@ OpenAPI_pcc_rule_t *ogs_sbi_build_pcc_rule( void ogs_sbi_free_pcc_rule(OpenAPI_pcc_rule_t *PccRule); OpenAPI_qos_data_t *ogs_sbi_build_qos_data(ogs_pcc_rule_t *pcc_rule); void ogs_sbi_free_qos_data(OpenAPI_qos_data_t *QosData); +char *ogs_sbi_s_nssai_to_string_plain(ogs_s_nssai_t *s_nssai); #ifdef __cplusplus } diff --git a/src/pcf/context.c b/src/pcf/context.c index de9a3fbf1..c65a80e12 100644 --- a/src/pcf/context.c +++ b/src/pcf/context.c @@ -121,6 +121,8 @@ int pcf_context_parse_config(void) /* handle config in sbi library */ } else if (!strcmp(pcf_key, "discovery")) { /* handle config in sbi library */ + } else if (!strcmp(pcf_key, "metrics")) { + /* handle config in metrics library */ } else ogs_warn("unknown key `%s`", pcf_key); } @@ -318,6 +320,11 @@ void pcf_sess_remove(pcf_sess_t *sess) OpenAPI_subscribed_default_qos_free(sess->subscribed_default_qos); ogs_pool_free(&pcf_sess_pool, sess); + + if (sess->s_nssai.sst != 0) { + pcf_metrics_inst_by_slice_add(&sess->pcf_ue->guami.plmn_id, + &sess->s_nssai, PCF_METR_GAUGE_PA_SESSIONNBR, -1); + } } void pcf_sess_remove_all(pcf_ue_t *pcf_ue) diff --git a/src/pcf/context.h b/src/pcf/context.h index 50704eece..7ac41e27f 100644 --- a/src/pcf/context.h +++ b/src/pcf/context.h @@ -26,6 +26,7 @@ #include "ogs-dbi.h" #include "pcf-sm.h" +#include "metrics.h" #ifdef __cplusplus extern "C" { diff --git a/src/pcf/init.c b/src/pcf/init.c index e87141754..b6a452681 100644 --- a/src/pcf/init.c +++ b/src/pcf/init.c @@ -18,6 +18,7 @@ */ #include "sbi-path.h" +#include "metrics.h" static ogs_thread_t *thread; static void pcf_main(void *data); @@ -28,15 +29,21 @@ int pcf_initialize() int rv; ogs_sbi_context_init(); - + ogs_metrics_context_init(); pcf_context_init(); rv = ogs_sbi_context_parse_config("pcf", "nrf", "scp"); if (rv != OGS_OK) return rv; + rv = ogs_metrics_context_parse_config("pcf"); + if (rv != OGS_OK) return rv; + rv = pcf_context_parse_config(); if (rv != OGS_OK) return rv; + rv = pcf_metrics_open(); + if (rv != 0) return OGS_ERROR; + rv = ogs_log_config_domain( ogs_app()->logger.domain, ogs_app()->logger.level); if (rv != OGS_OK) return rv; @@ -90,6 +97,8 @@ void pcf_terminate(void) ogs_dbi_final(); pcf_context_final(); + + pcf_metrics_close(); ogs_sbi_context_final(); } diff --git a/src/pcf/meson.build b/src/pcf/meson.build index cd9b1bf0e..43314578d 100644 --- a/src/pcf/meson.build +++ b/src/pcf/meson.build @@ -17,6 +17,7 @@ libpcf_sources = files(''' context.c + metrics.c event.c nnrf-handler.c @@ -44,12 +45,14 @@ libpcf_sources = files(''' libpcf = static_library('pcf', sources : libpcf_sources, dependencies : [libdbi_dep, + libmetrics_dep, libsbi_dep], install : false) libpcf_dep = declare_dependency( link_with : libpcf, dependencies : [libdbi_dep, + libmetrics_dep, libsbi_dep]) pcf_sources = files(''' diff --git a/src/pcf/metrics.c b/src/pcf/metrics.c new file mode 100644 index 000000000..1b0e0d8d1 --- /dev/null +++ b/src/pcf/metrics.c @@ -0,0 +1,320 @@ +#include "ogs-app.h" +#include "context.h" + +#include "metrics.h" + +typedef struct pcf_metrics_spec_def_s { + unsigned int type; + const char *name; + const char *description; + int initial_val; + unsigned int num_labels; + const char **labels; +} pcf_metrics_spec_def_t; + +/* Helper generic functions: */ +static int pcf_metrics_init_inst(ogs_metrics_inst_t **inst, + ogs_metrics_spec_t **specs, unsigned int len, + unsigned int num_labels, const char **labels) +{ + unsigned int i; + for (i = 0; i < len; i++) + inst[i] = ogs_metrics_inst_new(specs[i], num_labels, labels); + return OGS_OK; +} + +static int pcf_metrics_free_inst(ogs_metrics_inst_t **inst, + unsigned int len) +{ + unsigned int i; + for (i = 0; i < len; i++) + ogs_metrics_inst_free(inst[i]); + memset(inst, 0, sizeof(inst[0]) * len); + return OGS_OK; +} + +static int pcf_metrics_init_spec(ogs_metrics_context_t *ctx, + ogs_metrics_spec_t **dst, pcf_metrics_spec_def_t *src, unsigned int len) +{ + unsigned int i; + for (i = 0; i < len; i++) { + dst[i] = ogs_metrics_spec_new(ctx, src[i].type, + src[i].name, src[i].description, + src[i].initial_val, src[i].num_labels, src[i].labels); + } + return OGS_OK; +} + +/* GLOBAL */ +ogs_metrics_spec_t *pcf_metrics_spec_global[_PCF_METR_GLOB_MAX]; +ogs_metrics_inst_t *pcf_metrics_inst_global[_PCF_METR_GLOB_MAX]; +pcf_metrics_spec_def_t pcf_metrics_spec_def_global[_PCF_METR_GLOB_MAX] = { +/* Global Counters: */ +/* Global Gauges: */ +}; +static int pcf_metrics_init_inst_global(void) +{ + return pcf_metrics_init_inst(pcf_metrics_inst_global, + pcf_metrics_spec_global, _PCF_METR_GLOB_MAX, 0, NULL); +} +static int pcf_metrics_free_inst_global(void) +{ + return pcf_metrics_free_inst(pcf_metrics_inst_global, _PCF_METR_GLOB_MAX); +} + +/* BY_PLMN */ +const char *labels_plmn[] = { + "plmnid" +}; +#define PCF_METR_BY_PLMN_CTR_ENTRY(_id, _name, _desc) \ + [_id] = { \ + .type = OGS_METRICS_METRIC_TYPE_COUNTER, \ + .name = _name, \ + .description = _desc, \ + .num_labels = OGS_ARRAY_SIZE(labels_plmn), \ + .labels = labels_plmn, \ + }, +ogs_metrics_spec_t *pcf_metrics_spec_by_plmn[_PCF_METR_BY_PLMN_MAX]; +ogs_hash_t *metrics_hash_by_plmn = NULL; /* hash table for PLMN label */ +pcf_metrics_spec_def_t pcf_metrics_spec_def_by_plmn[_PCF_METR_BY_PLMN_MAX] = { +/* Counters: */ +PCF_METR_BY_PLMN_CTR_ENTRY( + PCF_METR_CTR_PA_POLICYAMASSOREQ, + "fivegs_pcffunction_pa_policyamassoreq", + "Number of AM policy association requests") +PCF_METR_BY_PLMN_CTR_ENTRY( + PCF_METR_CTR_PA_POLICYAMASSOSUCC, + "fivegs_pcffunction_pa_policyamassosucc", + "Number of successful AM policy associations") +}; +void pcf_metrics_init_by_plmn(void); +int pcf_metrics_free_inst_by_plmn(ogs_metrics_inst_t **inst); +typedef struct pcf_metric_key_by_plmn_s { + ogs_plmn_id_t plmn_id; + pcf_metric_type_by_plmn_t t; +} pcf_metric_key_by_plmn_t; + +void pcf_metrics_init_by_plmn(void) +{ + metrics_hash_by_plmn = ogs_hash_make(); + ogs_assert(metrics_hash_by_plmn); +} +void pcf_metrics_inst_by_plmn_add(ogs_plmn_id_t *plmn, + pcf_metric_type_by_plmn_t t, int val) +{ + ogs_metrics_inst_t *metrics = NULL; + pcf_metric_key_by_plmn_t *plmn_key; + + plmn_key = ogs_calloc(1, sizeof(*plmn_key)); + ogs_assert(plmn_key); + + if (plmn) { + plmn_key->plmn_id = *plmn; + } + + plmn_key->t = t; + + metrics = ogs_hash_get(metrics_hash_by_plmn, + plmn_key, sizeof(*plmn_key)); + + if (!metrics) { + char plmn_id[OGS_PLMNIDSTRLEN] = ""; + + if (plmn) { + ogs_plmn_id_to_string(plmn, plmn_id); + } + + metrics = ogs_metrics_inst_new(pcf_metrics_spec_by_plmn[t], + pcf_metrics_spec_def_by_plmn->num_labels, + (const char *[]){ plmn_id }); + + ogs_assert(metrics); + ogs_hash_set(metrics_hash_by_plmn, + plmn_key, sizeof(*plmn_key), metrics); + } else { + ogs_free(plmn_key); + } + + ogs_metrics_inst_add(metrics, val); +} + +int pcf_metrics_free_inst_by_plmn(ogs_metrics_inst_t **inst) +{ + return pcf_metrics_free_inst(inst, _PCF_METR_BY_PLMN_MAX); +} + +/* BY_SLICE */ +const char *labels_slice[] = { + "plmnid", + "snssai" +}; + +#define PCF_METR_BY_SLICE_CTR_ENTRY(_id, _name, _desc) \ + [_id] = { \ + .type = OGS_METRICS_METRIC_TYPE_COUNTER, \ + .name = _name, \ + .description = _desc, \ + .num_labels = OGS_ARRAY_SIZE(labels_slice), \ + .labels = labels_slice, \ + }, +#define PCF_METR_BY_SLICE_GAUGE_ENTRY(_id, _name, _desc) \ + [_id] = { \ + .type = OGS_METRICS_METRIC_TYPE_GAUGE, \ + .name = _name, \ + .description = _desc, \ + .num_labels = OGS_ARRAY_SIZE(labels_slice), \ + .labels = labels_slice, \ + }, +ogs_metrics_spec_t *pcf_metrics_spec_by_slice[_PCF_METR_BY_SLICE_MAX]; +ogs_hash_t *metrics_hash_by_slice = NULL; /* hash table for SLICE labels */ +pcf_metrics_spec_def_t pcf_metrics_spec_def_by_slice[_PCF_METR_BY_SLICE_MAX] = { +/* Counters: */ +PCF_METR_BY_SLICE_CTR_ENTRY( + PCF_METR_CTR_PA_POLICYSMASSOREQ, + "fivegs_pcffunction_pa_policysmassoreq", + "Number of SM policy association requests") +PCF_METR_BY_SLICE_CTR_ENTRY( + PCF_METR_CTR_PA_POLICYSMASSOSUCC, + "fivegs_pcffunction_pa_policysmassosucc", + "Number of successful SM policy associations") +/* Gauges: */ +PCF_METR_BY_SLICE_GAUGE_ENTRY( + PCF_METR_GAUGE_PA_SESSIONNBR, + "fivegs_pcffunction_pa_sessionnbr", + "Active Sessions") +}; +void pcf_metrics_init_by_slice(void); +int pcf_metrics_free_inst_by_slice(ogs_metrics_inst_t **inst); +typedef struct pcf_metric_key_by_slice_s { + ogs_plmn_id_t plmn_id; + ogs_s_nssai_t snssai; + pcf_metric_type_by_slice_t t; +} pcf_metric_key_by_slice_t; + +void pcf_metrics_init_by_slice(void) +{ + metrics_hash_by_slice = ogs_hash_make(); + ogs_assert(metrics_hash_by_slice); +} + +void pcf_metrics_inst_by_slice_add(ogs_plmn_id_t *plmn, + ogs_s_nssai_t *snssai, pcf_metric_type_by_slice_t t, int val) +{ + ogs_metrics_inst_t *metrics = NULL; + pcf_metric_key_by_slice_t *slice_key; + + slice_key = ogs_calloc(1, sizeof(*slice_key)); + ogs_assert(slice_key); + + if (plmn) { + slice_key->plmn_id = *plmn; + } + + if (snssai) { + slice_key->snssai = *snssai; + } else { + slice_key->snssai.sst = 0; + slice_key->snssai.sd.v = OGS_S_NSSAI_NO_SD_VALUE; + } + + slice_key->t = t; + + metrics = ogs_hash_get(metrics_hash_by_slice, + slice_key, sizeof(*slice_key)); + + if (!metrics) { + char plmn_id[OGS_PLMNIDSTRLEN] = ""; + char *s_nssai = NULL; + + if (plmn) { + ogs_plmn_id_to_string(plmn, plmn_id); + } + + if (snssai) { + s_nssai = ogs_sbi_s_nssai_to_string_plain(snssai); + } else { + s_nssai = ogs_strdup(""); + } + + metrics = ogs_metrics_inst_new(pcf_metrics_spec_by_slice[t], + pcf_metrics_spec_def_by_slice->num_labels, + (const char *[]){ plmn_id, s_nssai }); + + ogs_assert(metrics); + ogs_hash_set(metrics_hash_by_slice, + slice_key, sizeof(*slice_key), metrics); + + if (s_nssai) + ogs_free(s_nssai); + } else { + ogs_free(slice_key); + } + + ogs_metrics_inst_add(metrics, val); +} + +int pcf_metrics_free_inst_by_slice(ogs_metrics_inst_t **inst) +{ + return pcf_metrics_free_inst(inst, _PCF_METR_BY_SLICE_MAX); +} + +int pcf_metrics_open(void) +{ + ogs_metrics_context_t *ctx = ogs_metrics_self(); + ogs_metrics_context_open(ctx); + + pcf_metrics_init_spec(ctx, pcf_metrics_spec_global, + pcf_metrics_spec_def_global, _PCF_METR_GLOB_MAX); + pcf_metrics_init_spec(ctx, pcf_metrics_spec_by_plmn, + pcf_metrics_spec_def_by_plmn, _PCF_METR_BY_PLMN_MAX); + pcf_metrics_init_spec(ctx, pcf_metrics_spec_by_slice, + pcf_metrics_spec_def_by_slice, _PCF_METR_BY_SLICE_MAX); + + pcf_metrics_init_inst_global(); + pcf_metrics_init_by_plmn(); + pcf_metrics_init_by_slice(); + + return 0; +} + +int pcf_metrics_close(void) +{ + ogs_hash_index_t *hi; + ogs_metrics_context_t *ctx = ogs_metrics_self(); + + pcf_metrics_free_inst_global(); + + if (metrics_hash_by_slice) { + for (hi = ogs_hash_first(metrics_hash_by_slice); hi; hi = ogs_hash_next(hi)) { + pcf_metric_key_by_slice_t *key = + (pcf_metric_key_by_slice_t *)ogs_hash_this_key(hi); + //void *val = ogs_hash_this_val(hi); + + ogs_hash_set(metrics_hash_by_slice, key, sizeof(*key), NULL); + + ogs_free(key); + /* don't free val (metric itself) - + * it will be free'd by ogs_metrics_context_final() */ + //ogs_free(val); + } + ogs_hash_destroy(metrics_hash_by_slice); + } + if (metrics_hash_by_plmn) { + for (hi = ogs_hash_first(metrics_hash_by_plmn); hi; hi = ogs_hash_next(hi)) { + pcf_metric_key_by_plmn_t *key = + (pcf_metric_key_by_plmn_t *)ogs_hash_this_key(hi); + //void *val = ogs_hash_this_val(hi); + + ogs_hash_set(metrics_hash_by_plmn, key, sizeof(*key), NULL); + + ogs_free(key); + /* don't free val (metric ifself) - + * it will be free'd by ogs_metrics_context_final() */ + //ogs_free(val); + } + ogs_hash_destroy(metrics_hash_by_plmn); + } + + ogs_metrics_context_close(ctx); + return OGS_OK; +} diff --git a/src/pcf/metrics.h b/src/pcf/metrics.h new file mode 100644 index 000000000..e229837af --- /dev/null +++ b/src/pcf/metrics.h @@ -0,0 +1,53 @@ +#ifndef PCF_METRICS_H +#define PCF_METRICS_H + +#include "ogs-metrics.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum pcf_metric_type_global_s { + _PCF_METR_GLOB_MAX, +} pcf_metric_type_global_t; +extern ogs_metrics_inst_t *pcf_metrics_inst_global[_PCF_METR_GLOB_MAX]; + +static inline void pcf_metrics_inst_global_set(pcf_metric_type_global_t t, int val) +{ ogs_metrics_inst_set(pcf_metrics_inst_global[t], val); } +static inline void pcf_metrics_inst_global_add(pcf_metric_type_global_t t, int val) +{ ogs_metrics_inst_add(pcf_metrics_inst_global[t], val); } +static inline void pcf_metrics_inst_global_inc(pcf_metric_type_global_t t) +{ ogs_metrics_inst_inc(pcf_metrics_inst_global[t]); } +static inline void pcf_metrics_inst_global_dec(pcf_metric_type_global_t t) +{ ogs_metrics_inst_dec(pcf_metrics_inst_global[t]); } + +/* BY_PLMN */ +typedef enum pcf_metric_type_by_plmn_s { + PCF_METR_CTR_PA_POLICYAMASSOREQ = 0, + PCF_METR_CTR_PA_POLICYAMASSOSUCC, + _PCF_METR_BY_PLMN_MAX, +} pcf_metric_type_by_plmn_t; + +void pcf_metrics_inst_by_plmn_add( + ogs_plmn_id_t *plmn, pcf_metric_type_by_plmn_t t, int val); + +/* BY_SLICE */ +typedef enum pcf_metric_type_by_slice_s { + PCF_METR_CTR_PA_POLICYSMASSOREQ = 0, + PCF_METR_CTR_PA_POLICYSMASSOSUCC, + PCF_METR_GAUGE_PA_SESSIONNBR, + _PCF_METR_BY_SLICE_MAX, +} pcf_metric_type_by_slice_t; + +void pcf_metrics_inst_by_slice_add( + ogs_plmn_id_t *plmn, ogs_s_nssai_t *snssai, + pcf_metric_type_by_slice_t t, int val); + +int pcf_metrics_open(void); +int pcf_metrics_close(void); + +#ifdef __cplusplus +} +#endif + +#endif /* PCF_METRICS_H */ diff --git a/src/pcf/nbsf-handler.c b/src/pcf/nbsf-handler.c index fc48a5e28..6c200964f 100644 --- a/src/pcf/nbsf-handler.c +++ b/src/pcf/nbsf-handler.c @@ -384,6 +384,9 @@ bool pcf_nbsf_management_handle_register( if (SmPolicyDecision.supp_feat) ogs_free(SmPolicyDecision.supp_feat); + pcf_metrics_inst_by_slice_add(&sess->pcf_ue->guami.plmn_id, + &sess->s_nssai, PCF_METR_CTR_PA_POLICYSMASSOSUCC, 1); + ogs_session_data_free(&session_data); return true; diff --git a/src/pcf/npcf-handler.c b/src/pcf/npcf-handler.c index 6f0bef2f8..7030f29ed 100644 --- a/src/pcf/npcf-handler.c +++ b/src/pcf/npcf-handler.c @@ -35,6 +35,8 @@ bool pcf_npcf_am_policy_contrtol_handle_create(pcf_ue_t *pcf_ue, OpenAPI_uri_scheme_e scheme = OpenAPI_uri_scheme_NULL; ogs_sockaddr_t *addr = NULL; + pcf_metrics_inst_by_plmn_add(NULL, PCF_METR_CTR_PA_POLICYAMASSOREQ, 1); + ogs_assert(pcf_ue); ogs_assert(stream); ogs_assert(message); @@ -138,6 +140,9 @@ bool pcf_npcf_am_policy_contrtol_handle_create(pcf_ue_t *pcf_ue, ogs_sbi_parse_guami(&pcf_ue->guami, PolicyAssociationRequest->guami); } + pcf_metrics_inst_by_plmn_add(&pcf_ue->guami.plmn_id, + PCF_METR_CTR_PA_POLICYAMASSOREQ, 1); + if (PolicyAssociationRequest->rat_type) pcf_ue->rat_type = PolicyAssociationRequest->rat_type; @@ -172,6 +177,8 @@ bool pcf_npcf_smpolicycontrol_handle_create(pcf_sess_t *sess, OpenAPI_uri_scheme_e scheme = OpenAPI_uri_scheme_NULL; ogs_sockaddr_t *addr = NULL; + pcf_metrics_inst_by_slice_add(NULL, NULL, PCF_METR_CTR_PA_POLICYSMASSOREQ, 1); + ogs_assert(sess); pcf_ue = sess->pcf_ue; ogs_assert(stream); @@ -292,6 +299,11 @@ bool pcf_npcf_smpolicycontrol_handle_create(pcf_sess_t *sess, sess->s_nssai.sst = sliceInfo->sst; sess->s_nssai.sd = ogs_s_nssai_sd_from_string(sliceInfo->sd); + pcf_metrics_inst_by_slice_add(&pcf_ue->guami.plmn_id, + &sess->s_nssai, PCF_METR_GAUGE_PA_SESSIONNBR, 1); + pcf_metrics_inst_by_slice_add(&pcf_ue->guami.plmn_id, + &sess->s_nssai, PCF_METR_CTR_PA_POLICYSMASSOREQ, 1); + if (SmPolicyContextData->subs_sess_ambr) sess->subscribed_sess_ambr = OpenAPI_ambr_copy( sess->subscribed_sess_ambr, SmPolicyContextData->subs_sess_ambr); diff --git a/src/pcf/nudr-handler.c b/src/pcf/nudr-handler.c index b510a8ae5..c9c3a21ca 100644 --- a/src/pcf/nudr-handler.c +++ b/src/pcf/nudr-handler.c @@ -147,6 +147,9 @@ bool pcf_nudr_dr_handle_query_am_data( ogs_subscription_data_free(&subscription_data); + pcf_metrics_inst_by_plmn_add(&pcf_ue->guami.plmn_id, + PCF_METR_CTR_PA_POLICYAMASSOSUCC, 1); + return true; DEFAULT