/* * Copyright (C) 2019,2020 by Sukchan Lee * * This file is part of Open5GS. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "nnrf-build.h" ogs_sbi_request_t *smf_nnrf_nfm_build_register( ogs_sbi_nf_instance_t *nf_instance) { int i, j; ogs_sbi_nf_info_t *nf_info = NULL; ogs_sbi_message_t message; ogs_sbi_request_t *request = NULL; ogs_sbi_client_t *client = NULL; OpenAPI_nf_profile_t *NFProfile = NULL; OpenAPI_list_t *SmfInfoList = NULL; OpenAPI_map_t *SmfInfoMap = NULL; OpenAPI_smf_info_t *SmfInfo = NULL; int SmfInfoMapKey; OpenAPI_list_t *sNssaiSmfInfoList = NULL; OpenAPI_snssai_smf_info_item_t *sNssaiSmfInfoItem = NULL; OpenAPI_snssai_t *sNssai = NULL; OpenAPI_list_t *DnnSmfInfoList = NULL; OpenAPI_dnn_smf_info_item_t *DnnSmfInfoItem = 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, *node3 = NULL; ogs_assert(nf_instance); client = nf_instance->client; ogs_assert(client); memset(&message, 0, sizeof(message)); message.h.method = (char *)OGS_SBI_HTTP_METHOD_PUT; message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NNRF_NFM; message.h.api.version = (char *)OGS_SBI_API_V1; message.h.resource.component[0] = (char *)OGS_SBI_RESOURCE_NAME_NF_INSTANCES; message.h.resource.component[1] = ogs_sbi_self()->nf_instance_id; message.http.content_encoding = (char*)ogs_sbi_self()->content_encoding; SmfInfoList = OpenAPI_list_create(); ogs_assert(SmfInfoList); SmfInfoMapKey = 0; ogs_list_for_each(&ogs_sbi_self()->nf_info_list, nf_info) { if (nf_info->nf_type != OpenAPI_nf_type_SMF) { ogs_fatal("Not implemented NF-type[%s]", OpenAPI_nf_type_ToString(nf_info->nf_type)); ogs_assert_if_reached(); } if (nf_info->smf.num_of_slice == 0) { ogs_fatal("CHECK CONFIGURATION: No S-NSSAI"); ogs_assert_if_reached(); } SmfInfo = ogs_calloc(1, sizeof(*SmfInfo)); ogs_expect_or_return_val(SmfInfo, NULL); sNssaiSmfInfoList = OpenAPI_list_create(); ogs_assert(sNssaiSmfInfoList); for (i = 0; i < nf_info->smf.num_of_slice; i++) { DnnSmfInfoList = OpenAPI_list_create(); ogs_assert(DnnSmfInfoList); for (j = 0; j < nf_info->smf.slice[i].num_of_dnn; j++) { DnnSmfInfoItem = ogs_calloc(1, sizeof(*DnnSmfInfoItem)); ogs_expect_or_return_val(DnnSmfInfoItem, NULL); DnnSmfInfoItem->dnn = nf_info->smf.slice[i].dnn[j]; OpenAPI_list_add(DnnSmfInfoList, DnnSmfInfoItem); } if (!DnnSmfInfoList->count) { OpenAPI_list_free(DnnSmfInfoList); ogs_error("CHECK CONFIGURATION: No DNN"); ogs_expect_or_return_val(0, NULL); } sNssaiSmfInfoItem = ogs_calloc(1, sizeof(*sNssaiSmfInfoItem)); ogs_expect_or_return_val(sNssaiSmfInfoItem, NULL); sNssaiSmfInfoItem->dnn_smf_info_list = DnnSmfInfoList; sNssaiSmfInfoItem->s_nssai = sNssai = ogs_calloc(1, sizeof(*sNssai)); ogs_expect_or_return_val(sNssai, NULL); sNssai->sst = nf_info->smf.slice[i].s_nssai.sst; sNssai->sd = ogs_s_nssai_sd_to_string(nf_info->smf.slice[i].s_nssai.sd); OpenAPI_list_add(sNssaiSmfInfoList, sNssaiSmfInfoItem); } if (sNssaiSmfInfoList->count) SmfInfo->s_nssai_smf_info_list = sNssaiSmfInfoList; else OpenAPI_list_free(sNssaiSmfInfoList); TaiList = OpenAPI_list_create(); ogs_assert(TaiList); for (i = 0; i < nf_info->smf.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->smf.nr_tai[i].plmn_id); ogs_expect_or_return_val(TaiItem->plmn_id, NULL); TaiItem->tac = ogs_uint24_to_0string(nf_info->smf.nr_tai[i].tac); ogs_expect_or_return_val(TaiItem->tac, NULL); OpenAPI_list_add(TaiList, TaiItem); } if (TaiList->count) SmfInfo->tai_list = TaiList; else OpenAPI_list_free(TaiList); TaiRangeList = OpenAPI_list_create(); ogs_assert(TaiRangeList); for (i = 0; i < nf_info->smf.num_of_nr_tai_range; i++) { TacRangeList = OpenAPI_list_create(); ogs_assert(TacRangeList); for (j = 0; j < nf_info->smf.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->smf.nr_tai_range[i].start[j]); ogs_expect_or_return_val(TacRangeItem->start, NULL); TacRangeItem->end = ogs_uint24_to_0string(nf_info->smf.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->smf.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) SmfInfo->tai_range_list = TaiRangeList; else OpenAPI_list_free(TaiRangeList); SmfInfoMap = OpenAPI_map_create( ogs_msprintf("%d", ++SmfInfoMapKey), SmfInfo); ogs_assert(SmfInfoMap); OpenAPI_list_add(SmfInfoList, SmfInfoMap); } NFProfile = ogs_nnrf_nfm_build_nf_profile(nf_instance); ogs_expect_or_return_val(NFProfile, NULL); if (SmfInfoList->count == 1) { NFProfile->smf_info = SmfInfo; } else if (SmfInfoList->count > 1) { NFProfile->smf_info_list = SmfInfoList; } message.NFProfile = NFProfile; request = ogs_sbi_build_request(&message); ogs_sbi_nnrf_free_nf_profile(NFProfile); OpenAPI_list_for_each(SmfInfoList, node) { SmfInfoMap = node->data; if (SmfInfoMap) { SmfInfo = SmfInfoMap->value; if (SmfInfo) { sNssaiSmfInfoList = SmfInfo->s_nssai_smf_info_list; OpenAPI_list_for_each(sNssaiSmfInfoList, node2) { sNssaiSmfInfoItem = node2->data; ogs_assert(sNssaiSmfInfoItem); DnnSmfInfoList = sNssaiSmfInfoItem->dnn_smf_info_list; OpenAPI_list_for_each(DnnSmfInfoList, node3) { DnnSmfInfoItem = node3->data; ogs_assert(DnnSmfInfoItem); ogs_free(DnnSmfInfoItem); } OpenAPI_list_free(DnnSmfInfoList); sNssai = sNssaiSmfInfoItem->s_nssai; if (sNssai) { if (sNssai->sd) ogs_free(sNssai->sd); ogs_free(sNssai); } ogs_free(sNssaiSmfInfoItem); } OpenAPI_list_free(sNssaiSmfInfoList); TaiList = SmfInfo->tai_list; OpenAPI_list_for_each(TaiList, node2) { TaiItem = node2->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 = SmfInfo->tai_range_list; OpenAPI_list_for_each(TaiRangeList, node2) { TaiRangeItem = node2->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, node3) { TacRangeItem = node3->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(SmfInfo); } if (SmfInfoMap->key) ogs_free(SmfInfoMap->key); ogs_free(SmfInfoMap); } } OpenAPI_list_free(SmfInfoList); return request; }