From d3d4e5ce60e4e4fed4dfb16c55286f47e1222abf Mon Sep 17 00:00:00 2001 From: Gaber Stare Date: Wed, 14 Sep 2022 11:33:20 +0000 Subject: [PATCH] [AMF] Add amfInfoList to NFProfile The actual configured GUAMIs and TAIs are used to form NF profile. Comparing to SMF the "info" section is not introduced into amf.yaml! Each amf_id (region, set) produces a separate Info in the InfoList. Guami list consists of all GUAMIs of particular Info. taiList consists of all TAIs for all PLMNs of particular Info. Examle: amf.yaml: guami: - plmn_id: mcc: 999 mnc: 70 amf_id: region: 2 set: 2 pointer: 4 - plmn_id: mcc: 001 mnc: 01 amf_id: region: 2 set: 1 - plmn_id: mcc: 001 mnc: 02 amf_id: region: 2 set: 2 tai: - plmn_id: mcc: 001 mnc: 01 tac: [1, 2, 3] tai: - plmn_id: mcc: 002 mnc: 02 tac: 4 - plmn_id: mcc: 001 mnc: 02 tac: 10 tai: - plmn_id: mcc: 004 mnc: 04 tac: [6, 7] - plmn_id: mcc: 005 mnc: 05 tac: 8 - plmn_id: mcc: 999 mnc: 70 tac: [9, 10] "amfInfoList": { "1": { "amfSetId": "002", "amfRegionId": "02", "guamiList": [{ "plmnId": { "mcc": "999", "mnc": "70" }, "amfId": "020084" }, { "plmnId": { "mcc": "001", "mnc": "02" }, "amfId": "020080" }], "taiList": [{ "plmnId": { "mcc": "001", "mnc": "02" }, "tac": "00000a" }, { "plmnId": { "mcc": "999", "mnc": "70" }, "tac": "000009" }, { "plmnId": { "mcc": "999", "mnc": "70" }, "tac": "00000a" }] }, "2": { "amfSetId": "001", "amfRegionId": "02", "guamiList": [{ "plmnId": { "mcc": "001", "mnc": "01" }, "amfId": "020040" }], "taiList": [{ "plmnId": { "mcc": "001", "mnc": "01" }, "tac": "000001" }, { "plmnId": { "mcc": "001", "mnc": "01" }, "tac": "000002" }, { "plmnId": { "mcc": "001", "mnc": "01" }, "tac": "000003" }] } } --- lib/proto/types.h | 1 + lib/sbi/context.h | 25 ++++ lib/sbi/nnrf-build.c | 280 +++++++++++++++++++++++++++++++++++++++---- src/amf/context.c | 85 +++++++++++++ src/amf/context.h | 2 - 5 files changed, 367 insertions(+), 26 deletions(-) diff --git a/lib/proto/types.h b/lib/proto/types.h index 225b504c2..78fb5485c 100644 --- a/lib/proto/types.h +++ b/lib/proto/types.h @@ -81,6 +81,7 @@ extern "C" { #define OGS_MAX_PCO_LEN 251 #define OGS_MAX_FQDN_LEN 256 +#define MAX_NUM_OF_SERVED_GUAMI 8 #define OGS_MAX_NUM_OF_SERVED_TAI 16 #define OGS_MAX_NUM_OF_ALGORITHM 8 diff --git a/lib/sbi/context.h b/lib/sbi/context.h index d56a0672b..c8356a985 100644 --- a/lib/sbi/context.h +++ b/lib/sbi/context.h @@ -255,12 +255,37 @@ typedef struct ogs_sbi_smf_info_s { } nr_tai_range[OGS_MAX_NUM_OF_TAI]; } ogs_sbi_smf_info_t; +typedef struct ogs_sbi_amf_info_s { + int amf_set_id; + int amf_region_id; + + int num_of_guami; + ogs_guami_t guami[MAX_NUM_OF_SERVED_GUAMI]; + + int num_of_nr_tai; + ogs_5gs_tai_t nr_tai[OGS_MAX_NUM_OF_TAI]; + + int num_of_nr_tai_range; + struct { + ogs_plmn_id_t plmn_id; + /* + * TS29.510 6.1.6.2.28 Type: TacRange + * + * Either the start and end attributes, or + * the pattern attribute, shall be present. + */ + int num_of_tac_range; + ogs_uint24_t start[OGS_MAX_NUM_OF_TAI], end[OGS_MAX_NUM_OF_TAI]; + } nr_tai_range[OGS_MAX_NUM_OF_TAI]; +} ogs_sbi_amf_info_t; + typedef struct ogs_sbi_nf_info_s { ogs_lnode_t lnode; OpenAPI_nf_type_e nf_type; union { ogs_sbi_smf_info_t smf; + ogs_sbi_amf_info_t amf; }; } ogs_sbi_nf_info_t; diff --git a/lib/sbi/nnrf-build.c b/lib/sbi/nnrf-build.c index 5a69eb66e..4b16925f0 100644 --- a/lib/sbi/nnrf-build.c +++ b/lib/sbi/nnrf-build.c @@ -23,7 +23,9 @@ static OpenAPI_nf_service_t *build_nf_service( ogs_sbi_nf_service_t *nf_service); static void free_nf_service(OpenAPI_nf_service_t *NFService); static OpenAPI_smf_info_t *build_smf_info(ogs_sbi_nf_info_t *nf_info); +static OpenAPI_amf_info_t *build_amf_info(ogs_sbi_nf_info_t *nf_info); static void free_smf_info(OpenAPI_smf_info_t *SmfInfo); +static void free_amf_info(OpenAPI_amf_info_t *AmfInfo); ogs_sbi_request_t *ogs_nnrf_nfm_build_register(void) { @@ -79,13 +81,15 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile( OpenAPI_list_t *AllowedNfTypeList = NULL; OpenAPI_list_t *NFServiceList = NULL; OpenAPI_map_t *NFServiceMap = NULL; - OpenAPI_list_t *SmfInfoList = NULL; - OpenAPI_map_t *SmfInfoMap = NULL; + OpenAPI_list_t *InfoList = NULL; + OpenAPI_map_t *InfoMap = NULL; OpenAPI_smf_info_t *SmfInfo = NULL; - int SmfInfoMapKey; + int InfoMapKey; OpenAPI_lnode_t *node = NULL; + OpenAPI_amf_info_t *AmfInfo = NULL; + int i = 0; char *ipstr = NULL; @@ -222,10 +226,10 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile( } else OpenAPI_list_free(NFServiceList); - SmfInfoList = OpenAPI_list_create(); - ogs_assert(SmfInfoList); + InfoList = OpenAPI_list_create(); + ogs_assert(InfoList); - SmfInfoMapKey = 0; + InfoMapKey = 0; ogs_list_for_each(&nf_instance->nf_info_list, nf_info) { if (nf_info->nf_type == OpenAPI_nf_type_SMF) { @@ -238,11 +242,21 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile( SmfInfo = build_smf_info(nf_info); ogs_expect_or_return_val(SmfInfo, NULL); - SmfInfoMap = OpenAPI_map_create( - ogs_msprintf("%d", ++SmfInfoMapKey), SmfInfo); - ogs_assert(SmfInfoMap); + InfoMap = OpenAPI_map_create( + ogs_msprintf("%d", ++InfoMapKey), SmfInfo); + ogs_assert(InfoMap); - OpenAPI_list_add(SmfInfoList, SmfInfoMap); + OpenAPI_list_add(InfoList, InfoMap); + + } else if (nf_info->nf_type == OpenAPI_nf_type_AMF) { + AmfInfo = build_amf_info(nf_info); + ogs_expect_or_return_val(AmfInfo, NULL); + + InfoMap = OpenAPI_map_create( + ogs_msprintf("%d", ++InfoMapKey), AmfInfo); + ogs_assert(InfoMap); + + OpenAPI_list_add(InfoList, InfoMap); } else { ogs_fatal("Not implemented NF-type[%s]", @@ -250,23 +264,37 @@ OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile( ogs_assert_if_reached(); } } - - if (SmfInfoList->count == 1) { - NFProfile->smf_info = SmfInfo; - - OpenAPI_list_for_each(SmfInfoList, node) { - SmfInfoMap = node->data; - if (SmfInfoMap) { - if (SmfInfoMap->key) - ogs_free(SmfInfoMap->key); - ogs_free(SmfInfoMap); + if (InfoList->count == 1) { + if (nf_instance->nf_type == OpenAPI_nf_type_SMF) { + NFProfile->smf_info = SmfInfo; + } else if (nf_instance->nf_type == OpenAPI_nf_type_AMF) { + NFProfile->amf_info = AmfInfo; + } else { + ogs_fatal("Not implemented NF-type[%s]", + OpenAPI_nf_type_ToString(nf_instance->nf_type)); + ogs_assert_if_reached(); + } + OpenAPI_list_for_each(InfoList, node) { + InfoMap = node->data; + if (InfoMap) { + if (InfoMap->key) + ogs_free(InfoMap->key); + ogs_free(InfoMap); } } - OpenAPI_list_free(SmfInfoList); - } else if (SmfInfoList->count > 1) { - NFProfile->smf_info_list = SmfInfoList; + OpenAPI_list_free(InfoList); + } else if (InfoList->count > 1) { + if (nf_instance->nf_type == OpenAPI_nf_type_SMF) { + NFProfile->smf_info_list = InfoList; + } else if (nf_instance->nf_type == OpenAPI_nf_type_AMF) { + NFProfile->amf_info_list = InfoList; + } else { + ogs_fatal("Not implemented NF-type[%s]", + OpenAPI_nf_type_ToString(nf_instance->nf_type)); + ogs_assert_if_reached(); + } } else - OpenAPI_list_free(SmfInfoList); + OpenAPI_list_free(InfoList); return NFProfile; } @@ -277,6 +305,8 @@ void ogs_nnrf_nfm_free_nf_profile(OpenAPI_nf_profile_t *NFProfile) OpenAPI_nf_service_t *NFService = NULL; OpenAPI_map_t *SmfInfoMap = NULL; OpenAPI_smf_info_t *SmfInfo = NULL; + OpenAPI_map_t *AmfInfoMap = NULL; + OpenAPI_amf_info_t *AmfInfo = NULL; OpenAPI_lnode_t *node = NULL; ogs_assert(NFProfile); @@ -327,6 +357,22 @@ void ogs_nnrf_nfm_free_nf_profile(OpenAPI_nf_profile_t *NFProfile) if (NFProfile->smf_info) free_smf_info(NFProfile->smf_info); + OpenAPI_list_for_each(NFProfile->amf_info_list, node) { + AmfInfoMap = node->data; + if (AmfInfoMap) { + AmfInfo = AmfInfoMap->value; + if (AmfInfo) + free_amf_info(AmfInfo); + if (AmfInfoMap->key) + ogs_free(AmfInfoMap->key); + ogs_free(AmfInfoMap); + } + } + OpenAPI_list_free(NFProfile->amf_info_list); + + if (NFProfile->amf_info) + free_amf_info(NFProfile->amf_info); + ogs_free(NFProfile); } @@ -622,6 +668,124 @@ static OpenAPI_smf_info_t *build_smf_info(ogs_sbi_nf_info_t *nf_info) return SmfInfo; } +static OpenAPI_amf_info_t *build_amf_info(ogs_sbi_nf_info_t *nf_info) +{ + int i, j; + OpenAPI_amf_info_t *AmfInfo = NULL; + + OpenAPI_list_t *guamiAmfInfoList = NULL; + OpenAPI_guami_t *guamiAmfInfoItem = NULL; + + OpenAPI_list_t *TaiList = NULL; + OpenAPI_tai_t *TaiItem = NULL; + OpenAPI_list_t *TaiRangeList = NULL; + OpenAPI_tai_range_t *TaiRangeItem = NULL; + OpenAPI_list_t *TacRangeList = NULL; + OpenAPI_tac_range_t *TacRangeItem = NULL; + + ogs_assert(nf_info); + + AmfInfo = ogs_calloc(1, sizeof(*AmfInfo)); + ogs_expect_or_return_val(AmfInfo, NULL); + + AmfInfo->amf_set_id = ogs_msprintf("%03x", nf_info->amf.amf_set_id); + AmfInfo->amf_region_id = ogs_msprintf("%02x", nf_info->amf.amf_region_id); + + guamiAmfInfoList = OpenAPI_list_create(); + ogs_assert(guamiAmfInfoList); + + for (i = 0; i < nf_info->amf.num_of_guami; i++) { + + guamiAmfInfoItem = ogs_calloc(1, sizeof(*guamiAmfInfoItem)); + ogs_expect_or_return_val(guamiAmfInfoItem, NULL); + + guamiAmfInfoItem->plmn_id = + ogs_sbi_build_plmn_id_nid(&nf_info->amf.guami[i].plmn_id); + ogs_expect_or_return_val(guamiAmfInfoItem->plmn_id, NULL); + guamiAmfInfoItem->amf_id = + ogs_amf_id_to_string(&nf_info->amf.guami[i].amf_id); + ogs_expect_or_return_val(guamiAmfInfoItem->amf_id, NULL); + + OpenAPI_list_add(guamiAmfInfoList, guamiAmfInfoItem); + } + + if (guamiAmfInfoList->count) + AmfInfo->guami_list = guamiAmfInfoList; + else + OpenAPI_list_free(guamiAmfInfoList); + + TaiList = OpenAPI_list_create(); + ogs_assert(TaiList); + + for (i = 0; i < nf_info->amf.num_of_nr_tai; i++) { + TaiItem = ogs_calloc(1, sizeof(*TaiItem)); + ogs_expect_or_return_val(TaiItem, NULL); + TaiItem->plmn_id = ogs_sbi_build_plmn_id( + &nf_info->amf.nr_tai[i].plmn_id); + ogs_expect_or_return_val(TaiItem->plmn_id, NULL); + TaiItem->tac = + ogs_uint24_to_0string(nf_info->amf.nr_tai[i].tac); + ogs_expect_or_return_val(TaiItem->tac, NULL); + + OpenAPI_list_add(TaiList, TaiItem); + } + + if (TaiList->count) + AmfInfo->tai_list = TaiList; + else + OpenAPI_list_free(TaiList); + + TaiRangeList = OpenAPI_list_create(); + ogs_assert(TaiRangeList); + + for (i = 0; i < nf_info->amf.num_of_nr_tai_range; i++) { + TacRangeList = OpenAPI_list_create(); + ogs_assert(TacRangeList); + + for (j = 0; + j < nf_info->amf.nr_tai_range[i].num_of_tac_range; + j++) { + TacRangeItem = ogs_calloc(1, sizeof(*TacRangeItem)); + ogs_expect_or_return_val(TacRangeItem, NULL); + + TacRangeItem->start = ogs_uint24_to_0string( + nf_info->amf.nr_tai_range[i].start[j]); + ogs_expect_or_return_val(TacRangeItem->start, NULL); + TacRangeItem->end = + ogs_uint24_to_0string( + nf_info->amf.nr_tai_range[i].end[j]); + ogs_expect_or_return_val(TacRangeItem->end, NULL); + + OpenAPI_list_add(TacRangeList, TacRangeItem); + } + + if (!TacRangeList->count) { + OpenAPI_list_free(TacRangeList); + + ogs_error("CHECK CONFIGURATION: No Start/End in TacRange"); + ogs_expect_or_return_val(0, NULL); + } + + TaiRangeItem = ogs_calloc(1, sizeof(*TaiRangeItem)); + ogs_expect_or_return_val(TaiRangeItem, NULL); + + TaiRangeItem->plmn_id = ogs_sbi_build_plmn_id( + &nf_info->amf.nr_tai_range[i].plmn_id); + ogs_expect_or_return_val(TaiRangeItem->plmn_id, NULL); + + TaiRangeItem->tac_range_list = TacRangeList; + + OpenAPI_list_add(TaiRangeList, TaiRangeItem); + } + + if (TaiRangeList->count) + AmfInfo->tai_range_list = TaiRangeList; + else + OpenAPI_list_free(TaiRangeList); + + return AmfInfo; +} + static void free_smf_info(OpenAPI_smf_info_t *SmfInfo) { OpenAPI_list_t *sNssaiSmfInfoList = NULL; @@ -705,6 +869,74 @@ static void free_smf_info(OpenAPI_smf_info_t *SmfInfo) ogs_free(SmfInfo); } +static void free_amf_info(OpenAPI_amf_info_t *AmfInfo) +{ + OpenAPI_list_t *guamiAmfInfoList = NULL; + OpenAPI_guami_t *guamiAmfInfoItem = NULL; + + OpenAPI_list_t *TaiList = NULL; + OpenAPI_tai_t *TaiItem = NULL; + OpenAPI_list_t *TaiRangeList = NULL; + OpenAPI_tai_range_t *TaiRangeItem = NULL; + OpenAPI_list_t *TacRangeList = NULL; + OpenAPI_tac_range_t *TacRangeItem = NULL; + + OpenAPI_lnode_t *node = NULL, *node2 = NULL; + + ogs_assert(AmfInfo); + + ogs_free(AmfInfo->amf_set_id); + ogs_free(AmfInfo->amf_region_id); + + guamiAmfInfoList = AmfInfo->guami_list; + OpenAPI_list_for_each(guamiAmfInfoList, node) { + guamiAmfInfoItem = node->data; + ogs_assert(guamiAmfInfoItem); + ogs_free(guamiAmfInfoItem); + } + + OpenAPI_list_free(guamiAmfInfoList); + + TaiList = AmfInfo->tai_list; + OpenAPI_list_for_each(TaiList, node) { + TaiItem = node->data; + ogs_assert(TaiItem); + if (TaiItem->plmn_id) + ogs_sbi_free_plmn_id(TaiItem->plmn_id); + if (TaiItem->tac) + ogs_free(TaiItem->tac); + ogs_free(TaiItem); + } + OpenAPI_list_free(TaiList); + + TaiRangeList = AmfInfo->tai_range_list; + OpenAPI_list_for_each(TaiRangeList, node) { + TaiRangeItem = node->data; + ogs_assert(TaiRangeItem); + + if (TaiRangeItem->plmn_id) + ogs_sbi_free_plmn_id(TaiRangeItem->plmn_id); + + TacRangeList = TaiRangeItem->tac_range_list; + OpenAPI_list_for_each(TacRangeList, node2) { + TacRangeItem = node2->data; + ogs_assert(TacRangeItem); + if (TacRangeItem->start) + ogs_free(TacRangeItem->start); + if (TacRangeItem->end) + ogs_free(TacRangeItem->end); + + ogs_free(TacRangeItem); + } + OpenAPI_list_free(TacRangeList); + + ogs_free(TaiRangeItem); + } + OpenAPI_list_free(TaiRangeList); + + ogs_free(AmfInfo); +} + ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void) { ogs_sbi_nf_instance_t *nf_instance = NULL; diff --git a/src/amf/context.c b/src/amf/context.c index e0ccf7b6c..28784b703 100644 --- a/src/amf/context.c +++ b/src/amf/context.c @@ -180,6 +180,8 @@ int amf_context_parse_config(void) int rv; yaml_document_t *document = NULL; ogs_yaml_iter_t root_iter; + ogs_sbi_nf_instance_t *nf_instance = NULL; + ogs_sbi_nf_info_t *nf_info = NULL; document = ogs_app()->document; ogs_assert(document); @@ -831,6 +833,89 @@ int amf_context_parse_config(void) } } + int served_i, next_new_i, info_i; + bool next_found; + served_i = 0; + next_new_i = 0; + next_found = false; + do { + nf_instance = ogs_sbi_self()->nf_instance; + ogs_assert(nf_instance); + + nf_info = ogs_sbi_nf_info_add( + &nf_instance->nf_info_list, OpenAPI_nf_type_AMF); + ogs_assert(nf_info); + nf_info->amf.amf_set_id = self.served_guami[next_new_i].amf_id.set2; + nf_info->amf.amf_region_id = self.served_guami[next_new_i].amf_id.region; + next_found = false; + info_i = 0; + for (served_i = next_new_i; served_i < + self.num_of_served_guami; served_i++) { + if (self.served_guami[served_i].amf_id.set2 == + nf_info->amf.amf_set_id && + self.served_guami[served_i].amf_id.region == + nf_info->amf.amf_region_id) { + nf_info->amf.guami[info_i] = self.served_guami[served_i]; + nf_info->amf.num_of_guami++; + info_i++; + } else { + if (!next_found) { + int handled_i; + for (handled_i = 0; handled_i < served_i; handled_i++) { + if (self.served_guami[handled_i].amf_id.set2 == + self.served_guami[served_i].amf_id.set2 && + self.served_guami[handled_i].amf_id.region == + self.served_guami[served_i].amf_id.region) { + break; + } + next_found = true; + next_new_i = served_i; + } + } + } + } + + nf_info->amf.num_of_nr_tai = 0; + int i = 0, j = 0, info_tai_i = 0; + for (i = 0; i < self.num_of_served_tai; i++) { + if (self.served_tai[i].list2.num) { + for (j = 0; j < self.served_tai[i].list2.num; j++) { + for (served_i = 0; served_i < info_i; served_i++) { + if (ogs_plmn_id_hexdump + (&self.served_tai[i].list2.tai[j].plmn_id) == + ogs_plmn_id_hexdump + (&nf_info->amf.guami[served_i].plmn_id)) { + nf_info->amf.nr_tai[info_tai_i].plmn_id = + self.served_tai[i].list2.tai[j].plmn_id; + nf_info->amf.nr_tai[info_tai_i].tac = + self.served_tai[i].list2.tai[j].tac; + nf_info->amf.num_of_nr_tai++; + info_tai_i++; + } + } + } + } + for (j = 0; self.served_tai[i].list0.tai[j].num; j++) { + int k = 0; + for (k = 0; k < self.served_tai[i].list0.tai[j].num; k++) { + for (served_i = 0; served_i < info_i; served_i++) { + if (ogs_plmn_id_hexdump + (&self.served_tai[i].list0.tai[j].plmn_id) == + ogs_plmn_id_hexdump + (&nf_info->amf.guami[served_i].plmn_id)) { + nf_info->amf.nr_tai[info_tai_i].plmn_id = + self.served_tai[i].list0.tai[j].plmn_id; + nf_info->amf.nr_tai[info_tai_i].tac = + self.served_tai[i].list0.tai[j].tac[k]; + nf_info->amf.num_of_nr_tai++; + info_tai_i++; + } + } + } + } + } + } while (next_found); + rv = amf_context_validation(); if (rv != OGS_OK) return rv; diff --git a/src/amf/context.h b/src/amf/context.h index 63e12980c..fda22657a 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -34,8 +34,6 @@ extern "C" { #endif -#define MAX_NUM_OF_SERVED_GUAMI 8 - extern int __amf_log_domain; extern int __gmm_log_domain;