open5gs/src/smf/nnrf-build.c

294 lines
10 KiB
C

/*
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#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;
}