Coverage Report

Created: 2026-08-14 06:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/open5gs/lib/sbi/nnrf-build.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
3
 *
4
 * This file is part of Open5GS.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18
 */
19
20
#include "ogs-sbi.h"
21
22
static OpenAPI_nf_service_t *build_nf_service(
23
        ogs_sbi_nf_service_t *nf_service);
24
static void free_nf_service(OpenAPI_nf_service_t *NFService);
25
static OpenAPI_smf_info_t *build_smf_info(ogs_sbi_nf_info_t *nf_info);
26
static OpenAPI_amf_info_t *build_amf_info(ogs_sbi_nf_info_t *nf_info);
27
static OpenAPI_scp_info_t *build_scp_info(ogs_sbi_nf_info_t *nf_info);
28
static OpenAPI_sepp_info_t *build_sepp_info(ogs_sbi_nf_info_t *nf_info);
29
static void free_smf_info(OpenAPI_smf_info_t *SmfInfo);
30
static void free_amf_info(OpenAPI_amf_info_t *AmfInfo);
31
static void free_scp_info(OpenAPI_scp_info_t *ScpInfo);
32
static void free_sepp_info(OpenAPI_sepp_info_t *SeppInfo);
33
34
ogs_sbi_request_t *ogs_nnrf_nfm_build_register(void)
35
0
{
36
0
    ogs_sbi_nf_instance_t *nf_instance = NULL;
37
38
0
    ogs_sbi_message_t message;
39
0
    ogs_sbi_request_t *request = NULL;
40
41
0
    OpenAPI_nf_profile_t *NFProfile = NULL;
42
43
0
    nf_instance = ogs_sbi_self()->nf_instance;
44
0
    ogs_assert(nf_instance);
45
0
    ogs_assert(nf_instance->id);
46
47
0
    memset(&message, 0, sizeof(message));
48
0
    message.h.method = (char *)OGS_SBI_HTTP_METHOD_PUT;
49
0
    message.h.service.name =
50
0
        OpenAPI_service_name_ToString(OpenAPI_service_name_nnrf_nfm);
51
0
    message.h.api.version = (char *)OGS_SBI_API_V1;
52
0
    message.h.resource.component[0] =
53
0
        (char *)OGS_SBI_RESOURCE_NAME_NF_INSTANCES;
54
0
    message.h.resource.component[1] = nf_instance->id;
55
56
0
    message.http.content_encoding = (char*)ogs_sbi_self()->content_encoding;
57
58
0
    NFProfile = ogs_nnrf_nfm_build_nf_profile(
59
0
                    ogs_sbi_self()->nf_instance,
60
0
                    OpenAPI_service_name_NULL, NULL, true);
61
0
    if (!NFProfile) {
62
0
        ogs_error("No NFProfile");
63
0
        goto end;
64
0
    }
65
66
    /*
67
     * TS29510
68
     * 6.1.6.2 Structured data types
69
     * 6.1.6.2.2 Type: NFProfile
70
     * Table 6.1.6.2.2-1: Definition of type NFProfile
71
     *
72
     * NF Profile Changes Support Indicator.
73
     * See Annex B.
74
     *
75
     * This IE may be present in the NFRegister or
76
     * NFUpdate (NF Profile Complete Replacement)
77
     * request and shall be absent in the response.
78
     *
79
     * true: the NF Service Consumer supports receiving
80
     * NF Profile Changes in the response.
81
     *
82
     * false (default): the NF Service Consumer does not
83
     * support receiving NF Profile Changes in the response.
84
     */
85
0
    NFProfile->is_nf_profile_changes_support_ind = true;
86
0
    NFProfile->nf_profile_changes_support_ind = true;
87
88
0
    message.NFProfile = NFProfile;
89
90
0
    request = ogs_sbi_build_request(&message);
91
0
    ogs_expect(request);
92
93
0
end:
94
95
0
    if (NFProfile)
96
0
        ogs_nnrf_nfm_free_nf_profile(NFProfile);
97
98
0
    return request;
99
0
}
100
101
OpenAPI_nf_profile_t *ogs_nnrf_nfm_build_nf_profile(
102
        ogs_sbi_nf_instance_t *nf_instance,
103
        const OpenAPI_service_name_e service_name,
104
        ogs_sbi_discovery_option_t *discovery_option,
105
        bool service_map)
106
0
{
107
0
    ogs_sbi_nf_service_t *nf_service = NULL;
108
0
    ogs_sbi_nf_info_t *nf_info = NULL;
109
110
0
    OpenAPI_nf_profile_t *NFProfile = NULL;
111
0
    OpenAPI_list_t *Ipv4AddrList = NULL;
112
0
    OpenAPI_list_t *Ipv6AddrList = NULL;
113
0
    OpenAPI_list_t *AllowedNfTypeList = NULL;
114
0
    OpenAPI_list_t *NFServiceList = NULL;
115
0
    OpenAPI_map_t *NFServiceMap = NULL;
116
0
    OpenAPI_list_t *InfoList = NULL;
117
0
    OpenAPI_map_t *InfoMap = NULL;
118
0
    int InfoMapKey;
119
120
0
    OpenAPI_lnode_t *node = NULL;
121
122
0
    OpenAPI_smf_info_t *SmfInfo = NULL;
123
0
    OpenAPI_amf_info_t *AmfInfo = NULL;
124
125
0
    int i = 0;
126
0
    char *ipstr = NULL;
127
128
0
    ogs_assert(nf_instance);
129
0
    ogs_assert(nf_instance->id);
130
131
0
    NFProfile = ogs_calloc(1, sizeof(*NFProfile));
132
0
    if (!NFProfile) {
133
0
        ogs_error("No NFProfile");
134
0
        return NULL;
135
0
    }
136
137
0
    NFProfile->nf_instance_id = nf_instance->id;
138
0
    NFProfile->nf_type = nf_instance->nf_type;
139
0
    NFProfile->nf_status = nf_instance->nf_status;
140
141
0
    ogs_trace("[%s] ogs_nnrf_nfm_build_nf_profile()", nf_instance->id);
142
143
0
    ogs_trace("NF-Type[%s] NF-Status[%s] IPv4[%d] IPv6[%d]",
144
0
                OpenAPI_nf_type_ToString(nf_instance->nf_type),
145
0
                OpenAPI_nf_status_ToString(nf_instance->nf_status),
146
0
                nf_instance->num_of_ipv4, nf_instance->num_of_ipv6);
147
148
0
    if (nf_instance->time.heartbeat_interval) {
149
0
        NFProfile->is_heart_beat_timer = true;
150
0
        NFProfile->heart_beat_timer = nf_instance->time.heartbeat_interval;
151
0
    }
152
153
0
    if (nf_instance->num_of_plmn_id) {
154
0
        OpenAPI_list_t *PlmnIdList = NULL;
155
0
        OpenAPI_plmn_id_t *PlmnId = NULL;
156
0
        int i;
157
158
0
        PlmnIdList = OpenAPI_list_create();
159
0
        ogs_assert(PlmnIdList);
160
161
0
        for (i = 0; i < nf_instance->num_of_plmn_id; i++) {
162
0
            PlmnId = ogs_sbi_build_plmn_id(&nf_instance->plmn_id[i]);
163
0
            ogs_assert(PlmnId);
164
0
            OpenAPI_list_add(PlmnIdList, PlmnId);
165
0
        }
166
167
0
        if (PlmnIdList->count)
168
0
            NFProfile->plmn_list = PlmnIdList;
169
0
        else
170
0
            OpenAPI_list_free(PlmnIdList);
171
0
    }
172
173
0
    if (nf_instance->fqdn)
174
0
        NFProfile->fqdn = ogs_strdup(nf_instance->fqdn);
175
176
0
    NFProfile->is_priority = true;
177
0
    NFProfile->priority = nf_instance->priority;
178
0
    NFProfile->is_capacity = true;
179
0
    NFProfile->capacity = nf_instance->capacity;
180
0
    NFProfile->is_load = true;
181
0
    NFProfile->load = nf_instance->load;
182
183
0
    Ipv4AddrList = OpenAPI_list_create();
184
0
    if (!Ipv4AddrList) {
185
0
        ogs_error("No Ipv4AddrList");
186
0
        ogs_nnrf_nfm_free_nf_profile(NFProfile);
187
0
        return NULL;
188
0
    }
189
190
0
    for (i = 0; i < nf_instance->num_of_ipv4; i++) {
191
0
        if (nf_instance->ipv4[i]) {
192
0
            ogs_trace("IPv4 [family:%d, addr:%x, port:%d]",
193
0
                    nf_instance->ipv4[i]->ogs_sa_family,
194
0
                    htobe32(nf_instance->ipv4[i]->sin.sin_addr.s_addr),
195
0
                    nf_instance->ipv4[i]->ogs_sin_port);
196
0
            ogs_assert(nf_instance->ipv4[i]->ogs_sa_family == AF_INET);
197
0
            ipstr = ogs_ipstrdup(nf_instance->ipv4[i]);
198
0
            if (!ipstr) {
199
0
                ogs_error("No ipstr");
200
0
                ogs_nnrf_nfm_free_nf_profile(NFProfile);
201
0
                OpenAPI_list_free(Ipv4AddrList);
202
0
                return NULL;
203
0
            }
204
0
            OpenAPI_list_add(Ipv4AddrList, ipstr);
205
0
        }
206
0
    }
207
208
0
    if (Ipv4AddrList->count)
209
0
        NFProfile->ipv4_addresses = Ipv4AddrList;
210
0
    else
211
0
        OpenAPI_list_free(Ipv4AddrList);
212
213
0
    Ipv6AddrList = OpenAPI_list_create();
214
0
    if (!Ipv6AddrList) {
215
0
        ogs_error("No IPv6AddrList");
216
0
        ogs_nnrf_nfm_free_nf_profile(NFProfile);
217
0
        return NULL;
218
0
    }
219
220
0
    for (i = 0; i < nf_instance->num_of_ipv6; i++) {
221
0
        if (nf_instance->ipv6[i]) {
222
0
            ogs_trace("IPv6 [family:%d, port:%d]",
223
0
                    nf_instance->ipv6[i]->ogs_sa_family,
224
0
                    nf_instance->ipv6[i]->ogs_sin_port);
225
0
            ogs_assert(nf_instance->ipv6[i]->ogs_sa_family == AF_INET6);
226
0
            ipstr = ogs_ipstrdup(nf_instance->ipv6[i]);
227
0
            if (!ipstr) {
228
0
                ogs_error("No ipstr");
229
0
                ogs_nnrf_nfm_free_nf_profile(NFProfile);
230
0
                OpenAPI_list_free(Ipv6AddrList);
231
0
                return NULL;
232
0
            }
233
0
            OpenAPI_list_add(Ipv6AddrList, ipstr);
234
0
        }
235
0
    }
236
237
0
    if (Ipv6AddrList->count)
238
0
        NFProfile->ipv6_addresses = Ipv6AddrList;
239
0
    else
240
0
        OpenAPI_list_free(Ipv6AddrList);
241
242
0
    AllowedNfTypeList = OpenAPI_list_create();
243
0
    if (!AllowedNfTypeList) {
244
0
        ogs_error("No AllowedNfTypeList");
245
0
        ogs_nnrf_nfm_free_nf_profile(NFProfile);
246
0
        return NULL;
247
0
    }
248
249
0
    for (i = 0; i < nf_instance->num_of_allowed_nf_type; i++) {
250
0
        OpenAPI_list_add(AllowedNfTypeList,
251
0
                (void *)(uintptr_t)nf_instance->allowed_nf_type[i]);
252
0
    }
253
254
0
    if (AllowedNfTypeList->count)
255
0
        NFProfile->allowed_nf_types = AllowedNfTypeList;
256
0
    else
257
0
        OpenAPI_list_free(AllowedNfTypeList);
258
259
0
    if (nf_instance->num_of_s_nssai) {
260
0
        OpenAPI_list_t *sNssaiList = OpenAPI_list_create();
261
0
        ogs_assert(sNssaiList);
262
263
0
        for (i = 0; i < nf_instance->num_of_s_nssai; i++) {
264
0
            OpenAPI_ext_snssai_t *sNssai = OpenAPI_ext_snssai_create(
265
0
                    nf_instance->s_nssai[i].sst,
266
0
                    ogs_s_nssai_sd_to_string(nf_instance->s_nssai[i].sd),
267
0
                    NULL, false, 0);
268
0
            ogs_assert(sNssai);
269
0
            OpenAPI_list_add(sNssaiList, sNssai);
270
0
        }
271
272
0
        if (sNssaiList->count)
273
0
            NFProfile->s_nssais = sNssaiList;
274
0
        else
275
0
            OpenAPI_list_free(sNssaiList);
276
0
    }
277
278
0
    if (nf_instance->num_of_allowed_nssai) {
279
0
        OpenAPI_list_t *allowedNssaiList = OpenAPI_list_create();
280
0
        ogs_assert(allowedNssaiList);
281
282
0
        for (i = 0; i < nf_instance->num_of_allowed_nssai; i++) {
283
0
            OpenAPI_ext_snssai_t *sNssai = OpenAPI_ext_snssai_create(
284
0
                    nf_instance->allowed_nssai[i].sst,
285
0
                    ogs_s_nssai_sd_to_string(
286
0
                        nf_instance->allowed_nssai[i].sd),
287
0
                    NULL, false, 0);
288
0
            ogs_assert(sNssai);
289
0
            OpenAPI_list_add(allowedNssaiList, sNssai);
290
0
        }
291
292
0
        if (allowedNssaiList->count)
293
0
            NFProfile->allowed_nssais = allowedNssaiList;
294
0
        else
295
0
            OpenAPI_list_free(allowedNssaiList);
296
0
    }
297
298
0
    NFServiceList = OpenAPI_list_create();
299
0
    if (!NFServiceList) {
300
0
        ogs_error("No nf_service_list");
301
0
        ogs_nnrf_nfm_free_nf_profile(NFProfile);
302
0
        return NULL;
303
0
    }
304
305
0
    ogs_list_for_each(&nf_instance->nf_service_list, nf_service) {
306
0
        OpenAPI_nf_service_t *NFService = NULL;
307
308
0
        if (service_name && nf_service->name &&
309
0
            service_name != nf_service->name)
310
0
            continue;
311
312
0
        if (discovery_option && discovery_option->num_of_service_names) {
313
0
            for (i = 0; i < discovery_option->num_of_service_names; i++) {
314
0
                if (nf_service->name && discovery_option->service_names[i] &&
315
0
                    nf_service->name == discovery_option->service_names[i]) {
316
0
                    break;
317
0
                }
318
0
            }
319
320
0
            if (i == discovery_option->num_of_service_names)
321
0
                continue;
322
0
        }
323
324
0
        NFService = build_nf_service(nf_service);
325
0
        if (!NFService) {
326
0
            ogs_error("No NFService");
327
0
            ogs_nnrf_nfm_free_nf_profile(NFProfile);
328
0
            return NULL;
329
0
        }
330
331
0
        if (service_map == true) {
332
0
            NFServiceMap = OpenAPI_map_create(nf_service->id, NFService);
333
0
            if (!NFServiceMap) {
334
0
                ogs_error("No NFServiceMap");
335
0
                ogs_nnrf_nfm_free_nf_profile(NFProfile);
336
0
                return NULL;
337
0
            }
338
339
0
            OpenAPI_list_add(NFServiceList, NFServiceMap);
340
0
        } else {
341
0
            OpenAPI_list_add(NFServiceList, NFService);
342
0
        }
343
0
    }
344
345
0
    if (NFServiceList->count) {
346
0
        if (service_map == true) {
347
0
            NFProfile->nf_service_list = NFServiceList;
348
0
        } else {
349
0
            NFProfile->nf_services = NFServiceList;
350
0
        }
351
0
    }
352
0
    else
353
0
        OpenAPI_list_free(NFServiceList);
354
355
0
    InfoList = OpenAPI_list_create();
356
0
    ogs_assert(InfoList);
357
358
0
    InfoMapKey = 0;
359
360
0
    ogs_list_for_each(&nf_instance->nf_info_list, nf_info) {
361
0
        if (nf_info->nf_type == OpenAPI_nf_type_SMF) {
362
363
0
            if (nf_info->smf.num_of_slice == 0) {
364
0
                ogs_fatal("CHECK CONFIGURATION: No S-NSSAI");
365
0
                ogs_assert_if_reached();
366
0
            }
367
368
0
            SmfInfo = build_smf_info(nf_info);
369
0
            ogs_assert(SmfInfo);
370
371
0
            InfoMap = OpenAPI_map_create(
372
0
                    ogs_msprintf("%d", ++InfoMapKey), SmfInfo);
373
0
            ogs_assert(InfoMap);
374
375
0
            OpenAPI_list_add(InfoList, InfoMap);
376
377
0
        } else if (nf_info->nf_type == OpenAPI_nf_type_AMF) {
378
0
            AmfInfo = build_amf_info(nf_info);
379
0
            ogs_assert(AmfInfo);
380
381
0
            InfoMap = OpenAPI_map_create(
382
0
                    ogs_msprintf("%d", ++InfoMapKey), AmfInfo);
383
0
            ogs_assert(InfoMap);
384
385
0
            OpenAPI_list_add(InfoList, InfoMap);
386
387
0
        } else if (nf_info->nf_type == OpenAPI_nf_type_SCP) {
388
389
            /* SCP info will be skipped here first and dealt with below. */
390
391
0
        } else if (nf_info->nf_type == OpenAPI_nf_type_SEPP) {
392
393
            /* SEPP info will be skipped here first and dealt with below. */
394
395
0
        } else {
396
0
            ogs_fatal("Not implemented NF-type[%s]",
397
0
                    OpenAPI_nf_type_ToString(nf_info->nf_type));
398
0
            ogs_assert_if_reached();
399
0
        }
400
0
    }
401
0
    if (InfoList->count == 1) {
402
0
        if (nf_instance->nf_type == OpenAPI_nf_type_SMF) {
403
0
            NFProfile->smf_info = SmfInfo;
404
0
        } else if (nf_instance->nf_type == OpenAPI_nf_type_AMF) {
405
0
            NFProfile->amf_info = AmfInfo;
406
0
        } else {
407
0
            ogs_fatal("Not implemented NF-type[%s]",
408
0
                    OpenAPI_nf_type_ToString(nf_instance->nf_type));
409
0
            ogs_assert_if_reached();
410
0
        }
411
0
        OpenAPI_list_for_each(InfoList, node) {
412
0
            InfoMap = node->data;
413
0
            if (InfoMap) {
414
0
                if (InfoMap->key)
415
0
                    ogs_free(InfoMap->key);
416
0
                ogs_free(InfoMap);
417
0
            }
418
0
        }
419
0
        OpenAPI_list_free(InfoList);
420
0
    } else if (InfoList->count > 1) {
421
0
        if (nf_instance->nf_type == OpenAPI_nf_type_SMF) {
422
0
            NFProfile->smf_info_list = InfoList;
423
0
        } else if (nf_instance->nf_type == OpenAPI_nf_type_AMF) {
424
0
            NFProfile->amf_info_list = InfoList;
425
0
        } else {
426
0
            ogs_fatal("Not implemented NF-type[%s]",
427
0
                    OpenAPI_nf_type_ToString(nf_instance->nf_type));
428
0
            ogs_assert_if_reached();
429
0
        }
430
0
    } else
431
0
        OpenAPI_list_free(InfoList);
432
433
    /* There can only be one SCP info, not multiple. */
434
0
    nf_info = ogs_sbi_nf_info_find(
435
0
            &nf_instance->nf_info_list, OpenAPI_nf_type_SCP);
436
0
    if (nf_info) {
437
0
        NFProfile->scp_info = build_scp_info(nf_info);
438
0
        ogs_assert(NFProfile->scp_info);
439
0
    }
440
441
    /* There can only be one SEPP info, not multiple. */
442
0
    nf_info = ogs_sbi_nf_info_find(
443
0
            &nf_instance->nf_info_list, OpenAPI_nf_type_SEPP);
444
0
    if (nf_info) {
445
0
        NFProfile->sepp_info = build_sepp_info(nf_info);
446
0
        ogs_assert(NFProfile->sepp_info);
447
0
    }
448
449
0
    return NFProfile;
450
0
}
451
452
void ogs_nnrf_nfm_free_nf_profile(OpenAPI_nf_profile_t *NFProfile)
453
0
{
454
0
    OpenAPI_map_t *NFServiceMap = NULL;
455
0
    OpenAPI_nf_service_t *NFService = NULL;
456
0
    OpenAPI_map_t *SmfInfoMap = NULL;
457
0
    OpenAPI_smf_info_t *SmfInfo = NULL;
458
0
    OpenAPI_map_t *AmfInfoMap = NULL;
459
0
    OpenAPI_amf_info_t *AmfInfo = NULL;
460
0
    OpenAPI_lnode_t *node = NULL;
461
462
0
    ogs_assert(NFProfile);
463
464
0
    if (NFProfile->fqdn)
465
0
        ogs_free(NFProfile->fqdn);
466
467
0
    OpenAPI_list_for_each(NFProfile->ipv4_addresses, node)
468
0
        ogs_free(node->data);
469
0
    OpenAPI_list_free(NFProfile->ipv4_addresses);
470
0
    OpenAPI_list_for_each(NFProfile->ipv6_addresses, node)
471
0
        ogs_free(node->data);
472
0
    OpenAPI_list_free(NFProfile->ipv6_addresses);
473
474
0
    OpenAPI_list_for_each(NFProfile->plmn_list, node) {
475
0
        OpenAPI_plmn_id_t *PlmnId = node->data;
476
0
        if (PlmnId)
477
0
            ogs_sbi_free_plmn_id(PlmnId);
478
0
    }
479
0
    OpenAPI_list_free(NFProfile->plmn_list);
480
481
0
    OpenAPI_list_free(NFProfile->allowed_nf_types);
482
483
0
    OpenAPI_list_for_each(NFProfile->s_nssais, node)
484
0
        OpenAPI_ext_snssai_free(node->data);
485
0
    OpenAPI_list_free(NFProfile->s_nssais);
486
487
0
    OpenAPI_list_for_each(NFProfile->allowed_nssais, node)
488
0
        OpenAPI_ext_snssai_free(node->data);
489
0
    OpenAPI_list_free(NFProfile->allowed_nssais);
490
491
0
    OpenAPI_list_for_each(NFProfile->nf_services, node) {
492
0
        NFService = node->data;
493
0
        ogs_assert(NFService);
494
0
        free_nf_service(NFService);
495
0
    }
496
0
    OpenAPI_list_free(NFProfile->nf_services);
497
498
0
    OpenAPI_list_for_each(NFProfile->nf_service_list, node) {
499
0
        NFServiceMap = node->data;
500
0
        if (NFServiceMap) {
501
0
            NFService = NFServiceMap->value;
502
0
            ogs_assert(NFService);
503
0
            free_nf_service(NFService);
504
0
            ogs_free(NFServiceMap);
505
0
        }
506
0
    }
507
0
    OpenAPI_list_free(NFProfile->nf_service_list);
508
509
0
    OpenAPI_list_for_each(NFProfile->smf_info_list, node) {
510
0
        SmfInfoMap = node->data;
511
0
        if (SmfInfoMap) {
512
0
            SmfInfo = SmfInfoMap->value;
513
0
            if (SmfInfo)
514
0
                free_smf_info(SmfInfo);
515
0
            if (SmfInfoMap->key)
516
0
                ogs_free(SmfInfoMap->key);
517
0
            ogs_free(SmfInfoMap);
518
0
        }
519
0
    }
520
0
    OpenAPI_list_free(NFProfile->smf_info_list);
521
522
0
    if (NFProfile->smf_info)
523
0
        free_smf_info(NFProfile->smf_info);
524
525
0
    OpenAPI_list_for_each(NFProfile->amf_info_list, node) {
526
0
        AmfInfoMap = node->data;
527
0
        if (AmfInfoMap) {
528
0
            AmfInfo = AmfInfoMap->value;
529
0
            if (AmfInfo)
530
0
                free_amf_info(AmfInfo);
531
0
            if (AmfInfoMap->key)
532
0
                ogs_free(AmfInfoMap->key);
533
0
            ogs_free(AmfInfoMap);
534
0
        }
535
0
    }
536
0
    OpenAPI_list_free(NFProfile->amf_info_list);
537
538
0
    if (NFProfile->amf_info)
539
0
        free_amf_info(NFProfile->amf_info);
540
541
0
    if (NFProfile->scp_info)
542
0
        free_scp_info(NFProfile->scp_info);
543
544
0
    if (NFProfile->sepp_info)
545
0
        free_sepp_info(NFProfile->sepp_info);
546
547
0
    ogs_free(NFProfile);
548
0
}
549
550
static OpenAPI_nf_service_t *build_nf_service(
551
        ogs_sbi_nf_service_t *nf_service)
552
0
{
553
0
    int i;
554
0
    OpenAPI_nf_service_t *NFService = NULL;
555
0
    OpenAPI_list_t *VersionList = NULL;
556
0
    OpenAPI_list_t *IpEndPointList = NULL;
557
0
    OpenAPI_list_t *AllowedNfTypeList = NULL;
558
559
0
    ogs_assert(nf_service);
560
0
    ogs_assert(nf_service->id);
561
562
0
    NFService = ogs_calloc(1, sizeof(*NFService));
563
0
    if (!NFService) {
564
0
        ogs_error("No NFService");
565
0
        return NULL;
566
0
    }
567
0
    NFService->service_instance_id = ogs_strdup(nf_service->id);
568
0
    if (!NFService->service_instance_id) {
569
0
        ogs_error("No service_instance_id");
570
0
        free_nf_service(NFService);
571
0
        return NULL;
572
0
    }
573
0
    NFService->service_name = nf_service->name;
574
0
    if (!NFService->service_name) {
575
0
        ogs_error("No service_name");
576
0
        free_nf_service(NFService);
577
0
        return NULL;
578
0
    }
579
580
0
    VersionList = OpenAPI_list_create();
581
0
    if (!VersionList) {
582
0
        ogs_error("No VersionList");
583
0
        free_nf_service(NFService);
584
0
        return NULL;
585
0
    }
586
587
0
    for (i = 0; i < nf_service->num_of_version; i++) {
588
0
        OpenAPI_nf_service_version_t *NFServiceVersion = NULL;
589
590
0
        NFServiceVersion = ogs_calloc(1, sizeof(*NFServiceVersion));
591
0
        if (!NFServiceVersion) {
592
0
            ogs_error("No NFServiceVersion");
593
0
            free_nf_service(NFService);
594
0
            OpenAPI_list_free(VersionList);
595
0
            return NULL;
596
0
        }
597
0
        if (nf_service->version[i].in_uri) {
598
0
            NFServiceVersion->api_version_in_uri =
599
0
                ogs_strdup(nf_service->version[i].in_uri);
600
0
            if (!NFServiceVersion->api_version_in_uri) {
601
0
                ogs_error("No api_version_in_uri");
602
0
                if (NFServiceVersion)
603
0
                    ogs_free(NFServiceVersion);
604
0
                free_nf_service(NFService);
605
0
                OpenAPI_list_free(VersionList);
606
0
                return NULL;
607
0
            }
608
0
        }
609
0
        if (nf_service->version[i].full) {
610
0
            NFServiceVersion->api_full_version =
611
0
                ogs_strdup(nf_service->version[i].full);
612
0
            if (!NFServiceVersion->api_full_version) {
613
0
                ogs_error("No api_full_version");
614
0
                if (NFServiceVersion) {
615
0
                    if (NFServiceVersion->api_version_in_uri)
616
0
                        ogs_free(NFServiceVersion->api_version_in_uri);
617
0
                    ogs_free(NFServiceVersion);
618
0
                }
619
0
                free_nf_service(NFService);
620
0
                OpenAPI_list_free(VersionList);
621
0
                return NULL;
622
0
            }
623
0
        }
624
0
        if (nf_service->version[i].expiry) {
625
0
            NFServiceVersion->expiry =
626
0
                ogs_strdup(nf_service->version[i].expiry);
627
0
            if (!NFServiceVersion->expiry) {
628
0
                ogs_error("No expiry");
629
0
                if (NFServiceVersion) {
630
0
                    if (NFServiceVersion->api_version_in_uri)
631
0
                        ogs_free(NFServiceVersion->api_version_in_uri);
632
0
                    if (NFServiceVersion->api_full_version)
633
0
                        ogs_free(NFServiceVersion->api_full_version);
634
0
                    ogs_free(NFServiceVersion);
635
0
                }
636
0
                free_nf_service(NFService);
637
0
                OpenAPI_list_free(VersionList);
638
0
                return NULL;
639
0
            }
640
0
        }
641
642
0
        OpenAPI_list_add(VersionList, NFServiceVersion);
643
0
    }
644
645
0
    ogs_assert(VersionList->count);
646
0
    NFService->versions = VersionList;
647
648
0
    NFService->scheme = nf_service->scheme;
649
0
    NFService->nf_service_status = nf_service->status;
650
651
0
    if (nf_service->fqdn)
652
0
        NFService->fqdn = ogs_strdup(nf_service->fqdn);
653
654
0
    IpEndPointList = OpenAPI_list_create();
655
0
    if (!IpEndPointList) {
656
0
        ogs_error("No IpEndPointList");
657
0
        free_nf_service(NFService);
658
0
        return NULL;
659
0
    }
660
661
0
    for (i = 0; i < nf_service->num_of_addr; i++) {
662
0
        ogs_sockaddr_t *ipv4 = NULL;
663
0
        ogs_sockaddr_t *ipv6 = NULL;
664
665
0
        OpenAPI_ip_end_point_t *IpEndPoint = NULL;
666
667
0
        ipv4 = nf_service->addr[i].ipv4;
668
0
        ipv6 = nf_service->addr[i].ipv6;
669
670
0
        if (ipv4 || ipv6) {
671
0
            IpEndPoint = ogs_calloc(1, sizeof(*IpEndPoint));
672
0
            if (!IpEndPoint) {
673
0
                ogs_error("No IpEndPoint");
674
0
                free_nf_service(NFService);
675
0
                OpenAPI_list_free(IpEndPointList);
676
0
                return NULL;
677
0
            }
678
0
            if (ipv4) {
679
0
                IpEndPoint->ipv4_address = ogs_ipstrdup(ipv4);
680
0
                if (!IpEndPoint->ipv4_address) {
681
0
                    ogs_error("No ipv4_address");
682
0
                    if (IpEndPoint)
683
0
                        ogs_free(IpEndPoint);
684
0
                    free_nf_service(NFService);
685
0
                    OpenAPI_list_free(IpEndPointList);
686
0
                    return NULL;
687
0
                }
688
0
            }
689
0
            if (ipv6) {
690
0
                IpEndPoint->ipv6_address = ogs_ipstrdup(ipv6);
691
0
                if (!IpEndPoint->ipv6_address) {
692
0
                    ogs_error("No ipv6_address");
693
0
                    if (IpEndPoint) {
694
0
                        if (IpEndPoint->ipv4_address)
695
0
                            ogs_free(IpEndPoint->ipv4_address);
696
0
                        ogs_free(IpEndPoint);
697
0
                    }
698
0
                    free_nf_service(NFService);
699
0
                    OpenAPI_list_free(IpEndPointList);
700
0
                    return NULL;
701
0
                }
702
0
            }
703
0
            IpEndPoint->is_port = nf_service->addr[i].is_port;
704
0
            IpEndPoint->port = nf_service->addr[i].port;
705
0
            OpenAPI_list_add(IpEndPointList, IpEndPoint);
706
0
        }
707
0
    }
708
709
0
    if (IpEndPointList->count)
710
0
        NFService->ip_end_points = IpEndPointList;
711
0
    else
712
0
        OpenAPI_list_free(IpEndPointList);
713
714
0
    AllowedNfTypeList = OpenAPI_list_create();
715
0
    if (!AllowedNfTypeList) {
716
0
        ogs_error("No AllowedNfTypeList");
717
0
        free_nf_service(NFService);
718
0
        return NULL;
719
0
    }
720
721
0
    for (i = 0; i < nf_service->num_of_allowed_nf_type; i++) {
722
0
        OpenAPI_list_add(AllowedNfTypeList,
723
0
                (void *)(uintptr_t)nf_service->allowed_nf_type[i]);
724
0
    }
725
726
0
    if (AllowedNfTypeList->count)
727
0
        NFService->allowed_nf_types = AllowedNfTypeList;
728
0
    else
729
0
        OpenAPI_list_free(AllowedNfTypeList);
730
731
0
    NFService->is_priority = true;
732
0
    NFService->priority = nf_service->priority;
733
0
    NFService->is_capacity = true;
734
0
    NFService->capacity = nf_service->capacity;
735
0
    NFService->is_load = true;
736
0
    NFService->load = nf_service->load;
737
738
0
    return NFService;
739
0
}
740
741
static void free_nf_service(OpenAPI_nf_service_t *NFService)
742
0
{
743
0
    OpenAPI_lnode_t *node = NULL;
744
745
0
    ogs_assert(NFService);
746
747
0
    ogs_free(NFService->service_instance_id);
748
749
0
    OpenAPI_list_for_each(NFService->versions, node) {
750
0
        OpenAPI_nf_service_version_t *NFServiceVersion = node->data;
751
0
        ogs_assert(NFServiceVersion);
752
0
        ogs_free(NFServiceVersion->api_version_in_uri);
753
0
        ogs_free(NFServiceVersion->api_full_version);
754
0
        if (NFServiceVersion->expiry)
755
0
            ogs_free(NFServiceVersion->expiry);
756
0
        ogs_free(NFServiceVersion);
757
0
    }
758
0
    OpenAPI_list_free(NFService->versions);
759
760
0
    OpenAPI_list_for_each(NFService->ip_end_points, node) {
761
0
        OpenAPI_ip_end_point_t *IpEndPoint = node->data;
762
0
        ogs_assert(IpEndPoint);
763
0
        if (IpEndPoint->ipv4_address)
764
0
            ogs_free(IpEndPoint->ipv4_address);
765
0
        if (IpEndPoint->ipv6_address)
766
0
            ogs_free(IpEndPoint->ipv6_address);
767
0
        ogs_free(IpEndPoint);
768
0
    }
769
0
    OpenAPI_list_free(NFService->ip_end_points);
770
771
0
    OpenAPI_list_free(NFService->allowed_nf_types);
772
773
0
    if (NFService->fqdn)
774
0
        ogs_free(NFService->fqdn);
775
776
0
    ogs_free(NFService);
777
0
}
778
779
static OpenAPI_smf_info_t *build_smf_info(ogs_sbi_nf_info_t *nf_info)
780
0
{
781
0
    int i, j;
782
0
    OpenAPI_smf_info_t *SmfInfo = NULL;
783
784
0
    OpenAPI_list_t *sNssaiSmfInfoList = NULL;
785
0
    OpenAPI_snssai_smf_info_item_t *sNssaiSmfInfoItem = NULL;
786
0
    OpenAPI_ext_snssai_t *sNssai = NULL;
787
0
    OpenAPI_list_t *DnnSmfInfoList = NULL;
788
0
    OpenAPI_dnn_smf_info_item_t *DnnSmfInfoItem = NULL;
789
790
0
    OpenAPI_list_t *TaiList = NULL;
791
0
    OpenAPI_tai_t *TaiItem = NULL;
792
0
    OpenAPI_list_t *TaiRangeList = NULL;
793
0
    OpenAPI_tai_range_t *TaiRangeItem = NULL;
794
0
    OpenAPI_list_t *TacRangeList = NULL;
795
0
    OpenAPI_tac_range_t *TacRangeItem = NULL;
796
797
0
    ogs_assert(nf_info);
798
799
0
    SmfInfo = ogs_calloc(1, sizeof(*SmfInfo));
800
0
    if (!SmfInfo) {
801
0
        ogs_error("No SmfInfo");
802
0
        return NULL;
803
0
    }
804
805
0
    sNssaiSmfInfoList = OpenAPI_list_create();
806
0
    if (!sNssaiSmfInfoList) {
807
0
        ogs_error("No sNssaiSmfInfoList");
808
0
        free_smf_info(SmfInfo);
809
0
        return NULL;
810
0
    }
811
812
0
    for (i = 0; i < nf_info->smf.num_of_slice; i++) {
813
0
        DnnSmfInfoList = OpenAPI_list_create();
814
0
        if (!DnnSmfInfoList) {
815
0
            ogs_error("No DnnSmfInfoList");
816
0
            free_smf_info(SmfInfo);
817
0
            OpenAPI_list_free(sNssaiSmfInfoList);
818
0
            return NULL;
819
0
        }
820
821
0
        for (j = 0; j < nf_info->smf.slice[i].num_of_dnn; j++) {
822
0
            DnnSmfInfoItem = ogs_calloc(1, sizeof(*DnnSmfInfoItem));
823
0
            ogs_assert(DnnSmfInfoItem);
824
0
            DnnSmfInfoItem->dnn = nf_info->smf.slice[i].dnn[j];
825
826
0
            OpenAPI_list_add(DnnSmfInfoList, DnnSmfInfoItem);
827
0
        }
828
829
0
        if (!DnnSmfInfoList->count) {
830
0
            ogs_error("CHECK CONFIGURATION: No DNN");
831
832
0
            OpenAPI_list_free(DnnSmfInfoList);
833
0
            free_smf_info(SmfInfo);
834
0
            OpenAPI_list_free(sNssaiSmfInfoList);
835
836
0
            return NULL;
837
0
        }
838
839
0
        sNssaiSmfInfoItem = ogs_calloc(1, sizeof(*sNssaiSmfInfoItem));
840
0
        ogs_assert(sNssaiSmfInfoItem);
841
842
0
        sNssaiSmfInfoItem->dnn_smf_info_list = DnnSmfInfoList;
843
844
0
        sNssaiSmfInfoItem->s_nssai = sNssai = ogs_calloc(1, sizeof(*sNssai));
845
0
        ogs_assert(sNssai);
846
0
        sNssai->sst = nf_info->smf.slice[i].s_nssai.sst;
847
0
        sNssai->sd =
848
0
            ogs_s_nssai_sd_to_string(nf_info->smf.slice[i].s_nssai.sd);
849
850
0
        OpenAPI_list_add(sNssaiSmfInfoList, sNssaiSmfInfoItem);
851
0
    }
852
853
0
    if (sNssaiSmfInfoList->count)
854
0
        SmfInfo->s_nssai_smf_info_list = sNssaiSmfInfoList;
855
0
    else
856
0
        OpenAPI_list_free(sNssaiSmfInfoList);
857
858
0
    TaiList = OpenAPI_list_create();
859
0
    if (!TaiList) {
860
0
        ogs_error("No TaiList");
861
0
        free_smf_info(SmfInfo);
862
0
        return NULL;
863
0
    }
864
865
0
    for (i = 0; i < nf_info->smf.num_of_nr_tai; i++) {
866
0
        TaiItem = ogs_calloc(1, sizeof(*TaiItem));
867
0
        if (!TaiItem) {
868
0
            ogs_error("No TaiItem");
869
0
            free_smf_info(SmfInfo);
870
0
            OpenAPI_list_free(TaiList);
871
0
            return NULL;
872
0
        }
873
0
        TaiItem->plmn_id = ogs_sbi_build_plmn_id(
874
0
                &nf_info->smf.nr_tai[i].plmn_id);
875
0
        if (!TaiItem->plmn_id) {
876
0
            ogs_error("No TaiItem->plmn_id");
877
0
            if (TaiItem)
878
0
                ogs_free(TaiItem);
879
0
            free_smf_info(SmfInfo);
880
0
            OpenAPI_list_free(TaiList);
881
0
            return NULL;
882
0
        }
883
0
        TaiItem->tac =
884
0
            ogs_uint24_to_0string(nf_info->smf.nr_tai[i].tac);
885
0
        if (!TaiItem->tac) {
886
0
            ogs_error("No TaiItem->tac");
887
0
            OpenAPI_tai_free(TaiItem);
888
0
            OpenAPI_smf_info_free(SmfInfo);
889
0
            OpenAPI_list_free(TaiList);
890
0
            return NULL;
891
0
        }
892
893
0
        OpenAPI_list_add(TaiList, TaiItem);
894
0
    }
895
896
0
    if (TaiList->count)
897
0
        SmfInfo->tai_list = TaiList;
898
0
    else
899
0
        OpenAPI_list_free(TaiList);
900
901
0
    TaiRangeList = OpenAPI_list_create();
902
0
    if (!TaiRangeList) {
903
0
        ogs_error("No TaiRangeList");
904
0
        free_smf_info(SmfInfo);
905
0
        return NULL;
906
0
    }
907
908
0
    for (i = 0; i < nf_info->smf.num_of_nr_tai_range; i++) {
909
0
        TacRangeList = OpenAPI_list_create();
910
0
        if (!TacRangeList) {
911
0
            ogs_error("No TacRangeList");
912
0
            free_smf_info(SmfInfo);
913
0
            OpenAPI_list_free(TaiRangeList);
914
0
            return NULL;
915
0
        }
916
917
0
        for (j = 0;
918
0
                j < nf_info->smf.nr_tai_range[i].num_of_tac_range;
919
0
                j++) {
920
0
            TacRangeItem = ogs_calloc(1, sizeof(*TacRangeItem));
921
0
            ogs_assert(TacRangeItem);
922
923
0
            TacRangeItem->start = ogs_uint24_to_0string(
924
0
                    nf_info->smf.nr_tai_range[i].start[j]);
925
0
            ogs_assert(TacRangeItem->start);
926
0
            TacRangeItem->end =
927
0
                ogs_uint24_to_0string(
928
0
                        nf_info->smf.nr_tai_range[i].end[j]);
929
0
            ogs_assert(TacRangeItem->end);
930
931
0
            OpenAPI_list_add(TacRangeList, TacRangeItem);
932
0
        }
933
934
0
        if (!TacRangeList->count) {
935
0
            ogs_error("CHECK CONFIGURATION: No Start/End in TacRange");
936
937
0
            OpenAPI_list_free(TacRangeList);
938
0
            free_smf_info(SmfInfo);
939
0
            OpenAPI_list_free(TaiRangeList);
940
941
0
            return NULL;
942
0
        }
943
944
0
        TaiRangeItem = ogs_calloc(1, sizeof(*TaiRangeItem));
945
0
        ogs_assert(TaiRangeItem);
946
947
0
        TaiRangeItem->plmn_id = ogs_sbi_build_plmn_id(
948
0
                &nf_info->smf.nr_tai_range[i].plmn_id);
949
0
        ogs_assert(TaiRangeItem->plmn_id);
950
951
0
        TaiRangeItem->tac_range_list = TacRangeList;
952
953
0
        OpenAPI_list_add(TaiRangeList, TaiRangeItem);
954
0
    }
955
956
0
    if (TaiRangeList->count)
957
0
        SmfInfo->tai_range_list = TaiRangeList;
958
0
    else
959
0
        OpenAPI_list_free(TaiRangeList);
960
961
0
    return SmfInfo;
962
0
}
963
964
static OpenAPI_amf_info_t *build_amf_info(ogs_sbi_nf_info_t *nf_info)
965
0
{
966
0
    int i, j;
967
0
    OpenAPI_amf_info_t *AmfInfo = NULL;
968
969
0
    OpenAPI_list_t *guamiAmfInfoList = NULL;
970
0
    OpenAPI_guami_t *guamiAmfInfoItem = NULL;
971
972
0
    OpenAPI_list_t *TaiList = NULL;
973
0
    OpenAPI_tai_t *TaiItem = NULL;
974
0
    OpenAPI_list_t *TaiRangeList = NULL;
975
0
    OpenAPI_tai_range_t *TaiRangeItem = NULL;
976
0
    OpenAPI_list_t *TacRangeList = NULL;
977
0
    OpenAPI_tac_range_t *TacRangeItem = NULL;
978
979
0
    ogs_assert(nf_info);
980
981
0
    AmfInfo = ogs_calloc(1, sizeof(*AmfInfo));
982
0
    if (!AmfInfo) {
983
0
        ogs_error("No AmfInfo");
984
0
        return NULL;
985
0
    }
986
987
0
    AmfInfo->amf_set_id = ogs_msprintf("%03x", nf_info->amf.amf_set_id);
988
0
    if (!AmfInfo->amf_set_id) {
989
0
        ogs_error("No amf_set_id");
990
0
        free_amf_info(AmfInfo);
991
0
        return NULL;
992
0
    }
993
0
    AmfInfo->amf_region_id = ogs_msprintf("%02x", nf_info->amf.amf_region_id);
994
0
    if (!AmfInfo->amf_region_id) {
995
0
        ogs_error("No amf_region_id");
996
0
        free_amf_info(AmfInfo);
997
0
        return NULL;
998
0
    }
999
1000
    /* Guami list */
1001
0
    guamiAmfInfoList = OpenAPI_list_create();
1002
0
    if (!guamiAmfInfoList) {
1003
0
        ogs_error("No guamiAmfInfoList");
1004
0
        free_amf_info(AmfInfo);
1005
0
        return NULL;
1006
0
    }
1007
1008
0
    for (i = 0; i < nf_info->amf.num_of_guami; i++) {
1009
1010
0
        guamiAmfInfoItem = ogs_calloc(1, sizeof(*guamiAmfInfoItem));
1011
0
        if (!guamiAmfInfoItem) {
1012
0
            ogs_error("No guamiAmfInfoItem");
1013
0
            OpenAPI_amf_info_free(AmfInfo);
1014
0
            OpenAPI_list_free(guamiAmfInfoList);
1015
0
            return NULL;
1016
0
        }
1017
1018
0
        guamiAmfInfoItem->plmn_id =
1019
0
                ogs_sbi_build_plmn_id_nid(&nf_info->amf.guami[i].plmn_id);
1020
0
        if (!guamiAmfInfoItem->plmn_id) {
1021
0
            ogs_error("No guamiAmfInfoItem->plmn_id");
1022
0
            OpenAPI_guami_free(guamiAmfInfoItem);
1023
0
            OpenAPI_amf_info_free(AmfInfo);
1024
0
            OpenAPI_list_free(guamiAmfInfoList);
1025
0
            return NULL;
1026
0
        }
1027
0
        guamiAmfInfoItem->amf_id =
1028
0
                ogs_amf_id_to_string(&nf_info->amf.guami[i].amf_id);
1029
0
        if (!guamiAmfInfoItem->amf_id) {
1030
0
            ogs_error("No guamiAmfInfoItem->amf_id");
1031
0
            OpenAPI_guami_free(guamiAmfInfoItem);
1032
0
            OpenAPI_amf_info_free(AmfInfo);
1033
0
            OpenAPI_list_free(guamiAmfInfoList);
1034
0
            return NULL;
1035
0
        }
1036
1037
0
        OpenAPI_list_add(guamiAmfInfoList, guamiAmfInfoItem);
1038
0
    }
1039
1040
0
    if (guamiAmfInfoList->count)
1041
0
        AmfInfo->guami_list = guamiAmfInfoList;
1042
0
    else
1043
0
        OpenAPI_list_free(guamiAmfInfoList);
1044
1045
1046
    /* TAI list */
1047
0
    TaiList = OpenAPI_list_create();
1048
0
    if (!TaiList) {
1049
0
        ogs_error("No TaiList");
1050
0
        free_amf_info(AmfInfo);
1051
0
        return NULL;
1052
0
    }
1053
1054
0
    for (i = 0; i < nf_info->amf.num_of_nr_tai; i++) {
1055
0
        TaiItem = ogs_calloc(1, sizeof(*TaiItem));
1056
0
        if (!TaiItem) {
1057
0
            ogs_error("No TaiItem");
1058
0
            free_amf_info(AmfInfo);
1059
0
            OpenAPI_list_free(TaiList);
1060
0
            return NULL;
1061
0
        }
1062
0
        TaiItem->plmn_id = ogs_sbi_build_plmn_id(
1063
0
                &nf_info->amf.nr_tai[i].plmn_id);
1064
0
        if (!TaiItem->plmn_id) {
1065
0
            ogs_error("No TaiItem->plmn_id");
1066
0
            OpenAPI_tai_free(TaiItem);
1067
0
            OpenAPI_amf_info_free(AmfInfo);
1068
0
            OpenAPI_list_free(TaiList);
1069
0
            return NULL;
1070
0
        }
1071
0
        TaiItem->tac = ogs_uint24_to_0string(nf_info->amf.nr_tai[i].tac);
1072
0
        if (!TaiItem->tac) {
1073
0
            ogs_error("No TaiItem->tac");
1074
0
            OpenAPI_tai_free(TaiItem);
1075
0
            OpenAPI_amf_info_free(AmfInfo);
1076
0
            OpenAPI_list_free(TaiList);
1077
0
            return NULL;
1078
0
        }
1079
1080
0
        OpenAPI_list_add(TaiList, TaiItem);
1081
0
    }
1082
1083
0
    if (TaiList->count)
1084
0
        AmfInfo->tai_list = TaiList;
1085
0
    else
1086
0
        OpenAPI_list_free(TaiList);
1087
1088
1089
    /* TAI range list */
1090
0
    TaiRangeList = OpenAPI_list_create();
1091
0
    if (!TaiRangeList) {
1092
0
        ogs_error("No TaiRangeList");
1093
0
        free_amf_info(AmfInfo);
1094
0
        return NULL;
1095
0
    }
1096
1097
0
    for (i = 0; i < nf_info->amf.num_of_nr_tai_range; i++) {
1098
0
        TacRangeList = OpenAPI_list_create();
1099
0
        if (!TacRangeList) {
1100
0
            ogs_error("No TacRangeList");
1101
0
            free_amf_info(AmfInfo);
1102
0
            OpenAPI_list_free(TaiRangeList);
1103
0
            return NULL;
1104
0
        }
1105
1106
0
        for (j = 0;
1107
0
                j < nf_info->amf.nr_tai_range[i].num_of_tac_range;
1108
0
                j++) {
1109
0
            TacRangeItem = ogs_calloc(1, sizeof(*TacRangeItem));
1110
0
            ogs_assert(TacRangeItem);
1111
1112
0
            TacRangeItem->start = ogs_uint24_to_0string(
1113
0
                    nf_info->amf.nr_tai_range[i].start[j]);
1114
0
            ogs_assert(TacRangeItem->start);
1115
0
            TacRangeItem->end =
1116
0
                ogs_uint24_to_0string(
1117
0
                        nf_info->amf.nr_tai_range[i].end[j]);
1118
0
            ogs_assert(TacRangeItem->end);
1119
1120
0
            OpenAPI_list_add(TacRangeList, TacRangeItem);
1121
0
        }
1122
1123
0
        if (!TacRangeList->count) {
1124
0
            ogs_error("CHECK CONFIGURATION: No Start/End in TacRange");
1125
1126
0
            OpenAPI_list_free(TacRangeList);
1127
0
            free_amf_info(AmfInfo);
1128
0
            OpenAPI_list_free(TaiRangeList);
1129
1130
0
            return NULL;
1131
0
        }
1132
1133
0
        TaiRangeItem = ogs_calloc(1, sizeof(*TaiRangeItem));
1134
0
        if (!TaiRangeItem) {
1135
0
            ogs_error("No TaiRangeItem");
1136
0
            free_amf_info(AmfInfo);
1137
0
            OpenAPI_list_free(TaiRangeList);
1138
0
            return NULL;
1139
0
        }
1140
1141
0
        TaiRangeItem->plmn_id = ogs_sbi_build_plmn_id(
1142
0
                &nf_info->amf.nr_tai_range[i].plmn_id);
1143
0
        if (!TaiRangeItem->plmn_id) {
1144
0
            ogs_error("No TaiRangeItem->plmn_id");
1145
0
            ogs_free(TaiRangeItem);
1146
0
            free_amf_info(AmfInfo);
1147
0
            OpenAPI_list_free(TaiRangeList);
1148
0
            return NULL;
1149
0
        }
1150
1151
0
        TaiRangeItem->tac_range_list = TacRangeList;
1152
1153
0
        OpenAPI_list_add(TaiRangeList, TaiRangeItem);
1154
0
    }
1155
1156
0
    if (TaiRangeList->count)
1157
0
        AmfInfo->tai_range_list = TaiRangeList;
1158
0
    else
1159
0
        OpenAPI_list_free(TaiRangeList);
1160
1161
0
    return AmfInfo;
1162
0
}
1163
1164
static OpenAPI_scp_info_t *build_scp_info(ogs_sbi_nf_info_t *nf_info)
1165
0
{
1166
0
    int i;
1167
0
    OpenAPI_scp_info_t *ScpInfo = NULL;
1168
0
    OpenAPI_list_t *PortList = NULL;
1169
0
    OpenAPI_map_t *PortMap = NULL;
1170
1171
0
    OpenAPI_list_t *DomainInfoList = NULL;
1172
0
    OpenAPI_map_t *DomainInfoMap = NULL;
1173
0
    OpenAPI_scp_domain_info_t *DomainInfo = NULL;
1174
1175
0
    ogs_assert(nf_info);
1176
1177
0
    ScpInfo = ogs_calloc(1, sizeof(*ScpInfo));
1178
0
    if (!ScpInfo) {
1179
0
        ogs_error("No ScpInfo");
1180
0
        return NULL;
1181
0
    }
1182
1183
0
    PortList = OpenAPI_list_create();
1184
0
    if (!PortList) {
1185
0
        ogs_error("No PortList");
1186
0
        free_scp_info(ScpInfo);
1187
0
        return NULL;
1188
0
    }
1189
1190
0
    if (nf_info->scp.http.presence) {
1191
0
        PortMap = OpenAPI_map_create(
1192
0
                    (char *)"http", ogs_alloc_double(nf_info->scp.http.port));
1193
0
        if (!PortMap) {
1194
0
            ogs_error("No PortMap");
1195
0
            free_scp_info(ScpInfo);
1196
0
            return NULL;
1197
0
        }
1198
0
        OpenAPI_list_add(PortList, PortMap);
1199
0
    }
1200
0
    if (nf_info->scp.https.presence) {
1201
0
        PortMap = OpenAPI_map_create(
1202
0
                    (char *)"https", ogs_alloc_double(nf_info->scp.https.port));
1203
0
        if (!PortMap) {
1204
0
            ogs_error("No PortMap");
1205
0
            free_scp_info(ScpInfo);
1206
0
            return NULL;
1207
0
        }
1208
0
        OpenAPI_list_add(PortList, PortMap);
1209
0
    }
1210
1211
0
    if (PortList->count)
1212
0
        ScpInfo->scp_ports = PortList;
1213
0
    else
1214
0
        OpenAPI_list_free(PortList);
1215
1216
0
    DomainInfoList = OpenAPI_list_create();
1217
0
    if (!DomainInfoList) {
1218
0
        ogs_error("No DomainInfoList");
1219
0
        free_scp_info(ScpInfo);
1220
0
        return NULL;
1221
0
    }
1222
0
    for (i = 0; i < nf_info->scp.num_of_domain; i++) {
1223
0
        ogs_assert(nf_info->scp.domain[i].name);
1224
1225
0
        DomainInfo = ogs_calloc(1, sizeof(*DomainInfo));
1226
0
        if (!DomainInfo) {
1227
0
            ogs_error("No DomainInfo");
1228
0
            free_scp_info(ScpInfo);
1229
0
            return NULL;
1230
0
        }
1231
1232
0
        DomainInfo->scp_fqdn = nf_info->scp.domain[i].fqdn;
1233
1234
0
        PortList = OpenAPI_list_create();
1235
0
        if (!PortList) {
1236
0
            ogs_error("No PortList");
1237
0
            free_scp_info(ScpInfo);
1238
0
            return NULL;
1239
0
        }
1240
1241
0
        if (nf_info->scp.domain[i].http.presence) {
1242
0
            PortMap = OpenAPI_map_create(
1243
0
                        (char *)"http",
1244
0
                        ogs_alloc_double(nf_info->scp.domain[i].http.port));
1245
0
            if (!PortMap) {
1246
0
                ogs_error("No PortMap");
1247
0
                free_scp_info(ScpInfo);
1248
0
                return NULL;
1249
0
            }
1250
0
            OpenAPI_list_add(PortList, PortMap);
1251
0
        }
1252
0
        if (nf_info->scp.domain[i].https.presence) {
1253
0
            PortMap = OpenAPI_map_create(
1254
0
                        (char *)"https",
1255
0
                        ogs_alloc_double(nf_info->scp.domain[i].https.port));
1256
0
            if (!PortMap) {
1257
0
                ogs_error("No PortMap");
1258
0
                free_scp_info(ScpInfo);
1259
0
                return NULL;
1260
0
            }
1261
0
            OpenAPI_list_add(PortList, PortMap);
1262
0
        }
1263
1264
0
        if (PortList->count)
1265
0
            DomainInfo->scp_ports = PortList;
1266
0
        else
1267
0
            OpenAPI_list_free(PortList);
1268
1269
0
        DomainInfoMap = OpenAPI_map_create(
1270
0
                    nf_info->scp.domain[i].name, DomainInfo);
1271
0
        if (!DomainInfoMap) {
1272
0
            ogs_error("No PortMap");
1273
0
            free_scp_info(ScpInfo);
1274
0
            return NULL;
1275
0
        }
1276
1277
0
        OpenAPI_list_add(DomainInfoList, DomainInfoMap);
1278
0
    }
1279
1280
0
    if (DomainInfoList->count)
1281
0
        ScpInfo->scp_domain_info_list = DomainInfoList;
1282
0
    else
1283
0
        OpenAPI_list_free(DomainInfoList);
1284
1285
0
    return ScpInfo;
1286
0
}
1287
1288
static OpenAPI_sepp_info_t *build_sepp_info(ogs_sbi_nf_info_t *nf_info)
1289
0
{
1290
0
    OpenAPI_sepp_info_t *SeppInfo = NULL;
1291
0
    OpenAPI_list_t *PortList = NULL;
1292
0
    OpenAPI_map_t *PortMap = NULL;
1293
1294
0
    ogs_assert(nf_info);
1295
1296
0
    SeppInfo = ogs_calloc(1, sizeof(*SeppInfo));
1297
0
    if (!SeppInfo) {
1298
0
        ogs_error("No SeppInfo");
1299
0
        return NULL;
1300
0
    }
1301
1302
0
    PortList = OpenAPI_list_create();
1303
0
    if (!PortList) {
1304
0
        ogs_error("No PortList");
1305
0
        free_sepp_info(SeppInfo);
1306
0
        return NULL;
1307
0
    }
1308
1309
0
    if (nf_info->sepp.http.presence) {
1310
0
        PortMap = OpenAPI_map_create(
1311
0
                    (char *)"http", ogs_alloc_double(nf_info->sepp.http.port));
1312
0
        if (!PortMap) {
1313
0
            ogs_error("No PortMap");
1314
0
            free_sepp_info(SeppInfo);
1315
0
            return NULL;
1316
0
        }
1317
0
        OpenAPI_list_add(PortList, PortMap);
1318
0
    }
1319
0
    if (nf_info->sepp.https.presence) {
1320
0
        PortMap = OpenAPI_map_create(
1321
0
                    (char *)"https", ogs_alloc_double(nf_info->sepp.https.port));
1322
0
        if (!PortMap) {
1323
0
            ogs_error("No PortMap");
1324
0
            free_sepp_info(SeppInfo);
1325
0
            return NULL;
1326
0
        }
1327
0
        OpenAPI_list_add(PortList, PortMap);
1328
0
    }
1329
1330
0
    if (PortList->count)
1331
0
        SeppInfo->sepp_ports = PortList;
1332
0
    else
1333
0
        OpenAPI_list_free(PortList);
1334
1335
0
    return SeppInfo;
1336
0
}
1337
1338
static void free_smf_info(OpenAPI_smf_info_t *SmfInfo)
1339
0
{
1340
0
    OpenAPI_list_t *sNssaiSmfInfoList = NULL;
1341
0
    OpenAPI_snssai_smf_info_item_t *sNssaiSmfInfoItem = NULL;
1342
0
    OpenAPI_ext_snssai_t *sNssai = NULL;
1343
0
    OpenAPI_list_t *DnnSmfInfoList = NULL;
1344
0
    OpenAPI_dnn_smf_info_item_t *DnnSmfInfoItem = NULL;
1345
1346
0
    OpenAPI_list_t *TaiList = NULL;
1347
0
    OpenAPI_tai_t *TaiItem = NULL;
1348
0
    OpenAPI_list_t *TaiRangeList = NULL;
1349
0
    OpenAPI_tai_range_t *TaiRangeItem = NULL;
1350
0
    OpenAPI_list_t *TacRangeList = NULL;
1351
0
    OpenAPI_tac_range_t *TacRangeItem = NULL;
1352
1353
0
    OpenAPI_lnode_t *node = NULL, *node2 = NULL;
1354
1355
0
    ogs_assert(SmfInfo);
1356
1357
0
    sNssaiSmfInfoList = SmfInfo->s_nssai_smf_info_list;
1358
0
    OpenAPI_list_for_each(sNssaiSmfInfoList, node) {
1359
0
        sNssaiSmfInfoItem = node->data;
1360
0
        ogs_assert(sNssaiSmfInfoItem);
1361
1362
0
        DnnSmfInfoList = sNssaiSmfInfoItem->dnn_smf_info_list;
1363
0
        OpenAPI_list_for_each(DnnSmfInfoList, node2) {
1364
0
            DnnSmfInfoItem = node2->data;
1365
0
            ogs_assert(DnnSmfInfoItem);
1366
0
            ogs_free(DnnSmfInfoItem);
1367
0
        }
1368
0
        OpenAPI_list_free(DnnSmfInfoList);
1369
1370
0
        sNssai = sNssaiSmfInfoItem->s_nssai;
1371
0
        if (sNssai) {
1372
0
            if (sNssai->sd)
1373
0
                ogs_free(sNssai->sd);
1374
0
            ogs_free(sNssai);
1375
0
        }
1376
1377
0
        ogs_free(sNssaiSmfInfoItem);
1378
0
    }
1379
0
    OpenAPI_list_free(sNssaiSmfInfoList);
1380
1381
0
    TaiList = SmfInfo->tai_list;
1382
0
    OpenAPI_list_for_each(TaiList, node) {
1383
0
        TaiItem = node->data;
1384
0
        ogs_assert(TaiItem);
1385
0
        if (TaiItem->plmn_id)
1386
0
            ogs_sbi_free_plmn_id(TaiItem->plmn_id);
1387
0
        if (TaiItem->tac)
1388
0
            ogs_free(TaiItem->tac);
1389
0
        ogs_free(TaiItem);
1390
0
    }
1391
0
    OpenAPI_list_free(TaiList);
1392
1393
0
    TaiRangeList = SmfInfo->tai_range_list;
1394
0
    OpenAPI_list_for_each(TaiRangeList, node) {
1395
0
        TaiRangeItem = node->data;
1396
0
        ogs_assert(TaiRangeItem);
1397
1398
0
        if (TaiRangeItem->plmn_id)
1399
0
            ogs_sbi_free_plmn_id(TaiRangeItem->plmn_id);
1400
1401
0
        TacRangeList = TaiRangeItem->tac_range_list;
1402
0
        OpenAPI_list_for_each(TacRangeList, node2) {
1403
0
            TacRangeItem = node2->data;
1404
0
            ogs_assert(TacRangeItem);
1405
0
            if (TacRangeItem->start)
1406
0
                ogs_free(TacRangeItem->start);
1407
0
            if (TacRangeItem->end)
1408
0
                ogs_free(TacRangeItem->end);
1409
1410
0
            ogs_free(TacRangeItem);
1411
0
        }
1412
0
        OpenAPI_list_free(TacRangeList);
1413
1414
0
        ogs_free(TaiRangeItem);
1415
0
    }
1416
0
    OpenAPI_list_free(TaiRangeList);
1417
1418
0
    ogs_free(SmfInfo);
1419
0
}
1420
1421
static void free_amf_info(OpenAPI_amf_info_t *AmfInfo)
1422
0
{
1423
0
    OpenAPI_list_t *guamiAmfInfoList = NULL;
1424
0
    OpenAPI_guami_t *guamiAmfInfoItem = NULL;
1425
1426
0
    OpenAPI_list_t *TaiList = NULL;
1427
0
    OpenAPI_tai_t *TaiItem = NULL;
1428
0
    OpenAPI_list_t *TaiRangeList = NULL;
1429
0
    OpenAPI_tai_range_t *TaiRangeItem = NULL;
1430
0
    OpenAPI_list_t *TacRangeList = NULL;
1431
0
    OpenAPI_tac_range_t *TacRangeItem = NULL;
1432
1433
0
    OpenAPI_lnode_t *node = NULL, *node2 = NULL;
1434
1435
0
    ogs_assert(AmfInfo);
1436
1437
0
    if (AmfInfo->amf_set_id)
1438
0
        ogs_free(AmfInfo->amf_set_id);
1439
0
    if (AmfInfo->amf_region_id)
1440
0
        ogs_free(AmfInfo->amf_region_id);
1441
1442
0
    guamiAmfInfoList = AmfInfo->guami_list;
1443
0
    OpenAPI_list_for_each(guamiAmfInfoList, node) {
1444
0
        guamiAmfInfoItem = node->data;
1445
0
        if (guamiAmfInfoItem) {
1446
0
            if (guamiAmfInfoItem->plmn_id) {
1447
0
                if (guamiAmfInfoItem->plmn_id->mcc)
1448
0
                    ogs_free(guamiAmfInfoItem->plmn_id->mcc);
1449
0
                if (guamiAmfInfoItem->plmn_id->mnc)
1450
0
                    ogs_free(guamiAmfInfoItem->plmn_id->mnc);
1451
0
                ogs_free(guamiAmfInfoItem->plmn_id);
1452
0
            }
1453
0
            if (guamiAmfInfoItem->amf_id)
1454
0
                ogs_free(guamiAmfInfoItem->amf_id);
1455
0
        }
1456
0
        ogs_free(guamiAmfInfoItem);
1457
0
    }
1458
1459
0
    OpenAPI_list_free(guamiAmfInfoList);
1460
1461
0
    TaiList = AmfInfo->tai_list;
1462
0
    OpenAPI_list_for_each(TaiList, node) {
1463
0
        TaiItem = node->data;
1464
0
        ogs_assert(TaiItem);
1465
0
        if (TaiItem->plmn_id)
1466
0
            ogs_sbi_free_plmn_id(TaiItem->plmn_id);
1467
0
        if (TaiItem->tac)
1468
0
            ogs_free(TaiItem->tac);
1469
0
        ogs_free(TaiItem);
1470
0
    }
1471
0
    OpenAPI_list_free(TaiList);
1472
1473
0
    TaiRangeList = AmfInfo->tai_range_list;
1474
0
    OpenAPI_list_for_each(TaiRangeList, node) {
1475
0
        TaiRangeItem = node->data;
1476
0
        ogs_assert(TaiRangeItem);
1477
1478
0
        if (TaiRangeItem->plmn_id)
1479
0
            ogs_sbi_free_plmn_id(TaiRangeItem->plmn_id);
1480
1481
0
        TacRangeList = TaiRangeItem->tac_range_list;
1482
0
        OpenAPI_list_for_each(TacRangeList, node2) {
1483
0
            TacRangeItem = node2->data;
1484
0
            ogs_assert(TacRangeItem);
1485
0
            if (TacRangeItem->start)
1486
0
                ogs_free(TacRangeItem->start);
1487
0
            if (TacRangeItem->end)
1488
0
                ogs_free(TacRangeItem->end);
1489
1490
0
            ogs_free(TacRangeItem);
1491
0
        }
1492
0
        OpenAPI_list_free(TacRangeList);
1493
1494
0
        ogs_free(TaiRangeItem);
1495
0
    }
1496
0
    OpenAPI_list_free(TaiRangeList);
1497
1498
0
    ogs_free(AmfInfo);
1499
0
}
1500
1501
static void free_scp_info(OpenAPI_scp_info_t *ScpInfo)
1502
0
{
1503
0
    OpenAPI_map_t *PortMap = NULL;
1504
0
    OpenAPI_lnode_t *node = NULL, *node2 = NULL;
1505
1506
0
    OpenAPI_map_t *DomainInfoMap = NULL;
1507
0
    OpenAPI_scp_domain_info_t *DomainInfo = NULL;
1508
1509
0
    ogs_assert(ScpInfo);
1510
1511
0
    OpenAPI_list_for_each(ScpInfo->scp_ports, node) {
1512
0
        PortMap = node->data;
1513
0
        if (PortMap) {
1514
0
            ogs_free(PortMap->value);
1515
0
            OpenAPI_map_free(PortMap);
1516
0
        }
1517
0
    }
1518
0
    OpenAPI_list_free(ScpInfo->scp_ports);
1519
1520
0
    OpenAPI_list_for_each(ScpInfo->scp_domain_info_list, node) {
1521
0
        DomainInfoMap = node->data;
1522
0
        if (DomainInfoMap) {
1523
0
            DomainInfo = DomainInfoMap->value;
1524
0
            if (DomainInfo) {
1525
0
                OpenAPI_list_for_each(DomainInfo->scp_ports, node2) {
1526
0
                    PortMap = node2->data;
1527
0
                    if (PortMap) {
1528
0
                        ogs_free(PortMap->value);
1529
0
                        OpenAPI_map_free(PortMap);
1530
0
                    }
1531
0
                }
1532
0
                OpenAPI_list_free(DomainInfo->scp_ports);
1533
0
                ogs_free(DomainInfo);
1534
0
            }
1535
0
            OpenAPI_map_free(DomainInfoMap);
1536
0
        }
1537
0
    }
1538
0
    OpenAPI_list_free(ScpInfo->scp_domain_info_list);
1539
1540
0
    ogs_free(ScpInfo);
1541
0
}
1542
1543
static void free_sepp_info(OpenAPI_sepp_info_t *SeppInfo)
1544
0
{
1545
0
    OpenAPI_map_t *PortMap = NULL;
1546
0
    OpenAPI_lnode_t *node = NULL;
1547
1548
0
    ogs_assert(SeppInfo);
1549
1550
0
    OpenAPI_list_for_each(SeppInfo->sepp_ports, node) {
1551
0
        PortMap = node->data;
1552
0
        if (PortMap) {
1553
0
            ogs_free(PortMap->value);
1554
0
            OpenAPI_map_free(PortMap);
1555
0
        }
1556
0
    }
1557
0
    OpenAPI_list_free(SeppInfo->sepp_ports);
1558
1559
0
    ogs_free(SeppInfo);
1560
0
}
1561
1562
ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void)
1563
0
{
1564
0
    ogs_sbi_nf_instance_t *nf_instance = NULL;
1565
1566
0
    ogs_sbi_message_t message;
1567
0
    ogs_sbi_request_t *request = NULL;
1568
1569
0
    OpenAPI_list_t *PatchItemList = NULL;
1570
0
    OpenAPI_patch_item_t StatusItem;
1571
0
    OpenAPI_patch_item_t LoadItem;
1572
1573
0
    nf_instance = ogs_sbi_self()->nf_instance;
1574
0
    ogs_assert(nf_instance);
1575
0
    ogs_assert(nf_instance->id);
1576
1577
0
    memset(&StatusItem, 0, sizeof(StatusItem));
1578
0
    memset(&LoadItem, 0, sizeof(LoadItem));
1579
1580
0
    memset(&message, 0, sizeof(message));
1581
0
    message.h.method = (char *)OGS_SBI_HTTP_METHOD_PATCH;
1582
0
    message.h.service.name =
1583
0
        OpenAPI_service_name_ToString(OpenAPI_service_name_nnrf_nfm);
1584
0
    message.h.api.version = (char *)OGS_SBI_API_V1;
1585
0
    message.h.resource.component[0] =
1586
0
        (char *)OGS_SBI_RESOURCE_NAME_NF_INSTANCES;
1587
0
    message.h.resource.component[1] = nf_instance->id;
1588
1589
0
    message.http.content_type = (char *)OGS_SBI_CONTENT_PATCH_TYPE;
1590
1591
0
    PatchItemList = OpenAPI_list_create();
1592
0
    if (!PatchItemList) {
1593
0
        ogs_error("No PatchItemList");
1594
0
        goto end;
1595
0
    }
1596
1597
0
    StatusItem.op = OpenAPI_patch_operation_replace;
1598
0
    StatusItem.path = (char *)OGS_SBI_PATCH_PATH_NF_STATUS;
1599
0
    StatusItem.value = OpenAPI_any_type_create_string(
1600
0
        OpenAPI_nf_status_ToString(OpenAPI_nf_status_REGISTERED));
1601
0
    if (!StatusItem.value) {
1602
0
        ogs_error("No status item.value");
1603
0
        goto end;
1604
0
    }
1605
1606
0
    OpenAPI_list_add(PatchItemList, &StatusItem);
1607
1608
0
    LoadItem.op = OpenAPI_patch_operation_replace;
1609
0
    LoadItem.path = (char *)OGS_SBI_PATCH_PATH_LOAD;
1610
0
    LoadItem.value = OpenAPI_any_type_create_number(nf_instance->load);
1611
0
    if (!LoadItem.value) {
1612
0
        ogs_error("No load item.value");
1613
0
        goto end;
1614
0
    }
1615
1616
0
    OpenAPI_list_add(PatchItemList, &LoadItem);
1617
1618
0
    message.PatchItemList = PatchItemList;
1619
1620
0
    request = ogs_sbi_build_request(&message);
1621
0
    ogs_expect(request);
1622
1623
0
end:
1624
0
    if (LoadItem.value)
1625
0
        OpenAPI_any_type_free(LoadItem.value);
1626
0
    if (StatusItem.value)
1627
0
        OpenAPI_any_type_free(StatusItem.value);
1628
0
    if (PatchItemList)
1629
0
        OpenAPI_list_free(PatchItemList);
1630
1631
0
    return request;
1632
0
}
1633
1634
ogs_sbi_request_t *ogs_nnrf_nfm_build_de_register(void)
1635
0
{
1636
0
    ogs_sbi_nf_instance_t *nf_instance = NULL;
1637
1638
0
    ogs_sbi_message_t message;
1639
0
    ogs_sbi_request_t *request = NULL;
1640
1641
0
    nf_instance = ogs_sbi_self()->nf_instance;
1642
0
    ogs_assert(nf_instance);
1643
0
    ogs_assert(nf_instance->id);
1644
1645
0
    memset(&message, 0, sizeof(message));
1646
0
    message.h.method = (char *)OGS_SBI_HTTP_METHOD_DELETE;
1647
0
    message.h.service.name =
1648
0
        OpenAPI_service_name_ToString(OpenAPI_service_name_nnrf_nfm);
1649
0
    message.h.api.version = (char *)OGS_SBI_API_V1;
1650
0
    message.h.resource.component[0] =
1651
0
        (char *)OGS_SBI_RESOURCE_NAME_NF_INSTANCES;
1652
0
    message.h.resource.component[1] = nf_instance->id;
1653
1654
0
    request = ogs_sbi_build_request(&message);
1655
0
    ogs_expect(request);
1656
1657
0
    return request;
1658
0
}
1659
1660
ogs_sbi_request_t *ogs_nnrf_nfm_build_status_subscribe(
1661
        ogs_sbi_subscription_data_t *subscription_data)
1662
0
{
1663
0
    ogs_sbi_message_t message;
1664
0
    ogs_sbi_header_t header;
1665
0
    ogs_sbi_request_t *request = NULL;
1666
0
    ogs_sbi_server_t *server = NULL;
1667
1668
0
    OpenAPI_subscription_data_t *SubscriptionData = NULL;
1669
0
    OpenAPI_subscr_cond_t SubscrCond;
1670
1671
0
    ogs_assert(subscription_data);
1672
0
    ogs_assert(subscription_data->req_nf_type);
1673
1674
    /* Issue #2630 : The format of subscrCond is invalid. Must be 'oneOf'. */
1675
0
    ogs_assert(!subscription_data->subscr_cond.nf_type ||
1676
0
            !subscription_data->subscr_cond.service_name);
1677
1678
0
    memset(&message, 0, sizeof(message));
1679
0
    message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST;
1680
0
    message.h.service.name =
1681
0
        OpenAPI_service_name_ToString(OpenAPI_service_name_nnrf_nfm);
1682
0
    message.h.api.version = (char *)OGS_SBI_API_V1;
1683
0
    message.h.resource.component[0] =
1684
0
        (char *)OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS;
1685
1686
0
    SubscriptionData = ogs_calloc(1, sizeof(*SubscriptionData));
1687
0
    if (!SubscriptionData) {
1688
0
        ogs_error("No SubscriptionData");
1689
0
        goto end;
1690
0
    }
1691
1692
0
    server = ogs_sbi_server_first();
1693
0
    if (!server) {
1694
0
        ogs_error("No server");
1695
0
        goto end;
1696
0
    }
1697
1698
0
    memset(&header, 0, sizeof(header));
1699
0
    header.service.name =
1700
0
        OpenAPI_service_name_ToString(OpenAPI_service_name_nnrf_nfm);
1701
0
    header.api.version = (char *)OGS_SBI_API_V1;
1702
0
    header.resource.component[0] =
1703
0
            (char *)OGS_SBI_RESOURCE_NAME_NF_STATUS_NOTIFY;
1704
0
    SubscriptionData->nf_status_notification_uri =
1705
0
                        ogs_sbi_server_uri(server, &header);
1706
0
    if (!SubscriptionData->nf_status_notification_uri) {
1707
0
        ogs_error("No nf_status_notification_uri");
1708
0
        goto end;
1709
0
    }
1710
1711
0
    SubscriptionData->req_nf_type = subscription_data->req_nf_type;
1712
0
    SubscriptionData->req_nf_instance_id =
1713
0
        subscription_data->req_nf_instance_id;
1714
1715
0
    OGS_SBI_FEATURES_SET(subscription_data->requester_features,
1716
0
            OGS_SBI_NNRF_NFM_SERVICE_MAP);
1717
0
    SubscriptionData->requester_features =
1718
0
        ogs_uint64_to_string(subscription_data->requester_features);
1719
0
    if (!SubscriptionData->requester_features) {
1720
0
        ogs_error("No requester_features");
1721
0
        goto end;
1722
0
    }
1723
1724
0
    memset(&SubscrCond, 0, sizeof(SubscrCond));
1725
0
    if (subscription_data->subscr_cond.nf_type) {
1726
0
        SubscrCond.nf_type = subscription_data->subscr_cond.nf_type;
1727
0
        SubscriptionData->subscr_cond = &SubscrCond;
1728
0
    } else if (subscription_data->subscr_cond.service_name) {
1729
0
        SubscrCond.service_name = subscription_data->subscr_cond.service_name;
1730
0
        SubscriptionData->subscr_cond = &SubscrCond;
1731
0
    } else {
1732
0
        ogs_fatal("SubscrCond must be 'oneOf'.");
1733
0
        ogs_assert_if_reached();
1734
0
    }
1735
1736
0
    message.SubscriptionData = SubscriptionData;
1737
1738
0
    request = ogs_sbi_build_request(&message);
1739
0
    ogs_expect(request);
1740
1741
0
end:
1742
0
    if (SubscriptionData) {
1743
0
        if (SubscriptionData->nf_status_notification_uri)
1744
0
            ogs_free(SubscriptionData->nf_status_notification_uri);
1745
0
        if (SubscriptionData->requester_features)
1746
0
            ogs_free(SubscriptionData->requester_features);
1747
0
        ogs_free(SubscriptionData);
1748
0
    }
1749
1750
0
    return request;
1751
0
}
1752
1753
ogs_sbi_request_t *ogs_nnrf_nfm_build_status_update(
1754
        ogs_sbi_subscription_data_t *subscription_data)
1755
0
{
1756
0
    ogs_sbi_message_t message;
1757
0
    ogs_sbi_request_t *request = NULL;
1758
1759
0
    OpenAPI_list_t *PatchItemList = NULL;
1760
0
    OpenAPI_patch_item_t ValidityItem;
1761
0
    char *validity_time = NULL;
1762
1763
0
    ogs_assert(subscription_data);
1764
0
    ogs_assert(subscription_data->id);
1765
1766
0
    memset(&ValidityItem, 0, sizeof(ValidityItem));
1767
1768
0
    memset(&message, 0, sizeof(message));
1769
0
    message.h.method = (char *)OGS_SBI_HTTP_METHOD_PATCH;
1770
0
    message.h.uri = subscription_data->resource_uri;
1771
1772
0
    message.http.content_type = (char *)OGS_SBI_CONTENT_PATCH_TYPE;
1773
1774
0
    PatchItemList = OpenAPI_list_create();
1775
0
    if (!PatchItemList) {
1776
0
        ogs_error("No PatchItemList");
1777
0
        goto end;
1778
0
    }
1779
1780
0
    ogs_assert(subscription_data->validity_duration);
1781
0
    validity_time = ogs_sbi_localtime_string(
1782
0
            ogs_time_now() + subscription_data->validity_duration);
1783
0
    ogs_assert(validity_time);
1784
1785
0
    ValidityItem.op = OpenAPI_patch_operation_replace;
1786
0
    ValidityItem.path = (char *)OGS_SBI_PATCH_PATH_VALIDITY_TIME;
1787
0
    ValidityItem.value = OpenAPI_any_type_create_string(validity_time);
1788
1789
0
    if (!ValidityItem.value) {
1790
0
        ogs_error("No status item.value");
1791
0
        goto end;
1792
0
    }
1793
1794
0
    OpenAPI_list_add(PatchItemList, &ValidityItem);
1795
1796
0
    message.PatchItemList = PatchItemList;
1797
1798
0
    request = ogs_sbi_build_request(&message);
1799
0
    ogs_expect(request);
1800
1801
0
end:
1802
0
    if (ValidityItem.value)
1803
0
        OpenAPI_any_type_free(ValidityItem.value);
1804
0
    if (validity_time)
1805
0
        ogs_free(validity_time);
1806
1807
0
    if (PatchItemList)
1808
0
        OpenAPI_list_free(PatchItemList);
1809
1810
0
    return request;
1811
0
}
1812
1813
ogs_sbi_request_t *ogs_nnrf_nfm_build_status_unsubscribe(
1814
        ogs_sbi_subscription_data_t *subscription_data)
1815
0
{
1816
0
    ogs_sbi_message_t message;
1817
0
    ogs_sbi_request_t *request = NULL;
1818
1819
0
    ogs_assert(subscription_data);
1820
0
    ogs_assert(subscription_data->id);
1821
1822
0
    memset(&message, 0, sizeof(message));
1823
0
    message.h.method = (char *)OGS_SBI_HTTP_METHOD_DELETE;
1824
0
    message.h.uri = subscription_data->resource_uri;
1825
1826
0
    request = ogs_sbi_build_request(&message);
1827
0
    ogs_expect(request);
1828
1829
0
    return request;
1830
0
}
1831
1832
ogs_sbi_request_t *ogs_nnrf_nfm_build_profile_retrieve(char *nf_instance_id)
1833
0
{
1834
0
    ogs_sbi_message_t message;
1835
0
    ogs_sbi_request_t *request = NULL;
1836
1837
0
    ogs_assert(nf_instance_id);
1838
1839
0
    memset(&message, 0, sizeof(message));
1840
0
    message.h.method = (char *)OGS_SBI_HTTP_METHOD_GET;
1841
0
    message.h.service.name =
1842
0
        OpenAPI_service_name_ToString(OpenAPI_service_name_nnrf_nfm);
1843
0
    message.h.api.version = (char *)OGS_SBI_API_V1;
1844
0
    message.h.resource.component[0] =
1845
0
        (char *)OGS_SBI_RESOURCE_NAME_NF_INSTANCES;
1846
0
    message.h.resource.component[1] = nf_instance_id;
1847
1848
0
    request = ogs_sbi_build_request(&message);
1849
0
    ogs_expect(request);
1850
1851
0
    return request;
1852
0
}
1853
1854
ogs_sbi_request_t *ogs_nnrf_nfm_build_nflist_retrieve(void)
1855
0
{
1856
0
    ogs_sbi_message_t message;
1857
0
    ogs_sbi_request_t *request = NULL;
1858
1859
0
    memset(&message, 0, sizeof(message));
1860
0
    message.h.method = (char *)OGS_SBI_HTTP_METHOD_GET;
1861
0
    message.h.service.name =
1862
0
        OpenAPI_service_name_ToString(OpenAPI_service_name_nnrf_nfm);
1863
0
    message.h.api.version = (char *)OGS_SBI_API_V1;
1864
0
    message.h.resource.component[0] =
1865
0
        (char *)OGS_SBI_RESOURCE_NAME_NF_INSTANCES;
1866
1867
0
    request = ogs_sbi_build_request(&message);
1868
0
    ogs_expect(request);
1869
1870
0
    return request;
1871
0
}
1872
1873
ogs_sbi_request_t *ogs_nnrf_disc_build_discover(
1874
        OpenAPI_nf_type_e target_nf_type,
1875
        OpenAPI_nf_type_e requester_nf_type,
1876
        ogs_sbi_discovery_option_t *discovery_option)
1877
0
{
1878
0
    ogs_sbi_message_t message;
1879
0
    ogs_sbi_request_t *request = NULL;
1880
1881
0
    ogs_assert(target_nf_type);
1882
0
    ogs_assert(requester_nf_type);
1883
1884
0
    memset(&message, 0, sizeof(message));
1885
0
    message.h.method = (char *)OGS_SBI_HTTP_METHOD_GET;
1886
0
    message.h.service.name =
1887
0
        OpenAPI_service_name_ToString(OpenAPI_service_name_nnrf_disc);
1888
0
    message.h.api.version = (char *)OGS_SBI_API_V1;
1889
0
    message.h.resource.component[0] =
1890
0
        (char *)OGS_SBI_RESOURCE_NAME_NF_INSTANCES;
1891
1892
0
    message.param.target_nf_type = target_nf_type;
1893
0
    message.param.requester_nf_type = requester_nf_type;
1894
1895
0
    message.param.discovery_option = discovery_option;
1896
1897
0
    request = ogs_sbi_build_request(&message);
1898
0
    ogs_expect(request);
1899
1900
0
    return request;
1901
0
}