diff --git a/README.md b/README.md index 917afcc55..143affd05 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,13 @@ If you find Open5GS useful for work, please consider supporting this Open Source If you don't understand something about Open5GS, the [https://open5gs.org/open5gs/docs/](https://open5gs.org/open5gs/docs/) is a great place to look for answers. -## Technical Discussion +## Community -Problem with Open5GS can be filed as [issues](https://github.com/open5gs/open5gs/issues) in this repository. Voice and text chat are available in Open5GS's [Discord](https://discordapp.com/) workspace. Use [this link](https://discord.gg/GreNkuc) to get started. +Problem with Open5GS can be filed as [issues](https://github.com/open5gs/open5gs/issues) in this repository. + +Other topics related to this project are happening on the [discussions](https://github.com/open5gs/open5gs/discussions). + +Voice and text chat are available in Open5GS's [Discord](https://discordapp.com/) workspace. Use [this link](https://discord.gg/GreNkuc) to get started. ## Contributing diff --git a/configs/310014.yaml.in b/configs/310014.yaml.in index e7844453d..476e7ec17 100644 --- a/configs/310014.yaml.in +++ b/configs/310014.yaml.in @@ -9,6 +9,7 @@ parameter: # no_upf: true # no_ausf: true # no_udm: true +# no_pcf: true # no_udr: true # no_mme: true # no_sgwc: true diff --git a/configs/csfb.yaml.in b/configs/csfb.yaml.in index 0e8d1a976..56a18fd24 100644 --- a/configs/csfb.yaml.in +++ b/configs/csfb.yaml.in @@ -9,6 +9,7 @@ parameter: # no_upf: true # no_ausf: true # no_udm: true +# no_pcf: true # no_udr: true # no_mme: true # no_sgwc: true @@ -97,9 +98,9 @@ sgwc: - addr: 127.0.0.3 smf: - sbi: - - addr: 127.0.0.4 - port: 7777 +# sbi: +# - addr: 127.0.0.4 +# port: 7777 gtpc: - addr: 127.0.0.4 - addr: ::1 @@ -211,12 +212,12 @@ pcrf: - identity: smf.localdomain addr: 127.0.0.4 -nrf: - sbi: - - addr: - - 127.0.0.10 - - ::1 - port: 7777 +#nrf: +# sbi: +# - addr: +# - 127.0.0.10 +# - ::1 +# port: 7777 ausf: sbi: diff --git a/configs/meson.build b/configs/meson.build index 9ab40fa23..dd7eae14f 100644 --- a/configs/meson.build +++ b/configs/meson.build @@ -38,6 +38,7 @@ example_conf = ''' 310014.yaml csfb.yaml volte.yaml + vonr.yaml minimal.yaml srslte.yaml sample.yaml diff --git a/configs/minimal.yaml.in b/configs/minimal.yaml.in index 4c5caafd0..f02d6b9e4 100644 --- a/configs/minimal.yaml.in +++ b/configs/minimal.yaml.in @@ -9,6 +9,7 @@ parameter: # no_upf: true # no_ausf: true # no_udm: true +# no_pcf: true # no_udr: true # no_mme: true # no_sgwc: true diff --git a/configs/sample.yaml.in b/configs/sample.yaml.in index a69fe8f6d..e5e721513 100644 --- a/configs/sample.yaml.in +++ b/configs/sample.yaml.in @@ -9,6 +9,7 @@ parameter: # no_upf: true # no_ausf: true # no_udm: true +# no_pcf: true # no_udr: true # no_mme: true # no_sgwc: true diff --git a/configs/srslte.yaml.in b/configs/srslte.yaml.in index c7530a808..cbf102c86 100644 --- a/configs/srslte.yaml.in +++ b/configs/srslte.yaml.in @@ -9,6 +9,7 @@ parameter: # no_upf: true # no_ausf: true # no_udm: true +# no_pcf: true # no_udr: true # no_mme: true # no_sgwc: true @@ -63,9 +64,9 @@ sgwc: - addr: 127.0.0.3 smf: - sbi: - - addr: 127.0.0.4 - port: 7777 +# sbi: +# - addr: 127.0.0.4 +# port: 7777 gtpc: - addr: 127.0.0.4 - addr: ::1 @@ -177,12 +178,12 @@ pcrf: - identity: smf.localdomain addr: 127.0.0.4 -nrf: - sbi: - - addr: - - 127.0.0.10 - - ::1 - port: 7777 +#nrf: +# sbi: +# - addr: +# - 127.0.0.10 +# - ::1 +# port: 7777 ausf: sbi: diff --git a/configs/volte.yaml.in b/configs/volte.yaml.in index 58a7532f3..d63ce15d9 100644 --- a/configs/volte.yaml.in +++ b/configs/volte.yaml.in @@ -9,6 +9,7 @@ parameter: # no_upf: true # no_ausf: true # no_udm: true +# no_pcf: true # no_udr: true # no_mme: true # no_sgwc: true @@ -63,9 +64,9 @@ sgwc: - addr: 127.0.0.3 smf: - sbi: - - addr: 127.0.0.4 - port: 7777 +# sbi: +# - addr: 127.0.0.4 +# port: 7777 gtpc: - addr: 127.0.0.4 - addr: ::1 @@ -182,12 +183,12 @@ pcrf: - identity: pcscf.localdomain addr: 127.0.0.1 -nrf: - sbi: - - addr: - - 127.0.0.10 - - ::1 - port: 7777 +#nrf: +# sbi: +# - addr: +# - 127.0.0.10 +# - ::1 +# port: 7777 ausf: sbi: diff --git a/configs/vonr.yaml.in b/configs/vonr.yaml.in new file mode 100644 index 000000000..2a2fc69e8 --- /dev/null +++ b/configs/vonr.yaml.in @@ -0,0 +1,211 @@ +db_uri: mongodb://localhost/open5gs + +logger: + +parameter: +# no_nrf: true +# no_amf: true +# no_smf: true +# no_upf: true +# no_ausf: true +# no_udm: true +# no_pcf: true +# no_udr: true +# no_mme: true +# no_sgwc: true +# no_sgwu: true +# no_pcrf: true +# no_hss: true + +mme: + freeDiameter: + identity: mme.localdomain + realm: localdomain + listen_on: 127.0.0.2 + load_extension: + - module: @freediameter_extensions_builddir@/dbg_msg_dumps.fdx + conf: 0x8888 + - module: @freediameter_extensions_builddir@/dict_rfc5777.fdx + - module: @freediameter_extensions_builddir@/dict_mip6i.fdx + - module: @freediameter_extensions_builddir@/dict_nasreq.fdx + - module: @freediameter_extensions_builddir@/dict_nas_mipv6.fdx + - module: @freediameter_extensions_builddir@/dict_dcca.fdx + - module: @freediameter_extensions_builddir@/dict_dcca_3gpp.fdx + connect: + - identity: hss.localdomain + addr: 127.0.0.8 + + s1ap: + - addr: 127.0.0.2 + gtpc: + - addr: 127.0.0.2 + gummei: + plmn_id: + mcc: 901 + mnc: 70 + mme_gid: 2 + mme_code: 1 + tai: + plmn_id: + mcc: 901 + mnc: 70 + tac: 1 + security: + integrity_order : [ EIA2, EIA1, EIA0 ] + ciphering_order : [ EEA0, EEA1, EEA2 ] + + network_name: + full: Open5GS + +sgwc: + gtpc: + - addr: 127.0.0.3 + pfcp: + - addr: 127.0.0.3 + +smf: + sbi: + - addr: 127.0.0.4 + port: 7777 + gtpc: + - addr: 127.0.0.4 + - addr: ::1 + pfcp: + - addr: 127.0.0.4 + pdn: + - addr: 10.45.0.1/16 + - addr: cafe::1/64 + dns: + - 8.8.8.8 + - 8.8.4.4 + - 2001:4860:4860::8888 + - 2001:4860:4860::8844 + p-cscf: + - 127.0.0.1 + - ::1 + mtu: 1400 + freeDiameter: + identity: smf.localdomain + realm: localdomain + listen_on: 127.0.0.4 + load_extension: + - module: @freediameter_extensions_builddir@/dbg_msg_dumps.fdx + conf: 0x8888 + - module: @freediameter_extensions_builddir@/dict_rfc5777.fdx + - module: @freediameter_extensions_builddir@/dict_mip6i.fdx + - module: @freediameter_extensions_builddir@/dict_nasreq.fdx + - module: @freediameter_extensions_builddir@/dict_nas_mipv6.fdx + - module: @freediameter_extensions_builddir@/dict_dcca.fdx + - module: @freediameter_extensions_builddir@/dict_dcca_3gpp.fdx + connect: + - identity: pcrf.localdomain + addr: 127.0.0.9 +amf: + sbi: + - addr: 127.0.0.5 + port: 7777 + ngap: + - addr: 127.0.0.5 + guami: + - plmn_id: + mcc: 901 + mnc: 70 + amf_id: + region: 2 + set: 1 + tai: + - plmn_id: + mcc: 901 + mnc: 70 + tac: 1 + plmn_support: + - plmn_id: + mcc: 901 + mnc: 70 + s_nssai: + - sst: 1 + security: + integrity_order : [ NIA2, NIA1, NIA0 ] + ciphering_order : [ NEA0, NEA1, NEA2 ] + network_name: + full: Open5GS + amf_name: open5gs-amf0 + +sgwu: + gtpu: + - addr: 127.0.0.6 + pfcp: + - addr: 127.0.0.6 + +upf: + pfcp: + - addr: 127.0.0.7 + gtpu: + - addr: 127.0.0.7 + pdn: + - addr: 10.45.0.1/16 + - addr: cafe::1/64 + +hss: + freeDiameter: + identity: hss.localdomain + realm: localdomain + listen_on: 127.0.0.8 + load_extension: + - module: @freediameter_extensions_builddir@/dbg_msg_dumps.fdx + conf: 0x8888 + - module: @freediameter_extensions_builddir@/dict_rfc5777.fdx + - module: @freediameter_extensions_builddir@/dict_mip6i.fdx + - module: @freediameter_extensions_builddir@/dict_nasreq.fdx + - module: @freediameter_extensions_builddir@/dict_nas_mipv6.fdx + - module: @freediameter_extensions_builddir@/dict_dcca.fdx + - module: @freediameter_extensions_builddir@/dict_dcca_3gpp.fdx + connect: + - identity: mme.localdomain + addr: 127.0.0.2 +pcrf: + freeDiameter: + identity: pcrf.localdomain + realm: localdomain + listen_on: 127.0.0.9 + load_extension: + - module: @freediameter_extensions_builddir@/dbg_msg_dumps.fdx + conf: 0x8888 + - module: @freediameter_extensions_builddir@/dict_rfc5777.fdx + - module: @freediameter_extensions_builddir@/dict_mip6i.fdx + - module: @freediameter_extensions_builddir@/dict_nasreq.fdx + - module: @freediameter_extensions_builddir@/dict_nas_mipv6.fdx + - module: @freediameter_extensions_builddir@/dict_dcca.fdx + - module: @freediameter_extensions_builddir@/dict_dcca_3gpp.fdx + connect: + - identity: smf.localdomain + addr: 127.0.0.4 + - identity: pcscf.localdomain + addr: 127.0.0.1 + +nrf: + sbi: + - addr: + - 127.0.0.10 + - ::1 + port: 7777 + +ausf: + sbi: + - addr: 127.0.0.11 + port: 7777 + +udm: + sbi: + - addr: 127.0.0.12 + port: 7777 + +pcf: + sbi: + - addr: 127.0.0.13 + port: 7777 + +udr: + sbi: + - addr: 127.0.0.20 + port: 7777 diff --git a/lib/asn1c/util/message.c b/lib/asn1c/util/message.c index 9756aea13..0be8ff0fc 100644 --- a/lib/asn1c/util/message.c +++ b/lib/asn1c/util/message.c @@ -41,7 +41,7 @@ ogs_pkbuf_t *ogs_asn_encode(const asn_TYPE_descriptor_t *td, void *sptr) return NULL; } - ogs_pkbuf_trim(pkbuf, (enc_ret.encoded >> 3)); + ogs_pkbuf_trim(pkbuf, ((enc_ret.encoded + 7) >> 3)); return pkbuf; } diff --git a/lib/core/ogs-3gpp-types.c b/lib/core/ogs-3gpp-types.c index 8c8265a40..bc06fff8f 100644 --- a/lib/core/ogs-3gpp-types.c +++ b/lib/core/ogs-3gpp-types.c @@ -255,7 +255,7 @@ char *ogs_s_nssai_sd_to_string(ogs_uint24_t sd) if (sd.v == OGS_S_NSSAI_NO_SD_VALUE) return NULL; - return ogs_uint24_to_string(sd); + return ogs_uint24_to_0string(sd); } ogs_uint24_t ogs_s_nssai_sd_from_string(const char *hex) @@ -472,3 +472,13 @@ char *ogs_ipv6_to_string(uint8_t *addr6) return (char *)OGS_INET6_NTOP(addr6, buf); } + +void ogs_session_data_free(ogs_session_data_t *session_data) +{ + int i; + + ogs_assert(session_data); + + for (i = 0; i < session_data->num_of_pcc_rule; i++) + OGS_PCC_RULE_FREE(&session_data->pcc_rule[i]); +} diff --git a/lib/core/ogs-3gpp-types.h b/lib/core/ogs-3gpp-types.h index 89dd2cd62..04b6e3beb 100644 --- a/lib/core/ogs-3gpp-types.h +++ b/lib/core/ogs-3gpp-types.h @@ -330,8 +330,8 @@ typedef struct ogs_pcc_rule_s { #define OGS_PCC_RULE_TYPE_REMOVE 2 uint8_t type; -#define OGS_MAX_PCC_RULE_NAME_LEN 256 - char *name; + char *id; /* 5GC */ + char *name; /* EPC */ /* Num of Flow per PCC Rule */ #define OGS_MAX_NUM_OF_FLOW 8 @@ -359,8 +359,11 @@ typedef struct ogs_pcc_rule_s { if ((__sRC)->name) { \ (__dST)->name = ogs_strdup((__sRC)->name); \ ogs_assert((__dST)->name); \ - } else \ - ogs_assert_if_reached(); \ + } \ + if ((__sRC)->id) { \ + (__dST)->id = ogs_strdup((__sRC)->id); \ + ogs_assert((__dST)->id); \ + } \ for (__iNDEX = 0; __iNDEX < (__sRC)->num_of_flow; __iNDEX++) { \ (__dST)->flow[__iNDEX].direction = (__sRC)->flow[__iNDEX].direction; \ (__dST)->flow[__iNDEX].description = \ @@ -377,6 +380,8 @@ typedef struct ogs_pcc_rule_s { do { \ int __pCCrULE_iNDEX; \ ogs_assert((__pCCrULE)); \ + if ((__pCCrULE)->id) \ + ogs_free((__pCCrULE)->id); \ if ((__pCCrULE)->name) \ ogs_free((__pCCrULE)->name); \ for (__pCCrULE_iNDEX = 0; \ @@ -507,6 +512,15 @@ typedef struct ogs_subscription_data_s { } msisdn[OGS_MAX_NUM_OF_MSISDN]; } ogs_subscription_data_t; +typedef struct ogs_session_data_s { + ogs_pdn_t pdn; +#define OGS_MAX_NUM_OF_PCC_RULE 8 /* Num of PCC Rule */ + ogs_pcc_rule_t pcc_rule[OGS_MAX_NUM_OF_PCC_RULE]; + int num_of_pcc_rule; +} ogs_session_data_t; + +void ogs_session_data_free(ogs_session_data_t *session_data); + #ifdef __cplusplus } #endif diff --git a/lib/core/ogs-conv.c b/lib/core/ogs-conv.c index bfc7af084..ef4638f9f 100644 --- a/lib/core/ogs-conv.c +++ b/lib/core/ogs-conv.c @@ -23,6 +23,10 @@ #include #endif +#if HAVE_LIMITS_H +#include +#endif + #include "ogs-core.h" void *ogs_ascii_to_hex(char *in, int in_len, void *out, int out_len) @@ -156,64 +160,73 @@ char ogs_from_hex(char ch) return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; } -char *ogs_uint24_to_string(ogs_uint24_t x) +char *ogs_uint24_to_0string(ogs_uint24_t x) { return ogs_msprintf("%06x", x.v); } -char *ogs_uint28_to_string(uint32_t x) +char *ogs_uint28_to_0string(uint32_t x) { return ogs_msprintf("%07x", x); } -char *ogs_uint32_to_string(uint32_t x) +char *ogs_uint32_to_0string(uint32_t x) { return ogs_msprintf("%08x", x); } -char *ogs_uint36_to_string(uint64_t x) +char *ogs_uint36_to_0string(uint64_t x) { return ogs_msprintf("%09llx", (long long)x); } +char *ogs_uint64_to_0string(uint64_t x) +{ + return ogs_msprintf("%016llx", (long long)x); +} + +char *ogs_uint64_to_string(uint64_t x) +{ + char *str, *p; + + str = ogs_uint64_to_0string(x); + ogs_assert(str); + + p = ogs_left_trimcharacter(str, '0'); + ogs_assert(p); + + ogs_free(str); + return ogs_strdup(p); +} + ogs_uint24_t ogs_uint24_from_string(char *str) { ogs_uint24_t x; ogs_assert(str); - ogs_ascii_to_hex(str, strlen(str), &x, 3); - return ogs_be24toh(x); + + x.v = ogs_uint64_from_string(str); + return x; } -uint32_t ogs_uint28_from_string(char *str) -{ - uint32_t x; - - ogs_assert(str); - - x = 0; - ogs_ascii_to_hex(str, strlen(str), &x, 4); - - return be32toh(x) >> 4; -} - -uint32_t ogs_uint32_from_string(char *str) -{ - uint32_t x; - - ogs_assert(str); - ogs_ascii_to_hex(str, strlen(str), &x, 4); - return be32toh(x); -} - -uint64_t ogs_uint36_from_string(char *str) +uint64_t ogs_uint64_from_string(char *str) { uint64_t x; ogs_assert(str); - x = 0; - ogs_ascii_to_hex(str, strlen(str), &x, 5); + if (strlen(str) == 0) + return 0; - return be64toh(x) >> 28; + errno = 0; + x = strtoll(str, NULL, 16); + + if ((errno == ERANGE && (x == LONG_MAX || x == LONG_MIN)) || + (errno != 0 && x == 0)) { + ogs_log_message(OGS_LOG_FATAL, ogs_errno, "strtoll()) failed [%lld]", + (long long)x); + ogs_assert_if_reached(); + } + + return x; } diff --git a/lib/core/ogs-conv.h b/lib/core/ogs-conv.h index 3a27c30d3..68b96d6b7 100644 --- a/lib/core/ogs-conv.h +++ b/lib/core/ogs-conv.h @@ -39,15 +39,15 @@ void *ogs_buffer_to_bcd(uint8_t *in, int in_len, void *out); char ogs_from_hex(char ch); -char *ogs_uint24_to_string(ogs_uint24_t x); -char *ogs_uint28_to_string(uint32_t x); -char *ogs_uint32_to_string(uint32_t x); -char *ogs_uint36_to_string(uint64_t x); +char *ogs_uint24_to_0string(ogs_uint24_t x); +char *ogs_uint28_to_0string(uint32_t x); +char *ogs_uint32_to_0string(uint32_t x); +char *ogs_uint36_to_0string(uint64_t x); +char *ogs_uint64_to_0string(uint64_t x); +char *ogs_uint64_to_string(uint64_t x); ogs_uint24_t ogs_uint24_from_string(char *str); -uint32_t ogs_uint28_from_string(char *str); -uint32_t ogs_uint32_from_string(char *str); -uint64_t ogs_uint36_from_string(char *str); +uint64_t ogs_uint64_from_string(char *str); #ifdef __cplusplus } diff --git a/lib/core/ogs-strings.c b/lib/core/ogs-strings.c index 7f66df103..5f90e4424 100644 --- a/lib/core/ogs-strings.c +++ b/lib/core/ogs-strings.c @@ -53,6 +53,10 @@ #include #endif +#if HAVE_CTYPE_H +#include +#endif + #include "ogs-core.h" int ogs_vsnprintf(char *str, size_t size, const char *format, va_list ap) @@ -254,3 +258,64 @@ char *ogs_mstrcatf(char *source, const char *message, ...) } return out; } + +char *ogs_trimwhitespace(char *str) +{ + char *end; + + if (str == NULL) { + return NULL; + } else if (*str == 0) { + return str; + } + + while (isspace((unsigned char)*str)) str++; + + end = str + strlen(str) - 1; + while(end > str && isspace((unsigned char)*end)) { + end--; + } + + *(end+1) = 0; + + return str; +} + +char *ogs_left_trimcharacter(char *str, char to_remove) +{ + if (str == NULL) { + return NULL; + } else if (*str == 0) { + return str; + } + + while(*str == to_remove) str++; + + return str; +} + +char *ogs_right_trimcharacter(char *str, char to_remove) +{ + char *end; + + if (str == NULL) { + return NULL; + } else if (*str == 0) { + return str; + } + + end = str + strlen(str) - 1; + while(end > str && (*end == to_remove)) { + end--; + } + + *(end+1) = 0; + + return str; +} + +char *ogs_trimcharacter(char *str, char to_remove) +{ + return ogs_right_trimcharacter( + ogs_left_trimcharacter(str, to_remove), to_remove); +} diff --git a/lib/core/ogs-strings.h b/lib/core/ogs-strings.h index 6679601d3..211e3dcd8 100644 --- a/lib/core/ogs-strings.h +++ b/lib/core/ogs-strings.h @@ -96,6 +96,12 @@ char *ogs_msprintf(const char *message, ...) char *ogs_mstrcatf(char *source, const char *message, ...) OGS_GNUC_PRINTF(2, 3); +char *ogs_trimwhitespace(char *str); + +char *ogs_left_trimcharacter(char *str, char to_remove); +char *ogs_right_trimcharacter(char *str, char to_remove); +char *ogs_trimcharacter(char *str, char to_remove); + #ifdef __cplusplus } #endif diff --git a/lib/dbi/meson.build b/lib/dbi/meson.build index 3ddb18516..c430d59df 100644 --- a/lib/dbi/meson.build +++ b/lib/dbi/meson.build @@ -22,6 +22,7 @@ libdbi_sources = files(''' ogs-mongoc.c subscription.c + session.c '''.split()) libmongoc_dep = dependency('libmongoc-1.0') diff --git a/lib/dbi/ogs-dbi.h b/lib/dbi/ogs-dbi.h index 1b1f30e52..42a681554 100644 --- a/lib/dbi/ogs-dbi.h +++ b/lib/dbi/ogs-dbi.h @@ -27,6 +27,7 @@ #include "dbi/ogs-mongoc.h" #include "dbi/subscription.h" +#include "dbi/session.h" #undef OGS_DBI_INSIDE diff --git a/lib/dbi/session.c b/lib/dbi/session.c new file mode 100644 index 000000000..02cb689d2 --- /dev/null +++ b/lib/dbi/session.c @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2019 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 "ogs-dbi.h" + +int ogs_dbi_session_data(char *supi, char *dnn, + ogs_session_data_t *session_data) +{ + int rv = OGS_OK; + mongoc_cursor_t *cursor = NULL; + bson_t *query = NULL; + bson_t *opts = NULL; + bson_error_t error; + const bson_t *document; + bson_iter_t iter; + bson_iter_t child1_iter, child2_iter, child3_iter; + bson_iter_t child4_iter, child5_iter, child6_iter; + const char *utf8 = NULL; + uint32_t length = 0; + + char *supi_type = NULL; + char *supi_id = NULL; + + ogs_session_data_t zero_data; + + ogs_assert(supi); + ogs_assert(dnn); + ogs_assert(session_data); + + memset(&zero_data, 0, sizeof(zero_data)); + + /* session_data should be initialized to zero */ + ogs_assert(memcmp(session_data, &zero_data, sizeof(zero_data)) == 0); + + supi_type = ogs_id_get_type(supi); + ogs_assert(supi_type); + supi_id = ogs_id_get_value(supi); + ogs_assert(supi_id); + + query = BCON_NEW( + supi_type, BCON_UTF8(supi_id), + "pdn.apn", BCON_UTF8(dnn)); +#if MONGOC_MAJOR_VERSION >= 1 && MONGOC_MINOR_VERSION >= 5 + opts = BCON_NEW( + "projection", "{", + supi_type, BCON_INT64(1), + "pdn.$", BCON_INT64(1), + "}" + ); + cursor = mongoc_collection_find_with_opts( + ogs_mongoc()->collection.subscriber, query, opts, NULL); +#else + asdklfjasdf + opts = BCON_NEW( + supi_type, BCON_INT64(1), + "pdn.$", BCON_INT64(1) + ); + cursor = mongoc_collection_find(self.subscriberCollection, + MONGOC_QUERY_NONE, 0, 0, 0, query, opts, NULL); +#endif + + if (!mongoc_cursor_next(cursor, &document)) { + ogs_error("Cannot find IMSI(%s)+APN(%s) in DB", supi_id, dnn); + + rv = OGS_ERROR; + goto out; + } + + if (mongoc_cursor_error(cursor, &error)) { + ogs_error("Cursor Failure: %s", error.message); + + rv = OGS_ERROR; + goto out; + } + + if (!bson_iter_init(&iter, document)) { + ogs_error("bson_iter_init failed in this document"); + + rv = OGS_ERROR; + goto out; + } + + while (bson_iter_next(&iter)) { + const char *key = bson_iter_key(&iter); + if (!strcmp(key, "pdn") && + BSON_ITER_HOLDS_ARRAY(&iter)) { + int pdn_index = 0; + + bson_iter_recurse(&iter, &child1_iter); + while (bson_iter_next(&child1_iter)) { + const char *child1_key = bson_iter_key(&child1_iter); + ogs_pdn_t *pdn = NULL; + + ogs_assert(child1_key); + pdn_index = atoi(child1_key); + ogs_assert(pdn_index == 0); + + pdn = &session_data->pdn; + bson_iter_recurse(&child1_iter, &child2_iter); + while (bson_iter_next(&child2_iter)) { + const char *child2_key = bson_iter_key(&child2_iter); + if ((!strcmp(child2_key, "apn") || + !strcmp(child2_key, "dnn")) && + BSON_ITER_HOLDS_UTF8(&child2_iter)) { + utf8 = bson_iter_utf8(&child2_iter, &length); + ogs_cpystrn(pdn->dnn, utf8, + ogs_min(length, OGS_MAX_APN_LEN)+1); + } else if (!strcmp(child2_key, "type") && + BSON_ITER_HOLDS_INT32(&child2_iter)) { + pdn->pdn_type = bson_iter_int32(&child2_iter); + } else if (!strcmp(child2_key, "qos") && + BSON_ITER_HOLDS_DOCUMENT(&child2_iter)) { + bson_iter_recurse(&child2_iter, &child3_iter); + while (bson_iter_next(&child3_iter)) { + const char *child3_key = + bson_iter_key(&child3_iter); + if (!strcmp(child3_key, "qci") && + BSON_ITER_HOLDS_INT32(&child3_iter)) { + pdn->qos.qci = bson_iter_int32(&child3_iter); + } else if (!strcmp(child3_key, "arp") && + BSON_ITER_HOLDS_DOCUMENT(&child3_iter)) { + bson_iter_recurse(&child3_iter, &child4_iter); + while (bson_iter_next(&child4_iter)) { + const char *child4_key = + bson_iter_key(&child4_iter); + if (!strcmp(child4_key, "priority_level") && + BSON_ITER_HOLDS_INT32(&child4_iter)) { + pdn->qos.arp.priority_level = + bson_iter_int32(&child4_iter); + } else if (!strcmp(child4_key, + "pre_emption_capability") && + BSON_ITER_HOLDS_INT32(&child4_iter)) { + pdn->qos.arp.pre_emption_capability = + bson_iter_int32(&child4_iter); + } else if (!strcmp(child4_key, + "pre_emption_vulnerability") && + BSON_ITER_HOLDS_INT32(&child4_iter)) { + pdn->qos.arp.pre_emption_vulnerability = + bson_iter_int32(&child4_iter); + } + } + } + } + } else if (!strcmp(child2_key, "ambr") && + BSON_ITER_HOLDS_DOCUMENT(&child2_iter)) { + bson_iter_recurse(&child2_iter, &child3_iter); + while (bson_iter_next(&child3_iter)) { + const char *child3_key = + bson_iter_key(&child3_iter); + if (!strcmp(child3_key, "uplink") && + BSON_ITER_HOLDS_INT64(&child3_iter)) { + pdn->ambr.uplink = + bson_iter_int64(&child3_iter) * 1024; + } else if (!strcmp(child3_key, "downlink") && + BSON_ITER_HOLDS_INT64(&child3_iter)) { + pdn->ambr.downlink = + bson_iter_int64(&child3_iter) * 1024; + } + } + } else if (!strcmp(child2_key, "pcc_rule") && + BSON_ITER_HOLDS_ARRAY(&child2_iter)) { + int pcc_rule_index = 0; + + bson_iter_recurse(&child2_iter, &child3_iter); + while (bson_iter_next(&child3_iter)) { + const char *child3_key = + bson_iter_key(&child3_iter); + ogs_pcc_rule_t *pcc_rule = NULL; + + ogs_assert(child3_key); + pcc_rule_index = atoi(child3_key); + ogs_assert(pcc_rule_index < + OGS_MAX_NUM_OF_PCC_RULE); + + pcc_rule = &session_data->pcc_rule[pcc_rule_index]; + bson_iter_recurse(&child3_iter, &child4_iter); + while (bson_iter_next(&child4_iter)) { + const char *child4_key = + bson_iter_key(&child4_iter); + + if (!strcmp(child4_key, "qos") && + BSON_ITER_HOLDS_DOCUMENT(&child4_iter)) { + bson_iter_recurse( + &child4_iter, &child5_iter); + while (bson_iter_next(&child5_iter)) { + const char *child5_key = + bson_iter_key(&child5_iter); + if (!strcmp(child5_key, "qci") && + BSON_ITER_HOLDS_INT32( + &child5_iter)) { + pcc_rule->qos.qci = + bson_iter_int32(&child5_iter); + } else if (!strcmp(child5_key, "arp") && + BSON_ITER_HOLDS_DOCUMENT( + &child5_iter)) { + bson_iter_recurse( + &child5_iter, &child6_iter); + while (bson_iter_next( + &child6_iter)) { + const char *child6_key = + bson_iter_key(&child6_iter); + if (!strcmp(child6_key, + "priority_level") && + BSON_ITER_HOLDS_INT32( + &child6_iter)) { + pcc_rule->qos.arp. + priority_level = + bson_iter_int32( + &child6_iter); + } else if (!strcmp(child6_key, + "pre_emption_capability") && + BSON_ITER_HOLDS_INT32( + &child6_iter)) { + pcc_rule->qos.arp. + pre_emption_capability = + bson_iter_int32( + &child6_iter); + } else if (!strcmp(child6_key, + "pre_emption_vulnerability") + && BSON_ITER_HOLDS_INT32( + &child6_iter)) { + pcc_rule->qos.arp. + pre_emption_vulnerability = + bson_iter_int32( + &child6_iter); + } + } + } else if (!strcmp(child5_key, "mbr") && + BSON_ITER_HOLDS_DOCUMENT( + &child5_iter)) { + bson_iter_recurse( + &child5_iter, &child6_iter); + while (bson_iter_next( + &child6_iter)) { + const char *child6_key = + bson_iter_key(&child6_iter); + if (!strcmp(child6_key, + "downlink") && + BSON_ITER_HOLDS_INT64( + &child6_iter)) { + pcc_rule->qos.mbr.downlink = + bson_iter_int64( + &child6_iter) * 1024; + } else if (!strcmp(child6_key, + "uplink") && + BSON_ITER_HOLDS_INT64( + &child6_iter)) { + pcc_rule->qos.mbr.uplink = + bson_iter_int64( + &child6_iter) * 1024; + } + } + } else if (!strcmp(child5_key, "gbr") && + BSON_ITER_HOLDS_DOCUMENT( + &child5_iter)) { + bson_iter_recurse(&child5_iter, + &child6_iter); + while (bson_iter_next( + &child6_iter)) { + const char *child6_key = + bson_iter_key(&child6_iter); + if (!strcmp(child6_key, + "downlink") && + BSON_ITER_HOLDS_INT64( + &child6_iter)) { + pcc_rule->qos.gbr.downlink = + bson_iter_int64( + &child6_iter) * 1024; + } else if (!strcmp(child6_key, + "uplink") && + BSON_ITER_HOLDS_INT64( + &child6_iter)) { + pcc_rule->qos.gbr.uplink = + bson_iter_int64( + &child6_iter) * 1024; + } + } + } + } + } else if (!strcmp(child4_key, "flow") && + BSON_ITER_HOLDS_ARRAY(&child4_iter)) { + int flow_index = 0; + + bson_iter_recurse(&child4_iter, + &child5_iter); + while (bson_iter_next(&child5_iter)) { + const char *child5_key = + bson_iter_key(&child5_iter); + ogs_flow_t *flow = NULL; + + ogs_assert(child5_key); + flow_index = atoi(child5_key); + ogs_assert( + flow_index < OGS_MAX_NUM_OF_FLOW); + + flow = &pcc_rule->flow[flow_index]; + bson_iter_recurse( + &child5_iter, &child6_iter); + while (bson_iter_next(&child6_iter)) { + const char *child6_key = + bson_iter_key(&child6_iter); + if (!strcmp(child6_key, + "direction") && + BSON_ITER_HOLDS_INT32( + &child6_iter)) { + flow->direction = + bson_iter_int32( + &child6_iter); + } else if (!strcmp(child6_key, + "description") && + BSON_ITER_HOLDS_UTF8( + &child6_iter)) { + utf8 = bson_iter_utf8( + &child6_iter, &length); + flow->description = + ogs_malloc(length+1); + ogs_cpystrn( + (char*)flow->description, + utf8, length+1); + } + } + flow_index++; + } + pcc_rule->num_of_flow = flow_index; + } + } + + /* EPC: Charing-Rule-Name */ + if (pcc_rule->name) { + ogs_error( + "PCC Rule Name has already been defined"); + ogs_free(pcc_rule->name); + } + pcc_rule->name = ogs_msprintf( + "%s%d", dnn, pcc_rule_index+1); + ogs_assert(pcc_rule->name); + + /* 5GC: PCC-Rule-Id */ + if (pcc_rule->id) { + ogs_error( + "PCC Rule Id has already been defined"); + ogs_free(pcc_rule->id); + } + pcc_rule->id = ogs_msprintf("%d", pcc_rule_index+1); + ogs_assert(pcc_rule->id); + + pcc_rule->precedence = pcc_rule_index+1; + pcc_rule->flow_status = OGS_FLOW_STATUS_ENABLED; + pcc_rule_index++; + } + session_data->num_of_pcc_rule = pcc_rule_index; + } + } + } + } + } + +out: + if (query) bson_destroy(query); + if (opts) bson_destroy(opts); + if (cursor) mongoc_cursor_destroy(cursor); + + ogs_free(supi_type); + ogs_free(supi_id); + + return rv; +} diff --git a/lib/dbi/session.h b/lib/dbi/session.h new file mode 100644 index 000000000..4ec1a31fd --- /dev/null +++ b/lib/dbi/session.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2019 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 . + */ + +#if !defined(OGS_DBI_INSIDE) && !defined(OGS_DBI_COMPILATION) +#error "This header cannot be included directly." +#endif + +#ifndef OGS_DBI_SESSION_H +#define OGS_DBI_SESSION_H + +#ifdef __cplusplus +extern "C" { +#endif + +int ogs_dbi_session_data(char *supi, char *dnn, + ogs_session_data_t *session_data); + +#ifdef __cplusplus +} +#endif + +#endif /* OGS_DBI_SESSION_H */ diff --git a/lib/diameter/common/ogs-diameter-common.h b/lib/diameter/common/ogs-diameter-common.h index 913cc3623..8863c1176 100644 --- a/lib/diameter/common/ogs-diameter-common.h +++ b/lib/diameter/common/ogs-diameter-common.h @@ -35,8 +35,6 @@ #include "ogs-core.h" -#define OGS_MAX_NUM_OF_PCC_RULE 8 /* Num of PCC Rule */ - #define OGS_DIAMETER_INSIDE #include "diameter/common/message.h" diff --git a/lib/diameter/gx/message.c b/lib/diameter/gx/message.c index f0924523f..34bfbf5df 100644 --- a/lib/diameter/gx/message.c +++ b/lib/diameter/gx/message.c @@ -157,14 +157,3 @@ int ogs_diam_gx_init(void) return 0; } - -void ogs_diam_gx_message_free(ogs_diam_gx_message_t *gx_message) -{ - int i; - - ogs_assert(gx_message); - - for (i = 0; i < gx_message->num_of_pcc_rule; i++) { - OGS_PCC_RULE_FREE(&gx_message->pcc_rule[i]); - } -} diff --git a/lib/diameter/gx/message.h b/lib/diameter/gx/message.h index 207159d5e..3837a0668 100644 --- a/lib/diameter/gx/message.h +++ b/lib/diameter/gx/message.h @@ -155,13 +155,10 @@ typedef struct ogs_diam_gx_message_s { #define OGS_DIAM_GX_CC_REQUEST_TYPE_EVENT_REQUEST 4 uint32_t cc_request_type; - ogs_pdn_t pdn; - ogs_pcc_rule_t pcc_rule[OGS_MAX_NUM_OF_PCC_RULE]; - int num_of_pcc_rule; + ogs_session_data_t session_data; } ogs_diam_gx_message_t; int ogs_diam_gx_init(void); -void ogs_diam_gx_message_free(ogs_diam_gx_message_t *gx_message); #ifdef __cplusplus } diff --git a/lib/gtp/ogs-gtp.h b/lib/gtp/ogs-gtp.h index ebc866c5d..d04c0bc40 100644 --- a/lib/gtp/ogs-gtp.h +++ b/lib/gtp/ogs-gtp.h @@ -21,6 +21,7 @@ #define OGS_GTP_H #include "ogs-core.h" +#include "ipfw/ogs-ipfw.h" #include "ogs-app.h" #define OGS_GTPV1_U_UDP_PORT 2152 diff --git a/lib/gtp/types.c b/lib/gtp/types.c index a369884af..73148cb59 100644 --- a/lib/gtp/types.c +++ b/lib/gtp/types.c @@ -318,121 +318,125 @@ int16_t ogs_gtp_parse_tft(ogs_gtp_tft_t *tft, ogs_tlv_octet_t *octet) sizeof(tft->pf[i].precedence)); size += sizeof(tft->pf[i].precedence); - ogs_assert(size+sizeof(tft->pf[i].length) <= octet->len); - memcpy(&tft->pf[i].length, (unsigned char *)octet->data+size, - sizeof(tft->pf[i].length)); - size += sizeof(tft->pf[i].length); + ogs_assert(size+sizeof(tft->pf[i].content.length) <= octet->len); + memcpy(&tft->pf[i].content.length, (unsigned char *)octet->data+size, + sizeof(tft->pf[i].content.length)); + size += sizeof(tft->pf[i].content.length); j = 0; len = 0; - while(len < tft->pf[i].length) { - ogs_assert(size+len+sizeof(tft->pf[i].component[j].type) <= + while(len < tft->pf[i].content.length) { + ogs_assert(size+len+sizeof(tft->pf[i].content.component[j].type) <= octet->len); - memcpy(&tft->pf[i].component[j].type, + memcpy(&tft->pf[i].content.component[j].type, (unsigned char *)octet->data+size+len, - sizeof(tft->pf[i].component[j].type)); - len += sizeof(tft->pf[i].component[j].type); - switch(tft->pf[i].component[j].type) { - case GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE: - ogs_assert(size+len+sizeof(tft->pf[i].component[j].proto) <= - octet->len); - memcpy(&tft->pf[i].component[j].proto, + sizeof(tft->pf[i].content.component[j].type)); + len += sizeof(tft->pf[i].content.component[j].type); + switch(tft->pf[i].content.component[j].type) { + case OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE: + ogs_assert(size+len+ + sizeof(tft->pf[i].content.component[j].proto) <= + octet->len); + memcpy(&tft->pf[i].content.component[j].proto, (unsigned char *)octet->data+size+len, - sizeof(tft->pf[i].component[j].proto)); - len += sizeof(tft->pf[i].component[j].proto); + sizeof(tft->pf[i].content.component[j].proto)); + len += sizeof(tft->pf[i].content.component[j].proto); break; - case GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE: - case GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE: ogs_assert(size+len+ - sizeof(tft->pf[i].component[j].ipv4.addr) <= octet->len); - memcpy(&tft->pf[i].component[j].ipv4.addr, + sizeof(tft->pf[i].content.component[j].ipv4.addr) <= + octet->len); + memcpy(&tft->pf[i].content.component[j].ipv4.addr, (unsigned char *)octet->data+size+len, - sizeof(tft->pf[i].component[j].ipv4.addr)); - len += sizeof(tft->pf[i].component[j].ipv4.addr); + sizeof(tft->pf[i].content.component[j].ipv4.addr)); + len += sizeof(tft->pf[i].content.component[j].ipv4.addr); ogs_assert(size+len+ - sizeof(tft->pf[i].component[j].ipv4.mask) <= octet->len); - memcpy(&tft->pf[i].component[j].ipv4.mask, + sizeof(tft->pf[i].content.component[j].ipv4.mask) <= + octet->len); + memcpy(&tft->pf[i].content.component[j].ipv4.mask, (unsigned char *)octet->data+size+len, - sizeof(tft->pf[i].component[j].ipv4.mask)); - len += sizeof(tft->pf[i].component[j].ipv4.mask); + sizeof(tft->pf[i].content.component[j].ipv4.mask)); + len += sizeof(tft->pf[i].content.component[j].ipv4.mask); break; - case GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE: - case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE: + case OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE: + case OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE: ogs_assert(size+len+ - sizeof(tft->pf[i].component[j].ipv6.addr) <= octet->len); - memcpy(&tft->pf[i].component[j].ipv6.addr, + sizeof(tft->pf[i].content.component[j].ipv6.addr) <= + octet->len); + memcpy(&tft->pf[i].content.component[j].ipv6.addr, (unsigned char *)octet->data+size+len, - sizeof(tft->pf[i].component[j].ipv6.addr)); - len += sizeof(tft->pf[i].component[j].ipv6.addr); + sizeof(tft->pf[i].content.component[j].ipv6.addr)); + len += sizeof(tft->pf[i].content.component[j].ipv6.addr); ogs_assert(size+len+ - sizeof(tft->pf[i].component[j].ipv6.prefixlen) <= + sizeof(tft->pf[i].content.component[j].ipv6.prefixlen) <= octet->len); - memcpy(&tft->pf[i].component[j].ipv6.prefixlen, + memcpy(&tft->pf[i].content.component[j].ipv6.prefixlen, (unsigned char *)octet->data+size+len, - sizeof(tft->pf[i].component[j].ipv6.prefixlen)); - len += sizeof(tft->pf[i].component[j].ipv6.prefixlen); + sizeof(tft->pf[i].content.component[j].ipv6.prefixlen)); + len += sizeof(tft->pf[i].content.component[j].ipv6.prefixlen); break; - case GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE: - case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE: ogs_assert(size+len+ - sizeof(tft->pf[i].component[j].ipv6_mask.addr) <= + sizeof(tft->pf[i].content.component[j].ipv6_mask.addr) <= octet->len); - memcpy(&tft->pf[i].component[j].ipv6_mask.addr, + memcpy(&tft->pf[i].content.component[j].ipv6_mask.addr, (unsigned char *)octet->data+size+len, - sizeof(tft->pf[i].component[j].ipv6_mask.addr)); - len += sizeof(tft->pf[i].component[j].ipv6_mask.addr); + sizeof(tft->pf[i].content.component[j].ipv6_mask.addr)); + len += sizeof(tft->pf[i].content.component[j].ipv6_mask.addr); ogs_assert(size+len+ - sizeof(tft->pf[i].component[j].ipv6_mask.mask) <= + sizeof(tft->pf[i].content.component[j].ipv6_mask.mask) <= octet->len); - memcpy(&tft->pf[i].component[j].ipv6_mask.mask, + memcpy(&tft->pf[i].content.component[j].ipv6_mask.mask, (unsigned char *)octet->data+size+len, - sizeof(tft->pf[i].component[j].ipv6_mask.mask)); - len += sizeof(tft->pf[i].component[j].ipv6_mask.mask); + sizeof(tft->pf[i].content.component[j].ipv6_mask.mask)); + len += sizeof(tft->pf[i].content.component[j].ipv6_mask.mask); break; - case GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE: - case GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE: + case OGS_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE: + case OGS_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE: ogs_assert(size+len+ - sizeof(tft->pf[i].component[j].port.low) <= + sizeof(tft->pf[i].content.component[j].port.low) <= octet->len); - memcpy(&tft->pf[i].component[j].port.low, + memcpy(&tft->pf[i].content.component[j].port.low, (unsigned char *)octet->data+size+len, - sizeof(tft->pf[i].component[j].port.low)); - tft->pf[i].component[j].port.low = - htobe16(tft->pf[i].component[j].port.low); - len += sizeof(tft->pf[i].component[j].port.low); + sizeof(tft->pf[i].content.component[j].port.low)); + tft->pf[i].content.component[j].port.low = + htobe16(tft->pf[i].content.component[j].port.low); + len += sizeof(tft->pf[i].content.component[j].port.low); break; - case GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE: - case GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE: + case OGS_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE: + case OGS_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE: ogs_assert(size+len+ - sizeof(tft->pf[i].component[j].port.low) <= + sizeof(tft->pf[i].content.component[j].port.low) <= octet->len); - memcpy(&tft->pf[i].component[j].port.low, + memcpy(&tft->pf[i].content.component[j].port.low, (unsigned char *)octet->data+size+len, - sizeof(tft->pf[i].component[j].port.low)); - tft->pf[i].component[j].port.low = - htobe16(tft->pf[i].component[j].port.low); - len += sizeof(tft->pf[i].component[j].port.low); + sizeof(tft->pf[i].content.component[j].port.low)); + tft->pf[i].content.component[j].port.low = + htobe16(tft->pf[i].content.component[j].port.low); + len += sizeof(tft->pf[i].content.component[j].port.low); ogs_assert(size+len+ - sizeof(tft->pf[i].component[j].port.high) <= + sizeof(tft->pf[i].content.component[j].port.high) <= octet->len); - memcpy(&tft->pf[i].component[j].port.high, + memcpy(&tft->pf[i].content.component[j].port.high, (unsigned char *)octet->data+size+len, - sizeof(tft->pf[i].component[j].port.high)); - tft->pf[i].component[j].port.high = - htobe16(tft->pf[i].component[j].port.high); - len += sizeof(tft->pf[i].component[j].port.high); + sizeof(tft->pf[i].content.component[j].port.high)); + tft->pf[i].content.component[j].port.high = + htobe16(tft->pf[i].content.component[j].port.high); + len += sizeof(tft->pf[i].content.component[j].port.high); break; default: ogs_error("Unknown Packet Filter Type(%d)", - tft->pf[i].component[j].type); + tft->pf[i].content.component[j].type); return -1; } j++; } - tft->pf[i].num_of_component = j; + tft->pf[i].content.num_of_component = j; size += len; } @@ -480,118 +484,124 @@ int16_t ogs_gtp_build_tft( sizeof(target.pf[i].precedence)); size += sizeof(target.pf[i].precedence); - ogs_assert(size + sizeof(target.pf[i].length) <= data_len); - memcpy((unsigned char *)octet->data + size, &target.pf[i].length, - sizeof(target.pf[i].length)); - size += sizeof(target.pf[i].length); + ogs_assert(size + sizeof(target.pf[i].content.length) <= data_len); + memcpy((unsigned char *)octet->data + size, + &target.pf[i].content.length, + sizeof(target.pf[i].content.length)); + size += sizeof(target.pf[i].content.length); - for (j = 0; j < target.pf[i].num_of_component; j++) { + for (j = 0; j < target.pf[i].content.num_of_component; j++) { ogs_assert(size + - sizeof(target.pf[i].component[j].type) <= data_len); + sizeof(target.pf[i].content.component[j].type) <= data_len); memcpy((unsigned char *)octet->data + size, - &target.pf[i].component[j].type, - sizeof(target.pf[i].component[j].type)); - size += sizeof(target.pf[i].component[j].type); - switch(target.pf[i].component[j].type) { - case GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE: - ogs_assert(size + - sizeof(target.pf[i].component[j].proto) <= data_len); + &target.pf[i].content.component[j].type, + sizeof(target.pf[i].content.component[j].type)); + size += sizeof(target.pf[i].content.component[j].type); + switch(target.pf[i].content.component[j].type) { + case OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE: + ogs_assert(size + sizeof( + target.pf[i].content.component[j].proto) <= data_len); memcpy((unsigned char *)octet->data + size, - &target.pf[i].component[j].proto, - sizeof(target.pf[i].component[j].proto)); - size += sizeof(target.pf[i].component[j].proto); + &target.pf[i].content.component[j].proto, + sizeof(target.pf[i].content.component[j].proto)); + size += sizeof(target.pf[i].content.component[j].proto); break; - case GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE: - case GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE: ogs_assert(size + - sizeof(target.pf[i].component[j].ipv4.addr) + sizeof(target.pf[i].content.component[j].ipv4.addr) <= data_len); memcpy((unsigned char *)octet->data + size, - &target.pf[i].component[j].ipv4.addr, - sizeof(target.pf[i].component[j].ipv4.addr)); - size += sizeof(target.pf[i].component[j].ipv4.addr); + &target.pf[i].content.component[j].ipv4.addr, + sizeof(target.pf[i].content.component[j].ipv4.addr)); + size += sizeof(target.pf[i].content.component[j].ipv4.addr); ogs_assert(size + - sizeof(target.pf[i].component[j].ipv4.mask) + sizeof(target.pf[i].content.component[j].ipv4.mask) <= data_len); memcpy((unsigned char *)octet->data + size, - &target.pf[i].component[j].ipv4.mask, - sizeof(target.pf[i].component[j].ipv4.mask)); - size += sizeof(target.pf[i].component[j].ipv4.mask); + &target.pf[i].content.component[j].ipv4.mask, + sizeof(target.pf[i].content.component[j].ipv4.mask)); + size += sizeof(target.pf[i].content.component[j].ipv4.mask); break; - case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE: - case GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE: + case OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE: + case OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE: ogs_assert(size + - sizeof(target.pf[i].component[j].ipv6.addr) + sizeof(target.pf[i].content.component[j].ipv6.addr) <= data_len); memcpy((unsigned char *)octet->data + size, - &target.pf[i].component[j].ipv6.addr, - sizeof(target.pf[i].component[j].ipv6.addr)); - size += sizeof(target.pf[i].component[j].ipv6.addr); + &target.pf[i].content.component[j].ipv6.addr, + sizeof(target.pf[i].content.component[j].ipv6.addr)); + size += sizeof(target.pf[i].content.component[j].ipv6.addr); ogs_assert(size + - sizeof(target.pf[i].component[j].ipv6.prefixlen) + sizeof(target.pf[i].content.component[j].ipv6.prefixlen) <= data_len); memcpy((unsigned char *)octet->data + size, - &target.pf[i].component[j].ipv6.prefixlen, - sizeof(target.pf[i].component[j].ipv6.prefixlen)); - size += sizeof(target.pf[i].component[j].ipv6.prefixlen); + &target.pf[i].content.component[j].ipv6.prefixlen, + sizeof(target.pf[i].content.component[j].ipv6.prefixlen)); + size += sizeof( + target.pf[i].content.component[j].ipv6.prefixlen); break; - case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE: - case GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE: ogs_assert(size + - sizeof(target.pf[i].component[j].ipv6_mask.addr) + sizeof(target.pf[i].content.component[j].ipv6_mask.addr) <= data_len); memcpy((unsigned char *)octet->data + size, - &target.pf[i].component[j].ipv6_mask.addr, - sizeof(target.pf[i].component[j].ipv6_mask.addr)); - size += sizeof(target.pf[i].component[j].ipv6_mask.addr); + &target.pf[i].content.component[j].ipv6_mask.addr, + sizeof( + target.pf[i].content.component[j].ipv6_mask.addr)); + size += sizeof( + target.pf[i].content.component[j].ipv6_mask.addr); ogs_assert(size + - sizeof(target.pf[i].component[j].ipv6_mask.mask) + sizeof(target.pf[i].content.component[j].ipv6_mask.mask) <= data_len); memcpy((unsigned char *)octet->data + size, - &target.pf[i].component[j].ipv6_mask.mask, - sizeof(target.pf[i].component[j].ipv6_mask.mask)); - size += sizeof(target.pf[i].component[j].ipv6_mask.mask); + &target.pf[i].content.component[j].ipv6_mask.mask, + sizeof( + target.pf[i].content.component[j].ipv6_mask.mask)); + size += sizeof( + target.pf[i].content.component[j].ipv6_mask.mask); break; - case GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE: - case GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE: + case OGS_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE: + case OGS_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE: ogs_assert(size + - sizeof(target.pf[i].component[j].port.low) + sizeof(target.pf[i].content.component[j].port.low) <= data_len); - target.pf[i].component[j].port.low = - htobe16(target.pf[i].component[j].port.low); + target.pf[i].content.component[j].port.low = + htobe16(target.pf[i].content.component[j].port.low); memcpy((unsigned char *)octet->data + size, - &target.pf[i].component[j].port.low, - sizeof(target.pf[i].component[j].port.low)); - size += sizeof(target.pf[i].component[j].port.low); + &target.pf[i].content.component[j].port.low, + sizeof(target.pf[i].content.component[j].port.low)); + size += sizeof(target.pf[i].content.component[j].port.low); break; - case GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE: - case GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE: + case OGS_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE: + case OGS_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE: ogs_assert(size + - sizeof(target.pf[i].component[j].port.low) + sizeof(target.pf[i].content.component[j].port.low) <= data_len); - target.pf[i].component[j].port.low = - htobe16(target.pf[i].component[j].port.low); + target.pf[i].content.component[j].port.low = + htobe16(target.pf[i].content.component[j].port.low); memcpy((unsigned char *)octet->data + size, - &target.pf[i].component[j].port.low, - sizeof(target.pf[i].component[j].port.low)); - size += sizeof(target.pf[i].component[j].port.low); + &target.pf[i].content.component[j].port.low, + sizeof(target.pf[i].content.component[j].port.low)); + size += sizeof(target.pf[i].content.component[j].port.low); ogs_assert(size + - sizeof(target.pf[i].component[j].port.high) + sizeof(target.pf[i].content.component[j].port.high) <= data_len); - target.pf[i].component[j].port.high = - htobe16(target.pf[i].component[j].port.high); + target.pf[i].content.component[j].port.high = + htobe16(target.pf[i].content.component[j].port.high); memcpy((unsigned char *)octet->data + size, - &target.pf[i].component[j].port.high, - sizeof(target.pf[i].component[j].port.high)); - size += sizeof(target.pf[i].component[j].port.high); + &target.pf[i].content.component[j].port.high, + sizeof(target.pf[i].content.component[j].port.high)); + size += sizeof(target.pf[i].content.component[j].port.high); break; default: ogs_error("Unknown Packet Filter Type(%d)", - target.pf[i].component[j].type); + target.pf[i].content.component[j].type); return -1; } } diff --git a/lib/gtp/types.h b/lib/gtp/types.h index d35b31d59..7be06d986 100644 --- a/lib/gtp/types.h +++ b/lib/gtp/types.h @@ -275,7 +275,6 @@ int16_t ogs_gtp_build_flow_qos(ogs_tlv_octet_t *octet, * See subclause 10.5.6.12 in 3GPP TS 24.008 [13]. */ #define OGS_GTP_MAX_TRAFFIC_FLOW_TEMPLATE 255 -#define OGS_GTP_MAX_NUM_OF_PACKET_FILTER_COMPONENT 16 typedef struct ogs_gtp_tft_s { union { struct { @@ -302,44 +301,7 @@ ED3(uint8_t code:3;, uint8_t flags; }; uint8_t precedence; - uint8_t length; -#define GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE 48 -#define GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE 16 -#define GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE 17 -#define GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE 32 -#define GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE 33 -#define GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE 34 -#define GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE 35 -#define GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE 64 -#define GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE 65 -#define GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE 80 -#define GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE 81 -#define GTP_PACKET_FILTER_SECURITY_PARAMETER_INDEX_TYPE 96 -#define GTP_PACKET_FILTER_TOS_TRAFFIC_CLASS_TYPE 112 -#define GTP_PACKET_FILTER_FLOW_LABEL_TYPE 128 - struct { - uint8_t type; - union { - uint8_t proto; - struct { - uint32_t addr; - uint32_t mask; - } ipv4; - struct { - uint32_t addr[4]; - uint8_t prefixlen; - } ipv6; - struct { - uint32_t addr[4]; - uint32_t mask[4]; - } ipv6_mask; - struct { - uint16_t low; - uint16_t high; - } port; - }; - } component[OGS_GTP_MAX_NUM_OF_PACKET_FILTER_COMPONENT]; - uint8_t num_of_component; + ogs_pf_content_t content; } pf[OGS_MAX_NUM_OF_PACKET_FILTER]; } ogs_gtp_tft_t; diff --git a/lib/ipfw/ogs-ipfw.c b/lib/ipfw/ogs-ipfw.c index d6d5ce3d5..ea7ff3946 100644 --- a/lib/ipfw/ogs-ipfw.c +++ b/lib/ipfw/ogs-ipfw.c @@ -365,3 +365,123 @@ void ogs_ipfw_rule_swap(ogs_ipfw_rule_t *ipfw_rule) ogs_ipfw_copy_and_swap(&dst, ipfw_rule); memcpy(ipfw_rule, &dst, sizeof(ogs_ipfw_rule_t)); } + +void ogs_pf_content_from_ipfw_rule( + uint8_t direction, ogs_pf_content_t *content, ogs_ipfw_rule_t *rule) +{ + int j, len; + + ogs_assert(content); + ogs_assert(rule); + + j = 0, len = 0; + if (rule->proto) { + content->component[j].type = + OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE; + content->component[j].proto = rule->proto; + j++; len += 2; + } + + if (rule->ipv4_src) { + if (direction == OGS_FLOW_DOWNLINK_ONLY) + content->component[j].type = + OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; + else + content->component[j].type = + OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; + content->component[j].ipv4.addr = rule->ip.src.addr[0]; + content->component[j].ipv4.mask = rule->ip.src.mask[0]; + j++; len += 9; + } + + if (rule->ipv4_dst) { + if (direction == OGS_FLOW_DOWNLINK_ONLY) + content->component[j].type = + OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; + else + content->component[j].type = + OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; + + content->component[j].ipv4.addr = rule->ip.dst.addr[0]; + content->component[j].ipv4.mask = rule->ip.dst.mask[0]; + j++; len += 9; + } + + if (rule->ipv6_src) { + if (direction == OGS_FLOW_DOWNLINK_ONLY) + content->component[j].type = + OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE; + else + content->component[j].type = + OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE; + memcpy(content->component[j].ipv6.addr, + rule->ip.src.addr, sizeof rule->ip.src.addr); + content->component[j].ipv6.prefixlen = + contigmask((uint8_t *)rule->ip.src.mask, 128); + j++; len += 18; + } + + if (rule->ipv6_dst) { + if (direction == OGS_FLOW_DOWNLINK_ONLY) + content->component[j].type = + OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE; + else + content->component[j].type = + OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE; + memcpy(content->component[j].ipv6.addr, + rule->ip.dst.addr, sizeof rule->ip.dst.addr); + content->component[j].ipv6.prefixlen = + contigmask((uint8_t *)rule->ip.dst.mask, 128); + j++; len += 18; + } + + if (rule->port.src.low) { + if (rule->port.src.low == rule->port.src.high) { + if (direction == OGS_FLOW_DOWNLINK_ONLY) + content->component[j].type = + OGS_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE; + else + content->component[j].type = + OGS_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE; + content->component[j].port.low = rule->port.src.low; + j++; len += 3; + } else { + if (direction == OGS_FLOW_DOWNLINK_ONLY) + content->component[j].type = + OGS_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE; + else + content->component[j].type = + OGS_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE; + content->component[j].port.low = rule->port.src.low; + content->component[j].port.high = rule->port.src.high; + j++; len += 5; + } + } + + if (rule->port.dst.low) { + if (rule->port.dst.low == rule->port.dst.high) { + if (direction == OGS_FLOW_DOWNLINK_ONLY) + content->component[j].type = + OGS_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE; + else + content->component[j].type = + OGS_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE; + content->component[j].port.low = rule->port.dst.low; + j++; len += 3; + } else { + if (direction == OGS_FLOW_DOWNLINK_ONLY) + content->component[j].type = + OGS_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE; + else + content->component[j].type = + OGS_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE; + content->component[j].port.low = rule->port.dst.low; + content->component[j].port.high = rule->port.dst.high; + j++; len += 5; + } + } + + content->num_of_component = j; + content->length = len; +} + diff --git a/lib/ipfw/ogs-ipfw.h b/lib/ipfw/ogs-ipfw.h index 6c98b178c..e45ec482f 100644 --- a/lib/ipfw/ogs-ipfw.h +++ b/lib/ipfw/ogs-ipfw.h @@ -86,6 +86,52 @@ ogs_ipfw_rule_t *ogs_ipfw_copy_and_swap( ogs_ipfw_rule_t *dst, ogs_ipfw_rule_t *src); void ogs_ipfw_rule_swap(ogs_ipfw_rule_t *ipfw_rule); +#define OGS_MAX_NUM_OF_PACKET_FILTER_COMPONENT 16 +typedef struct ogs_pf_content_s { + uint8_t length; +#define OGS_PACKET_FILTER_MATCH_ALL 1 +#define OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE 48 +#define OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE 16 +#define OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE 17 +#define OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE 32 +#define OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE 33 +#define OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE 34 +#define OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE 35 +#define OGS_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE 64 +#define OGS_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE 65 +#define OGS_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE 80 +#define OGS_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE 81 +#define OGS_PACKET_FILTER_SECURITY_PARAMETER_INDEX_TYPE 96 +#define OGS_PACKET_FILTER_TOS_TRAFFIC_CLASS_TYPE 112 +#define OGS_PACKET_FILTER_FLOW_LABEL_TYPE 128 + struct { + uint8_t type; + union { + uint8_t proto; + struct { + uint32_t addr; + uint32_t mask; + } ipv4; + struct { + uint32_t addr[4]; + uint8_t prefixlen; + } ipv6; + struct { + uint32_t addr[4]; + uint32_t mask[4]; + } ipv6_mask; + struct { + uint16_t low; + uint16_t high; + } port; + }; + } component[OGS_MAX_NUM_OF_PACKET_FILTER_COMPONENT]; + uint8_t num_of_component; +} ogs_pf_content_t; + +void ogs_pf_content_from_ipfw_rule( + uint8_t direction, ogs_pf_content_t *content, ogs_ipfw_rule_t *rule); + #ifdef __cplusplus } #endif diff --git a/lib/nas/5gs/ogs-nas-5gs.h b/lib/nas/5gs/ogs-nas-5gs.h index 457cd5149..afac3b909 100644 --- a/lib/nas/5gs/ogs-nas-5gs.h +++ b/lib/nas/5gs/ogs-nas-5gs.h @@ -21,6 +21,7 @@ #define OGS_NAS_5GS_H #include "ogs-nas-common.h" +#include "ipfw/ogs-ipfw.h" #define OGS_NAS_INSIDE diff --git a/lib/nas/5gs/types.c b/lib/nas/5gs/types.c index 1177ff875..365d756a2 100644 --- a/lib/nas/5gs/types.c +++ b/lib/nas/5gs/types.c @@ -246,10 +246,84 @@ int ogs_nas_parse_nssai(ogs_s_nssai_t *s_nssai, ogs_nas_nssai_t *nas_nssai) return num_of_s_nssai; } +void ogs_nas_build_qos_flow_descriptions( + ogs_nas_qos_flow_descriptions_t *flow_descriptions, + ogs_nas_qos_flow_description_t *flow_description, + int num_of_flow_description) +{ + int i, j; + char *buffer; + uint16_t length; + ogs_nas_qos_flow_description_t target; + + ogs_assert(flow_descriptions); + ogs_assert(flow_description); + ogs_assert(num_of_flow_description); + + buffer = ogs_calloc(1, OGS_NAS_MAX_QOS_FLOW_DESCRIPTIONS_LEN); + ogs_assert(buffer); + length = 0; + + for (i = 0; i < num_of_flow_description; i++) { + memcpy(&target, flow_description + i, + sizeof(ogs_nas_qos_flow_description_t)); + + ogs_assert(length + 3 <= OGS_NAS_MAX_QOS_FLOW_DESCRIPTIONS_LEN); + memcpy(buffer + length, &target, 3); + length += 3; + + for (j = 0; j < target.num_of_parameter; j++) { + ogs_assert(length + sizeof(target.param[j].identifier) <= + OGS_NAS_MAX_QOS_FLOW_DESCRIPTIONS_LEN); + memcpy(buffer + length, &target.param[j].identifier, + sizeof(target.param[j].identifier)); + length += sizeof(target.param[j].identifier); + + ogs_assert(length + sizeof(target.param[j].len) <= + OGS_NAS_MAX_QOS_FLOW_DESCRIPTIONS_LEN); + memcpy(buffer + length, &target.param[j].len, + sizeof(target.param[j].len)); + length += sizeof(target.param[j].len); + + switch(target.param[j].identifier) { + case OGS_NAX_QOS_FLOW_PARAMETER_ID_5QI: + ogs_assert(target.param[j].len == 1); + ogs_assert(length + target.param[j].len <= + OGS_NAS_MAX_QOS_FLOW_DESCRIPTIONS_LEN); + memcpy(buffer + length, &target.param[j].qci, + target.param[j].len); + length += target.param[j].len; + break; + + case OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_UPLINK: + case OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_DOWNLINK: + case OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_UPLINK: + case OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_DOWNLINK: + ogs_assert(target.param[j].len == 3); + ogs_assert(length + target.param[j].len <= + OGS_NAS_MAX_QOS_FLOW_DESCRIPTIONS_LEN); + target.param[j].br.bitrate = + htobe16(target.param[j].br.bitrate); + memcpy(buffer + length, &target.param[j].br, + target.param[j].len); + length += target.param[j].len; + break; + default: + ogs_fatal("Unknown qos_flow parameter identifier [%d]", + target.param[j].identifier); + ogs_assert_if_reached(); + } + } + } + + flow_descriptions->buffer = buffer; + flow_descriptions->length = length; +} + void ogs_nas_build_qos_rules(ogs_nas_qos_rules_t *rules, ogs_nas_qos_rule_t *rule, int num_of_rule) { - int i, j; + int i, j, k; char *buffer; uint16_t length; ogs_nas_qos_rule_t target; @@ -263,6 +337,8 @@ void ogs_nas_build_qos_rules(ogs_nas_qos_rules_t *rules, length = 0; for (i = 0; i < num_of_rule; i++) { + char *rule_length = NULL; + memcpy(&target, rule + i, sizeof(ogs_nas_qos_rule_t)); ogs_assert(length + sizeof(target.identifier) <= @@ -270,10 +346,13 @@ void ogs_nas_build_qos_rules(ogs_nas_qos_rules_t *rules, memcpy(buffer + length, &target.identifier, sizeof(target.identifier)); length += sizeof(target.identifier); + ogs_assert(length + sizeof(target.length) <= OGS_NAS_MAX_QOS_RULES_LEN); - target.length = htobe16(target.length); - memcpy(buffer + length, &target.length, sizeof(target.length)); + + /* Just store the location of the QoS rule length */ + rule_length = buffer+length; + length += sizeof(target.length); ogs_assert(length + sizeof(target.flags) <= OGS_NAS_MAX_QOS_RULES_LEN); @@ -287,126 +366,137 @@ void ogs_nas_build_qos_rules(ogs_nas_qos_rules_t *rules, sizeof(target.pf[j].flags)); length += sizeof(target.pf[j].flags); - ogs_assert(length + sizeof(target.pf[j].length) <= + ogs_assert(length + sizeof(target.pf[j].content.length) <= OGS_NAS_MAX_QOS_RULES_LEN); - memcpy(buffer + length, &target.pf[j].length, - sizeof(target.pf[j].length)); - length += sizeof(target.pf[j].length); + memcpy(buffer + length, &target.pf[j].content.length, + sizeof(target.pf[j].content.length)); + length += sizeof(target.pf[j].content.length); - for (j = 0; j < target.pf[j].num_of_component; j++) { - ogs_assert(length + sizeof(target.pf[j].component[j].type) <= + for (k = 0; k < target.pf[j].content.num_of_component; k++) { + ogs_assert(length + + sizeof(target.pf[j].content.component[k].type) <= OGS_NAS_MAX_QOS_RULES_LEN); - memcpy(buffer + length, - &target.pf[j].component[j].type, - sizeof(target.pf[j].component[j].type)); - length += sizeof(target.pf[j].component[j].type); - switch(target.pf[j].component[j].type) { + memcpy(buffer + length, &target.pf[j].content.component[k].type, + sizeof(target.pf[j].content.component[k].type)); + length += sizeof(target.pf[j].content.component[k].type); + switch(target.pf[j].content.component[k].type) { case OGS_PACKET_FILTER_MATCH_ALL: break; case OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE: ogs_assert(length + - sizeof(target.pf[j].component[j].proto) <= + sizeof(target.pf[j].content.component[k].proto) <= OGS_NAS_MAX_QOS_RULES_LEN); memcpy(buffer + length, - &target.pf[j].component[j].proto, - sizeof(target.pf[j].component[j].proto)); - length += sizeof(target.pf[j].component[j].proto); + &target.pf[j].content.component[k].proto, + sizeof(target.pf[j].content.component[k].proto)); + length += sizeof(target.pf[j].content.component[k].proto); break; case OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE: case OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE: ogs_assert(length + - sizeof(target.pf[j].component[j].ipv4.addr) + sizeof(target.pf[j].content.component[k].ipv4.addr) <= OGS_NAS_MAX_QOS_RULES_LEN); memcpy(buffer + length, - &target.pf[j].component[j].ipv4.addr, - sizeof(target.pf[j].component[j].ipv4.addr)); - length += sizeof(target.pf[j].component[j].ipv4.addr); + &target.pf[j].content.component[k].ipv4.addr, + sizeof(target.pf[j].content.component[k].ipv4.addr)); + length += + sizeof(target.pf[j].content.component[k].ipv4.addr); ogs_assert(length + - sizeof(target.pf[j].component[j].ipv4.mask) + sizeof(target.pf[j].content.component[k].ipv4.mask) <= OGS_NAS_MAX_QOS_RULES_LEN); memcpy(buffer + length, - &target.pf[j].component[j].ipv4.mask, - sizeof(target.pf[j].component[j].ipv4.mask)); - length += sizeof(target.pf[j].component[j].ipv4.mask); + &target.pf[j].content.component[k].ipv4.mask, + sizeof(target.pf[j].content.component[k].ipv4.mask)); + length += + sizeof(target.pf[j].content.component[k].ipv4.mask); break; case OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE: case OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE: ogs_assert(length + - sizeof(target.pf[j].component[j].ipv6.addr) + sizeof(target.pf[j].content.component[k].ipv6.addr) <= OGS_NAS_MAX_QOS_RULES_LEN); memcpy(buffer + length, - &target.pf[j].component[j].ipv6.addr, - sizeof(target.pf[j].component[j].ipv6.addr)); - length += sizeof(target.pf[j].component[j].ipv6.addr); + &target.pf[j].content.component[k].ipv6.addr, + sizeof(target.pf[j].content.component[k].ipv6.addr)); + length += + sizeof(target.pf[j].content.component[k].ipv6.addr); ogs_assert(length + - sizeof(target.pf[j].component[j].ipv6.prefixlen) + sizeof(target.pf[j].content.component[k].ipv6.prefixlen) <= OGS_NAS_MAX_QOS_RULES_LEN); memcpy(buffer + length, - &target.pf[j].component[j].ipv6.prefixlen, - sizeof(target.pf[j].component[j].ipv6.prefixlen)); - length += sizeof(target.pf[j].component[j].ipv6.prefixlen); + &target.pf[j].content.component[k].ipv6.prefixlen, + sizeof( + target.pf[j].content.component[k].ipv6.prefixlen)); + length += sizeof( + target.pf[j].content.component[k].ipv6.prefixlen); break; case OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE: case OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE: ogs_assert(length + - sizeof(target.pf[j].component[j].ipv6_mask.addr) + sizeof(target.pf[j].content.component[k].ipv6_mask.addr) <= OGS_NAS_MAX_QOS_RULES_LEN); memcpy(buffer + length, - &target.pf[j].component[j].ipv6_mask.addr, - sizeof(target.pf[j].component[j].ipv6_mask.addr)); - length += sizeof(target.pf[j].component[j].ipv6_mask.addr); + &target.pf[j].content.component[k].ipv6_mask.addr, + sizeof( + target.pf[j].content.component[k].ipv6_mask.addr)); + length += sizeof( + target.pf[j].content.component[k].ipv6_mask.addr); ogs_assert(length + - sizeof(target.pf[j].component[j].ipv6_mask.mask) + sizeof(target.pf[j].content.component[k].ipv6_mask.mask) <= OGS_NAS_MAX_QOS_RULES_LEN); memcpy(buffer + length, - &target.pf[j].component[j].ipv6_mask.mask, - sizeof(target.pf[j].component[j].ipv6_mask.mask)); - length += sizeof(target.pf[j].component[j].ipv6_mask.mask); + &target.pf[j].content.component[k].ipv6_mask.mask, + sizeof( + target.pf[j].content.component[k].ipv6_mask.mask)); + length += sizeof( + target.pf[j].content.component[k].ipv6_mask.mask); break; case OGS_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE: case OGS_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE: ogs_assert(length + - sizeof(target.pf[j].component[j].port.low) + sizeof(target.pf[j].content.component[k].port.low) <= OGS_NAS_MAX_QOS_RULES_LEN); - target.pf[j].component[j].port.low = - htobe16(target.pf[j].component[j].port.low); + target.pf[j].content.component[k].port.low = + htobe16(target.pf[j].content.component[k].port.low); memcpy(buffer + length, - &target.pf[j].component[j].port.low, - sizeof(target.pf[j].component[j].port.low)); - length += sizeof(target.pf[j].component[j].port.low); + &target.pf[j].content.component[k].port.low, + sizeof(target.pf[j].content.component[k].port.low)); + length += + sizeof(target.pf[j].content.component[k].port.low); break; case OGS_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE: case OGS_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE: ogs_assert(length + - sizeof(target.pf[j].component[j].port.low) + sizeof(target.pf[j].content.component[k].port.low) <= OGS_NAS_MAX_QOS_RULES_LEN); - target.pf[j].component[j].port.low = - htobe16(target.pf[j].component[j].port.low); + target.pf[j].content.component[k].port.low = + htobe16(target.pf[j].content.component[k].port.low); memcpy(buffer + length, - &target.pf[j].component[j].port.low, - sizeof(target.pf[j].component[j].port.low)); - length += sizeof(target.pf[j].component[j].port.low); + &target.pf[j].content.component[k].port.low, + sizeof(target.pf[j].content.component[k].port.low)); + length += + sizeof(target.pf[j].content.component[k].port.low); ogs_assert(length + - sizeof(target.pf[j].component[j].port.high) + sizeof(target.pf[j].content.component[k].port.high) <= OGS_NAS_MAX_QOS_RULES_LEN); - target.pf[j].component[j].port.high = - htobe16(target.pf[j].component[j].port.high); + target.pf[j].content.component[k].port.high = + htobe16(target.pf[j].content.component[k].port.high); memcpy(buffer + length, - &target.pf[j].component[j].port.high, - sizeof(target.pf[j].component[j].port.high)); - length += sizeof(target.pf[j].component[j].port.high); + &target.pf[j].content.component[k].port.high, + sizeof(target.pf[j].content.component[k].port.high)); + length += + sizeof(target.pf[j].content.component[k].port.high); break; default: ogs_fatal("Unknown Packet Filter Type(%d)", - target.pf[j].component[j].type); + target.pf[j].content.component[k].type); ogs_assert_if_reached(); } } - } ogs_assert(length + sizeof(target.precedence) <= @@ -417,6 +507,11 @@ void ogs_nas_build_qos_rules(ogs_nas_qos_rules_t *rules, OGS_NAS_MAX_QOS_RULES_LEN); memcpy(buffer + length, &target.flow.flags, sizeof(target.precedence)); length += sizeof(target.flow.flags); + + /* Update QoS Rule Length */ + target.length = htobe16( + buffer+length - rule_length - sizeof(target.length)); + memcpy(rule_length, &target.length, sizeof(target.length)); } rules->buffer = buffer; diff --git a/lib/nas/5gs/types.h b/lib/nas/5gs/types.h index 946ae1f6c..3a125ecf3 100644 --- a/lib/nas/5gs/types.h +++ b/lib/nas/5gs/types.h @@ -707,10 +707,14 @@ typedef struct ogs_nas_qos_flow_parameter_s { #define OGS_NAX_QOS_FLOW_PARAMETER_ID_EPS_BEARER_IDENTITY 7 uint8_t identifier; uint8_t len; -#define OGS_NAS_MAX_QOS_FLOW_PARAEMTER_LEN 255 - uint8_t content[OGS_NAS_MAX_QOS_FLOW_PARAEMTER_LEN]; + union { + uint8_t qci; + ogs_nas_bitrate_t br; + }; } ogs_nas_qos_flow_parameter_t; +#define OGS_NAS_MAX_NUM_OF_QOS_FLOW_DESCRIPTION 8 +#define OGS_NAS_MAX_NUM_OF_QOS_FLOW_PARAMETER 8 typedef struct ogs_nas_qos_flow_description_s { ED2(uint8_t spare1:2;, uint8_t identifier:6;) @@ -734,18 +738,23 @@ ED3(uint8_t spare3:1;, * 0 extension of previously provided parameters * 1 replacement of all previously provided parameters */ - uint8_t E:1;, + uint8_t E_bit:1;, uint8_t num_of_parameter:6;) -#define OGS_NAS_MAX_NUM_OF_QOS_FLOW_PARAMETER 8 ogs_nas_qos_flow_parameter_t param[OGS_NAS_MAX_NUM_OF_QOS_FLOW_PARAMETER]; } ogs_nas_qos_flow_description_t; +#define OGS_NAS_MAX_QOS_FLOW_DESCRIPTIONS_LEN 65535 typedef struct ogs_nas_qos_flow_descriptions_s { uint16_t length; void *buffer; } ogs_nas_qos_flow_descriptions_t; +void ogs_nas_build_qos_flow_descriptions( + ogs_nas_qos_flow_descriptions_t *flow_descriptions, + ogs_nas_qos_flow_description_t *flow_description, + int num_of_flow_description); + /* 9.11.4.13 QoS rules * M LV-E 6-65535 */ #define OGS_NAS_MAX_NUM_OF_QOS_RULE 8 @@ -775,49 +784,11 @@ typedef struct ogs_nas_qos_rule_s { #define OGS_NAS_QOS_DIRECTION_UPLINK 2 #define OGS_NAS_QOS_DIRECTION_BIDIRECTIONAL 3 uint8_t direction:2;, - uint8_t pf_identifier:4;) + uint8_t identifier:4;) }; uint8_t flags; }; - uint8_t length; -#define OGS_PACKET_FILTER_MATCH_ALL 1 -#define OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE 48 -#define OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE 16 -#define OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE 17 -#define OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE 32 -#define OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE 33 -#define OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE 34 -#define OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE 35 -#define OGS_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE 64 -#define OGS_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE 65 -#define OGS_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE 80 -#define OGS_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE 81 -#define OGS_PACKET_FILTER_SECURITY_PARAMETER_INDEX_TYPE 96 -#define OGS_PACKET_FILTER_TOS_TRAFFIC_CLASS_TYPE 112 -#define OGS_PACKET_FILTER_FLOW_LABEL_TYPE 128 - struct { - uint8_t type; - union { - uint8_t proto; - struct { - uint32_t addr; - uint32_t mask; - } ipv4; - struct { - uint32_t addr[4]; - uint8_t prefixlen; - } ipv6; - struct { - uint32_t addr[4]; - uint32_t mask[4]; - } ipv6_mask; - struct { - uint16_t low; - uint16_t high; - } port; - }; - } component[OGS_NAS_MAX_NUM_OF_PACKET_FILTER_COMPONENT]; - uint8_t num_of_component; + ogs_pf_content_t content; } pf[OGS_MAX_NUM_OF_PACKET_FILTER]; uint8_t precedence; diff --git a/lib/nas/common/types.h b/lib/nas/common/types.h index 6413e88b8..899f03eb7 100644 --- a/lib/nas/common/types.h +++ b/lib/nas/common/types.h @@ -782,9 +782,10 @@ ED2(uint8_t reserved:5;, #define OGS_NAS_EPS_PDN_TYPE_NON_IP 5 #define OGS_NAS_5GS_REQUEST_TYPE_INITIAL 1 #define OGS_NAS_5GS_REQUEST_TYPE_EXISTING_PDU_SESSION 2 -#define OGS_NAS_5GS_REQUEST_TYPE_INITIAL_EMERGENCY 3 -#define OGS_NAS_5GS_REQUEST_TYPE_EXISTING_PDU_SESSION_EMERGENCY 4 -#define OGS_NAS_5GS_REQUEST_TYPE_MODIFICATION 5 +#define OGS_NAS_5GS_REQUEST_TYPE_INITIAL_EMERGENCY_REQUEST 3 +#define OGS_NAS_5GS_REQUEST_TYPE_EXISTING_EMERGENCY_PDU_SESSION 4 +#define OGS_NAS_5GS_REQUEST_TYPE_MODIFICATION_REQUEST 5 +#define OGS_NAS_5GS_REQUEST_TYPE_MA_PDU_REQUEST 6 typedef struct ogs_nas_request_type_s { ED3(uint8_t type:4;, uint8_t spare:1;, diff --git a/lib/pfcp/build.c b/lib/pfcp/build.c index 675f090d3..ec066db63 100644 --- a/lib/pfcp/build.c +++ b/lib/pfcp/build.c @@ -509,7 +509,7 @@ void ogs_pfcp_build_update_far_activate( message->far_id.presence = 1; message->far_id.u32 = far->id; - ogs_assert(far->apply_action == OGS_PFCP_APPLY_ACTION_FORW); + ogs_assert(far->apply_action & OGS_PFCP_APPLY_ACTION_FORW); message->apply_action.presence = 1; message->apply_action.u8 = far->apply_action; diff --git a/lib/pfcp/context.c b/lib/pfcp/context.c index c19fa2f13..c9e4f4bae 100644 --- a/lib/pfcp/context.c +++ b/lib/pfcp/context.c @@ -544,7 +544,7 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote) v = ogs_yaml_iter_value(&e_cell_id_iter); if (v) { e_cell_id[num_of_e_cell_id] - = ogs_uint28_from_string((char*)v); + = ogs_uint64_from_string((char*)v); num_of_e_cell_id++; } } while ( @@ -572,7 +572,7 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote) v = ogs_yaml_iter_value(&nr_cell_id_iter); if (v) { nr_cell_id[num_of_nr_cell_id] - = ogs_uint36_from_string((char*)v); + = ogs_uint64_from_string((char*)v); num_of_nr_cell_id++; } } while ( diff --git a/lib/pfcp/types.h b/lib/pfcp/types.h index 5e31eda32..6150a3bdb 100644 --- a/lib/pfcp/types.h +++ b/lib/pfcp/types.h @@ -486,6 +486,7 @@ ED5(uint8_t spare1:4;, uint8_t ipv6:1;, uint8_t ipv4:1;) union { +#define OGS_PFCP_DEFAULT_CHOOSE_ID 5 struct { ED4(uint8_t choose_id;, uint8_t spare2;, diff --git a/lib/sbi/context.c b/lib/sbi/context.c index 050608b59..06c7b2541 100644 --- a/lib/sbi/context.c +++ b/lib/sbi/context.c @@ -996,9 +996,10 @@ void ogs_sbi_object_free(ogs_sbi_object_t *sbi_object) } } -ogs_sbi_xact_t *ogs_sbi_xact_add(OpenAPI_nf_type_e target_nf_type, - ogs_sbi_object_t *sbi_object, void *data, - ogs_sbi_build_f build, void (*timer_cb)(void *data)) +ogs_sbi_xact_t *ogs_sbi_xact_add( + OpenAPI_nf_type_e target_nf_type, ogs_sbi_object_t *sbi_object, + ogs_sbi_build_f build, void *context, void *data, + void (*timer_cb)(void *data)) { ogs_sbi_xact_t *xact = NULL; @@ -1011,7 +1012,7 @@ ogs_sbi_xact_t *ogs_sbi_xact_add(OpenAPI_nf_type_e target_nf_type, xact->target_nf_type = target_nf_type; xact->sbi_object = sbi_object; - xact->request = (*build)(sbi_object, data); + xact->request = (*build)(context, data); ogs_assert(xact->request); xact->t_response = ogs_timer_add( diff --git a/lib/sbi/context.h b/lib/sbi/context.h index 47d8bcb6b..6fab8c1a7 100644 --- a/lib/sbi/context.h +++ b/lib/sbi/context.h @@ -125,7 +125,7 @@ typedef struct ogs_sbi_object_s { } ogs_sbi_object_t; typedef ogs_sbi_request_t *(*ogs_sbi_build_f)( - ogs_sbi_object_t *sbi_object, void *data); + void *context, void *data); typedef struct ogs_sbi_xact_s { ogs_lnode_t lnode; @@ -230,9 +230,10 @@ bool ogs_sbi_nf_instance_associate(ogs_sbi_nf_type_array_t nf_type_array, void ogs_sbi_object_free(ogs_sbi_object_t *sbi_object); -ogs_sbi_xact_t *ogs_sbi_xact_add(OpenAPI_nf_type_e target_nf_type, - ogs_sbi_object_t *sbi_object, void *data, - ogs_sbi_build_f build, void (*timer_cb)(void *data)); +ogs_sbi_xact_t *ogs_sbi_xact_add( + OpenAPI_nf_type_e target_nf_type, ogs_sbi_object_t *sbi_object, + ogs_sbi_build_f build, void *context, void *data, + void (*timer_cb)(void *data)); void ogs_sbi_xact_remove(ogs_sbi_xact_t *xact); void ogs_sbi_xact_remove_all(ogs_sbi_object_t *sbi_object); diff --git a/lib/sbi/conv.c b/lib/sbi/conv.c index 6023cacf4..0fb90cdbe 100644 --- a/lib/sbi/conv.c +++ b/lib/sbi/conv.c @@ -546,12 +546,12 @@ OpenAPI_nr_location_t *ogs_sbi_build_nr_location( Tai = ogs_calloc(1, sizeof(*Tai)); ogs_assert(Tai); Tai->plmn_id = ogs_sbi_build_plmn_id(&tai->plmn_id); - Tai->tac = ogs_uint24_to_string(tai->tac); + Tai->tac = ogs_uint24_to_0string(tai->tac); Ncgi = ogs_calloc(1, sizeof(*Ncgi)); ogs_assert(Ncgi); Ncgi->plmn_id = ogs_sbi_build_plmn_id(&nr_cgi->plmn_id); - Ncgi->nr_cell_id = ogs_uint36_to_string(nr_cgi->cell_id); + Ncgi->nr_cell_id = ogs_uint36_to_0string(nr_cgi->cell_id); NrLocation = ogs_calloc(1, sizeof(*NrLocation)); ogs_assert(NrLocation); @@ -584,7 +584,7 @@ bool ogs_sbi_parse_nr_location(ogs_5gs_tai_t *tai, ogs_nr_cgi_t *nr_cgi, if (Ncgi->plmn_id) ogs_sbi_parse_plmn_id(&nr_cgi->plmn_id, Ncgi->plmn_id); if (Ncgi->nr_cell_id) - nr_cgi->cell_id = ogs_uint36_from_string(Ncgi->nr_cell_id); + nr_cgi->cell_id = ogs_uint64_from_string(Ncgi->nr_cell_id); } diff --git a/lib/sbi/message.h b/lib/sbi/message.h index 2c6ad1463..161f26721 100644 --- a/lib/sbi/message.h +++ b/lib/sbi/message.h @@ -140,6 +140,57 @@ extern "C" { #define OGS_SBI_SERVICE_NAME_NPCF_SMPOLICYCONTROL "npcf-smpolicycontrol" #define OGS_SBI_RESOURCE_NAME_SM_POLICIES "sm-policies" +#define OGS_SBI_FEATURES_IS_SET(__fEATURES, __n) \ + (__fEATURES & (1 << ((__n)-1))) +#define OGS_SBI_FEATURES_SET(__fEATURES, __n) \ + __fEATURES |= (1 << ((__n)-1)) + +#define OGS_SBI_NPCF_AM_POLICY_CONTROL_SLICE_SUPPORT 1 +#define OGS_SBI_NPCF_AM_POLICY_CONTROL_PENDING_TRANSACTION 2 +#define OGS_SBI_NPCF_AM_POLICY_CONTROL_UE_AMBR_AUTHORIZATION 3 +#define OGS_SBI_NPCF_AM_POLICY_CONTROL_DNN_REPLACEMENT_CONTROL 4 +#define OGS_SBI_NPCF_AM_POLICY_CONTROL_MULTIPLE_ACCESS_TYPES 5 +#define OGS_SBI_NPCF_AM_POLICY_CONTROL_WIRELINE_WIRELESS_CONVERGE 6 + +#define OGS_SBI_NPCF_SMPOLICYCONTROL_TSC 1 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_RES_SHARE 2 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_3GPP_PS_DATA_OFF 3 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_ADC 4 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_UMC 5 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_NET_LOC 6 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_RAN_NAS_CAUSE 7 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_PROV_AF_SIGNAL_FLOW 8 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_PCSCF_RESTORATION_ENHANCEMENT 9 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_PRA 10 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_RULE_VERSIONING 11 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_SPONSORED_CONNECTIVITY 12 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_RAN_SUPPORT_INFO 13 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_POLICY_UPDATE_WHEN_UE_SUSPENDS 14 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_ACCESS_TYPE_CONDITION 15 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_MULTI_IPV6_ADDR_PREFIX 16 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_SESSION_RULE_ERROR_HANDLING 17 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_AF_CHARGING_IDENTIFIER 18 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_ATSSS 19 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_PENDING_TRANSACTION 20 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_URLLC 21 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_MAC_ADDRESS_RANGE 22 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_WWC 23 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_QOS_MONITORING 24 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_AUTHORIZATION_WITH_REQUIRED_QOS 25 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_ENHANCED_BACKGROUND_DATA_TRANSFER 26 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_DN_AUTHORIZATION 27 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_PDU_SESSION_REL_CAUSE 28 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_SAME_PCF 29 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_ADC_MULTI_REDIRECTION 30 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_RESP_BASED_SESSION_REL 31 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_TIME_SENSITIVE_NETWORKING 32 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_EMDBV 33 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_DNN_SELECTION_MODE 34 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_EPS_FALLBACK_REPORT 35 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_POLICY_DECISION_ERROR_HANDLING 36 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_DDN_EVENT_POLICY_CONTROL 37 +#define OGS_SBI_NPCF_SMPOLICYCONTROL_REALLOCATION_OF_CREDIT 38 + #define OGS_SBI_PARAM_NF_TYPE "nf-type" #define OGS_SBI_PARAM_TARGET_NF_TYPE "target-nf-type" #define OGS_SBI_PARAM_REQUESTER_NF_TYPE "requester-nf-type" diff --git a/lib/sbi/openapi/model/af_sig_protocol.c b/lib/sbi/openapi/model/af_sig_protocol.c index 4ca143354..da7b728c7 100644 --- a/lib/sbi/openapi/model/af_sig_protocol.c +++ b/lib/sbi/openapi/model/af_sig_protocol.c @@ -4,82 +4,27 @@ #include #include "af_sig_protocol.h" -OpenAPI_af_sig_protocol_t *OpenAPI_af_sig_protocol_create( - ) +char* OpenAPI_af_sig_protocol_ToString(OpenAPI_af_sig_protocol_e af_sig_protocol) { - OpenAPI_af_sig_protocol_t *af_sig_protocol_local_var = OpenAPI_malloc(sizeof(OpenAPI_af_sig_protocol_t)); - if (!af_sig_protocol_local_var) { - return NULL; - } - - return af_sig_protocol_local_var; + const char *af_sig_protocolArray[] = { "NULL", "NO_INFORMATION", "SIP" }; + size_t sizeofArray = sizeof(af_sig_protocolArray) / sizeof(af_sig_protocolArray[0]); + if (af_sig_protocol < sizeofArray) + return (char *)af_sig_protocolArray[af_sig_protocol]; + else + return (char *)"Unknown"; } -void OpenAPI_af_sig_protocol_free(OpenAPI_af_sig_protocol_t *af_sig_protocol) +OpenAPI_af_sig_protocol_e OpenAPI_af_sig_protocol_FromString(char* af_sig_protocol) { - if (NULL == af_sig_protocol) { - return; + int stringToReturn = 0; + const char *af_sig_protocolArray[] = { "NULL", "NO_INFORMATION", "SIP" }; + size_t sizeofArray = sizeof(af_sig_protocolArray) / sizeof(af_sig_protocolArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(af_sig_protocol, af_sig_protocolArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(af_sig_protocol); -} - -cJSON *OpenAPI_af_sig_protocol_convertToJSON(OpenAPI_af_sig_protocol_t *af_sig_protocol) -{ - cJSON *item = NULL; - - if (af_sig_protocol == NULL) { - ogs_error("OpenAPI_af_sig_protocol_convertToJSON() failed [AfSigProtocol]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_af_sig_protocol_t *OpenAPI_af_sig_protocol_parseFromJSON(cJSON *af_sig_protocolJSON) -{ - OpenAPI_af_sig_protocol_t *af_sig_protocol_local_var = NULL; - af_sig_protocol_local_var = OpenAPI_af_sig_protocol_create ( - ); - - return af_sig_protocol_local_var; -end: - return NULL; -} - -OpenAPI_af_sig_protocol_t *OpenAPI_af_sig_protocol_copy(OpenAPI_af_sig_protocol_t *dst, OpenAPI_af_sig_protocol_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_af_sig_protocol_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_af_sig_protocol_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_af_sig_protocol_free(dst); - dst = OpenAPI_af_sig_protocol_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/af_sig_protocol.h b/lib/sbi/openapi/model/af_sig_protocol.h index 27d09d3af..6841e1c0e 100644 --- a/lib/sbi/openapi/model/af_sig_protocol.h +++ b/lib/sbi/openapi/model/af_sig_protocol.h @@ -1,7 +1,7 @@ /* * af_sig_protocol.h * - * Possible values are - NO_INFORMATION: Indicate that no information about the AF signalling protocol is being provided. - SIP: Indicate that the signalling protocol is Session Initiation Protocol. + * */ #ifndef _OpenAPI_af_sig_protocol_H_ @@ -12,22 +12,16 @@ #include "../include/list.h" #include "../include/keyValuePair.h" #include "../include/binary.h" -#include "null_value.h" #ifdef __cplusplus extern "C" { #endif -typedef struct OpenAPI_af_sig_protocol_s OpenAPI_af_sig_protocol_t; -typedef struct OpenAPI_af_sig_protocol_s { -} OpenAPI_af_sig_protocol_t; +typedef enum { OpenAPI_af_sig_protocol_NULL = 0, OpenAPI_af_sig_protocol_NO_INFORMATION, OpenAPI_af_sig_protocol_SIP } OpenAPI_af_sig_protocol_e; -OpenAPI_af_sig_protocol_t *OpenAPI_af_sig_protocol_create( - ); -void OpenAPI_af_sig_protocol_free(OpenAPI_af_sig_protocol_t *af_sig_protocol); -OpenAPI_af_sig_protocol_t *OpenAPI_af_sig_protocol_parseFromJSON(cJSON *af_sig_protocolJSON); -cJSON *OpenAPI_af_sig_protocol_convertToJSON(OpenAPI_af_sig_protocol_t *af_sig_protocol); -OpenAPI_af_sig_protocol_t *OpenAPI_af_sig_protocol_copy(OpenAPI_af_sig_protocol_t *dst, OpenAPI_af_sig_protocol_t *src); +char* OpenAPI_af_sig_protocol_ToString(OpenAPI_af_sig_protocol_e af_sig_protocol); + +OpenAPI_af_sig_protocol_e OpenAPI_af_sig_protocol_FromString(char* af_sig_protocol); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/charging_data.c b/lib/sbi/openapi/model/charging_data.c index ff0be6aae..256d9bade 100644 --- a/lib/sbi/openapi/model/charging_data.c +++ b/lib/sbi/openapi/model/charging_data.c @@ -6,12 +6,12 @@ OpenAPI_charging_data_t *OpenAPI_charging_data_create( char *chg_id, - OpenAPI_metering_method_t *metering_method, + OpenAPI_metering_method_e metering_method, int offline, int online, int sdf_handl, int rating_group, - OpenAPI_reporting_level_t *reporting_level, + OpenAPI_reporting_level_e reporting_level, int service_id, char *sponsor_id, char *app_svc_prov_id, @@ -46,8 +46,6 @@ void OpenAPI_charging_data_free(OpenAPI_charging_data_t *charging_data) } OpenAPI_lnode_t *node; ogs_free(charging_data->chg_id); - OpenAPI_metering_method_free(charging_data->metering_method); - OpenAPI_reporting_level_free(charging_data->reporting_level); ogs_free(charging_data->sponsor_id); ogs_free(charging_data->app_svc_prov_id); ogs_free(charging_data->af_charg_id); @@ -74,13 +72,7 @@ cJSON *OpenAPI_charging_data_convertToJSON(OpenAPI_charging_data_t *charging_dat } if (charging_data->metering_method) { - cJSON *metering_method_local_JSON = OpenAPI_metering_method_convertToJSON(charging_data->metering_method); - if (metering_method_local_JSON == NULL) { - ogs_error("OpenAPI_charging_data_convertToJSON() failed [metering_method]"); - goto end; - } - cJSON_AddItemToObject(item, "meteringMethod", metering_method_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "meteringMethod", OpenAPI_metering_method_ToString(charging_data->metering_method)) == NULL) { ogs_error("OpenAPI_charging_data_convertToJSON() failed [metering_method]"); goto end; } @@ -115,13 +107,7 @@ cJSON *OpenAPI_charging_data_convertToJSON(OpenAPI_charging_data_t *charging_dat } if (charging_data->reporting_level) { - cJSON *reporting_level_local_JSON = OpenAPI_reporting_level_convertToJSON(charging_data->reporting_level); - if (reporting_level_local_JSON == NULL) { - ogs_error("OpenAPI_charging_data_convertToJSON() failed [reporting_level]"); - goto end; - } - cJSON_AddItemToObject(item, "reportingLevel", reporting_level_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "reportingLevel", OpenAPI_reporting_level_ToString(charging_data->reporting_level)) == NULL) { ogs_error("OpenAPI_charging_data_convertToJSON() failed [reporting_level]"); goto end; } @@ -183,9 +169,13 @@ OpenAPI_charging_data_t *OpenAPI_charging_data_parseFromJSON(cJSON *charging_dat cJSON *metering_method = cJSON_GetObjectItemCaseSensitive(charging_dataJSON, "meteringMethod"); - OpenAPI_metering_method_t *metering_method_local_nonprim = NULL; + OpenAPI_metering_method_e metering_methodVariable; if (metering_method) { - metering_method_local_nonprim = OpenAPI_metering_method_parseFromJSON(metering_method); + if (!cJSON_IsString(metering_method)) { + ogs_error("OpenAPI_charging_data_parseFromJSON() failed [metering_method]"); + goto end; + } + metering_methodVariable = OpenAPI_metering_method_FromString(metering_method->valuestring); } cJSON *offline = cJSON_GetObjectItemCaseSensitive(charging_dataJSON, "offline"); @@ -226,9 +216,13 @@ OpenAPI_charging_data_t *OpenAPI_charging_data_parseFromJSON(cJSON *charging_dat cJSON *reporting_level = cJSON_GetObjectItemCaseSensitive(charging_dataJSON, "reportingLevel"); - OpenAPI_reporting_level_t *reporting_level_local_nonprim = NULL; + OpenAPI_reporting_level_e reporting_levelVariable; if (reporting_level) { - reporting_level_local_nonprim = OpenAPI_reporting_level_parseFromJSON(reporting_level); + if (!cJSON_IsString(reporting_level)) { + ogs_error("OpenAPI_charging_data_parseFromJSON() failed [reporting_level]"); + goto end; + } + reporting_levelVariable = OpenAPI_reporting_level_FromString(reporting_level->valuestring); } cJSON *service_id = cJSON_GetObjectItemCaseSensitive(charging_dataJSON, "serviceId"); @@ -278,12 +272,12 @@ OpenAPI_charging_data_t *OpenAPI_charging_data_parseFromJSON(cJSON *charging_dat charging_data_local_var = OpenAPI_charging_data_create ( ogs_strdup(chg_id->valuestring), - metering_method ? metering_method_local_nonprim : NULL, + metering_method ? metering_methodVariable : 0, offline ? offline->valueint : 0, online ? online->valueint : 0, sdf_handl ? sdf_handl->valueint : 0, rating_group ? rating_group->valuedouble : 0, - reporting_level ? reporting_level_local_nonprim : NULL, + reporting_level ? reporting_levelVariable : 0, service_id ? service_id->valuedouble : 0, sponsor_id ? ogs_strdup(sponsor_id->valuestring) : NULL, app_svc_prov_id ? ogs_strdup(app_svc_prov_id->valuestring) : NULL, diff --git a/lib/sbi/openapi/model/charging_data.h b/lib/sbi/openapi/model/charging_data.h index c1c315462..6375263f3 100644 --- a/lib/sbi/openapi/model/charging_data.h +++ b/lib/sbi/openapi/model/charging_data.h @@ -22,12 +22,12 @@ extern "C" { typedef struct OpenAPI_charging_data_s OpenAPI_charging_data_t; typedef struct OpenAPI_charging_data_s { char *chg_id; - struct OpenAPI_metering_method_s *metering_method; + OpenAPI_metering_method_e metering_method; int offline; int online; int sdf_handl; int rating_group; - struct OpenAPI_reporting_level_s *reporting_level; + OpenAPI_reporting_level_e reporting_level; int service_id; char *sponsor_id; char *app_svc_prov_id; @@ -37,12 +37,12 @@ typedef struct OpenAPI_charging_data_s { OpenAPI_charging_data_t *OpenAPI_charging_data_create( char *chg_id, - OpenAPI_metering_method_t *metering_method, + OpenAPI_metering_method_e metering_method, int offline, int online, int sdf_handl, int rating_group, - OpenAPI_reporting_level_t *reporting_level, + OpenAPI_reporting_level_e reporting_level, int service_id, char *sponsor_id, char *app_svc_prov_id, diff --git a/lib/sbi/openapi/model/credit_management_status.c b/lib/sbi/openapi/model/credit_management_status.c index a3680ba8b..283422f02 100644 --- a/lib/sbi/openapi/model/credit_management_status.c +++ b/lib/sbi/openapi/model/credit_management_status.c @@ -4,82 +4,27 @@ #include #include "credit_management_status.h" -OpenAPI_credit_management_status_t *OpenAPI_credit_management_status_create( - ) +char* OpenAPI_credit_management_status_ToString(OpenAPI_credit_management_status_e credit_management_status) { - OpenAPI_credit_management_status_t *credit_management_status_local_var = OpenAPI_malloc(sizeof(OpenAPI_credit_management_status_t)); - if (!credit_management_status_local_var) { - return NULL; - } - - return credit_management_status_local_var; + const char *credit_management_statusArray[] = { "NULL", "END_USER_SER_DENIED", "CREDIT_CTRL_NOT_APP", "AUTH_REJECTED", "USER_UNKNOWN", "RATING_FAILED" }; + size_t sizeofArray = sizeof(credit_management_statusArray) / sizeof(credit_management_statusArray[0]); + if (credit_management_status < sizeofArray) + return (char *)credit_management_statusArray[credit_management_status]; + else + return (char *)"Unknown"; } -void OpenAPI_credit_management_status_free(OpenAPI_credit_management_status_t *credit_management_status) +OpenAPI_credit_management_status_e OpenAPI_credit_management_status_FromString(char* credit_management_status) { - if (NULL == credit_management_status) { - return; + int stringToReturn = 0; + const char *credit_management_statusArray[] = { "NULL", "END_USER_SER_DENIED", "CREDIT_CTRL_NOT_APP", "AUTH_REJECTED", "USER_UNKNOWN", "RATING_FAILED" }; + size_t sizeofArray = sizeof(credit_management_statusArray) / sizeof(credit_management_statusArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(credit_management_status, credit_management_statusArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(credit_management_status); -} - -cJSON *OpenAPI_credit_management_status_convertToJSON(OpenAPI_credit_management_status_t *credit_management_status) -{ - cJSON *item = NULL; - - if (credit_management_status == NULL) { - ogs_error("OpenAPI_credit_management_status_convertToJSON() failed [CreditManagementStatus]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_credit_management_status_t *OpenAPI_credit_management_status_parseFromJSON(cJSON *credit_management_statusJSON) -{ - OpenAPI_credit_management_status_t *credit_management_status_local_var = NULL; - credit_management_status_local_var = OpenAPI_credit_management_status_create ( - ); - - return credit_management_status_local_var; -end: - return NULL; -} - -OpenAPI_credit_management_status_t *OpenAPI_credit_management_status_copy(OpenAPI_credit_management_status_t *dst, OpenAPI_credit_management_status_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_credit_management_status_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_credit_management_status_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_credit_management_status_free(dst); - dst = OpenAPI_credit_management_status_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/credit_management_status.h b/lib/sbi/openapi/model/credit_management_status.h index bdddb0a51..85479abbb 100644 --- a/lib/sbi/openapi/model/credit_management_status.h +++ b/lib/sbi/openapi/model/credit_management_status.h @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_credit_management_status_s OpenAPI_credit_management_status_t; -typedef struct OpenAPI_credit_management_status_s { -} OpenAPI_credit_management_status_t; +typedef enum { OpenAPI_credit_management_status_NULL = 0, OpenAPI_credit_management_status_END_USER_SER_DENIED, OpenAPI_credit_management_status_CREDIT_CTRL_NOT_APP, OpenAPI_credit_management_status_AUTH_REJECTED, OpenAPI_credit_management_status_USER_UNKNOWN, OpenAPI_credit_management_status_RATING_FAILED } OpenAPI_credit_management_status_e; -OpenAPI_credit_management_status_t *OpenAPI_credit_management_status_create( - ); -void OpenAPI_credit_management_status_free(OpenAPI_credit_management_status_t *credit_management_status); -OpenAPI_credit_management_status_t *OpenAPI_credit_management_status_parseFromJSON(cJSON *credit_management_statusJSON); -cJSON *OpenAPI_credit_management_status_convertToJSON(OpenAPI_credit_management_status_t *credit_management_status); -OpenAPI_credit_management_status_t *OpenAPI_credit_management_status_copy(OpenAPI_credit_management_status_t *dst, OpenAPI_credit_management_status_t *src); +char* OpenAPI_credit_management_status_ToString(OpenAPI_credit_management_status_e credit_management_status); + +OpenAPI_credit_management_status_e OpenAPI_credit_management_status_FromString(char* credit_management_status); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/eth_flow_description.c b/lib/sbi/openapi/model/eth_flow_description.c index 16ccc71d8..9ea9e9a3f 100644 --- a/lib/sbi/openapi/model/eth_flow_description.c +++ b/lib/sbi/openapi/model/eth_flow_description.c @@ -8,7 +8,7 @@ OpenAPI_eth_flow_description_t *OpenAPI_eth_flow_description_create( char *dest_mac_addr, char *eth_type, char *f_desc, - OpenAPI_flow_direction_t *f_dir, + OpenAPI_flow_direction_e f_dir, char *source_mac_addr, OpenAPI_list_t *vlan_tags, char *src_mac_addr_end, @@ -40,7 +40,6 @@ void OpenAPI_eth_flow_description_free(OpenAPI_eth_flow_description_t *eth_flow_ ogs_free(eth_flow_description->dest_mac_addr); ogs_free(eth_flow_description->eth_type); ogs_free(eth_flow_description->f_desc); - OpenAPI_flow_direction_free(eth_flow_description->f_dir); ogs_free(eth_flow_description->source_mac_addr); OpenAPI_list_for_each(eth_flow_description->vlan_tags, node) { ogs_free(node->data); @@ -85,13 +84,7 @@ cJSON *OpenAPI_eth_flow_description_convertToJSON(OpenAPI_eth_flow_description_t } if (eth_flow_description->f_dir) { - cJSON *f_dir_local_JSON = OpenAPI_flow_direction_convertToJSON(eth_flow_description->f_dir); - if (f_dir_local_JSON == NULL) { - ogs_error("OpenAPI_eth_flow_description_convertToJSON() failed [f_dir]"); - goto end; - } - cJSON_AddItemToObject(item, "fDir", f_dir_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "fDir", OpenAPI_flow_direction_ToString(eth_flow_description->f_dir)) == NULL) { ogs_error("OpenAPI_eth_flow_description_convertToJSON() failed [f_dir]"); goto end; } @@ -173,9 +166,13 @@ OpenAPI_eth_flow_description_t *OpenAPI_eth_flow_description_parseFromJSON(cJSON cJSON *f_dir = cJSON_GetObjectItemCaseSensitive(eth_flow_descriptionJSON, "fDir"); - OpenAPI_flow_direction_t *f_dir_local_nonprim = NULL; + OpenAPI_flow_direction_e f_dirVariable; if (f_dir) { - f_dir_local_nonprim = OpenAPI_flow_direction_parseFromJSON(f_dir); + if (!cJSON_IsString(f_dir)) { + ogs_error("OpenAPI_eth_flow_description_parseFromJSON() failed [f_dir]"); + goto end; + } + f_dirVariable = OpenAPI_flow_direction_FromString(f_dir->valuestring); } cJSON *source_mac_addr = cJSON_GetObjectItemCaseSensitive(eth_flow_descriptionJSON, "sourceMacAddr"); @@ -229,7 +226,7 @@ OpenAPI_eth_flow_description_t *OpenAPI_eth_flow_description_parseFromJSON(cJSON dest_mac_addr ? ogs_strdup(dest_mac_addr->valuestring) : NULL, ogs_strdup(eth_type->valuestring), f_desc ? ogs_strdup(f_desc->valuestring) : NULL, - f_dir ? f_dir_local_nonprim : NULL, + f_dir ? f_dirVariable : 0, source_mac_addr ? ogs_strdup(source_mac_addr->valuestring) : NULL, vlan_tags ? vlan_tagsList : NULL, src_mac_addr_end ? ogs_strdup(src_mac_addr_end->valuestring) : NULL, diff --git a/lib/sbi/openapi/model/eth_flow_description.h b/lib/sbi/openapi/model/eth_flow_description.h index 48e318558..aec086ee3 100644 --- a/lib/sbi/openapi/model/eth_flow_description.h +++ b/lib/sbi/openapi/model/eth_flow_description.h @@ -23,7 +23,7 @@ typedef struct OpenAPI_eth_flow_description_s { char *dest_mac_addr; char *eth_type; char *f_desc; - struct OpenAPI_flow_direction_s *f_dir; + OpenAPI_flow_direction_e f_dir; char *source_mac_addr; OpenAPI_list_t *vlan_tags; char *src_mac_addr_end; @@ -34,7 +34,7 @@ OpenAPI_eth_flow_description_t *OpenAPI_eth_flow_description_create( char *dest_mac_addr, char *eth_type, char *f_desc, - OpenAPI_flow_direction_t *f_dir, + OpenAPI_flow_direction_e f_dir, char *source_mac_addr, OpenAPI_list_t *vlan_tags, char *src_mac_addr_end, diff --git a/lib/sbi/openapi/model/failure_cause.c b/lib/sbi/openapi/model/failure_cause.c index ab0642242..808c4421d 100644 --- a/lib/sbi/openapi/model/failure_cause.c +++ b/lib/sbi/openapi/model/failure_cause.c @@ -4,82 +4,27 @@ #include #include "failure_cause.h" -OpenAPI_failure_cause_t *OpenAPI_failure_cause_create( - ) +char* OpenAPI_failure_cause_ToString(OpenAPI_failure_cause_e failure_cause) { - OpenAPI_failure_cause_t *failure_cause_local_var = OpenAPI_malloc(sizeof(OpenAPI_failure_cause_t)); - if (!failure_cause_local_var) { - return NULL; - } - - return failure_cause_local_var; + const char *failure_causeArray[] = { "NULL", "PCC_RULE_EVENT", "PCC_QOS_FLOW_EVENT", "RULE_PERMANENT_ERROR", "RULE_TEMPORARY_ERROR" }; + size_t sizeofArray = sizeof(failure_causeArray) / sizeof(failure_causeArray[0]); + if (failure_cause < sizeofArray) + return (char *)failure_causeArray[failure_cause]; + else + return (char *)"Unknown"; } -void OpenAPI_failure_cause_free(OpenAPI_failure_cause_t *failure_cause) +OpenAPI_failure_cause_e OpenAPI_failure_cause_FromString(char* failure_cause) { - if (NULL == failure_cause) { - return; + int stringToReturn = 0; + const char *failure_causeArray[] = { "NULL", "PCC_RULE_EVENT", "PCC_QOS_FLOW_EVENT", "RULE_PERMANENT_ERROR", "RULE_TEMPORARY_ERROR" }; + size_t sizeofArray = sizeof(failure_causeArray) / sizeof(failure_causeArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(failure_cause, failure_causeArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(failure_cause); -} - -cJSON *OpenAPI_failure_cause_convertToJSON(OpenAPI_failure_cause_t *failure_cause) -{ - cJSON *item = NULL; - - if (failure_cause == NULL) { - ogs_error("OpenAPI_failure_cause_convertToJSON() failed [FailureCause]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_failure_cause_t *OpenAPI_failure_cause_parseFromJSON(cJSON *failure_causeJSON) -{ - OpenAPI_failure_cause_t *failure_cause_local_var = NULL; - failure_cause_local_var = OpenAPI_failure_cause_create ( - ); - - return failure_cause_local_var; -end: - return NULL; -} - -OpenAPI_failure_cause_t *OpenAPI_failure_cause_copy(OpenAPI_failure_cause_t *dst, OpenAPI_failure_cause_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_failure_cause_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_failure_cause_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_failure_cause_free(dst); - dst = OpenAPI_failure_cause_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/failure_cause.h b/lib/sbi/openapi/model/failure_cause.h index 22a3a9aae..8dde24e31 100644 --- a/lib/sbi/openapi/model/failure_cause.h +++ b/lib/sbi/openapi/model/failure_cause.h @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_failure_cause_s OpenAPI_failure_cause_t; -typedef struct OpenAPI_failure_cause_s { -} OpenAPI_failure_cause_t; +typedef enum { OpenAPI_failure_cause_NULL = 0, OpenAPI_failure_cause_PCC_RULE_EVENT, OpenAPI_failure_cause_PCC_QOS_FLOW_EVENT, OpenAPI_failure_cause_RULE_PERMANENT_ERROR, OpenAPI_failure_cause_RULE_TEMPORARY_ERROR } OpenAPI_failure_cause_e; -OpenAPI_failure_cause_t *OpenAPI_failure_cause_create( - ); -void OpenAPI_failure_cause_free(OpenAPI_failure_cause_t *failure_cause); -OpenAPI_failure_cause_t *OpenAPI_failure_cause_parseFromJSON(cJSON *failure_causeJSON); -cJSON *OpenAPI_failure_cause_convertToJSON(OpenAPI_failure_cause_t *failure_cause); -OpenAPI_failure_cause_t *OpenAPI_failure_cause_copy(OpenAPI_failure_cause_t *dst, OpenAPI_failure_cause_t *src); +char* OpenAPI_failure_cause_ToString(OpenAPI_failure_cause_e failure_cause); + +OpenAPI_failure_cause_e OpenAPI_failure_cause_FromString(char* failure_cause); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/failure_code.c b/lib/sbi/openapi/model/failure_code.c index 10e5d77d9..ad11b65d3 100644 --- a/lib/sbi/openapi/model/failure_code.c +++ b/lib/sbi/openapi/model/failure_code.c @@ -4,82 +4,27 @@ #include #include "failure_code.h" -OpenAPI_failure_code_t *OpenAPI_failure_code_create( - ) +char* OpenAPI_failure_code_ToString(OpenAPI_failure_code_e failure_code) { - OpenAPI_failure_code_t *failure_code_local_var = OpenAPI_malloc(sizeof(OpenAPI_failure_code_t)); - if (!failure_code_local_var) { - return NULL; - } - - return failure_code_local_var; + const char *failure_codeArray[] = { "NULL", "UNK_RULE_ID", "RA_GR_ERR", "SER_ID_ERR", "NF_MAL", "RES_LIM", "MAX_NR_QoS_FLOW", "MISS_FLOW_INFO", "RES_ALLO_FAIL", "UNSUCC_QOS_VAL", "INCOR_FLOW_INFO", "PS_TO_CS_HAN", "APP_ID_ERR", "NO_QOS_FLOW_BOUND", "FILTER_RES", "MISS_REDI_SER_ADDR", "CM_END_USER_SER_DENIED", "CM_CREDIT_CON_NOT_APP", "CM_AUTH_REJ", "CM_USER_UNK", "CM_RAT_FAILED", "UE_STA_SUSP" }; + size_t sizeofArray = sizeof(failure_codeArray) / sizeof(failure_codeArray[0]); + if (failure_code < sizeofArray) + return (char *)failure_codeArray[failure_code]; + else + return (char *)"Unknown"; } -void OpenAPI_failure_code_free(OpenAPI_failure_code_t *failure_code) +OpenAPI_failure_code_e OpenAPI_failure_code_FromString(char* failure_code) { - if (NULL == failure_code) { - return; + int stringToReturn = 0; + const char *failure_codeArray[] = { "NULL", "UNK_RULE_ID", "RA_GR_ERR", "SER_ID_ERR", "NF_MAL", "RES_LIM", "MAX_NR_QoS_FLOW", "MISS_FLOW_INFO", "RES_ALLO_FAIL", "UNSUCC_QOS_VAL", "INCOR_FLOW_INFO", "PS_TO_CS_HAN", "APP_ID_ERR", "NO_QOS_FLOW_BOUND", "FILTER_RES", "MISS_REDI_SER_ADDR", "CM_END_USER_SER_DENIED", "CM_CREDIT_CON_NOT_APP", "CM_AUTH_REJ", "CM_USER_UNK", "CM_RAT_FAILED", "UE_STA_SUSP" }; + size_t sizeofArray = sizeof(failure_codeArray) / sizeof(failure_codeArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(failure_code, failure_codeArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(failure_code); -} - -cJSON *OpenAPI_failure_code_convertToJSON(OpenAPI_failure_code_t *failure_code) -{ - cJSON *item = NULL; - - if (failure_code == NULL) { - ogs_error("OpenAPI_failure_code_convertToJSON() failed [FailureCode]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_failure_code_t *OpenAPI_failure_code_parseFromJSON(cJSON *failure_codeJSON) -{ - OpenAPI_failure_code_t *failure_code_local_var = NULL; - failure_code_local_var = OpenAPI_failure_code_create ( - ); - - return failure_code_local_var; -end: - return NULL; -} - -OpenAPI_failure_code_t *OpenAPI_failure_code_copy(OpenAPI_failure_code_t *dst, OpenAPI_failure_code_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_failure_code_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_failure_code_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_failure_code_free(dst); - dst = OpenAPI_failure_code_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/failure_code.h b/lib/sbi/openapi/model/failure_code.h index 51f847ad0..c8bde5b91 100644 --- a/lib/sbi/openapi/model/failure_code.h +++ b/lib/sbi/openapi/model/failure_code.h @@ -1,7 +1,7 @@ /* * failure_code.h * - * Possible values are - UNK_RULE_ID: Indicates that the pre-provisioned PCC rule could not be successfully activated because the PCC rule identifier is unknown to the SMF. - RA_GR_ERR: Indicate that the PCC rule could not be successfully installed or enforced because the Rating Group specified within the Charging Data policy decision which the PCC rule refers to is unknown or, invalid. - SER_ID_ERR: Indicate that the PCC rule could not be successfully installed or enforced because the Service Identifier specified within the Charging Data policy decision which the PCC rule refers to is invalid, unknown, or not applicable to the service being charged. - NF_MAL: Indicate that the PCC rule could not be successfully installed (for those provisioned from the PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to SMF/UPF malfunction. - RES_LIM: Indicate that the PCC rule could not be successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to a limitation of resources at the SMF/UPF. - MAX_NR_QoS_FLOW: Indicate that the PCC rule could not be successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to the fact that the maximum number of QoS flows has been reached for the PDU session. - MISS_FLOW_INFO: Indicate that the PCC rule could not be successfully installed or enforced because neither the \"flowInfos\" attribute nor the \"appId\" attribute is specified within the PccRule data structure by the PCF during the first install request of the PCC rule. - RES_ALLO_FAIL: Indicate that the PCC rule could not be successfully installed or maintained since the QoS flow establishment/modification failed, or the QoS flow was released. - UNSUCC_QOS_VAL: indicate that the QoS validation has failed or when Guaranteed Bandwidth > Max-Requested-Bandwidth. - INCOR_FLOW_INFO: Indicate that the PCC rule could not be successfully installed or modified at the SMF because the provided flow information is not supported by the network (e.g. the provided IP address(es) or Ipv6 prefix(es) do not correspond to an IP version applicable for the PDU session). - PS_TO_CS_HAN: Indicate that the PCC rule could not be maintained because of PS to CS handover. - APP_ID_ERR: Indicate that the rule could not be successfully installed or enforced because the Application Identifier is invalid, unknown, or not applicable to the application required for detection. - NO_QOS_FLOW_BOUND: Indicate that there is no QoS flow which the SMF can bind the PCC rule(s) to. - FILTER_RES: Indicate that the Flow Information within the \"flowInfos\" attribute cannot be handled by the SMF because any of the restrictions defined in subclause 5.4.2 of 3GPP TS 29.212 was not met. - MISS_REDI_SER_ADDR: Indicate that the PCC rule could not be successfully installed or enforced at the SMF because there is no valid Redirect Server Address within the Traffic Control Data policy decision which the PCC rule refers to provided by the PCF and no preconfigured redirection address for this PCC rule at the SMF. - CM_END_USER_SER_DENIED: Indicate that the charging system denied the service request due to service restrictions (e.g. terminate rating group) or limitations related to the end-user, for example the end-user's account could not cover the requested service. - CM_CREDIT_CON_NOT_APP: Indicate that the charging system determined that the service can be granted to the end user but no further credit control is needed for the service (e.g. service is free of charge or is treated for offline charging). - CM_AUTH_REJ: Indicate that the charging system denied the service request in order to terminate the service for which credit is requested. - CM_USER_UNK: Indicate that the specified end user could not be found in the charging system. - CM_RAT_FAILED: Indicate that the charging system cannot rate the service request due to insufficient rating input, incorrect AVP combination or due to an attribute or an attribute value that is not recognized or supported in the rating. - UE_STA_SUSP: Indicates that the UE is in suspend state. + * */ #ifndef _OpenAPI_failure_code_H_ @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_failure_code_s OpenAPI_failure_code_t; -typedef struct OpenAPI_failure_code_s { -} OpenAPI_failure_code_t; +typedef enum { OpenAPI_failure_code_NULL = 0, OpenAPI_failure_code_UNK_RULE_ID, OpenAPI_failure_code_RA_GR_ERR, OpenAPI_failure_code_SER_ID_ERR, OpenAPI_failure_code_NF_MAL, OpenAPI_failure_code_RES_LIM, OpenAPI_failure_code_MAX_NR_QoS_FLOW, OpenAPI_failure_code_MISS_FLOW_INFO, OpenAPI_failure_code_RES_ALLO_FAIL, OpenAPI_failure_code_UNSUCC_QOS_VAL, OpenAPI_failure_code_INCOR_FLOW_INFO, OpenAPI_failure_code_PS_TO_CS_HAN, OpenAPI_failure_code_APP_ID_ERR, OpenAPI_failure_code_NO_QOS_FLOW_BOUND, OpenAPI_failure_code_FILTER_RES, OpenAPI_failure_code_MISS_REDI_SER_ADDR, OpenAPI_failure_code_CM_END_USER_SER_DENIED, OpenAPI_failure_code_CM_CREDIT_CON_NOT_APP, OpenAPI_failure_code_CM_AUTH_REJ, OpenAPI_failure_code_CM_USER_UNK, OpenAPI_failure_code_CM_RAT_FAILED, OpenAPI_failure_code_UE_STA_SUSP } OpenAPI_failure_code_e; -OpenAPI_failure_code_t *OpenAPI_failure_code_create( - ); -void OpenAPI_failure_code_free(OpenAPI_failure_code_t *failure_code); -OpenAPI_failure_code_t *OpenAPI_failure_code_parseFromJSON(cJSON *failure_codeJSON); -cJSON *OpenAPI_failure_code_convertToJSON(OpenAPI_failure_code_t *failure_code); -OpenAPI_failure_code_t *OpenAPI_failure_code_copy(OpenAPI_failure_code_t *dst, OpenAPI_failure_code_t *src); +char* OpenAPI_failure_code_ToString(OpenAPI_failure_code_e failure_code); + +OpenAPI_failure_code_e OpenAPI_failure_code_FromString(char* failure_code); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/flow_direction.c b/lib/sbi/openapi/model/flow_direction.c index 971695bda..52fdae576 100644 --- a/lib/sbi/openapi/model/flow_direction.c +++ b/lib/sbi/openapi/model/flow_direction.c @@ -4,82 +4,27 @@ #include #include "flow_direction.h" -OpenAPI_flow_direction_t *OpenAPI_flow_direction_create( - ) +char* OpenAPI_flow_direction_ToString(OpenAPI_flow_direction_e flow_direction) { - OpenAPI_flow_direction_t *flow_direction_local_var = OpenAPI_malloc(sizeof(OpenAPI_flow_direction_t)); - if (!flow_direction_local_var) { - return NULL; - } - - return flow_direction_local_var; + const char *flow_directionArray[] = { "NULL", "DOWNLINK", "UPLINK", "BIDIRECTIONAL", "UNSPECIFIED" }; + size_t sizeofArray = sizeof(flow_directionArray) / sizeof(flow_directionArray[0]); + if (flow_direction < sizeofArray) + return (char *)flow_directionArray[flow_direction]; + else + return (char *)"Unknown"; } -void OpenAPI_flow_direction_free(OpenAPI_flow_direction_t *flow_direction) +OpenAPI_flow_direction_e OpenAPI_flow_direction_FromString(char* flow_direction) { - if (NULL == flow_direction) { - return; + int stringToReturn = 0; + const char *flow_directionArray[] = { "NULL", "DOWNLINK", "UPLINK", "BIDIRECTIONAL", "UNSPECIFIED" }; + size_t sizeofArray = sizeof(flow_directionArray) / sizeof(flow_directionArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(flow_direction, flow_directionArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(flow_direction); -} - -cJSON *OpenAPI_flow_direction_convertToJSON(OpenAPI_flow_direction_t *flow_direction) -{ - cJSON *item = NULL; - - if (flow_direction == NULL) { - ogs_error("OpenAPI_flow_direction_convertToJSON() failed [FlowDirection]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_flow_direction_t *OpenAPI_flow_direction_parseFromJSON(cJSON *flow_directionJSON) -{ - OpenAPI_flow_direction_t *flow_direction_local_var = NULL; - flow_direction_local_var = OpenAPI_flow_direction_create ( - ); - - return flow_direction_local_var; -end: - return NULL; -} - -OpenAPI_flow_direction_t *OpenAPI_flow_direction_copy(OpenAPI_flow_direction_t *dst, OpenAPI_flow_direction_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_flow_direction_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_flow_direction_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_flow_direction_free(dst); - dst = OpenAPI_flow_direction_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/flow_direction.h b/lib/sbi/openapi/model/flow_direction.h index 4e02f8133..6185e4db6 100644 --- a/lib/sbi/openapi/model/flow_direction.h +++ b/lib/sbi/openapi/model/flow_direction.h @@ -1,7 +1,7 @@ /* * flow_direction.h * - * Possible values are - DOWNLINK: The corresponding filter applies for traffic to the UE. - UPLINK: The corresponding filter applies for traffic from the UE. - BIDIRECTIONAL: The corresponding filter applies for traffic both to and from the UE. - UNSPECIFIED: The corresponding filter applies for traffic to the UE (downlink), but has no specific direction declared. The service data flow detection shall apply the filter for uplink traffic as if the filter was bidirectional. The PCF shall not use the value UNSPECIFIED in filters created by the network in NW-initiated procedures. The PCF shall only include the value UNSPECIFIED in filters in UE-initiated procedures if the same value is received from the SMF. + * */ #ifndef _OpenAPI_flow_direction_H_ @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_flow_direction_s OpenAPI_flow_direction_t; -typedef struct OpenAPI_flow_direction_s { -} OpenAPI_flow_direction_t; +typedef enum { OpenAPI_flow_direction_NULL = 0, OpenAPI_flow_direction_DOWNLINK, OpenAPI_flow_direction_UPLINK, OpenAPI_flow_direction_BIDIRECTIONAL, OpenAPI_flow_direction_UNSPECIFIED } OpenAPI_flow_direction_e; -OpenAPI_flow_direction_t *OpenAPI_flow_direction_create( - ); -void OpenAPI_flow_direction_free(OpenAPI_flow_direction_t *flow_direction); -OpenAPI_flow_direction_t *OpenAPI_flow_direction_parseFromJSON(cJSON *flow_directionJSON); -cJSON *OpenAPI_flow_direction_convertToJSON(OpenAPI_flow_direction_t *flow_direction); -OpenAPI_flow_direction_t *OpenAPI_flow_direction_copy(OpenAPI_flow_direction_t *dst, OpenAPI_flow_direction_t *src); +char* OpenAPI_flow_direction_ToString(OpenAPI_flow_direction_e flow_direction); + +OpenAPI_flow_direction_e OpenAPI_flow_direction_FromString(char* flow_direction); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/flow_information.c b/lib/sbi/openapi/model/flow_information.c index 2342e4ca3..1f8fe2fe9 100644 --- a/lib/sbi/openapi/model/flow_information.c +++ b/lib/sbi/openapi/model/flow_information.c @@ -12,7 +12,7 @@ OpenAPI_flow_information_t *OpenAPI_flow_information_create( char *tos_traffic_class, char *spi, char *flow_label, - OpenAPI_flow_direction_rm_t *flow_direction + OpenAPI_flow_direction_e flow_direction ) { OpenAPI_flow_information_t *flow_information_local_var = OpenAPI_malloc(sizeof(OpenAPI_flow_information_t)); @@ -43,7 +43,6 @@ void OpenAPI_flow_information_free(OpenAPI_flow_information_t *flow_information) ogs_free(flow_information->tos_traffic_class); ogs_free(flow_information->spi); ogs_free(flow_information->flow_label); - OpenAPI_flow_direction_rm_free(flow_information->flow_direction); ogs_free(flow_information); } @@ -113,13 +112,7 @@ cJSON *OpenAPI_flow_information_convertToJSON(OpenAPI_flow_information_t *flow_i } if (flow_information->flow_direction) { - cJSON *flow_direction_local_JSON = OpenAPI_flow_direction_rm_convertToJSON(flow_information->flow_direction); - if (flow_direction_local_JSON == NULL) { - ogs_error("OpenAPI_flow_information_convertToJSON() failed [flow_direction]"); - goto end; - } - cJSON_AddItemToObject(item, "flowDirection", flow_direction_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "flowDirection", OpenAPI_flow_direction_ToString(flow_information->flow_direction)) == NULL) { ogs_error("OpenAPI_flow_information_convertToJSON() failed [flow_direction]"); goto end; } @@ -195,9 +188,13 @@ OpenAPI_flow_information_t *OpenAPI_flow_information_parseFromJSON(cJSON *flow_i cJSON *flow_direction = cJSON_GetObjectItemCaseSensitive(flow_informationJSON, "flowDirection"); - OpenAPI_flow_direction_rm_t *flow_direction_local_nonprim = NULL; + OpenAPI_flow_direction_e flow_directionVariable; if (flow_direction) { - flow_direction_local_nonprim = OpenAPI_flow_direction_rm_parseFromJSON(flow_direction); + if (!cJSON_IsString(flow_direction)) { + ogs_error("OpenAPI_flow_information_parseFromJSON() failed [flow_direction]"); + goto end; + } + flow_directionVariable = OpenAPI_flow_direction_FromString(flow_direction->valuestring); } flow_information_local_var = OpenAPI_flow_information_create ( @@ -208,7 +205,7 @@ OpenAPI_flow_information_t *OpenAPI_flow_information_parseFromJSON(cJSON *flow_i tos_traffic_class ? ogs_strdup(tos_traffic_class->valuestring) : NULL, spi ? ogs_strdup(spi->valuestring) : NULL, flow_label ? ogs_strdup(flow_label->valuestring) : NULL, - flow_direction ? flow_direction_local_nonprim : NULL + flow_direction ? flow_directionVariable : 0 ); return flow_information_local_var; diff --git a/lib/sbi/openapi/model/flow_information.h b/lib/sbi/openapi/model/flow_information.h index 003217517..ab2e4302e 100644 --- a/lib/sbi/openapi/model/flow_information.h +++ b/lib/sbi/openapi/model/flow_information.h @@ -13,7 +13,7 @@ #include "../include/keyValuePair.h" #include "../include/binary.h" #include "eth_flow_description.h" -#include "flow_direction_rm.h" +#include "flow_direction.h" #ifdef __cplusplus extern "C" { @@ -28,7 +28,7 @@ typedef struct OpenAPI_flow_information_s { char *tos_traffic_class; char *spi; char *flow_label; - struct OpenAPI_flow_direction_rm_s *flow_direction; + OpenAPI_flow_direction_e flow_direction; } OpenAPI_flow_information_t; OpenAPI_flow_information_t *OpenAPI_flow_information_create( @@ -39,7 +39,7 @@ OpenAPI_flow_information_t *OpenAPI_flow_information_create( char *tos_traffic_class, char *spi, char *flow_label, - OpenAPI_flow_direction_rm_t *flow_direction + OpenAPI_flow_direction_e flow_direction ); void OpenAPI_flow_information_free(OpenAPI_flow_information_t *flow_information); OpenAPI_flow_information_t *OpenAPI_flow_information_parseFromJSON(cJSON *flow_informationJSON); diff --git a/lib/sbi/openapi/model/ma_pdu_indication.c b/lib/sbi/openapi/model/ma_pdu_indication.c index 6bb8f8afc..56d100d24 100644 --- a/lib/sbi/openapi/model/ma_pdu_indication.c +++ b/lib/sbi/openapi/model/ma_pdu_indication.c @@ -4,82 +4,27 @@ #include #include "ma_pdu_indication.h" -OpenAPI_ma_pdu_indication_t *OpenAPI_ma_pdu_indication_create( - ) +char* OpenAPI_ma_pdu_indication_ToString(OpenAPI_ma_pdu_indication_e ma_pdu_indication) { - OpenAPI_ma_pdu_indication_t *ma_pdu_indication_local_var = OpenAPI_malloc(sizeof(OpenAPI_ma_pdu_indication_t)); - if (!ma_pdu_indication_local_var) { - return NULL; - } - - return ma_pdu_indication_local_var; + const char *ma_pdu_indicationArray[] = { "NULL", "MA_PDU_REQUEST", "MA_PDU_NETWORK_UPGRADE_ALLOWED" }; + size_t sizeofArray = sizeof(ma_pdu_indicationArray) / sizeof(ma_pdu_indicationArray[0]); + if (ma_pdu_indication < sizeofArray) + return (char *)ma_pdu_indicationArray[ma_pdu_indication]; + else + return (char *)"Unknown"; } -void OpenAPI_ma_pdu_indication_free(OpenAPI_ma_pdu_indication_t *ma_pdu_indication) +OpenAPI_ma_pdu_indication_e OpenAPI_ma_pdu_indication_FromString(char* ma_pdu_indication) { - if (NULL == ma_pdu_indication) { - return; + int stringToReturn = 0; + const char *ma_pdu_indicationArray[] = { "NULL", "MA_PDU_REQUEST", "MA_PDU_NETWORK_UPGRADE_ALLOWED" }; + size_t sizeofArray = sizeof(ma_pdu_indicationArray) / sizeof(ma_pdu_indicationArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(ma_pdu_indication, ma_pdu_indicationArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(ma_pdu_indication); -} - -cJSON *OpenAPI_ma_pdu_indication_convertToJSON(OpenAPI_ma_pdu_indication_t *ma_pdu_indication) -{ - cJSON *item = NULL; - - if (ma_pdu_indication == NULL) { - ogs_error("OpenAPI_ma_pdu_indication_convertToJSON() failed [MaPduIndication]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_ma_pdu_indication_t *OpenAPI_ma_pdu_indication_parseFromJSON(cJSON *ma_pdu_indicationJSON) -{ - OpenAPI_ma_pdu_indication_t *ma_pdu_indication_local_var = NULL; - ma_pdu_indication_local_var = OpenAPI_ma_pdu_indication_create ( - ); - - return ma_pdu_indication_local_var; -end: - return NULL; -} - -OpenAPI_ma_pdu_indication_t *OpenAPI_ma_pdu_indication_copy(OpenAPI_ma_pdu_indication_t *dst, OpenAPI_ma_pdu_indication_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_ma_pdu_indication_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_ma_pdu_indication_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_ma_pdu_indication_free(dst); - dst = OpenAPI_ma_pdu_indication_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/ma_pdu_indication.h b/lib/sbi/openapi/model/ma_pdu_indication.h index 69fe1ac27..0c5fd0a69 100644 --- a/lib/sbi/openapi/model/ma_pdu_indication.h +++ b/lib/sbi/openapi/model/ma_pdu_indication.h @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_ma_pdu_indication_s OpenAPI_ma_pdu_indication_t; -typedef struct OpenAPI_ma_pdu_indication_s { -} OpenAPI_ma_pdu_indication_t; +typedef enum { OpenAPI_ma_pdu_indication_NULL = 0, OpenAPI_ma_pdu_indication_MA_PDU_REQUEST, OpenAPI_ma_pdu_indication_MA_PDU_NETWORK_UPGRADE_ALLOWED } OpenAPI_ma_pdu_indication_e; -OpenAPI_ma_pdu_indication_t *OpenAPI_ma_pdu_indication_create( - ); -void OpenAPI_ma_pdu_indication_free(OpenAPI_ma_pdu_indication_t *ma_pdu_indication); -OpenAPI_ma_pdu_indication_t *OpenAPI_ma_pdu_indication_parseFromJSON(cJSON *ma_pdu_indicationJSON); -cJSON *OpenAPI_ma_pdu_indication_convertToJSON(OpenAPI_ma_pdu_indication_t *ma_pdu_indication); -OpenAPI_ma_pdu_indication_t *OpenAPI_ma_pdu_indication_copy(OpenAPI_ma_pdu_indication_t *dst, OpenAPI_ma_pdu_indication_t *src); +char* OpenAPI_ma_pdu_indication_ToString(OpenAPI_ma_pdu_indication_e ma_pdu_indication); + +OpenAPI_ma_pdu_indication_e OpenAPI_ma_pdu_indication_FromString(char* ma_pdu_indication); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/metering_method.c b/lib/sbi/openapi/model/metering_method.c index ed7272ebf..c53121900 100644 --- a/lib/sbi/openapi/model/metering_method.c +++ b/lib/sbi/openapi/model/metering_method.c @@ -4,82 +4,27 @@ #include #include "metering_method.h" -OpenAPI_metering_method_t *OpenAPI_metering_method_create( - ) +char* OpenAPI_metering_method_ToString(OpenAPI_metering_method_e metering_method) { - OpenAPI_metering_method_t *metering_method_local_var = OpenAPI_malloc(sizeof(OpenAPI_metering_method_t)); - if (!metering_method_local_var) { - return NULL; - } - - return metering_method_local_var; + const char *metering_methodArray[] = { "NULL", "DURATION", "VOLUME", "DURATION_VOLUME", "EVENT" }; + size_t sizeofArray = sizeof(metering_methodArray) / sizeof(metering_methodArray[0]); + if (metering_method < sizeofArray) + return (char *)metering_methodArray[metering_method]; + else + return (char *)"Unknown"; } -void OpenAPI_metering_method_free(OpenAPI_metering_method_t *metering_method) +OpenAPI_metering_method_e OpenAPI_metering_method_FromString(char* metering_method) { - if (NULL == metering_method) { - return; + int stringToReturn = 0; + const char *metering_methodArray[] = { "NULL", "DURATION", "VOLUME", "DURATION_VOLUME", "EVENT" }; + size_t sizeofArray = sizeof(metering_methodArray) / sizeof(metering_methodArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(metering_method, metering_methodArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(metering_method); -} - -cJSON *OpenAPI_metering_method_convertToJSON(OpenAPI_metering_method_t *metering_method) -{ - cJSON *item = NULL; - - if (metering_method == NULL) { - ogs_error("OpenAPI_metering_method_convertToJSON() failed [MeteringMethod]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_metering_method_t *OpenAPI_metering_method_parseFromJSON(cJSON *metering_methodJSON) -{ - OpenAPI_metering_method_t *metering_method_local_var = NULL; - metering_method_local_var = OpenAPI_metering_method_create ( - ); - - return metering_method_local_var; -end: - return NULL; -} - -OpenAPI_metering_method_t *OpenAPI_metering_method_copy(OpenAPI_metering_method_t *dst, OpenAPI_metering_method_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_metering_method_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_metering_method_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_metering_method_free(dst); - dst = OpenAPI_metering_method_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/metering_method.h b/lib/sbi/openapi/model/metering_method.h index 3d0451b9c..0700c74ab 100644 --- a/lib/sbi/openapi/model/metering_method.h +++ b/lib/sbi/openapi/model/metering_method.h @@ -1,7 +1,7 @@ /* * metering_method.h * - * Possible values are - DURATION: Indicates that the duration of the service data flow traffic shall be metered. - VOLUME: Indicates that volume of the service data flow traffic shall be metered. - DURATION_VOLUME: Indicates that the duration and the volume of the service data flow traffic shall be metered. - EVENT: Indicates that events of the service data flow traffic shall be metered. + * */ #ifndef _OpenAPI_metering_method_H_ @@ -12,22 +12,16 @@ #include "../include/list.h" #include "../include/keyValuePair.h" #include "../include/binary.h" -#include "null_value.h" #ifdef __cplusplus extern "C" { #endif -typedef struct OpenAPI_metering_method_s OpenAPI_metering_method_t; -typedef struct OpenAPI_metering_method_s { -} OpenAPI_metering_method_t; +typedef enum { OpenAPI_metering_method_NULL = 0, OpenAPI_metering_method_DURATION, OpenAPI_metering_method_VOLUME, OpenAPI_metering_method_DURATION_VOLUME, OpenAPI_metering_method_EVENT } OpenAPI_metering_method_e; -OpenAPI_metering_method_t *OpenAPI_metering_method_create( - ); -void OpenAPI_metering_method_free(OpenAPI_metering_method_t *metering_method); -OpenAPI_metering_method_t *OpenAPI_metering_method_parseFromJSON(cJSON *metering_methodJSON); -cJSON *OpenAPI_metering_method_convertToJSON(OpenAPI_metering_method_t *metering_method); -OpenAPI_metering_method_t *OpenAPI_metering_method_copy(OpenAPI_metering_method_t *dst, OpenAPI_metering_method_t *src); +char* OpenAPI_metering_method_ToString(OpenAPI_metering_method_e metering_method); + +OpenAPI_metering_method_e OpenAPI_metering_method_FromString(char* metering_method); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/packet_filter_info.c b/lib/sbi/openapi/model/packet_filter_info.c index 165b57768..af9c58a75 100644 --- a/lib/sbi/openapi/model/packet_filter_info.c +++ b/lib/sbi/openapi/model/packet_filter_info.c @@ -10,7 +10,7 @@ OpenAPI_packet_filter_info_t *OpenAPI_packet_filter_info_create( char *tos_traffic_class, char *spi, char *flow_label, - OpenAPI_flow_direction_t *flow_direction + OpenAPI_flow_direction_e flow_direction ) { OpenAPI_packet_filter_info_t *packet_filter_info_local_var = OpenAPI_malloc(sizeof(OpenAPI_packet_filter_info_t)); @@ -38,7 +38,6 @@ void OpenAPI_packet_filter_info_free(OpenAPI_packet_filter_info_t *packet_filter ogs_free(packet_filter_info->tos_traffic_class); ogs_free(packet_filter_info->spi); ogs_free(packet_filter_info->flow_label); - OpenAPI_flow_direction_free(packet_filter_info->flow_direction); ogs_free(packet_filter_info); } @@ -88,13 +87,7 @@ cJSON *OpenAPI_packet_filter_info_convertToJSON(OpenAPI_packet_filter_info_t *pa } if (packet_filter_info->flow_direction) { - cJSON *flow_direction_local_JSON = OpenAPI_flow_direction_convertToJSON(packet_filter_info->flow_direction); - if (flow_direction_local_JSON == NULL) { - ogs_error("OpenAPI_packet_filter_info_convertToJSON() failed [flow_direction]"); - goto end; - } - cJSON_AddItemToObject(item, "flowDirection", flow_direction_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "flowDirection", OpenAPI_flow_direction_ToString(packet_filter_info->flow_direction)) == NULL) { ogs_error("OpenAPI_packet_filter_info_convertToJSON() failed [flow_direction]"); goto end; } @@ -154,9 +147,13 @@ OpenAPI_packet_filter_info_t *OpenAPI_packet_filter_info_parseFromJSON(cJSON *pa cJSON *flow_direction = cJSON_GetObjectItemCaseSensitive(packet_filter_infoJSON, "flowDirection"); - OpenAPI_flow_direction_t *flow_direction_local_nonprim = NULL; + OpenAPI_flow_direction_e flow_directionVariable; if (flow_direction) { - flow_direction_local_nonprim = OpenAPI_flow_direction_parseFromJSON(flow_direction); + if (!cJSON_IsString(flow_direction)) { + ogs_error("OpenAPI_packet_filter_info_parseFromJSON() failed [flow_direction]"); + goto end; + } + flow_directionVariable = OpenAPI_flow_direction_FromString(flow_direction->valuestring); } packet_filter_info_local_var = OpenAPI_packet_filter_info_create ( @@ -165,7 +162,7 @@ OpenAPI_packet_filter_info_t *OpenAPI_packet_filter_info_parseFromJSON(cJSON *pa tos_traffic_class ? ogs_strdup(tos_traffic_class->valuestring) : NULL, spi ? ogs_strdup(spi->valuestring) : NULL, flow_label ? ogs_strdup(flow_label->valuestring) : NULL, - flow_direction ? flow_direction_local_nonprim : NULL + flow_direction ? flow_directionVariable : 0 ); return packet_filter_info_local_var; diff --git a/lib/sbi/openapi/model/packet_filter_info.h b/lib/sbi/openapi/model/packet_filter_info.h index 6cb76c865..d553667bc 100644 --- a/lib/sbi/openapi/model/packet_filter_info.h +++ b/lib/sbi/openapi/model/packet_filter_info.h @@ -25,7 +25,7 @@ typedef struct OpenAPI_packet_filter_info_s { char *tos_traffic_class; char *spi; char *flow_label; - struct OpenAPI_flow_direction_s *flow_direction; + OpenAPI_flow_direction_e flow_direction; } OpenAPI_packet_filter_info_t; OpenAPI_packet_filter_info_t *OpenAPI_packet_filter_info_create( @@ -34,7 +34,7 @@ OpenAPI_packet_filter_info_t *OpenAPI_packet_filter_info_create( char *tos_traffic_class, char *spi, char *flow_label, - OpenAPI_flow_direction_t *flow_direction + OpenAPI_flow_direction_e flow_direction ); void OpenAPI_packet_filter_info_free(OpenAPI_packet_filter_info_t *packet_filter_info); OpenAPI_packet_filter_info_t *OpenAPI_packet_filter_info_parseFromJSON(cJSON *packet_filter_infoJSON); diff --git a/lib/sbi/openapi/model/partial_success_report.c b/lib/sbi/openapi/model/partial_success_report.c index b520e4e60..d80a98b4f 100644 --- a/lib/sbi/openapi/model/partial_success_report.c +++ b/lib/sbi/openapi/model/partial_success_report.c @@ -5,7 +5,7 @@ #include "partial_success_report.h" OpenAPI_partial_success_report_t *OpenAPI_partial_success_report_create( - OpenAPI_failure_cause_t *failure_cause, + OpenAPI_failure_cause_e failure_cause, OpenAPI_list_t *rule_reports, OpenAPI_list_t *sess_rule_reports, OpenAPI_ue_camping_rep_t *ue_camping_rep @@ -29,7 +29,6 @@ void OpenAPI_partial_success_report_free(OpenAPI_partial_success_report_t *parti return; } OpenAPI_lnode_t *node; - OpenAPI_failure_cause_free(partial_success_report->failure_cause); OpenAPI_list_for_each(partial_success_report->rule_reports, node) { OpenAPI_rule_report_free(node->data); } @@ -56,13 +55,7 @@ cJSON *OpenAPI_partial_success_report_convertToJSON(OpenAPI_partial_success_repo ogs_error("OpenAPI_partial_success_report_convertToJSON() failed [failure_cause]"); goto end; } - cJSON *failure_cause_local_JSON = OpenAPI_failure_cause_convertToJSON(partial_success_report->failure_cause); - if (failure_cause_local_JSON == NULL) { - ogs_error("OpenAPI_partial_success_report_convertToJSON() failed [failure_cause]"); - goto end; - } - cJSON_AddItemToObject(item, "failureCause", failure_cause_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "failureCause", OpenAPI_failure_cause_ToString(partial_success_report->failure_cause)) == NULL) { ogs_error("OpenAPI_partial_success_report_convertToJSON() failed [failure_cause]"); goto end; } @@ -133,9 +126,13 @@ OpenAPI_partial_success_report_t *OpenAPI_partial_success_report_parseFromJSON(c goto end; } - OpenAPI_failure_cause_t *failure_cause_local_nonprim = NULL; + OpenAPI_failure_cause_e failure_causeVariable; - failure_cause_local_nonprim = OpenAPI_failure_cause_parseFromJSON(failure_cause); + if (!cJSON_IsString(failure_cause)) { + ogs_error("OpenAPI_partial_success_report_parseFromJSON() failed [failure_cause]"); + goto end; + } + failure_causeVariable = OpenAPI_failure_cause_FromString(failure_cause->valuestring); cJSON *rule_reports = cJSON_GetObjectItemCaseSensitive(partial_success_reportJSON, "ruleReports"); @@ -191,7 +188,7 @@ OpenAPI_partial_success_report_t *OpenAPI_partial_success_report_parseFromJSON(c } partial_success_report_local_var = OpenAPI_partial_success_report_create ( - failure_cause_local_nonprim, + failure_causeVariable, rule_reports ? rule_reportsList : NULL, sess_rule_reports ? sess_rule_reportsList : NULL, ue_camping_rep ? ue_camping_rep_local_nonprim : NULL diff --git a/lib/sbi/openapi/model/partial_success_report.h b/lib/sbi/openapi/model/partial_success_report.h index bcb2c92f8..908e1c9aa 100644 --- a/lib/sbi/openapi/model/partial_success_report.h +++ b/lib/sbi/openapi/model/partial_success_report.h @@ -23,14 +23,14 @@ extern "C" { typedef struct OpenAPI_partial_success_report_s OpenAPI_partial_success_report_t; typedef struct OpenAPI_partial_success_report_s { - struct OpenAPI_failure_cause_s *failure_cause; + OpenAPI_failure_cause_e failure_cause; OpenAPI_list_t *rule_reports; OpenAPI_list_t *sess_rule_reports; struct OpenAPI_ue_camping_rep_s *ue_camping_rep; } OpenAPI_partial_success_report_t; OpenAPI_partial_success_report_t *OpenAPI_partial_success_report_create( - OpenAPI_failure_cause_t *failure_cause, + OpenAPI_failure_cause_e failure_cause, OpenAPI_list_t *rule_reports, OpenAPI_list_t *sess_rule_reports, OpenAPI_ue_camping_rep_t *ue_camping_rep diff --git a/lib/sbi/openapi/model/pcc_rule.c b/lib/sbi/openapi/model/pcc_rule.c index d6934eb74..9d4424642 100644 --- a/lib/sbi/openapi/model/pcc_rule.c +++ b/lib/sbi/openapi/model/pcc_rule.c @@ -10,7 +10,7 @@ OpenAPI_pcc_rule_t *OpenAPI_pcc_rule_create( int cont_ver, char *pcc_rule_id, int precedence, - OpenAPI_af_sig_protocol_t *af_sig_protocol, + OpenAPI_af_sig_protocol_e af_sig_protocol, int app_reloc, OpenAPI_list_t *ref_qos_data, OpenAPI_list_t *ref_alt_qos_params, @@ -65,7 +65,6 @@ void OpenAPI_pcc_rule_free(OpenAPI_pcc_rule_t *pcc_rule) OpenAPI_list_free(pcc_rule->flow_infos); ogs_free(pcc_rule->app_id); ogs_free(pcc_rule->pcc_rule_id); - OpenAPI_af_sig_protocol_free(pcc_rule->af_sig_protocol); OpenAPI_list_for_each(pcc_rule->ref_qos_data, node) { ogs_free(node->data); } @@ -165,13 +164,7 @@ cJSON *OpenAPI_pcc_rule_convertToJSON(OpenAPI_pcc_rule_t *pcc_rule) } if (pcc_rule->af_sig_protocol) { - cJSON *af_sig_protocol_local_JSON = OpenAPI_af_sig_protocol_convertToJSON(pcc_rule->af_sig_protocol); - if (af_sig_protocol_local_JSON == NULL) { - ogs_error("OpenAPI_pcc_rule_convertToJSON() failed [af_sig_protocol]"); - goto end; - } - cJSON_AddItemToObject(item, "afSigProtocol", af_sig_protocol_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "afSigProtocol", OpenAPI_af_sig_protocol_ToString(pcc_rule->af_sig_protocol)) == NULL) { ogs_error("OpenAPI_pcc_rule_convertToJSON() failed [af_sig_protocol]"); goto end; } @@ -423,9 +416,13 @@ OpenAPI_pcc_rule_t *OpenAPI_pcc_rule_parseFromJSON(cJSON *pcc_ruleJSON) cJSON *af_sig_protocol = cJSON_GetObjectItemCaseSensitive(pcc_ruleJSON, "afSigProtocol"); - OpenAPI_af_sig_protocol_t *af_sig_protocol_local_nonprim = NULL; + OpenAPI_af_sig_protocol_e af_sig_protocolVariable; if (af_sig_protocol) { - af_sig_protocol_local_nonprim = OpenAPI_af_sig_protocol_parseFromJSON(af_sig_protocol); + if (!cJSON_IsString(af_sig_protocol)) { + ogs_error("OpenAPI_pcc_rule_parseFromJSON() failed [af_sig_protocol]"); + goto end; + } + af_sig_protocolVariable = OpenAPI_af_sig_protocol_FromString(af_sig_protocol->valuestring); } cJSON *app_reloc = cJSON_GetObjectItemCaseSensitive(pcc_ruleJSON, "appReloc"); @@ -635,7 +632,7 @@ OpenAPI_pcc_rule_t *OpenAPI_pcc_rule_parseFromJSON(cJSON *pcc_ruleJSON) cont_ver ? cont_ver->valuedouble : 0, ogs_strdup(pcc_rule_id->valuestring), precedence ? precedence->valuedouble : 0, - af_sig_protocol ? af_sig_protocol_local_nonprim : NULL, + af_sig_protocol ? af_sig_protocolVariable : 0, app_reloc ? app_reloc->valueint : 0, ref_qos_data ? ref_qos_dataList : NULL, ref_alt_qos_params ? ref_alt_qos_paramsList : NULL, diff --git a/lib/sbi/openapi/model/pcc_rule.h b/lib/sbi/openapi/model/pcc_rule.h index f201a7515..9a96309df 100644 --- a/lib/sbi/openapi/model/pcc_rule.h +++ b/lib/sbi/openapi/model/pcc_rule.h @@ -27,7 +27,7 @@ typedef struct OpenAPI_pcc_rule_s { int cont_ver; char *pcc_rule_id; int precedence; - struct OpenAPI_af_sig_protocol_s *af_sig_protocol; + OpenAPI_af_sig_protocol_e af_sig_protocol; int app_reloc; OpenAPI_list_t *ref_qos_data; OpenAPI_list_t *ref_alt_qos_params; @@ -49,7 +49,7 @@ OpenAPI_pcc_rule_t *OpenAPI_pcc_rule_create( int cont_ver, char *pcc_rule_id, int precedence, - OpenAPI_af_sig_protocol_t *af_sig_protocol, + OpenAPI_af_sig_protocol_e af_sig_protocol, int app_reloc, OpenAPI_list_t *ref_qos_data, OpenAPI_list_t *ref_alt_qos_params, diff --git a/lib/sbi/openapi/model/pdu_session_rel_cause.c b/lib/sbi/openapi/model/pdu_session_rel_cause.c index c666eb233..339ac0c4a 100644 --- a/lib/sbi/openapi/model/pdu_session_rel_cause.c +++ b/lib/sbi/openapi/model/pdu_session_rel_cause.c @@ -4,82 +4,27 @@ #include #include "pdu_session_rel_cause.h" -OpenAPI_pdu_session_rel_cause_t *OpenAPI_pdu_session_rel_cause_create( - ) +char* OpenAPI_pdu_session_rel_cause_ToString(OpenAPI_pdu_session_rel_cause_e pdu_session_rel_cause) { - OpenAPI_pdu_session_rel_cause_t *pdu_session_rel_cause_local_var = OpenAPI_malloc(sizeof(OpenAPI_pdu_session_rel_cause_t)); - if (!pdu_session_rel_cause_local_var) { - return NULL; - } - - return pdu_session_rel_cause_local_var; + const char *pdu_session_rel_causeArray[] = { "NULL", "PS_TO_CS_HO" }; + size_t sizeofArray = sizeof(pdu_session_rel_causeArray) / sizeof(pdu_session_rel_causeArray[0]); + if (pdu_session_rel_cause < sizeofArray) + return (char *)pdu_session_rel_causeArray[pdu_session_rel_cause]; + else + return (char *)"Unknown"; } -void OpenAPI_pdu_session_rel_cause_free(OpenAPI_pdu_session_rel_cause_t *pdu_session_rel_cause) +OpenAPI_pdu_session_rel_cause_e OpenAPI_pdu_session_rel_cause_FromString(char* pdu_session_rel_cause) { - if (NULL == pdu_session_rel_cause) { - return; + int stringToReturn = 0; + const char *pdu_session_rel_causeArray[] = { "NULL", "PS_TO_CS_HO" }; + size_t sizeofArray = sizeof(pdu_session_rel_causeArray) / sizeof(pdu_session_rel_causeArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(pdu_session_rel_cause, pdu_session_rel_causeArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(pdu_session_rel_cause); -} - -cJSON *OpenAPI_pdu_session_rel_cause_convertToJSON(OpenAPI_pdu_session_rel_cause_t *pdu_session_rel_cause) -{ - cJSON *item = NULL; - - if (pdu_session_rel_cause == NULL) { - ogs_error("OpenAPI_pdu_session_rel_cause_convertToJSON() failed [PduSessionRelCause]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_pdu_session_rel_cause_t *OpenAPI_pdu_session_rel_cause_parseFromJSON(cJSON *pdu_session_rel_causeJSON) -{ - OpenAPI_pdu_session_rel_cause_t *pdu_session_rel_cause_local_var = NULL; - pdu_session_rel_cause_local_var = OpenAPI_pdu_session_rel_cause_create ( - ); - - return pdu_session_rel_cause_local_var; -end: - return NULL; -} - -OpenAPI_pdu_session_rel_cause_t *OpenAPI_pdu_session_rel_cause_copy(OpenAPI_pdu_session_rel_cause_t *dst, OpenAPI_pdu_session_rel_cause_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_pdu_session_rel_cause_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_pdu_session_rel_cause_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_pdu_session_rel_cause_free(dst); - dst = OpenAPI_pdu_session_rel_cause_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/pdu_session_rel_cause.h b/lib/sbi/openapi/model/pdu_session_rel_cause.h index 45cdcb0fc..c8856aa55 100644 --- a/lib/sbi/openapi/model/pdu_session_rel_cause.h +++ b/lib/sbi/openapi/model/pdu_session_rel_cause.h @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_pdu_session_rel_cause_s OpenAPI_pdu_session_rel_cause_t; -typedef struct OpenAPI_pdu_session_rel_cause_s { -} OpenAPI_pdu_session_rel_cause_t; +typedef enum { OpenAPI_pdu_session_rel_cause_NULL = 0, OpenAPI_pdu_session_rel_cause_PS_TO_CS_HO } OpenAPI_pdu_session_rel_cause_e; -OpenAPI_pdu_session_rel_cause_t *OpenAPI_pdu_session_rel_cause_create( - ); -void OpenAPI_pdu_session_rel_cause_free(OpenAPI_pdu_session_rel_cause_t *pdu_session_rel_cause); -OpenAPI_pdu_session_rel_cause_t *OpenAPI_pdu_session_rel_cause_parseFromJSON(cJSON *pdu_session_rel_causeJSON); -cJSON *OpenAPI_pdu_session_rel_cause_convertToJSON(OpenAPI_pdu_session_rel_cause_t *pdu_session_rel_cause); -OpenAPI_pdu_session_rel_cause_t *OpenAPI_pdu_session_rel_cause_copy(OpenAPI_pdu_session_rel_cause_t *dst, OpenAPI_pdu_session_rel_cause_t *src); +char* OpenAPI_pdu_session_rel_cause_ToString(OpenAPI_pdu_session_rel_cause_e pdu_session_rel_cause); + +OpenAPI_pdu_session_rel_cause_e OpenAPI_pdu_session_rel_cause_FromString(char* pdu_session_rel_cause); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/policy_association_request.c b/lib/sbi/openapi/model/policy_association_request.c index 8982fd14f..70289d1d3 100644 --- a/lib/sbi/openapi/model/policy_association_request.c +++ b/lib/sbi/openapi/model/policy_association_request.c @@ -28,7 +28,7 @@ OpenAPI_policy_association_request_t *OpenAPI_policy_association_request_create( OpenAPI_list_t *mapping_snssais, OpenAPI_list_t *n3g_allowed_snssais, OpenAPI_guami_t *guami, - char *servive_name, + char *service_name, OpenAPI_trace_data_t *trace_req, char *supp_feat ) @@ -60,7 +60,7 @@ OpenAPI_policy_association_request_t *OpenAPI_policy_association_request_create( policy_association_request_local_var->mapping_snssais = mapping_snssais; policy_association_request_local_var->n3g_allowed_snssais = n3g_allowed_snssais; policy_association_request_local_var->guami = guami; - policy_association_request_local_var->servive_name = servive_name; + policy_association_request_local_var->service_name = service_name; policy_association_request_local_var->trace_req = trace_req; policy_association_request_local_var->supp_feat = supp_feat; @@ -111,7 +111,7 @@ void OpenAPI_policy_association_request_free(OpenAPI_policy_association_request_ } OpenAPI_list_free(policy_association_request->n3g_allowed_snssais); OpenAPI_guami_free(policy_association_request->guami); - ogs_free(policy_association_request->servive_name); + ogs_free(policy_association_request->service_name); OpenAPI_trace_data_free(policy_association_request->trace_req); ogs_free(policy_association_request->supp_feat); ogs_free(policy_association_request); @@ -416,9 +416,9 @@ cJSON *OpenAPI_policy_association_request_convertToJSON(OpenAPI_policy_associati } } - if (policy_association_request->servive_name) { - if (cJSON_AddStringToObject(item, "serviveName", policy_association_request->servive_name) == NULL) { - ogs_error("OpenAPI_policy_association_request_convertToJSON() failed [servive_name]"); + if (policy_association_request->service_name) { + if (cJSON_AddStringToObject(item, "serviceName", policy_association_request->service_name) == NULL) { + ogs_error("OpenAPI_policy_association_request_convertToJSON() failed [service_name]"); goto end; } } @@ -756,11 +756,11 @@ OpenAPI_policy_association_request_t *OpenAPI_policy_association_request_parseFr guami_local_nonprim = OpenAPI_guami_parseFromJSON(guami); } - cJSON *servive_name = cJSON_GetObjectItemCaseSensitive(policy_association_requestJSON, "serviveName"); + cJSON *service_name = cJSON_GetObjectItemCaseSensitive(policy_association_requestJSON, "serviceName"); - if (servive_name) { - if (!cJSON_IsString(servive_name)) { - ogs_error("OpenAPI_policy_association_request_parseFromJSON() failed [servive_name]"); + if (service_name) { + if (!cJSON_IsString(service_name)) { + ogs_error("OpenAPI_policy_association_request_parseFromJSON() failed [service_name]"); goto end; } } @@ -808,7 +808,7 @@ OpenAPI_policy_association_request_t *OpenAPI_policy_association_request_parseFr mapping_snssais ? mapping_snssaisList : NULL, n3g_allowed_snssais ? n3g_allowed_snssaisList : NULL, guami ? guami_local_nonprim : NULL, - servive_name ? ogs_strdup(servive_name->valuestring) : NULL, + service_name ? ogs_strdup(service_name->valuestring) : NULL, trace_req ? trace_req_local_nonprim : NULL, ogs_strdup(supp_feat->valuestring) ); diff --git a/lib/sbi/openapi/model/policy_association_request.h b/lib/sbi/openapi/model/policy_association_request.h index 69f0eafcb..2e7e21209 100644 --- a/lib/sbi/openapi/model/policy_association_request.h +++ b/lib/sbi/openapi/model/policy_association_request.h @@ -1,7 +1,7 @@ /* * policy_association_request.h * - * Information which the NF service consumer provides when requesting the creation of a policy association. The serviveName property corresponds to the serviceName in the main body of the specification. + * Information which the NF service consumer provides when requesting the creation of a policy association. The serviceName property corresponds to the serviceName in the main body of the specification. */ #ifndef _OpenAPI_policy_association_request_H_ @@ -53,7 +53,7 @@ typedef struct OpenAPI_policy_association_request_s { OpenAPI_list_t *mapping_snssais; OpenAPI_list_t *n3g_allowed_snssais; struct OpenAPI_guami_s *guami; - char *servive_name; + char *service_name; struct OpenAPI_trace_data_s *trace_req; char *supp_feat; } OpenAPI_policy_association_request_t; @@ -82,7 +82,7 @@ OpenAPI_policy_association_request_t *OpenAPI_policy_association_request_create( OpenAPI_list_t *mapping_snssais, OpenAPI_list_t *n3g_allowed_snssais, OpenAPI_guami_t *guami, - char *servive_name, + char *service_name, OpenAPI_trace_data_t *trace_req, char *supp_feat ); diff --git a/lib/sbi/openapi/model/policy_control_request_trigger.c b/lib/sbi/openapi/model/policy_control_request_trigger.c index 3fa244568..23fc97e63 100644 --- a/lib/sbi/openapi/model/policy_control_request_trigger.c +++ b/lib/sbi/openapi/model/policy_control_request_trigger.c @@ -4,82 +4,27 @@ #include #include "policy_control_request_trigger.h" -OpenAPI_policy_control_request_trigger_t *OpenAPI_policy_control_request_trigger_create( - ) +char* OpenAPI_policy_control_request_trigger_ToString(OpenAPI_policy_control_request_trigger_e policy_control_request_trigger) { - OpenAPI_policy_control_request_trigger_t *policy_control_request_trigger_local_var = OpenAPI_malloc(sizeof(OpenAPI_policy_control_request_trigger_t)); - if (!policy_control_request_trigger_local_var) { - return NULL; - } - - return policy_control_request_trigger_local_var; + const char *policy_control_request_triggerArray[] = { "NULL", "PLMN_CH", "RES_MO_RE", "AC_TY_CH", "UE_IP_CH", "UE_MAC_CH", "AN_CH_COR", "US_RE", "APP_STA", "APP_STO", "AN_INFO", "CM_SES_FAIL", "PS_DA_OFF", "DEF_QOS_CH", "SE_AMBR_CH", "QOS_NOTIF", "NO_CREDIT", "REALLO_OF_CREDIT", "PRA_CH", "SAREA_CH", "SCNN_CH", "RE_TIMEOUT", "RES_RELEASE", "SUCC_RES_ALLO", "RAT_TY_CH", "REF_QOS_IND_CH", "NUM_OF_PACKET_FILTER", "UE_STATUS_RESUME", "UE_TZ_CH", "AUTH_PROF_CH", "QOS_MONITORING", "SCELL_CH", "EPS_FALLBACK", "MA_PDU", "TSN_ETHER_PORT", "TSN_CONTAINER", "_5G_RG_JOIN", "_5G_RG_LEAVE" }; + size_t sizeofArray = sizeof(policy_control_request_triggerArray) / sizeof(policy_control_request_triggerArray[0]); + if (policy_control_request_trigger < sizeofArray) + return (char *)policy_control_request_triggerArray[policy_control_request_trigger]; + else + return (char *)"Unknown"; } -void OpenAPI_policy_control_request_trigger_free(OpenAPI_policy_control_request_trigger_t *policy_control_request_trigger) +OpenAPI_policy_control_request_trigger_e OpenAPI_policy_control_request_trigger_FromString(char* policy_control_request_trigger) { - if (NULL == policy_control_request_trigger) { - return; + int stringToReturn = 0; + const char *policy_control_request_triggerArray[] = { "NULL", "PLMN_CH", "RES_MO_RE", "AC_TY_CH", "UE_IP_CH", "UE_MAC_CH", "AN_CH_COR", "US_RE", "APP_STA", "APP_STO", "AN_INFO", "CM_SES_FAIL", "PS_DA_OFF", "DEF_QOS_CH", "SE_AMBR_CH", "QOS_NOTIF", "NO_CREDIT", "REALLO_OF_CREDIT", "PRA_CH", "SAREA_CH", "SCNN_CH", "RE_TIMEOUT", "RES_RELEASE", "SUCC_RES_ALLO", "RAT_TY_CH", "REF_QOS_IND_CH", "NUM_OF_PACKET_FILTER", "UE_STATUS_RESUME", "UE_TZ_CH", "AUTH_PROF_CH", "QOS_MONITORING", "SCELL_CH", "EPS_FALLBACK", "MA_PDU", "TSN_ETHER_PORT", "TSN_CONTAINER", "_5G_RG_JOIN", "_5G_RG_LEAVE" }; + size_t sizeofArray = sizeof(policy_control_request_triggerArray) / sizeof(policy_control_request_triggerArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(policy_control_request_trigger, policy_control_request_triggerArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(policy_control_request_trigger); -} - -cJSON *OpenAPI_policy_control_request_trigger_convertToJSON(OpenAPI_policy_control_request_trigger_t *policy_control_request_trigger) -{ - cJSON *item = NULL; - - if (policy_control_request_trigger == NULL) { - ogs_error("OpenAPI_policy_control_request_trigger_convertToJSON() failed [PolicyControlRequestTrigger]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_policy_control_request_trigger_t *OpenAPI_policy_control_request_trigger_parseFromJSON(cJSON *policy_control_request_triggerJSON) -{ - OpenAPI_policy_control_request_trigger_t *policy_control_request_trigger_local_var = NULL; - policy_control_request_trigger_local_var = OpenAPI_policy_control_request_trigger_create ( - ); - - return policy_control_request_trigger_local_var; -end: - return NULL; -} - -OpenAPI_policy_control_request_trigger_t *OpenAPI_policy_control_request_trigger_copy(OpenAPI_policy_control_request_trigger_t *dst, OpenAPI_policy_control_request_trigger_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_policy_control_request_trigger_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_policy_control_request_trigger_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_policy_control_request_trigger_free(dst); - dst = OpenAPI_policy_control_request_trigger_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/policy_control_request_trigger.h b/lib/sbi/openapi/model/policy_control_request_trigger.h index 4ac39e3cc..390251da5 100644 --- a/lib/sbi/openapi/model/policy_control_request_trigger.h +++ b/lib/sbi/openapi/model/policy_control_request_trigger.h @@ -1,7 +1,7 @@ /* * policy_control_request_trigger.h * - * Possible values are - PLMN_CH: PLMN Change - RES_MO_RE: A request for resource modification has been received by the SMF. The SMF always reports to the PCF. - AC_TY_CH: Access Type Change - UE_IP_CH: UE IP address change. The SMF always reports to the PCF. - UE_MAC_CH: A new UE MAC address is detected or a used UE MAC address is inactive for a specific period - AN_CH_COR: Access Network Charging Correlation Information - US_RE: The PDU Session or the Monitoring key specific resources consumed by a UE either reached the threshold or needs to be reported for other reasons. - APP_STA: The start of application traffic has been detected. - APP_STO: The stop of application traffic has been detected. - AN_INFO: Access Network Information report - CM_SES_FAIL: Credit management session failure - PS_DA_OFF: The SMF reports when the 3GPP PS Data Off status changes. The SMF always reports to the PCF. - DEF_QOS_CH: Default QoS Change. The SMF always reports to the PCF. - SE_AMBR_CH: Session AMBR Change. The SMF always reports to the PCF. - QOS_NOTIF: The SMF notify the PCF when receiving notification from RAN that QoS targets of the QoS Flow cannot be guranteed or gurateed again. - NO_CREDIT: Out of credit - REALLO_OF_CREDIT: Reallocation of credit - PRA_CH: Change of UE presence in Presence Reporting Area - SAREA_CH: Location Change with respect to the Serving Area - SCNN_CH: Location Change with respect to the Serving CN node - RE_TIMEOUT: Indicates the SMF generated the request because there has been a PCC revalidation timeout - RES_RELEASE: Indicate that the SMF can inform the PCF of the outcome of the release of resources for those rules that require so. - SUCC_RES_ALLO: Indicates that the requested rule data is the successful resource allocation. - RAT_TY_CH: RAT Type Change. - REF_QOS_IND_CH: Reflective QoS indication Change - NUM_OF_PACKET_FILTER: Indicates that the SMF shall report the number of supported packet filter for signalled QoS rules - UE_STATUS_RESUME: Indicates that the UE’s status is resumed. - UE_TZ_CH: UE Time Zone Change - AUTH_PROF_CH: The DN-AAA authorization profile index has changed - QOS_MONITORING: Indicate that the SMF notifies the PCF of the QoS Monitoring information. - SCELL_CH: Location Change with respect to the Serving Cell. Only applicable to the interworking scenario as defined in Annex B. - EPS_FALLBACK: EPS Fallback report is enabled in the SMF. - MA_PDU: UE Indicates that the SMF notifies the PCF of the MA PDU session request - TSN_ETHER_PORT: Manageable Ethernet port detected - TSN_CONTAINER: Port management container detected. - 5G_RG_JOIN: The 5G-RG has joined to an IP Multicast Group. - 5G_RG_LEAVE: The 5G-RG has left an IP Multicast Group. + * */ #ifndef _OpenAPI_policy_control_request_trigger_H_ @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_policy_control_request_trigger_s OpenAPI_policy_control_request_trigger_t; -typedef struct OpenAPI_policy_control_request_trigger_s { -} OpenAPI_policy_control_request_trigger_t; +typedef enum { OpenAPI_policy_control_request_trigger_NULL = 0, OpenAPI_policy_control_request_trigger_PLMN_CH, OpenAPI_policy_control_request_trigger_RES_MO_RE, OpenAPI_policy_control_request_trigger_AC_TY_CH, OpenAPI_policy_control_request_trigger_UE_IP_CH, OpenAPI_policy_control_request_trigger_UE_MAC_CH, OpenAPI_policy_control_request_trigger_AN_CH_COR, OpenAPI_policy_control_request_trigger_US_RE, OpenAPI_policy_control_request_trigger_APP_STA, OpenAPI_policy_control_request_trigger_APP_STO, OpenAPI_policy_control_request_trigger_AN_INFO, OpenAPI_policy_control_request_trigger_CM_SES_FAIL, OpenAPI_policy_control_request_trigger_PS_DA_OFF, OpenAPI_policy_control_request_trigger_DEF_QOS_CH, OpenAPI_policy_control_request_trigger_SE_AMBR_CH, OpenAPI_policy_control_request_trigger_QOS_NOTIF, OpenAPI_policy_control_request_trigger_NO_CREDIT, OpenAPI_policy_control_request_trigger_REALLO_OF_CREDIT, OpenAPI_policy_control_request_trigger_PRA_CH, OpenAPI_policy_control_request_trigger_SAREA_CH, OpenAPI_policy_control_request_trigger_SCNN_CH, OpenAPI_policy_control_request_trigger_RE_TIMEOUT, OpenAPI_policy_control_request_trigger_RES_RELEASE, OpenAPI_policy_control_request_trigger_SUCC_RES_ALLO, OpenAPI_policy_control_request_trigger_RAT_TY_CH, OpenAPI_policy_control_request_trigger_REF_QOS_IND_CH, OpenAPI_policy_control_request_trigger_NUM_OF_PACKET_FILTER, OpenAPI_policy_control_request_trigger_UE_STATUS_RESUME, OpenAPI_policy_control_request_trigger_UE_TZ_CH, OpenAPI_policy_control_request_trigger_AUTH_PROF_CH, OpenAPI_policy_control_request_trigger_QOS_MONITORING, OpenAPI_policy_control_request_trigger_SCELL_CH, OpenAPI_policy_control_request_trigger_EPS_FALLBACK, OpenAPI_policy_control_request_trigger_MA_PDU, OpenAPI_policy_control_request_trigger_TSN_ETHER_PORT, OpenAPI_policy_control_request_trigger_TSN_CONTAINER, OpenAPI_policy_control_request_trigger__5G_RG_JOIN, OpenAPI_policy_control_request_trigger__5G_RG_LEAVE } OpenAPI_policy_control_request_trigger_e; -OpenAPI_policy_control_request_trigger_t *OpenAPI_policy_control_request_trigger_create( - ); -void OpenAPI_policy_control_request_trigger_free(OpenAPI_policy_control_request_trigger_t *policy_control_request_trigger); -OpenAPI_policy_control_request_trigger_t *OpenAPI_policy_control_request_trigger_parseFromJSON(cJSON *policy_control_request_triggerJSON); -cJSON *OpenAPI_policy_control_request_trigger_convertToJSON(OpenAPI_policy_control_request_trigger_t *policy_control_request_trigger); -OpenAPI_policy_control_request_trigger_t *OpenAPI_policy_control_request_trigger_copy(OpenAPI_policy_control_request_trigger_t *dst, OpenAPI_policy_control_request_trigger_t *src); +char* OpenAPI_policy_control_request_trigger_ToString(OpenAPI_policy_control_request_trigger_e policy_control_request_trigger); + +OpenAPI_policy_control_request_trigger_e OpenAPI_policy_control_request_trigger_FromString(char* policy_control_request_trigger); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/qos_flow_usage.c b/lib/sbi/openapi/model/qos_flow_usage.c index cace47632..cd3b85c19 100644 --- a/lib/sbi/openapi/model/qos_flow_usage.c +++ b/lib/sbi/openapi/model/qos_flow_usage.c @@ -4,82 +4,27 @@ #include #include "qos_flow_usage.h" -OpenAPI_qos_flow_usage_t *OpenAPI_qos_flow_usage_create( - ) +char* OpenAPI_qos_flow_usage_ToString(OpenAPI_qos_flow_usage_e qos_flow_usage) { - OpenAPI_qos_flow_usage_t *qos_flow_usage_local_var = OpenAPI_malloc(sizeof(OpenAPI_qos_flow_usage_t)); - if (!qos_flow_usage_local_var) { - return NULL; - } - - return qos_flow_usage_local_var; + const char *qos_flow_usageArray[] = { "NULL", "GENERAL", "IMS_SIG" }; + size_t sizeofArray = sizeof(qos_flow_usageArray) / sizeof(qos_flow_usageArray[0]); + if (qos_flow_usage < sizeofArray) + return (char *)qos_flow_usageArray[qos_flow_usage]; + else + return (char *)"Unknown"; } -void OpenAPI_qos_flow_usage_free(OpenAPI_qos_flow_usage_t *qos_flow_usage) +OpenAPI_qos_flow_usage_e OpenAPI_qos_flow_usage_FromString(char* qos_flow_usage) { - if (NULL == qos_flow_usage) { - return; + int stringToReturn = 0; + const char *qos_flow_usageArray[] = { "NULL", "GENERAL", "IMS_SIG" }; + size_t sizeofArray = sizeof(qos_flow_usageArray) / sizeof(qos_flow_usageArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(qos_flow_usage, qos_flow_usageArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(qos_flow_usage); -} - -cJSON *OpenAPI_qos_flow_usage_convertToJSON(OpenAPI_qos_flow_usage_t *qos_flow_usage) -{ - cJSON *item = NULL; - - if (qos_flow_usage == NULL) { - ogs_error("OpenAPI_qos_flow_usage_convertToJSON() failed [QosFlowUsage]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_qos_flow_usage_t *OpenAPI_qos_flow_usage_parseFromJSON(cJSON *qos_flow_usageJSON) -{ - OpenAPI_qos_flow_usage_t *qos_flow_usage_local_var = NULL; - qos_flow_usage_local_var = OpenAPI_qos_flow_usage_create ( - ); - - return qos_flow_usage_local_var; -end: - return NULL; -} - -OpenAPI_qos_flow_usage_t *OpenAPI_qos_flow_usage_copy(OpenAPI_qos_flow_usage_t *dst, OpenAPI_qos_flow_usage_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_qos_flow_usage_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_qos_flow_usage_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_qos_flow_usage_free(dst); - dst = OpenAPI_qos_flow_usage_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/qos_flow_usage.h b/lib/sbi/openapi/model/qos_flow_usage.h index 1a4b2d926..7a5e9a7e3 100644 --- a/lib/sbi/openapi/model/qos_flow_usage.h +++ b/lib/sbi/openapi/model/qos_flow_usage.h @@ -1,7 +1,7 @@ /* * qos_flow_usage.h * - * Possible values are - GENERAL: Indicate no specific QoS flow usage information is available. - IMS_SIG: Indicate that the QoS flow is used for IMS signalling only. + * */ #ifndef _OpenAPI_qos_flow_usage_H_ @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_qos_flow_usage_s OpenAPI_qos_flow_usage_t; -typedef struct OpenAPI_qos_flow_usage_s { -} OpenAPI_qos_flow_usage_t; +typedef enum { OpenAPI_qos_flow_usage_NULL = 0, OpenAPI_qos_flow_usage_GENERAL, OpenAPI_qos_flow_usage_IMS_SIG } OpenAPI_qos_flow_usage_e; -OpenAPI_qos_flow_usage_t *OpenAPI_qos_flow_usage_create( - ); -void OpenAPI_qos_flow_usage_free(OpenAPI_qos_flow_usage_t *qos_flow_usage); -OpenAPI_qos_flow_usage_t *OpenAPI_qos_flow_usage_parseFromJSON(cJSON *qos_flow_usageJSON); -cJSON *OpenAPI_qos_flow_usage_convertToJSON(OpenAPI_qos_flow_usage_t *qos_flow_usage); -OpenAPI_qos_flow_usage_t *OpenAPI_qos_flow_usage_copy(OpenAPI_qos_flow_usage_t *dst, OpenAPI_qos_flow_usage_t *src); +char* OpenAPI_qos_flow_usage_ToString(OpenAPI_qos_flow_usage_e qos_flow_usage); + +OpenAPI_qos_flow_usage_e OpenAPI_qos_flow_usage_FromString(char* qos_flow_usage); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/qos_monitoring_data.c b/lib/sbi/openapi/model/qos_monitoring_data.c index 0656d0f6e..d6ecb9cae 100644 --- a/lib/sbi/openapi/model/qos_monitoring_data.c +++ b/lib/sbi/openapi/model/qos_monitoring_data.c @@ -42,13 +42,7 @@ void OpenAPI_qos_monitoring_data_free(OpenAPI_qos_monitoring_data_t *qos_monitor } OpenAPI_lnode_t *node; ogs_free(qos_monitoring_data->qm_id); - OpenAPI_list_for_each(qos_monitoring_data->req_qos_mon_params, node) { - OpenAPI_requested_qos_monitoring_parameter_free(node->data); - } OpenAPI_list_free(qos_monitoring_data->req_qos_mon_params); - OpenAPI_list_for_each(qos_monitoring_data->rep_freqs, node) { - OpenAPI_reporting_frequency_free(node->data); - } OpenAPI_list_free(qos_monitoring_data->rep_freqs); ogs_free(qos_monitoring_data->notify_uri); ogs_free(qos_monitoring_data->notify_corre_id); @@ -75,41 +69,31 @@ cJSON *OpenAPI_qos_monitoring_data_convertToJSON(OpenAPI_qos_monitoring_data_t * } if (qos_monitoring_data->req_qos_mon_params) { - cJSON *req_qos_mon_paramsList = cJSON_AddArrayToObject(item, "reqQosMonParams"); - if (req_qos_mon_paramsList == NULL) { + cJSON *req_qos_mon_params = cJSON_AddArrayToObject(item, "reqQosMonParams"); + if (req_qos_mon_params == NULL) { ogs_error("OpenAPI_qos_monitoring_data_convertToJSON() failed [req_qos_mon_params]"); goto end; } - OpenAPI_lnode_t *req_qos_mon_params_node; - if (qos_monitoring_data->req_qos_mon_params) { - OpenAPI_list_for_each(qos_monitoring_data->req_qos_mon_params, req_qos_mon_params_node) { - cJSON *itemLocal = OpenAPI_requested_qos_monitoring_parameter_convertToJSON(req_qos_mon_params_node->data); - if (itemLocal == NULL) { - ogs_error("OpenAPI_qos_monitoring_data_convertToJSON() failed [req_qos_mon_params]"); - goto end; - } - cJSON_AddItemToArray(req_qos_mon_paramsList, itemLocal); + OpenAPI_list_for_each(qos_monitoring_data->req_qos_mon_params, req_qos_mon_params_node) { + if (cJSON_AddStringToObject(req_qos_mon_params, "", OpenAPI_requested_qos_monitoring_parameter_ToString((OpenAPI_requested_qos_monitoring_parameter_e)req_qos_mon_params_node->data)) == NULL) { + ogs_error("OpenAPI_qos_monitoring_data_convertToJSON() failed [req_qos_mon_params]"); + goto end; } } } if (qos_monitoring_data->rep_freqs) { - cJSON *rep_freqsList = cJSON_AddArrayToObject(item, "repFreqs"); - if (rep_freqsList == NULL) { + cJSON *rep_freqs = cJSON_AddArrayToObject(item, "repFreqs"); + if (rep_freqs == NULL) { ogs_error("OpenAPI_qos_monitoring_data_convertToJSON() failed [rep_freqs]"); goto end; } - OpenAPI_lnode_t *rep_freqs_node; - if (qos_monitoring_data->rep_freqs) { - OpenAPI_list_for_each(qos_monitoring_data->rep_freqs, rep_freqs_node) { - cJSON *itemLocal = OpenAPI_reporting_frequency_convertToJSON(rep_freqs_node->data); - if (itemLocal == NULL) { - ogs_error("OpenAPI_qos_monitoring_data_convertToJSON() failed [rep_freqs]"); - goto end; - } - cJSON_AddItemToArray(rep_freqsList, itemLocal); + OpenAPI_list_for_each(qos_monitoring_data->rep_freqs, rep_freqs_node) { + if (cJSON_AddStringToObject(rep_freqs, "", OpenAPI_reporting_frequency_ToString((OpenAPI_reporting_frequency_e)rep_freqs_node->data)) == NULL) { + ogs_error("OpenAPI_qos_monitoring_data_convertToJSON() failed [rep_freqs]"); + goto end; } } } @@ -195,13 +179,12 @@ OpenAPI_qos_monitoring_data_t *OpenAPI_qos_monitoring_data_parseFromJSON(cJSON * req_qos_mon_paramsList = OpenAPI_list_create(); cJSON_ArrayForEach(req_qos_mon_params_local_nonprimitive, req_qos_mon_params ) { - if (!cJSON_IsObject(req_qos_mon_params_local_nonprimitive)) { + if (!cJSON_IsString(req_qos_mon_params_local_nonprimitive)) { ogs_error("OpenAPI_qos_monitoring_data_parseFromJSON() failed [req_qos_mon_params]"); goto end; } - OpenAPI_requested_qos_monitoring_parameter_t *req_qos_mon_paramsItem = OpenAPI_requested_qos_monitoring_parameter_parseFromJSON(req_qos_mon_params_local_nonprimitive); - OpenAPI_list_add(req_qos_mon_paramsList, req_qos_mon_paramsItem); + OpenAPI_list_add(req_qos_mon_paramsList, (void *)OpenAPI_requested_qos_monitoring_parameter_FromString(req_qos_mon_params_local_nonprimitive->valuestring)); } } @@ -218,13 +201,12 @@ OpenAPI_qos_monitoring_data_t *OpenAPI_qos_monitoring_data_parseFromJSON(cJSON * rep_freqsList = OpenAPI_list_create(); cJSON_ArrayForEach(rep_freqs_local_nonprimitive, rep_freqs ) { - if (!cJSON_IsObject(rep_freqs_local_nonprimitive)) { + if (!cJSON_IsString(rep_freqs_local_nonprimitive)) { ogs_error("OpenAPI_qos_monitoring_data_parseFromJSON() failed [rep_freqs]"); goto end; } - OpenAPI_reporting_frequency_t *rep_freqsItem = OpenAPI_reporting_frequency_parseFromJSON(rep_freqs_local_nonprimitive); - OpenAPI_list_add(rep_freqsList, rep_freqsItem); + OpenAPI_list_add(rep_freqsList, (void *)OpenAPI_reporting_frequency_FromString(rep_freqs_local_nonprimitive->valuestring)); } } diff --git a/lib/sbi/openapi/model/redirect_address_type.c b/lib/sbi/openapi/model/redirect_address_type.c index 373fe17c0..847cd214b 100644 --- a/lib/sbi/openapi/model/redirect_address_type.c +++ b/lib/sbi/openapi/model/redirect_address_type.c @@ -4,82 +4,27 @@ #include #include "redirect_address_type.h" -OpenAPI_redirect_address_type_t *OpenAPI_redirect_address_type_create( - ) +char* OpenAPI_redirect_address_type_ToString(OpenAPI_redirect_address_type_e redirect_address_type) { - OpenAPI_redirect_address_type_t *redirect_address_type_local_var = OpenAPI_malloc(sizeof(OpenAPI_redirect_address_type_t)); - if (!redirect_address_type_local_var) { - return NULL; - } - - return redirect_address_type_local_var; + const char *redirect_address_typeArray[] = { "NULL", "IPV4_ADDR", "IPV6_ADDR", "URL", "SIP_URI" }; + size_t sizeofArray = sizeof(redirect_address_typeArray) / sizeof(redirect_address_typeArray[0]); + if (redirect_address_type < sizeofArray) + return (char *)redirect_address_typeArray[redirect_address_type]; + else + return (char *)"Unknown"; } -void OpenAPI_redirect_address_type_free(OpenAPI_redirect_address_type_t *redirect_address_type) +OpenAPI_redirect_address_type_e OpenAPI_redirect_address_type_FromString(char* redirect_address_type) { - if (NULL == redirect_address_type) { - return; + int stringToReturn = 0; + const char *redirect_address_typeArray[] = { "NULL", "IPV4_ADDR", "IPV6_ADDR", "URL", "SIP_URI" }; + size_t sizeofArray = sizeof(redirect_address_typeArray) / sizeof(redirect_address_typeArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(redirect_address_type, redirect_address_typeArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(redirect_address_type); -} - -cJSON *OpenAPI_redirect_address_type_convertToJSON(OpenAPI_redirect_address_type_t *redirect_address_type) -{ - cJSON *item = NULL; - - if (redirect_address_type == NULL) { - ogs_error("OpenAPI_redirect_address_type_convertToJSON() failed [RedirectAddressType]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_redirect_address_type_t *OpenAPI_redirect_address_type_parseFromJSON(cJSON *redirect_address_typeJSON) -{ - OpenAPI_redirect_address_type_t *redirect_address_type_local_var = NULL; - redirect_address_type_local_var = OpenAPI_redirect_address_type_create ( - ); - - return redirect_address_type_local_var; -end: - return NULL; -} - -OpenAPI_redirect_address_type_t *OpenAPI_redirect_address_type_copy(OpenAPI_redirect_address_type_t *dst, OpenAPI_redirect_address_type_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_redirect_address_type_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_redirect_address_type_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_redirect_address_type_free(dst); - dst = OpenAPI_redirect_address_type_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/redirect_address_type.h b/lib/sbi/openapi/model/redirect_address_type.h index cef9c0d3f..89f868870 100644 --- a/lib/sbi/openapi/model/redirect_address_type.h +++ b/lib/sbi/openapi/model/redirect_address_type.h @@ -1,7 +1,7 @@ /* * redirect_address_type.h * - * Possible values are - IPV4_ADDR: Indicates that the address type is in the form of \"dotted-decimal\" IPv4 address. - IPV6_ADDR: Indicates that the address type is in the form of IPv6 address. - URL: Indicates that the address type is in the form of Uniform Resource Locator. - SIP_URI: Indicates that the address type is in the form of SIP Uniform Resource Identifier. + * */ #ifndef _OpenAPI_redirect_address_type_H_ @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_redirect_address_type_s OpenAPI_redirect_address_type_t; -typedef struct OpenAPI_redirect_address_type_s { -} OpenAPI_redirect_address_type_t; +typedef enum { OpenAPI_redirect_address_type_NULL = 0, OpenAPI_redirect_address_type_IPV4_ADDR, OpenAPI_redirect_address_type_IPV6_ADDR, OpenAPI_redirect_address_type_URL, OpenAPI_redirect_address_type_SIP_URI } OpenAPI_redirect_address_type_e; -OpenAPI_redirect_address_type_t *OpenAPI_redirect_address_type_create( - ); -void OpenAPI_redirect_address_type_free(OpenAPI_redirect_address_type_t *redirect_address_type); -OpenAPI_redirect_address_type_t *OpenAPI_redirect_address_type_parseFromJSON(cJSON *redirect_address_typeJSON); -cJSON *OpenAPI_redirect_address_type_convertToJSON(OpenAPI_redirect_address_type_t *redirect_address_type); -OpenAPI_redirect_address_type_t *OpenAPI_redirect_address_type_copy(OpenAPI_redirect_address_type_t *dst, OpenAPI_redirect_address_type_t *src); +char* OpenAPI_redirect_address_type_ToString(OpenAPI_redirect_address_type_e redirect_address_type); + +OpenAPI_redirect_address_type_e OpenAPI_redirect_address_type_FromString(char* redirect_address_type); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/redirect_information.c b/lib/sbi/openapi/model/redirect_information.c index 6d0150ed1..47f268359 100644 --- a/lib/sbi/openapi/model/redirect_information.c +++ b/lib/sbi/openapi/model/redirect_information.c @@ -6,7 +6,7 @@ OpenAPI_redirect_information_t *OpenAPI_redirect_information_create( int redirect_enabled, - OpenAPI_redirect_address_type_t *redirect_address_type, + OpenAPI_redirect_address_type_e redirect_address_type, char *redirect_server_address ) { @@ -27,7 +27,6 @@ void OpenAPI_redirect_information_free(OpenAPI_redirect_information_t *redirect_ return; } OpenAPI_lnode_t *node; - OpenAPI_redirect_address_type_free(redirect_information->redirect_address_type); ogs_free(redirect_information->redirect_server_address); ogs_free(redirect_information); } @@ -50,13 +49,7 @@ cJSON *OpenAPI_redirect_information_convertToJSON(OpenAPI_redirect_information_t } if (redirect_information->redirect_address_type) { - cJSON *redirect_address_type_local_JSON = OpenAPI_redirect_address_type_convertToJSON(redirect_information->redirect_address_type); - if (redirect_address_type_local_JSON == NULL) { - ogs_error("OpenAPI_redirect_information_convertToJSON() failed [redirect_address_type]"); - goto end; - } - cJSON_AddItemToObject(item, "redirectAddressType", redirect_address_type_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "redirectAddressType", OpenAPI_redirect_address_type_ToString(redirect_information->redirect_address_type)) == NULL) { ogs_error("OpenAPI_redirect_information_convertToJSON() failed [redirect_address_type]"); goto end; } @@ -87,9 +80,13 @@ OpenAPI_redirect_information_t *OpenAPI_redirect_information_parseFromJSON(cJSON cJSON *redirect_address_type = cJSON_GetObjectItemCaseSensitive(redirect_informationJSON, "redirectAddressType"); - OpenAPI_redirect_address_type_t *redirect_address_type_local_nonprim = NULL; + OpenAPI_redirect_address_type_e redirect_address_typeVariable; if (redirect_address_type) { - redirect_address_type_local_nonprim = OpenAPI_redirect_address_type_parseFromJSON(redirect_address_type); + if (!cJSON_IsString(redirect_address_type)) { + ogs_error("OpenAPI_redirect_information_parseFromJSON() failed [redirect_address_type]"); + goto end; + } + redirect_address_typeVariable = OpenAPI_redirect_address_type_FromString(redirect_address_type->valuestring); } cJSON *redirect_server_address = cJSON_GetObjectItemCaseSensitive(redirect_informationJSON, "redirectServerAddress"); @@ -103,7 +100,7 @@ OpenAPI_redirect_information_t *OpenAPI_redirect_information_parseFromJSON(cJSON redirect_information_local_var = OpenAPI_redirect_information_create ( redirect_enabled ? redirect_enabled->valueint : 0, - redirect_address_type ? redirect_address_type_local_nonprim : NULL, + redirect_address_type ? redirect_address_typeVariable : 0, redirect_server_address ? ogs_strdup(redirect_server_address->valuestring) : NULL ); diff --git a/lib/sbi/openapi/model/redirect_information.h b/lib/sbi/openapi/model/redirect_information.h index 14aacd06d..74bec2b85 100644 --- a/lib/sbi/openapi/model/redirect_information.h +++ b/lib/sbi/openapi/model/redirect_information.h @@ -21,13 +21,13 @@ extern "C" { typedef struct OpenAPI_redirect_information_s OpenAPI_redirect_information_t; typedef struct OpenAPI_redirect_information_s { int redirect_enabled; - struct OpenAPI_redirect_address_type_s *redirect_address_type; + OpenAPI_redirect_address_type_e redirect_address_type; char *redirect_server_address; } OpenAPI_redirect_information_t; OpenAPI_redirect_information_t *OpenAPI_redirect_information_create( int redirect_enabled, - OpenAPI_redirect_address_type_t *redirect_address_type, + OpenAPI_redirect_address_type_e redirect_address_type, char *redirect_server_address ); void OpenAPI_redirect_information_free(OpenAPI_redirect_information_t *redirect_information); diff --git a/lib/sbi/openapi/model/reporting_frequency.c b/lib/sbi/openapi/model/reporting_frequency.c index 770b5563f..6305002dc 100644 --- a/lib/sbi/openapi/model/reporting_frequency.c +++ b/lib/sbi/openapi/model/reporting_frequency.c @@ -4,82 +4,27 @@ #include #include "reporting_frequency.h" -OpenAPI_reporting_frequency_t *OpenAPI_reporting_frequency_create( - ) +char* OpenAPI_reporting_frequency_ToString(OpenAPI_reporting_frequency_e reporting_frequency) { - OpenAPI_reporting_frequency_t *reporting_frequency_local_var = OpenAPI_malloc(sizeof(OpenAPI_reporting_frequency_t)); - if (!reporting_frequency_local_var) { - return NULL; - } - - return reporting_frequency_local_var; + const char *reporting_frequencyArray[] = { "NULL", "EVENT_TRIGGERED", "PERIODIC", "SESSION_RELEASE" }; + size_t sizeofArray = sizeof(reporting_frequencyArray) / sizeof(reporting_frequencyArray[0]); + if (reporting_frequency < sizeofArray) + return (char *)reporting_frequencyArray[reporting_frequency]; + else + return (char *)"Unknown"; } -void OpenAPI_reporting_frequency_free(OpenAPI_reporting_frequency_t *reporting_frequency) +OpenAPI_reporting_frequency_e OpenAPI_reporting_frequency_FromString(char* reporting_frequency) { - if (NULL == reporting_frequency) { - return; + int stringToReturn = 0; + const char *reporting_frequencyArray[] = { "NULL", "EVENT_TRIGGERED", "PERIODIC", "SESSION_RELEASE" }; + size_t sizeofArray = sizeof(reporting_frequencyArray) / sizeof(reporting_frequencyArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(reporting_frequency, reporting_frequencyArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(reporting_frequency); -} - -cJSON *OpenAPI_reporting_frequency_convertToJSON(OpenAPI_reporting_frequency_t *reporting_frequency) -{ - cJSON *item = NULL; - - if (reporting_frequency == NULL) { - ogs_error("OpenAPI_reporting_frequency_convertToJSON() failed [ReportingFrequency]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_reporting_frequency_t *OpenAPI_reporting_frequency_parseFromJSON(cJSON *reporting_frequencyJSON) -{ - OpenAPI_reporting_frequency_t *reporting_frequency_local_var = NULL; - reporting_frequency_local_var = OpenAPI_reporting_frequency_create ( - ); - - return reporting_frequency_local_var; -end: - return NULL; -} - -OpenAPI_reporting_frequency_t *OpenAPI_reporting_frequency_copy(OpenAPI_reporting_frequency_t *dst, OpenAPI_reporting_frequency_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_reporting_frequency_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_reporting_frequency_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_reporting_frequency_free(dst); - dst = OpenAPI_reporting_frequency_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/reporting_frequency.h b/lib/sbi/openapi/model/reporting_frequency.h index 144cf50a8..ff864a2ac 100644 --- a/lib/sbi/openapi/model/reporting_frequency.h +++ b/lib/sbi/openapi/model/reporting_frequency.h @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_reporting_frequency_s OpenAPI_reporting_frequency_t; -typedef struct OpenAPI_reporting_frequency_s { -} OpenAPI_reporting_frequency_t; +typedef enum { OpenAPI_reporting_frequency_NULL = 0, OpenAPI_reporting_frequency_EVENT_TRIGGERED, OpenAPI_reporting_frequency_PERIODIC, OpenAPI_reporting_frequency_SESSION_RELEASE } OpenAPI_reporting_frequency_e; -OpenAPI_reporting_frequency_t *OpenAPI_reporting_frequency_create( - ); -void OpenAPI_reporting_frequency_free(OpenAPI_reporting_frequency_t *reporting_frequency); -OpenAPI_reporting_frequency_t *OpenAPI_reporting_frequency_parseFromJSON(cJSON *reporting_frequencyJSON); -cJSON *OpenAPI_reporting_frequency_convertToJSON(OpenAPI_reporting_frequency_t *reporting_frequency); -OpenAPI_reporting_frequency_t *OpenAPI_reporting_frequency_copy(OpenAPI_reporting_frequency_t *dst, OpenAPI_reporting_frequency_t *src); +char* OpenAPI_reporting_frequency_ToString(OpenAPI_reporting_frequency_e reporting_frequency); + +OpenAPI_reporting_frequency_e OpenAPI_reporting_frequency_FromString(char* reporting_frequency); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/reporting_level.c b/lib/sbi/openapi/model/reporting_level.c index b0b8292ef..8041d4df6 100644 --- a/lib/sbi/openapi/model/reporting_level.c +++ b/lib/sbi/openapi/model/reporting_level.c @@ -4,82 +4,27 @@ #include #include "reporting_level.h" -OpenAPI_reporting_level_t *OpenAPI_reporting_level_create( - ) +char* OpenAPI_reporting_level_ToString(OpenAPI_reporting_level_e reporting_level) { - OpenAPI_reporting_level_t *reporting_level_local_var = OpenAPI_malloc(sizeof(OpenAPI_reporting_level_t)); - if (!reporting_level_local_var) { - return NULL; - } - - return reporting_level_local_var; + const char *reporting_levelArray[] = { "NULL", "SER_ID_LEVEL", "RAT_GR_LEVEL", "SPON_CON_LEVEL" }; + size_t sizeofArray = sizeof(reporting_levelArray) / sizeof(reporting_levelArray[0]); + if (reporting_level < sizeofArray) + return (char *)reporting_levelArray[reporting_level]; + else + return (char *)"Unknown"; } -void OpenAPI_reporting_level_free(OpenAPI_reporting_level_t *reporting_level) +OpenAPI_reporting_level_e OpenAPI_reporting_level_FromString(char* reporting_level) { - if (NULL == reporting_level) { - return; + int stringToReturn = 0; + const char *reporting_levelArray[] = { "NULL", "SER_ID_LEVEL", "RAT_GR_LEVEL", "SPON_CON_LEVEL" }; + size_t sizeofArray = sizeof(reporting_levelArray) / sizeof(reporting_levelArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(reporting_level, reporting_levelArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(reporting_level); -} - -cJSON *OpenAPI_reporting_level_convertToJSON(OpenAPI_reporting_level_t *reporting_level) -{ - cJSON *item = NULL; - - if (reporting_level == NULL) { - ogs_error("OpenAPI_reporting_level_convertToJSON() failed [ReportingLevel]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_reporting_level_t *OpenAPI_reporting_level_parseFromJSON(cJSON *reporting_levelJSON) -{ - OpenAPI_reporting_level_t *reporting_level_local_var = NULL; - reporting_level_local_var = OpenAPI_reporting_level_create ( - ); - - return reporting_level_local_var; -end: - return NULL; -} - -OpenAPI_reporting_level_t *OpenAPI_reporting_level_copy(OpenAPI_reporting_level_t *dst, OpenAPI_reporting_level_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_reporting_level_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_reporting_level_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_reporting_level_free(dst); - dst = OpenAPI_reporting_level_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/reporting_level.h b/lib/sbi/openapi/model/reporting_level.h index c01de44f9..9c78df113 100644 --- a/lib/sbi/openapi/model/reporting_level.h +++ b/lib/sbi/openapi/model/reporting_level.h @@ -1,7 +1,7 @@ /* * reporting_level.h * - * Possible values are - SER_ID_LEVEL: Indicates that the usage shall be reported on service id and rating group combination level. - RAT_GR_LEVEL: Indicates that the usage shall be reported on rating group level. - SPON_CON_LEVEL: Indicates that the usage shall be reported on sponsor identity and rating group combination level. + * */ #ifndef _OpenAPI_reporting_level_H_ @@ -12,22 +12,16 @@ #include "../include/list.h" #include "../include/keyValuePair.h" #include "../include/binary.h" -#include "null_value.h" #ifdef __cplusplus extern "C" { #endif -typedef struct OpenAPI_reporting_level_s OpenAPI_reporting_level_t; -typedef struct OpenAPI_reporting_level_s { -} OpenAPI_reporting_level_t; +typedef enum { OpenAPI_reporting_level_NULL = 0, OpenAPI_reporting_level_SER_ID_LEVEL, OpenAPI_reporting_level_RAT_GR_LEVEL, OpenAPI_reporting_level_SPON_CON_LEVEL } OpenAPI_reporting_level_e; -OpenAPI_reporting_level_t *OpenAPI_reporting_level_create( - ); -void OpenAPI_reporting_level_free(OpenAPI_reporting_level_t *reporting_level); -OpenAPI_reporting_level_t *OpenAPI_reporting_level_parseFromJSON(cJSON *reporting_levelJSON); -cJSON *OpenAPI_reporting_level_convertToJSON(OpenAPI_reporting_level_t *reporting_level); -OpenAPI_reporting_level_t *OpenAPI_reporting_level_copy(OpenAPI_reporting_level_t *dst, OpenAPI_reporting_level_t *src); +char* OpenAPI_reporting_level_ToString(OpenAPI_reporting_level_e reporting_level); + +OpenAPI_reporting_level_e OpenAPI_reporting_level_FromString(char* reporting_level); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/requested_qos_monitoring_parameter.c b/lib/sbi/openapi/model/requested_qos_monitoring_parameter.c index a8e20bbf8..c66196a4b 100644 --- a/lib/sbi/openapi/model/requested_qos_monitoring_parameter.c +++ b/lib/sbi/openapi/model/requested_qos_monitoring_parameter.c @@ -4,82 +4,27 @@ #include #include "requested_qos_monitoring_parameter.h" -OpenAPI_requested_qos_monitoring_parameter_t *OpenAPI_requested_qos_monitoring_parameter_create( - ) +char* OpenAPI_requested_qos_monitoring_parameter_ToString(OpenAPI_requested_qos_monitoring_parameter_e requested_qos_monitoring_parameter) { - OpenAPI_requested_qos_monitoring_parameter_t *requested_qos_monitoring_parameter_local_var = OpenAPI_malloc(sizeof(OpenAPI_requested_qos_monitoring_parameter_t)); - if (!requested_qos_monitoring_parameter_local_var) { - return NULL; - } - - return requested_qos_monitoring_parameter_local_var; + const char *requested_qos_monitoring_parameterArray[] = { "NULL", "DOWNLINK", "UPLINK", "ROUND_TRIP" }; + size_t sizeofArray = sizeof(requested_qos_monitoring_parameterArray) / sizeof(requested_qos_monitoring_parameterArray[0]); + if (requested_qos_monitoring_parameter < sizeofArray) + return (char *)requested_qos_monitoring_parameterArray[requested_qos_monitoring_parameter]; + else + return (char *)"Unknown"; } -void OpenAPI_requested_qos_monitoring_parameter_free(OpenAPI_requested_qos_monitoring_parameter_t *requested_qos_monitoring_parameter) +OpenAPI_requested_qos_monitoring_parameter_e OpenAPI_requested_qos_monitoring_parameter_FromString(char* requested_qos_monitoring_parameter) { - if (NULL == requested_qos_monitoring_parameter) { - return; + int stringToReturn = 0; + const char *requested_qos_monitoring_parameterArray[] = { "NULL", "DOWNLINK", "UPLINK", "ROUND_TRIP" }; + size_t sizeofArray = sizeof(requested_qos_monitoring_parameterArray) / sizeof(requested_qos_monitoring_parameterArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(requested_qos_monitoring_parameter, requested_qos_monitoring_parameterArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(requested_qos_monitoring_parameter); -} - -cJSON *OpenAPI_requested_qos_monitoring_parameter_convertToJSON(OpenAPI_requested_qos_monitoring_parameter_t *requested_qos_monitoring_parameter) -{ - cJSON *item = NULL; - - if (requested_qos_monitoring_parameter == NULL) { - ogs_error("OpenAPI_requested_qos_monitoring_parameter_convertToJSON() failed [RequestedQosMonitoringParameter]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_requested_qos_monitoring_parameter_t *OpenAPI_requested_qos_monitoring_parameter_parseFromJSON(cJSON *requested_qos_monitoring_parameterJSON) -{ - OpenAPI_requested_qos_monitoring_parameter_t *requested_qos_monitoring_parameter_local_var = NULL; - requested_qos_monitoring_parameter_local_var = OpenAPI_requested_qos_monitoring_parameter_create ( - ); - - return requested_qos_monitoring_parameter_local_var; -end: - return NULL; -} - -OpenAPI_requested_qos_monitoring_parameter_t *OpenAPI_requested_qos_monitoring_parameter_copy(OpenAPI_requested_qos_monitoring_parameter_t *dst, OpenAPI_requested_qos_monitoring_parameter_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_requested_qos_monitoring_parameter_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_requested_qos_monitoring_parameter_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_requested_qos_monitoring_parameter_free(dst); - dst = OpenAPI_requested_qos_monitoring_parameter_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/requested_qos_monitoring_parameter.h b/lib/sbi/openapi/model/requested_qos_monitoring_parameter.h index 8783b112f..9b6b04b48 100644 --- a/lib/sbi/openapi/model/requested_qos_monitoring_parameter.h +++ b/lib/sbi/openapi/model/requested_qos_monitoring_parameter.h @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_requested_qos_monitoring_parameter_s OpenAPI_requested_qos_monitoring_parameter_t; -typedef struct OpenAPI_requested_qos_monitoring_parameter_s { -} OpenAPI_requested_qos_monitoring_parameter_t; +typedef enum { OpenAPI_requested_qos_monitoring_parameter_NULL = 0, OpenAPI_requested_qos_monitoring_parameter_DOWNLINK, OpenAPI_requested_qos_monitoring_parameter_UPLINK, OpenAPI_requested_qos_monitoring_parameter_ROUND_TRIP } OpenAPI_requested_qos_monitoring_parameter_e; -OpenAPI_requested_qos_monitoring_parameter_t *OpenAPI_requested_qos_monitoring_parameter_create( - ); -void OpenAPI_requested_qos_monitoring_parameter_free(OpenAPI_requested_qos_monitoring_parameter_t *requested_qos_monitoring_parameter); -OpenAPI_requested_qos_monitoring_parameter_t *OpenAPI_requested_qos_monitoring_parameter_parseFromJSON(cJSON *requested_qos_monitoring_parameterJSON); -cJSON *OpenAPI_requested_qos_monitoring_parameter_convertToJSON(OpenAPI_requested_qos_monitoring_parameter_t *requested_qos_monitoring_parameter); -OpenAPI_requested_qos_monitoring_parameter_t *OpenAPI_requested_qos_monitoring_parameter_copy(OpenAPI_requested_qos_monitoring_parameter_t *dst, OpenAPI_requested_qos_monitoring_parameter_t *src); +char* OpenAPI_requested_qos_monitoring_parameter_ToString(OpenAPI_requested_qos_monitoring_parameter_e requested_qos_monitoring_parameter); + +OpenAPI_requested_qos_monitoring_parameter_e OpenAPI_requested_qos_monitoring_parameter_FromString(char* requested_qos_monitoring_parameter); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/requested_rule_data.c b/lib/sbi/openapi/model/requested_rule_data.c index 7588715f3..bb32d5f1b 100644 --- a/lib/sbi/openapi/model/requested_rule_data.c +++ b/lib/sbi/openapi/model/requested_rule_data.c @@ -29,9 +29,6 @@ void OpenAPI_requested_rule_data_free(OpenAPI_requested_rule_data_t *requested_r ogs_free(node->data); } OpenAPI_list_free(requested_rule_data->ref_pcc_rule_ids); - OpenAPI_list_for_each(requested_rule_data->req_data, node) { - OpenAPI_requested_rule_data_type_free(node->data); - } OpenAPI_list_free(requested_rule_data->req_data); ogs_free(requested_rule_data); } @@ -68,21 +65,16 @@ cJSON *OpenAPI_requested_rule_data_convertToJSON(OpenAPI_requested_rule_data_t * ogs_error("OpenAPI_requested_rule_data_convertToJSON() failed [req_data]"); goto end; } - cJSON *req_dataList = cJSON_AddArrayToObject(item, "reqData"); - if (req_dataList == NULL) { + cJSON *req_data = cJSON_AddArrayToObject(item, "reqData"); + if (req_data == NULL) { ogs_error("OpenAPI_requested_rule_data_convertToJSON() failed [req_data]"); goto end; } - OpenAPI_lnode_t *req_data_node; - if (requested_rule_data->req_data) { - OpenAPI_list_for_each(requested_rule_data->req_data, req_data_node) { - cJSON *itemLocal = OpenAPI_requested_rule_data_type_convertToJSON(req_data_node->data); - if (itemLocal == NULL) { - ogs_error("OpenAPI_requested_rule_data_convertToJSON() failed [req_data]"); - goto end; - } - cJSON_AddItemToArray(req_dataList, itemLocal); + OpenAPI_list_for_each(requested_rule_data->req_data, req_data_node) { + if (cJSON_AddStringToObject(req_data, "", OpenAPI_requested_rule_data_type_ToString((OpenAPI_requested_rule_data_type_e)req_data_node->data)) == NULL) { + ogs_error("OpenAPI_requested_rule_data_convertToJSON() failed [req_data]"); + goto end; } } @@ -133,13 +125,12 @@ OpenAPI_requested_rule_data_t *OpenAPI_requested_rule_data_parseFromJSON(cJSON * req_dataList = OpenAPI_list_create(); cJSON_ArrayForEach(req_data_local_nonprimitive, req_data ) { - if (!cJSON_IsObject(req_data_local_nonprimitive)) { + if (!cJSON_IsString(req_data_local_nonprimitive)) { ogs_error("OpenAPI_requested_rule_data_parseFromJSON() failed [req_data]"); goto end; } - OpenAPI_requested_rule_data_type_t *req_dataItem = OpenAPI_requested_rule_data_type_parseFromJSON(req_data_local_nonprimitive); - OpenAPI_list_add(req_dataList, req_dataItem); + OpenAPI_list_add(req_dataList, (void *)OpenAPI_requested_rule_data_type_FromString(req_data_local_nonprimitive->valuestring)); } requested_rule_data_local_var = OpenAPI_requested_rule_data_create ( diff --git a/lib/sbi/openapi/model/requested_rule_data_type.c b/lib/sbi/openapi/model/requested_rule_data_type.c index 06b4c2289..a2ab46031 100644 --- a/lib/sbi/openapi/model/requested_rule_data_type.c +++ b/lib/sbi/openapi/model/requested_rule_data_type.c @@ -4,82 +4,27 @@ #include #include "requested_rule_data_type.h" -OpenAPI_requested_rule_data_type_t *OpenAPI_requested_rule_data_type_create( - ) +char* OpenAPI_requested_rule_data_type_ToString(OpenAPI_requested_rule_data_type_e requested_rule_data_type) { - OpenAPI_requested_rule_data_type_t *requested_rule_data_type_local_var = OpenAPI_malloc(sizeof(OpenAPI_requested_rule_data_type_t)); - if (!requested_rule_data_type_local_var) { - return NULL; - } - - return requested_rule_data_type_local_var; + const char *requested_rule_data_typeArray[] = { "NULL", "CH_ID", "MS_TIME_ZONE", "USER_LOC_INFO", "RES_RELEASE", "SUCC_RES_ALLO", "EPS_FALLBACK" }; + size_t sizeofArray = sizeof(requested_rule_data_typeArray) / sizeof(requested_rule_data_typeArray[0]); + if (requested_rule_data_type < sizeofArray) + return (char *)requested_rule_data_typeArray[requested_rule_data_type]; + else + return (char *)"Unknown"; } -void OpenAPI_requested_rule_data_type_free(OpenAPI_requested_rule_data_type_t *requested_rule_data_type) +OpenAPI_requested_rule_data_type_e OpenAPI_requested_rule_data_type_FromString(char* requested_rule_data_type) { - if (NULL == requested_rule_data_type) { - return; + int stringToReturn = 0; + const char *requested_rule_data_typeArray[] = { "NULL", "CH_ID", "MS_TIME_ZONE", "USER_LOC_INFO", "RES_RELEASE", "SUCC_RES_ALLO", "EPS_FALLBACK" }; + size_t sizeofArray = sizeof(requested_rule_data_typeArray) / sizeof(requested_rule_data_typeArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(requested_rule_data_type, requested_rule_data_typeArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(requested_rule_data_type); -} - -cJSON *OpenAPI_requested_rule_data_type_convertToJSON(OpenAPI_requested_rule_data_type_t *requested_rule_data_type) -{ - cJSON *item = NULL; - - if (requested_rule_data_type == NULL) { - ogs_error("OpenAPI_requested_rule_data_type_convertToJSON() failed [RequestedRuleDataType]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_requested_rule_data_type_t *OpenAPI_requested_rule_data_type_parseFromJSON(cJSON *requested_rule_data_typeJSON) -{ - OpenAPI_requested_rule_data_type_t *requested_rule_data_type_local_var = NULL; - requested_rule_data_type_local_var = OpenAPI_requested_rule_data_type_create ( - ); - - return requested_rule_data_type_local_var; -end: - return NULL; -} - -OpenAPI_requested_rule_data_type_t *OpenAPI_requested_rule_data_type_copy(OpenAPI_requested_rule_data_type_t *dst, OpenAPI_requested_rule_data_type_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_requested_rule_data_type_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_requested_rule_data_type_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_requested_rule_data_type_free(dst); - dst = OpenAPI_requested_rule_data_type_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/requested_rule_data_type.h b/lib/sbi/openapi/model/requested_rule_data_type.h index 4b92ae1ae..34ff25e45 100644 --- a/lib/sbi/openapi/model/requested_rule_data_type.h +++ b/lib/sbi/openapi/model/requested_rule_data_type.h @@ -1,7 +1,7 @@ /* * requested_rule_data_type.h * - * Possible values are - CH_ID: Indicates that the requested rule data is the charging identifier. - MS_TIME_ZONE: Indicates that the requested access network info type is the UE's timezone. - USER_LOC_INFO: Indicates that the requested access network info type is the UE's location. - RES_RELEASE: Indicates that the requested rule data is the result of the release of resource. - SUCC_RES_ALLO: Indicates that the requested rule data is the successful resource allocation. - EPS_FALLBACK: Indicates that the requested rule data is the report of QoS flow rejection due to EPS fallback. + * */ #ifndef _OpenAPI_requested_rule_data_type_H_ @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_requested_rule_data_type_s OpenAPI_requested_rule_data_type_t; -typedef struct OpenAPI_requested_rule_data_type_s { -} OpenAPI_requested_rule_data_type_t; +typedef enum { OpenAPI_requested_rule_data_type_NULL = 0, OpenAPI_requested_rule_data_type_CH_ID, OpenAPI_requested_rule_data_type_MS_TIME_ZONE, OpenAPI_requested_rule_data_type_USER_LOC_INFO, OpenAPI_requested_rule_data_type_RES_RELEASE, OpenAPI_requested_rule_data_type_SUCC_RES_ALLO, OpenAPI_requested_rule_data_type_EPS_FALLBACK } OpenAPI_requested_rule_data_type_e; -OpenAPI_requested_rule_data_type_t *OpenAPI_requested_rule_data_type_create( - ); -void OpenAPI_requested_rule_data_type_free(OpenAPI_requested_rule_data_type_t *requested_rule_data_type); -OpenAPI_requested_rule_data_type_t *OpenAPI_requested_rule_data_type_parseFromJSON(cJSON *requested_rule_data_typeJSON); -cJSON *OpenAPI_requested_rule_data_type_convertToJSON(OpenAPI_requested_rule_data_type_t *requested_rule_data_type); -OpenAPI_requested_rule_data_type_t *OpenAPI_requested_rule_data_type_copy(OpenAPI_requested_rule_data_type_t *dst, OpenAPI_requested_rule_data_type_t *src); +char* OpenAPI_requested_rule_data_type_ToString(OpenAPI_requested_rule_data_type_e requested_rule_data_type); + +OpenAPI_requested_rule_data_type_e OpenAPI_requested_rule_data_type_FromString(char* requested_rule_data_type); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/rule_operation.c b/lib/sbi/openapi/model/rule_operation.c index c75e87729..800ee1206 100644 --- a/lib/sbi/openapi/model/rule_operation.c +++ b/lib/sbi/openapi/model/rule_operation.c @@ -4,82 +4,27 @@ #include #include "rule_operation.h" -OpenAPI_rule_operation_t *OpenAPI_rule_operation_create( - ) +char* OpenAPI_rule_operation_ToString(OpenAPI_rule_operation_e rule_operation) { - OpenAPI_rule_operation_t *rule_operation_local_var = OpenAPI_malloc(sizeof(OpenAPI_rule_operation_t)); - if (!rule_operation_local_var) { - return NULL; - } - - return rule_operation_local_var; + const char *rule_operationArray[] = { "NULL", "CREATE_PCC_RULE", "DELETE_PCC_RULE", "MODIFY_PCC_RULE_AND_ADD_PACKET_FILTERS", "MODIFY_PCC_RULE_AND_REPLACE_PACKET_FILTERS", "MODIFY_PCC_RULE_AND_DELETE_PACKET_FILTERS", "MODIFY_PCC_RULE_WITHOUT_MODIFY_PACKET_FILTERS" }; + size_t sizeofArray = sizeof(rule_operationArray) / sizeof(rule_operationArray[0]); + if (rule_operation < sizeofArray) + return (char *)rule_operationArray[rule_operation]; + else + return (char *)"Unknown"; } -void OpenAPI_rule_operation_free(OpenAPI_rule_operation_t *rule_operation) +OpenAPI_rule_operation_e OpenAPI_rule_operation_FromString(char* rule_operation) { - if (NULL == rule_operation) { - return; + int stringToReturn = 0; + const char *rule_operationArray[] = { "NULL", "CREATE_PCC_RULE", "DELETE_PCC_RULE", "MODIFY_PCC_RULE_AND_ADD_PACKET_FILTERS", "MODIFY_PCC_RULE_AND_REPLACE_PACKET_FILTERS", "MODIFY_PCC_RULE_AND_DELETE_PACKET_FILTERS", "MODIFY_PCC_RULE_WITHOUT_MODIFY_PACKET_FILTERS" }; + size_t sizeofArray = sizeof(rule_operationArray) / sizeof(rule_operationArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(rule_operation, rule_operationArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(rule_operation); -} - -cJSON *OpenAPI_rule_operation_convertToJSON(OpenAPI_rule_operation_t *rule_operation) -{ - cJSON *item = NULL; - - if (rule_operation == NULL) { - ogs_error("OpenAPI_rule_operation_convertToJSON() failed [RuleOperation]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_rule_operation_t *OpenAPI_rule_operation_parseFromJSON(cJSON *rule_operationJSON) -{ - OpenAPI_rule_operation_t *rule_operation_local_var = NULL; - rule_operation_local_var = OpenAPI_rule_operation_create ( - ); - - return rule_operation_local_var; -end: - return NULL; -} - -OpenAPI_rule_operation_t *OpenAPI_rule_operation_copy(OpenAPI_rule_operation_t *dst, OpenAPI_rule_operation_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_rule_operation_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_rule_operation_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_rule_operation_free(dst); - dst = OpenAPI_rule_operation_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/rule_operation.h b/lib/sbi/openapi/model/rule_operation.h index 6f4f1f5c4..d1d80310a 100644 --- a/lib/sbi/openapi/model/rule_operation.h +++ b/lib/sbi/openapi/model/rule_operation.h @@ -1,7 +1,7 @@ /* * rule_operation.h * - * Possible values are - CREATE_PCC_RULE: Indicates to create a new PCC rule to reserve the resource requested by the UE. - DELETE_PCC_RULE: Indicates to delete a PCC rule corresponding to reserve the resource requested by the UE.. - MODIFY_PCC_RULE_AND_ADD_PACKET_FILTERS: Indicates to modify the PCC rule by adding new packet filter(s). - MODIFY_ PCC_RULE_AND_REPLACE_PACKET_FILTERS: Indicates to modify the PCC rule by replacing the existing packet filter(s). - MODIFY_ PCC_RULE_AND_DELETE_PACKET_FILTERS: Indicates to modify the PCC rule by deleting the existing packet filter(s). - MODIFY_PCC_RULE_WITHOUT_MODIFY_PACKET_FILTERS: Indicates to modify the PCC rule by modifying the QoS of the PCC rule. + * */ #ifndef _OpenAPI_rule_operation_H_ @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_rule_operation_s OpenAPI_rule_operation_t; -typedef struct OpenAPI_rule_operation_s { -} OpenAPI_rule_operation_t; +typedef enum { OpenAPI_rule_operation_NULL = 0, OpenAPI_rule_operation_CREATE_PCC_RULE, OpenAPI_rule_operation_DELETE_PCC_RULE, OpenAPI_rule_operation_MODIFY_PCC_RULE_AND_ADD_PACKET_FILTERS, OpenAPI_rule_operation_MODIFY_PCC_RULE_AND_REPLACE_PACKET_FILTERS, OpenAPI_rule_operation_MODIFY_PCC_RULE_AND_DELETE_PACKET_FILTERS, OpenAPI_rule_operation_MODIFY_PCC_RULE_WITHOUT_MODIFY_PACKET_FILTERS } OpenAPI_rule_operation_e; -OpenAPI_rule_operation_t *OpenAPI_rule_operation_create( - ); -void OpenAPI_rule_operation_free(OpenAPI_rule_operation_t *rule_operation); -OpenAPI_rule_operation_t *OpenAPI_rule_operation_parseFromJSON(cJSON *rule_operationJSON); -cJSON *OpenAPI_rule_operation_convertToJSON(OpenAPI_rule_operation_t *rule_operation); -OpenAPI_rule_operation_t *OpenAPI_rule_operation_copy(OpenAPI_rule_operation_t *dst, OpenAPI_rule_operation_t *src); +char* OpenAPI_rule_operation_ToString(OpenAPI_rule_operation_e rule_operation); + +OpenAPI_rule_operation_e OpenAPI_rule_operation_FromString(char* rule_operation); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/rule_report.c b/lib/sbi/openapi/model/rule_report.c index 5f88ab6a2..9b735b562 100644 --- a/lib/sbi/openapi/model/rule_report.c +++ b/lib/sbi/openapi/model/rule_report.c @@ -6,9 +6,9 @@ OpenAPI_rule_report_t *OpenAPI_rule_report_create( OpenAPI_list_t *pcc_rule_ids, - OpenAPI_rule_status_t *rule_status, + OpenAPI_rule_status_e rule_status, OpenAPI_list_t *cont_vers, - OpenAPI_failure_code_t *failure_code, + OpenAPI_failure_code_e failure_code, OpenAPI_final_unit_action_t *fin_unit_act, OpenAPI_list_t *ran_nas_rel_causes ) @@ -37,12 +37,10 @@ void OpenAPI_rule_report_free(OpenAPI_rule_report_t *rule_report) ogs_free(node->data); } OpenAPI_list_free(rule_report->pcc_rule_ids); - OpenAPI_rule_status_free(rule_report->rule_status); OpenAPI_list_for_each(rule_report->cont_vers, node) { ogs_free(node->data); } OpenAPI_list_free(rule_report->cont_vers); - OpenAPI_failure_code_free(rule_report->failure_code); OpenAPI_final_unit_action_free(rule_report->fin_unit_act); OpenAPI_list_for_each(rule_report->ran_nas_rel_causes, node) { OpenAPI_ran_nas_rel_cause_free(node->data); @@ -83,13 +81,7 @@ cJSON *OpenAPI_rule_report_convertToJSON(OpenAPI_rule_report_t *rule_report) ogs_error("OpenAPI_rule_report_convertToJSON() failed [rule_status]"); goto end; } - cJSON *rule_status_local_JSON = OpenAPI_rule_status_convertToJSON(rule_report->rule_status); - if (rule_status_local_JSON == NULL) { - ogs_error("OpenAPI_rule_report_convertToJSON() failed [rule_status]"); - goto end; - } - cJSON_AddItemToObject(item, "ruleStatus", rule_status_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "ruleStatus", OpenAPI_rule_status_ToString(rule_report->rule_status)) == NULL) { ogs_error("OpenAPI_rule_report_convertToJSON() failed [rule_status]"); goto end; } @@ -111,13 +103,7 @@ cJSON *OpenAPI_rule_report_convertToJSON(OpenAPI_rule_report_t *rule_report) } if (rule_report->failure_code) { - cJSON *failure_code_local_JSON = OpenAPI_failure_code_convertToJSON(rule_report->failure_code); - if (failure_code_local_JSON == NULL) { - ogs_error("OpenAPI_rule_report_convertToJSON() failed [failure_code]"); - goto end; - } - cJSON_AddItemToObject(item, "failureCode", failure_code_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "failureCode", OpenAPI_failure_code_ToString(rule_report->failure_code)) == NULL) { ogs_error("OpenAPI_rule_report_convertToJSON() failed [failure_code]"); goto end; } @@ -192,9 +178,13 @@ OpenAPI_rule_report_t *OpenAPI_rule_report_parseFromJSON(cJSON *rule_reportJSON) goto end; } - OpenAPI_rule_status_t *rule_status_local_nonprim = NULL; + OpenAPI_rule_status_e rule_statusVariable; - rule_status_local_nonprim = OpenAPI_rule_status_parseFromJSON(rule_status); + if (!cJSON_IsString(rule_status)) { + ogs_error("OpenAPI_rule_report_parseFromJSON() failed [rule_status]"); + goto end; + } + rule_statusVariable = OpenAPI_rule_status_FromString(rule_status->valuestring); cJSON *cont_vers = cJSON_GetObjectItemCaseSensitive(rule_reportJSON, "contVers"); @@ -218,9 +208,13 @@ OpenAPI_rule_report_t *OpenAPI_rule_report_parseFromJSON(cJSON *rule_reportJSON) cJSON *failure_code = cJSON_GetObjectItemCaseSensitive(rule_reportJSON, "failureCode"); - OpenAPI_failure_code_t *failure_code_local_nonprim = NULL; + OpenAPI_failure_code_e failure_codeVariable; if (failure_code) { - failure_code_local_nonprim = OpenAPI_failure_code_parseFromJSON(failure_code); + if (!cJSON_IsString(failure_code)) { + ogs_error("OpenAPI_rule_report_parseFromJSON() failed [failure_code]"); + goto end; + } + failure_codeVariable = OpenAPI_failure_code_FromString(failure_code->valuestring); } cJSON *fin_unit_act = cJSON_GetObjectItemCaseSensitive(rule_reportJSON, "finUnitAct"); @@ -255,9 +249,9 @@ OpenAPI_rule_report_t *OpenAPI_rule_report_parseFromJSON(cJSON *rule_reportJSON) rule_report_local_var = OpenAPI_rule_report_create ( pcc_rule_idsList, - rule_status_local_nonprim, + rule_statusVariable, cont_vers ? cont_versList : NULL, - failure_code ? failure_code_local_nonprim : NULL, + failure_code ? failure_codeVariable : 0, fin_unit_act ? fin_unit_act_local_nonprim : NULL, ran_nas_rel_causes ? ran_nas_rel_causesList : NULL ); diff --git a/lib/sbi/openapi/model/rule_report.h b/lib/sbi/openapi/model/rule_report.h index 9ab765d83..0ba037dc1 100644 --- a/lib/sbi/openapi/model/rule_report.h +++ b/lib/sbi/openapi/model/rule_report.h @@ -24,18 +24,18 @@ extern "C" { typedef struct OpenAPI_rule_report_s OpenAPI_rule_report_t; typedef struct OpenAPI_rule_report_s { OpenAPI_list_t *pcc_rule_ids; - struct OpenAPI_rule_status_s *rule_status; + OpenAPI_rule_status_e rule_status; OpenAPI_list_t *cont_vers; - struct OpenAPI_failure_code_s *failure_code; + OpenAPI_failure_code_e failure_code; struct OpenAPI_final_unit_action_s *fin_unit_act; OpenAPI_list_t *ran_nas_rel_causes; } OpenAPI_rule_report_t; OpenAPI_rule_report_t *OpenAPI_rule_report_create( OpenAPI_list_t *pcc_rule_ids, - OpenAPI_rule_status_t *rule_status, + OpenAPI_rule_status_e rule_status, OpenAPI_list_t *cont_vers, - OpenAPI_failure_code_t *failure_code, + OpenAPI_failure_code_e failure_code, OpenAPI_final_unit_action_t *fin_unit_act, OpenAPI_list_t *ran_nas_rel_causes ); diff --git a/lib/sbi/openapi/model/rule_status.c b/lib/sbi/openapi/model/rule_status.c index ffd145d07..022cb886f 100644 --- a/lib/sbi/openapi/model/rule_status.c +++ b/lib/sbi/openapi/model/rule_status.c @@ -4,82 +4,27 @@ #include #include "rule_status.h" -OpenAPI_rule_status_t *OpenAPI_rule_status_create( - ) +char* OpenAPI_rule_status_ToString(OpenAPI_rule_status_e rule_status) { - OpenAPI_rule_status_t *rule_status_local_var = OpenAPI_malloc(sizeof(OpenAPI_rule_status_t)); - if (!rule_status_local_var) { - return NULL; - } - - return rule_status_local_var; + const char *rule_statusArray[] = { "NULL", "ACTIVE", "INACTIVE" }; + size_t sizeofArray = sizeof(rule_statusArray) / sizeof(rule_statusArray[0]); + if (rule_status < sizeofArray) + return (char *)rule_statusArray[rule_status]; + else + return (char *)"Unknown"; } -void OpenAPI_rule_status_free(OpenAPI_rule_status_t *rule_status) +OpenAPI_rule_status_e OpenAPI_rule_status_FromString(char* rule_status) { - if (NULL == rule_status) { - return; + int stringToReturn = 0; + const char *rule_statusArray[] = { "NULL", "ACTIVE", "INACTIVE" }; + size_t sizeofArray = sizeof(rule_statusArray) / sizeof(rule_statusArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(rule_status, rule_statusArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(rule_status); -} - -cJSON *OpenAPI_rule_status_convertToJSON(OpenAPI_rule_status_t *rule_status) -{ - cJSON *item = NULL; - - if (rule_status == NULL) { - ogs_error("OpenAPI_rule_status_convertToJSON() failed [RuleStatus]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_rule_status_t *OpenAPI_rule_status_parseFromJSON(cJSON *rule_statusJSON) -{ - OpenAPI_rule_status_t *rule_status_local_var = NULL; - rule_status_local_var = OpenAPI_rule_status_create ( - ); - - return rule_status_local_var; -end: - return NULL; -} - -OpenAPI_rule_status_t *OpenAPI_rule_status_copy(OpenAPI_rule_status_t *dst, OpenAPI_rule_status_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_rule_status_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_rule_status_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_rule_status_free(dst); - dst = OpenAPI_rule_status_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/rule_status.h b/lib/sbi/openapi/model/rule_status.h index 1c5cdfded..063705435 100644 --- a/lib/sbi/openapi/model/rule_status.h +++ b/lib/sbi/openapi/model/rule_status.h @@ -1,7 +1,7 @@ /* * rule_status.h * - * Possible values are - ACTIVE: Indicates that the PCC rule(s) are successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF), or the session rule(s) are successfully installed - INACTIVE: Indicates that the PCC rule(s) are removed (for those provisioned from PCF) or inactive (for those pre-defined in SMF) or the session rule(s) are removed. + * */ #ifndef _OpenAPI_rule_status_H_ @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_rule_status_s OpenAPI_rule_status_t; -typedef struct OpenAPI_rule_status_s { -} OpenAPI_rule_status_t; +typedef enum { OpenAPI_rule_status_NULL = 0, OpenAPI_rule_status_ACTIVE, OpenAPI_rule_status_INACTIVE } OpenAPI_rule_status_e; -OpenAPI_rule_status_t *OpenAPI_rule_status_create( - ); -void OpenAPI_rule_status_free(OpenAPI_rule_status_t *rule_status); -OpenAPI_rule_status_t *OpenAPI_rule_status_parseFromJSON(cJSON *rule_statusJSON); -cJSON *OpenAPI_rule_status_convertToJSON(OpenAPI_rule_status_t *rule_status); -OpenAPI_rule_status_t *OpenAPI_rule_status_copy(OpenAPI_rule_status_t *dst, OpenAPI_rule_status_t *src); +char* OpenAPI_rule_status_ToString(OpenAPI_rule_status_e rule_status); + +OpenAPI_rule_status_e OpenAPI_rule_status_FromString(char* rule_status); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/session_rule_failure_code.c b/lib/sbi/openapi/model/session_rule_failure_code.c index 2abb215e1..4b6e0753c 100644 --- a/lib/sbi/openapi/model/session_rule_failure_code.c +++ b/lib/sbi/openapi/model/session_rule_failure_code.c @@ -4,82 +4,27 @@ #include #include "session_rule_failure_code.h" -OpenAPI_session_rule_failure_code_t *OpenAPI_session_rule_failure_code_create( - ) +char* OpenAPI_session_rule_failure_code_ToString(OpenAPI_session_rule_failure_code_e session_rule_failure_code) { - OpenAPI_session_rule_failure_code_t *session_rule_failure_code_local_var = OpenAPI_malloc(sizeof(OpenAPI_session_rule_failure_code_t)); - if (!session_rule_failure_code_local_var) { - return NULL; - } - - return session_rule_failure_code_local_var; + const char *session_rule_failure_codeArray[] = { "NULL", "NF_MAL", "RES_LIM", "UNSUCC_QOS_VAL", "UE_STA_SUSP" }; + size_t sizeofArray = sizeof(session_rule_failure_codeArray) / sizeof(session_rule_failure_codeArray[0]); + if (session_rule_failure_code < sizeofArray) + return (char *)session_rule_failure_codeArray[session_rule_failure_code]; + else + return (char *)"Unknown"; } -void OpenAPI_session_rule_failure_code_free(OpenAPI_session_rule_failure_code_t *session_rule_failure_code) +OpenAPI_session_rule_failure_code_e OpenAPI_session_rule_failure_code_FromString(char* session_rule_failure_code) { - if (NULL == session_rule_failure_code) { - return; + int stringToReturn = 0; + const char *session_rule_failure_codeArray[] = { "NULL", "NF_MAL", "RES_LIM", "UNSUCC_QOS_VAL", "UE_STA_SUSP" }; + size_t sizeofArray = sizeof(session_rule_failure_codeArray) / sizeof(session_rule_failure_codeArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(session_rule_failure_code, session_rule_failure_codeArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(session_rule_failure_code); -} - -cJSON *OpenAPI_session_rule_failure_code_convertToJSON(OpenAPI_session_rule_failure_code_t *session_rule_failure_code) -{ - cJSON *item = NULL; - - if (session_rule_failure_code == NULL) { - ogs_error("OpenAPI_session_rule_failure_code_convertToJSON() failed [SessionRuleFailureCode]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_session_rule_failure_code_t *OpenAPI_session_rule_failure_code_parseFromJSON(cJSON *session_rule_failure_codeJSON) -{ - OpenAPI_session_rule_failure_code_t *session_rule_failure_code_local_var = NULL; - session_rule_failure_code_local_var = OpenAPI_session_rule_failure_code_create ( - ); - - return session_rule_failure_code_local_var; -end: - return NULL; -} - -OpenAPI_session_rule_failure_code_t *OpenAPI_session_rule_failure_code_copy(OpenAPI_session_rule_failure_code_t *dst, OpenAPI_session_rule_failure_code_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_session_rule_failure_code_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_session_rule_failure_code_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_session_rule_failure_code_free(dst); - dst = OpenAPI_session_rule_failure_code_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/session_rule_failure_code.h b/lib/sbi/openapi/model/session_rule_failure_code.h index 932ee5c90..78a9fa134 100644 --- a/lib/sbi/openapi/model/session_rule_failure_code.h +++ b/lib/sbi/openapi/model/session_rule_failure_code.h @@ -1,7 +1,7 @@ /* * session_rule_failure_code.h * - * Possible values are - NF_MAL: Indicate that the PCC rule could not be successfully installed (for those provisioned from the PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to SMF/UPF malfunction. - RES_LIM: Indicate that the PCC rule could not be successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to a limitation of resources at the SMF/UPF. - UNSUCC_QOS_VAL: indicate that the QoS validation has failed. - UE_STA_SUSP: Indicates that the UE is in suspend state. + * */ #ifndef _OpenAPI_session_rule_failure_code_H_ @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_session_rule_failure_code_s OpenAPI_session_rule_failure_code_t; -typedef struct OpenAPI_session_rule_failure_code_s { -} OpenAPI_session_rule_failure_code_t; +typedef enum { OpenAPI_session_rule_failure_code_NULL = 0, OpenAPI_session_rule_failure_code_NF_MAL, OpenAPI_session_rule_failure_code_RES_LIM, OpenAPI_session_rule_failure_code_UNSUCC_QOS_VAL, OpenAPI_session_rule_failure_code_UE_STA_SUSP } OpenAPI_session_rule_failure_code_e; -OpenAPI_session_rule_failure_code_t *OpenAPI_session_rule_failure_code_create( - ); -void OpenAPI_session_rule_failure_code_free(OpenAPI_session_rule_failure_code_t *session_rule_failure_code); -OpenAPI_session_rule_failure_code_t *OpenAPI_session_rule_failure_code_parseFromJSON(cJSON *session_rule_failure_codeJSON); -cJSON *OpenAPI_session_rule_failure_code_convertToJSON(OpenAPI_session_rule_failure_code_t *session_rule_failure_code); -OpenAPI_session_rule_failure_code_t *OpenAPI_session_rule_failure_code_copy(OpenAPI_session_rule_failure_code_t *dst, OpenAPI_session_rule_failure_code_t *src); +char* OpenAPI_session_rule_failure_code_ToString(OpenAPI_session_rule_failure_code_e session_rule_failure_code); + +OpenAPI_session_rule_failure_code_e OpenAPI_session_rule_failure_code_FromString(char* session_rule_failure_code); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/session_rule_report.c b/lib/sbi/openapi/model/session_rule_report.c index 9e3c0ee20..3c8bc9073 100644 --- a/lib/sbi/openapi/model/session_rule_report.c +++ b/lib/sbi/openapi/model/session_rule_report.c @@ -6,8 +6,8 @@ OpenAPI_session_rule_report_t *OpenAPI_session_rule_report_create( OpenAPI_list_t *rule_ids, - OpenAPI_rule_status_t *rule_status, - OpenAPI_session_rule_failure_code_t *sess_rule_failure_code + OpenAPI_rule_status_e rule_status, + OpenAPI_session_rule_failure_code_e sess_rule_failure_code ) { OpenAPI_session_rule_report_t *session_rule_report_local_var = OpenAPI_malloc(sizeof(OpenAPI_session_rule_report_t)); @@ -31,8 +31,6 @@ void OpenAPI_session_rule_report_free(OpenAPI_session_rule_report_t *session_rul ogs_free(node->data); } OpenAPI_list_free(session_rule_report->rule_ids); - OpenAPI_rule_status_free(session_rule_report->rule_status); - OpenAPI_session_rule_failure_code_free(session_rule_report->sess_rule_failure_code); ogs_free(session_rule_report); } @@ -68,25 +66,13 @@ cJSON *OpenAPI_session_rule_report_convertToJSON(OpenAPI_session_rule_report_t * ogs_error("OpenAPI_session_rule_report_convertToJSON() failed [rule_status]"); goto end; } - cJSON *rule_status_local_JSON = OpenAPI_rule_status_convertToJSON(session_rule_report->rule_status); - if (rule_status_local_JSON == NULL) { - ogs_error("OpenAPI_session_rule_report_convertToJSON() failed [rule_status]"); - goto end; - } - cJSON_AddItemToObject(item, "ruleStatus", rule_status_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "ruleStatus", OpenAPI_rule_status_ToString(session_rule_report->rule_status)) == NULL) { ogs_error("OpenAPI_session_rule_report_convertToJSON() failed [rule_status]"); goto end; } if (session_rule_report->sess_rule_failure_code) { - cJSON *sess_rule_failure_code_local_JSON = OpenAPI_session_rule_failure_code_convertToJSON(session_rule_report->sess_rule_failure_code); - if (sess_rule_failure_code_local_JSON == NULL) { - ogs_error("OpenAPI_session_rule_report_convertToJSON() failed [sess_rule_failure_code]"); - goto end; - } - cJSON_AddItemToObject(item, "sessRuleFailureCode", sess_rule_failure_code_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "sessRuleFailureCode", OpenAPI_session_rule_failure_code_ToString(session_rule_report->sess_rule_failure_code)) == NULL) { ogs_error("OpenAPI_session_rule_report_convertToJSON() failed [sess_rule_failure_code]"); goto end; } @@ -128,21 +114,29 @@ OpenAPI_session_rule_report_t *OpenAPI_session_rule_report_parseFromJSON(cJSON * goto end; } - OpenAPI_rule_status_t *rule_status_local_nonprim = NULL; + OpenAPI_rule_status_e rule_statusVariable; - rule_status_local_nonprim = OpenAPI_rule_status_parseFromJSON(rule_status); + if (!cJSON_IsString(rule_status)) { + ogs_error("OpenAPI_session_rule_report_parseFromJSON() failed [rule_status]"); + goto end; + } + rule_statusVariable = OpenAPI_rule_status_FromString(rule_status->valuestring); cJSON *sess_rule_failure_code = cJSON_GetObjectItemCaseSensitive(session_rule_reportJSON, "sessRuleFailureCode"); - OpenAPI_session_rule_failure_code_t *sess_rule_failure_code_local_nonprim = NULL; + OpenAPI_session_rule_failure_code_e sess_rule_failure_codeVariable; if (sess_rule_failure_code) { - sess_rule_failure_code_local_nonprim = OpenAPI_session_rule_failure_code_parseFromJSON(sess_rule_failure_code); + if (!cJSON_IsString(sess_rule_failure_code)) { + ogs_error("OpenAPI_session_rule_report_parseFromJSON() failed [sess_rule_failure_code]"); + goto end; + } + sess_rule_failure_codeVariable = OpenAPI_session_rule_failure_code_FromString(sess_rule_failure_code->valuestring); } session_rule_report_local_var = OpenAPI_session_rule_report_create ( rule_idsList, - rule_status_local_nonprim, - sess_rule_failure_code ? sess_rule_failure_code_local_nonprim : NULL + rule_statusVariable, + sess_rule_failure_code ? sess_rule_failure_codeVariable : 0 ); return session_rule_report_local_var; diff --git a/lib/sbi/openapi/model/session_rule_report.h b/lib/sbi/openapi/model/session_rule_report.h index 80f7a9c25..06ff7f33f 100644 --- a/lib/sbi/openapi/model/session_rule_report.h +++ b/lib/sbi/openapi/model/session_rule_report.h @@ -22,14 +22,14 @@ extern "C" { typedef struct OpenAPI_session_rule_report_s OpenAPI_session_rule_report_t; typedef struct OpenAPI_session_rule_report_s { OpenAPI_list_t *rule_ids; - struct OpenAPI_rule_status_s *rule_status; - struct OpenAPI_session_rule_failure_code_s *sess_rule_failure_code; + OpenAPI_rule_status_e rule_status; + OpenAPI_session_rule_failure_code_e sess_rule_failure_code; } OpenAPI_session_rule_report_t; OpenAPI_session_rule_report_t *OpenAPI_session_rule_report_create( OpenAPI_list_t *rule_ids, - OpenAPI_rule_status_t *rule_status, - OpenAPI_session_rule_failure_code_t *sess_rule_failure_code + OpenAPI_rule_status_e rule_status, + OpenAPI_session_rule_failure_code_e sess_rule_failure_code ); void OpenAPI_session_rule_report_free(OpenAPI_session_rule_report_t *session_rule_report); OpenAPI_session_rule_report_t *OpenAPI_session_rule_report_parseFromJSON(cJSON *session_rule_reportJSON); diff --git a/lib/sbi/openapi/model/sm_policy_association_release_cause.c b/lib/sbi/openapi/model/sm_policy_association_release_cause.c index e13fa88fd..10d4a5269 100644 --- a/lib/sbi/openapi/model/sm_policy_association_release_cause.c +++ b/lib/sbi/openapi/model/sm_policy_association_release_cause.c @@ -4,82 +4,27 @@ #include #include "sm_policy_association_release_cause.h" -OpenAPI_sm_policy_association_release_cause_t *OpenAPI_sm_policy_association_release_cause_create( - ) +char* OpenAPI_sm_policy_association_release_cause_ToString(OpenAPI_sm_policy_association_release_cause_e sm_policy_association_release_cause) { - OpenAPI_sm_policy_association_release_cause_t *sm_policy_association_release_cause_local_var = OpenAPI_malloc(sizeof(OpenAPI_sm_policy_association_release_cause_t)); - if (!sm_policy_association_release_cause_local_var) { - return NULL; - } - - return sm_policy_association_release_cause_local_var; + const char *sm_policy_association_release_causeArray[] = { "NULL", "UNSPECIFIED", "UE_SUBSCRIPTION", "INSUFFICIENT_RES", "VALIDATION_CONDITION_NOT_MET" }; + size_t sizeofArray = sizeof(sm_policy_association_release_causeArray) / sizeof(sm_policy_association_release_causeArray[0]); + if (sm_policy_association_release_cause < sizeofArray) + return (char *)sm_policy_association_release_causeArray[sm_policy_association_release_cause]; + else + return (char *)"Unknown"; } -void OpenAPI_sm_policy_association_release_cause_free(OpenAPI_sm_policy_association_release_cause_t *sm_policy_association_release_cause) +OpenAPI_sm_policy_association_release_cause_e OpenAPI_sm_policy_association_release_cause_FromString(char* sm_policy_association_release_cause) { - if (NULL == sm_policy_association_release_cause) { - return; + int stringToReturn = 0; + const char *sm_policy_association_release_causeArray[] = { "NULL", "UNSPECIFIED", "UE_SUBSCRIPTION", "INSUFFICIENT_RES", "VALIDATION_CONDITION_NOT_MET" }; + size_t sizeofArray = sizeof(sm_policy_association_release_causeArray) / sizeof(sm_policy_association_release_causeArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(sm_policy_association_release_cause, sm_policy_association_release_causeArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(sm_policy_association_release_cause); -} - -cJSON *OpenAPI_sm_policy_association_release_cause_convertToJSON(OpenAPI_sm_policy_association_release_cause_t *sm_policy_association_release_cause) -{ - cJSON *item = NULL; - - if (sm_policy_association_release_cause == NULL) { - ogs_error("OpenAPI_sm_policy_association_release_cause_convertToJSON() failed [SmPolicyAssociationReleaseCause]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_sm_policy_association_release_cause_t *OpenAPI_sm_policy_association_release_cause_parseFromJSON(cJSON *sm_policy_association_release_causeJSON) -{ - OpenAPI_sm_policy_association_release_cause_t *sm_policy_association_release_cause_local_var = NULL; - sm_policy_association_release_cause_local_var = OpenAPI_sm_policy_association_release_cause_create ( - ); - - return sm_policy_association_release_cause_local_var; -end: - return NULL; -} - -OpenAPI_sm_policy_association_release_cause_t *OpenAPI_sm_policy_association_release_cause_copy(OpenAPI_sm_policy_association_release_cause_t *dst, OpenAPI_sm_policy_association_release_cause_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_sm_policy_association_release_cause_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_sm_policy_association_release_cause_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_sm_policy_association_release_cause_free(dst); - dst = OpenAPI_sm_policy_association_release_cause_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/sm_policy_association_release_cause.h b/lib/sbi/openapi/model/sm_policy_association_release_cause.h index 8ba77e8da..1f9e98cbb 100644 --- a/lib/sbi/openapi/model/sm_policy_association_release_cause.h +++ b/lib/sbi/openapi/model/sm_policy_association_release_cause.h @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_sm_policy_association_release_cause_s OpenAPI_sm_policy_association_release_cause_t; -typedef struct OpenAPI_sm_policy_association_release_cause_s { -} OpenAPI_sm_policy_association_release_cause_t; +typedef enum { OpenAPI_sm_policy_association_release_cause_NULL = 0, OpenAPI_sm_policy_association_release_cause_UNSPECIFIED, OpenAPI_sm_policy_association_release_cause_UE_SUBSCRIPTION, OpenAPI_sm_policy_association_release_cause_INSUFFICIENT_RES, OpenAPI_sm_policy_association_release_cause_VALIDATION_CONDITION_NOT_MET } OpenAPI_sm_policy_association_release_cause_e; -OpenAPI_sm_policy_association_release_cause_t *OpenAPI_sm_policy_association_release_cause_create( - ); -void OpenAPI_sm_policy_association_release_cause_free(OpenAPI_sm_policy_association_release_cause_t *sm_policy_association_release_cause); -OpenAPI_sm_policy_association_release_cause_t *OpenAPI_sm_policy_association_release_cause_parseFromJSON(cJSON *sm_policy_association_release_causeJSON); -cJSON *OpenAPI_sm_policy_association_release_cause_convertToJSON(OpenAPI_sm_policy_association_release_cause_t *sm_policy_association_release_cause); -OpenAPI_sm_policy_association_release_cause_t *OpenAPI_sm_policy_association_release_cause_copy(OpenAPI_sm_policy_association_release_cause_t *dst, OpenAPI_sm_policy_association_release_cause_t *src); +char* OpenAPI_sm_policy_association_release_cause_ToString(OpenAPI_sm_policy_association_release_cause_e sm_policy_association_release_cause); + +OpenAPI_sm_policy_association_release_cause_e OpenAPI_sm_policy_association_release_cause_FromString(char* sm_policy_association_release_cause); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/sm_policy_context_data.c b/lib/sbi/openapi/model/sm_policy_context_data.c index 0804b6645..4e8497bef 100644 --- a/lib/sbi/openapi/model/sm_policy_context_data.c +++ b/lib/sbi/openapi/model/sm_policy_context_data.c @@ -36,12 +36,12 @@ OpenAPI_sm_policy_context_data_t *OpenAPI_sm_policy_context_data_create( int ref_qos_indication, OpenAPI_trace_data_t *trace_req, OpenAPI_snssai_t *slice_info, - OpenAPI_qos_flow_usage_t *qos_flow_usage, + OpenAPI_qos_flow_usage_e qos_flow_usage, OpenAPI_serving_nf_identity_t *serv_nf_id, char *supp_feat, char *smf_id, char *recovery_time, - OpenAPI_ma_pdu_indication_t *ma_pdu_ind, + OpenAPI_ma_pdu_indication_e ma_pdu_ind, OpenAPI_atsss_capability_t *atsss_capab ) { @@ -121,12 +121,10 @@ void OpenAPI_sm_policy_context_data_free(OpenAPI_sm_policy_context_data_t *sm_po OpenAPI_subscribed_default_qos_free(sm_policy_context_data->subs_def_qos); OpenAPI_trace_data_free(sm_policy_context_data->trace_req); OpenAPI_snssai_free(sm_policy_context_data->slice_info); - OpenAPI_qos_flow_usage_free(sm_policy_context_data->qos_flow_usage); OpenAPI_serving_nf_identity_free(sm_policy_context_data->serv_nf_id); ogs_free(sm_policy_context_data->supp_feat); ogs_free(sm_policy_context_data->smf_id); ogs_free(sm_policy_context_data->recovery_time); - OpenAPI_ma_pdu_indication_free(sm_policy_context_data->ma_pdu_ind); OpenAPI_atsss_capability_free(sm_policy_context_data->atsss_capab); ogs_free(sm_policy_context_data); } @@ -434,13 +432,7 @@ cJSON *OpenAPI_sm_policy_context_data_convertToJSON(OpenAPI_sm_policy_context_da } if (sm_policy_context_data->qos_flow_usage) { - cJSON *qos_flow_usage_local_JSON = OpenAPI_qos_flow_usage_convertToJSON(sm_policy_context_data->qos_flow_usage); - if (qos_flow_usage_local_JSON == NULL) { - ogs_error("OpenAPI_sm_policy_context_data_convertToJSON() failed [qos_flow_usage]"); - goto end; - } - cJSON_AddItemToObject(item, "qosFlowUsage", qos_flow_usage_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "qosFlowUsage", OpenAPI_qos_flow_usage_ToString(sm_policy_context_data->qos_flow_usage)) == NULL) { ogs_error("OpenAPI_sm_policy_context_data_convertToJSON() failed [qos_flow_usage]"); goto end; } @@ -481,13 +473,7 @@ cJSON *OpenAPI_sm_policy_context_data_convertToJSON(OpenAPI_sm_policy_context_da } if (sm_policy_context_data->ma_pdu_ind) { - cJSON *ma_pdu_ind_local_JSON = OpenAPI_ma_pdu_indication_convertToJSON(sm_policy_context_data->ma_pdu_ind); - if (ma_pdu_ind_local_JSON == NULL) { - ogs_error("OpenAPI_sm_policy_context_data_convertToJSON() failed [ma_pdu_ind]"); - goto end; - } - cJSON_AddItemToObject(item, "maPduInd", ma_pdu_ind_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "maPduInd", OpenAPI_ma_pdu_indication_ToString(sm_policy_context_data->ma_pdu_ind)) == NULL) { ogs_error("OpenAPI_sm_policy_context_data_convertToJSON() failed [ma_pdu_ind]"); goto end; } @@ -813,9 +799,13 @@ OpenAPI_sm_policy_context_data_t *OpenAPI_sm_policy_context_data_parseFromJSON(c cJSON *qos_flow_usage = cJSON_GetObjectItemCaseSensitive(sm_policy_context_dataJSON, "qosFlowUsage"); - OpenAPI_qos_flow_usage_t *qos_flow_usage_local_nonprim = NULL; + OpenAPI_qos_flow_usage_e qos_flow_usageVariable; if (qos_flow_usage) { - qos_flow_usage_local_nonprim = OpenAPI_qos_flow_usage_parseFromJSON(qos_flow_usage); + if (!cJSON_IsString(qos_flow_usage)) { + ogs_error("OpenAPI_sm_policy_context_data_parseFromJSON() failed [qos_flow_usage]"); + goto end; + } + qos_flow_usageVariable = OpenAPI_qos_flow_usage_FromString(qos_flow_usage->valuestring); } cJSON *serv_nf_id = cJSON_GetObjectItemCaseSensitive(sm_policy_context_dataJSON, "servNfId"); @@ -854,9 +844,13 @@ OpenAPI_sm_policy_context_data_t *OpenAPI_sm_policy_context_data_parseFromJSON(c cJSON *ma_pdu_ind = cJSON_GetObjectItemCaseSensitive(sm_policy_context_dataJSON, "maPduInd"); - OpenAPI_ma_pdu_indication_t *ma_pdu_ind_local_nonprim = NULL; + OpenAPI_ma_pdu_indication_e ma_pdu_indVariable; if (ma_pdu_ind) { - ma_pdu_ind_local_nonprim = OpenAPI_ma_pdu_indication_parseFromJSON(ma_pdu_ind); + if (!cJSON_IsString(ma_pdu_ind)) { + ogs_error("OpenAPI_sm_policy_context_data_parseFromJSON() failed [ma_pdu_ind]"); + goto end; + } + ma_pdu_indVariable = OpenAPI_ma_pdu_indication_FromString(ma_pdu_ind->valuestring); } cJSON *atsss_capab = cJSON_GetObjectItemCaseSensitive(sm_policy_context_dataJSON, "atsssCapab"); @@ -898,12 +892,12 @@ OpenAPI_sm_policy_context_data_t *OpenAPI_sm_policy_context_data_parseFromJSON(c ref_qos_indication ? ref_qos_indication->valueint : 0, trace_req ? trace_req_local_nonprim : NULL, slice_info_local_nonprim, - qos_flow_usage ? qos_flow_usage_local_nonprim : NULL, + qos_flow_usage ? qos_flow_usageVariable : 0, serv_nf_id ? serv_nf_id_local_nonprim : NULL, supp_feat ? ogs_strdup(supp_feat->valuestring) : NULL, smf_id ? ogs_strdup(smf_id->valuestring) : NULL, recovery_time ? ogs_strdup(recovery_time->valuestring) : NULL, - ma_pdu_ind ? ma_pdu_ind_local_nonprim : NULL, + ma_pdu_ind ? ma_pdu_indVariable : 0, atsss_capab ? atsss_capab_local_nonprim : NULL ); diff --git a/lib/sbi/openapi/model/sm_policy_context_data.h b/lib/sbi/openapi/model/sm_policy_context_data.h index 25da1689d..f4b1e9c7e 100644 --- a/lib/sbi/openapi/model/sm_policy_context_data.h +++ b/lib/sbi/openapi/model/sm_policy_context_data.h @@ -67,12 +67,12 @@ typedef struct OpenAPI_sm_policy_context_data_s { int ref_qos_indication; struct OpenAPI_trace_data_s *trace_req; struct OpenAPI_snssai_s *slice_info; - struct OpenAPI_qos_flow_usage_s *qos_flow_usage; + OpenAPI_qos_flow_usage_e qos_flow_usage; struct OpenAPI_serving_nf_identity_s *serv_nf_id; char *supp_feat; char *smf_id; char *recovery_time; - struct OpenAPI_ma_pdu_indication_s *ma_pdu_ind; + OpenAPI_ma_pdu_indication_e ma_pdu_ind; struct OpenAPI_atsss_capability_s *atsss_capab; } OpenAPI_sm_policy_context_data_t; @@ -108,12 +108,12 @@ OpenAPI_sm_policy_context_data_t *OpenAPI_sm_policy_context_data_create( int ref_qos_indication, OpenAPI_trace_data_t *trace_req, OpenAPI_snssai_t *slice_info, - OpenAPI_qos_flow_usage_t *qos_flow_usage, + OpenAPI_qos_flow_usage_e qos_flow_usage, OpenAPI_serving_nf_identity_t *serv_nf_id, char *supp_feat, char *smf_id, char *recovery_time, - OpenAPI_ma_pdu_indication_t *ma_pdu_ind, + OpenAPI_ma_pdu_indication_e ma_pdu_ind, OpenAPI_atsss_capability_t *atsss_capab ); void OpenAPI_sm_policy_context_data_free(OpenAPI_sm_policy_context_data_t *sm_policy_context_data); diff --git a/lib/sbi/openapi/model/sm_policy_decision.c b/lib/sbi/openapi/model/sm_policy_decision.c index 699927b3b..8501eb01d 100644 --- a/lib/sbi/openapi/model/sm_policy_decision.c +++ b/lib/sbi/openapi/model/sm_policy_decision.c @@ -26,8 +26,8 @@ OpenAPI_sm_policy_decision_t *OpenAPI_sm_policy_decision_create( OpenAPI_list_t* pra_infos, int ipv4_index, int ipv6_index, - OpenAPI_qos_flow_usage_t *qos_flow_usage, - OpenAPI_sm_policy_association_release_cause_t *rel_cause, + OpenAPI_qos_flow_usage_e qos_flow_usage, + OpenAPI_sm_policy_association_release_cause_e rel_cause, char *supp_feat, OpenAPI_port_management_container_t *tsn_port_man_cont_dstt, OpenAPI_list_t *tsn_port_man_cont_nwtts @@ -129,9 +129,6 @@ void OpenAPI_sm_policy_decision_free(OpenAPI_sm_policy_decision_t *sm_policy_dec } OpenAPI_list_free(sm_policy_decision->conds); ogs_free(sm_policy_decision->revalidation_time); - OpenAPI_list_for_each(sm_policy_decision->policy_ctrl_req_triggers, node) { - OpenAPI_policy_control_request_trigger_free(node->data); - } OpenAPI_list_free(sm_policy_decision->policy_ctrl_req_triggers); OpenAPI_list_for_each(sm_policy_decision->last_req_rule_data, node) { OpenAPI_requested_rule_data_free(node->data); @@ -144,8 +141,6 @@ void OpenAPI_sm_policy_decision_free(OpenAPI_sm_policy_decision_t *sm_policy_dec ogs_free(localKeyValue); } OpenAPI_list_free(sm_policy_decision->pra_infos); - OpenAPI_qos_flow_usage_free(sm_policy_decision->qos_flow_usage); - OpenAPI_sm_policy_association_release_cause_free(sm_policy_decision->rel_cause); ogs_free(sm_policy_decision->supp_feat); OpenAPI_port_management_container_free(sm_policy_decision->tsn_port_man_cont_dstt); OpenAPI_list_for_each(sm_policy_decision->tsn_port_man_cont_nwtts, node) { @@ -403,21 +398,16 @@ cJSON *OpenAPI_sm_policy_decision_convertToJSON(OpenAPI_sm_policy_decision_t *sm } if (sm_policy_decision->policy_ctrl_req_triggers) { - cJSON *policy_ctrl_req_triggersList = cJSON_AddArrayToObject(item, "policyCtrlReqTriggers"); - if (policy_ctrl_req_triggersList == NULL) { + cJSON *policy_ctrl_req_triggers = cJSON_AddArrayToObject(item, "policyCtrlReqTriggers"); + if (policy_ctrl_req_triggers == NULL) { ogs_error("OpenAPI_sm_policy_decision_convertToJSON() failed [policy_ctrl_req_triggers]"); goto end; } - OpenAPI_lnode_t *policy_ctrl_req_triggers_node; - if (sm_policy_decision->policy_ctrl_req_triggers) { - OpenAPI_list_for_each(sm_policy_decision->policy_ctrl_req_triggers, policy_ctrl_req_triggers_node) { - cJSON *itemLocal = OpenAPI_policy_control_request_trigger_convertToJSON(policy_ctrl_req_triggers_node->data); - if (itemLocal == NULL) { - ogs_error("OpenAPI_sm_policy_decision_convertToJSON() failed [policy_ctrl_req_triggers]"); - goto end; - } - cJSON_AddItemToArray(policy_ctrl_req_triggersList, itemLocal); + OpenAPI_list_for_each(sm_policy_decision->policy_ctrl_req_triggers, policy_ctrl_req_triggers_node) { + if (cJSON_AddStringToObject(policy_ctrl_req_triggers, "", OpenAPI_policy_control_request_trigger_ToString((OpenAPI_policy_control_request_trigger_e)policy_ctrl_req_triggers_node->data)) == NULL) { + ogs_error("OpenAPI_sm_policy_decision_convertToJSON() failed [policy_ctrl_req_triggers]"); + goto end; } } } @@ -491,26 +481,14 @@ cJSON *OpenAPI_sm_policy_decision_convertToJSON(OpenAPI_sm_policy_decision_t *sm } if (sm_policy_decision->qos_flow_usage) { - cJSON *qos_flow_usage_local_JSON = OpenAPI_qos_flow_usage_convertToJSON(sm_policy_decision->qos_flow_usage); - if (qos_flow_usage_local_JSON == NULL) { - ogs_error("OpenAPI_sm_policy_decision_convertToJSON() failed [qos_flow_usage]"); - goto end; - } - cJSON_AddItemToObject(item, "qosFlowUsage", qos_flow_usage_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "qosFlowUsage", OpenAPI_qos_flow_usage_ToString(sm_policy_decision->qos_flow_usage)) == NULL) { ogs_error("OpenAPI_sm_policy_decision_convertToJSON() failed [qos_flow_usage]"); goto end; } } if (sm_policy_decision->rel_cause) { - cJSON *rel_cause_local_JSON = OpenAPI_sm_policy_association_release_cause_convertToJSON(sm_policy_decision->rel_cause); - if (rel_cause_local_JSON == NULL) { - ogs_error("OpenAPI_sm_policy_decision_convertToJSON() failed [rel_cause]"); - goto end; - } - cJSON_AddItemToObject(item, "relCause", rel_cause_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "relCause", OpenAPI_sm_policy_association_release_cause_ToString(sm_policy_decision->rel_cause)) == NULL) { ogs_error("OpenAPI_sm_policy_decision_convertToJSON() failed [rel_cause]"); goto end; } @@ -835,13 +813,12 @@ OpenAPI_sm_policy_decision_t *OpenAPI_sm_policy_decision_parseFromJSON(cJSON *sm policy_ctrl_req_triggersList = OpenAPI_list_create(); cJSON_ArrayForEach(policy_ctrl_req_triggers_local_nonprimitive, policy_ctrl_req_triggers ) { - if (!cJSON_IsObject(policy_ctrl_req_triggers_local_nonprimitive)) { + if (!cJSON_IsString(policy_ctrl_req_triggers_local_nonprimitive)) { ogs_error("OpenAPI_sm_policy_decision_parseFromJSON() failed [policy_ctrl_req_triggers]"); goto end; } - OpenAPI_policy_control_request_trigger_t *policy_ctrl_req_triggersItem = OpenAPI_policy_control_request_trigger_parseFromJSON(policy_ctrl_req_triggers_local_nonprimitive); - OpenAPI_list_add(policy_ctrl_req_triggersList, policy_ctrl_req_triggersItem); + OpenAPI_list_add(policy_ctrl_req_triggersList, (void *)OpenAPI_policy_control_request_trigger_FromString(policy_ctrl_req_triggers_local_nonprimitive->valuestring)); } } @@ -918,16 +895,24 @@ OpenAPI_sm_policy_decision_t *OpenAPI_sm_policy_decision_parseFromJSON(cJSON *sm cJSON *qos_flow_usage = cJSON_GetObjectItemCaseSensitive(sm_policy_decisionJSON, "qosFlowUsage"); - OpenAPI_qos_flow_usage_t *qos_flow_usage_local_nonprim = NULL; + OpenAPI_qos_flow_usage_e qos_flow_usageVariable; if (qos_flow_usage) { - qos_flow_usage_local_nonprim = OpenAPI_qos_flow_usage_parseFromJSON(qos_flow_usage); + if (!cJSON_IsString(qos_flow_usage)) { + ogs_error("OpenAPI_sm_policy_decision_parseFromJSON() failed [qos_flow_usage]"); + goto end; + } + qos_flow_usageVariable = OpenAPI_qos_flow_usage_FromString(qos_flow_usage->valuestring); } cJSON *rel_cause = cJSON_GetObjectItemCaseSensitive(sm_policy_decisionJSON, "relCause"); - OpenAPI_sm_policy_association_release_cause_t *rel_cause_local_nonprim = NULL; + OpenAPI_sm_policy_association_release_cause_e rel_causeVariable; if (rel_cause) { - rel_cause_local_nonprim = OpenAPI_sm_policy_association_release_cause_parseFromJSON(rel_cause); + if (!cJSON_IsString(rel_cause)) { + ogs_error("OpenAPI_sm_policy_decision_parseFromJSON() failed [rel_cause]"); + goto end; + } + rel_causeVariable = OpenAPI_sm_policy_association_release_cause_FromString(rel_cause->valuestring); } cJSON *supp_feat = cJSON_GetObjectItemCaseSensitive(sm_policy_decisionJSON, "suppFeat"); @@ -991,8 +976,8 @@ OpenAPI_sm_policy_decision_t *OpenAPI_sm_policy_decision_parseFromJSON(cJSON *sm pra_infos ? pra_infosList : NULL, ipv4_index ? ipv4_index->valuedouble : 0, ipv6_index ? ipv6_index->valuedouble : 0, - qos_flow_usage ? qos_flow_usage_local_nonprim : NULL, - rel_cause ? rel_cause_local_nonprim : NULL, + qos_flow_usage ? qos_flow_usageVariable : 0, + rel_cause ? rel_causeVariable : 0, supp_feat ? ogs_strdup(supp_feat->valuestring) : NULL, tsn_port_man_cont_dstt ? tsn_port_man_cont_dstt_local_nonprim : NULL, tsn_port_man_cont_nwtts ? tsn_port_man_cont_nwttsList : NULL diff --git a/lib/sbi/openapi/model/sm_policy_decision.h b/lib/sbi/openapi/model/sm_policy_decision.h index 325e54ab1..38c174176 100644 --- a/lib/sbi/openapi/model/sm_policy_decision.h +++ b/lib/sbi/openapi/model/sm_policy_decision.h @@ -57,8 +57,8 @@ typedef struct OpenAPI_sm_policy_decision_s { OpenAPI_list_t* pra_infos; int ipv4_index; int ipv6_index; - struct OpenAPI_qos_flow_usage_s *qos_flow_usage; - struct OpenAPI_sm_policy_association_release_cause_s *rel_cause; + OpenAPI_qos_flow_usage_e qos_flow_usage; + OpenAPI_sm_policy_association_release_cause_e rel_cause; char *supp_feat; struct OpenAPI_port_management_container_s *tsn_port_man_cont_dstt; OpenAPI_list_t *tsn_port_man_cont_nwtts; @@ -86,8 +86,8 @@ OpenAPI_sm_policy_decision_t *OpenAPI_sm_policy_decision_create( OpenAPI_list_t* pra_infos, int ipv4_index, int ipv6_index, - OpenAPI_qos_flow_usage_t *qos_flow_usage, - OpenAPI_sm_policy_association_release_cause_t *rel_cause, + OpenAPI_qos_flow_usage_e qos_flow_usage, + OpenAPI_sm_policy_association_release_cause_e rel_cause, char *supp_feat, OpenAPI_port_management_container_t *tsn_port_man_cont_dstt, OpenAPI_list_t *tsn_port_man_cont_nwtts diff --git a/lib/sbi/openapi/model/sm_policy_delete_data.c b/lib/sbi/openapi/model/sm_policy_delete_data.c index 04909137d..d856d53e8 100644 --- a/lib/sbi/openapi/model/sm_policy_delete_data.c +++ b/lib/sbi/openapi/model/sm_policy_delete_data.c @@ -11,7 +11,7 @@ OpenAPI_sm_policy_delete_data_t *OpenAPI_sm_policy_delete_data_create( char *user_location_info_time, OpenAPI_list_t *ran_nas_rel_causes, OpenAPI_list_t *accu_usage_reports, - OpenAPI_pdu_session_rel_cause_t *pdu_sess_rel_cause + OpenAPI_pdu_session_rel_cause_e pdu_sess_rel_cause ) { OpenAPI_sm_policy_delete_data_t *sm_policy_delete_data_local_var = OpenAPI_malloc(sizeof(OpenAPI_sm_policy_delete_data_t)); @@ -47,7 +47,6 @@ void OpenAPI_sm_policy_delete_data_free(OpenAPI_sm_policy_delete_data_t *sm_poli OpenAPI_accu_usage_report_free(node->data); } OpenAPI_list_free(sm_policy_delete_data->accu_usage_reports); - OpenAPI_pdu_session_rel_cause_free(sm_policy_delete_data->pdu_sess_rel_cause); ogs_free(sm_policy_delete_data); } @@ -142,13 +141,7 @@ cJSON *OpenAPI_sm_policy_delete_data_convertToJSON(OpenAPI_sm_policy_delete_data } if (sm_policy_delete_data->pdu_sess_rel_cause) { - cJSON *pdu_sess_rel_cause_local_JSON = OpenAPI_pdu_session_rel_cause_convertToJSON(sm_policy_delete_data->pdu_sess_rel_cause); - if (pdu_sess_rel_cause_local_JSON == NULL) { - ogs_error("OpenAPI_sm_policy_delete_data_convertToJSON() failed [pdu_sess_rel_cause]"); - goto end; - } - cJSON_AddItemToObject(item, "pduSessRelCause", pdu_sess_rel_cause_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "pduSessRelCause", OpenAPI_pdu_session_rel_cause_ToString(sm_policy_delete_data->pdu_sess_rel_cause)) == NULL) { ogs_error("OpenAPI_sm_policy_delete_data_convertToJSON() failed [pdu_sess_rel_cause]"); goto end; } @@ -241,9 +234,13 @@ OpenAPI_sm_policy_delete_data_t *OpenAPI_sm_policy_delete_data_parseFromJSON(cJS cJSON *pdu_sess_rel_cause = cJSON_GetObjectItemCaseSensitive(sm_policy_delete_dataJSON, "pduSessRelCause"); - OpenAPI_pdu_session_rel_cause_t *pdu_sess_rel_cause_local_nonprim = NULL; + OpenAPI_pdu_session_rel_cause_e pdu_sess_rel_causeVariable; if (pdu_sess_rel_cause) { - pdu_sess_rel_cause_local_nonprim = OpenAPI_pdu_session_rel_cause_parseFromJSON(pdu_sess_rel_cause); + if (!cJSON_IsString(pdu_sess_rel_cause)) { + ogs_error("OpenAPI_sm_policy_delete_data_parseFromJSON() failed [pdu_sess_rel_cause]"); + goto end; + } + pdu_sess_rel_causeVariable = OpenAPI_pdu_session_rel_cause_FromString(pdu_sess_rel_cause->valuestring); } sm_policy_delete_data_local_var = OpenAPI_sm_policy_delete_data_create ( @@ -253,7 +250,7 @@ OpenAPI_sm_policy_delete_data_t *OpenAPI_sm_policy_delete_data_parseFromJSON(cJS user_location_info_time ? ogs_strdup(user_location_info_time->valuestring) : NULL, ran_nas_rel_causes ? ran_nas_rel_causesList : NULL, accu_usage_reports ? accu_usage_reportsList : NULL, - pdu_sess_rel_cause ? pdu_sess_rel_cause_local_nonprim : NULL + pdu_sess_rel_cause ? pdu_sess_rel_causeVariable : 0 ); return sm_policy_delete_data_local_var; diff --git a/lib/sbi/openapi/model/sm_policy_delete_data.h b/lib/sbi/openapi/model/sm_policy_delete_data.h index ca05df7f3..baef3f480 100644 --- a/lib/sbi/openapi/model/sm_policy_delete_data.h +++ b/lib/sbi/openapi/model/sm_policy_delete_data.h @@ -30,7 +30,7 @@ typedef struct OpenAPI_sm_policy_delete_data_s { char *user_location_info_time; OpenAPI_list_t *ran_nas_rel_causes; OpenAPI_list_t *accu_usage_reports; - struct OpenAPI_pdu_session_rel_cause_s *pdu_sess_rel_cause; + OpenAPI_pdu_session_rel_cause_e pdu_sess_rel_cause; } OpenAPI_sm_policy_delete_data_t; OpenAPI_sm_policy_delete_data_t *OpenAPI_sm_policy_delete_data_create( @@ -40,7 +40,7 @@ OpenAPI_sm_policy_delete_data_t *OpenAPI_sm_policy_delete_data_create( char *user_location_info_time, OpenAPI_list_t *ran_nas_rel_causes, OpenAPI_list_t *accu_usage_reports, - OpenAPI_pdu_session_rel_cause_t *pdu_sess_rel_cause + OpenAPI_pdu_session_rel_cause_e pdu_sess_rel_cause ); void OpenAPI_sm_policy_delete_data_free(OpenAPI_sm_policy_delete_data_t *sm_policy_delete_data); OpenAPI_sm_policy_delete_data_t *OpenAPI_sm_policy_delete_data_parseFromJSON(cJSON *sm_policy_delete_dataJSON); diff --git a/lib/sbi/openapi/model/sm_policy_update_context_data.c b/lib/sbi/openapi/model/sm_policy_update_context_data.c index eb2dd31e3..be5e714be 100644 --- a/lib/sbi/openapi/model/sm_policy_update_context_data.c +++ b/lib/sbi/openapi/model/sm_policy_update_context_data.c @@ -38,11 +38,11 @@ OpenAPI_sm_policy_update_context_data_t *OpenAPI_sm_policy_update_context_data_c OpenAPI_list_t* rep_pra_infos, OpenAPI_ue_initiated_resource_request_t *ue_init_res_req, int ref_qos_indication, - OpenAPI_qos_flow_usage_t *qos_flow_usage, - OpenAPI_credit_management_status_t *credit_manage_status, + OpenAPI_qos_flow_usage_e qos_flow_usage, + OpenAPI_credit_management_status_e credit_manage_status, OpenAPI_serving_nf_identity_t *serv_nf_id, OpenAPI_trace_data_t *trace_req, - OpenAPI_ma_pdu_indication_t *ma_pdu_ind, + OpenAPI_ma_pdu_indication_e ma_pdu_ind, OpenAPI_atsss_capability_t *atsss_capab, OpenAPI_tsn_bridge_info_t *tsn_bridge_info, OpenAPI_port_management_container_t *tsn_port_man_cont_dstt, @@ -107,9 +107,6 @@ void OpenAPI_sm_policy_update_context_data_free(OpenAPI_sm_policy_update_context return; } OpenAPI_lnode_t *node; - OpenAPI_list_for_each(sm_policy_update_context_data->rep_policy_ctrl_req_triggers, node) { - OpenAPI_policy_control_request_trigger_free(node->data); - } OpenAPI_list_free(sm_policy_update_context_data->rep_policy_ctrl_req_triggers); OpenAPI_list_for_each(sm_policy_update_context_data->acc_net_ch_ids, node) { OpenAPI_acc_net_ch_id_free(node->data); @@ -164,11 +161,8 @@ void OpenAPI_sm_policy_update_context_data_free(OpenAPI_sm_policy_update_context } OpenAPI_list_free(sm_policy_update_context_data->rep_pra_infos); OpenAPI_ue_initiated_resource_request_free(sm_policy_update_context_data->ue_init_res_req); - OpenAPI_qos_flow_usage_free(sm_policy_update_context_data->qos_flow_usage); - OpenAPI_credit_management_status_free(sm_policy_update_context_data->credit_manage_status); OpenAPI_serving_nf_identity_free(sm_policy_update_context_data->serv_nf_id); OpenAPI_trace_data_free(sm_policy_update_context_data->trace_req); - OpenAPI_ma_pdu_indication_free(sm_policy_update_context_data->ma_pdu_ind); OpenAPI_atsss_capability_free(sm_policy_update_context_data->atsss_capab); OpenAPI_tsn_bridge_info_free(sm_policy_update_context_data->tsn_bridge_info); OpenAPI_port_management_container_free(sm_policy_update_context_data->tsn_port_man_cont_dstt); @@ -194,21 +188,16 @@ cJSON *OpenAPI_sm_policy_update_context_data_convertToJSON(OpenAPI_sm_policy_upd item = cJSON_CreateObject(); if (sm_policy_update_context_data->rep_policy_ctrl_req_triggers) { - cJSON *rep_policy_ctrl_req_triggersList = cJSON_AddArrayToObject(item, "repPolicyCtrlReqTriggers"); - if (rep_policy_ctrl_req_triggersList == NULL) { + cJSON *rep_policy_ctrl_req_triggers = cJSON_AddArrayToObject(item, "repPolicyCtrlReqTriggers"); + if (rep_policy_ctrl_req_triggers == NULL) { ogs_error("OpenAPI_sm_policy_update_context_data_convertToJSON() failed [rep_policy_ctrl_req_triggers]"); goto end; } - OpenAPI_lnode_t *rep_policy_ctrl_req_triggers_node; - if (sm_policy_update_context_data->rep_policy_ctrl_req_triggers) { - OpenAPI_list_for_each(sm_policy_update_context_data->rep_policy_ctrl_req_triggers, rep_policy_ctrl_req_triggers_node) { - cJSON *itemLocal = OpenAPI_policy_control_request_trigger_convertToJSON(rep_policy_ctrl_req_triggers_node->data); - if (itemLocal == NULL) { - ogs_error("OpenAPI_sm_policy_update_context_data_convertToJSON() failed [rep_policy_ctrl_req_triggers]"); - goto end; - } - cJSON_AddItemToArray(rep_policy_ctrl_req_triggersList, itemLocal); + OpenAPI_list_for_each(sm_policy_update_context_data->rep_policy_ctrl_req_triggers, rep_policy_ctrl_req_triggers_node) { + if (cJSON_AddStringToObject(rep_policy_ctrl_req_triggers, "", OpenAPI_policy_control_request_trigger_ToString((OpenAPI_policy_control_request_trigger_e)rep_policy_ctrl_req_triggers_node->data)) == NULL) { + ogs_error("OpenAPI_sm_policy_update_context_data_convertToJSON() failed [rep_policy_ctrl_req_triggers]"); + goto end; } } } @@ -585,26 +574,14 @@ cJSON *OpenAPI_sm_policy_update_context_data_convertToJSON(OpenAPI_sm_policy_upd } if (sm_policy_update_context_data->qos_flow_usage) { - cJSON *qos_flow_usage_local_JSON = OpenAPI_qos_flow_usage_convertToJSON(sm_policy_update_context_data->qos_flow_usage); - if (qos_flow_usage_local_JSON == NULL) { - ogs_error("OpenAPI_sm_policy_update_context_data_convertToJSON() failed [qos_flow_usage]"); - goto end; - } - cJSON_AddItemToObject(item, "qosFlowUsage", qos_flow_usage_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "qosFlowUsage", OpenAPI_qos_flow_usage_ToString(sm_policy_update_context_data->qos_flow_usage)) == NULL) { ogs_error("OpenAPI_sm_policy_update_context_data_convertToJSON() failed [qos_flow_usage]"); goto end; } } if (sm_policy_update_context_data->credit_manage_status) { - cJSON *credit_manage_status_local_JSON = OpenAPI_credit_management_status_convertToJSON(sm_policy_update_context_data->credit_manage_status); - if (credit_manage_status_local_JSON == NULL) { - ogs_error("OpenAPI_sm_policy_update_context_data_convertToJSON() failed [credit_manage_status]"); - goto end; - } - cJSON_AddItemToObject(item, "creditManageStatus", credit_manage_status_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "creditManageStatus", OpenAPI_credit_management_status_ToString(sm_policy_update_context_data->credit_manage_status)) == NULL) { ogs_error("OpenAPI_sm_policy_update_context_data_convertToJSON() failed [credit_manage_status]"); goto end; } @@ -637,13 +614,7 @@ cJSON *OpenAPI_sm_policy_update_context_data_convertToJSON(OpenAPI_sm_policy_upd } if (sm_policy_update_context_data->ma_pdu_ind) { - cJSON *ma_pdu_ind_local_JSON = OpenAPI_ma_pdu_indication_convertToJSON(sm_policy_update_context_data->ma_pdu_ind); - if (ma_pdu_ind_local_JSON == NULL) { - ogs_error("OpenAPI_sm_policy_update_context_data_convertToJSON() failed [ma_pdu_ind]"); - goto end; - } - cJSON_AddItemToObject(item, "maPduInd", ma_pdu_ind_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "maPduInd", OpenAPI_ma_pdu_indication_ToString(sm_policy_update_context_data->ma_pdu_ind)) == NULL) { ogs_error("OpenAPI_sm_policy_update_context_data_convertToJSON() failed [ma_pdu_ind]"); goto end; } @@ -748,13 +719,12 @@ OpenAPI_sm_policy_update_context_data_t *OpenAPI_sm_policy_update_context_data_p rep_policy_ctrl_req_triggersList = OpenAPI_list_create(); cJSON_ArrayForEach(rep_policy_ctrl_req_triggers_local_nonprimitive, rep_policy_ctrl_req_triggers ) { - if (!cJSON_IsObject(rep_policy_ctrl_req_triggers_local_nonprimitive)) { + if (!cJSON_IsString(rep_policy_ctrl_req_triggers_local_nonprimitive)) { ogs_error("OpenAPI_sm_policy_update_context_data_parseFromJSON() failed [rep_policy_ctrl_req_triggers]"); goto end; } - OpenAPI_policy_control_request_trigger_t *rep_policy_ctrl_req_triggersItem = OpenAPI_policy_control_request_trigger_parseFromJSON(rep_policy_ctrl_req_triggers_local_nonprimitive); - OpenAPI_list_add(rep_policy_ctrl_req_triggersList, rep_policy_ctrl_req_triggersItem); + OpenAPI_list_add(rep_policy_ctrl_req_triggersList, (void *)OpenAPI_policy_control_request_trigger_FromString(rep_policy_ctrl_req_triggers_local_nonprimitive->valuestring)); } } @@ -1150,16 +1120,24 @@ OpenAPI_sm_policy_update_context_data_t *OpenAPI_sm_policy_update_context_data_p cJSON *qos_flow_usage = cJSON_GetObjectItemCaseSensitive(sm_policy_update_context_dataJSON, "qosFlowUsage"); - OpenAPI_qos_flow_usage_t *qos_flow_usage_local_nonprim = NULL; + OpenAPI_qos_flow_usage_e qos_flow_usageVariable; if (qos_flow_usage) { - qos_flow_usage_local_nonprim = OpenAPI_qos_flow_usage_parseFromJSON(qos_flow_usage); + if (!cJSON_IsString(qos_flow_usage)) { + ogs_error("OpenAPI_sm_policy_update_context_data_parseFromJSON() failed [qos_flow_usage]"); + goto end; + } + qos_flow_usageVariable = OpenAPI_qos_flow_usage_FromString(qos_flow_usage->valuestring); } cJSON *credit_manage_status = cJSON_GetObjectItemCaseSensitive(sm_policy_update_context_dataJSON, "creditManageStatus"); - OpenAPI_credit_management_status_t *credit_manage_status_local_nonprim = NULL; + OpenAPI_credit_management_status_e credit_manage_statusVariable; if (credit_manage_status) { - credit_manage_status_local_nonprim = OpenAPI_credit_management_status_parseFromJSON(credit_manage_status); + if (!cJSON_IsString(credit_manage_status)) { + ogs_error("OpenAPI_sm_policy_update_context_data_parseFromJSON() failed [credit_manage_status]"); + goto end; + } + credit_manage_statusVariable = OpenAPI_credit_management_status_FromString(credit_manage_status->valuestring); } cJSON *serv_nf_id = cJSON_GetObjectItemCaseSensitive(sm_policy_update_context_dataJSON, "servNfId"); @@ -1178,9 +1156,13 @@ OpenAPI_sm_policy_update_context_data_t *OpenAPI_sm_policy_update_context_data_p cJSON *ma_pdu_ind = cJSON_GetObjectItemCaseSensitive(sm_policy_update_context_dataJSON, "maPduInd"); - OpenAPI_ma_pdu_indication_t *ma_pdu_ind_local_nonprim = NULL; + OpenAPI_ma_pdu_indication_e ma_pdu_indVariable; if (ma_pdu_ind) { - ma_pdu_ind_local_nonprim = OpenAPI_ma_pdu_indication_parseFromJSON(ma_pdu_ind); + if (!cJSON_IsString(ma_pdu_ind)) { + ogs_error("OpenAPI_sm_policy_update_context_data_parseFromJSON() failed [ma_pdu_ind]"); + goto end; + } + ma_pdu_indVariable = OpenAPI_ma_pdu_indication_FromString(ma_pdu_ind->valuestring); } cJSON *atsss_capab = cJSON_GetObjectItemCaseSensitive(sm_policy_update_context_dataJSON, "atsssCapab"); @@ -1284,11 +1266,11 @@ OpenAPI_sm_policy_update_context_data_t *OpenAPI_sm_policy_update_context_data_p rep_pra_infos ? rep_pra_infosList : NULL, ue_init_res_req ? ue_init_res_req_local_nonprim : NULL, ref_qos_indication ? ref_qos_indication->valueint : 0, - qos_flow_usage ? qos_flow_usage_local_nonprim : NULL, - credit_manage_status ? credit_manage_status_local_nonprim : NULL, + qos_flow_usage ? qos_flow_usageVariable : 0, + credit_manage_status ? credit_manage_statusVariable : 0, serv_nf_id ? serv_nf_id_local_nonprim : NULL, trace_req ? trace_req_local_nonprim : NULL, - ma_pdu_ind ? ma_pdu_ind_local_nonprim : NULL, + ma_pdu_ind ? ma_pdu_indVariable : 0, atsss_capab ? atsss_capab_local_nonprim : NULL, tsn_bridge_info ? tsn_bridge_info_local_nonprim : NULL, tsn_port_man_cont_dstt ? tsn_port_man_cont_dstt_local_nonprim : NULL, diff --git a/lib/sbi/openapi/model/sm_policy_update_context_data.h b/lib/sbi/openapi/model/sm_policy_update_context_data.h index 483fc346e..1a17b7007 100644 --- a/lib/sbi/openapi/model/sm_policy_update_context_data.h +++ b/lib/sbi/openapi/model/sm_policy_update_context_data.h @@ -78,11 +78,11 @@ typedef struct OpenAPI_sm_policy_update_context_data_s { OpenAPI_list_t* rep_pra_infos; struct OpenAPI_ue_initiated_resource_request_s *ue_init_res_req; int ref_qos_indication; - struct OpenAPI_qos_flow_usage_s *qos_flow_usage; - struct OpenAPI_credit_management_status_s *credit_manage_status; + OpenAPI_qos_flow_usage_e qos_flow_usage; + OpenAPI_credit_management_status_e credit_manage_status; struct OpenAPI_serving_nf_identity_s *serv_nf_id; struct OpenAPI_trace_data_s *trace_req; - struct OpenAPI_ma_pdu_indication_s *ma_pdu_ind; + OpenAPI_ma_pdu_indication_e ma_pdu_ind; struct OpenAPI_atsss_capability_s *atsss_capab; struct OpenAPI_tsn_bridge_info_s *tsn_bridge_info; struct OpenAPI_port_management_container_s *tsn_port_man_cont_dstt; @@ -124,11 +124,11 @@ OpenAPI_sm_policy_update_context_data_t *OpenAPI_sm_policy_update_context_data_c OpenAPI_list_t* rep_pra_infos, OpenAPI_ue_initiated_resource_request_t *ue_init_res_req, int ref_qos_indication, - OpenAPI_qos_flow_usage_t *qos_flow_usage, - OpenAPI_credit_management_status_t *credit_manage_status, + OpenAPI_qos_flow_usage_e qos_flow_usage, + OpenAPI_credit_management_status_e credit_manage_status, OpenAPI_serving_nf_identity_t *serv_nf_id, OpenAPI_trace_data_t *trace_req, - OpenAPI_ma_pdu_indication_t *ma_pdu_ind, + OpenAPI_ma_pdu_indication_e ma_pdu_ind, OpenAPI_atsss_capability_t *atsss_capab, OpenAPI_tsn_bridge_info_t *tsn_bridge_info, OpenAPI_port_management_container_t *tsn_port_man_cont_dstt, diff --git a/lib/sbi/openapi/model/steer_mode_value.c b/lib/sbi/openapi/model/steer_mode_value.c index 3bf63805b..b3d946fa5 100644 --- a/lib/sbi/openapi/model/steer_mode_value.c +++ b/lib/sbi/openapi/model/steer_mode_value.c @@ -4,82 +4,27 @@ #include #include "steer_mode_value.h" -OpenAPI_steer_mode_value_t *OpenAPI_steer_mode_value_create( - ) +char* OpenAPI_steer_mode_value_ToString(OpenAPI_steer_mode_value_e steer_mode_value) { - OpenAPI_steer_mode_value_t *steer_mode_value_local_var = OpenAPI_malloc(sizeof(OpenAPI_steer_mode_value_t)); - if (!steer_mode_value_local_var) { - return NULL; - } - - return steer_mode_value_local_var; + const char *steer_mode_valueArray[] = { "NULL", "ACTIVE_STANDBY", "LOAD_BALANCING", "SMALLEST_DELAY", "PRIORITY_BASED" }; + size_t sizeofArray = sizeof(steer_mode_valueArray) / sizeof(steer_mode_valueArray[0]); + if (steer_mode_value < sizeofArray) + return (char *)steer_mode_valueArray[steer_mode_value]; + else + return (char *)"Unknown"; } -void OpenAPI_steer_mode_value_free(OpenAPI_steer_mode_value_t *steer_mode_value) +OpenAPI_steer_mode_value_e OpenAPI_steer_mode_value_FromString(char* steer_mode_value) { - if (NULL == steer_mode_value) { - return; + int stringToReturn = 0; + const char *steer_mode_valueArray[] = { "NULL", "ACTIVE_STANDBY", "LOAD_BALANCING", "SMALLEST_DELAY", "PRIORITY_BASED" }; + size_t sizeofArray = sizeof(steer_mode_valueArray) / sizeof(steer_mode_valueArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(steer_mode_value, steer_mode_valueArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(steer_mode_value); -} - -cJSON *OpenAPI_steer_mode_value_convertToJSON(OpenAPI_steer_mode_value_t *steer_mode_value) -{ - cJSON *item = NULL; - - if (steer_mode_value == NULL) { - ogs_error("OpenAPI_steer_mode_value_convertToJSON() failed [SteerModeValue]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_steer_mode_value_t *OpenAPI_steer_mode_value_parseFromJSON(cJSON *steer_mode_valueJSON) -{ - OpenAPI_steer_mode_value_t *steer_mode_value_local_var = NULL; - steer_mode_value_local_var = OpenAPI_steer_mode_value_create ( - ); - - return steer_mode_value_local_var; -end: - return NULL; -} - -OpenAPI_steer_mode_value_t *OpenAPI_steer_mode_value_copy(OpenAPI_steer_mode_value_t *dst, OpenAPI_steer_mode_value_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_steer_mode_value_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_steer_mode_value_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_steer_mode_value_free(dst); - dst = OpenAPI_steer_mode_value_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/steer_mode_value.h b/lib/sbi/openapi/model/steer_mode_value.h index 0aaa5ca75..c19fa56aa 100644 --- a/lib/sbi/openapi/model/steer_mode_value.h +++ b/lib/sbi/openapi/model/steer_mode_value.h @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_steer_mode_value_s OpenAPI_steer_mode_value_t; -typedef struct OpenAPI_steer_mode_value_s { -} OpenAPI_steer_mode_value_t; +typedef enum { OpenAPI_steer_mode_value_NULL = 0, OpenAPI_steer_mode_value_ACTIVE_STANDBY, OpenAPI_steer_mode_value_LOAD_BALANCING, OpenAPI_steer_mode_value_SMALLEST_DELAY, OpenAPI_steer_mode_value_PRIORITY_BASED } OpenAPI_steer_mode_value_e; -OpenAPI_steer_mode_value_t *OpenAPI_steer_mode_value_create( - ); -void OpenAPI_steer_mode_value_free(OpenAPI_steer_mode_value_t *steer_mode_value); -OpenAPI_steer_mode_value_t *OpenAPI_steer_mode_value_parseFromJSON(cJSON *steer_mode_valueJSON); -cJSON *OpenAPI_steer_mode_value_convertToJSON(OpenAPI_steer_mode_value_t *steer_mode_value); -OpenAPI_steer_mode_value_t *OpenAPI_steer_mode_value_copy(OpenAPI_steer_mode_value_t *dst, OpenAPI_steer_mode_value_t *src); +char* OpenAPI_steer_mode_value_ToString(OpenAPI_steer_mode_value_e steer_mode_value); + +OpenAPI_steer_mode_value_e OpenAPI_steer_mode_value_FromString(char* steer_mode_value); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/steering_functionality.c b/lib/sbi/openapi/model/steering_functionality.c index d1445fb32..e16066f19 100644 --- a/lib/sbi/openapi/model/steering_functionality.c +++ b/lib/sbi/openapi/model/steering_functionality.c @@ -4,82 +4,27 @@ #include #include "steering_functionality.h" -OpenAPI_steering_functionality_t *OpenAPI_steering_functionality_create( - ) +char* OpenAPI_steering_functionality_ToString(OpenAPI_steering_functionality_e steering_functionality) { - OpenAPI_steering_functionality_t *steering_functionality_local_var = OpenAPI_malloc(sizeof(OpenAPI_steering_functionality_t)); - if (!steering_functionality_local_var) { - return NULL; - } - - return steering_functionality_local_var; + const char *steering_functionalityArray[] = { "NULL", "MPTCP", "ATSSS_LL" }; + size_t sizeofArray = sizeof(steering_functionalityArray) / sizeof(steering_functionalityArray[0]); + if (steering_functionality < sizeofArray) + return (char *)steering_functionalityArray[steering_functionality]; + else + return (char *)"Unknown"; } -void OpenAPI_steering_functionality_free(OpenAPI_steering_functionality_t *steering_functionality) +OpenAPI_steering_functionality_e OpenAPI_steering_functionality_FromString(char* steering_functionality) { - if (NULL == steering_functionality) { - return; + int stringToReturn = 0; + const char *steering_functionalityArray[] = { "NULL", "MPTCP", "ATSSS_LL" }; + size_t sizeofArray = sizeof(steering_functionalityArray) / sizeof(steering_functionalityArray[0]); + while (stringToReturn < sizeofArray) { + if (strcmp(steering_functionality, steering_functionalityArray[stringToReturn]) == 0) { + return stringToReturn; + } + stringToReturn++; } - OpenAPI_lnode_t *node; - ogs_free(steering_functionality); -} - -cJSON *OpenAPI_steering_functionality_convertToJSON(OpenAPI_steering_functionality_t *steering_functionality) -{ - cJSON *item = NULL; - - if (steering_functionality == NULL) { - ogs_error("OpenAPI_steering_functionality_convertToJSON() failed [SteeringFunctionality]"); - return NULL; - } - - item = cJSON_CreateObject(); -end: - return item; -} - -OpenAPI_steering_functionality_t *OpenAPI_steering_functionality_parseFromJSON(cJSON *steering_functionalityJSON) -{ - OpenAPI_steering_functionality_t *steering_functionality_local_var = NULL; - steering_functionality_local_var = OpenAPI_steering_functionality_create ( - ); - - return steering_functionality_local_var; -end: - return NULL; -} - -OpenAPI_steering_functionality_t *OpenAPI_steering_functionality_copy(OpenAPI_steering_functionality_t *dst, OpenAPI_steering_functionality_t *src) -{ - cJSON *item = NULL; - char *content = NULL; - - ogs_assert(src); - item = OpenAPI_steering_functionality_convertToJSON(src); - if (!item) { - ogs_error("OpenAPI_steering_functionality_convertToJSON() failed"); - return NULL; - } - - content = cJSON_Print(item); - cJSON_Delete(item); - - if (!content) { - ogs_error("cJSON_Print() failed"); - return NULL; - } - - item = cJSON_Parse(content); - ogs_free(content); - if (!item) { - ogs_error("cJSON_Parse() failed"); - return NULL; - } - - OpenAPI_steering_functionality_free(dst); - dst = OpenAPI_steering_functionality_parseFromJSON(item); - cJSON_Delete(item); - - return dst; + return 0; } diff --git a/lib/sbi/openapi/model/steering_functionality.h b/lib/sbi/openapi/model/steering_functionality.h index 91bd4fd33..7c6816256 100644 --- a/lib/sbi/openapi/model/steering_functionality.h +++ b/lib/sbi/openapi/model/steering_functionality.h @@ -1,7 +1,7 @@ /* * steering_functionality.h * - * Possible values are - MPTCP: Indicates that PCF authorizes the MPTCP functionality to support traffic steering, switching and splitting. - ATSSS_LL: Indicates that PCF authorizes the ATSSS-LL functionality to support traffic steering, switching and splitting. + * */ #ifndef _OpenAPI_steering_functionality_H_ @@ -17,16 +17,11 @@ extern "C" { #endif -typedef struct OpenAPI_steering_functionality_s OpenAPI_steering_functionality_t; -typedef struct OpenAPI_steering_functionality_s { -} OpenAPI_steering_functionality_t; +typedef enum { OpenAPI_steering_functionality_NULL = 0, OpenAPI_steering_functionality_MPTCP, OpenAPI_steering_functionality_ATSSS_LL } OpenAPI_steering_functionality_e; -OpenAPI_steering_functionality_t *OpenAPI_steering_functionality_create( - ); -void OpenAPI_steering_functionality_free(OpenAPI_steering_functionality_t *steering_functionality); -OpenAPI_steering_functionality_t *OpenAPI_steering_functionality_parseFromJSON(cJSON *steering_functionalityJSON); -cJSON *OpenAPI_steering_functionality_convertToJSON(OpenAPI_steering_functionality_t *steering_functionality); -OpenAPI_steering_functionality_t *OpenAPI_steering_functionality_copy(OpenAPI_steering_functionality_t *dst, OpenAPI_steering_functionality_t *src); +char* OpenAPI_steering_functionality_ToString(OpenAPI_steering_functionality_e steering_functionality); + +OpenAPI_steering_functionality_e OpenAPI_steering_functionality_FromString(char* steering_functionality); #ifdef __cplusplus } diff --git a/lib/sbi/openapi/model/steering_mode.c b/lib/sbi/openapi/model/steering_mode.c index 5762a5eda..6e034c951 100644 --- a/lib/sbi/openapi/model/steering_mode.c +++ b/lib/sbi/openapi/model/steering_mode.c @@ -5,7 +5,7 @@ #include "steering_mode.h" OpenAPI_steering_mode_t *OpenAPI_steering_mode_create( - OpenAPI_steer_mode_value_t *steer_mode_value, + OpenAPI_steer_mode_value_e steer_mode_value, OpenAPI_access_type_e active, OpenAPI_access_type_e standby, int _3g_load, @@ -31,7 +31,6 @@ void OpenAPI_steering_mode_free(OpenAPI_steering_mode_t *steering_mode) return; } OpenAPI_lnode_t *node; - OpenAPI_steer_mode_value_free(steering_mode->steer_mode_value); ogs_free(steering_mode); } @@ -49,13 +48,7 @@ cJSON *OpenAPI_steering_mode_convertToJSON(OpenAPI_steering_mode_t *steering_mod ogs_error("OpenAPI_steering_mode_convertToJSON() failed [steer_mode_value]"); goto end; } - cJSON *steer_mode_value_local_JSON = OpenAPI_steer_mode_value_convertToJSON(steering_mode->steer_mode_value); - if (steer_mode_value_local_JSON == NULL) { - ogs_error("OpenAPI_steering_mode_convertToJSON() failed [steer_mode_value]"); - goto end; - } - cJSON_AddItemToObject(item, "steerModeValue", steer_mode_value_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "steerModeValue", OpenAPI_steer_mode_value_ToString(steering_mode->steer_mode_value)) == NULL) { ogs_error("OpenAPI_steering_mode_convertToJSON() failed [steer_mode_value]"); goto end; } @@ -101,9 +94,13 @@ OpenAPI_steering_mode_t *OpenAPI_steering_mode_parseFromJSON(cJSON *steering_mod goto end; } - OpenAPI_steer_mode_value_t *steer_mode_value_local_nonprim = NULL; + OpenAPI_steer_mode_value_e steer_mode_valueVariable; - steer_mode_value_local_nonprim = OpenAPI_steer_mode_value_parseFromJSON(steer_mode_value); + if (!cJSON_IsString(steer_mode_value)) { + ogs_error("OpenAPI_steering_mode_parseFromJSON() failed [steer_mode_value]"); + goto end; + } + steer_mode_valueVariable = OpenAPI_steer_mode_value_FromString(steer_mode_value->valuestring); cJSON *active = cJSON_GetObjectItemCaseSensitive(steering_modeJSON, "active"); @@ -148,7 +145,7 @@ OpenAPI_steering_mode_t *OpenAPI_steering_mode_parseFromJSON(cJSON *steering_mod } steering_mode_local_var = OpenAPI_steering_mode_create ( - steer_mode_value_local_nonprim, + steer_mode_valueVariable, active ? activeVariable : 0, standby ? standbyVariable : 0, _3g_load ? _3g_load->valuedouble : 0, diff --git a/lib/sbi/openapi/model/steering_mode.h b/lib/sbi/openapi/model/steering_mode.h index f48e93737..98ffe33c4 100644 --- a/lib/sbi/openapi/model/steering_mode.h +++ b/lib/sbi/openapi/model/steering_mode.h @@ -21,7 +21,7 @@ extern "C" { typedef struct OpenAPI_steering_mode_s OpenAPI_steering_mode_t; typedef struct OpenAPI_steering_mode_s { - struct OpenAPI_steer_mode_value_s *steer_mode_value; + OpenAPI_steer_mode_value_e steer_mode_value; OpenAPI_access_type_e active; OpenAPI_access_type_e standby; int _3g_load; @@ -29,7 +29,7 @@ typedef struct OpenAPI_steering_mode_s { } OpenAPI_steering_mode_t; OpenAPI_steering_mode_t *OpenAPI_steering_mode_create( - OpenAPI_steer_mode_value_t *steer_mode_value, + OpenAPI_steer_mode_value_e steer_mode_value, OpenAPI_access_type_e active, OpenAPI_access_type_e standby, int _3g_load, diff --git a/lib/sbi/openapi/model/termination_notification.c b/lib/sbi/openapi/model/termination_notification.c index e207ecee6..bfa0e1165 100644 --- a/lib/sbi/openapi/model/termination_notification.c +++ b/lib/sbi/openapi/model/termination_notification.c @@ -6,7 +6,7 @@ OpenAPI_termination_notification_t *OpenAPI_termination_notification_create( char *resource_uri, - OpenAPI_sm_policy_association_release_cause_t *cause + OpenAPI_sm_policy_association_release_cause_e cause ) { OpenAPI_termination_notification_t *termination_notification_local_var = OpenAPI_malloc(sizeof(OpenAPI_termination_notification_t)); @@ -26,7 +26,6 @@ void OpenAPI_termination_notification_free(OpenAPI_termination_notification_t *t } OpenAPI_lnode_t *node; ogs_free(termination_notification->resource_uri); - OpenAPI_sm_policy_association_release_cause_free(termination_notification->cause); ogs_free(termination_notification); } @@ -53,13 +52,7 @@ cJSON *OpenAPI_termination_notification_convertToJSON(OpenAPI_termination_notifi ogs_error("OpenAPI_termination_notification_convertToJSON() failed [cause]"); goto end; } - cJSON *cause_local_JSON = OpenAPI_sm_policy_association_release_cause_convertToJSON(termination_notification->cause); - if (cause_local_JSON == NULL) { - ogs_error("OpenAPI_termination_notification_convertToJSON() failed [cause]"); - goto end; - } - cJSON_AddItemToObject(item, "cause", cause_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "cause", OpenAPI_sm_policy_association_release_cause_ToString(termination_notification->cause)) == NULL) { ogs_error("OpenAPI_termination_notification_convertToJSON() failed [cause]"); goto end; } @@ -89,13 +82,17 @@ OpenAPI_termination_notification_t *OpenAPI_termination_notification_parseFromJS goto end; } - OpenAPI_sm_policy_association_release_cause_t *cause_local_nonprim = NULL; + OpenAPI_sm_policy_association_release_cause_e causeVariable; - cause_local_nonprim = OpenAPI_sm_policy_association_release_cause_parseFromJSON(cause); + if (!cJSON_IsString(cause)) { + ogs_error("OpenAPI_termination_notification_parseFromJSON() failed [cause]"); + goto end; + } + causeVariable = OpenAPI_sm_policy_association_release_cause_FromString(cause->valuestring); termination_notification_local_var = OpenAPI_termination_notification_create ( ogs_strdup(resource_uri->valuestring), - cause_local_nonprim + causeVariable ); return termination_notification_local_var; diff --git a/lib/sbi/openapi/model/termination_notification.h b/lib/sbi/openapi/model/termination_notification.h index 1e3b63cdf..08d118d84 100644 --- a/lib/sbi/openapi/model/termination_notification.h +++ b/lib/sbi/openapi/model/termination_notification.h @@ -21,12 +21,12 @@ extern "C" { typedef struct OpenAPI_termination_notification_s OpenAPI_termination_notification_t; typedef struct OpenAPI_termination_notification_s { char *resource_uri; - struct OpenAPI_sm_policy_association_release_cause_s *cause; + OpenAPI_sm_policy_association_release_cause_e cause; } OpenAPI_termination_notification_t; OpenAPI_termination_notification_t *OpenAPI_termination_notification_create( char *resource_uri, - OpenAPI_sm_policy_association_release_cause_t *cause + OpenAPI_sm_policy_association_release_cause_e cause ); void OpenAPI_termination_notification_free(OpenAPI_termination_notification_t *termination_notification); OpenAPI_termination_notification_t *OpenAPI_termination_notification_parseFromJSON(cJSON *termination_notificationJSON); diff --git a/lib/sbi/openapi/model/traffic_control_data.c b/lib/sbi/openapi/model/traffic_control_data.c index cbe43e87e..b78992783 100644 --- a/lib/sbi/openapi/model/traffic_control_data.c +++ b/lib/sbi/openapi/model/traffic_control_data.c @@ -15,7 +15,7 @@ OpenAPI_traffic_control_data_t *OpenAPI_traffic_control_data_create( OpenAPI_list_t *route_to_locs, int traff_corre_ind, OpenAPI_up_path_chg_event_t *up_path_chg_event, - OpenAPI_steering_functionality_t *steer_fun, + OpenAPI_steering_functionality_e steer_fun, OpenAPI_steering_mode_t *steer_mode_dl, OpenAPI_steering_mode_t *steer_mode_ul, OpenAPI_multicast_access_control_t *mul_acc_ctrl @@ -63,7 +63,6 @@ void OpenAPI_traffic_control_data_free(OpenAPI_traffic_control_data_t *traffic_c } OpenAPI_list_free(traffic_control_data->route_to_locs); OpenAPI_up_path_chg_event_free(traffic_control_data->up_path_chg_event); - OpenAPI_steering_functionality_free(traffic_control_data->steer_fun); OpenAPI_steering_mode_free(traffic_control_data->steer_mode_dl); OpenAPI_steering_mode_free(traffic_control_data->steer_mode_ul); OpenAPI_multicast_access_control_free(traffic_control_data->mul_acc_ctrl); @@ -197,13 +196,7 @@ cJSON *OpenAPI_traffic_control_data_convertToJSON(OpenAPI_traffic_control_data_t } if (traffic_control_data->steer_fun) { - cJSON *steer_fun_local_JSON = OpenAPI_steering_functionality_convertToJSON(traffic_control_data->steer_fun); - if (steer_fun_local_JSON == NULL) { - ogs_error("OpenAPI_traffic_control_data_convertToJSON() failed [steer_fun]"); - goto end; - } - cJSON_AddItemToObject(item, "steerFun", steer_fun_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "steerFun", OpenAPI_steering_functionality_ToString(traffic_control_data->steer_fun)) == NULL) { ogs_error("OpenAPI_traffic_control_data_convertToJSON() failed [steer_fun]"); goto end; } @@ -372,9 +365,13 @@ OpenAPI_traffic_control_data_t *OpenAPI_traffic_control_data_parseFromJSON(cJSON cJSON *steer_fun = cJSON_GetObjectItemCaseSensitive(traffic_control_dataJSON, "steerFun"); - OpenAPI_steering_functionality_t *steer_fun_local_nonprim = NULL; + OpenAPI_steering_functionality_e steer_funVariable; if (steer_fun) { - steer_fun_local_nonprim = OpenAPI_steering_functionality_parseFromJSON(steer_fun); + if (!cJSON_IsString(steer_fun)) { + ogs_error("OpenAPI_traffic_control_data_parseFromJSON() failed [steer_fun]"); + goto end; + } + steer_funVariable = OpenAPI_steering_functionality_FromString(steer_fun->valuestring); } cJSON *steer_mode_dl = cJSON_GetObjectItemCaseSensitive(traffic_control_dataJSON, "steerModeDl"); @@ -409,7 +406,7 @@ OpenAPI_traffic_control_data_t *OpenAPI_traffic_control_data_parseFromJSON(cJSON route_to_locs ? route_to_locsList : NULL, traff_corre_ind ? traff_corre_ind->valueint : 0, up_path_chg_event ? up_path_chg_event_local_nonprim : NULL, - steer_fun ? steer_fun_local_nonprim : NULL, + steer_fun ? steer_funVariable : 0, steer_mode_dl ? steer_mode_dl_local_nonprim : NULL, steer_mode_ul ? steer_mode_ul_local_nonprim : NULL, mul_acc_ctrl ? mul_acc_ctrl_local_nonprim : NULL diff --git a/lib/sbi/openapi/model/traffic_control_data.h b/lib/sbi/openapi/model/traffic_control_data.h index 0c8132bee..499be1629 100644 --- a/lib/sbi/openapi/model/traffic_control_data.h +++ b/lib/sbi/openapi/model/traffic_control_data.h @@ -36,7 +36,7 @@ typedef struct OpenAPI_traffic_control_data_s { OpenAPI_list_t *route_to_locs; int traff_corre_ind; struct OpenAPI_up_path_chg_event_s *up_path_chg_event; - struct OpenAPI_steering_functionality_s *steer_fun; + OpenAPI_steering_functionality_e steer_fun; struct OpenAPI_steering_mode_s *steer_mode_dl; struct OpenAPI_steering_mode_s *steer_mode_ul; struct OpenAPI_multicast_access_control_s *mul_acc_ctrl; @@ -53,7 +53,7 @@ OpenAPI_traffic_control_data_t *OpenAPI_traffic_control_data_create( OpenAPI_list_t *route_to_locs, int traff_corre_ind, OpenAPI_up_path_chg_event_t *up_path_chg_event, - OpenAPI_steering_functionality_t *steer_fun, + OpenAPI_steering_functionality_e steer_fun, OpenAPI_steering_mode_t *steer_mode_dl, OpenAPI_steering_mode_t *steer_mode_ul, OpenAPI_multicast_access_control_t *mul_acc_ctrl diff --git a/lib/sbi/openapi/model/ue_initiated_resource_request.c b/lib/sbi/openapi/model/ue_initiated_resource_request.c index 7c4d6faf8..5aa9a7ff0 100644 --- a/lib/sbi/openapi/model/ue_initiated_resource_request.c +++ b/lib/sbi/openapi/model/ue_initiated_resource_request.c @@ -6,7 +6,7 @@ OpenAPI_ue_initiated_resource_request_t *OpenAPI_ue_initiated_resource_request_create( char *pcc_rule_id, - OpenAPI_rule_operation_t *rule_op, + OpenAPI_rule_operation_e rule_op, int precedence, OpenAPI_list_t *pack_filt_info, OpenAPI_requested_qos_t *req_qos @@ -32,7 +32,6 @@ void OpenAPI_ue_initiated_resource_request_free(OpenAPI_ue_initiated_resource_re } OpenAPI_lnode_t *node; ogs_free(ue_initiated_resource_request->pcc_rule_id); - OpenAPI_rule_operation_free(ue_initiated_resource_request->rule_op); OpenAPI_list_for_each(ue_initiated_resource_request->pack_filt_info, node) { OpenAPI_packet_filter_info_free(node->data); } @@ -62,13 +61,7 @@ cJSON *OpenAPI_ue_initiated_resource_request_convertToJSON(OpenAPI_ue_initiated_ ogs_error("OpenAPI_ue_initiated_resource_request_convertToJSON() failed [rule_op]"); goto end; } - cJSON *rule_op_local_JSON = OpenAPI_rule_operation_convertToJSON(ue_initiated_resource_request->rule_op); - if (rule_op_local_JSON == NULL) { - ogs_error("OpenAPI_ue_initiated_resource_request_convertToJSON() failed [rule_op]"); - goto end; - } - cJSON_AddItemToObject(item, "ruleOp", rule_op_local_JSON); - if (item->child == NULL) { + if (cJSON_AddStringToObject(item, "ruleOp", OpenAPI_rule_operation_ToString(ue_initiated_resource_request->rule_op)) == NULL) { ogs_error("OpenAPI_ue_initiated_resource_request_convertToJSON() failed [rule_op]"); goto end; } @@ -137,9 +130,13 @@ OpenAPI_ue_initiated_resource_request_t *OpenAPI_ue_initiated_resource_request_p goto end; } - OpenAPI_rule_operation_t *rule_op_local_nonprim = NULL; + OpenAPI_rule_operation_e rule_opVariable; - rule_op_local_nonprim = OpenAPI_rule_operation_parseFromJSON(rule_op); + if (!cJSON_IsString(rule_op)) { + ogs_error("OpenAPI_ue_initiated_resource_request_parseFromJSON() failed [rule_op]"); + goto end; + } + rule_opVariable = OpenAPI_rule_operation_FromString(rule_op->valuestring); cJSON *precedence = cJSON_GetObjectItemCaseSensitive(ue_initiated_resource_requestJSON, "precedence"); @@ -185,7 +182,7 @@ OpenAPI_ue_initiated_resource_request_t *OpenAPI_ue_initiated_resource_request_p ue_initiated_resource_request_local_var = OpenAPI_ue_initiated_resource_request_create ( pcc_rule_id ? ogs_strdup(pcc_rule_id->valuestring) : NULL, - rule_op_local_nonprim, + rule_opVariable, precedence ? precedence->valuedouble : 0, pack_filt_infoList, req_qos ? req_qos_local_nonprim : NULL diff --git a/lib/sbi/openapi/model/ue_initiated_resource_request.h b/lib/sbi/openapi/model/ue_initiated_resource_request.h index 5f1985afe..28a65cda9 100644 --- a/lib/sbi/openapi/model/ue_initiated_resource_request.h +++ b/lib/sbi/openapi/model/ue_initiated_resource_request.h @@ -23,7 +23,7 @@ extern "C" { typedef struct OpenAPI_ue_initiated_resource_request_s OpenAPI_ue_initiated_resource_request_t; typedef struct OpenAPI_ue_initiated_resource_request_s { char *pcc_rule_id; - struct OpenAPI_rule_operation_s *rule_op; + OpenAPI_rule_operation_e rule_op; int precedence; OpenAPI_list_t *pack_filt_info; struct OpenAPI_requested_qos_s *req_qos; @@ -31,7 +31,7 @@ typedef struct OpenAPI_ue_initiated_resource_request_s { OpenAPI_ue_initiated_resource_request_t *OpenAPI_ue_initiated_resource_request_create( char *pcc_rule_id, - OpenAPI_rule_operation_t *rule_op, + OpenAPI_rule_operation_e rule_op, int precedence, OpenAPI_list_t *pack_filt_info, OpenAPI_requested_qos_t *req_qos diff --git a/lib/sbi/support/modified/TS29507_Npcf_AMPolicyControl.yaml b/lib/sbi/support/modified/TS29507_Npcf_AMPolicyControl.yaml index 86229fa96..fcea8075f 100644 --- a/lib/sbi/support/modified/TS29507_Npcf_AMPolicyControl.yaml +++ b/lib/sbi/support/modified/TS29507_Npcf_AMPolicyControl.yaml @@ -300,7 +300,7 @@ components: required: - suppFeat PolicyAssociationRequest: - description: Information which the NF service consumer provides when requesting the creation of a policy association. The serviveName property corresponds to the serviceName in the main body of the specification. + description: Information which the NF service consumer provides when requesting the creation of a policy association. The serviceName property corresponds to the serviceName in the main body of the specification. type: object properties: notificationUri: @@ -378,7 +378,7 @@ components: minItems: 1 guami: $ref: 'TS29571_CommonData.yaml#/components/schemas/Guami' - serviveName: + serviceName: $ref: 'TS29510_Nnrf_NFManagement.yaml#/components/schemas/ServiceName' traceReq: $ref: 'TS29571_CommonData.yaml#/components/schemas/TraceData' diff --git a/lib/sbi/support/modified/TS29512_Npcf_SMPolicyControl.yaml b/lib/sbi/support/modified/TS29512_Npcf_SMPolicyControl.yaml index cd0127e50..652f0a3aa 100644 --- a/lib/sbi/support/modified/TS29512_Npcf_SMPolicyControl.yaml +++ b/lib/sbi/support/modified/TS29512_Npcf_SMPolicyControl.yaml @@ -1558,69 +1558,69 @@ components: type: string description: Defines a packet filter for an IP flow. Refer to subclause 5.4.2 of 3GPP TS 29.212 for encoding. FlowDirection: - anyOf: - - type: string +# anyOf: +# - type: string enum: - DOWNLINK - UPLINK - BIDIRECTIONAL - UNSPECIFIED - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - DOWNLINK: The corresponding filter applies for traffic to the UE. - - UPLINK: The corresponding filter applies for traffic from the UE. - - BIDIRECTIONAL: The corresponding filter applies for traffic both to and from the UE. - - UNSPECIFIED: The corresponding filter applies for traffic to the UE (downlink), but has no specific direction declared. The service data flow detection shall apply the filter for uplink traffic as if the filter was bidirectional. The PCF shall not use the value UNSPECIFIED in filters created by the network in NW-initiated procedures. The PCF shall only include the value UNSPECIFIED in filters in UE-initiated procedures if the same value is received from the SMF. + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - DOWNLINK: The corresponding filter applies for traffic to the UE. +# - UPLINK: The corresponding filter applies for traffic from the UE. +# - BIDIRECTIONAL: The corresponding filter applies for traffic both to and from the UE. +# - UNSPECIFIED: The corresponding filter applies for traffic to the UE (downlink), but has no specific direction declared. The service data flow detection shall apply the filter for uplink traffic as if the filter was bidirectional. The PCF shall not use the value UNSPECIFIED in filters created by the network in NW-initiated procedures. The PCF shall only include the value UNSPECIFIED in filters in UE-initiated procedures if the same value is received from the SMF. FlowDirectionRm: - anyOf: - - $ref: '#/components/schemas/FlowDirection' - - $ref: 'TS29571_CommonData.yaml#/components/schemas/NullValue' +# anyOf: + $ref: '#/components/schemas/FlowDirection' +# - $ref: 'TS29571_CommonData.yaml#/components/schemas/NullValue' ReportingLevel: - anyOf: - - type: string +# anyOf: +# - type: string enum: - SER_ID_LEVEL - RAT_GR_LEVEL - SPON_CON_LEVEL - - $ref: 'TS29571_CommonData.yaml#/components/schemas/NullValue' - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - SER_ID_LEVEL: Indicates that the usage shall be reported on service id and rating group combination level. - - RAT_GR_LEVEL: Indicates that the usage shall be reported on rating group level. - - SPON_CON_LEVEL: Indicates that the usage shall be reported on sponsor identity and rating group combination level. +# - $ref: 'TS29571_CommonData.yaml#/components/schemas/NullValue' + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - SER_ID_LEVEL: Indicates that the usage shall be reported on service id and rating group combination level. +# - RAT_GR_LEVEL: Indicates that the usage shall be reported on rating group level. +# - SPON_CON_LEVEL: Indicates that the usage shall be reported on sponsor identity and rating group combination level. MeteringMethod: - anyOf: - - type: string +# anyOf: +# - type: string enum: - DURATION - VOLUME - DURATION_VOLUME - EVENT - - $ref: 'TS29571_CommonData.yaml#/components/schemas/NullValue' - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - DURATION: Indicates that the duration of the service data flow traffic shall be metered. - - VOLUME: Indicates that volume of the service data flow traffic shall be metered. - - DURATION_VOLUME: Indicates that the duration and the volume of the service data flow traffic shall be metered. - - EVENT: Indicates that events of the service data flow traffic shall be metered. +# - $ref: 'TS29571_CommonData.yaml#/components/schemas/NullValue' + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - DURATION: Indicates that the duration of the service data flow traffic shall be metered. +# - VOLUME: Indicates that volume of the service data flow traffic shall be metered. +# - DURATION_VOLUME: Indicates that the duration and the volume of the service data flow traffic shall be metered. +# - EVENT: Indicates that events of the service data flow traffic shall be metered. PolicyControlRequestTrigger: - anyOf: - - type: string +# anyOf: +# - type: string enum: - PLMN_CH - RES_MO_RE @@ -1659,53 +1659,53 @@ components: - TSN_CONTAINER - 5G_RG_JOIN - 5G_RG_LEAVE - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - PLMN_CH: PLMN Change - - RES_MO_RE: A request for resource modification has been received by the SMF. The SMF always reports to the PCF. - - AC_TY_CH: Access Type Change - - UE_IP_CH: UE IP address change. The SMF always reports to the PCF. - - UE_MAC_CH: A new UE MAC address is detected or a used UE MAC address is inactive for a specific period - - AN_CH_COR: Access Network Charging Correlation Information - - US_RE: The PDU Session or the Monitoring key specific resources consumed by a UE either reached the threshold or needs to be reported for other reasons. - - APP_STA: The start of application traffic has been detected. - - APP_STO: The stop of application traffic has been detected. - - AN_INFO: Access Network Information report - - CM_SES_FAIL: Credit management session failure - - PS_DA_OFF: The SMF reports when the 3GPP PS Data Off status changes. The SMF always reports to the PCF. - - DEF_QOS_CH: Default QoS Change. The SMF always reports to the PCF. - - SE_AMBR_CH: Session AMBR Change. The SMF always reports to the PCF. - - QOS_NOTIF: The SMF notify the PCF when receiving notification from RAN that QoS targets of the QoS Flow cannot be guranteed or gurateed again. - - NO_CREDIT: Out of credit - - REALLO_OF_CREDIT: Reallocation of credit - - PRA_CH: Change of UE presence in Presence Reporting Area - - SAREA_CH: Location Change with respect to the Serving Area - - SCNN_CH: Location Change with respect to the Serving CN node - - RE_TIMEOUT: Indicates the SMF generated the request because there has been a PCC revalidation timeout - - RES_RELEASE: Indicate that the SMF can inform the PCF of the outcome of the release of resources for those rules that require so. - - SUCC_RES_ALLO: Indicates that the requested rule data is the successful resource allocation. - - RAT_TY_CH: RAT Type Change. - - REF_QOS_IND_CH: Reflective QoS indication Change - - NUM_OF_PACKET_FILTER: Indicates that the SMF shall report the number of supported packet filter for signalled QoS rules - - UE_STATUS_RESUME: Indicates that the UE’s status is resumed. - - UE_TZ_CH: UE Time Zone Change - - AUTH_PROF_CH: The DN-AAA authorization profile index has changed - - QOS_MONITORING: Indicate that the SMF notifies the PCF of the QoS Monitoring information. - - SCELL_CH: Location Change with respect to the Serving Cell. Only applicable to the interworking scenario as defined in Annex B. - - EPS_FALLBACK: EPS Fallback report is enabled in the SMF. - - MA_PDU: UE Indicates that the SMF notifies the PCF of the MA PDU session request - - TSN_ETHER_PORT: Manageable Ethernet port detected - - TSN_CONTAINER: Port management container detected. - - 5G_RG_JOIN: The 5G-RG has joined to an IP Multicast Group. - - 5G_RG_LEAVE: The 5G-RG has left an IP Multicast Group. + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - PLMN_CH: PLMN Change +# - RES_MO_RE: A request for resource modification has been received by the SMF. The SMF always reports to the PCF. +# - AC_TY_CH: Access Type Change +# - UE_IP_CH: UE IP address change. The SMF always reports to the PCF. +# - UE_MAC_CH: A new UE MAC address is detected or a used UE MAC address is inactive for a specific period +# - AN_CH_COR: Access Network Charging Correlation Information +# - US_RE: The PDU Session or the Monitoring key specific resources consumed by a UE either reached the threshold or needs to be reported for other reasons. +# - APP_STA: The start of application traffic has been detected. +# - APP_STO: The stop of application traffic has been detected. +# - AN_INFO: Access Network Information report +# - CM_SES_FAIL: Credit management session failure +# - PS_DA_OFF: The SMF reports when the 3GPP PS Data Off status changes. The SMF always reports to the PCF. +# - DEF_QOS_CH: Default QoS Change. The SMF always reports to the PCF. +# - SE_AMBR_CH: Session AMBR Change. The SMF always reports to the PCF. +# - QOS_NOTIF: The SMF notify the PCF when receiving notification from RAN that QoS targets of the QoS Flow cannot be guranteed or gurateed again. +# - NO_CREDIT: Out of credit +# - REALLO_OF_CREDIT: Reallocation of credit +# - PRA_CH: Change of UE presence in Presence Reporting Area +# - SAREA_CH: Location Change with respect to the Serving Area +# - SCNN_CH: Location Change with respect to the Serving CN node +# - RE_TIMEOUT: Indicates the SMF generated the request because there has been a PCC revalidation timeout +# - RES_RELEASE: Indicate that the SMF can inform the PCF of the outcome of the release of resources for those rules that require so. +# - SUCC_RES_ALLO: Indicates that the requested rule data is the successful resource allocation. +# - RAT_TY_CH: RAT Type Change. +# - REF_QOS_IND_CH: Reflective QoS indication Change +# - NUM_OF_PACKET_FILTER: Indicates that the SMF shall report the number of supported packet filter for signalled QoS rules +# - UE_STATUS_RESUME: Indicates that the UE’s status is resumed. +# - UE_TZ_CH: UE Time Zone Change +# - AUTH_PROF_CH: The DN-AAA authorization profile index has changed +# - QOS_MONITORING: Indicate that the SMF notifies the PCF of the QoS Monitoring information. +# - SCELL_CH: Location Change with respect to the Serving Cell. Only applicable to the interworking scenario as defined in Annex B. +# - EPS_FALLBACK: EPS Fallback report is enabled in the SMF. +# - MA_PDU: UE Indicates that the SMF notifies the PCF of the MA PDU session request +# - TSN_ETHER_PORT: Manageable Ethernet port detected +# - TSN_CONTAINER: Port management container detected. +# - 5G_RG_JOIN: The 5G-RG has joined to an IP Multicast Group. +# - 5G_RG_LEAVE: The 5G-RG has left an IP Multicast Group. RequestedRuleDataType: - anyOf: - - type: string +# anyOf: +# - type: string enum: - CH_ID - MS_TIME_ZONE @@ -1713,37 +1713,37 @@ components: - RES_RELEASE - SUCC_RES_ALLO - EPS_FALLBACK - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - CH_ID: Indicates that the requested rule data is the charging identifier. - - MS_TIME_ZONE: Indicates that the requested access network info type is the UE's timezone. - - USER_LOC_INFO: Indicates that the requested access network info type is the UE's location. - - RES_RELEASE: Indicates that the requested rule data is the result of the release of resource. - - SUCC_RES_ALLO: Indicates that the requested rule data is the successful resource allocation. - - EPS_FALLBACK: Indicates that the requested rule data is the report of QoS flow rejection due to EPS fallback. + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - CH_ID: Indicates that the requested rule data is the charging identifier. +# - MS_TIME_ZONE: Indicates that the requested access network info type is the UE's timezone. +# - USER_LOC_INFO: Indicates that the requested access network info type is the UE's location. +# - RES_RELEASE: Indicates that the requested rule data is the result of the release of resource. +# - SUCC_RES_ALLO: Indicates that the requested rule data is the successful resource allocation. +# - EPS_FALLBACK: Indicates that the requested rule data is the report of QoS flow rejection due to EPS fallback. RuleStatus: - anyOf: - - type: string +# anyOf: +# - type: string enum: - ACTIVE - INACTIVE - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - ACTIVE: Indicates that the PCC rule(s) are successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF), or the session rule(s) are successfully installed - - INACTIVE: Indicates that the PCC rule(s) are removed (for those provisioned from PCF) or inactive (for those pre-defined in SMF) or the session rule(s) are removed. + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - ACTIVE: Indicates that the PCC rule(s) are successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF), or the session rule(s) are successfully installed +# - INACTIVE: Indicates that the PCC rule(s) are removed (for those provisioned from PCF) or inactive (for those pre-defined in SMF) or the session rule(s) are removed. FailureCode: - anyOf: - - type: string +# anyOf: +# - type: string enum: - UNK_RULE_ID - RA_GR_ERR @@ -1766,169 +1766,169 @@ components: - CM_USER_UNK - CM_RAT_FAILED - UE_STA_SUSP - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - UNK_RULE_ID: Indicates that the pre-provisioned PCC rule could not be successfully activated because the PCC rule identifier is unknown to the SMF. - - RA_GR_ERR: Indicate that the PCC rule could not be successfully installed or enforced because the Rating Group specified within the Charging Data policy decision which the PCC rule refers to is unknown or, invalid. - - SER_ID_ERR: Indicate that the PCC rule could not be successfully installed or enforced because the Service Identifier specified within the Charging Data policy decision which the PCC rule refers to is invalid, unknown, or not applicable to the service being charged. - - NF_MAL: Indicate that the PCC rule could not be successfully installed (for those provisioned from the PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to SMF/UPF malfunction. - - RES_LIM: Indicate that the PCC rule could not be successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to a limitation of resources at the SMF/UPF. - - MAX_NR_QoS_FLOW: Indicate that the PCC rule could not be successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to the fact that the maximum number of QoS flows has been reached for the PDU session. - - MISS_FLOW_INFO: Indicate that the PCC rule could not be successfully installed or enforced because neither the "flowInfos" attribute nor the "appId" attribute is specified within the PccRule data structure by the PCF during the first install request of the PCC rule. - - RES_ALLO_FAIL: Indicate that the PCC rule could not be successfully installed or maintained since the QoS flow establishment/modification failed, or the QoS flow was released. - - UNSUCC_QOS_VAL: indicate that the QoS validation has failed or when Guaranteed Bandwidth > Max-Requested-Bandwidth. - - INCOR_FLOW_INFO: Indicate that the PCC rule could not be successfully installed or modified at the SMF because the provided flow information is not supported by the network (e.g. the provided IP address(es) or Ipv6 prefix(es) do not correspond to an IP version applicable for the PDU session). - - PS_TO_CS_HAN: Indicate that the PCC rule could not be maintained because of PS to CS handover. - - APP_ID_ERR: Indicate that the rule could not be successfully installed or enforced because the Application Identifier is invalid, unknown, or not applicable to the application required for detection. - - NO_QOS_FLOW_BOUND: Indicate that there is no QoS flow which the SMF can bind the PCC rule(s) to. - - FILTER_RES: Indicate that the Flow Information within the "flowInfos" attribute cannot be handled by the SMF because any of the restrictions defined in subclause 5.4.2 of 3GPP TS 29.212 was not met. - - MISS_REDI_SER_ADDR: Indicate that the PCC rule could not be successfully installed or enforced at the SMF because there is no valid Redirect Server Address within the Traffic Control Data policy decision which the PCC rule refers to provided by the PCF and no preconfigured redirection address for this PCC rule at the SMF. - - CM_END_USER_SER_DENIED: Indicate that the charging system denied the service request due to service restrictions (e.g. terminate rating group) or limitations related to the end-user, for example the end-user's account could not cover the requested service. - - CM_CREDIT_CON_NOT_APP: Indicate that the charging system determined that the service can be granted to the end user but no further credit control is needed for the service (e.g. service is free of charge or is treated for offline charging). - - CM_AUTH_REJ: Indicate that the charging system denied the service request in order to terminate the service for which credit is requested. - - CM_USER_UNK: Indicate that the specified end user could not be found in the charging system. - - CM_RAT_FAILED: Indicate that the charging system cannot rate the service request due to insufficient rating input, incorrect AVP combination or due to an attribute or an attribute value that is not recognized or supported in the rating. - - UE_STA_SUSP: Indicates that the UE is in suspend state. + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - UNK_RULE_ID: Indicates that the pre-provisioned PCC rule could not be successfully activated because the PCC rule identifier is unknown to the SMF. +# - RA_GR_ERR: Indicate that the PCC rule could not be successfully installed or enforced because the Rating Group specified within the Charging Data policy decision which the PCC rule refers to is unknown or, invalid. +# - SER_ID_ERR: Indicate that the PCC rule could not be successfully installed or enforced because the Service Identifier specified within the Charging Data policy decision which the PCC rule refers to is invalid, unknown, or not applicable to the service being charged. +# - NF_MAL: Indicate that the PCC rule could not be successfully installed (for those provisioned from the PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to SMF/UPF malfunction. +# - RES_LIM: Indicate that the PCC rule could not be successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to a limitation of resources at the SMF/UPF. +# - MAX_NR_QoS_FLOW: Indicate that the PCC rule could not be successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to the fact that the maximum number of QoS flows has been reached for the PDU session. +# - MISS_FLOW_INFO: Indicate that the PCC rule could not be successfully installed or enforced because neither the "flowInfos" attribute nor the "appId" attribute is specified within the PccRule data structure by the PCF during the first install request of the PCC rule. +# - RES_ALLO_FAIL: Indicate that the PCC rule could not be successfully installed or maintained since the QoS flow establishment/modification failed, or the QoS flow was released. +# - UNSUCC_QOS_VAL: indicate that the QoS validation has failed or when Guaranteed Bandwidth > Max-Requested-Bandwidth. +# - INCOR_FLOW_INFO: Indicate that the PCC rule could not be successfully installed or modified at the SMF because the provided flow information is not supported by the network (e.g. the provided IP address(es) or Ipv6 prefix(es) do not correspond to an IP version applicable for the PDU session). +# - PS_TO_CS_HAN: Indicate that the PCC rule could not be maintained because of PS to CS handover. +# - APP_ID_ERR: Indicate that the rule could not be successfully installed or enforced because the Application Identifier is invalid, unknown, or not applicable to the application required for detection. +# - NO_QOS_FLOW_BOUND: Indicate that there is no QoS flow which the SMF can bind the PCC rule(s) to. +# - FILTER_RES: Indicate that the Flow Information within the "flowInfos" attribute cannot be handled by the SMF because any of the restrictions defined in subclause 5.4.2 of 3GPP TS 29.212 was not met. +# - MISS_REDI_SER_ADDR: Indicate that the PCC rule could not be successfully installed or enforced at the SMF because there is no valid Redirect Server Address within the Traffic Control Data policy decision which the PCC rule refers to provided by the PCF and no preconfigured redirection address for this PCC rule at the SMF. +# - CM_END_USER_SER_DENIED: Indicate that the charging system denied the service request due to service restrictions (e.g. terminate rating group) or limitations related to the end-user, for example the end-user's account could not cover the requested service. +# - CM_CREDIT_CON_NOT_APP: Indicate that the charging system determined that the service can be granted to the end user but no further credit control is needed for the service (e.g. service is free of charge or is treated for offline charging). +# - CM_AUTH_REJ: Indicate that the charging system denied the service request in order to terminate the service for which credit is requested. +# - CM_USER_UNK: Indicate that the specified end user could not be found in the charging system. +# - CM_RAT_FAILED: Indicate that the charging system cannot rate the service request due to insufficient rating input, incorrect AVP combination or due to an attribute or an attribute value that is not recognized or supported in the rating. +# - UE_STA_SUSP: Indicates that the UE is in suspend state. AfSigProtocol: - anyOf: - - type: string +# anyOf: +# - type: string enum: - NO_INFORMATION - SIP - - $ref: 'TS29571_CommonData.yaml#/components/schemas/NullValue' - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - NO_INFORMATION: Indicate that no information about the AF signalling protocol is being provided. - - SIP: Indicate that the signalling protocol is Session Initiation Protocol. +# - $ref: 'TS29571_CommonData.yaml#/components/schemas/NullValue' + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - NO_INFORMATION: Indicate that no information about the AF signalling protocol is being provided. +# - SIP: Indicate that the signalling protocol is Session Initiation Protocol. RuleOperation: - anyOf: - - type: string +# anyOf: +# - type: string enum: - CREATE_PCC_RULE - DELETE_PCC_RULE - MODIFY_PCC_RULE_AND_ADD_PACKET_FILTERS - - MODIFY_ PCC_RULE_AND_REPLACE_PACKET_FILTERS - - MODIFY_ PCC_RULE_AND_DELETE_PACKET_FILTERS + - MODIFY_PCC_RULE_AND_REPLACE_PACKET_FILTERS + - MODIFY_PCC_RULE_AND_DELETE_PACKET_FILTERS - MODIFY_PCC_RULE_WITHOUT_MODIFY_PACKET_FILTERS - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - CREATE_PCC_RULE: Indicates to create a new PCC rule to reserve the resource requested by the UE. - - DELETE_PCC_RULE: Indicates to delete a PCC rule corresponding to reserve the resource requested by the UE.. - - MODIFY_PCC_RULE_AND_ADD_PACKET_FILTERS: Indicates to modify the PCC rule by adding new packet filter(s). - - MODIFY_ PCC_RULE_AND_REPLACE_PACKET_FILTERS: Indicates to modify the PCC rule by replacing the existing packet filter(s). - - MODIFY_ PCC_RULE_AND_DELETE_PACKET_FILTERS: Indicates to modify the PCC rule by deleting the existing packet filter(s). - - MODIFY_PCC_RULE_WITHOUT_MODIFY_PACKET_FILTERS: Indicates to modify the PCC rule by modifying the QoS of the PCC rule. + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - CREATE_PCC_RULE: Indicates to create a new PCC rule to reserve the resource requested by the UE. +# - DELETE_PCC_RULE: Indicates to delete a PCC rule corresponding to reserve the resource requested by the UE.. +# - MODIFY_PCC_RULE_AND_ADD_PACKET_FILTERS: Indicates to modify the PCC rule by adding new packet filter(s). +# - MODIFY_ PCC_RULE_AND_REPLACE_PACKET_FILTERS: Indicates to modify the PCC rule by replacing the existing packet filter(s). +# - MODIFY_ PCC_RULE_AND_DELETE_PACKET_FILTERS: Indicates to modify the PCC rule by deleting the existing packet filter(s). +# - MODIFY_PCC_RULE_WITHOUT_MODIFY_PACKET_FILTERS: Indicates to modify the PCC rule by modifying the QoS of the PCC rule. RedirectAddressType: - anyOf: - - type: string +# anyOf: +# - type: string enum: - IPV4_ADDR - IPV6_ADDR - URL - SIP_URI - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - IPV4_ADDR: Indicates that the address type is in the form of "dotted-decimal" IPv4 address. - - IPV6_ADDR: Indicates that the address type is in the form of IPv6 address. - - URL: Indicates that the address type is in the form of Uniform Resource Locator. - - SIP_URI: Indicates that the address type is in the form of SIP Uniform Resource Identifier. + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - IPV4_ADDR: Indicates that the address type is in the form of "dotted-decimal" IPv4 address. +# - IPV6_ADDR: Indicates that the address type is in the form of IPv6 address. +# - URL: Indicates that the address type is in the form of Uniform Resource Locator. +# - SIP_URI: Indicates that the address type is in the form of SIP Uniform Resource Identifier. QosFlowUsage: - anyOf: - - type: string +# anyOf: +# - type: string enum: - GENERAL - IMS_SIG - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - GENERAL: Indicate no specific QoS flow usage information is available. - - IMS_SIG: Indicate that the QoS flow is used for IMS signalling only. + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - GENERAL: Indicate no specific QoS flow usage information is available. +# - IMS_SIG: Indicate that the QoS flow is used for IMS signalling only. FailureCause: - anyOf: - - type: string +# anyOf: +# - type: string enum: - PCC_RULE_EVENT - PCC_QOS_FLOW_EVENT - RULE_PERMANENT_ERROR - RULE_TEMPORARY_ERROR - - type: string + type: string CreditManagementStatus: - anyOf: - - type: string +# anyOf: +# - type: string enum: - END_USER_SER_DENIED - CREDIT_CTRL_NOT_APP - AUTH_REJECTED - USER_UNKNOWN - RATING_FAILED - - type: string + type: string SessionRuleFailureCode: - anyOf: - - type: string +# anyOf: +# - type: string enum: - NF_MAL - RES_LIM - UNSUCC_QOS_VAL - UE_STA_SUSP - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - NF_MAL: Indicate that the PCC rule could not be successfully installed (for those provisioned from the PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to SMF/UPF malfunction. - - RES_LIM: Indicate that the PCC rule could not be successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to a limitation of resources at the SMF/UPF. - - UNSUCC_QOS_VAL: indicate that the QoS validation has failed. - - UE_STA_SUSP: Indicates that the UE is in suspend state. + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - NF_MAL: Indicate that the PCC rule could not be successfully installed (for those provisioned from the PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to SMF/UPF malfunction. +# - RES_LIM: Indicate that the PCC rule could not be successfully installed (for those provisioned from PCF) or activated (for those pre-defined in SMF) or enforced (for those already successfully installed) due to a limitation of resources at the SMF/UPF. +# - UNSUCC_QOS_VAL: indicate that the QoS validation has failed. +# - UE_STA_SUSP: Indicates that the UE is in suspend state. SteeringFunctionality: - anyOf: - - type: string +# anyOf: +# - type: string enum: - MPTCP - ATSSS_LL - - type: string - description: > - This string provides forward-compatibility with future - extensions to the enumeration but is not used to encode - content defined in the present version of this API. - description: > - Possible values are - - MPTCP: Indicates that PCF authorizes the MPTCP functionality to support traffic steering, switching and splitting. - - ATSSS_LL: Indicates that PCF authorizes the ATSSS-LL functionality to support traffic steering, switching and splitting. + type: string +# description: > +# This string provides forward-compatibility with future +# extensions to the enumeration but is not used to encode +# content defined in the present version of this API. +# description: > +# Possible values are +# - MPTCP: Indicates that PCF authorizes the MPTCP functionality to support traffic steering, switching and splitting. +# - ATSSS_LL: Indicates that PCF authorizes the ATSSS-LL functionality to support traffic steering, switching and splitting. SteerModeValue: - anyOf: - - type: string +# anyOf: +# - type: string enum: - ACTIVE_STANDBY - LOAD_BALANCING - SMALLEST_DELAY - PRIORITY_BASED - - type: string + type: string MulticastAccessControl: anyOf: - type: string @@ -1937,43 +1937,43 @@ components: - NOT_ALLOWED - type: string RequestedQosMonitoringParameter: - anyOf: - - type: string +# anyOf: +# - type: string enum: - DOWNLINK - UPLINK - ROUND_TRIP - - type: string + type: string ReportingFrequency: - anyOf: - - type: string +# anyOf: +# - type: string enum: - EVENT_TRIGGERED - PERIODIC - SESSION_RELEASE - - type: string + type: string SmPolicyAssociationReleaseCause: - anyOf: - - type: string +# anyOf: +# - type: string enum: - UNSPECIFIED - UE_SUBSCRIPTION - INSUFFICIENT_RES - VALIDATION_CONDITION_NOT_MET - - type: string + type: string PduSessionRelCause: - anyOf: - - type: string +# anyOf: +# - type: string enum: - PS_TO_CS_HO - - type: string + type: string MaPduIndication: - anyOf: - - type: string +# anyOf: +# - type: string enum: - MA_PDU_REQUEST - - MA_PDU_ NETWORK_UPGRADE ALLOWED - - type: string + - MA_PDU_NETWORK_UPGRADE_ALLOWED + type: string AtsssCapability: anyOf: - type: string diff --git a/src/amf/context.c b/src/amf/context.c index 5388786a6..b5fa79018 100644 --- a/src/amf/context.c +++ b/src/amf/context.c @@ -1082,8 +1082,13 @@ amf_ue_t *amf_ue_add(ran_ue_t *ran_ue) ogs_assert(amf_ue); memset(amf_ue, 0, sizeof *amf_ue); + /* SBI Type */ amf_ue->sbi.type = OGS_SBI_OBJ_UE_TYPE; + /* SBI Features */ + OGS_SBI_FEATURES_SET(amf_ue->am_policy_control_features, + OGS_SBI_NPCF_AM_POLICY_CONTROL_UE_AMBR_AUTHORIZATION); + ogs_list_init(&amf_ue->sess_list); /* TODO : Hard-coded */ diff --git a/src/amf/context.h b/src/amf/context.h index d0184508b..c6ed52642 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -341,10 +341,12 @@ struct amf_ue_s { * #define OGS_NAS_SECURITY_ALGORITHMS_128_NIA3 3 */ uint8_t selected_int_algorithm; - ogs_bitrate_t subscribed_ue_ambr; /* UE-AMBR */ + ogs_bitrate_t ue_ambr; /* UE-AMBR */ int num_of_subscribed_dnn; char *subscribed_dnn[OGS_MAX_NUM_OF_DNN]; + uint64_t am_policy_control_features; /* SBI Features */ + #define CM_CONNECTED(__aMF) \ ((__aMF) && ((__aMF)->ran_ue != NULL) && ran_ue_cycle((__aMF)->ran_ue)) #define CM_IDLE(__aMF) \ diff --git a/src/amf/namf-handler.c b/src/amf/namf-handler.c index f33abf80d..bcd6b1dfc 100644 --- a/src/amf/namf-handler.c +++ b/src/amf/namf-handler.c @@ -88,6 +88,15 @@ int amf_namf_comm_handle_n1_n2_message_transfer( ogs_error("No n2InfoContent"); return OGS_ERROR; } + switch (n2InfoContent->ngap_ie_type) { + case OpenAPI_ngap_ie_type_PDU_RES_SETUP_REQ: + case OpenAPI_ngap_ie_type_PDU_RES_MOD_REQ: + break; + default: + ogs_error("Not implemented ngap_ie_type[%d]", + n2InfoContent->ngap_ie_type); + return OGS_ERROR; + } ngapData = n2InfoContent->ngap_data; if (!ngapData || !ngapData->content_id) { ogs_error("No ngapData"); @@ -144,45 +153,68 @@ int amf_namf_comm_handle_n1_n2_message_transfer( n2smbuf = ogs_pkbuf_copy(n2smbuf); ogs_assert(n2smbuf); - if (sess->pdu_session_establishment_accept) { - ogs_pkbuf_free(sess->pdu_session_establishment_accept); - sess->pdu_session_establishment_accept = NULL; - } + status = OGS_SBI_HTTP_STATUS_OK; gmmbuf = gmm_build_dl_nas_transport(sess, OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0); ogs_assert(gmmbuf); - ngapbuf = ngap_build_pdu_session_resource_setup_request( - sess, gmmbuf, n2smbuf); - ogs_assert(ngapbuf); + switch (n2InfoContent->ngap_ie_type) { + case OpenAPI_ngap_ie_type_PDU_RES_SETUP_REQ: + if (sess->pdu_session_establishment_accept) { + ogs_pkbuf_free(sess->pdu_session_establishment_accept); + sess->pdu_session_establishment_accept = NULL; + } - status = OGS_SBI_HTTP_STATUS_OK; + ngapbuf = ngap_build_pdu_session_resource_setup_request( + sess, gmmbuf, n2smbuf); + ogs_assert(ngapbuf); + + if (SESSION_CONTEXT_IN_SMF(sess)) { + /* + * [1-CLIENT] /nsmf-pdusession/v1/sm-contexts + * [2-SERVER] /namf-comm/v1/ue-contexts/{supi}/n1-n2-messages + * + * If [2-SERVER] arrives after [1-CLIENT], + * sm-context-ref is created in [1-CLIENT]. + * So, the PDU session establishment accpet can be transmitted now. + */ + if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK) { + ogs_error("nas_5gs_send_to_gnb() failed"); + status = OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR; + } + } else { + sess->pdu_session_establishment_accept = ngapbuf; + } + break; + + case OpenAPI_ngap_ie_type_PDU_RES_MOD_REQ: + ngapbuf = ngap_build_pdu_session_resource_modify_request( + sess, gmmbuf, n2smbuf); + ogs_assert(ngapbuf); - if (SESSION_CONTEXT_IN_SMF(sess)) { - /* - * [1-CLIENT] /nsmf-pdusession/v1/sm-contexts - * [2-SERVER] /namf-comm/v1/ue-contexts/{supi}/n1-n2-messages - * - * If [2-SERVER] arrives after [1-CLIENT], - * sm-context-ref is created in [1-CLIENT]. - * So, the PDU session establishment accpet can be transmitted now. - */ if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK) { ogs_error("nas_5gs_send_to_gnb() failed"); status = OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR; } - } else { - sess->pdu_session_establishment_accept = ngapbuf; - } + break; - memset(&N1N2MessageTransferRspData, 0, sizeof(N1N2MessageTransferRspData)); - N1N2MessageTransferRspData.cause = - OpenAPI_n1_n2_message_transfer_cause_N1_N2_TRANSFER_INITIATED; + default: + ogs_error("Not implemented ngap_ie_type[%d]", + n2InfoContent->ngap_ie_type); + ogs_assert_if_reached(); + } memset(&sendmsg, 0, sizeof(sendmsg)); - sendmsg.N1N2MessageTransferRspData = &N1N2MessageTransferRspData; + if (status == OGS_SBI_HTTP_STATUS_OK) { + memset(&N1N2MessageTransferRspData, 0, + sizeof(N1N2MessageTransferRspData)); + N1N2MessageTransferRspData.cause = + OpenAPI_n1_n2_message_transfer_cause_N1_N2_TRANSFER_INITIATED; + + sendmsg.N1N2MessageTransferRspData = &N1N2MessageTransferRspData; + } response = ogs_sbi_build_response(&sendmsg, status); ogs_assert(response); diff --git a/src/amf/ngap-build.c b/src/amf/ngap-build.c index a0b3c811a..f8a6d504f 100644 --- a/src/amf/ngap-build.c +++ b/src/amf/ngap-build.c @@ -354,8 +354,7 @@ ogs_pkbuf_t *ngap_build_initial_context_setup_request( RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; - if (amf_ue->subscribed_ue_ambr.downlink || - amf_ue->subscribed_ue_ambr.uplink) { + if (amf_ue->ue_ambr.downlink || amf_ue->ue_ambr.uplink) { ie = CALLOC(1, sizeof(NGAP_InitialContextSetupRequestIEs_t)); ASN_SEQUENCE_ADD(&InitialContextSetupRequest->protocolIEs, ie); @@ -368,10 +367,10 @@ ogs_pkbuf_t *ngap_build_initial_context_setup_request( asn_uint642INTEGER( &UEAggregateMaximumBitRate->uEAggregateMaximumBitRateUL, - amf_ue->subscribed_ue_ambr.uplink); + amf_ue->ue_ambr.uplink); asn_uint642INTEGER( &UEAggregateMaximumBitRate->uEAggregateMaximumBitRateDL, - amf_ue->subscribed_ue_ambr.downlink); + amf_ue->ue_ambr.downlink); } ie = CALLOC(1, sizeof(NGAP_InitialContextSetupRequestIEs_t)); @@ -911,6 +910,105 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request( return ogs_ngap_encode(&pdu); } +ogs_pkbuf_t *ngap_build_pdu_session_resource_modify_request( + amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf) +{ + amf_ue_t *amf_ue = NULL; + ran_ue_t *ran_ue = NULL; + + NGAP_NGAP_PDU_t pdu; + NGAP_InitiatingMessage_t *initiatingMessage = NULL; + NGAP_PDUSessionResourceModifyRequest_t *PDUSessionResourceModifyRequest; + + NGAP_PDUSessionResourceModifyRequestIEs_t *ie = NULL; + NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; + + NGAP_PDUSessionResourceModifyListModReq_t *PDUSessionList = NULL; + NGAP_PDUSessionResourceModifyItemModReq_t *PDUSessionItem = NULL; + NGAP_NAS_PDU_t *nAS_PDU = NULL; + OCTET_STRING_t *transfer = NULL; + + ogs_assert(gmmbuf); + ogs_assert(n2smbuf); + ogs_assert(sess); + + amf_ue = sess->amf_ue; + ogs_assert(amf_ue); + ran_ue = ran_ue_cycle(amf_ue->ran_ue); + ogs_assert(ran_ue); + + memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t)); + pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t)); + + initiatingMessage = pdu.choice.initiatingMessage; + initiatingMessage->procedureCode = + NGAP_ProcedureCode_id_PDUSessionResourceModify; + initiatingMessage->criticality = NGAP_Criticality_reject; + initiatingMessage->value.present = + NGAP_InitiatingMessage__value_PR_PDUSessionResourceModifyRequest; + + PDUSessionResourceModifyRequest = + &initiatingMessage->value.choice.PDUSessionResourceModifyRequest; + + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceModifyRequestIEs_t)); + ASN_SEQUENCE_ADD(&PDUSessionResourceModifyRequest->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = + NGAP_PDUSessionResourceModifyRequestIEs__value_PR_AMF_UE_NGAP_ID; + + AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; + + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceModifyRequestIEs_t)); + ASN_SEQUENCE_ADD(&PDUSessionResourceModifyRequest->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = + NGAP_PDUSessionResourceModifyRequestIEs__value_PR_RAN_UE_NGAP_ID; + + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceModifyRequestIEs_t)); + ASN_SEQUENCE_ADD(&PDUSessionResourceModifyRequest->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModReq; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_PDUSessionResourceModifyRequestIEs__value_PR_PDUSessionResourceModifyListModReq; + + PDUSessionList = &ie->value.choice.PDUSessionResourceModifyListModReq; + + ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld]", + ran_ue->ran_ue_ngap_id, (long long)ran_ue->amf_ue_ngap_id); + + asn_uint642INTEGER(AMF_UE_NGAP_ID, ran_ue->amf_ue_ngap_id); + *RAN_UE_NGAP_ID = ran_ue->ran_ue_ngap_id; + + PDUSessionItem = + CALLOC(1, sizeof(struct NGAP_PDUSessionResourceModifyItemModReq)); + ASN_SEQUENCE_ADD(&PDUSessionList->list, PDUSessionItem); + + PDUSessionItem->pDUSessionID = sess->psi; + + nAS_PDU = CALLOC(1, sizeof(NGAP_NAS_PDU_t)); + PDUSessionItem->nAS_PDU = nAS_PDU; + nAS_PDU->size = gmmbuf->len; + nAS_PDU->buf = CALLOC(nAS_PDU->size, sizeof(uint8_t)); + memcpy(nAS_PDU->buf, gmmbuf->data, nAS_PDU->size); + ogs_pkbuf_free(gmmbuf); + + transfer = &PDUSessionItem->pDUSessionResourceModifyRequestTransfer; + transfer->size = n2smbuf->len; + transfer->buf = CALLOC(transfer->size, sizeof(uint8_t)); + memcpy(transfer->buf, n2smbuf->data, transfer->size); + ogs_pkbuf_free(n2smbuf); + + return ogs_ngap_encode(&pdu); +} + ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command( amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf) { diff --git a/src/amf/ngap-build.h b/src/amf/ngap-build.h index 8d788b6c2..c5353f154 100644 --- a/src/amf/ngap-build.h +++ b/src/amf/ngap-build.h @@ -41,6 +41,8 @@ ogs_pkbuf_t *ngap_build_ue_context_release_command( ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request( amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf); +ogs_pkbuf_t *ngap_build_pdu_session_resource_modify_request( + amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf); ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command( amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf); diff --git a/src/amf/ngap-handler.c b/src/amf/ngap-handler.c index edbe3d3bc..3151c47e9 100644 --- a/src/amf/ngap-handler.c +++ b/src/amf/ngap-handler.c @@ -799,7 +799,6 @@ void ngap_handle_initial_context_setup_response( param.n2SmInfoType = OpenAPI_n2_sm_info_type_PDU_RES_SETUP_RSP; ogs_pkbuf_put_data(param.n2smbuf, transfer->buf, transfer->size); - /* UPDATE_UpCnxState - ACTIVATED */ amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF, sess, AMF_UPDATE_SM_CONTEXT_ACTIVATED, ¶m, amf_nsmf_pdu_session_build_update_sm_context); @@ -1374,7 +1373,6 @@ void ngap_handle_pdu_session_resource_setup_response( param.n2SmInfoType = OpenAPI_n2_sm_info_type_PDU_RES_SETUP_RSP; ogs_pkbuf_put_data(param.n2smbuf, transfer->buf, transfer->size); - /* UPDATE_UpCnxState - ACTIVATED */ amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF, sess, AMF_UPDATE_SM_CONTEXT_ACTIVATED, ¶m, amf_nsmf_pdu_session_build_update_sm_context); @@ -1383,6 +1381,169 @@ void ngap_handle_pdu_session_resource_setup_response( } } +void ngap_handle_pdu_session_resource_modify_response( + amf_gnb_t *gnb, ogs_ngap_message_t *message) +{ + char buf[OGS_ADDRSTRLEN]; + int i; + + amf_ue_t *amf_ue = NULL; + ran_ue_t *ran_ue = NULL; + uint64_t amf_ue_ngap_id; + amf_nsmf_pdu_session_update_sm_context_param_t param; + + NGAP_SuccessfulOutcome_t *successfulOutcome = NULL; + NGAP_PDUSessionResourceModifyResponse_t *PDUSessionResourceModifyResponse; + + NGAP_PDUSessionResourceModifyResponseIEs_t *ie = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; + NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; + NGAP_PDUSessionResourceModifyListModRes_t *PDUSessionList = NULL; + NGAP_PDUSessionResourceModifyItemModRes_t *PDUSessionItem = NULL; + OCTET_STRING_t *transfer = NULL; + + ogs_assert(gnb); + ogs_assert(gnb->sctp.sock); + + ogs_assert(message); + successfulOutcome = message->choice.successfulOutcome; + ogs_assert(successfulOutcome); + PDUSessionResourceModifyResponse = + &successfulOutcome->value.choice.PDUSessionResourceModifyResponse; + ogs_assert(PDUSessionResourceModifyResponse); + + ogs_debug("PDU session resource modify response"); + + for (i = 0; i < PDUSessionResourceModifyResponse->protocolIEs.list.count; + i++) { + ie = PDUSessionResourceModifyResponse->protocolIEs.list.array[i]; + switch (ie->id) { + case NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID: + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + break; + case NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID: + AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; + break; + case NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModRes: + PDUSessionList = + &ie->value.choice.PDUSessionResourceModifyListModRes; + break; + default: + break; + } + } + + ogs_debug(" IP[%s] RAN_ID[%d]", + OGS_ADDR(gnb->sctp.addr, buf), gnb->gnb_id); + + if (!AMF_UE_NGAP_ID) { + ogs_error("No AMF_UE_NGAP_ID"); + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, + NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); + return; + } + + if (asn_INTEGER2ulong(AMF_UE_NGAP_ID, + (unsigned long *)&amf_ue_ngap_id) != 0) { + ogs_error("Invalid AMF_UE_NGAP_ID"); + ngap_send_error_indication(gnb, (uint32_t *)RAN_UE_NGAP_ID, NULL, + NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); + return; + } + + ran_ue = ran_ue_find_by_amf_ue_ngap_id(amf_ue_ngap_id); + if (!ran_ue) { + ogs_error("No RAN UE Context : AMF_UE_NGAP_ID[%lld]", + (long long)amf_ue_ngap_id); + ngap_send_error_indication( + gnb, (uint32_t *)RAN_UE_NGAP_ID, &amf_ue_ngap_id, + NGAP_Cause_PR_radioNetwork, + NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID); + return; + } + + ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld]", + ran_ue->ran_ue_ngap_id, (long long)ran_ue->amf_ue_ngap_id); + + amf_ue = ran_ue->amf_ue; + if (!amf_ue) { + ogs_error("Cannot find AMF-UE Context [%lld]", + (long long)amf_ue_ngap_id); + ngap_send_error_indication( + gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id, + NGAP_Cause_PR_radioNetwork, + NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID); + return; + } + + if (!PDUSessionList) { + ogs_error("No PDUSessionResourceModifyListModRes"); + ngap_send_error_indication2(amf_ue, + NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); + return; + } + + for (i = 0; i < PDUSessionList->list.count; i++) { + amf_sess_t *sess = NULL; + PDUSessionItem = (NGAP_PDUSessionResourceModifyItemModRes_t *) + PDUSessionList->list.array[i]; + + if (!PDUSessionItem) { + ogs_error("No PDUSessionResourceModifyItemModRes"); + ngap_send_error_indication2(amf_ue, + NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); + return; + } + + transfer = &PDUSessionItem->pDUSessionResourceModifyResponseTransfer; + if (!transfer) { + ogs_error("No PDUSessionResourceModifyResponseTransfer"); + ngap_send_error_indication2(amf_ue, + NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); + return; + } + + if (PDUSessionItem->pDUSessionID == + OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED) { + ogs_error("PDU Session Identity is unassigned"); + ngap_send_error_indication2(amf_ue, + NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error); + return; + } + + sess = amf_sess_find_by_psi(amf_ue, PDUSessionItem->pDUSessionID); + if (!sess) { + ogs_error("Cannot find PDU Session ID [%d]", + (int)PDUSessionItem->pDUSessionID); + ngap_send_error_indication2(amf_ue, + NGAP_Cause_PR_radioNetwork, + NGAP_CauseRadioNetwork_unknown_PDU_session_ID); + return; + } + + if (!SESSION_CONTEXT_IN_SMF(sess)) { + ogs_error("Session Context is not in SMF [%d]", + (int)PDUSessionItem->pDUSessionID); + ngap_send_error_indication2(amf_ue, + NGAP_Cause_PR_radioNetwork, + NGAP_CauseRadioNetwork_unknown_PDU_session_ID); + return; + } + + memset(¶m, 0, sizeof(param)); + param.n2smbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN); + ogs_assert(param.n2smbuf); + param.n2SmInfoType = OpenAPI_n2_sm_info_type_PDU_RES_MOD_RSP; + ogs_pkbuf_put_data(param.n2smbuf, transfer->buf, transfer->size); + + amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF, + sess, AMF_UPDATE_SM_CONTEXT_MODIFIED, ¶m, + amf_nsmf_pdu_session_build_update_sm_context); + + ogs_pkbuf_free(param.n2smbuf); + } +} + void ngap_handle_pdu_session_resource_release_response( amf_gnb_t *gnb, ogs_ngap_message_t *message) { @@ -1763,7 +1924,6 @@ void ngap_handle_path_switch_request( param.n2SmInfoType = OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ; ogs_pkbuf_put_data(param.n2smbuf, transfer->buf, transfer->size); - /* UPDATE_UpCnxState - ACTIVATED */ amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF, sess, AMF_UPDATE_SM_CONTEXT_ACTIVATED, ¶m, amf_nsmf_pdu_session_build_update_sm_context); diff --git a/src/amf/ngap-handler.h b/src/amf/ngap-handler.h index 36bdca1df..5a766f5f3 100644 --- a/src/amf/ngap-handler.h +++ b/src/amf/ngap-handler.h @@ -41,6 +41,8 @@ void ngap_handle_initial_context_setup_failure( void ngap_handle_pdu_session_resource_setup_response( amf_gnb_t *gnb, ogs_ngap_message_t *message); +void ngap_handle_pdu_session_resource_modify_response( + amf_gnb_t *gnb, ogs_ngap_message_t *message); void ngap_handle_pdu_session_resource_release_response( amf_gnb_t *gnb, ogs_ngap_message_t *message); diff --git a/src/amf/ngap-sm.c b/src/amf/ngap-sm.c index 206c19a00..7900dfa00 100644 --- a/src/amf/ngap-sm.c +++ b/src/amf/ngap-sm.c @@ -137,6 +137,9 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e) case NGAP_ProcedureCode_id_PDUSessionResourceSetup: ngap_handle_pdu_session_resource_setup_response(gnb, pdu); break; + case NGAP_ProcedureCode_id_PDUSessionResourceModify: + ngap_handle_pdu_session_resource_modify_response(gnb, pdu); + break; case NGAP_ProcedureCode_id_PDUSessionResourceRelease: ngap_handle_pdu_session_resource_release_response(gnb, pdu); break; diff --git a/src/amf/npcf-build.c b/src/amf/npcf-build.c index 48c20115b..17ef3c292 100644 --- a/src/amf/npcf-build.c +++ b/src/amf/npcf-build.c @@ -34,7 +34,7 @@ ogs_sbi_request_t *amf_npcf_am_policy_control_build_create( OpenAPI_list_t *AllowedSnssais = NULL; OpenAPI_user_location_t ueLocation; - OpenAPI_ambr_t ueAmbr; + OpenAPI_ambr_t UeAmbr; ogs_assert(amf_ue); ogs_assert(amf_ue->supi); @@ -89,17 +89,20 @@ ogs_sbi_request_t *amf_npcf_am_policy_control_build_create( PolicyAssociationRequest.rat_type = amf_ue_rat_type(amf_ue); - memset(&ueAmbr, 0, sizeof(ueAmbr)); - if (amf_ue->subscribed_ue_ambr.uplink) { - ueAmbr.uplink = ogs_sbi_bitrate_to_string( - amf_ue->subscribed_ue_ambr.uplink, OGS_SBI_BITRATE_KBPS); - } - if (amf_ue->subscribed_ue_ambr.downlink) { - ueAmbr.downlink = ogs_sbi_bitrate_to_string( - amf_ue->subscribed_ue_ambr.downlink, OGS_SBI_BITRATE_KBPS); - } - if (ueAmbr.downlink || ueAmbr.uplink) { - PolicyAssociationRequest.ue_ambr = &ueAmbr; + memset(&UeAmbr, 0, sizeof(UeAmbr)); + if (OGS_SBI_FEATURES_IS_SET(amf_ue->am_policy_control_features, + OGS_SBI_NPCF_AM_POLICY_CONTROL_UE_AMBR_AUTHORIZATION)) { + if (amf_ue->ue_ambr.uplink) { + UeAmbr.uplink = ogs_sbi_bitrate_to_string( + amf_ue->ue_ambr.uplink, OGS_SBI_BITRATE_KBPS); + } + if (amf_ue->ue_ambr.downlink) { + UeAmbr.downlink = ogs_sbi_bitrate_to_string( + amf_ue->ue_ambr.downlink, OGS_SBI_BITRATE_KBPS); + } + if (UeAmbr.downlink || UeAmbr.uplink) { + PolicyAssociationRequest.ue_ambr = &UeAmbr; + } } AllowedSnssais = OpenAPI_list_create(); @@ -128,7 +131,12 @@ ogs_sbi_request_t *amf_npcf_am_policy_control_build_create( PolicyAssociationRequest.guami = ogs_sbi_build_guami(amf_ue->guami); - PolicyAssociationRequest.supp_feat = (char *)""; + PolicyAssociationRequest.service_name = + (char *)OGS_SBI_SERVICE_NAME_NAMF_CALLBACK; + + PolicyAssociationRequest.supp_feat = + ogs_uint64_to_string(amf_ue->am_policy_control_features); + ogs_assert(PolicyAssociationRequest.supp_feat); message.PolicyAssociationRequest = &PolicyAssociationRequest; @@ -136,6 +144,8 @@ ogs_sbi_request_t *amf_npcf_am_policy_control_build_create( ogs_assert(request); ogs_free(PolicyAssociationRequest.notification_uri); + ogs_free(PolicyAssociationRequest.supp_feat); + if (PolicyAssociationRequest.gpsi) ogs_free(PolicyAssociationRequest.gpsi); @@ -150,8 +160,8 @@ ogs_sbi_request_t *amf_npcf_am_policy_control_build_create( if (PolicyAssociationRequest.serving_plmn) ogs_sbi_free_plmn_id_nid(PolicyAssociationRequest.serving_plmn); - if (ueAmbr.downlink) ogs_free(ueAmbr.downlink); - if (ueAmbr.uplink) ogs_free(ueAmbr.uplink); + if (UeAmbr.downlink) ogs_free(UeAmbr.downlink); + if (UeAmbr.uplink) ogs_free(UeAmbr.uplink); OpenAPI_list_for_each(PolicyAssociationRequest.allowed_snssais, node) { struct OpenAPI_snssai_s *Snssai = node->data; diff --git a/src/amf/npcf-handler.c b/src/amf/npcf-handler.c index a1f8b826d..9fbb4f9ba 100644 --- a/src/amf/npcf-handler.c +++ b/src/amf/npcf-handler.c @@ -27,7 +27,10 @@ int amf_npcf_am_policy_control_handle_create( { int rv; + uint64_t supported_features; + OpenAPI_policy_association_t *PolicyAssociation = NULL; + OpenAPI_lnode_t *node = NULL; ogs_sbi_message_t message; ogs_sbi_header_t header; @@ -83,10 +86,37 @@ int amf_npcf_am_policy_control_handle_create( return OGS_ERROR; } + /* SBI Features */ + supported_features = ogs_uint64_from_string(PolicyAssociation->supp_feat); + amf_ue->am_policy_control_features &= supported_features; + if (amf_ue->policy_association_id) ogs_free(amf_ue->policy_association_id); amf_ue->policy_association_id = ogs_strdup(message.h.resource.component[1]); + OpenAPI_list_for_each(PolicyAssociation->triggers, node) { + if (node->data) { + OpenAPI_request_trigger_e trigger = + (OpenAPI_request_trigger_e)node->data; + OpenAPI_ambr_t *UeAmbr = NULL; + + switch (trigger) { + case OpenAPI_request_trigger_UE_AMBR_CH: + UeAmbr = PolicyAssociation->ue_ambr; + if (UeAmbr) { + amf_ue->ue_ambr.uplink = + ogs_sbi_bitrate_from_string(UeAmbr->uplink); + amf_ue->ue_ambr.downlink = + ogs_sbi_bitrate_from_string(UeAmbr->downlink); + } + break; + default: + ogs_error("Not implemented [%d]", trigger); + break; + } + } + } + ogs_sbi_header_free(&header); return OGS_OK; diff --git a/src/amf/nsmf-build.c b/src/amf/nsmf-build.c index 6943fd572..051a9ff17 100644 --- a/src/amf/nsmf-build.c +++ b/src/amf/nsmf-build.c @@ -35,6 +35,7 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context( OpenAPI_snssai_t hplmnSnssai; OpenAPI_ref_to_binary_data_t n1SmMsg; OpenAPI_user_location_t ueLocation; + ogs_sbi_nf_instance_t *pcf_nf_instance = NULL; ogs_assert(sess); amf_ue = sess->amf_ue; @@ -64,6 +65,7 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context( } } SmContextCreateData.pdu_session_id = sess->psi; + ogs_assert(sess->dnn); SmContextCreateData.dnn = sess->dnn; memset(&sNssai, 0, sizeof(sNssai)); @@ -98,6 +100,8 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context( n1SmMsg.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID; SmContextCreateData.n1_sm_msg = &n1SmMsg; + SmContextCreateData.rat_type = amf_ue_rat_type(amf_ue); + memset(&ueLocation, 0, sizeof(ueLocation)); ueLocation.nr_location = ogs_sbi_build_nr_location( &amf_ue->tai, &amf_ue->nr_cgi); @@ -108,6 +112,11 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context( SmContextCreateData.ue_location = &ueLocation; SmContextCreateData.ue_time_zone = ogs_sbi_timezone_string(ogs_timezone()); + pcf_nf_instance = OGS_SBI_NF_INSTANCE_GET( + amf_ue->sbi.nf_type_array, OpenAPI_nf_type_PCF); + ogs_assert(pcf_nf_instance); + SmContextCreateData.pcf_id = pcf_nf_instance->id; + message.SmContextCreateData = &SmContextCreateData; message.part[message.num_of_part].pkbuf = sess->payload_container; diff --git a/src/amf/nsmf-handler.c b/src/amf/nsmf-handler.c index 8a0efb688..8e9e8f643 100644 --- a/src/amf/nsmf-handler.c +++ b/src/amf/nsmf-handler.c @@ -275,6 +275,15 @@ int amf_nsmf_pdu_session_handle_update_sm_context( * 3. PFCP Session Modifcation Request (Apply: FORWARD) * 4. PFCP Session Modifcation Response */ + + } else if (state == AMF_UPDATE_SM_CONTEXT_MODIFIED) { + /* + * 1. PDUSessionResourceModifyResponse + * 2. /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify + * 3. PFCP Session Modifcation Request + * 4. PFCP Session Modifcation Response + */ + } else if (state == AMF_UPDATE_SM_CONTEXT_DEACTIVATED) { /* * 1. UEContextReleaseRequest diff --git a/src/amf/nudm-handler.c b/src/amf/nudm-handler.c index 8f4a73707..df9232c74 100644 --- a/src/amf/nudm-handler.c +++ b/src/amf/nudm-handler.c @@ -31,7 +31,10 @@ int amf_nudm_sdm_handle_provisioned( SWITCH(recvmsg->h.resource.component[1]) CASE(OGS_SBI_RESOURCE_NAME_AM_DATA) if (recvmsg->AccessAndMobilitySubscriptionData) { - OpenAPI_list_t *GpsiList = + OpenAPI_ambr_rm_t *ue_ambr = + recvmsg->AccessAndMobilitySubscriptionData-> + subscribed_ue_ambr; + OpenAPI_list_t *gpsiList = recvmsg->AccessAndMobilitySubscriptionData->gpsis; OpenAPI_ambr_rm_t *SubscribedUeAmbr = recvmsg->AccessAndMobilitySubscriptionData->subscribed_ue_ambr; @@ -39,9 +42,16 @@ int amf_nudm_sdm_handle_provisioned( recvmsg->AccessAndMobilitySubscriptionData->subscribed_dnn_list; OpenAPI_lnode_t *node = NULL; - if (GpsiList) { + if (ue_ambr) { + amf_ue->ue_ambr.uplink = + ogs_sbi_bitrate_from_string(ue_ambr->uplink); + amf_ue->ue_ambr.downlink = + ogs_sbi_bitrate_from_string(ue_ambr->downlink); + } + + if (gpsiList) { amf_ue->num_of_msisdn = 0; - OpenAPI_list_for_each(GpsiList, node) { + OpenAPI_list_for_each(gpsiList, node) { if (node->data) { char *gpsi = NULL; @@ -66,9 +76,9 @@ int amf_nudm_sdm_handle_provisioned( } if (SubscribedUeAmbr) { - amf_ue->subscribed_ue_ambr.uplink = + amf_ue->ue_ambr.uplink = ogs_sbi_bitrate_from_string(SubscribedUeAmbr->uplink); - amf_ue->subscribed_ue_ambr.downlink = + amf_ue->ue_ambr.downlink = ogs_sbi_bitrate_from_string(SubscribedUeAmbr->downlink); } diff --git a/src/amf/sbi-path.c b/src/amf/sbi-path.c index 6080db3e2..1c9dbaaf1 100644 --- a/src/amf/sbi-path.c +++ b/src/amf/sbi-path.c @@ -129,8 +129,9 @@ void amf_ue_sbi_discover_and_send( ogs_assert(amf_ue); ogs_assert(build); - xact = ogs_sbi_xact_add(target_nf_type, &amf_ue->sbi, data, - (ogs_sbi_build_f)build, amf_timer_sbi_client_wait_expire); + xact = ogs_sbi_xact_add(target_nf_type, &amf_ue->sbi, + (ogs_sbi_build_f)build, amf_ue, data, + amf_timer_sbi_client_wait_expire); ogs_assert(xact); if (ogs_sbi_discover_and_send(xact, @@ -151,8 +152,9 @@ void amf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type, ogs_assert(sess); ogs_assert(build); - xact = ogs_sbi_xact_add(target_nf_type, &sess->sbi, data, - (ogs_sbi_build_f)build, amf_timer_sbi_client_wait_expire); + xact = ogs_sbi_xact_add(target_nf_type, &sess->sbi, + (ogs_sbi_build_f)build, sess, data, + amf_timer_sbi_client_wait_expire); ogs_assert(xact); xact->state = state; @@ -174,7 +176,6 @@ void amf_sbi_send_activating_session(amf_sess_t *sess) memset(¶m, 0, sizeof(param)); param.upCnxState = OpenAPI_up_cnx_state_ACTIVATING; - /* UPDATE_UpCnxState - ACTIVATING */ amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF, sess, AMF_UPDATE_SM_CONTEXT_ACTIVATING, ¶m, amf_nsmf_pdu_session_build_update_sm_context); @@ -194,7 +195,6 @@ void amf_sbi_send_deactivate_session( param.ue_location = true; param.ue_timezone = true; - /* UPDATE_UpCnxState - DEACTIVATED */ amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF, sess, state, ¶m, amf_nsmf_pdu_session_build_update_sm_context); } diff --git a/src/amf/sbi-path.h b/src/amf/sbi-path.h index ded8dda50..250f57221 100644 --- a/src/amf/sbi-path.h +++ b/src/amf/sbi-path.h @@ -41,7 +41,7 @@ void amf_ue_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type, #define AMF_UPDATE_SM_CONTEXT_ACTIVATED 1 #define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 2 #define AMF_UPDATE_SM_CONTEXT_ACTIVATING 3 -#define AMF_UPDATE_SM_CONTEXT_SUSPENDED 4 +#define AMF_UPDATE_SM_CONTEXT_MODIFIED 4 #define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 5 #define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 6 #define AMF_UPDATE_SM_CONTEXT_NG_RESET 7 diff --git a/src/ausf/nnrf-handler.c b/src/ausf/nnrf-handler.c index 7c54e5bc7..8c2282c29 100644 --- a/src/ausf/nnrf-handler.c +++ b/src/ausf/nnrf-handler.c @@ -240,7 +240,6 @@ void ausf_nnrf_handle_nf_discover( { ogs_sbi_object_t *sbi_object = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL; - ogs_sbi_stream_t *stream = NULL; OpenAPI_search_result_t *SearchResult = NULL; OpenAPI_lnode_t *node = NULL; @@ -249,8 +248,6 @@ void ausf_nnrf_handle_nf_discover( ogs_assert(xact); sbi_object = xact->sbi_object; ogs_assert(sbi_object); - stream = xact->assoc_stream; - ogs_assert(stream); ogs_assert(recvmsg); SearchResult = recvmsg->SearchResult; diff --git a/src/ausf/sbi-path.c b/src/ausf/sbi-path.c index c30190833..a483c48cc 100644 --- a/src/ausf/sbi-path.c +++ b/src/ausf/sbi-path.c @@ -128,8 +128,9 @@ void ausf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type, ogs_assert(stream); ogs_assert(build); - xact = ogs_sbi_xact_add(target_nf_type, &ausf_ue->sbi, data, - (ogs_sbi_build_f)build, ausf_timer_sbi_client_wait_expire); + xact = ogs_sbi_xact_add(target_nf_type, &ausf_ue->sbi, + (ogs_sbi_build_f)build, ausf_ue, data, + ausf_timer_sbi_client_wait_expire); ogs_assert(xact); xact->assoc_stream = stream; diff --git a/src/mme/mme-context.c b/src/mme/mme-context.c index 5f69493be..797542fc6 100644 --- a/src/mme/mme-context.c +++ b/src/mme/mme-context.c @@ -1481,7 +1481,7 @@ int mme_context_parse_config() v = ogs_yaml_iter_value(&e_cell_id_iter); if (v) { e_cell_id[num_of_e_cell_id] - = ogs_uint28_from_string((char*)v); + = ogs_uint64_from_string((char*)v); num_of_e_cell_id++; } } while ( diff --git a/src/mme/mme-fd-path.c b/src/mme/mme-fd-path.c index 5fab45e00..54f5f8808 100644 --- a/src/mme/mme-fd-path.c +++ b/src/mme/mme-fd-path.c @@ -933,7 +933,8 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg) } ret = fd_avp_search_avp(avpch3, - ogs_diam_s6a_allocation_retention_priority, &avpch4); + ogs_diam_s6a_allocation_retention_priority, + &avpch4); ogs_assert(ret == 0); if (avpch4) { ret = fd_avp_search_avp(avpch4, @@ -964,7 +965,8 @@ static void mme_s6a_ula_cb(void *data, struct msg **msg) } ret = fd_avp_search_avp(avpch4, - ogs_diam_s6a_pre_emption_vulnerability, &avpch5); + ogs_diam_s6a_pre_emption_vulnerability, + &avpch5); ogs_assert(ret == 0); if (avpch5) { ret = fd_msg_avp_hdr(avpch5, &hdr); diff --git a/src/mme/mme-s11-handler.c b/src/mme/mme-s11-handler.c index ac19d78a3..69ffbe9a0 100644 --- a/src/mme/mme-s11-handler.c +++ b/src/mme/mme-s11-handler.c @@ -473,6 +473,18 @@ void mme_s11_handle_create_bearer_request( bearer->qos.gbr.downlink = bearer_qos.dl_gbr; bearer->qos.gbr.uplink = bearer_qos.ul_gbr; + if (bearer->qos.mbr.downlink || bearer->qos.mbr.uplink || + bearer->qos.gbr.downlink || bearer->qos.gbr.uplink) { + if (bearer->qos.mbr.downlink == 0) + bearer->qos.mbr.downlink = MAX_BIT_RATE; + if (bearer->qos.mbr.uplink == 0) + bearer->qos.mbr.uplink = MAX_BIT_RATE; + if (bearer->qos.gbr.downlink == 0) + bearer->qos.gbr.downlink = MAX_BIT_RATE; + if (bearer->qos.gbr.uplink == 0) + bearer->qos.gbr.uplink = MAX_BIT_RATE; + } + /* Save Bearer TFT */ OGS_TLV_STORE_DATA(&bearer->tft, &req->bearer_contexts.tft); diff --git a/src/mme/s1ap-build.c b/src/mme/s1ap-build.c index 1398daf6c..311573cd9 100644 --- a/src/mme/s1ap-build.c +++ b/src/mme/s1ap-build.c @@ -429,14 +429,10 @@ ogs_pkbuf_t *s1ap_build_initial_context_setup_request( if (bearer->qos.mbr.downlink || bearer->qos.mbr.uplink || bearer->qos.gbr.downlink || bearer->qos.gbr.uplink) { - if (bearer->qos.mbr.downlink == 0) - bearer->qos.mbr.downlink = MAX_BIT_RATE; - if (bearer->qos.mbr.uplink == 0) - bearer->qos.mbr.uplink = MAX_BIT_RATE; - if (bearer->qos.gbr.downlink == 0) - bearer->qos.gbr.downlink = MAX_BIT_RATE; - if (bearer->qos.gbr.uplink == 0) - bearer->qos.gbr.uplink = MAX_BIT_RATE; + ogs_assert(bearer->qos.mbr.downlink); + ogs_assert(bearer->qos.mbr.uplink); + ogs_assert(bearer->qos.gbr.downlink); + ogs_assert(bearer->qos.gbr.uplink); gbrQosInformation = CALLOC(1, sizeof(struct S1AP_GBR_QosInformation)); @@ -938,14 +934,10 @@ ogs_pkbuf_t *s1ap_build_e_rab_setup_request( if (bearer->qos.mbr.downlink || bearer->qos.mbr.uplink || bearer->qos.gbr.downlink || bearer->qos.gbr.uplink) { - if (bearer->qos.mbr.downlink == 0) - bearer->qos.mbr.downlink = MAX_BIT_RATE; - if (bearer->qos.mbr.uplink == 0) - bearer->qos.mbr.uplink = MAX_BIT_RATE; - if (bearer->qos.gbr.downlink == 0) - bearer->qos.gbr.downlink = MAX_BIT_RATE; - if (bearer->qos.gbr.uplink == 0) - bearer->qos.gbr.uplink = MAX_BIT_RATE; + ogs_assert(bearer->qos.mbr.downlink); + ogs_assert(bearer->qos.mbr.uplink); + ogs_assert(bearer->qos.gbr.downlink); + ogs_assert(bearer->qos.gbr.uplink); gbrQosInformation = CALLOC(1, sizeof(S1AP_GBR_QosInformation_t)); asn_uint642INTEGER(&gbrQosInformation->e_RAB_MaximumBitrateDL, @@ -1075,14 +1067,10 @@ ogs_pkbuf_t *s1ap_build_e_rab_modify_request( if (bearer->qos.mbr.downlink || bearer->qos.mbr.uplink || bearer->qos.gbr.downlink || bearer->qos.gbr.uplink) { - if (bearer->qos.mbr.downlink == 0) - bearer->qos.mbr.downlink = MAX_BIT_RATE; - if (bearer->qos.mbr.uplink == 0) - bearer->qos.mbr.uplink = MAX_BIT_RATE; - if (bearer->qos.gbr.downlink == 0) - bearer->qos.gbr.downlink = MAX_BIT_RATE; - if (bearer->qos.gbr.uplink == 0) - bearer->qos.gbr.uplink = MAX_BIT_RATE; + ogs_assert(bearer->qos.mbr.downlink); + ogs_assert(bearer->qos.mbr.uplink); + ogs_assert(bearer->qos.gbr.downlink); + ogs_assert(bearer->qos.gbr.uplink); gbrQosInformation = CALLOC(1, sizeof(S1AP_GBR_QosInformation_t)); @@ -1976,14 +1964,10 @@ ogs_pkbuf_t *s1ap_build_handover_request( if (bearer->qos.mbr.downlink || bearer->qos.mbr.uplink || bearer->qos.gbr.downlink || bearer->qos.gbr.uplink) { - if (bearer->qos.mbr.downlink == 0) - bearer->qos.mbr.downlink = MAX_BIT_RATE; - if (bearer->qos.mbr.uplink == 0) - bearer->qos.mbr.uplink = MAX_BIT_RATE; - if (bearer->qos.gbr.downlink == 0) - bearer->qos.gbr.downlink = MAX_BIT_RATE; - if (bearer->qos.gbr.uplink == 0) - bearer->qos.gbr.uplink = MAX_BIT_RATE; + ogs_assert(bearer->qos.mbr.downlink); + ogs_assert(bearer->qos.mbr.uplink); + ogs_assert(bearer->qos.gbr.downlink); + ogs_assert(bearer->qos.gbr.uplink); gbrQosInformation = CALLOC(1, sizeof(struct S1AP_GBR_QosInformation)); diff --git a/src/pcf/context.c b/src/pcf/context.c index 2d6f4e5c9..b413fac7e 100644 --- a/src/pcf/context.c +++ b/src/pcf/context.c @@ -35,6 +35,7 @@ void pcf_context_init(void) /* Initialize PCF context */ memset(&self, 0, sizeof(pcf_context_t)); + ogs_log_install_domain(&__ogs_dbi_domain, "dbi", ogs_core()->log.level); ogs_log_install_domain(&__pcf_log_domain, "pcf", ogs_core()->log.level); ogs_pool_init(&pcf_ue_pool, ogs_app()->max.ue); @@ -125,8 +126,13 @@ pcf_ue_t *pcf_ue_add(char *supi) ogs_assert(pcf_ue); memset(pcf_ue, 0, sizeof *pcf_ue); + /* SBI Type */ pcf_ue->sbi.type = OGS_SBI_OBJ_UE_TYPE; + /* SBI Features */ + OGS_SBI_FEATURES_SET(pcf_ue->am_policy_control_features, + OGS_SBI_NPCF_AM_POLICY_CONTROL_UE_AMBR_AUTHORIZATION); + pcf_ue->association_id = ogs_msprintf("%d", (int)ogs_pool_index(&pcf_ue_pool, pcf_ue)); ogs_assert(pcf_ue->association_id); @@ -164,6 +170,8 @@ void pcf_ue_remove(pcf_ue_t *pcf_ue) pcf_sess_remove_all(pcf_ue); OpenAPI_policy_association_request_free(pcf_ue->policy_association_request); + if (pcf_ue->subscribed_ue_ambr) + OpenAPI_ambr_free(pcf_ue->subscribed_ue_ambr); ogs_assert(pcf_ue->association_id); ogs_free(pcf_ue->association_id); @@ -210,8 +218,13 @@ pcf_sess_t *pcf_sess_add(pcf_ue_t *pcf_ue, uint8_t psi) ogs_assert(sess); memset(sess, 0, sizeof *sess); + /* SBI Type */ sess->sbi.type = OGS_SBI_OBJ_SESS_TYPE; + /* SBI Features */ + OGS_SBI_FEATURES_SET(sess->smpolicycontrol_features, + OGS_SBI_NPCF_SMPOLICYCONTROL_DN_AUTHORIZATION); + sess->sm_policy_id = ogs_msprintf("%d", (int)ogs_pool_index(&pcf_sess_pool, sess)); ogs_assert(sess->sm_policy_id); @@ -258,6 +271,11 @@ void pcf_sess_remove(pcf_sess_t *sess) if (sess->notification_uri) ogs_free(sess->notification_uri); + if (sess->subscribed_sess_ambr) + OpenAPI_ambr_free(sess->subscribed_sess_ambr); + if (sess->subscribed_default_qos) + OpenAPI_subscribed_default_qos_free(sess->subscribed_default_qos); + ogs_pool_free(&pcf_sess_pool, sess); } diff --git a/src/pcf/context.h b/src/pcf/context.h index 500218d82..2cf6a51e9 100644 --- a/src/pcf/context.h +++ b/src/pcf/context.h @@ -23,6 +23,7 @@ #include "ogs-app.h" #include "ogs-crypt.h" #include "ogs-sbi.h" +#include "ogs-dbi.h" #include "pcf-sm.h" #include "timer.h" @@ -66,8 +67,6 @@ struct pcf_ue_s { ogs_sbi_object_t sbi; ogs_fsm_t sm; - OpenAPI_policy_association_request_t *policy_association_request; - char *association_id; char *supi; @@ -76,6 +75,11 @@ struct pcf_ue_s { ogs_guami_t guami; OpenAPI_rat_type_e rat_type; + uint64_t am_policy_control_features; /* SBI Features */ + + OpenAPI_policy_association_request_t *policy_association_request; + OpenAPI_ambr_t *subscribed_ue_ambr; + ogs_list_t sess_list; }; @@ -92,8 +96,13 @@ struct pcf_sess_s { char *notification_uri; ogs_s_nssai_t s_nssai; + uint64_t smpolicycontrol_features; /* SBI Features */ + + OpenAPI_ambr_t *subscribed_sess_ambr; + OpenAPI_subscribed_default_qos_t *subscribed_default_qos; + /* Related Context */ - pcf_ue_t *pcf_ue; + pcf_ue_t *pcf_ue; }; void pcf_context_init(void); diff --git a/src/pcf/init.c b/src/pcf/init.c index 91e984cb2..660d6c434 100644 --- a/src/pcf/init.c +++ b/src/pcf/init.c @@ -41,6 +41,9 @@ int pcf_initialize() ogs_app()->logger.domain, ogs_app()->logger.level); if (rv != OGS_OK) return rv; + rv = ogs_dbi_init(ogs_app()->db_uri); + if (rv != OGS_OK) return rv; + thread = ogs_thread_create(pcf_main, NULL); if (!thread) return OGS_ERROR; @@ -79,6 +82,8 @@ void pcf_terminate(void) ogs_thread_destroy(thread); ogs_timer_delete(t_termination_holding); + ogs_dbi_final(); + pcf_context_final(); ogs_sbi_context_final(); diff --git a/src/pcf/meson.build b/src/pcf/meson.build index 56bd14254..32da4ff3e 100644 --- a/src/pcf/meson.build +++ b/src/pcf/meson.build @@ -40,15 +40,17 @@ libpcf_sources = files(''' libpcf = static_library('pcf', sources : libpcf_sources, link_with : libipfw, - dependencies : [libapp_dep, - libcrypt_dep, + dependencies : [libcrypt_dep, + libapp_dep, + libdbi_dep, libsbi_dep], install : false) libpcf_dep = declare_dependency( link_with : libpcf, - dependencies : [libapp_dep, - libcrypt_dep, + dependencies : [libcrypt_dep, + libapp_dep, + libdbi_dep, libsbi_dep]) pcf_sources = files(''' diff --git a/src/pcf/nnrf-handler.c b/src/pcf/nnrf-handler.c index b0827c09d..1c6a1fb4f 100644 --- a/src/pcf/nnrf-handler.c +++ b/src/pcf/nnrf-handler.c @@ -242,7 +242,6 @@ void pcf_nnrf_handle_nf_discover( pcf_ue_t *pcf_ue = NULL; pcf_sess_t *sess = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL; - ogs_sbi_stream_t *stream = NULL; OpenAPI_search_result_t *SearchResult = NULL; OpenAPI_lnode_t *node = NULL; @@ -251,8 +250,6 @@ void pcf_nnrf_handle_nf_discover( ogs_assert(xact); sbi_object = xact->sbi_object; ogs_assert(sbi_object); - stream = xact->assoc_stream; - ogs_assert(stream); ogs_assert(recvmsg); SearchResult = recvmsg->SearchResult; diff --git a/src/pcf/npcf-handler.c b/src/pcf/npcf-handler.c index 9b88a7247..c961f8d5c 100644 --- a/src/pcf/npcf-handler.c +++ b/src/pcf/npcf-handler.c @@ -27,6 +27,8 @@ bool pcf_npcf_am_policy_contrtol_handle_create(pcf_ue_t *pcf_ue, OpenAPI_policy_association_request_t *PolicyAssociationRequest = NULL; OpenAPI_guami_t *Guami = NULL; + uint64_t supported_features = 0; + ogs_assert(pcf_ue); ogs_assert(stream); ogs_assert(message); @@ -65,6 +67,10 @@ bool pcf_npcf_am_policy_contrtol_handle_create(pcf_ue_t *pcf_ue, pcf_ue->notification_uri = ogs_strdup( PolicyAssociationRequest->notification_uri); + supported_features = + ogs_uint64_from_string(PolicyAssociationRequest->supp_feat); + pcf_ue->am_policy_control_features &= supported_features; + Guami = PolicyAssociationRequest->guami; if (Guami && Guami->amf_id && Guami->plmn_id && Guami->plmn_id->mnc && Guami->plmn_id->mcc) { @@ -79,6 +85,10 @@ bool pcf_npcf_am_policy_contrtol_handle_create(pcf_ue_t *pcf_ue, pcf_ue->policy_association_request, message->PolicyAssociationRequest); + if (PolicyAssociationRequest->ue_ambr) + pcf_ue->subscribed_ue_ambr = OpenAPI_ambr_copy( + pcf_ue->subscribed_ue_ambr, PolicyAssociationRequest->ue_ambr); + pcf_ue_sbi_discover_and_send(OpenAPI_nf_type_UDR, pcf_ue, stream, NULL, pcf_nudr_dr_build_query_am_data); @@ -88,12 +98,15 @@ bool pcf_npcf_am_policy_contrtol_handle_create(pcf_ue_t *pcf_ue, bool pcf_npcf_smpolicycontrtol_handle_create(pcf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *message) { + int status = 0; char *strerror = NULL; pcf_ue_t *pcf_ue = NULL; OpenAPI_sm_policy_context_data_t *SmPolicyContextData = NULL; OpenAPI_snssai_t *sliceInfo = NULL; + uint64_t supported_features = 0; + ogs_assert(sess); pcf_ue = sess->pcf_ue; ogs_assert(stream); @@ -103,34 +116,40 @@ bool pcf_npcf_smpolicycontrtol_handle_create(pcf_sess_t *sess, if (!SmPolicyContextData) { strerror = ogs_msprintf("[%s:%d] No SmPolicyContextData", pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; goto cleanup; } if (!SmPolicyContextData->supi) { strerror = ogs_msprintf("[%s:%d] No supi", pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; goto cleanup; } if (!SmPolicyContextData->pdu_session_id) { strerror = ogs_msprintf("[%s:%d] No pduSessionId", pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; goto cleanup; } if (!SmPolicyContextData->pdu_session_type) { strerror = ogs_msprintf("[%s:%d] No pduSessionType", pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; goto cleanup; } if (!SmPolicyContextData->dnn) { strerror = ogs_msprintf("[%s:%d] No dnn", pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; goto cleanup; } if (!SmPolicyContextData->notification_uri) { strerror = ogs_msprintf("[%s:%d] No notificationUri", pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; goto cleanup; } @@ -138,9 +157,18 @@ bool pcf_npcf_smpolicycontrtol_handle_create(pcf_sess_t *sess, if (!sliceInfo) { strerror = ogs_msprintf("[%s:%d] No sliceInfo", pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; goto cleanup; } + if (SmPolicyContextData->supp_feat) { + supported_features = + ogs_uint64_from_string(SmPolicyContextData->supp_feat); + sess->smpolicycontrol_features &= supported_features; + } else { + sess->smpolicycontrol_features = 0; + } + sess->pdu_session_type = SmPolicyContextData->pdu_session_type; if (sess->dnn) @@ -154,16 +182,24 @@ bool pcf_npcf_smpolicycontrtol_handle_create(pcf_sess_t *sess, sess->s_nssai.sst = sliceInfo->sst; sess->s_nssai.sd = ogs_s_nssai_sd_from_string(sliceInfo->sd); + if (SmPolicyContextData->subs_sess_ambr) + sess->subscribed_sess_ambr = OpenAPI_ambr_copy( + sess->subscribed_sess_ambr, SmPolicyContextData->subs_sess_ambr); + + if (SmPolicyContextData->subs_def_qos) + sess->subscribed_default_qos = OpenAPI_subscribed_default_qos_copy( + sess->subscribed_default_qos, SmPolicyContextData->subs_def_qos); + pcf_sess_sbi_discover_and_send(OpenAPI_nf_type_UDR, sess, stream, NULL, pcf_nudr_dr_build_query_sm_data); return true; cleanup: + ogs_assert(status); ogs_assert(strerror); ogs_error("%s", strerror); - ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, - message, strerror, NULL); + ogs_sbi_server_send_error(stream, status, message, strerror, NULL); ogs_free(strerror); return false; diff --git a/src/pcf/nudr-handler.c b/src/pcf/nudr-handler.c index 4393410f6..1d36ad545 100644 --- a/src/pcf/nudr-handler.c +++ b/src/pcf/nudr-handler.c @@ -22,6 +22,7 @@ bool pcf_nudr_dr_handle_query_am_data( pcf_ue_t *pcf_ue, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { + int rv, status = 0; char *strerror = NULL; ogs_sbi_server_t *server = NULL; @@ -38,22 +39,79 @@ bool pcf_nudr_dr_handle_query_am_data( SWITCH(recvmsg->h.resource.component[3]) CASE(OGS_SBI_RESOURCE_NAME_AM_DATA) + ogs_subscription_data_t subscription_data; + OpenAPI_policy_association_t PolicyAssociation; + OpenAPI_ambr_t UeAmbr; + OpenAPI_list_t *TriggerList = NULL; if (!recvmsg->AmPolicyData) { strerror = ogs_msprintf("[%s] No AmPolicyData", pcf_ue->supi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; goto cleanup; } if (!pcf_ue->policy_association_request) { strerror = ogs_msprintf("[%s] No PolicyAssociationRequest", pcf_ue->supi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; + goto cleanup; + } + + rv = ogs_dbi_subscription_data(pcf_ue->supi, &subscription_data); + if (rv != OGS_OK) { + strerror = ogs_msprintf("[%s] Cannot find SUPI in DB", + pcf_ue->supi); + status = OGS_SBI_HTTP_STATUS_NOT_FOUND; + goto cleanup; + } + + if (!subscription_data.ambr.uplink && + !subscription_data.ambr.downlink) { + ogs_error("[%s] No UE-AMBR", pcf_ue->supi); + status = OGS_SBI_HTTP_STATUS_NOT_FOUND; goto cleanup; } memset(&PolicyAssociation, 0, sizeof(PolicyAssociation)); PolicyAssociation.request = pcf_ue->policy_association_request; - PolicyAssociation.supp_feat = (char *)""; + PolicyAssociation.supp_feat = + ogs_uint64_to_string(pcf_ue->am_policy_control_features); + ogs_assert(PolicyAssociation.supp_feat); + + TriggerList = OpenAPI_list_create(); + ogs_assert(TriggerList); + + memset(&UeAmbr, 0, sizeof(UeAmbr)); + if (OGS_SBI_FEATURES_IS_SET(pcf_ue->am_policy_control_features, + OGS_SBI_NPCF_AM_POLICY_CONTROL_UE_AMBR_AUTHORIZATION)) { + if (pcf_ue->subscribed_ue_ambr) { + ogs_bitrate_t subscribed_ue_ambr; + + subscribed_ue_ambr.uplink = ogs_sbi_bitrate_from_string( + pcf_ue->subscribed_ue_ambr->uplink); + subscribed_ue_ambr.downlink = ogs_sbi_bitrate_from_string( + pcf_ue->subscribed_ue_ambr->downlink); + + if (((subscribed_ue_ambr.uplink / 1024) != + (subscription_data.ambr.uplink / 1024)) || + ((subscribed_ue_ambr.downlink / 1024) != + (subscription_data.ambr.downlink / 1024))) { + + OpenAPI_list_add(TriggerList, + (void *)OpenAPI_request_trigger_UE_AMBR_CH); + } + + UeAmbr.uplink = ogs_sbi_bitrate_to_string( + subscription_data.ambr.uplink, OGS_SBI_BITRATE_KBPS); + UeAmbr.downlink = ogs_sbi_bitrate_to_string( + subscription_data.ambr.downlink, OGS_SBI_BITRATE_KBPS); + PolicyAssociation.ue_ambr = &UeAmbr; + } + } + + if (TriggerList->count) + PolicyAssociation.triggers = TriggerList; memset(&header, 0, sizeof(header)); header.service.name = @@ -74,6 +132,15 @@ bool pcf_nudr_dr_handle_query_am_data( ogs_free(sendmsg.http.location); + ogs_free(PolicyAssociation.supp_feat); + + OpenAPI_list_free(TriggerList); + + if (UeAmbr.uplink) + ogs_free(UeAmbr.uplink); + if (UeAmbr.downlink) + ogs_free(UeAmbr.downlink); + return true; DEFAULT @@ -83,9 +150,9 @@ bool pcf_nudr_dr_handle_query_am_data( cleanup: ogs_assert(strerror); + ogs_assert(status); ogs_error("%s", strerror); - ogs_sbi_server_send_error( - stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, recvmsg, strerror, NULL); + ogs_sbi_server_send_error(stream, status, recvmsg, strerror, NULL); ogs_free(strerror); return false; @@ -94,6 +161,7 @@ cleanup: bool pcf_nudr_dr_handle_query_sm_data( pcf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg) { + int i, j, rv, status = 0; char *strerror = NULL; pcf_ue_t *pcf_ue = NULL; ogs_sbi_server_t *server = NULL; @@ -102,6 +170,8 @@ bool pcf_nudr_dr_handle_query_sm_data( ogs_sbi_header_t header; ogs_sbi_response_t *response = NULL; + ogs_session_data_t session_data; + ogs_assert(sess); pcf_ue = sess->pcf_ue; ogs_assert(pcf_ue); @@ -111,18 +181,307 @@ bool pcf_nudr_dr_handle_query_sm_data( ogs_assert(recvmsg); + memset(&session_data, 0, sizeof(ogs_session_data_t)); + SWITCH(recvmsg->h.resource.component[3]) CASE(OGS_SBI_RESOURCE_NAME_SM_DATA) + ogs_pdn_t *pdn = NULL; + OpenAPI_sm_policy_decision_t SmPolicyDecision; + OpenAPI_lnode_t *node = NULL, *node2 = NULL; + + OpenAPI_list_t *SessRuleList = NULL; + OpenAPI_map_t *SessRuleMap = NULL; + OpenAPI_session_rule_t *SessionRule = NULL; + + OpenAPI_ambr_t AuthSessAmbr; + OpenAPI_authorized_default_qos_t AuthDefQos; + + OpenAPI_list_t *PccRuleList = NULL; + OpenAPI_map_t *PccRuleMap = NULL; + OpenAPI_pcc_rule_t *PccRule = NULL; + OpenAPI_flow_information_t *FlowInformation = NULL; + + OpenAPI_list_t *QosDecisionList = NULL; + OpenAPI_map_t *QosDecisionMap = NULL; + OpenAPI_qos_data_t *QosData = NULL; + + OpenAPI_list_t *PolicyCtrlReqTriggers = NULL; + if (!recvmsg->SmPolicyData) { strerror = ogs_msprintf("[%s:%d] No SmPolicyData", pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; + goto cleanup; + } + + ogs_assert(pcf_ue->supi); + ogs_assert(sess->dnn); + + rv = ogs_dbi_session_data(pcf_ue->supi, sess->dnn, &session_data); + if (rv != OGS_OK) { + strerror = ogs_msprintf("[%s:%d] Cannot find SUPI in DB", + pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_NOT_FOUND; + goto cleanup; + } + + pdn = &session_data.pdn; + + if (!pdn->qos.qci) { + strerror = ogs_msprintf("[%s:%d] No QCI", pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; + goto cleanup; + } + if (!pdn->qos.arp.priority_level) { + strerror = ogs_msprintf("[%s:%d] No Priority Level", + pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; + goto cleanup; + } + + if (!pdn->ambr.uplink && !pdn->ambr.downlink) { + strerror = ogs_msprintf("[%s:%d] No Session-AMBR", + pcf_ue->supi, sess->psi); + status = OGS_SBI_HTTP_STATUS_BAD_REQUEST; goto cleanup; } memset(&SmPolicyDecision, 0, sizeof(SmPolicyDecision)); + PolicyCtrlReqTriggers = OpenAPI_list_create(); + ogs_assert(PolicyCtrlReqTriggers); + + /************************************************************** + * Session Rule + *************************************************************/ + SessRuleList = OpenAPI_list_create(); + ogs_assert(SessRuleList); + + SessionRule = ogs_calloc(1, sizeof(*SessionRule)); + ogs_assert(SessionRule); + + /* Only 1 SessionRule is used */ + SessionRule->sess_rule_id = (char *)"1"; + + if (OGS_SBI_FEATURES_IS_SET(sess->smpolicycontrol_features, + OGS_SBI_NPCF_SMPOLICYCONTROL_DN_AUTHORIZATION)) { + if (sess->subscribed_sess_ambr) { + ogs_bitrate_t subscribed_sess_ambr; + + subscribed_sess_ambr.uplink = ogs_sbi_bitrate_from_string( + sess->subscribed_sess_ambr->uplink); + subscribed_sess_ambr.downlink = ogs_sbi_bitrate_from_string( + sess->subscribed_sess_ambr->downlink); + if (((subscribed_sess_ambr.uplink / 1024) != + (pdn->ambr.uplink / 1024)) || + ((subscribed_sess_ambr.downlink / 1024) != + (pdn->ambr.downlink / 1024))) { + + OpenAPI_list_add(PolicyCtrlReqTriggers, + (void *)OpenAPI_policy_control_request_trigger_SE_AMBR_CH); + } + + memset(&AuthSessAmbr, 0, sizeof(AuthSessAmbr)); + AuthSessAmbr.uplink = ogs_sbi_bitrate_to_string( + pdn->ambr.uplink, OGS_SBI_BITRATE_KBPS); + AuthSessAmbr.downlink = ogs_sbi_bitrate_to_string( + pdn->ambr.downlink, OGS_SBI_BITRATE_KBPS); + SessionRule->auth_sess_ambr = &AuthSessAmbr; + } + } + + if (sess->subscribed_default_qos) { + bool triggered = false; + + memset(&AuthDefQos, 0, sizeof(AuthDefQos)); + AuthDefQos.arp = ogs_calloc(1, sizeof(OpenAPI_arp_t)); + ogs_assert(AuthDefQos.arp); + + AuthDefQos._5qi = pdn->qos.qci; + AuthDefQos.priority_level = pdn->qos.arp.priority_level; + + if (pdn->qos.arp.pre_emption_capability == + OGS_PDN_PRE_EMPTION_CAPABILITY_ENABLED) + AuthDefQos.arp->preempt_cap = + OpenAPI_preemption_capability_MAY_PREEMPT; + else + AuthDefQos.arp->preempt_cap = + OpenAPI_preemption_capability_NOT_PREEMPT; + if (pdn->qos.arp.pre_emption_vulnerability == + OGS_PDN_PRE_EMPTION_CAPABILITY_ENABLED) + AuthDefQos.arp->preempt_vuln = + OpenAPI_preemption_vulnerability_PREEMPTABLE; + else + AuthDefQos.arp->preempt_vuln = + OpenAPI_preemption_vulnerability_NOT_PREEMPTABLE; + AuthDefQos.arp->priority_level = pdn->qos.arp.priority_level; + + SessionRule->auth_def_qos = &AuthDefQos; + + if (sess->subscribed_default_qos->_5qi != AuthDefQos._5qi) + triggered = true; + if (sess->subscribed_default_qos->priority_level != + AuthDefQos.priority_level) + triggered = true; + if (sess->subscribed_default_qos->arp) { + if (sess->subscribed_default_qos->arp->priority_level != + AuthDefQos.arp->priority_level) + triggered = true; + if (sess->subscribed_default_qos->arp->preempt_cap != + AuthDefQos.arp->preempt_cap) + triggered = true; + if (sess->subscribed_default_qos->arp->preempt_vuln != + AuthDefQos.arp->preempt_vuln) + triggered = true; + + } + + if (triggered) + OpenAPI_list_add(PolicyCtrlReqTriggers, + (void *)OpenAPI_policy_control_request_trigger_DEF_QOS_CH); + + } + + SessRuleMap = OpenAPI_map_create( + SessionRule->sess_rule_id, SessionRule); + ogs_assert(SessRuleMap); + + OpenAPI_list_add(SessRuleList, SessRuleMap); + + if (SessRuleList->count) + SmPolicyDecision.sess_rules = SessRuleList; + + /************************************************************** + * PCC Rule & QoS Decision + *************************************************************/ + PccRuleList = OpenAPI_list_create(); + ogs_assert(PccRuleList); + + QosDecisionList = OpenAPI_list_create(); + ogs_assert(QosDecisionList); + + for (i = 0; i < session_data.num_of_pcc_rule; i++) { + OpenAPI_list_t *FlowInformationList = NULL; + ogs_pcc_rule_t *pcc_rule = &session_data.pcc_rule[i]; + + ogs_assert(pcc_rule); + + PccRule = ogs_calloc(1, sizeof(*PccRule)); + ogs_assert(PccRule); + QosData = ogs_calloc(1, sizeof(*QosData)); + ogs_assert(QosData); + + /* + * At this point, only 1 QosData is used for PccRule. + * Therefore, QoS ID uses the same value as PCC Rule ID. + */ + PccRule->pcc_rule_id = pcc_rule->id; + QosData->qos_id = pcc_rule->id; + + PccRule->ref_qos_data = OpenAPI_list_create(); + ogs_assert(PccRule->ref_qos_data); + + OpenAPI_list_add(PccRule->ref_qos_data, QosData->qos_id); + + PccRule->precedence = pcc_rule->precedence; + + FlowInformationList = OpenAPI_list_create(); + ogs_assert(FlowInformationList); + + for (j = 0; j < pcc_rule->num_of_flow; j++) { + ogs_flow_t *flow = &pcc_rule->flow[j]; + ogs_assert(flow); + + FlowInformation = ogs_calloc(1, sizeof(*FlowInformation)); + ogs_assert(FlowInformation); + + if (flow->direction == OGS_FLOW_UPLINK_ONLY) + FlowInformation->flow_direction = + OpenAPI_flow_direction_UPLINK; + else if (flow->direction == OGS_FLOW_DOWNLINK_ONLY) + FlowInformation->flow_direction = + OpenAPI_flow_direction_DOWNLINK; + else { + ogs_fatal("Unsupported direction [%d]", flow->direction); + ogs_assert_if_reached(); + } + + ogs_assert(flow->description); + FlowInformation->flow_description = flow->description; + + OpenAPI_list_add(FlowInformationList, FlowInformation); + } + + if (FlowInformationList->count) + PccRule->flow_infos = FlowInformationList; + else + OpenAPI_list_free(FlowInformationList); + + PccRuleMap = OpenAPI_map_create(PccRule->pcc_rule_id, PccRule); + ogs_assert(PccRuleMap); + + OpenAPI_list_add(PccRuleList, PccRuleMap); + + QosData->_5qi = pcc_rule->qos.qci; + QosData->priority_level = pcc_rule->qos.arp.priority_level; + + QosData->arp = ogs_calloc(1, sizeof(OpenAPI_arp_t)); + ogs_assert(QosData->arp); + + if (pcc_rule->qos.arp.pre_emption_capability == + OGS_PDN_PRE_EMPTION_CAPABILITY_ENABLED) + QosData->arp->preempt_cap = + OpenAPI_preemption_capability_MAY_PREEMPT; + else + QosData->arp->preempt_cap = + OpenAPI_preemption_capability_NOT_PREEMPT; + if (pcc_rule->qos.arp.pre_emption_vulnerability == + OGS_PDN_PRE_EMPTION_CAPABILITY_ENABLED) + QosData->arp->preempt_vuln = + OpenAPI_preemption_vulnerability_PREEMPTABLE; + else + QosData->arp->preempt_vuln = + OpenAPI_preemption_vulnerability_NOT_PREEMPTABLE; + QosData->arp->priority_level = pcc_rule->qos.arp.priority_level; + + if (pcc_rule->qos.mbr.uplink) + QosData->maxbr_ul = ogs_sbi_bitrate_to_string( + pcc_rule->qos.mbr.uplink, OGS_SBI_BITRATE_KBPS); + if (pcc_rule->qos.mbr.downlink) + QosData->maxbr_dl = ogs_sbi_bitrate_to_string( + pcc_rule->qos.mbr.downlink, OGS_SBI_BITRATE_KBPS); + + if (pcc_rule->qos.gbr.uplink) + QosData->gbr_ul = ogs_sbi_bitrate_to_string( + pcc_rule->qos.gbr.uplink, OGS_SBI_BITRATE_KBPS); + if (pcc_rule->qos.gbr.downlink) + QosData->gbr_dl = ogs_sbi_bitrate_to_string( + pcc_rule->qos.gbr.downlink, OGS_SBI_BITRATE_KBPS); + + QosDecisionMap = OpenAPI_map_create(QosData->qos_id, QosData); + ogs_assert(QosDecisionMap); + + OpenAPI_list_add(QosDecisionList, QosDecisionMap); + } + + if (PccRuleList->count) + SmPolicyDecision.pcc_rules = PccRuleList; + + if (QosDecisionList->count) + SmPolicyDecision.qos_decs = QosDecisionList; + + /* Policy Control Request Triggers */ + if (PolicyCtrlReqTriggers->count) + SmPolicyDecision.policy_ctrl_req_triggers = PolicyCtrlReqTriggers; + + /* Supported Features */ + if (sess->smpolicycontrol_features) { + SmPolicyDecision.supp_feat = + ogs_uint64_to_string(sess->smpolicycontrol_features); + } + memset(&header, 0, sizeof(header)); header.service.name = (char *)OGS_SBI_SERVICE_NAME_NPCF_SMPOLICYCONTROL; header.api.version = (char *)OGS_SBI_API_V1; @@ -140,6 +499,74 @@ bool pcf_nudr_dr_handle_query_sm_data( ogs_free(sendmsg.http.location); + OpenAPI_list_for_each(SessRuleList, node) { + SessRuleMap = node->data; + if (SessRuleMap) { + SessionRule = SessRuleMap->value; + if (SessionRule) { + if (SessionRule->auth_sess_ambr) { + if (SessionRule->auth_sess_ambr->uplink) + ogs_free(SessionRule->auth_sess_ambr->uplink); + if (SessionRule->auth_sess_ambr->downlink) + ogs_free(SessionRule->auth_sess_ambr->downlink); + } + if (SessionRule->auth_def_qos) { + ogs_free(SessionRule->auth_def_qos->arp); + + } + ogs_free(SessionRule); + } + ogs_free(SessRuleMap); + } + } + OpenAPI_list_free(SessRuleList); + + OpenAPI_list_for_each(PccRuleList, node) { + PccRuleMap = node->data; + if (PccRuleMap) { + PccRule = PccRuleMap->value; + if (PccRule) { + if (PccRule->ref_qos_data) + OpenAPI_list_free(PccRule->ref_qos_data); + if (PccRule->flow_infos) { + OpenAPI_list_for_each(PccRule->flow_infos, node2) { + FlowInformation = node2->data; + if (FlowInformation) ogs_free(FlowInformation); + } + OpenAPI_list_free(PccRule->flow_infos); + } + ogs_free(PccRule); + } + ogs_free(PccRuleMap); + } + } + OpenAPI_list_free(PccRuleList); + + OpenAPI_list_for_each(QosDecisionList, node) { + QosDecisionMap = node->data; + if (QosDecisionMap) { + QosData = QosDecisionMap->value; + if (QosData) { + if (QosData->arp) ogs_free(QosData->arp); + if (QosData->maxbr_ul) ogs_free(QosData->maxbr_ul); + if (QosData->maxbr_dl) ogs_free(QosData->maxbr_dl); + if (QosData->gbr_ul) ogs_free(QosData->gbr_ul); + if (QosData->gbr_dl) ogs_free(QosData->gbr_dl); + + ogs_free(QosData); + } + ogs_free(QosDecisionMap); + } + } + OpenAPI_list_free(QosDecisionList); + + OpenAPI_list_free(PolicyCtrlReqTriggers); + + if (SmPolicyDecision.supp_feat) + ogs_free(SmPolicyDecision.supp_feat); + + ogs_session_data_free(&session_data); + return true; DEFAULT @@ -150,9 +577,10 @@ bool pcf_nudr_dr_handle_query_sm_data( cleanup: ogs_assert(strerror); ogs_error("%s", strerror); - ogs_sbi_server_send_error( - stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, recvmsg, strerror, NULL); + ogs_sbi_server_send_error(stream, status, recvmsg, strerror, NULL); ogs_free(strerror); + ogs_session_data_free(&session_data); + return false; } diff --git a/src/pcf/sbi-path.c b/src/pcf/sbi-path.c index 21a28d7cd..15df1b107 100644 --- a/src/pcf/sbi-path.c +++ b/src/pcf/sbi-path.c @@ -124,8 +124,8 @@ void pcf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact) } static bool pcf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type, - ogs_sbi_object_t *sbi_object, ogs_sbi_stream_t *stream, void *data, - ogs_sbi_build_f build) + ogs_sbi_object_t *sbi_object, ogs_sbi_stream_t *stream, + ogs_sbi_build_f build, void *context, void *data) { ogs_sbi_xact_t *xact = NULL; @@ -134,8 +134,9 @@ static bool pcf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type, ogs_assert(stream); ogs_assert(build); - xact = ogs_sbi_xact_add(target_nf_type, sbi_object, data, - build, pcf_timer_sbi_client_wait_expire); + xact = ogs_sbi_xact_add(target_nf_type, sbi_object, + build, context, data, + pcf_timer_sbi_client_wait_expire); ogs_assert(xact); xact->assoc_stream = stream; @@ -148,9 +149,8 @@ void pcf_ue_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type, pcf_ue_t *pcf_ue, ogs_sbi_stream_t *stream, void *data, ogs_sbi_request_t *(*build)(pcf_ue_t *pcf_ue, void *data)) { - if (pcf_sbi_discover_and_send( - target_nf_type, &pcf_ue->sbi, stream, data, - (ogs_sbi_build_f)build) != true) { + if (pcf_sbi_discover_and_send(target_nf_type, &pcf_ue->sbi, stream, + (ogs_sbi_build_f)build, pcf_ue, data) != true) { ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL, "Cannot discover", pcf_ue->supi); @@ -161,9 +161,8 @@ void pcf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type, pcf_sess_t *sess, ogs_sbi_stream_t *stream, void *data, ogs_sbi_request_t *(*build)(pcf_sess_t *sess, void *data)) { - if (pcf_sbi_discover_and_send( - target_nf_type, &sess->sbi, stream, data, - (ogs_sbi_build_f)build) != true) { + if (pcf_sbi_discover_and_send(target_nf_type, &sess->sbi, stream, + (ogs_sbi_build_f)build, sess, data) != true) { ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL, "Cannot discover", NULL); diff --git a/src/pcrf/pcrf-context.c b/src/pcrf/pcrf-context.c index 69fcb3070..495833092 100644 --- a/src/pcrf/pcrf-context.c +++ b/src/pcrf/pcrf-context.c @@ -262,364 +262,23 @@ int pcrf_context_parse_config(void) return OGS_OK; } -int pcrf_db_init() +int pcrf_db_qos_data( + char *imsi_bcd, char *apn, ogs_session_data_t *session_data) { int rv; - - rv = ogs_mongoc_init(ogs_app()->db_uri); - if (rv != OGS_OK) return rv; - - if (ogs_mongoc()->client && ogs_mongoc()->name) { - self.subscriberCollection = mongoc_client_get_collection( - ogs_mongoc()->client, ogs_mongoc()->name, "subscribers"); - ogs_assert(self.subscriberCollection); - } - - return OGS_OK; -} - -int pcrf_db_final() -{ - if (self.subscriberCollection) { - mongoc_collection_destroy(self.subscriberCollection); - } - - ogs_mongoc_final(); - - return OGS_OK; -} - -int pcrf_db_qos_data(char *imsi_bcd, char *apn, - ogs_diam_gx_message_t *gx_message) -{ - int rv = OGS_OK; - mongoc_cursor_t *cursor = NULL; - bson_t *query = NULL; - bson_t *opts = NULL; - bson_error_t error; - const bson_t *document; - bson_iter_t iter; - bson_iter_t child1_iter, child2_iter, child3_iter; - bson_iter_t child4_iter, child5_iter, child6_iter; - const char *utf8 = NULL; - uint32_t length = 0; + char *supi = NULL; ogs_assert(imsi_bcd); ogs_assert(apn); - ogs_assert(gx_message); + ogs_assert(session_data); ogs_thread_mutex_lock(&self.db_lock); + supi = ogs_msprintf("%s-%s", OGS_ID_SUPI_TYPE_IMSI, imsi_bcd); + ogs_assert(supi); - query = BCON_NEW( - "imsi", BCON_UTF8(imsi_bcd), - "pdn.apn", BCON_UTF8(apn)); -#if MONGOC_MAJOR_VERSION >= 1 && MONGOC_MINOR_VERSION >= 5 - opts = BCON_NEW( - "projection", "{", - "imsi", BCON_INT64(1), - "pdn.$", BCON_INT64(1), - "}" - ); - cursor = mongoc_collection_find_with_opts( - self.subscriberCollection, query, opts, NULL); -#else - opts = BCON_NEW( - "imsi", BCON_INT64(1), - "pdn.$", BCON_INT64(1) - ); - cursor = mongoc_collection_find(self.subscriberCollection, - MONGOC_QUERY_NONE, 0, 0, 0, query, opts, NULL); -#endif - - if (!mongoc_cursor_next(cursor, &document)) { - ogs_error("Cannot find IMSI(%s)+APN(%s) in DB", imsi_bcd, apn); - - rv = OGS_ERROR; - goto out; - } - - if (mongoc_cursor_error(cursor, &error)) { - ogs_error("Cursor Failure: %s", error.message); - - rv = OGS_ERROR; - goto out; - } - - if (!bson_iter_init(&iter, document)) { - ogs_error("bson_iter_init failed in this document"); - - rv = OGS_ERROR; - goto out; - } - - while (bson_iter_next(&iter)) { - const char *key = bson_iter_key(&iter); - if (!strcmp(key, "pdn") && - BSON_ITER_HOLDS_ARRAY(&iter)) { - int pdn_index = 0; - - bson_iter_recurse(&iter, &child1_iter); - while (bson_iter_next(&child1_iter)) { - const char *child1_key = bson_iter_key(&child1_iter); - ogs_pdn_t *pdn = NULL; - - ogs_assert(child1_key); - pdn_index = atoi(child1_key); - ogs_assert(pdn_index == 0); - - pdn = &gx_message->pdn; - bson_iter_recurse(&child1_iter, &child2_iter); - while (bson_iter_next(&child2_iter)) { - const char *child2_key = bson_iter_key(&child2_iter); - if (!strcmp(child2_key, "apn") && - BSON_ITER_HOLDS_UTF8(&child2_iter)) { - utf8 = bson_iter_utf8(&child2_iter, &length); - ogs_cpystrn(pdn->apn, utf8, - ogs_min(length, OGS_MAX_APN_LEN)+1); - } else if (!strcmp(child2_key, "type") && - BSON_ITER_HOLDS_INT32(&child2_iter)) { - pdn->pdn_type = bson_iter_int32(&child2_iter); - } else if (!strcmp(child2_key, "qos") && - BSON_ITER_HOLDS_DOCUMENT(&child2_iter)) { - bson_iter_recurse(&child2_iter, &child3_iter); - while (bson_iter_next(&child3_iter)) { - const char *child3_key = - bson_iter_key(&child3_iter); - if (!strcmp(child3_key, "qci") && - BSON_ITER_HOLDS_INT32(&child3_iter)) { - pdn->qos.qci = bson_iter_int32(&child3_iter); - } else if (!strcmp(child3_key, "arp") && - BSON_ITER_HOLDS_DOCUMENT(&child3_iter)) { - bson_iter_recurse(&child3_iter, &child4_iter); - while (bson_iter_next(&child4_iter)) { - const char *child4_key = - bson_iter_key(&child4_iter); - if (!strcmp(child4_key, "priority_level") && - BSON_ITER_HOLDS_INT32(&child4_iter)) { - pdn->qos.arp.priority_level = - bson_iter_int32(&child4_iter); - } else if (!strcmp(child4_key, - "pre_emption_capability") && - BSON_ITER_HOLDS_INT32(&child4_iter)) { - pdn->qos.arp.pre_emption_capability = - bson_iter_int32(&child4_iter); - } else if (!strcmp(child4_key, - "pre_emption_vulnerability") && - BSON_ITER_HOLDS_INT32(&child4_iter)) { - pdn->qos.arp.pre_emption_vulnerability = - bson_iter_int32(&child4_iter); - } - } - } - } - } else if (!strcmp(child2_key, "ambr") && - BSON_ITER_HOLDS_DOCUMENT(&child2_iter)) { - bson_iter_recurse(&child2_iter, &child3_iter); - while (bson_iter_next(&child3_iter)) { - const char *child3_key = - bson_iter_key(&child3_iter); - if (!strcmp(child3_key, "uplink") && - BSON_ITER_HOLDS_INT64(&child3_iter)) { - pdn->ambr.uplink = - bson_iter_int64(&child3_iter) * 1024; - } else if (!strcmp(child3_key, "downlink") && - BSON_ITER_HOLDS_INT64(&child3_iter)) { - pdn->ambr.downlink = - bson_iter_int64(&child3_iter) * 1024; - } - } - } else if (!strcmp(child2_key, "pcc_rule") && - BSON_ITER_HOLDS_ARRAY(&child2_iter)) { - int pcc_rule_index = 0; - - bson_iter_recurse(&child2_iter, &child3_iter); - while (bson_iter_next(&child3_iter)) { - const char *child3_key = - bson_iter_key(&child3_iter); - ogs_pcc_rule_t *pcc_rule = NULL; - - ogs_assert(child3_key); - pcc_rule_index = atoi(child3_key); - ogs_assert(pcc_rule_index < - OGS_MAX_NUM_OF_PCC_RULE); - - pcc_rule = &gx_message->pcc_rule[pcc_rule_index]; - bson_iter_recurse(&child3_iter, &child4_iter); - while (bson_iter_next(&child4_iter)) { - const char *child4_key = - bson_iter_key(&child4_iter); - - if (!strcmp(child4_key, "qos") && - BSON_ITER_HOLDS_DOCUMENT(&child4_iter)) { - bson_iter_recurse( - &child4_iter, &child5_iter); - while (bson_iter_next(&child5_iter)) { - const char *child5_key = - bson_iter_key(&child5_iter); - if (!strcmp(child5_key, "qci") && - BSON_ITER_HOLDS_INT32( - &child5_iter)) { - pcc_rule->qos.qci = - bson_iter_int32(&child5_iter); - } else if (!strcmp(child5_key, "arp") && - BSON_ITER_HOLDS_DOCUMENT( - &child5_iter)) { - bson_iter_recurse( - &child5_iter, &child6_iter); - while (bson_iter_next( - &child6_iter)) { - const char *child6_key = - bson_iter_key(&child6_iter); - if (!strcmp(child6_key, - "priority_level") && - BSON_ITER_HOLDS_INT32( - &child6_iter)) { - pcc_rule->qos.arp. - priority_level = - bson_iter_int32( - &child6_iter); - } else if (!strcmp(child6_key, - "pre_emption_capability") && - BSON_ITER_HOLDS_INT32( - &child6_iter)) { - pcc_rule->qos.arp. - pre_emption_capability = - bson_iter_int32( - &child6_iter); - } else if (!strcmp(child6_key, - "pre_emption_vulnerability") - && BSON_ITER_HOLDS_INT32( - &child6_iter)) { - pcc_rule->qos.arp. - pre_emption_vulnerability = - bson_iter_int32( - &child6_iter); - } - } - } else if (!strcmp(child5_key, "mbr") && - BSON_ITER_HOLDS_DOCUMENT( - &child5_iter)) { - bson_iter_recurse( - &child5_iter, &child6_iter); - while (bson_iter_next( - &child6_iter)) { - const char *child6_key = - bson_iter_key(&child6_iter); - if (!strcmp(child6_key, - "downlink") && - BSON_ITER_HOLDS_INT64( - &child6_iter)) { - pcc_rule->qos.mbr.downlink = - bson_iter_int64( - &child6_iter) * 1024; - } else if (!strcmp(child6_key, - "uplink") && - BSON_ITER_HOLDS_INT64( - &child6_iter)) { - pcc_rule->qos.mbr.uplink = - bson_iter_int64( - &child6_iter) * 1024; - } - } - } else if (!strcmp(child5_key, "gbr") && - BSON_ITER_HOLDS_DOCUMENT( - &child5_iter)) { - bson_iter_recurse(&child5_iter, - &child6_iter); - while (bson_iter_next( - &child6_iter)) { - const char *child6_key = - bson_iter_key(&child6_iter); - if (!strcmp(child6_key, - "downlink") && - BSON_ITER_HOLDS_INT64( - &child6_iter)) { - pcc_rule->qos.gbr.downlink = - bson_iter_int64( - &child6_iter) * 1024; - } else if (!strcmp(child6_key, - "uplink") && - BSON_ITER_HOLDS_INT64( - &child6_iter)) { - pcc_rule->qos.gbr.uplink = - bson_iter_int64( - &child6_iter) * 1024; - } - } - } - } - } else if (!strcmp(child4_key, "flow") && - BSON_ITER_HOLDS_ARRAY(&child4_iter)) { - int flow_index = 0; - - bson_iter_recurse(&child4_iter, - &child5_iter); - while (bson_iter_next(&child5_iter)) { - const char *child5_key = - bson_iter_key(&child5_iter); - ogs_flow_t *flow = NULL; - - ogs_assert(child5_key); - flow_index = atoi(child5_key); - ogs_assert( - flow_index < OGS_MAX_NUM_OF_FLOW); - - flow = &pcc_rule->flow[flow_index]; - bson_iter_recurse( - &child5_iter, &child6_iter); - while (bson_iter_next(&child6_iter)) { - const char *child6_key = - bson_iter_key(&child6_iter); - if (!strcmp(child6_key, - "direction") && - BSON_ITER_HOLDS_INT32( - &child6_iter)) { - flow->direction = - bson_iter_int32( - &child6_iter); - } else if (!strcmp(child6_key, - "description") && - BSON_ITER_HOLDS_UTF8( - &child6_iter)) { - utf8 = bson_iter_utf8( - &child6_iter, &length); - flow->description = - ogs_malloc(length+1); - ogs_cpystrn( - (char*)flow->description, - utf8, length+1); - } - } - flow_index++; - } - pcc_rule->num_of_flow = flow_index; - } - } - /* Charing-Rule-Name is automatically configured */ - if (pcc_rule->name) { - ogs_error("PCC Rule Name has already " - "been defined"); - ogs_free(pcc_rule->name); - } - pcc_rule->name = ogs_msprintf( - "%s%d", apn, pcc_rule_index+1); - ogs_assert(pcc_rule->name); - pcc_rule->precedence = pcc_rule_index+1; - pcc_rule->flow_status = OGS_FLOW_STATUS_ENABLED; - pcc_rule_index++; - } - gx_message->num_of_pcc_rule = pcc_rule_index; - } - } - } - } - } - -out: - if (query) bson_destroy(query); - if (opts) bson_destroy(opts); - if (cursor) mongoc_cursor_destroy(cursor); + rv = ogs_dbi_session_data(supi, apn, session_data); + ogs_free(supi); ogs_thread_mutex_unlock(&self.db_lock); return rv; diff --git a/src/pcrf/pcrf-context.h b/src/pcrf/pcrf-context.h index fbfe8a9dd..1a0feca3f 100644 --- a/src/pcrf/pcrf-context.h +++ b/src/pcrf/pcrf-context.h @@ -22,6 +22,7 @@ #include "ogs-diameter-gx.h" #include "ogs-diameter-rx.h" +#include "ogs-dbi.h" #include "ogs-app.h" #ifdef __cplusplus @@ -40,7 +41,6 @@ typedef struct pcrf_context_s { const char *diam_conf_path; /* PCRF Diameter conf path */ ogs_diam_config_t *diam_config; /* PCRF Diameter config */ - void *subscriberCollection; ogs_thread_mutex_t db_lock; ogs_hash_t *ip_hash; /* hash table for Gx Frame IPv4/IPv6 */ @@ -53,11 +53,8 @@ pcrf_context_t *pcrf_self(void); int pcrf_context_parse_config(void); -int pcrf_db_init(void); -int pcrf_db_final(void); - int pcrf_db_qos_data(char *imsi_bcd, char *apn, - ogs_diam_gx_message_t *gx_message); + ogs_session_data_t *session_data); int pcrf_sess_set_ipv4(const void *key, uint8_t *sid); int pcrf_sess_set_ipv6(const void *key, uint8_t *sid); diff --git a/src/pcrf/pcrf-gx-path.c b/src/pcrf/pcrf-gx-path.c index 672b9248b..4b845e96b 100644 --- a/src/pcrf/pcrf-gx-path.c +++ b/src/pcrf/pcrf-gx-path.c @@ -420,7 +420,8 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, } /* Retrieve QoS Data from Database */ - rv = pcrf_db_qos_data(sess_data->imsi_bcd, sess_data->apn, &gx_message); + rv = pcrf_db_qos_data( + sess_data->imsi_bcd, sess_data->apn, &gx_message.session_data); if (rv != OGS_OK) { ogs_error("Cannot get data for IMSI(%s)+APN(%s)'", sess_data->imsi_bcd, sess_data->apn); @@ -432,8 +433,8 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, cc_request_type == OGS_DIAM_GX_CC_REQUEST_TYPE_UPDATE_REQUEST) { int charging_rule = 0; - for (i = 0; i < gx_message.num_of_pcc_rule; i++) { - ogs_pcc_rule_t *pcc_rule = &gx_message.pcc_rule[i]; + for (i = 0; i < gx_message.session_data.num_of_pcc_rule; i++) { + ogs_pcc_rule_t *pcc_rule = &gx_message.session_data.pcc_rule[i]; if (pcc_rule->num_of_flow) { if (charging_rule == 0) { ret = fd_msg_avp_new( @@ -454,26 +455,27 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, } /* Set QoS-Information */ - if (gx_message.pdn.ambr.downlink || gx_message.pdn.ambr.uplink) { + if (gx_message.session_data.pdn.ambr.downlink || + gx_message.session_data.pdn.ambr.uplink) { ret = fd_msg_avp_new(ogs_diam_gx_qos_information, 0, &avp); ogs_assert(ret == 0); - if (gx_message.pdn.ambr.uplink) { + if (gx_message.session_data.pdn.ambr.uplink) { ret = fd_msg_avp_new( ogs_diam_gx_apn_aggregate_max_bitrate_ul, 0, &avpch1); ogs_assert(ret == 0); - val.u32 = gx_message.pdn.ambr.uplink; + val.u32 = gx_message.session_data.pdn.ambr.uplink; ret = fd_msg_avp_setvalue (avpch1, &val); ogs_assert(ret == 0); ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1); ogs_assert(ret == 0); } - if (gx_message.pdn.ambr.downlink) { + if (gx_message.session_data.pdn.ambr.downlink) { ret = fd_msg_avp_new( ogs_diam_gx_apn_aggregate_max_bitrate_dl, 0, &avpch1); ogs_assert(ret == 0); - val.u32 = gx_message.pdn.ambr.downlink; + val.u32 = gx_message.session_data.pdn.ambr.downlink; ret = fd_msg_avp_setvalue (avpch1, &val); ogs_assert(ret == 0); ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1); @@ -490,7 +492,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, ret = fd_msg_avp_new(ogs_diam_gx_qos_class_identifier, 0, &avpch1); ogs_assert(ret == 0); - val.u32 = gx_message.pdn.qos.qci; + val.u32 = gx_message.session_data.pdn.qos.qci; ret = fd_msg_avp_setvalue (avpch1, &val); ogs_assert(ret == 0); ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1); @@ -502,7 +504,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, ret = fd_msg_avp_new(ogs_diam_gx_priority_level, 0, &avpch2); ogs_assert(ret == 0); - val.u32 = gx_message.pdn.qos.arp.priority_level; + val.u32 = gx_message.session_data.pdn.qos.arp.priority_level; ret = fd_msg_avp_setvalue (avpch2, &val); ogs_assert(ret == 0); ret = fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2); @@ -510,7 +512,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, ret = fd_msg_avp_new(ogs_diam_gx_pre_emption_capability, 0, &avpch2); ogs_assert(ret == 0); - val.u32 = gx_message.pdn.qos.arp.pre_emption_capability; + val.u32 = gx_message.session_data.pdn.qos.arp.pre_emption_capability; ret = fd_msg_avp_setvalue (avpch2, &val); ogs_assert(ret == 0); ret = fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2); @@ -518,7 +520,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, ret = fd_msg_avp_new(ogs_diam_gx_pre_emption_vulnerability, 0, &avpch2); ogs_assert(ret == 0); - val.u32 = gx_message.pdn.qos.arp.pre_emption_vulnerability; + val.u32 = gx_message.session_data.pdn.qos.arp.pre_emption_vulnerability; ret = fd_msg_avp_setvalue (avpch2, &val); ogs_assert(ret == 0); ret = fd_msg_avp_add (avpch1, MSG_BRW_LAST_CHILD, avpch2); @@ -589,7 +591,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, ogs_diam_logger_self()->stats.nb_echoed++; ogs_assert(pthread_mutex_unlock(&ogs_diam_logger_self()->stats_lock) ==0); - ogs_diam_gx_message_free(&gx_message); + ogs_session_data_free(&gx_message.session_data); return 0; @@ -626,7 +628,7 @@ out: ret = fd_msg_send(msg, NULL, NULL); ogs_assert(ret == 0); - ogs_diam_gx_message_free(&gx_message); + ogs_session_data_free(&gx_message.session_data); return 0; } @@ -712,7 +714,8 @@ int pcrf_gx_send_rar( } /* Retrieve QoS Data from Database */ - rv = pcrf_db_qos_data(sess_data->imsi_bcd, sess_data->apn, &gx_message); + rv = pcrf_db_qos_data( + sess_data->imsi_bcd, sess_data->apn, &gx_message.session_data); if (rv != OGS_OK) { ogs_error("Cannot get data for IMSI(%s)+APN(%s)'", sess_data->imsi_bcd, sess_data->apn); @@ -751,9 +754,9 @@ int pcrf_gx_send_rar( goto out; } - for (j = 0; j < gx_message.num_of_pcc_rule; j++) { - if (gx_message.pcc_rule[j].qos.qci == qci) { - db_pcc_rule = &gx_message.pcc_rule[j]; + for (j = 0; j < gx_message.session_data.num_of_pcc_rule; j++) { + if (gx_message.session_data.pcc_rule[j].qos.qci == qci) { + db_pcc_rule = &gx_message.session_data.pcc_rule[j]; break; } } @@ -764,12 +767,12 @@ int pcrf_gx_send_rar( * Check for default bearer for IMS signalling * QCI 5 and ARP 1 */ - if (gx_message.pdn.qos.qci != OGS_PDN_QCI_5 || - gx_message.pdn.qos.arp.priority_level != 1) { + if (gx_message.session_data.pdn.qos.qci != OGS_PDN_QCI_5 || + gx_message.session_data.pdn.qos.arp.priority_level != 1) { ogs_error("CHECK WEBUI : Even the Default " "Bearer(QCI:%d,ARP:%d) cannot support IMS signalling.", - gx_message.pdn.qos.qci, - gx_message.pdn.qos.arp.priority_level); + gx_message.session_data.pdn.qos.qci, + gx_message.session_data.pdn.qos.arp.priority_level); rx_message->result_code = OGS_DIAM_RX_DIAMETER_REQUESTED_SERVICE_NOT_AUTHORIZED; goto out; @@ -982,7 +985,7 @@ int pcrf_gx_send_rar( /* Set no error */ rx_message->result_code = ER_DIAMETER_SUCCESS; - ogs_diam_gx_message_free(&gx_message); + ogs_session_data_free(&gx_message.session_data); return OGS_OK; @@ -991,7 +994,7 @@ out: ret = fd_sess_state_store(pcrf_gx_reg, session, &sess_data); ogs_assert(sess_data == NULL); - ogs_diam_gx_message_free(&gx_message); + ogs_session_data_free(&gx_message.session_data); return OGS_ERROR; } diff --git a/src/pcrf/pcrf-init.c b/src/pcrf/pcrf-init.c index e9942904f..5971ea60e 100644 --- a/src/pcrf/pcrf-init.c +++ b/src/pcrf/pcrf-init.c @@ -35,7 +35,7 @@ int pcrf_initialize(void) ogs_app()->logger.domain, ogs_app()->logger.level); if (rv != OGS_OK) return rv; - rv = pcrf_db_init(); + rv = ogs_dbi_init(ogs_app()->db_uri); if (rv != OGS_OK) return rv; rv = pcrf_fd_init(); @@ -52,7 +52,7 @@ void pcrf_terminate(void) pcrf_fd_final(); - pcrf_db_final(); + ogs_dbi_final(); pcrf_context_final(); return; diff --git a/src/smf/bearer-binding.c b/src/smf/binding.c similarity index 54% rename from src/smf/bearer-binding.c rename to src/smf/binding.c index 85e45bf74..e6761bb80 100644 --- a/src/smf/bearer-binding.c +++ b/src/smf/binding.c @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -#include "bearer-binding.h" +#include "binding.h" #include "s5c-build.h" #include "pfcp-path.h" @@ -73,7 +73,7 @@ static void bearer_timeout(ogs_gtp_xact_t *xact, void *data) static void encode_traffic_flow_template( ogs_gtp_tft_t *tft, smf_bearer_t *bearer) { - int i, j, len; + int i; smf_pf_t *pf = NULL; ogs_assert(tft); @@ -89,121 +89,9 @@ static void encode_traffic_flow_template( tft->pf[i].identifier = pf->identifier - 1; tft->pf[i].precedence = i+1; - j = 0, len = 0; - if (pf->ipfw_rule.proto) { - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE; - tft->pf[i].component[j].proto = pf->ipfw_rule.proto; - j++; len += 2; - } + ogs_pf_content_from_ipfw_rule( + pf->direction, &tft->pf[i].content, &pf->ipfw_rule); - if (pf->ipfw_rule.ipv4_src) { - if (pf->direction == OGS_FLOW_DOWNLINK_ONLY) - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; - else - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; - tft->pf[i].component[j].ipv4.addr = pf->ipfw_rule.ip.src.addr[0]; - tft->pf[i].component[j].ipv4.mask = pf->ipfw_rule.ip.src.mask[0]; - j++; len += 9; - } - - if (pf->ipfw_rule.ipv4_dst) { - if (pf->direction == OGS_FLOW_DOWNLINK_ONLY) - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; - else - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; - - tft->pf[i].component[j].ipv4.addr = pf->ipfw_rule.ip.dst.addr[0]; - tft->pf[i].component[j].ipv4.mask = pf->ipfw_rule.ip.dst.mask[0]; - j++; len += 9; - } - - if (pf->ipfw_rule.ipv6_src) { - if (pf->direction == OGS_FLOW_DOWNLINK_ONLY) - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE; - else - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE; - memcpy(tft->pf[i].component[j].ipv6.addr, - pf->ipfw_rule.ip.src.addr, - sizeof pf->ipfw_rule.ip.src.addr); - tft->pf[i].component[j].ipv6.prefixlen = - contigmask((uint8_t *)pf->ipfw_rule.ip.src.mask, 128); - j++; len += 18; - } - - if (pf->ipfw_rule.ipv6_dst) { - if (pf->direction == OGS_FLOW_DOWNLINK_ONLY) - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE; - else - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE; - memcpy(tft->pf[i].component[j].ipv6.addr, - pf->ipfw_rule.ip.dst.addr, - sizeof pf->ipfw_rule.ip.dst.addr); - tft->pf[i].component[j].ipv6.prefixlen = - contigmask((uint8_t *)pf->ipfw_rule.ip.dst.mask, 128); - j++; len += 18; - } - - if (pf->ipfw_rule.port.src.low) { - if (pf->ipfw_rule.port.src.low == pf->ipfw_rule.port.src.high) { - if (pf->direction == OGS_FLOW_DOWNLINK_ONLY) - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE; - else - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE; - tft->pf[i].component[j].port.low = pf->ipfw_rule.port.src.low; - j++; len += 3; - } else { - if (pf->direction == OGS_FLOW_DOWNLINK_ONLY) - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE; - else - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE; - tft->pf[i].component[j].port.low = pf->ipfw_rule.port.src.low; - tft->pf[i].component[j].port.high = - pf->ipfw_rule.port.src.high; - j++; len += 5; - } - } - - if (pf->ipfw_rule.port.dst.low) { - if (pf->ipfw_rule.port.dst.low == pf->ipfw_rule.port.dst.high) { - if (pf->direction == OGS_FLOW_DOWNLINK_ONLY) - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE; - else - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE; - tft->pf[i].component[j].port.low = - pf->ipfw_rule.port.dst.low; - j++; len += 3; - } else { - if (pf->direction == OGS_FLOW_DOWNLINK_ONLY) - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE; - else - tft->pf[i].component[j].type = - GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE; - tft->pf[i].component[j].port.low = - pf->ipfw_rule.port.dst.low; - tft->pf[i].component[j].port.high = - pf->ipfw_rule.port.dst.high; - j++; len += 5; - } - } - - tft->pf[i].num_of_component = j; - tft->pf[i].length = len; i++; pf = smf_pf_next(pf); @@ -259,15 +147,15 @@ void smf_bearer_binding(smf_sess_t *sess) bearer->dl_pdr->precedence = bearer->dl_pdr->id; bearer->ul_pdr->precedence = bearer->ul_pdr->id; - bearer->name = ogs_strdup(pcc_rule->name); - ogs_assert(bearer->name); + bearer->pcc_rule.name = ogs_strdup(pcc_rule->name); + ogs_assert(bearer->pcc_rule.name); memcpy(&bearer->qos, &pcc_rule->qos, sizeof(ogs_qos_t)); bearer_created = 1; } else { - ogs_assert(strcmp(bearer->name, pcc_rule->name) == 0); + ogs_assert(strcmp(bearer->pcc_rule.name, pcc_rule->name) == 0); if (pcc_rule->num_of_flow) { /* We'll use always 'Create new TFT'. @@ -324,7 +212,7 @@ void smf_bearer_binding(smf_sess_t *sess) flow->direction); } - pf = smf_pf_add(bearer, pcc_rule->precedence); + pf = smf_pf_add(bearer); ogs_assert(pf); pf->direction = flow->direction; @@ -414,7 +302,7 @@ void smf_bearer_binding(smf_sess_t *sess) } } else if (pcc_rule->type == OGS_PCC_RULE_TYPE_REMOVE) { - bearer = smf_bearer_find_by_name(sess, pcc_rule->name); + bearer = smf_bearer_find_by_pcc_rule_name(sess, pcc_rule->name); if (!bearer) { ogs_warn("No need to send 'Delete Bearer Request'"); @@ -474,3 +362,262 @@ void smf_gtp_send_create_bearer_request(smf_bearer_t *bearer) rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); } + +void smf_qos_flow_binding(smf_sess_t *sess, ogs_sbi_stream_t *stream) +{ + int rv; + int i, j; + + ogs_assert(sess); + + for (i = 0; i < sess->num_of_pcc_rule; i++) { +#if 0 + ogs_gtp_header_t h; + ogs_pkbuf_t *pkbuf = NULL; +#endif + smf_bearer_t *qos_flow = NULL; + + ogs_pcc_rule_t *pcc_rule = &sess->pcc_rule[i]; + int qos_flow_created = 0; + int qos_presence = 0; + + ogs_assert(pcc_rule); + if (pcc_rule->id == NULL) { + ogs_error("No PCC Rule Id"); + continue; + } + + if (pcc_rule->type == OGS_PCC_RULE_TYPE_INSTALL) { + ogs_pfcp_pdr_t *dl_pdr = NULL, *ul_pdr = NULL; + + qos_flow = smf_bearer_find_by_qci_arp(sess, + pcc_rule->qos.qci, + pcc_rule->qos.arp.priority_level, + pcc_rule->qos.arp.pre_emption_capability, + pcc_rule->qos.arp.pre_emption_vulnerability); + if (!qos_flow) { + if (pcc_rule->num_of_flow == 0) { + /* TFT is mandatory in + * activate dedicated EPS bearer context request */ + ogs_error("No flow in PCC Rule"); + continue; + } + + qos_flow = smf_qos_flow_add(sess); + ogs_assert(qos_flow); + + dl_pdr = qos_flow->dl_pdr; + ogs_assert(dl_pdr); + ul_pdr = qos_flow->ul_pdr; + ogs_assert(ul_pdr); + + /* Precedence is derived from PCC Rule Precedence */ + dl_pdr->precedence = pcc_rule->precedence; + ul_pdr->precedence = pcc_rule->precedence; + + /* Set UPF-N3 TEID & ADDR to the UL PDR */ + ogs_assert(sess->pfcp_node); + if (sess->pfcp_node->up_function_features.ftup) { + ul_pdr->f_teid.ch = 1; + ul_pdr->f_teid.chid = 1; + ul_pdr->f_teid.choose_id = OGS_PFCP_DEFAULT_CHOOSE_ID; + ul_pdr->f_teid_len = 2; + } else { + ogs_assert(sess->upf_n3_addr || sess->upf_n3_addr6); + ogs_pfcp_sockaddr_to_f_teid( + sess->upf_n3_addr, sess->upf_n3_addr6, + &ul_pdr->f_teid, &ul_pdr->f_teid_len); + ul_pdr->f_teid.teid = sess->upf_n3_teid; + } + + qos_flow->pcc_rule.id = ogs_strdup(pcc_rule->id); + ogs_assert(qos_flow->pcc_rule.id); + + memcpy(&qos_flow->qos, &pcc_rule->qos, sizeof(ogs_qos_t)); + + qos_flow_created = 1; + + } else { + ogs_assert(strcmp(qos_flow->pcc_rule.id, pcc_rule->id) == 0); + + if (pcc_rule->num_of_flow) { + /* We'll use always 'Create new TFT'. + * Therefore, all previous flows are removed + * and replaced by the new flow */ + smf_pf_remove_all(qos_flow); + } + + if ((pcc_rule->qos.mbr.downlink && + qos_flow->qos.mbr.downlink != pcc_rule->qos.mbr.downlink) || + (pcc_rule->qos.mbr.uplink && + qos_flow->qos.mbr.uplink != pcc_rule->qos.mbr.uplink) || + (pcc_rule->qos.gbr.downlink && + qos_flow->qos.gbr.downlink != pcc_rule->qos.gbr.downlink) || + (pcc_rule->qos.gbr.uplink && + qos_flow->qos.gbr.uplink != pcc_rule->qos.gbr.uplink)) { + /* Update QoS parameter */ + memcpy(&qos_flow->qos, &pcc_rule->qos, sizeof(ogs_qos_t)); + + /* Update Bearer Request encodes updated QoS parameter */ + qos_presence = 1; + } + + if (pcc_rule->num_of_flow == 0 && qos_presence == 0) { + ogs_warn("No need to send 'Session Modification Request'"); + ogs_warn(" - Both QoS and TFT are same as before"); + continue; + } + } + + dl_pdr = qos_flow->dl_pdr; + ogs_assert(dl_pdr); + ul_pdr = qos_flow->ul_pdr; + ogs_assert(ul_pdr); + + dl_pdr->num_of_flow = 0; + ul_pdr->num_of_flow = 0; + + for (j = 0; j < pcc_rule->num_of_flow; j++) { + ogs_flow_t *flow = &pcc_rule->flow[j]; + smf_pf_t *pf = NULL; + + ogs_expect_or_return(flow); + ogs_expect_or_return(flow->description); + + if (flow->direction == OGS_FLOW_DOWNLINK_ONLY) { + dl_pdr->flow_description[dl_pdr->num_of_flow++] = + flow->description; + } else if (flow->direction == OGS_FLOW_UPLINK_ONLY) { + ul_pdr->flow_description[ul_pdr->num_of_flow++] = + flow->description; + } else { + ogs_error("Flow Bidirectional is not supported[%d]", + flow->direction); + } + + pf = smf_pf_add(qos_flow); + ogs_assert(pf); + + pf->direction = flow->direction; + pf->flow_description = ogs_strdup(flow->description); + + rv = ogs_ipfw_compile_rule( + &pf->ipfw_rule, pf->flow_description); +/* + * Refer to lib/ipfw/ogs-ipfw.h + * Issue #338 + * + * + * GX : permit out from to + * --> + * RULE : Source Destination + * + * + * GX : permit out from to + * --> + * RULE : Source Destination + */ + if (flow->direction == OGS_FLOW_UPLINK_ONLY) + ogs_ipfw_rule_swap(&pf->ipfw_rule); + + if (rv != OGS_OK) { + ogs_error("Invalid Flow-Description[%s]", + pf->flow_description); + smf_pf_remove(pf); + break; + } + } + + if (qos_flow_created == 1) { + /* Setup QER */ + if (qos_flow->qos.mbr.downlink || qos_flow->qos.mbr.uplink || + qos_flow->qos.gbr.downlink || qos_flow->qos.gbr.uplink) { + ogs_pfcp_qer_t *qer = NULL; + + /* Only 1 QER is used per qos_flow */ + qer = qos_flow->qer; + if (!qer) { + qer = ogs_pfcp_qer_add(&sess->pfcp); + ogs_assert(qer); + qos_flow->qer = qer; + } + + ogs_pfcp_pdr_associate_qer(qos_flow->dl_pdr, qer); + ogs_pfcp_pdr_associate_qer(qos_flow->ul_pdr, qer); + + qer->mbr.uplink = qos_flow->qos.mbr.uplink; + qer->mbr.downlink = qos_flow->qos.mbr.downlink; + qer->gbr.uplink = qos_flow->qos.gbr.uplink; + qer->gbr.downlink = qos_flow->qos.gbr.downlink; + } + + smf_5gc_pfcp_send_qos_flow_modification_request( + qos_flow, NULL, OGS_PFCP_MODIFY_CREATE); + + } else { + ogs_fatal("Update Qos Flow Not Implemented"); + ogs_assert_if_reached(); +#if 0 + ogs_gtp_tft_t tft; + + memset(&tft, 0, sizeof tft); + if (pcc_rule->num_of_flow) + encode_traffic_flow_template(&tft, qos_flow); + + memset(&h, 0, sizeof(ogs_gtp_header_t)); + h.type = OGS_GTP_UPDATE_BEARER_REQUEST_TYPE; + h.teid = sess->sgw_s5c_teid; + + pkbuf = smf_s5c_build_update_qos_flow_request( + h.type, qos_flow, + OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, + pcc_rule->num_of_flow ? &tft : NULL, qos_presence); + ogs_expect_or_return(pkbuf); + + xact = ogs_gtp_xact_local_create( + sess->gnode, &h, pkbuf, qos_flow_timeout, qos_flow); + ogs_expect_or_return(xact); + + if (pcc_rule->num_of_flow) + xact->update_flags |= OGS_GTP_MODIFY_TFT_UPDATE; + if (qos_presence) + xact->update_flags |= OGS_GTP_MODIFY_QOS_UPDATE; + + rv = ogs_gtp_xact_commit(xact); + ogs_expect(rv == OGS_OK); +#endif + } + } else if (pcc_rule->type == OGS_PCC_RULE_TYPE_REMOVE) { + ogs_fatal("Remove Type Not Implemented"); + ogs_assert_if_reached(); +#if 0 + qos_flow = smf_qos_flow_find_by_name(sess, pcc_rule->name); + + if (!qos_flow) { + ogs_warn("No need to send 'Delete Bearer Request'"); + ogs_warn(" - Bearer[Name:%s] has already been removed.", + pcc_rule->name); + continue; + } + + memset(&h, 0, sizeof(ogs_gtp_header_t)); + h.type = OGS_GTP_DELETE_BEARER_REQUEST_TYPE; + h.teid = sess->sgw_s5c_teid; + + pkbuf = smf_s5c_build_delete_qos_flow_request(h.type, qos_flow, + OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED); + ogs_expect_or_return(pkbuf); + + xact = ogs_gtp_xact_local_create( + sess->gnode, &h, pkbuf, qos_flow_timeout, qos_flow); + ogs_expect_or_return(xact); + + rv = ogs_gtp_xact_commit(xact); + ogs_expect(rv == OGS_OK); +#endif + } else { + ogs_error("Invalid Type[%d]", pcc_rule->type); + ogs_assert_if_reached(); + } + } +} diff --git a/src/smf/bearer-binding.h b/src/smf/binding.h similarity index 87% rename from src/smf/bearer-binding.h rename to src/smf/binding.h index 4843754f7..3b28be4df 100644 --- a/src/smf/bearer-binding.h +++ b/src/smf/binding.h @@ -17,8 +17,8 @@ * along with this program. If not, see . */ -#ifndef SMF_BEARER_BINDING_H -#define SMF_BEARER_BINDING_H +#ifndef SMF_BINDING_H +#define SMF_BINDING_H #include "context.h" @@ -29,8 +29,10 @@ extern "C" { void smf_bearer_binding(smf_sess_t *sess); void smf_gtp_send_create_bearer_request(smf_bearer_t *bearer); +void smf_qos_flow_binding(smf_sess_t *sess, ogs_sbi_stream_t *stream); + #ifdef __cplusplus } #endif -#endif /* SMF_BEARER_BINDING_H */ +#endif /* SMF_BINDING_H */ diff --git a/src/smf/context.c b/src/smf/context.c index f1932e861..95c3a7b12 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -831,6 +831,10 @@ smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi) } memset(sess, 0, sizeof *sess); + /* SBI Features */ + OGS_SBI_FEATURES_SET(sess->smpolicycontrol_features, + OGS_SBI_NPCF_SMPOLICYCONTROL_DN_AUTHORIZATION); + ogs_pfcp_pool_init(&sess->pfcp); smf_qfi_pool_init(sess); @@ -1071,6 +1075,9 @@ void smf_sess_remove(smf_sess_t *sess) if (sess->upf_n3_addr6) ogs_freeaddrinfo(sess->upf_n3_addr6); + if (sess->pcf_id) + ogs_free(sess->pcf_id); + /* Free SBI object memory */ ogs_sbi_object_free(&sess->sbi); @@ -1190,6 +1197,8 @@ smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess) ogs_assert(qos_flow); memset(qos_flow, 0, sizeof *qos_flow); + smf_pf_identifier_pool_init(qos_flow); + qos_flow->index = ogs_pool_index(&smf_bearer_pool, qos_flow); ogs_assert(qos_flow->index > 0 && qos_flow->index <= ogs_app()->pool.bearer); @@ -1280,6 +1289,23 @@ smf_bearer_t *smf_qos_flow_find_by_qfi(smf_sess_t *sess, uint8_t qfi) return qos_flow; } +smf_bearer_t *smf_qos_flow_find_by_pcc_rule_id( + smf_sess_t *sess, char *pcc_rule_id) +{ + smf_bearer_t *qos_flow = NULL; + + ogs_assert(sess); + ogs_assert(pcc_rule_id); + + ogs_list_for_each(&sess->bearer_list, qos_flow) { + if (qos_flow->pcc_rule.id && + strcmp(qos_flow->pcc_rule.id, pcc_rule_id) == 0) + return qos_flow; + } + + return NULL; +} + smf_bearer_t *smf_bearer_add(smf_sess_t *sess) { smf_bearer_t *bearer = NULL; @@ -1411,8 +1437,10 @@ int smf_bearer_remove(smf_bearer_t *bearer) if (bearer->qer) ogs_pfcp_qer_remove(bearer->qer); - if (bearer->name) - ogs_free(bearer->name); + if (bearer->pcc_rule.name) + ogs_free(bearer->pcc_rule.name); + if (bearer->pcc_rule.id) + ogs_free(bearer->pcc_rule.id); if (bearer->pgw_s5u_addr) ogs_freeaddrinfo(bearer->pgw_s5u_addr); if (bearer->pgw_s5u_addr6) @@ -1474,15 +1502,17 @@ smf_bearer_t *smf_bearer_find_by_ebi(smf_sess_t *sess, uint8_t ebi) return NULL; } -smf_bearer_t *smf_bearer_find_by_name(smf_sess_t *sess, char *name) +smf_bearer_t *smf_bearer_find_by_pcc_rule_name( + smf_sess_t *sess, char *pcc_rule_name) { smf_bearer_t *bearer = NULL; ogs_assert(sess); - ogs_assert(name); + ogs_assert(pcc_rule_name); ogs_list_for_each(&sess->bearer_list, bearer) { - if (bearer->name && strcmp(bearer->name, name) == 0) + if (bearer->pcc_rule.name && + strcmp(bearer->pcc_rule.name, pcc_rule_name) == 0) return bearer; } @@ -1580,7 +1610,7 @@ smf_bearer_t *smf_bearer_next(smf_bearer_t *bearer) return ogs_list_next(bearer); } -smf_pf_t *smf_pf_add(smf_bearer_t *bearer, uint32_t precedence) +smf_pf_t *smf_pf_add(smf_bearer_t *bearer) { smf_pf_t *pf = NULL; diff --git a/src/smf/context.h b/src/smf/context.h index f8a2d28d6..349884d45 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -171,7 +171,10 @@ typedef struct smf_bearer_s { uint32_t sgw_s5u_teid; /* SGW-S5U TEID */ ogs_ip_t sgw_s5u_ip; /* SGW-S5U IPv4/IPv6 */ - char *name; /* PCC Rule Name */ + struct { + char *name; /* EPC: PCC Rule Name */ + char *id; /* 5GC: PCC Rule Id */ + } pcc_rule; ogs_qos_t qos; /* QoS Infomration */ OGS_POOL(pf_identifier_pool, uint8_t); @@ -192,6 +195,8 @@ typedef struct smf_sess_s { ogs_pfcp_sess_t pfcp; /* PFCP session context */ + uint64_t smpolicycontrol_features; /* SBI features */ + uint32_t smf_n4_teid; /* SMF-N4-TEID is derived from INDEX */ uint32_t sgw_s5c_teid; /* SGW-S5C-TEID is received from SGW */ @@ -235,6 +240,9 @@ typedef struct smf_sess_s { ogs_eps_tai_t e_tai; ogs_e_cgi_t e_cgi; + /* Rat Type */ + OpenAPI_rat_type_e rat_type; + /* NR Location */ ogs_5gs_tai_t nr_tai; ogs_nr_cgi_t nr_cgi; @@ -244,6 +252,9 @@ typedef struct smf_sess_s { ogs_s_nssai_t s_nssai; char *dnn; + /* PCF ID */ + char *pcf_id; + /* Integrity protection maximum data rate */ struct { uint8_t mbr_dl; @@ -326,6 +337,8 @@ smf_sess_t *smf_sess_cycle(smf_sess_t *sess); smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess); smf_bearer_t *smf_qos_flow_find_by_qfi(smf_sess_t *sess, uint8_t qfi); +smf_bearer_t *smf_qos_flow_find_by_pcc_rule_id( + smf_sess_t *sess, char *pcc_rule_id); smf_bearer_t *smf_bearer_add(smf_sess_t *sess); int smf_bearer_remove(smf_bearer_t *bearer); @@ -334,7 +347,8 @@ smf_bearer_t *smf_bearer_find(uint32_t index); smf_bearer_t *smf_bearer_find_by_pgw_s5u_teid( smf_sess_t *sess, uint32_t pgw_s5u_teid); smf_bearer_t *smf_bearer_find_by_ebi(smf_sess_t *sess, uint8_t ebi); -smf_bearer_t *smf_bearer_find_by_name(smf_sess_t *sess, char *name); +smf_bearer_t *smf_bearer_find_by_pcc_rule_name( + smf_sess_t *sess, char *pcc_rule_name); smf_bearer_t *smf_bearer_find_by_qci_arp(smf_sess_t *sess, uint8_t qci, uint8_t priority_level, @@ -347,7 +361,7 @@ bool smf_bearer_is_default(smf_bearer_t *bearer); smf_bearer_t *smf_bearer_first(smf_sess_t *sess); smf_bearer_t *smf_bearer_next(smf_bearer_t *bearer); -smf_pf_t *smf_pf_add(smf_bearer_t *bearer, uint32_t precedence); +smf_pf_t *smf_pf_add(smf_bearer_t *bearer); int smf_pf_remove(smf_pf_t *pf); void smf_pf_remove_all(smf_bearer_t *bearer); smf_pf_t *smf_pf_find_by_id(smf_bearer_t *smf_bearer, uint8_t id); diff --git a/src/smf/event.h b/src/smf/event.h index d99cd1db2..0184767ed 100644 --- a/src/smf/event.h +++ b/src/smf/event.h @@ -81,6 +81,7 @@ typedef struct smf_event_s { ogs_sbi_request_t *request; ogs_sbi_response_t *response; void *data; + int state; ogs_sbi_message_t *message; } sbi; diff --git a/src/smf/fd-path.c b/src/smf/fd-path.c index 211e51acc..b8feebbbd 100644 --- a/src/smf/fd-path.c +++ b/src/smf/fd-path.c @@ -489,6 +489,7 @@ static void smf_gx_cca_cb(void *data, struct msg **msg) smf_event_t *e = NULL; ogs_gtp_xact_t *xact = NULL; smf_sess_t *sess = NULL; + ogs_pcc_rule_t *pcc_rule = NULL; ogs_pkbuf_t *gxbuf = NULL; ogs_diam_gx_message_t *gx_message = NULL; uint16_t gxbuf_len = 0; @@ -626,7 +627,7 @@ static void smf_gx_cca_cb(void *data, struct msg **msg) if (avpch1) { ret = fd_msg_avp_hdr(avpch1, &hdr); ogs_assert(ret == 0); - gx_message->pdn.ambr.uplink = hdr->avp_value->u32; + gx_message->session_data.pdn.ambr.uplink = hdr->avp_value->u32; } ret = fd_avp_search_avp( avp, ogs_diam_gx_apn_aggregate_max_bitrate_dl, &avpch1); @@ -634,7 +635,7 @@ static void smf_gx_cca_cb(void *data, struct msg **msg) if (avpch1) { ret = fd_msg_avp_hdr(avpch1, &hdr); ogs_assert(ret == 0); - gx_message->pdn.ambr.downlink = hdr->avp_value->u32; + gx_message->session_data.pdn.ambr.downlink = hdr->avp_value->u32; } } @@ -646,7 +647,7 @@ static void smf_gx_cca_cb(void *data, struct msg **msg) if (avpch1) { ret = fd_msg_avp_hdr(avpch1, &hdr); ogs_assert(ret == 0); - gx_message->pdn.qos.qci = hdr->avp_value->u32; + gx_message->session_data.pdn.qos.qci = hdr->avp_value->u32; } ret = fd_avp_search_avp( @@ -659,7 +660,8 @@ static void smf_gx_cca_cb(void *data, struct msg **msg) if (avpch2) { ret = fd_msg_avp_hdr(avpch2, &hdr); ogs_assert(ret == 0); - gx_message->pdn.qos.arp.priority_level = hdr->avp_value->u32; + gx_message->session_data.pdn.qos.arp.priority_level = + hdr->avp_value->u32; } ret = fd_avp_search_avp( @@ -668,7 +670,7 @@ static void smf_gx_cca_cb(void *data, struct msg **msg) if (avpch2) { ret = fd_msg_avp_hdr(avpch2, &hdr); ogs_assert(ret == 0); - gx_message->pdn.qos.arp.pre_emption_capability = + gx_message->session_data.pdn.qos.arp.pre_emption_capability = hdr->avp_value->u32; } @@ -678,7 +680,7 @@ static void smf_gx_cca_cb(void *data, struct msg **msg) if (avpch2) { ret = fd_msg_avp_hdr(avpch2, &hdr); ogs_assert(ret == 0); - gx_message->pdn.qos.arp.pre_emption_vulnerability = + gx_message->session_data.pdn.qos.arp.pre_emption_vulnerability = hdr->avp_value->u32; } } @@ -714,18 +716,15 @@ static void smf_gx_cca_cb(void *data, struct msg **msg) ogs_assert(ret == 0); switch (hdr->avp_code) { case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION: - { - ogs_pcc_rule_t *pcc_rule = &gx_message->pcc_rule - [gx_message->num_of_pcc_rule]; + pcc_rule = &gx_message->session_data.pcc_rule + [gx_message->session_data.num_of_pcc_rule]; - rv = decode_pcc_rule_definition( - pcc_rule, avpch1, &error); + rv = decode_pcc_rule_definition(pcc_rule, avpch1, &error); ogs_assert(rv == OGS_OK); pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; - gx_message->num_of_pcc_rule++; + gx_message->session_data.num_of_pcc_rule++; break; - } default: ogs_error("Not supported(%d)", hdr->avp_code); break; @@ -751,14 +750,14 @@ out: rv = ogs_queue_push(ogs_app()->queue, e); if (rv != OGS_OK) { ogs_warn("ogs_queue_push() failed:%d", (int)rv); - ogs_diam_gx_message_free(gx_message); + ogs_session_data_free(&gx_message->session_data); ogs_pkbuf_free(e->pkbuf); smf_event_free(e); } else { ogs_pollset_notify(ogs_app()->pollset); } } else { - ogs_diam_gx_message_free(gx_message); + ogs_session_data_free(&gx_message->session_data); ogs_pkbuf_free(gxbuf); } @@ -846,6 +845,7 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp, ogs_pkbuf_t *gxbuf = NULL; smf_sess_t *sess = NULL; ogs_diam_gx_message_t *gx_message = NULL; + ogs_pcc_rule_t *pcc_rule = NULL; uint32_t result_code = OGS_DIAM_UNKNOWN_SESSION_ID; @@ -900,59 +900,46 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp, case OGS_DIAM_GX_AVP_CODE_RE_AUTH_REQUEST_TYPE: break; case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_INSTALL: - { ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL); ogs_assert(ret == 0); - while(avpch1) - { + while(avpch1) { ret = fd_msg_avp_hdr(avpch1, &hdr); ogs_assert(ret == 0); - switch(hdr->avp_code) - { - case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION: - { - ogs_pcc_rule_t *pcc_rule = &gx_message->pcc_rule - [gx_message->num_of_pcc_rule]; + switch(hdr->avp_code) { + case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION: + pcc_rule = &gx_message->session_data.pcc_rule + [gx_message->session_data.num_of_pcc_rule]; - rv = decode_pcc_rule_definition( - pcc_rule, avpch1, NULL); - ogs_assert(rv == OGS_OK); + rv = decode_pcc_rule_definition(pcc_rule, avpch1, NULL); + ogs_assert(rv == OGS_OK); - pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; - gx_message->num_of_pcc_rule++; - break; - } - default: - { - ogs_error("Not supported(%d)", hdr->avp_code); - break; - } - } - fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL); - } - break; - } - case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_REMOVE: - { - ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL); - ogs_assert(ret == 0); - while (avpch1) { - ret = fd_msg_avp_hdr(avpch1, &hdr); - ogs_assert(ret == 0); - switch (hdr->avp_code) { - case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_NAME: - { - ogs_pcc_rule_t *pcc_rule = &gx_message->pcc_rule - [gx_message->num_of_pcc_rule]; - - pcc_rule->name = - ogs_strdup((char*)hdr->avp_value->os.data); - ogs_assert(pcc_rule->name); - - pcc_rule->type = OGS_PCC_RULE_TYPE_REMOVE; - gx_message->num_of_pcc_rule++; + pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; + gx_message->session_data.num_of_pcc_rule++; + break; + default: + ogs_error("Not supported(%d)", hdr->avp_code); + break; + } + fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL); + } + break; + case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_REMOVE: + ret = fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &avpch1, NULL); + ogs_assert(ret == 0); + while (avpch1) { + ret = fd_msg_avp_hdr(avpch1, &hdr); + ogs_assert(ret == 0); + switch (hdr->avp_code) { + case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_NAME: + pcc_rule = &gx_message->session_data.pcc_rule + [gx_message->session_data.num_of_pcc_rule]; + + pcc_rule->name = ogs_strdup((char*)hdr->avp_value->os.data); + ogs_assert(pcc_rule->name); + + pcc_rule->type = OGS_PCC_RULE_TYPE_REMOVE; + gx_message->session_data.num_of_pcc_rule++; break; - } default: ogs_error("Not supported(%d)", hdr->avp_code); break; @@ -960,7 +947,6 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp, fd_msg_browse(avpch1, MSG_BRW_NEXT, &avpch1, NULL); } break; - } default: ogs_warn("Not supported(%d)", hdr->avp_code); break; @@ -977,7 +963,7 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp, rv = ogs_queue_push(ogs_app()->queue, e); if (rv != OGS_OK) { ogs_warn("ogs_queue_push() failed:%d", (int)rv); - ogs_diam_gx_message_free(gx_message); + ogs_session_data_free(&gx_message->session_data); ogs_pkbuf_free(e->pkbuf); smf_event_free(e); } else { @@ -1033,7 +1019,7 @@ out: ret = fd_msg_send(msg, NULL, NULL); ogs_assert(ret == 0); - ogs_diam_gx_message_free(gx_message); + ogs_session_data_free(&gx_message->session_data); ogs_pkbuf_free(gxbuf); return 0; @@ -1143,6 +1129,8 @@ static int decode_pcc_rule_definition( ret = fd_msg_browse(avpch1, MSG_BRW_FIRST_CHILD, &avpch2, NULL); ogs_assert(ret == 0); while (avpch2) { + ogs_flow_t *flow = NULL; + ret = fd_msg_avp_hdr(avpch2, &hdr); ogs_assert(ret == 0); switch (hdr->avp_code) { @@ -1155,9 +1143,7 @@ static int decode_pcc_rule_definition( ogs_assert(pcc_rule->name); break; case OGS_DIAM_GX_AVP_CODE_FLOW_INFORMATION: - { - ogs_flow_t *flow = - &pcc_rule->flow[pcc_rule->num_of_flow]; + flow = &pcc_rule->flow[pcc_rule->num_of_flow]; ret = fd_avp_search_avp( avpch2, ogs_diam_gx_flow_direction, &avpch3); @@ -1171,8 +1157,7 @@ static int decode_pcc_rule_definition( ret = fd_avp_search_avp( avpch2, ogs_diam_gx_flow_description, &avpch3); ogs_assert(ret == 0); - if (avpch3) - { + if (avpch3) { ret = fd_msg_avp_hdr(avpch3, &hdr); ogs_assert(ret == 0); flow->description = ogs_malloc(hdr->avp_value->os.len+1); @@ -1183,7 +1168,6 @@ static int decode_pcc_rule_definition( pcc_rule->num_of_flow++; break; - } case OGS_DIAM_GX_AVP_CODE_FLOW_STATUS: pcc_rule->flow_status = hdr->avp_value->i32; break; diff --git a/src/smf/gsm-build.c b/src/smf/gsm-build.c index 65bb45820..4089ce865 100644 --- a/src/smf/gsm-build.c +++ b/src/smf/gsm-build.c @@ -26,6 +26,7 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) { ogs_pkbuf_t *pkbuf = NULL; smf_bearer_t *qos_flow = NULL; + int num_of_param; ogs_nas_5gs_message_t message; ogs_nas_5gs_pdu_session_establishment_accept_t * @@ -44,7 +45,8 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) ogs_nas_dnn_t *dnn = NULL; ogs_nas_qos_rule_t qos_rule[OGS_NAS_MAX_NUM_OF_QOS_RULE]; - ogs_nas_qos_flow_description_t qos_flow_description; + ogs_nas_qos_flow_description_t + qos_flow_description[OGS_NAS_MAX_NUM_OF_QOS_FLOW_DESCRIPTION]; uint8_t pco_buf[OGS_MAX_PCO_LEN]; int16_t pco_len; @@ -76,6 +78,7 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) ogs_assert(sess); qos_flow = smf_default_bearer_in_sess(sess); ogs_assert(qos_flow); + ogs_assert(ogs_list_next(qos_flow) == NULL); memset(&message, 0, sizeof(message)); message.gsm.h.extended_protocol_discriminator = @@ -104,17 +107,16 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) * associated with and the RQA should not be sent for this QoS Flow. */ memset(qos_rule, 0, sizeof(qos_rule)); - qos_rule[0].identifier = 1; - qos_rule[0].length = 6; + qos_rule[0].identifier = qos_flow->qfi; /* Use QFI in Open5GS */ qos_rule[0].code = OGS_NAS_QOS_CODE_CREATE_NEW_QOS_RULE; qos_rule[0].DQR_bit = 1; qos_rule[0].num_of_packet_filter = 1; qos_rule[0].pf[0].direction = OGS_NAS_QOS_DIRECTION_UPLINK; - qos_rule[0].pf[0].pf_identifier = 1; - qos_rule[0].pf[0].length = 1; - qos_rule[0].pf[0].num_of_component = 1; - qos_rule[0].pf[0].component[0].type = OGS_PACKET_FILTER_MATCH_ALL; + qos_rule[0].pf[0].identifier = 1; + qos_rule[0].pf[0].content.length = 1; + qos_rule[0].pf[0].content.num_of_component = 1; + qos_rule[0].pf[0].content.component[0].type = OGS_PACKET_FILTER_MATCH_ALL; /* * TS23.501 @@ -130,6 +132,7 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) qos_rule[0].flow.identifier = qos_flow->qfi; ogs_nas_build_qos_rules(authorized_qos_rules, qos_rule, 1); + ogs_assert(authorized_qos_rules->length); /* Session-AMBR */ session_ambr->length = 6; @@ -180,19 +183,26 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) /* QoS flow descriptions */ memset(&qos_flow_description, 0, sizeof(qos_flow_description)); - qos_flow_description.identifier = qos_flow->qfi; - qos_flow_description.code = OGS_NAS_CREATE_NEW_QOS_FLOW_DESCRIPTION; - qos_flow_description.E = 1; - qos_flow_description.num_of_parameter = 1; - qos_flow_description.param[0].identifier = + qos_flow_description[0].identifier = qos_flow->qfi; + qos_flow_description[0].code = OGS_NAS_CREATE_NEW_QOS_FLOW_DESCRIPTION; + qos_flow_description[0].E_bit = 1; + + num_of_param = 0; + + qos_flow_description[0].param[num_of_param].identifier = OGS_NAX_QOS_FLOW_PARAMETER_ID_5QI; - qos_flow_description.param[0].len = 1; - qos_flow_description.param[0].content[0] = sess->pdn.qos.qci; + qos_flow_description[0].param[num_of_param].len = + sizeof(qos_flow_description[0].param[num_of_param].qci); + qos_flow_description[0].param[num_of_param].qci = qos_flow->qos.qci; + num_of_param++; + + qos_flow_description[0].num_of_parameter = num_of_param; pdu_session_establishment_accept->presencemask |= OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_ACCEPT_AUTHORIZED_QOS_FLOW_DESCRIPTIONS_PRESENT; - authorized_qos_flow_descriptions->length = 6; - authorized_qos_flow_descriptions->buffer = &qos_flow_description; + ogs_nas_build_qos_flow_descriptions( + authorized_qos_flow_descriptions, qos_flow_description, 1); + ogs_assert(authorized_qos_flow_descriptions->length); /* Extended protocol configuration options */ if (sess->nas.ue_pco.buffer && sess->nas.ue_pco.length) { @@ -216,6 +226,7 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess) ogs_assert(pkbuf); ogs_free(authorized_qos_rules->buffer); + ogs_free(authorized_qos_flow_descriptions->buffer); return pkbuf; } @@ -240,6 +251,157 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_reject( return ogs_nas_5gs_plain_encode(&message); } +static void encode_qos_rule_packet_filter( + ogs_nas_qos_rule_t *qos_rule, smf_bearer_t *qos_flow) +{ + int i; + smf_pf_t *pf = NULL; + + ogs_assert(qos_rule); + ogs_assert(qos_flow); + + i = 0; + ogs_list_for_each(&qos_flow->pf_list, pf) { + qos_rule->pf[i].direction = pf->direction; + qos_rule->pf[i].identifier = pf->identifier; + + ogs_pf_content_from_ipfw_rule( + pf->direction, &qos_rule->pf[i].content, &pf->ipfw_rule); + i++; + } + qos_rule->num_of_packet_filter = i; +} + +ogs_pkbuf_t *gsm_build_qos_flow_modification_command( + smf_bearer_t *qos_flow, uint8_t pti) +{ + ogs_pkbuf_t *pkbuf = NULL; + smf_sess_t *sess = NULL; + ogs_pfcp_pdr_t *dl_pdr = NULL; + int num_of_param; + + ogs_nas_5gs_message_t message; + ogs_nas_5gs_pdu_session_modification_command_t + *pdu_session_modification_command = + &message.gsm.pdu_session_modification_command; + + ogs_nas_qos_rules_t *authorized_qos_rules = NULL; + ogs_nas_qos_flow_descriptions_t *authorized_qos_flow_descriptions = NULL; + + ogs_nas_qos_rule_t qos_rule[OGS_NAS_MAX_NUM_OF_QOS_RULE]; + ogs_nas_qos_flow_description_t + qos_flow_description[OGS_NAS_MAX_NUM_OF_QOS_FLOW_DESCRIPTION]; + + authorized_qos_rules = &pdu_session_modification_command-> + authorized_qos_rules; + ogs_assert(authorized_qos_rules); + authorized_qos_flow_descriptions = + &pdu_session_modification_command->authorized_qos_flow_descriptions; + ogs_assert(authorized_qos_flow_descriptions); + + ogs_assert(qos_flow); + sess = qos_flow->sess; + ogs_assert(sess); + dl_pdr = qos_flow->dl_pdr; + ogs_assert(dl_pdr); + + memset(&message, 0, sizeof(message)); + message.gsm.h.extended_protocol_discriminator = + OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GSM; + message.gsm.h.pdu_session_identity = sess->psi; + message.gsm.h.procedure_transaction_identity = pti; + message.gsm.h.message_type = OGS_NAS_5GS_PDU_SESSION_MODIFICATION_COMMAND; + + /* QoS rule */ + memset(qos_rule, 0, sizeof(qos_rule)); + qos_rule[0].identifier = qos_flow->qfi; /* Use QFI in Open5GS */ + qos_rule[0].code = OGS_NAS_QOS_CODE_CREATE_NEW_QOS_RULE; + + encode_qos_rule_packet_filter(&qos_rule[0], qos_flow); + + ogs_assert(dl_pdr->precedence > 0 && dl_pdr->precedence < 255); + qos_rule[0].precedence = dl_pdr->precedence; /* Use PCC Rule Precedence */ + qos_rule[0].flow.segregation = 0; + qos_rule[0].flow.identifier = qos_flow->qfi; + + pdu_session_modification_command->presencemask |= + OGS_NAS_5GS_PDU_SESSION_MODIFICATION_COMMAND_AUTHORIZED_QOS_RULES_PRESENT; + ogs_nas_build_qos_rules(authorized_qos_rules, qos_rule, 1); + ogs_assert(authorized_qos_rules->length); + + /* QoS flow descriptions */ + memset(&qos_flow_description, 0, sizeof(qos_flow_description)); + qos_flow_description[0].identifier = qos_flow->qfi; + qos_flow_description[0].code = OGS_NAS_CREATE_NEW_QOS_FLOW_DESCRIPTION; + qos_flow_description[0].E_bit = 1; + + num_of_param = 0; + + qos_flow_description[0].param[num_of_param].identifier = + OGS_NAX_QOS_FLOW_PARAMETER_ID_5QI; + qos_flow_description[0].param[num_of_param].len = + sizeof(qos_flow_description[0].param[num_of_param].qci); + qos_flow_description[0].param[num_of_param].qci = qos_flow->qos.qci; + num_of_param++; + + if (qos_flow->qos.gbr.uplink) { + qos_flow_description[0].param[num_of_param].identifier = + OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_UPLINK; + qos_flow_description[0].param[num_of_param].len = + sizeof(qos_flow_description[0].param[num_of_param].br); + ogs_nas_bitrate_from_uint64( + &qos_flow_description[0].param[num_of_param].br, + qos_flow->qos.gbr.uplink); + num_of_param++; + } + if (qos_flow->qos.gbr.downlink) { + qos_flow_description[0].param[num_of_param].identifier = + OGS_NAX_QOS_FLOW_PARAMETER_ID_GFBR_DOWNLINK; + qos_flow_description[0].param[num_of_param].len = + sizeof(qos_flow_description[0].param[num_of_param].br); + ogs_nas_bitrate_from_uint64( + &qos_flow_description[0].param[num_of_param].br, + qos_flow->qos.gbr.downlink); + num_of_param++; + } + if (qos_flow->qos.mbr.uplink) { + qos_flow_description[0].param[num_of_param].identifier = + OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_UPLINK; + qos_flow_description[0].param[num_of_param].len = + sizeof(qos_flow_description[0].param[num_of_param].br); + ogs_nas_bitrate_from_uint64( + &qos_flow_description[0].param[num_of_param].br, + qos_flow->qos.mbr.uplink); + num_of_param++; + } + if (qos_flow->qos.mbr.downlink) { + qos_flow_description[0].param[num_of_param].identifier = + OGS_NAX_QOS_FLOW_PARAMETER_ID_MFBR_DOWNLINK; + qos_flow_description[0].param[num_of_param].len = + sizeof(qos_flow_description[0].param[num_of_param].br); + ogs_nas_bitrate_from_uint64( + &qos_flow_description[0].param[num_of_param].br, + qos_flow->qos.mbr.downlink); + num_of_param++; + } + + qos_flow_description[0].num_of_parameter = num_of_param; + + pdu_session_modification_command->presencemask |= + OGS_NAS_5GS_PDU_SESSION_MODIFICATION_COMMAND_AUTHORIZED_QOS_FLOW_DESCRIPTIONS_PRESENT; + ogs_nas_build_qos_flow_descriptions( + authorized_qos_flow_descriptions, qos_flow_description, 1); + ogs_assert(authorized_qos_flow_descriptions->length); + + pkbuf = ogs_nas_5gs_plain_encode(&message); + ogs_assert(pkbuf); + + ogs_free(authorized_qos_rules->buffer); + ogs_free(authorized_qos_flow_descriptions->buffer); + + return pkbuf; +} + ogs_pkbuf_t *gsm_build_pdu_session_release_command( smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause) { diff --git a/src/smf/gsm-build.h b/src/smf/gsm-build.h index 7bde876a2..10368944b 100644 --- a/src/smf/gsm-build.h +++ b/src/smf/gsm-build.h @@ -30,6 +30,9 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess); ogs_pkbuf_t *gsm_build_pdu_session_establishment_reject( smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause); +ogs_pkbuf_t *gsm_build_qos_flow_modification_command( + smf_bearer_t *qos_flow, uint8_t pti); + ogs_pkbuf_t *gsm_build_pdu_session_release_command( smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause); ogs_pkbuf_t *gsm_build_pdu_session_release_reject( diff --git a/src/smf/gsm-sm.c b/src/smf/gsm-sm.c index ba618bfa0..f3d1d80d7 100644 --- a/src/smf/gsm-sm.c +++ b/src/smf/gsm-sm.c @@ -22,6 +22,7 @@ #include "nsmf-handler.h" #include "nudm-handler.h" #include "npcf-handler.h" +#include "namf-handler.h" #include "gsm-handler.h" #include "ngap-handler.h" #include "pfcp-path.h" @@ -103,11 +104,11 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) smf_ue = sess->smf_ue; ogs_assert(smf_ue); - stream = e->sbi.data; - ogs_assert(stream); - SWITCH(sbi_message->h.service.name) CASE(OGS_SBI_SERVICE_NAME_NUDM_SDM) + stream = e->sbi.data; + ogs_assert(stream); + SWITCH(sbi_message->h.resource.component[1]) CASE(OGS_SBI_RESOURCE_NAME_SM_DATA) if (sbi_message->res_status != OGS_SBI_HTTP_STATUS_OK) { @@ -145,6 +146,9 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) break; CASE(OGS_SBI_SERVICE_NAME_NPCF_SMPOLICYCONTROL) + stream = e->sbi.data; + ogs_assert(stream); + SWITCH(sbi_message->h.resource.component[0]) CASE(OGS_SBI_RESOURCE_NAME_SM_POLICIES) if (sbi_message->res_status != OGS_SBI_HTTP_STATUS_CREATED) { @@ -186,6 +190,9 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) smf_ue->supi, sess->psi, sbi_message->res_status); break; } + + smf_namf_comm_handler_n1_n2_message_transfer( + sess, e->sbi.state, sbi_message); break; DEFAULT @@ -224,6 +231,10 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) } break; + case OGS_NAS_5GS_PDU_SESSION_MODIFICATION_COMPLETE: + smf_sbi_send_response(stream, OGS_SBI_HTTP_STATUS_NO_CONTENT); + break; + case OGS_NAS_5GS_PDU_SESSION_RELEASE_REQUEST: smf_5gc_pfcp_send_session_deletion_request( sess, stream, OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED); @@ -285,6 +296,16 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) } break; + case OpenAPI_n2_sm_info_type_PDU_RES_MOD_RSP: + rv = ngap_handle_pdu_session_resource_modify_response_transfer( + sess, stream, pkbuf); + if (rv != OGS_OK) { + ogs_error("[%s:%d] Cannot handle NGAP message", + smf_ue->supi, sess->psi); + OGS_FSM_TRAN(s, smf_gsm_state_exception); + } + break; + case OpenAPI_n2_sm_info_type_PDU_RES_REL_RSP: smf_sbi_send_response(stream, OGS_SBI_HTTP_STATUS_NO_CONTENT); break; diff --git a/src/smf/gx-handler.c b/src/smf/gx-handler.c index 8e1b21865..b5d338af8 100644 --- a/src/smf/gx-handler.c +++ b/src/smf/gx-handler.c @@ -21,7 +21,7 @@ #include "gtp-path.h" #include "pfcp-path.h" #include "gx-handler.h" -#include "bearer-binding.h" +#include "binding.h" static uint8_t gtp_cause_from_diameter( const uint32_t *dia_err, const uint32_t *dia_exp_err) @@ -70,22 +70,23 @@ void smf_gx_handle_cca_initial_request( return; } - sess->num_of_pcc_rule = gx_message->num_of_pcc_rule; - for (i = 0; i < gx_message->num_of_pcc_rule; i++) - OGS_STORE_PCC_RULE(&sess->pcc_rule[i], &gx_message->pcc_rule[i]); + sess->num_of_pcc_rule = gx_message->session_data.num_of_pcc_rule; + for (i = 0; i < gx_message->session_data.num_of_pcc_rule; i++) + OGS_STORE_PCC_RULE(&sess->pcc_rule[i], + &gx_message->session_data.pcc_rule[i]); /* APN-AMBR * if PCRF changes APN-AMBR, this should be included. */ sess->gtp_5gc.create_session_response_apn_ambr = false; - if ((gx_message->pdn.ambr.uplink && + if ((gx_message->session_data.pdn.ambr.uplink && (sess->pdn.ambr.uplink / 1000) != - (gx_message->pdn.ambr.uplink / 1000)) || - (gx_message->pdn.ambr.downlink && + (gx_message->session_data.pdn.ambr.uplink / 1000)) || + (gx_message->session_data.pdn.ambr.downlink && (sess->pdn.ambr.downlink / 1000) != - (gx_message->pdn.ambr.downlink / 1000))) { + (gx_message->session_data.pdn.ambr.downlink / 1000))) { - sess->pdn.ambr.downlink = gx_message->pdn.ambr.downlink; - sess->pdn.ambr.uplink = gx_message->pdn.ambr.uplink; + sess->pdn.ambr.downlink = gx_message->session_data.pdn.ambr.downlink; + sess->pdn.ambr.uplink = gx_message->session_data.pdn.ambr.uplink; sess->gtp_5gc.create_session_response_apn_ambr = true; } @@ -93,23 +94,23 @@ void smf_gx_handle_cca_initial_request( /* Bearer QoS * if PCRF changes Bearer QoS, this should be included. */ sess->gtp_5gc.create_session_response_bearer_qos = false; - if ((gx_message->pdn.qos.qci && - sess->pdn.qos.qci != gx_message->pdn.qos.qci) || - (gx_message->pdn.qos.arp.priority_level && + if ((gx_message->session_data.pdn.qos.qci && + sess->pdn.qos.qci != gx_message->session_data.pdn.qos.qci) || + (gx_message->session_data.pdn.qos.arp.priority_level && sess->pdn.qos.arp.priority_level != - gx_message->pdn.qos.arp.priority_level) || + gx_message->session_data.pdn.qos.arp.priority_level) || sess->pdn.qos.arp.pre_emption_capability != - gx_message->pdn.qos.arp.pre_emption_capability || + gx_message->session_data.pdn.qos.arp.pre_emption_capability || sess->pdn.qos.arp.pre_emption_vulnerability != - gx_message->pdn.qos.arp.pre_emption_vulnerability) { + gx_message->session_data.pdn.qos.arp.pre_emption_vulnerability) { - sess->pdn.qos.qci = gx_message->pdn.qos.qci; + sess->pdn.qos.qci = gx_message->session_data.pdn.qos.qci; sess->pdn.qos.arp.priority_level = - gx_message->pdn.qos.arp.priority_level; + gx_message->session_data.pdn.qos.arp.priority_level; sess->pdn.qos.arp.pre_emption_capability = - gx_message->pdn.qos.arp.pre_emption_capability; + gx_message->session_data.pdn.qos.arp.pre_emption_capability; sess->pdn.qos.arp.pre_emption_vulnerability = - gx_message->pdn.qos.arp.pre_emption_vulnerability; + gx_message->session_data.pdn.qos.arp.pre_emption_vulnerability; sess->gtp_5gc.create_session_response_bearer_qos = true; } @@ -185,9 +186,10 @@ void smf_gx_handle_re_auth_request( { int i; - sess->num_of_pcc_rule = gx_message->num_of_pcc_rule; - for (i = 0; i < gx_message->num_of_pcc_rule; i++) - OGS_STORE_PCC_RULE(&sess->pcc_rule[i], &gx_message->pcc_rule[i]); + sess->num_of_pcc_rule = gx_message->session_data.num_of_pcc_rule; + for (i = 0; i < gx_message->session_data.num_of_pcc_rule; i++) + OGS_STORE_PCC_RULE(&sess->pcc_rule[i], + &gx_message->session_data.pcc_rule[i]); smf_bearer_binding(sess); } diff --git a/src/smf/meson.build b/src/smf/meson.build index 4baccac6a..4e7403278 100644 --- a/src/smf/meson.build +++ b/src/smf/meson.build @@ -43,12 +43,13 @@ libsmf_sources = files(''' pfcp-path.h n4-build.h n4-handler.h - bearer-binding.h + binding.h nnrf-handler.h nudm-build.h nudm-handler.h nsmf-handler.h namf-build.h + namf-handler.h npcf-build.h npcf-handler.h sbi-path.h @@ -75,12 +76,13 @@ libsmf_sources = files(''' pfcp-path.c n4-build.c n4-handler.c - bearer-binding.c + binding.c nnrf-handler.c nudm-build.c nudm-handler.c nsmf-handler.c namf-build.c + namf-handler.c npcf-build.c npcf-handler.c sbi-path.c diff --git a/src/smf/n4-build.c b/src/smf/n4-build.c index 86cbeadeb..47ab61ffa 100644 --- a/src/smf/n4-build.c +++ b/src/smf/n4-build.c @@ -108,6 +108,58 @@ ogs_pkbuf_t *smf_n4_build_session_establishment_request( return pkbuf; } +ogs_pkbuf_t *smf_n4_build_session_modification_request( + uint8_t type, smf_sess_t *sess, uint64_t modify_flags) +{ + int i; + + ogs_pfcp_message_t pfcp_message; + ogs_pfcp_session_modification_request_t *req = NULL; + ogs_pfcp_far_t *far = NULL; + ogs_pkbuf_t *pkbuf = NULL; + + ogs_debug("Session Modification Request"); + ogs_assert(sess); + ogs_assert(modify_flags); + + req = &pfcp_message.pfcp_session_modification_request; + memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); + + i = 0; + ogs_list_for_each(&sess->pfcp.far_list, far) { + + /* Update FAR - Only DL */ + if (far->dst_if == OGS_PFCP_INTERFACE_ACCESS) { + + if (modify_flags & OGS_PFCP_MODIFY_ACTIVATE) { + + if (far->apply_action & OGS_PFCP_APPLY_ACTION_FORW) { + + if (modify_flags & OGS_PFCP_MODIFY_END_MARKER) { + far->smreq_flags.send_end_marker_packets = 1; + } + + ogs_pfcp_build_update_far_activate( + &req->update_far[i], i, far); + + /* Clear all FAR flags */ + far->smreq_flags.value = 0; + } + + } else if (modify_flags & OGS_PFCP_MODIFY_DEACTIVATE) { + ogs_pfcp_build_update_far_deactivate( + &req->update_far[i], i, far); + } + i++; + } + } + + pfcp_message.h.type = type; + pkbuf = ogs_pfcp_build_msg(&pfcp_message); + + return pkbuf; +} + ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request( uint8_t type, smf_bearer_t *qos_flow, uint64_t modify_flags) { @@ -235,16 +287,27 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request( /* Update FAR - Only DL */ i = 0; if (qos_flow->dl_far) { - if (modify_flags & OGS_PFCP_MODIFY_END_MARKER) { - qos_flow->dl_far->smreq_flags.send_end_marker_packets = 1; - } + if (qos_flow->dl_far->apply_action & + OGS_PFCP_APPLY_ACTION_FORW) { - ogs_pfcp_build_update_far_activate( + if (modify_flags & OGS_PFCP_MODIFY_END_MARKER) { + qos_flow->dl_far->smreq_flags.send_end_marker_packets = 1; + } + + ogs_pfcp_build_update_far_activate( + &req->update_far[i], i, qos_flow->dl_far); + i++; + + /* Clear all FAR flags */ + qos_flow->dl_far->smreq_flags.value = 0; + } + } + } else if (modify_flags & OGS_PFCP_MODIFY_DEACTIVATE) { + i = 0; + if (qos_flow->dl_far) { + ogs_pfcp_build_update_far_deactivate( &req->update_far[i], i, qos_flow->dl_far); i++; - - /* Clear all FAR flags */ - qos_flow->dl_far->smreq_flags.value = 0; } } if (modify_flags & OGS_PFCP_MODIFY_QOS_UPDATE) { @@ -279,36 +342,3 @@ ogs_pkbuf_t *smf_n4_build_session_deletion_request( pfcp_message.h.type = type; return ogs_pfcp_build_msg(&pfcp_message); } - -ogs_pkbuf_t *smf_5gc_n4_build_session_modification_request( - uint8_t type, smf_sess_t *sess, uint64_t modify_flags) -{ - int i; - - ogs_pfcp_message_t pfcp_message; - ogs_pfcp_session_modification_request_t *req = NULL; - ogs_pfcp_far_t *far = NULL; - ogs_pkbuf_t *pkbuf = NULL; - - ogs_debug("Session Modification Request"); - ogs_assert(sess); - ogs_assert(modify_flags & OGS_PFCP_MODIFY_DEACTIVATE); - - req = &pfcp_message.pfcp_session_modification_request; - memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); - - i = 0; - ogs_list_for_each(&sess->pfcp.far_list, far) { - /* Update FAR - Only DL */ - if (far->dst_if == OGS_PFCP_INTERFACE_ACCESS) { - ogs_pfcp_build_update_far_deactivate( - &req->update_far[i], i, far); - i++; - } - } - - pfcp_message.h.type = type; - pkbuf = ogs_pfcp_build_msg(&pfcp_message); - - return pkbuf; -} diff --git a/src/smf/n4-build.h b/src/smf/n4-build.h index 8f36c0973..bb11599ab 100644 --- a/src/smf/n4-build.h +++ b/src/smf/n4-build.h @@ -28,14 +28,13 @@ extern "C" { ogs_pkbuf_t *smf_n4_build_session_establishment_request( uint8_t type, smf_sess_t *sess); +ogs_pkbuf_t *smf_n4_build_session_modification_request( + uint8_t type, smf_sess_t *sess, uint64_t modify_flags); ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request( uint8_t type, smf_bearer_t *qos_flow, uint64_t modify_flags); ogs_pkbuf_t *smf_n4_build_session_deletion_request( uint8_t type, smf_sess_t *sess); -ogs_pkbuf_t *smf_5gc_n4_build_session_modification_request( - uint8_t type, smf_sess_t *sess, uint64_t modify_flags); - #ifdef __cplusplus } #endif diff --git a/src/smf/n4-handler.c b/src/smf/n4-handler.c index 1ce5f9804..1f86ce22d 100644 --- a/src/smf/n4-handler.c +++ b/src/smf/n4-handler.c @@ -22,8 +22,9 @@ #include "pfcp-path.h" #include "gtp-path.h" #include "n4-handler.h" -#include "bearer-binding.h" +#include "binding.h" #include "sbi-path.h" +#include "ngap-path.h" static uint8_t gtp_cause_from_pfcp(uint8_t pfcp_cause) { @@ -101,6 +102,8 @@ void smf_5gc_n4_handle_session_establishment_response( { int i; + ogs_pkbuf_t *n1smbuf = NULL; + ogs_pkbuf_t *n2smbuf = NULL; ogs_sbi_stream_t *stream = NULL; uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED; @@ -187,12 +190,14 @@ void smf_5gc_n4_handle_session_establishment_response( ogs_assert(up_f_seid); sess->upf_n4_seid = be64toh(up_f_seid->seid); - smf_sbi_discover_and_send(OpenAPI_nf_type_AMF, sess, stream, NULL, - smf_namf_comm_build_n1_n2_message_transfer); + n1smbuf = gsm_build_pdu_session_establishment_accept(sess); + ogs_assert(n1smbuf); + n2smbuf = ngap_build_pdu_session_resource_setup_request_transfer(sess); + ogs_assert(n2smbuf); -#if 0 - smf_bearer_binding(sess); -#endif + smf_namf_comm_send_n1_n2_message_transfer( + sess, SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT, + n1smbuf, n2smbuf); } void smf_5gc_n4_handle_session_modification_response( @@ -202,15 +207,20 @@ void smf_5gc_n4_handle_session_modification_response( int status = 0; uint64_t flags = 0; ogs_sbi_stream_t *stream = NULL; + smf_bearer_t *qos_flow = NULL; ogs_assert(xact); ogs_assert(rsp); - stream = xact->assoc_stream; - ogs_assert(stream); flags = xact->modify_flags; ogs_assert(flags); + /* 'stream' could be NULL in smf_qos_flow_binding() */ + stream = xact->assoc_stream; + + /* If smf_5gc_pfcp_send_qos_flow_modification_request() is called */ + qos_flow = xact->data; + ogs_pfcp_xact_commit(xact); status = OGS_SBI_HTTP_STATUS_OK; @@ -271,8 +281,9 @@ void smf_5gc_n4_handle_session_modification_response( if (status != OGS_SBI_HTTP_STATUS_OK) { char *strerror = ogs_msprintf( "PFCP Cause [%d] : Not Accepted", rsp->cause.u8); - smf_sbi_send_sm_context_update_error(stream, status, strerror, - NULL, NULL, NULL); + if (stream) + smf_sbi_send_sm_context_update_error( + stream, status, strerror, NULL, NULL, NULL); ogs_free(strerror); return; } @@ -280,8 +291,9 @@ void smf_5gc_n4_handle_session_modification_response( ogs_assert(sess); if (sess->upf_n3_addr == NULL && sess->upf_n3_addr6 == NULL) { - smf_sbi_send_sm_context_update_error(stream, status, "No UP F_TEID", - NULL, NULL, NULL); + if (stream) + smf_sbi_send_sm_context_update_error( + stream, status, "No UP F_TEID", NULL, NULL, NULL); return; } @@ -293,6 +305,20 @@ void smf_5gc_n4_handle_session_modification_response( /* Only ACTIVING & DEACTIVATED is Included */ smf_sbi_send_sm_context_updated_data( sess, stream, OpenAPI_up_cnx_state_DEACTIVATED); + } else if (flags & OGS_PFCP_MODIFY_CREATE) { + ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL; + + ogs_assert(qos_flow); + n1smbuf = gsm_build_qos_flow_modification_command( + qos_flow, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED); + ogs_assert(n1smbuf); + n2smbuf = ngap_build_qos_flow_resource_modify_request_transfer( + qos_flow); + ogs_assert(n2smbuf); + + smf_namf_comm_send_n1_n2_message_transfer( + sess, SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION, + n1smbuf, n2smbuf); } } diff --git a/src/smf/namf-build.c b/src/smf/namf-build.c index c10feb8ef..1ceb69871 100644 --- a/src/smf/namf-build.c +++ b/src/smf/namf-build.c @@ -22,7 +22,7 @@ #include "ngap-build.h" ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer( - smf_sess_t *sess, void *data) + smf_sess_t *sess, smf_n1_n2_message_transfer_data_t *data) { int i; smf_ue_t *smf_ue = NULL; @@ -45,6 +45,11 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer( ogs_assert(smf_ue); ogs_assert(smf_ue->supi); + ogs_assert(data); + ogs_assert(data->state); + ogs_assert(data->n1smbuf); + ogs_assert(data->n2smbuf); + memset(&message, 0, sizeof(message)); message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST; message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NAMF_COMM; @@ -76,7 +81,18 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer( smInfo.n2_info_content = &n2InfoContent; memset(&n2InfoContent, 0, sizeof(n2InfoContent)); - n2InfoContent.ngap_ie_type = OpenAPI_ngap_ie_type_PDU_RES_SETUP_REQ; + switch (data->state) { + case SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT: + n2InfoContent.ngap_ie_type = OpenAPI_ngap_ie_type_PDU_RES_SETUP_REQ; + break; + case SMF_NETWORK_REQUESTED_PDU_SESSION_MODIFICATION: + case SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION: + n2InfoContent.ngap_ie_type = OpenAPI_ngap_ie_type_PDU_RES_MOD_REQ; + break; + default: + ogs_fatal("Unexpected state [%d]", data->state); + ogs_assert_if_reached(); + } n2InfoContent.ngap_data = &ngapData; memset(&ngapData, 0, sizeof(ngapData)); @@ -84,8 +100,7 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer( message.num_of_part = 0; - message.part[message.num_of_part].pkbuf = - gsm_build_pdu_session_establishment_accept(sess); + message.part[message.num_of_part].pkbuf = data->n1smbuf; if (message.part[message.num_of_part].pkbuf) { message.part[message.num_of_part].content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID; @@ -94,8 +109,7 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer( message.num_of_part++; } - message.part[message.num_of_part].pkbuf = - ngap_build_pdu_session_resource_setup_request_transfer(sess); + message.part[message.num_of_part].pkbuf = data->n2smbuf; if (message.part[message.num_of_part].pkbuf) { message.part[message.num_of_part].content_id = (char *)OGS_SBI_CONTENT_NGAP_SM_ID; diff --git a/src/smf/namf-build.h b/src/smf/namf-build.h index 67861b1be..6b108fbef 100644 --- a/src/smf/namf-build.h +++ b/src/smf/namf-build.h @@ -26,8 +26,20 @@ extern "C" { #endif +typedef struct smf_n1_n2_message_transfer_data_s { +#define SMF_N1_N2_MESSAGE_TRANSFER_NO_STATE 0 +#define SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT 1 +#define SMF_NETWORK_REQUESTED_PDU_SESSION_MODIFICATION 2 +#define SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION 3 + int state; + + ogs_pkbuf_t *n1smbuf; + ogs_pkbuf_t *n2smbuf; +} smf_n1_n2_message_transfer_data_t; + ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer( - smf_sess_t *sess, void *data); + smf_sess_t *sess, smf_n1_n2_message_transfer_data_t *data); + ogs_sbi_request_t *smf_namf_callback_build_sm_context_status( smf_sess_t *sess, void *data); diff --git a/src/smf/namf-handler.c b/src/smf/namf-handler.c new file mode 100644 index 000000000..734cb8672 --- /dev/null +++ b/src/smf/namf-handler.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2019 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 "sbi-path.h" +#include "binding.h" +#include "namf-handler.h" + +bool smf_namf_comm_handler_n1_n2_message_transfer( + smf_sess_t *sess, int state, ogs_sbi_message_t *recvmsg) +{ + ogs_assert(sess); + ogs_assert(state); + ogs_assert(recvmsg); + + switch (state) { + case SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT: + smf_qos_flow_binding(sess, NULL); + break; + + case SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION: + /* Nothing */ + break; + + default: + ogs_fatal("Unexpected state [%d]", state); + ogs_assert_if_reached(); + } + + return true; +} diff --git a/src/smf/namf-handler.h b/src/smf/namf-handler.h new file mode 100644 index 000000000..aae07b101 --- /dev/null +++ b/src/smf/namf-handler.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2019 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 . + */ + +#ifndef SMF_NAMF_HANDLER_H +#define SMF_NAMF_HANDLER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "context.h" + +bool smf_namf_comm_handler_n1_n2_message_transfer( + smf_sess_t *sess, int state, ogs_sbi_message_t *recvmsg); + +#ifdef __cplusplus +} +#endif + +#endif /* SMF_NAMF_HANDLER_H */ diff --git a/src/smf/ngap-build.c b/src/smf/ngap-build.c index 7ec0c6660..f5a85d95d 100644 --- a/src/smf/ngap-build.c +++ b/src/smf/ngap-build.c @@ -39,10 +39,9 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( NGAP_QosCharacteristics_t *qosCharacteristics = NULL; NGAP_NonDynamic5QIDescriptor_t *nonDynamic5QI = NULL; NGAP_AllocationAndRetentionPriority_t *allocationAndRetentionPriority; + NGAP_GBR_QosInformation_t *gBR_QosInformation = NULL; ogs_assert(sess); - qos_flow = smf_default_bearer_in_sess(sess); - ogs_assert(qos_flow); ogs_debug("PDUSessionResourceSetupRequestTransfer"); memset(&message, 0, sizeof(NGAP_PDUSessionResourceSetupRequestTransfer_t)); @@ -118,28 +117,125 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( QosFlowSetupRequestList = &ie->value.choice.QosFlowSetupRequestList; - QosFlowSetupRequestItem = - CALLOC(1, sizeof(struct NGAP_QosFlowSetupRequestItem)); - ASN_SEQUENCE_ADD(&QosFlowSetupRequestList->list, QosFlowSetupRequestItem); + ogs_list_for_each(&sess->bearer_list, qos_flow) { + QosFlowSetupRequestItem = + CALLOC(1, sizeof(struct NGAP_QosFlowSetupRequestItem)); + ASN_SEQUENCE_ADD(&QosFlowSetupRequestList->list, + QosFlowSetupRequestItem); - qosFlowIdentifier = &QosFlowSetupRequestItem->qosFlowIdentifier; - qosFlowLevelQosParameters = - &QosFlowSetupRequestItem->qosFlowLevelQosParameters; + qosFlowIdentifier = &QosFlowSetupRequestItem->qosFlowIdentifier; + qosFlowLevelQosParameters = + &QosFlowSetupRequestItem->qosFlowLevelQosParameters; + + allocationAndRetentionPriority = + &qosFlowLevelQosParameters->allocationAndRetentionPriority; + qosCharacteristics = &qosFlowLevelQosParameters->qosCharacteristics; + nonDynamic5QI = CALLOC(1, sizeof(struct NGAP_NonDynamic5QIDescriptor)); + qosCharacteristics->choice.nonDynamic5QI = nonDynamic5QI; + qosCharacteristics->present = NGAP_QosCharacteristics_PR_nonDynamic5QI; + + *qosFlowIdentifier = qos_flow->qfi; + + nonDynamic5QI->fiveQI = qos_flow->qos.qci; + + allocationAndRetentionPriority->priorityLevelARP = + qos_flow->qos.arp.priority_level; + if (qos_flow->qos.arp.pre_emption_capability == + OGS_PDN_PRE_EMPTION_CAPABILITY_DISABLED) + allocationAndRetentionPriority->pre_emptionCapability = + NGAP_Pre_emptionCapability_shall_not_trigger_pre_emption; + else + allocationAndRetentionPriority->pre_emptionCapability = + NGAP_Pre_emptionCapability_may_trigger_pre_emption; + + if (qos_flow->qos.arp.pre_emption_vulnerability == + OGS_PDN_PRE_EMPTION_VULNERABILITY_DISABLED) + allocationAndRetentionPriority->pre_emptionVulnerability = + NGAP_Pre_emptionVulnerability_not_pre_emptable; + else + allocationAndRetentionPriority->pre_emptionVulnerability = + NGAP_Pre_emptionVulnerability_pre_emptable; + + if (qos_flow->qos.mbr.downlink || qos_flow->qos.mbr.uplink || + qos_flow->qos.gbr.downlink || qos_flow->qos.gbr.uplink) { + ogs_assert(qos_flow->qos.mbr.downlink); + ogs_assert(qos_flow->qos.mbr.uplink); + ogs_assert(qos_flow->qos.gbr.downlink); + ogs_assert(qos_flow->qos.gbr.uplink); + + qosFlowLevelQosParameters->gBR_QosInformation = + gBR_QosInformation = CALLOC(1, sizeof(*gBR_QosInformation)); + + asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateDL, + qos_flow->qos.mbr.downlink); + asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateUL, + qos_flow->qos.mbr.uplink); + asn_uint642INTEGER(&gBR_QosInformation-> + guaranteedFlowBitRateDL, qos_flow->qos.gbr.downlink); + asn_uint642INTEGER(&gBR_QosInformation-> + guaranteedFlowBitRateUL, qos_flow->qos.gbr.uplink); + } + } + + return ogs_asn_encode( + &asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, &message); +} + +ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer( + smf_bearer_t *qos_flow) +{ + NGAP_PDUSessionResourceModifyRequestTransfer_t message; + + NGAP_PDUSessionResourceModifyRequestTransferIEs_t *ie = NULL; + + NGAP_QosFlowAddOrModifyRequestList_t *QosFlowAddOrModifyRequestList = NULL; + NGAP_QosFlowAddOrModifyRequestItem_t *QosFlowAddOrModifyRequestItem = NULL; + NGAP_QosFlowIdentifier_t *qosFlowIdentifier = NULL; + NGAP_QosFlowLevelQosParameters_t *qosFlowLevelQosParameters = NULL; + NGAP_QosCharacteristics_t *qosCharacteristics = NULL; + NGAP_NonDynamic5QIDescriptor_t *nonDynamic5QI = NULL; + NGAP_AllocationAndRetentionPriority_t *allocationAndRetentionPriority; + NGAP_GBR_QosInformation_t *gBR_QosInformation; + + ogs_assert(qos_flow); + + ogs_debug("PDUSessionResourceModifyRequestTransfer"); + memset(&message, 0, sizeof(NGAP_PDUSessionResourceModifyRequestTransfer_t)); + + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceModifyRequestTransferIEs_t)); + ASN_SEQUENCE_ADD(&message.protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_QosFlowAddOrModifyRequestList; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_PDUSessionResourceModifyRequestTransferIEs__value_PR_QosFlowAddOrModifyRequestList; + + QosFlowAddOrModifyRequestList = &ie->value.choice.QosFlowAddOrModifyRequestList; + + QosFlowAddOrModifyRequestItem = + CALLOC(1, sizeof(*QosFlowAddOrModifyRequestItem)); + ASN_SEQUENCE_ADD(&QosFlowAddOrModifyRequestList->list, QosFlowAddOrModifyRequestItem); + + qosFlowIdentifier = &QosFlowAddOrModifyRequestItem->qosFlowIdentifier; + + QosFlowAddOrModifyRequestItem->qosFlowLevelQosParameters = + qosFlowLevelQosParameters = + CALLOC(1, sizeof(*qosFlowLevelQosParameters)); allocationAndRetentionPriority = &qosFlowLevelQosParameters->allocationAndRetentionPriority; qosCharacteristics = &qosFlowLevelQosParameters->qosCharacteristics; - nonDynamic5QI = CALLOC(1, sizeof(struct NGAP_NonDynamic5QIDescriptor)); - qosCharacteristics->choice.nonDynamic5QI = nonDynamic5QI; + qosCharacteristics->present = NGAP_QosCharacteristics_PR_nonDynamic5QI; + qosCharacteristics->choice.nonDynamic5QI = + nonDynamic5QI = CALLOC(1, sizeof(struct NGAP_NonDynamic5QIDescriptor)); *qosFlowIdentifier = qos_flow->qfi; - nonDynamic5QI->fiveQI = sess->pdn.qos.qci; + nonDynamic5QI->fiveQI = qos_flow->qos.qci; allocationAndRetentionPriority->priorityLevelARP = - sess->pdn.qos.arp.priority_level;; - if (sess->pdn.qos.arp.pre_emption_capability == + qos_flow->qos.arp.priority_level; + if (qos_flow->qos.arp.pre_emption_capability == OGS_PDN_PRE_EMPTION_CAPABILITY_DISABLED) allocationAndRetentionPriority->pre_emptionCapability = NGAP_Pre_emptionCapability_shall_not_trigger_pre_emption; @@ -147,7 +243,7 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( allocationAndRetentionPriority->pre_emptionCapability = NGAP_Pre_emptionCapability_may_trigger_pre_emption; - if (sess->pdn.qos.arp.pre_emption_vulnerability == + if (qos_flow->qos.arp.pre_emption_vulnerability == OGS_PDN_PRE_EMPTION_VULNERABILITY_DISABLED) allocationAndRetentionPriority->pre_emptionVulnerability = NGAP_Pre_emptionVulnerability_not_pre_emptable; @@ -155,8 +251,28 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( allocationAndRetentionPriority->pre_emptionVulnerability = NGAP_Pre_emptionVulnerability_pre_emptable; + if (qos_flow->qos.mbr.downlink || qos_flow->qos.mbr.uplink || + qos_flow->qos.gbr.downlink || qos_flow->qos.gbr.uplink) { + ogs_assert(qos_flow->qos.mbr.downlink); + ogs_assert(qos_flow->qos.mbr.uplink); + ogs_assert(qos_flow->qos.gbr.downlink); + ogs_assert(qos_flow->qos.gbr.uplink); + + qosFlowLevelQosParameters->gBR_QosInformation = + gBR_QosInformation = CALLOC(1, sizeof(*gBR_QosInformation)); + + asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateDL, + qos_flow->qos.mbr.downlink); + asn_uint642INTEGER(&gBR_QosInformation->maximumFlowBitRateUL, + qos_flow->qos.mbr.uplink); + asn_uint642INTEGER(&gBR_QosInformation-> + guaranteedFlowBitRateDL, qos_flow->qos.gbr.downlink); + asn_uint642INTEGER(&gBR_QosInformation-> + guaranteedFlowBitRateUL, qos_flow->qos.gbr.uplink); + } + return ogs_asn_encode( - &asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, &message); + &asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, &message); } ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer( diff --git a/src/smf/ngap-build.h b/src/smf/ngap-build.h index c48f8cebe..0f3d1bd5b 100644 --- a/src/smf/ngap-build.h +++ b/src/smf/ngap-build.h @@ -28,6 +28,10 @@ extern "C" { ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( smf_sess_t *sess); + +ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer( + smf_bearer_t *qos_flow); + ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer( NGAP_Cause_PR group, long cause); diff --git a/src/smf/ngap-handler.c b/src/smf/ngap-handler.c index 378aeec8e..8532e69ae 100644 --- a/src/smf/ngap-handler.c +++ b/src/smf/ngap-handler.c @@ -81,25 +81,6 @@ int ngap_handle_pdu_session_resource_setup_response_transfer( goto cleanup; } - associatedQosFlowList = &dLQosFlowPerTNLInformation->associatedQosFlowList; - for (i = 0; i < associatedQosFlowList->list.count; i++) { - NGAP_AssociatedQosFlowItem_t *associatedQosFlowItem = NULL; - associatedQosFlowItem = (NGAP_AssociatedQosFlowItem_t *) - associatedQosFlowList->list.array[i]; - if (associatedQosFlowItem) { - qos_flow = smf_qos_flow_find_by_qfi(sess, - associatedQosFlowItem->qosFlowIdentifier); - } - } - - if (!qos_flow) { - ogs_error("[%s:%d] No QoS flow", smf_ue->supi, sess->psi); - smf_sbi_send_sm_context_update_error(stream, - OGS_SBI_HTTP_STATUS_BAD_REQUEST, - "No QoS flow", smf_ue->supi, NULL, NULL); - goto cleanup; - } - gTPTunnel = uPTransportLayerInformation->choice.gTPTunnel; if (!gTPTunnel) { ogs_error("[%s:%d] No GTPTunnel", smf_ue->supi, sess->psi); @@ -118,25 +99,46 @@ int ngap_handle_pdu_session_resource_setup_response_transfer( sess->gnb_n3_teid != upf_n3_teid) far_update = true; - dl_far = qos_flow->dl_far; - ogs_assert(dl_far); - if (dl_far->apply_action != OGS_PFCP_APPLY_ACTION_FORW) { - far_update = true; - } - /* Setup FAR */ memcpy(&sess->gnb_n3_ip, &upf_n3_ip, sizeof(sess->gnb_n3_ip)); sess->gnb_n3_teid = upf_n3_teid; - dl_far->apply_action = OGS_PFCP_APPLY_ACTION_FORW; + associatedQosFlowList = &dLQosFlowPerTNLInformation->associatedQosFlowList; + for (i = 0; i < associatedQosFlowList->list.count; i++) { + NGAP_AssociatedQosFlowItem_t *associatedQosFlowItem = NULL; + associatedQosFlowItem = (NGAP_AssociatedQosFlowItem_t *) + associatedQosFlowList->list.array[i]; - ogs_pfcp_ip_to_outer_header_creation(&sess->gnb_n3_ip, - &dl_far->outer_header_creation, &dl_far->outer_header_creation_len); - dl_far->outer_header_creation.teid = sess->gnb_n3_teid; + if (associatedQosFlowItem) { + qos_flow = smf_qos_flow_find_by_qfi(sess, + associatedQosFlowItem->qosFlowIdentifier); + + if (qos_flow) { + dl_far = qos_flow->dl_far; + ogs_assert(dl_far); + if (dl_far->apply_action != OGS_PFCP_APPLY_ACTION_FORW) { + far_update = true; + } + + dl_far->apply_action = OGS_PFCP_APPLY_ACTION_FORW; + ogs_pfcp_ip_to_outer_header_creation( + &sess->gnb_n3_ip, + &dl_far->outer_header_creation, + &dl_far->outer_header_creation_len); + dl_far->outer_header_creation.teid = sess->gnb_n3_teid; + } else { + ogs_error("[%s:%d] No QoS flow", smf_ue->supi, sess->psi); + smf_sbi_send_sm_context_update_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + "No QoS flow", smf_ue->supi, NULL, NULL); + goto cleanup; + } + } + } if (far_update) { - smf_5gc_pfcp_send_qos_flow_modification_request( - qos_flow, stream, OGS_PFCP_MODIFY_ACTIVATE); + smf_5gc_pfcp_send_session_modification_request( + sess, stream, OGS_PFCP_MODIFY_ACTIVATE); } else { /* ACTIVATED Is NOT Inlcuded in RESPONSE */ smf_sbi_send_sm_context_updated_data(sess, stream, 0); @@ -148,3 +150,82 @@ cleanup: &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, &message); return rv; } + +int ngap_handle_pdu_session_resource_modify_response_transfer( + smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf) +{ + smf_ue_t *smf_ue = NULL; + smf_bearer_t *qos_flow = NULL; + int rv, i; + + ogs_pfcp_far_t *dl_far = NULL; + + NGAP_PDUSessionResourceModifyResponseTransfer_t message; + + NGAP_QosFlowAddOrModifyResponseList_t *qosFlowAddOrModifyResponseList; + + ogs_assert(pkbuf); + ogs_assert(stream); + + ogs_assert(sess); + smf_ue = sess->smf_ue; + ogs_assert(smf_ue); + + rv = ogs_asn_decode( + &asn_DEF_NGAP_PDUSessionResourceModifyResponseTransfer, + &message, sizeof(message), pkbuf); + if (rv != OGS_OK) { + ogs_error("[%s:%d] Cannot decode NGAP message", + smf_ue->supi, sess->psi); + smf_sbi_send_sm_context_update_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + "No N2 SM Info Type", smf_ue->supi, NULL, NULL); + goto cleanup; + } + + rv = OGS_ERROR; + + qosFlowAddOrModifyResponseList = message.qosFlowAddOrModifyResponseList; + if (qosFlowAddOrModifyResponseList) { + for (i = 0; i < qosFlowAddOrModifyResponseList->list.count; i++) { + NGAP_QosFlowAddOrModifyResponseItem_t + *qosFlowAddOrModifyResponseItem = NULL; + qosFlowAddOrModifyResponseItem = + (NGAP_QosFlowAddOrModifyResponseItem_t *) + qosFlowAddOrModifyResponseList->list.array[i]; + + if (qosFlowAddOrModifyResponseItem) { + qos_flow = smf_qos_flow_find_by_qfi(sess, + qosFlowAddOrModifyResponseItem->qosFlowIdentifier); + } + } + } + + if (!qos_flow) { + ogs_error("[%s:%d] No QoS flow", smf_ue->supi, sess->psi); + smf_sbi_send_sm_context_update_error(stream, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + "No QoS flow", smf_ue->supi, NULL, NULL); + goto cleanup; + } + + dl_far = qos_flow->dl_far; + ogs_assert(dl_far); + + dl_far->apply_action = OGS_PFCP_APPLY_ACTION_FORW; + ogs_pfcp_ip_to_outer_header_creation( + &sess->gnb_n3_ip, + &dl_far->outer_header_creation, + &dl_far->outer_header_creation_len); + dl_far->outer_header_creation.teid = sess->gnb_n3_teid; + + smf_5gc_pfcp_send_qos_flow_modification_request( + qos_flow, stream, OGS_PFCP_MODIFY_ACTIVATE); + + rv = OGS_OK; + +cleanup: + ogs_asn_free( + &asn_DEF_NGAP_PDUSessionResourceModifyResponseTransfer, &message); + return rv; +} diff --git a/src/smf/ngap-handler.h b/src/smf/ngap-handler.h index 97c0e607f..26581382e 100644 --- a/src/smf/ngap-handler.h +++ b/src/smf/ngap-handler.h @@ -28,6 +28,8 @@ extern "C" { int ngap_handle_pdu_session_resource_setup_response_transfer( smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf); +int ngap_handle_pdu_session_resource_modify_response_transfer( + smf_sess_t *sess, ogs_sbi_stream_t *stream, ogs_pkbuf_t *pkbuf); #ifdef __cplusplus } diff --git a/src/smf/nnrf-handler.c b/src/smf/nnrf-handler.c index ef8086e10..195ff5cf8 100644 --- a/src/smf/nnrf-handler.c +++ b/src/smf/nnrf-handler.c @@ -240,7 +240,6 @@ void smf_nnrf_handle_nf_discover( { ogs_sbi_object_t *sbi_object = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL; - ogs_sbi_stream_t *stream = NULL; OpenAPI_search_result_t *SearchResult = NULL; OpenAPI_lnode_t *node = NULL; @@ -249,8 +248,6 @@ void smf_nnrf_handle_nf_discover( ogs_assert(xact); sbi_object = xact->sbi_object; ogs_assert(sbi_object); - stream = xact->assoc_stream; - ogs_assert(stream); ogs_assert(recvmsg); SearchResult = recvmsg->SearchResult; diff --git a/src/smf/npcf-build.c b/src/smf/npcf-build.c index 99756fb6d..a5a33dfaf 100644 --- a/src/smf/npcf-build.c +++ b/src/smf/npcf-build.c @@ -30,6 +30,9 @@ ogs_sbi_request_t *smf_npcf_smpolicycontrol_build_create( ogs_sbi_server_t *server = NULL; OpenAPI_sm_policy_context_data_t SmPolicyContextData; + OpenAPI_ambr_t SubsSessAmbr; + OpenAPI_subscribed_default_qos_t SubsDefQos; + OpenAPI_arp_t Arp; OpenAPI_snssai_t sNssai; ogs_assert(sess); @@ -54,11 +57,6 @@ ogs_sbi_request_t *smf_npcf_smpolicycontrol_build_create( ogs_assert(sess->dnn); SmPolicyContextData.dnn = sess->dnn; - memset(&sNssai, 0, sizeof(sNssai)); - sNssai.sst = sess->s_nssai.sst; - sNssai.sd = ogs_s_nssai_sd_to_string(sess->s_nssai.sd); - SmPolicyContextData.slice_info = &sNssai; - server = ogs_list_first(&ogs_sbi_self()->server_list); ogs_assert(server); @@ -71,6 +69,52 @@ ogs_sbi_request_t *smf_npcf_smpolicycontrol_build_create( SmPolicyContextData.notification_uri = ogs_sbi_server_uri(server, &header); ogs_assert(SmPolicyContextData.notification_uri); + memset(&SubsSessAmbr, 0, sizeof(SubsSessAmbr)); + if (OGS_SBI_FEATURES_IS_SET(sess->smpolicycontrol_features, + OGS_SBI_NPCF_SMPOLICYCONTROL_DN_AUTHORIZATION)) { + if (sess->pdn.ambr.uplink) { + SubsSessAmbr.uplink = ogs_sbi_bitrate_to_string( + sess->pdn.ambr.uplink, OGS_SBI_BITRATE_KBPS); + } + if (sess->pdn.ambr.downlink) { + SubsSessAmbr.downlink = ogs_sbi_bitrate_to_string( + sess->pdn.ambr.downlink, OGS_SBI_BITRATE_KBPS); + } + if (SubsSessAmbr.downlink || SubsSessAmbr.uplink) { + SmPolicyContextData.subs_sess_ambr = &SubsSessAmbr; + } + } + + memset(&Arp, 0, sizeof(Arp)); + if (sess->pdn.qos.arp.pre_emption_capability == + OGS_PDN_PRE_EMPTION_CAPABILITY_ENABLED) + Arp.preempt_cap = OpenAPI_preemption_capability_MAY_PREEMPT; + else + Arp.preempt_cap = OpenAPI_preemption_capability_NOT_PREEMPT; + if (sess->pdn.qos.arp.pre_emption_vulnerability == + OGS_PDN_PRE_EMPTION_CAPABILITY_ENABLED) + Arp.preempt_vuln = OpenAPI_preemption_vulnerability_PREEMPTABLE; + else + Arp.preempt_vuln = OpenAPI_preemption_vulnerability_NOT_PREEMPTABLE; + Arp.priority_level = sess->pdn.qos.arp.priority_level; + + memset(&SubsDefQos, 0, sizeof(SubsDefQos)); + SubsDefQos.arp = &Arp; + SubsDefQos._5qi = sess->pdn.qos.qci; + SubsDefQos.priority_level = sess->pdn.qos.arp.priority_level; + + SmPolicyContextData.subs_def_qos = &SubsDefQos; + + if (sess->smpolicycontrol_features) { + SmPolicyContextData.supp_feat = + ogs_uint64_to_string(sess->smpolicycontrol_features); + } + + memset(&sNssai, 0, sizeof(sNssai)); + sNssai.sst = sess->s_nssai.sst; + sNssai.sd = ogs_s_nssai_sd_to_string(sess->s_nssai.sd); + SmPolicyContextData.slice_info = &sNssai; + message.SmPolicyContextData = &SmPolicyContextData; request = ogs_sbi_build_request(&message); @@ -83,5 +127,11 @@ ogs_sbi_request_t *smf_npcf_smpolicycontrol_build_create( if (sNssai.sd) ogs_free(sNssai.sd); + if (SubsSessAmbr.downlink) ogs_free(SubsSessAmbr.downlink); + if (SubsSessAmbr.uplink) ogs_free(SubsSessAmbr.uplink); + + if (SmPolicyContextData.supp_feat) + ogs_free(SmPolicyContextData.supp_feat); + return request; } diff --git a/src/smf/npcf-handler.c b/src/smf/npcf-handler.c index 816b23806..37efd659c 100644 --- a/src/smf/npcf-handler.c +++ b/src/smf/npcf-handler.c @@ -30,6 +30,8 @@ bool smf_npcf_smpolicycontrol_handle_create( char buf1[OGS_ADDRSTRLEN]; char buf2[OGS_ADDRSTRLEN]; + uint64_t supported_features; + char *strerror = NULL; smf_ue_t *smf_ue = NULL; @@ -40,6 +42,10 @@ bool smf_npcf_smpolicycontrol_handle_create( ogs_pfcp_qer_t *qer = NULL; OpenAPI_sm_policy_decision_t *SmPolicyDecision = NULL; + OpenAPI_lnode_t *node = NULL, *node2 = NULL; + +#define MAX_TRIGGER_ID 128 + bool trigger_results[MAX_TRIGGER_ID]; ogs_sbi_message_t message; ogs_sbi_header_t header; @@ -88,6 +94,262 @@ bool smf_npcf_smpolicycontrol_handle_create( ogs_sbi_header_free(&header); + /* SBI Features */ + if (SmPolicyDecision->supp_feat) { + supported_features = + ogs_uint64_from_string(SmPolicyDecision->supp_feat); + sess->smpolicycontrol_features &= supported_features; + } else { + sess->smpolicycontrol_features = 0; + } + + /********************************************************************* + * Handle Policy Control Request Triggers + *********************************************************************/ + + /* Get policy control request triggers */ + memset(&trigger_results, 0, sizeof(trigger_results)); + OpenAPI_list_for_each(SmPolicyDecision->policy_ctrl_req_triggers, node) { + if (node->data) { + OpenAPI_policy_control_request_trigger_e trigger_id = + (OpenAPI_policy_control_request_trigger_e)node->data; + + ogs_assert(trigger_id < MAX_TRIGGER_ID); + trigger_results[trigger_id] = true; + } + } + + /* Update authorized session-AMBR */ + if (SmPolicyDecision->sess_rules) { + OpenAPI_map_t *SessRuleMap = NULL; + OpenAPI_session_rule_t *SessionRule = NULL; + + OpenAPI_ambr_t *AuthSessAmbr = NULL; + OpenAPI_authorized_default_qos_t *AuthDefQos = NULL; + + OpenAPI_list_for_each(SmPolicyDecision->sess_rules, node) { + SessRuleMap = node->data; + if (!SessRuleMap) { + ogs_error("No SessRuleMap"); + continue; + } + + SessionRule = SessRuleMap->value; + if (!SessionRule) { + ogs_error("No SessionRule"); + continue; + } + + + AuthSessAmbr = SessionRule->auth_sess_ambr; + if (AuthSessAmbr && trigger_results[ + OpenAPI_policy_control_request_trigger_SE_AMBR_CH] == true) { + if (AuthSessAmbr->uplink) + sess->pdn.ambr.uplink = + ogs_sbi_bitrate_from_string(AuthSessAmbr->uplink); + if (AuthSessAmbr->downlink) + sess->pdn.ambr.downlink = + ogs_sbi_bitrate_from_string(AuthSessAmbr->downlink); + } + + AuthDefQos = SessionRule->auth_def_qos; + if (AuthDefQos && trigger_results[ + OpenAPI_policy_control_request_trigger_DEF_QOS_CH] == true) { + sess->pdn.qos.qci = AuthDefQos->_5qi; + sess->pdn.qos.arp.priority_level = + AuthDefQos->priority_level; + if (AuthDefQos->arp) { + sess->pdn.qos.arp.priority_level = + AuthDefQos->arp->priority_level; + if (AuthDefQos->arp->preempt_cap == + OpenAPI_preemption_capability_NOT_PREEMPT) + sess->pdn.qos.arp.pre_emption_capability = + OGS_PDN_PRE_EMPTION_CAPABILITY_DISABLED; + else if (AuthDefQos->arp->preempt_cap == + OpenAPI_preemption_capability_MAY_PREEMPT) + sess->pdn.qos.arp.pre_emption_capability = + OGS_PDN_PRE_EMPTION_CAPABILITY_ENABLED; + + if (AuthDefQos->arp->preempt_vuln == + OpenAPI_preemption_vulnerability_NOT_PREEMPTABLE) + sess->pdn.qos.arp.pre_emption_vulnerability = + OGS_PDN_PRE_EMPTION_VULNERABILITY_DISABLED; + else if (AuthDefQos->arp->preempt_vuln == + OpenAPI_preemption_vulnerability_PREEMPTABLE) + sess->pdn.qos.arp.pre_emption_vulnerability = + OGS_PDN_PRE_EMPTION_VULNERABILITY_ENABLED; + } + } + } + } + + /* Update authorized PCC rule & QoS */ + if (SmPolicyDecision->pcc_rules) { + OpenAPI_map_t *PccRuleMap = NULL; + OpenAPI_pcc_rule_t *PccRule = NULL; + OpenAPI_flow_information_t *FlowInformation = NULL; + OpenAPI_qos_data_t *QosData = NULL; + char *QosId = NULL; + + ogs_assert(sess->num_of_pcc_rule == 0); + OpenAPI_list_for_each(SmPolicyDecision->pcc_rules, node) { + ogs_pcc_rule_t *pcc_rule = &sess->pcc_rule[sess->num_of_pcc_rule]; + + ogs_assert(pcc_rule); + + PccRuleMap = node->data; + if (!PccRuleMap) { + ogs_error("No PccRuleMap"); + continue; + } + + PccRule = PccRuleMap->value; + if (!PccRule) { + ogs_error("No PccRule"); + continue; + } + + if (!PccRule->ref_qos_data) { + ogs_error("No RefQosData"); + continue; + } + + if (!PccRule->ref_qos_data->first) { + ogs_error("No RefQosData->first"); + continue; + } + + QosId = PccRule->ref_qos_data->first->data; + if (!QosId) { + ogs_error("no QosId"); + continue; + } + + if (SmPolicyDecision->qos_decs) { + OpenAPI_map_t *QosDecisionMap = NULL; + OpenAPI_qos_data_t *QosDataIter = NULL; + + OpenAPI_list_for_each(SmPolicyDecision->qos_decs, node2) { + QosDecisionMap = node2->data; + if (!QosDecisionMap) { + ogs_error("No QosDecisionMap"); + continue; + } + + QosDataIter = QosDecisionMap->value; + if (!QosDataIter) { + ogs_error("No QosData"); + continue; + } + + if (!QosDataIter->qos_id) { + ogs_error("No QosId"); + continue; + + } + + if (strcmp(QosId, QosDataIter->qos_id) == 0) { + QosData = QosDataIter; + break; + } + } + } + + if (!QosData) { + ogs_error("no qosData"); + continue; + } + + pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; + pcc_rule->id = ogs_strdup(PccRule->pcc_rule_id); + pcc_rule->precedence = PccRule->precedence; + + if (PccRule->flow_infos) { + ogs_assert(pcc_rule->num_of_flow == 0); + OpenAPI_list_for_each(PccRule->flow_infos, node2) { + ogs_flow_t *flow = &pcc_rule->flow[pcc_rule->num_of_flow]; + + ogs_assert(flow); + + FlowInformation = node2->data; + if (!FlowInformation) { + ogs_error("No FlowInformation"); + continue; + } + + if (FlowInformation->flow_direction == + OpenAPI_flow_direction_UPLINK) + flow->direction = OGS_FLOW_UPLINK_ONLY; + else if (FlowInformation->flow_direction == + OpenAPI_flow_direction_DOWNLINK) + flow->direction = OGS_FLOW_DOWNLINK_ONLY; + else { + ogs_fatal("Unsupported direction [%d]", + FlowInformation->flow_direction); + ogs_assert_if_reached(); + } + + flow->description = + ogs_strdup(FlowInformation->flow_description); + + pcc_rule->num_of_flow++; + } + } + + pcc_rule->qos.qci = QosData->_5qi; + pcc_rule->qos.arp.priority_level = QosData->priority_level; + + if (QosData->arp) { + pcc_rule->qos.arp.priority_level = QosData->arp->priority_level; + if (QosData->arp->preempt_cap == + OpenAPI_preemption_capability_NOT_PREEMPT) + pcc_rule->qos.arp.pre_emption_capability = + OGS_PDN_PRE_EMPTION_CAPABILITY_DISABLED; + else if (QosData->arp->preempt_cap == + OpenAPI_preemption_capability_MAY_PREEMPT) + pcc_rule->qos.arp.pre_emption_capability = + OGS_PDN_PRE_EMPTION_CAPABILITY_ENABLED; + + if (QosData->arp->preempt_vuln == + OpenAPI_preemption_vulnerability_NOT_PREEMPTABLE) + pcc_rule->qos.arp.pre_emption_vulnerability = + OGS_PDN_PRE_EMPTION_VULNERABILITY_DISABLED; + else if (QosData->arp->preempt_vuln == + OpenAPI_preemption_vulnerability_PREEMPTABLE) + pcc_rule->qos.arp.pre_emption_vulnerability = + OGS_PDN_PRE_EMPTION_VULNERABILITY_ENABLED; + } + + if (QosData->maxbr_ul) + pcc_rule->qos.mbr.uplink = + ogs_sbi_bitrate_from_string(QosData->maxbr_ul); + if (QosData->maxbr_dl) + pcc_rule->qos.mbr.downlink = + ogs_sbi_bitrate_from_string(QosData->maxbr_dl); + + if (QosData->gbr_ul) + pcc_rule->qos.gbr.uplink = + ogs_sbi_bitrate_from_string(QosData->gbr_ul); + if (QosData->gbr_dl) + pcc_rule->qos.gbr.downlink = + ogs_sbi_bitrate_from_string(QosData->gbr_dl); + + if (pcc_rule->qos.mbr.downlink || pcc_rule->qos.mbr.uplink || + pcc_rule->qos.gbr.downlink || pcc_rule->qos.gbr.uplink) { + if (pcc_rule->qos.mbr.downlink == 0) + pcc_rule->qos.mbr.downlink = MAX_BIT_RATE; + if (pcc_rule->qos.mbr.uplink == 0) + pcc_rule->qos.mbr.uplink = MAX_BIT_RATE; + if (pcc_rule->qos.gbr.downlink == 0) + pcc_rule->qos.gbr.downlink = MAX_BIT_RATE; + if (pcc_rule->qos.gbr.uplink == 0) + pcc_rule->qos.gbr.uplink = MAX_BIT_RATE; + } + + sess->num_of_pcc_rule++; + } + } + /********************************************************************* * Send PFCP Session Establiashment Request to the UPF *********************************************************************/ @@ -109,6 +371,9 @@ bool smf_npcf_smpolicycontrol_handle_create( qos_flow = smf_qos_flow_add(sess); ogs_assert(qos_flow); + /* Copy Session QoS information to Default QoS Flow */ + memcpy(&qos_flow->qos, &sess->pdn.qos, sizeof(ogs_qos_t)); + /* Setup QER */ qer = qos_flow->qer; ogs_assert(qer); @@ -134,9 +399,12 @@ bool smf_npcf_smpolicycontrol_handle_create( sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : ""); /* Set UPF-N3 TEID & ADDR to the Default UL PDR */ + ogs_assert(sess->pfcp_node); if (sess->pfcp_node->up_function_features.ftup) { ul_pdr->f_teid.ch = 1; - ul_pdr->f_teid_len = 1; + ul_pdr->f_teid.chid = 1; + ul_pdr->f_teid.choose_id = OGS_PFCP_DEFAULT_CHOOSE_ID; + ul_pdr->f_teid_len = 2; } else { resource = ogs_pfcp_gtpu_resource_find( &sess->pfcp_node->gtpu_resource_list, diff --git a/src/smf/nsmf-handler.c b/src/smf/nsmf-handler.c index e9fcdbe81..9c78aacf1 100644 --- a/src/smf/nsmf-handler.c +++ b/src/smf/nsmf-handler.c @@ -154,6 +154,9 @@ bool smf_nsmf_handle_create_sm_context( } ogs_sbi_parse_plmn_id_nid(&sess->plmn_id, servingNetwork); + + sess->rat_type = SmContextCreateData->rat_type; + ogs_sbi_parse_nr_location(&sess->nr_tai, &sess->nr_cgi, NrLocation); if (NrLocation->ue_location_timestamp) ogs_sbi_time_from_string(&sess->ue_location_timestamp, @@ -188,6 +191,11 @@ bool smf_nsmf_handle_create_sm_context( sess->dnn = ogs_strdup(SmContextCreateData->dnn); } + if (SmContextCreateData->pcf_id) { + if (sess->pcf_id) ogs_free(sess->pcf_id); + sess->pcf_id = ogs_strdup(SmContextCreateData->pcf_id); + } + /* * NOTE : The pkbuf created in the SBI message will be removed * from ogs_sbi_message_free(). diff --git a/src/smf/pfcp-path.c b/src/smf/pfcp-path.c index 1720a0386..89f0085f9 100644 --- a/src/smf/pfcp-path.c +++ b/src/smf/pfcp-path.c @@ -291,11 +291,14 @@ void smf_5gc_pfcp_send_session_modification_request( h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE; h.seid = sess->upf_n4_seid; - n4buf = smf_5gc_n4_build_session_modification_request(h.type, sess, flags); + n4buf = smf_n4_build_session_modification_request(h.type, sess, flags); ogs_expect_or_return(n4buf); xact = ogs_pfcp_xact_local_create( - sess->pfcp_node, &h, n4buf, sess_5gc_timeout, sess); + sess->pfcp_node, &h, n4buf, sess_5gc_timeout, + /* We'll use xact->data to find out + * Modification Type(Session or QosFlow) */ + NULL); ogs_expect_or_return(xact); xact->assoc_stream = stream; xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION; @@ -317,8 +320,6 @@ void smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow, sess = qos_flow->sess; ogs_assert(sess); - ogs_assert(stream); - memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE; h.seid = sess->upf_n4_seid; @@ -327,7 +328,10 @@ void smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow, ogs_expect_or_return(n4buf); xact = ogs_pfcp_xact_local_create( - sess->pfcp_node, &h, n4buf, sess_5gc_timeout, qos_flow); + sess->pfcp_node, &h, n4buf, sess_5gc_timeout, + /* We'll use xact->data to find out + * Modification Type(Session or QosFlow) */ + qos_flow); ogs_expect_or_return(xact); xact->assoc_stream = stream; diff --git a/src/smf/s5c-handler.c b/src/smf/s5c-handler.c index 36473f359..8c9bcd26a 100644 --- a/src/smf/s5c-handler.c +++ b/src/smf/s5c-handler.c @@ -589,74 +589,82 @@ static int reconfigure_packet_filter(smf_pf_t *pf, ogs_gtp_tft_t *tft, int i) memset(&pf->ipfw_rule, 0, sizeof(ogs_ipfw_rule_t)); pf->direction = tft->pf[i].direction; - for (j = 0; j < tft->pf[i].num_of_component; j++) { - switch(tft->pf[i].component[j].type) { - case GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE: - pf->ipfw_rule.proto = tft->pf[i].component[j].proto; + for (j = 0; j < tft->pf[i].content.num_of_component; j++) { + switch(tft->pf[i].content.component[j].type) { + case OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE: + pf->ipfw_rule.proto = tft->pf[i].content.component[j].proto; break; - case GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE: pf->ipfw_rule.ipv4_dst = 1; - pf->ipfw_rule.ip.dst.addr[0] = tft->pf[i].component[j].ipv4.addr; - pf->ipfw_rule.ip.dst.mask[0] = tft->pf[i].component[j].ipv4.mask; + pf->ipfw_rule.ip.dst.addr[0] = + tft->pf[i].content.component[j].ipv4.addr; + pf->ipfw_rule.ip.dst.mask[0] = + tft->pf[i].content.component[j].ipv4.mask; break; - case GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE: pf->ipfw_rule.ipv4_src = 1; - pf->ipfw_rule.ip.src.addr[0] = tft->pf[i].component[j].ipv4.addr; - pf->ipfw_rule.ip.src.mask[0] = tft->pf[i].component[j].ipv4.mask; + pf->ipfw_rule.ip.src.addr[0] = + tft->pf[i].content.component[j].ipv4.addr; + pf->ipfw_rule.ip.src.mask[0] = + tft->pf[i].content.component[j].ipv4.mask; break; - case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_TYPE: pf->ipfw_rule.ipv6_dst = 1; memcpy(pf->ipfw_rule.ip.dst.addr, - tft->pf[i].component[j].ipv6_mask.addr, + tft->pf[i].content.component[j].ipv6_mask.addr, sizeof(pf->ipfw_rule.ip.dst.addr)); memcpy(pf->ipfw_rule.ip.dst.mask, - tft->pf[i].component[j].ipv6_mask.mask, + tft->pf[i].content.component[j].ipv6_mask.mask, sizeof(pf->ipfw_rule.ip.dst.mask)); break; - case GTP_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE: + case OGS_PACKET_FILTER_IPV6_REMOTE_ADDRESS_PREFIX_LENGTH_TYPE: pf->ipfw_rule.ipv6_dst = 1; memcpy(pf->ipfw_rule.ip.dst.addr, - tft->pf[i].component[j].ipv6_mask.addr, + tft->pf[i].content.component[j].ipv6_mask.addr, sizeof(pf->ipfw_rule.ip.dst.addr)); n2mask((struct in6_addr *)pf->ipfw_rule.ip.dst.mask, - tft->pf[i].component[j].ipv6.prefixlen); + tft->pf[i].content.component[j].ipv6.prefixlen); break; - case GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE: + case OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE: pf->ipfw_rule.ipv6_src = 1; memcpy(pf->ipfw_rule.ip.src.addr, - tft->pf[i].component[j].ipv6_mask.addr, + tft->pf[i].content.component[j].ipv6_mask.addr, sizeof(pf->ipfw_rule.ip.src.addr)); memcpy(pf->ipfw_rule.ip.src.mask, - tft->pf[i].component[j].ipv6_mask.mask, + tft->pf[i].content.component[j].ipv6_mask.mask, sizeof(pf->ipfw_rule.ip.src.mask)); break; - case GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE: + case OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE: pf->ipfw_rule.ipv6_src = 1; memcpy(pf->ipfw_rule.ip.src.addr, - tft->pf[i].component[j].ipv6_mask.addr, + tft->pf[i].content.component[j].ipv6_mask.addr, sizeof(pf->ipfw_rule.ip.src.addr)); n2mask((struct in6_addr *)pf->ipfw_rule.ip.src.mask, - tft->pf[i].component[j].ipv6.prefixlen); + tft->pf[i].content.component[j].ipv6.prefixlen); break; - case GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE: + case OGS_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE: pf->ipfw_rule.port.src.low = pf->ipfw_rule.port.src.high = - tft->pf[i].component[j].port.low; + tft->pf[i].content.component[j].port.low; break; - case GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE: + case OGS_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE: pf->ipfw_rule.port.dst.low = pf->ipfw_rule.port.dst.high = - tft->pf[i].component[j].port.low; + tft->pf[i].content.component[j].port.low; break; - case GTP_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE: - pf->ipfw_rule.port.src.low = tft->pf[i].component[j].port.low; - pf->ipfw_rule.port.src.high = tft->pf[i].component[j].port.high; + case OGS_PACKET_FILTER_LOCAL_PORT_RANGE_TYPE: + pf->ipfw_rule.port.src.low = + tft->pf[i].content.component[j].port.low; + pf->ipfw_rule.port.src.high = + tft->pf[i].content.component[j].port.high; break; - case GTP_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE: - pf->ipfw_rule.port.dst.low = tft->pf[i].component[j].port.low; - pf->ipfw_rule.port.dst.high = tft->pf[i].component[j].port.high; + case OGS_PACKET_FILTER_REMOTE_PORT_RANGE_TYPE: + pf->ipfw_rule.port.dst.low = + tft->pf[i].content.component[j].port.low; + pf->ipfw_rule.port.dst.high = + tft->pf[i].content.component[j].port.high; break; default: ogs_error("Unknown Packet Filter Type(%d)", - tft->pf[i].component[j].type); + tft->pf[i].content.component[j].type); return OGS_ERROR; } } @@ -810,7 +818,7 @@ void smf_s5c_handle_bearer_resource_command( for (i = 0; i < tft.num_of_packet_filter; i++) { pf = smf_pf_find_by_id(bearer, tft.pf[i].identifier+1); if (!pf) - pf = smf_pf_add(bearer, tft.pf[i].precedence); + pf = smf_pf_add(bearer); ogs_assert(pf); if (reconfigure_packet_filter(pf, &tft, i) < 0) { diff --git a/src/smf/sbi-path.c b/src/smf/sbi-path.c index a73ee0c38..59b0c2a16 100644 --- a/src/smf/sbi-path.c +++ b/src/smf/sbi-path.c @@ -135,8 +135,9 @@ void smf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type, ogs_assert(stream); ogs_assert(build); - xact = ogs_sbi_xact_add(target_nf_type, &sess->sbi, data, - (ogs_sbi_build_f)build, smf_timer_sbi_client_wait_expire); + xact = ogs_sbi_xact_add(target_nf_type, &sess->sbi, + (ogs_sbi_build_f)build, sess, data, + smf_timer_sbi_client_wait_expire); ogs_assert(xact); xact->assoc_stream = stream; @@ -150,6 +151,38 @@ void smf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type, } } +void smf_namf_comm_send_n1_n2_message_transfer( + smf_sess_t *sess, int state, + ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf) +{ + ogs_sbi_xact_t *xact = NULL; + smf_ue_t *smf_ue = NULL; + smf_n1_n2_message_transfer_data_t data; + + ogs_assert(state); + ogs_assert(n1smbuf); + ogs_assert(n2smbuf); + + ogs_assert(sess); + smf_ue = sess->smf_ue; + ogs_assert(smf_ue); + + memset(&data, 0, sizeof(data)); + data.state = state; + data.n1smbuf = n1smbuf; + data.n2smbuf = n2smbuf; + + xact = ogs_sbi_xact_add(OpenAPI_nf_type_AMF, &sess->sbi, + (ogs_sbi_build_f)smf_namf_comm_build_n1_n2_message_transfer, + sess, &data, smf_timer_sbi_client_wait_expire); + ogs_assert(xact); + + xact->state = state; + + ogs_sbi_discover_and_send(xact, + (ogs_fsm_handler_t)smf_nf_state_registered, client_cb); +} + void smf_sbi_send_response(ogs_sbi_stream_t *stream, int status) { ogs_sbi_message_t sendmsg; diff --git a/src/smf/sbi-path.h b/src/smf/sbi-path.h index 9f5155d02..4955269ab 100644 --- a/src/smf/sbi-path.h +++ b/src/smf/sbi-path.h @@ -34,10 +34,15 @@ int smf_sbi_open(void); void smf_sbi_close(void); void smf_sbi_send(ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_xact_t *xact); + void smf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type, smf_sess_t *sess, ogs_sbi_stream_t *stream, void *data, ogs_sbi_request_t *(*build)(smf_sess_t *sess, void *data)); +void smf_namf_comm_send_n1_n2_message_transfer( + smf_sess_t *sess, int state, + ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf); + void smf_sbi_send_response(ogs_sbi_stream_t *stream, int status); void smf_sbi_send_sm_context_create_error( diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c index 939cdc933..e64651f08 100644 --- a/src/smf/smf-sm.c +++ b/src/smf/smf-sm.c @@ -213,7 +213,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) break; } - ogs_diam_gx_message_free(gx_message); + ogs_session_data_free(&gx_message->session_data); ogs_pkbuf_free(recvbuf); break; case SMF_EVT_N4_MESSAGE: @@ -541,6 +541,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) e->sess = sess; e->sbi.message = &sbi_message; e->sbi.data = sbi_xact->assoc_stream; + e->sbi.state = sbi_xact->state; ogs_sbi_xact_remove(sbi_xact); diff --git a/src/udm/nnrf-handler.c b/src/udm/nnrf-handler.c index 0faa0f615..dd900371e 100644 --- a/src/udm/nnrf-handler.c +++ b/src/udm/nnrf-handler.c @@ -240,7 +240,6 @@ void udm_nnrf_handle_nf_discover( { ogs_sbi_object_t *sbi_object = NULL; ogs_sbi_nf_instance_t *nf_instance = NULL; - ogs_sbi_stream_t *stream = NULL; OpenAPI_search_result_t *SearchResult = NULL; OpenAPI_lnode_t *node = NULL; @@ -249,8 +248,6 @@ void udm_nnrf_handle_nf_discover( ogs_assert(xact); sbi_object = xact->sbi_object; ogs_assert(sbi_object); - stream = xact->assoc_stream; - ogs_assert(stream); ogs_assert(recvmsg); SearchResult = recvmsg->SearchResult; diff --git a/src/udm/sbi-path.c b/src/udm/sbi-path.c index 40b30402f..46d0d9d9d 100644 --- a/src/udm/sbi-path.c +++ b/src/udm/sbi-path.c @@ -138,8 +138,9 @@ void udm_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type, ogs_assert(stream); ogs_assert(build); - xact = ogs_sbi_xact_add(target_nf_type, &udm_ue->sbi, data, - (ogs_sbi_build_f)build, udm_timer_sbi_client_wait_expire); + xact = ogs_sbi_xact_add(target_nf_type, &udm_ue->sbi, + (ogs_sbi_build_f)build, udm_ue, data, + udm_timer_sbi_client_wait_expire); ogs_assert(xact); xact->assoc_stream = stream; diff --git a/src/udr/nudr-handler.c b/src/udr/nudr-handler.c index 4f17c8871..0dd7b0714 100644 --- a/src/udr/nudr-handler.c +++ b/src/udr/nudr-handler.c @@ -484,19 +484,8 @@ bool udr_nudr_dr_handle_subscription_provisioned( } if (!pdn->ambr.uplink && !pdn->ambr.downlink) { - if (!subscription_data.ambr.uplink && - !subscription_data.ambr.downlink) { - ogs_error("No Session-AMBR"); - ogs_error("No UE-AMBR"); - continue; - } - - pdn->ambr.uplink = subscription_data.ambr.uplink; - pdn->ambr.downlink = subscription_data.ambr.downlink; - ogs_warn("No Session-AMBR : Set UE-AMBR to Session-AMBR " - "[DL-%lld:UL-%lld]", - (long long)pdn->ambr.downlink, - (long long)pdn->ambr.uplink); + ogs_error("No Session-AMBR"); + continue; } dnnConfiguration = ogs_calloc(1, sizeof(*dnnConfiguration)); diff --git a/tests/app/epc-init.c b/tests/app/epc-init.c index e05eed04a..c84f0ffe2 100644 --- a/tests/app/epc-init.c +++ b/tests/app/epc-init.c @@ -19,7 +19,6 @@ #include "test-app.h" -static ogs_thread_t *nrf_thread = NULL; static ogs_thread_t *pcrf_thread = NULL; static ogs_thread_t *upf_thread = NULL; static ogs_thread_t *smf_thread = NULL; @@ -48,8 +47,6 @@ int app_initialize(const char *const argv[]) argv_out[i] = NULL; } - if (ogs_app()->parameter.no_nrf == 0) - nrf_thread = test_child_create("nrf", argv_out); if (ogs_app()->parameter.no_hss == 0) hss_thread = test_child_create("hss", argv_out); if (ogs_app()->parameter.no_pcrf == 0) @@ -90,7 +87,6 @@ void app_terminate(void) if (hss_thread) ogs_thread_destroy(hss_thread); if (pcrf_thread) ogs_thread_destroy(pcrf_thread); - if (nrf_thread) ogs_thread_destroy(nrf_thread); } void test_epc_init(void) diff --git a/tests/common/esm-build.c b/tests/common/esm-build.c index a2be7dce1..45b8f432d 100644 --- a/tests/common/esm-build.c +++ b/tests/common/esm-build.c @@ -413,14 +413,14 @@ ogs_pkbuf_t *testesm_build_bearer_resource_modification_request( tft.pf[0].direction = 1; tft.pf[0].identifier = 0; tft.pf[0].precedence = 0x0f; - tft.pf[0].length = 9; - tft.pf[0].component[0].type = - GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; + tft.pf[0].content.length = 9; + tft.pf[0].content.component[0].type = + OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; rv = ogs_ipsubnet(&ipsubnet, "201.20.2.5", NULL); ogs_assert(rv == OGS_OK); - tft.pf[0].component[0].ipv4.addr = ipsubnet.sub[0]; - tft.pf[0].component[0].ipv4.mask = ipsubnet.mask[0]; - tft.pf[0].num_of_component = 1; + tft.pf[0].content.component[0].ipv4.addr = ipsubnet.sub[0]; + tft.pf[0].content.component[0].ipv4.mask = ipsubnet.mask[0]; + tft.pf[0].content.num_of_component = 1; } else if (tft.code == OGS_GTP_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT) { tft.num_of_packet_filter = 1; @@ -431,22 +431,22 @@ ogs_pkbuf_t *testesm_build_bearer_resource_modification_request( rv = ogs_ipsubnet(&ipsubnet, "cafe::9", "120"); ogs_assert(rv == OGS_OK); #if 1 - tft.pf[0].length = 18; - tft.pf[0].component[0].type = - GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE; - memcpy(tft.pf[0].component[0].ipv6.addr, ipsubnet.sub, - sizeof(tft.pf[0].component[0].ipv6.addr)); - tft.pf[0].component[0].ipv6.prefixlen = 120; + tft.pf[0].content.length = 18; + tft.pf[0].content.component[0].type = + OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_PREFIX_LENGTH_TYPE; + memcpy(tft.pf[0].content.component[0].ipv6.addr, ipsubnet.sub, + sizeof(tft.pf[0].content.component[0].ipv6.addr)); + tft.pf[0].content.component[0].ipv6.prefixlen = 120; #else - tft.pf[0].length = 33; - tft.pf[0].component[0].type = - GTP_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE; - memcpy(tft.pf[0].component[0].ipv6_mask.addr, ipsubnet.sub, - sizeof(tft.pf[0].component[0].ipv6_mask.addr)); - memcpy(tft.pf[0].component[0].ipv6_mask.mask, ipsubnet.mask, - sizeof(tft.pf[0].component[0].ipv6_mask.mask)); + tft.pf[0].content.length = 33; + tft.pf[0].content.component[0].type = + OGS_PACKET_FILTER_IPV6_LOCAL_ADDRESS_TYPE; + memcpy(tft.pf[0].content.component[0].ipv6_mask.addr, ipsubnet.sub, + sizeof(tft.pf[0].content.component[0].ipv6_mask.addr)); + memcpy(tft.pf[0].content.component[0].ipv6_mask.mask, ipsubnet.mask, + sizeof(tft.pf[0].content.component[0].ipv6_mask.mask)); #endif - tft.pf[0].num_of_component = 1; + tft.pf[0].content.num_of_component = 1; } else if (tft.code == OGS_GTP_TFT_CODE_CREATE_NEW_TFT) { tft.num_of_packet_filter = 4; @@ -454,98 +454,98 @@ ogs_pkbuf_t *testesm_build_bearer_resource_modification_request( tft.pf[0].direction = 1; tft.pf[0].identifier = 0; tft.pf[0].precedence = 0x01; - tft.pf[0].length = 0x17; - tft.pf[0].component[0].type = - GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE; - tft.pf[0].component[0].proto = 0x11; /* UDP */ - tft.pf[0].component[1].type = - GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; + tft.pf[0].content.length = 0x17; + tft.pf[0].content.component[0].type = + OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE; + tft.pf[0].content.component[0].proto = 0x11; /* UDP */ + tft.pf[0].content.component[1].type = + OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; rv = ogs_ipsubnet(&ipsubnet, "172.20.166.84", NULL); ogs_assert(rv == OGS_OK); - tft.pf[0].component[1].ipv4.addr = ipsubnet.sub[0]; - tft.pf[0].component[1].ipv4.mask = ipsubnet.mask[0]; - tft.pf[0].component[2].type = - GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; + tft.pf[0].content.component[1].ipv4.addr = ipsubnet.sub[0]; + tft.pf[0].content.component[1].ipv4.mask = ipsubnet.mask[0]; + tft.pf[0].content.component[2].type = + OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; rv = ogs_ipsubnet(&ipsubnet, "172.18.128.20", NULL); ogs_assert(rv == OGS_OK); - tft.pf[0].component[2].ipv4.addr = ipsubnet.sub[0]; - tft.pf[0].component[2].ipv4.mask = ipsubnet.mask[0]; - tft.pf[0].component[3].type = - GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE; - tft.pf[0].component[3].port.low = 20001; - tft.pf[0].num_of_component = 4; + tft.pf[0].content.component[2].ipv4.addr = ipsubnet.sub[0]; + tft.pf[0].content.component[2].ipv4.mask = ipsubnet.mask[0]; + tft.pf[0].content.component[3].type = + OGS_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE; + tft.pf[0].content.component[3].port.low = 20001; + tft.pf[0].content.num_of_component = 4; tft.pf[1].direction = 2; tft.pf[1].identifier = 1; tft.pf[1].precedence = 0x02; - tft.pf[1].length = 0x17; - tft.pf[1].component[0].type = - GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE; - tft.pf[1].component[0].proto = 0x11; /* UDP */ - tft.pf[1].component[1].type = - GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; + tft.pf[1].content.length = 0x17; + tft.pf[1].content.component[0].type = + OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE; + tft.pf[1].content.component[0].proto = 0x11; /* UDP */ + tft.pf[1].content.component[1].type = + OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; rv = ogs_ipsubnet(&ipsubnet, "172.20.166.84", NULL); ogs_assert(rv == OGS_OK); - tft.pf[1].component[1].ipv4.addr = ipsubnet.sub[0]; - tft.pf[1].component[1].ipv4.mask = ipsubnet.mask[0]; - tft.pf[1].component[2].type = - GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; + tft.pf[1].content.component[1].ipv4.addr = ipsubnet.sub[0]; + tft.pf[1].content.component[1].ipv4.mask = ipsubnet.mask[0]; + tft.pf[1].content.component[2].type = + OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; rv = ogs_ipsubnet(&ipsubnet, "172.18.128.20", NULL); ogs_assert(rv == OGS_OK); - tft.pf[1].component[2].ipv4.addr = ipsubnet.sub[0]; - tft.pf[1].component[2].ipv4.mask = ipsubnet.mask[0]; - tft.pf[1].component[3].type = - GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE; - tft.pf[1].component[3].port.low = 20360; - tft.pf[1].num_of_component = 4; + tft.pf[1].content.component[2].ipv4.addr = ipsubnet.sub[0]; + tft.pf[1].content.component[2].ipv4.mask = ipsubnet.mask[0]; + tft.pf[1].content.component[3].type = + OGS_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE; + tft.pf[1].content.component[3].port.low = 20360; + tft.pf[1].content.num_of_component = 4; tft.pf[2].direction = 1; tft.pf[2].identifier = 2; tft.pf[2].precedence = 0x03; - tft.pf[2].length = 0x17; - tft.pf[2].component[0].type = - GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE; - tft.pf[2].component[0].proto = 0x11; /* UDP */ - tft.pf[2].component[1].type = - GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; + tft.pf[2].content.length = 0x17; + tft.pf[2].content.component[0].type = + OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE; + tft.pf[2].content.component[0].proto = 0x11; /* UDP */ + tft.pf[2].content.component[1].type = + OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; rv = ogs_ipsubnet(&ipsubnet, "172.20.166.84", NULL); ogs_assert(rv == OGS_OK); - tft.pf[2].component[1].ipv4.addr = ipsubnet.sub[0]; - tft.pf[2].component[1].ipv4.mask = ipsubnet.mask[0]; - tft.pf[2].component[2].type = - GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; + tft.pf[2].content.component[1].ipv4.addr = ipsubnet.sub[0]; + tft.pf[2].content.component[1].ipv4.mask = ipsubnet.mask[0]; + tft.pf[2].content.component[2].type = + OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; rv = ogs_ipsubnet(&ipsubnet, "172.18.128.20", NULL); ogs_assert(rv == OGS_OK); - tft.pf[2].component[2].ipv4.addr = ipsubnet.sub[0]; - tft.pf[2].component[2].ipv4.mask = ipsubnet.mask[0]; - tft.pf[2].component[3].type = - GTP_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE; - tft.pf[2].component[3].port.low = 20002; - tft.pf[2].num_of_component = 4; + tft.pf[2].content.component[2].ipv4.addr = ipsubnet.sub[0]; + tft.pf[2].content.component[2].ipv4.mask = ipsubnet.mask[0]; + tft.pf[2].content.component[3].type = + OGS_PACKET_FILTER_SINGLE_REMOTE_PORT_TYPE; + tft.pf[2].content.component[3].port.low = 20002; + tft.pf[2].content.num_of_component = 4; tft.pf[3].direction = 2; tft.pf[3].identifier = 3; tft.pf[3].precedence = 0x04; - tft.pf[3].length = 0x17; - tft.pf[3].component[0].type = - GTP_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE; - tft.pf[3].component[0].proto = 0x11; /* UDP */ - tft.pf[3].component[1].type = - GTP_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; + tft.pf[3].content.length = 0x17; + tft.pf[3].content.component[0].type = + OGS_PACKET_FILTER_PROTOCOL_IDENTIFIER_NEXT_HEADER_TYPE; + tft.pf[3].content.component[0].proto = 0x11; /* UDP */ + tft.pf[3].content.component[1].type = + OGS_PACKET_FILTER_IPV4_LOCAL_ADDRESS_TYPE; rv = ogs_ipsubnet(&ipsubnet, "172.20.166.84", NULL); ogs_assert(rv == OGS_OK); - tft.pf[3].component[1].ipv4.addr = ipsubnet.sub[0]; - tft.pf[3].component[1].ipv4.mask = ipsubnet.mask[0]; - tft.pf[3].component[2].type = - GTP_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; + tft.pf[3].content.component[1].ipv4.addr = ipsubnet.sub[0]; + tft.pf[3].content.component[1].ipv4.mask = ipsubnet.mask[0]; + tft.pf[3].content.component[2].type = + OGS_PACKET_FILTER_IPV4_REMOTE_ADDRESS_TYPE; rv = ogs_ipsubnet(&ipsubnet, "172.18.128.20", NULL); ogs_assert(rv == OGS_OK); - tft.pf[3].component[2].ipv4.addr = ipsubnet.sub[0]; - tft.pf[3].component[2].ipv4.mask = ipsubnet.mask[0]; - tft.pf[3].component[3].type = - GTP_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE; - tft.pf[3].component[3].port.low = 20361; - tft.pf[3].num_of_component = 4; + tft.pf[3].content.component[2].ipv4.addr = ipsubnet.sub[0]; + tft.pf[3].content.component[2].ipv4.mask = ipsubnet.mask[0]; + tft.pf[3].content.component[3].type = + OGS_PACKET_FILTER_SINGLE_LOCAL_PORT_TYPE; + tft.pf[3].content.component[3].port.low = 20361; + tft.pf[3].content.num_of_component = 4; } else if (tft.code == OGS_GTP_TFT_CODE_DELETE_PACKET_FILTERS_FROM_EXISTING) { tft.num_of_packet_filter = 4; diff --git a/tests/common/gsm-build.c b/tests/common/gsm-build.c index 8a11cd564..65dbe907c 100644 --- a/tests/common/gsm-build.c +++ b/tests/common/gsm-build.c @@ -89,6 +89,32 @@ ogs_pkbuf_t *testgsm_build_pdu_session_establishment_request( return ogs_nas_5gs_plain_encode(&message); } +ogs_pkbuf_t *testgsm_build_pdu_session_modification_complete( + test_sess_t *test_sess) +{ + ogs_nas_5gs_message_t message; + ogs_nas_5gs_pdu_session_modification_complete_t + *pdu_session_modification_complete = + &message.gsm.pdu_session_modification_complete; + + test_ue_t *test_ue = NULL; + ogs_pkbuf_t *pkbuf = NULL; + + ogs_assert(test_sess); + test_ue = test_sess; + ogs_assert(test_ue); + + memset(&message, 0, sizeof(message)); + + message.gsm.h.extended_protocol_discriminator = + OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GSM; + message.gsm.h.pdu_session_identity = test_sess->psi; + message.gsm.h.procedure_transaction_identity = test_sess->pti; + message.gsm.h.message_type = OGS_NAS_5GS_PDU_SESSION_MODIFICATION_COMPLETE; + + return ogs_nas_5gs_plain_encode(&message); +} + ogs_pkbuf_t *testgsm_build_pdu_session_release_request(test_sess_t *test_sess) { ogs_nas_5gs_message_t message; diff --git a/tests/common/gsm-build.h b/tests/common/gsm-build.h index 165a4b161..495ee983c 100644 --- a/tests/common/gsm-build.h +++ b/tests/common/gsm-build.h @@ -26,6 +26,8 @@ extern "C" { ogs_pkbuf_t *testgsm_build_pdu_session_establishment_request( test_sess_t *test_sess); +ogs_pkbuf_t *testgsm_build_pdu_session_modification_complete( + test_sess_t *test_sess); ogs_pkbuf_t *testgsm_build_pdu_session_release_request(test_sess_t *test_sess); ogs_pkbuf_t *testgsm_build_pdu_session_release_complete(test_sess_t *test_sess); diff --git a/tests/common/gsm-handler.c b/tests/common/gsm-handler.c index 5f60ac3d9..16346e60f 100644 --- a/tests/common/gsm-handler.c +++ b/tests/common/gsm-handler.c @@ -56,3 +56,11 @@ void testgsm_handle_pdu_session_establishment_accept(test_sess_t *sess, } } + +void testgsm_handle_pdu_session_modification_command(test_sess_t *sess, + ogs_nas_5gs_pdu_session_modification_command_t + *pdu_session_modification_command) +{ + ogs_assert(sess); + ogs_assert(pdu_session_modification_command); +} diff --git a/tests/common/gsm-handler.h b/tests/common/gsm-handler.h index 02e8a789e..2858b27a0 100644 --- a/tests/common/gsm-handler.h +++ b/tests/common/gsm-handler.h @@ -27,6 +27,9 @@ extern "C" { void testgsm_handle_pdu_session_establishment_accept(test_sess_t *sess, ogs_nas_5gs_pdu_session_establishment_accept_t *pdu_session_establishment_accept); +void testgsm_handle_pdu_session_modification_command(test_sess_t *sess, + ogs_nas_5gs_pdu_session_modification_command_t + *pdu_session_modification_command); #ifdef __cplusplus } diff --git a/tests/common/nas-path.c b/tests/common/nas-path.c index 8c5e43de2..18c09cce6 100644 --- a/tests/common/nas-path.c +++ b/tests/common/nas-path.c @@ -79,11 +79,17 @@ void testgsm_recv(test_sess_t *sess, ogs_pkbuf_t *pkbuf) rv = ogs_nas_5gsm_decode(&message, pkbuf); ogs_assert(rv == OGS_OK); + sess->pti = message.gsm.h.procedure_transaction_identity; + switch (message.gsm.h.message_type) { case OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_ACCEPT: testgsm_handle_pdu_session_establishment_accept(sess, &message.gsm.pdu_session_establishment_accept); break; + case OGS_NAS_5GS_PDU_SESSION_MODIFICATION_COMMAND: + testgsm_handle_pdu_session_modification_command(sess, + &message.gsm.pdu_session_modification_command); + break; case OGS_NAS_5GS_PDU_SESSION_RELEASE_COMMAND: break; default: diff --git a/tests/common/ngap-build.c b/tests/common/ngap-build.c index 79b4e78ce..4fd1513b9 100644 --- a/tests/common/ngap-build.c +++ b/tests/common/ngap-build.c @@ -20,6 +20,8 @@ #include "test-common.h" static ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response_trasfer( + test_sess_t *sess); +static ogs_pkbuf_t *testngap_build_pdu_session_resource_modify_response_trasfer( test_bearer_t *qos_flow); ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id, uint8_t bitsize) @@ -448,8 +450,6 @@ ogs_pkbuf_t *testngap_build_initial_context_setup_response( OCTET_STRING_t *transfer = NULL; ogs_pkbuf_t *n2smbuf = NULL; - test_bearer_t *bearer = NULL; - ie = CALLOC(1, sizeof(NGAP_InitialContextSetupResponseIEs_t)); ASN_SEQUENCE_ADD(&InitialContextSetupResponse->protocolIEs, ie); @@ -465,11 +465,8 @@ ogs_pkbuf_t *testngap_build_initial_context_setup_response( PDUSessionItem->pDUSessionID = sess->psi; - bearer = ogs_list_first(&sess->bearer_list); - ogs_assert(bearer); - n2smbuf = testngap_build_pdu_session_resource_setup_response_trasfer( - bearer); + sess); ogs_assert(n2smbuf); transfer = &PDUSessionItem->pDUSessionResourceSetupResponseTransfer; @@ -784,7 +781,6 @@ ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response( int rv; test_ue_t *test_ue = NULL; - test_bearer_t *qos_flow = NULL; ogs_pkbuf_t *n2smbuf = NULL; ogs_pkbuf_t *ngapbuf = NULL; @@ -856,11 +852,8 @@ ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response( PDUSessionItem->pDUSessionID = sess->psi; - qos_flow = ogs_list_first(&sess->bearer_list); - ogs_assert(qos_flow); - n2smbuf = testngap_build_pdu_session_resource_setup_response_trasfer( - qos_flow); + sess); ogs_assert(n2smbuf); transfer = &PDUSessionItem->pDUSessionResourceSetupResponseTransfer; @@ -872,6 +865,99 @@ ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response( return ogs_ngap_encode(&pdu); } +ogs_pkbuf_t *testngap_build_pdu_session_resource_modify_response( + test_bearer_t *qos_flow) +{ + int rv; + + test_ue_t *test_ue = NULL; + test_sess_t *sess = NULL; + + ogs_pkbuf_t *n2smbuf = NULL; + ogs_pkbuf_t *ngapbuf = NULL; + + NGAP_NGAP_PDU_t pdu; + NGAP_SuccessfulOutcome_t *successfulOutcome = NULL; + NGAP_PDUSessionResourceModifyResponse_t *PDUSessionResourceModifyResponse; + + NGAP_PDUSessionResourceModifyResponseIEs_t *ie = NULL; + NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL; + NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL; + NGAP_PDUSessionResourceModifyListModRes_t *PDUSessionList = NULL; + NGAP_PDUSessionResourceModifyItemModRes_t *PDUSessionItem = NULL; + OCTET_STRING_t *transfer = NULL; + + ogs_assert(qos_flow); + sess = qos_flow->sess; + ogs_assert(sess); + test_ue = sess->test_ue; + ogs_assert(test_ue); + + memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t)); + pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome; + pdu.choice.successfulOutcome = CALLOC(1, sizeof(NGAP_SuccessfulOutcome_t)); + + successfulOutcome = pdu.choice.successfulOutcome; + successfulOutcome->procedureCode = + NGAP_ProcedureCode_id_PDUSessionResourceModify; + successfulOutcome->criticality = NGAP_Criticality_reject; + successfulOutcome->value.present = + NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceModifyResponse; + + PDUSessionResourceModifyResponse = + &successfulOutcome->value.choice.PDUSessionResourceModifyResponse; + + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ASN_SEQUENCE_ADD(&PDUSessionResourceModifyResponse->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = + NGAP_PDUSessionResourceModifyResponseIEs__value_PR_AMF_UE_NGAP_ID; + + AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID; + + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ASN_SEQUENCE_ADD(&PDUSessionResourceModifyResponse->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID; + ie->criticality = NGAP_Criticality_ignore; + ie->value.present = + NGAP_PDUSessionResourceModifyResponseIEs__value_PR_RAN_UE_NGAP_ID; + + RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID; + + ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceModifyResponseIEs_t)); + ASN_SEQUENCE_ADD(&PDUSessionResourceModifyResponse->protocolIEs, ie); + + ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModRes; + ie->criticality = NGAP_Criticality_reject; + ie->value.present = NGAP_PDUSessionResourceModifyResponseIEs__value_PR_PDUSessionResourceModifyListModRes; + + PDUSessionList = &ie->value.choice.PDUSessionResourceModifyListModRes; + + asn_uint642INTEGER(AMF_UE_NGAP_ID, test_ue->amf_ue_ngap_id); + *RAN_UE_NGAP_ID = test_ue->ran_ue_ngap_id; + + PDUSessionItem = + CALLOC(1, sizeof(struct NGAP_PDUSessionResourceModifyItemModRes)); + ASN_SEQUENCE_ADD(&PDUSessionList->list, PDUSessionItem); + + PDUSessionItem->pDUSessionID = sess->psi; + + n2smbuf = testngap_build_pdu_session_resource_modify_response_trasfer( + qos_flow); + ogs_assert(n2smbuf); + transfer = &PDUSessionItem->pDUSessionResourceModifyResponseTransfer; + + transfer->size = n2smbuf->len; + transfer->buf = CALLOC(transfer->size, sizeof(uint8_t)); + memcpy(transfer->buf, n2smbuf->data, transfer->size); + ogs_pkbuf_free(n2smbuf); + + return ogs_ngap_encode(&pdu); +} + ogs_pkbuf_t *testngap_build_pdu_session_resource_release_response( test_sess_t *sess) { @@ -955,18 +1041,15 @@ ogs_pkbuf_t *testngap_build_pdu_session_resource_release_response( } static ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response_trasfer( - test_bearer_t *qos_flow) + test_sess_t *sess) { int rv; - - test_sess_t *sess = NULL; + test_bearer_t *qos_flow = NULL; ogs_gtp_f_teid_t f_teid; ogs_ip_t ip; int len; - ogs_assert(qos_flow); - sess = qos_flow->sess; ogs_assert(sess); NGAP_PDUSessionResourceSetupResponseTransfer_t message; @@ -1002,12 +1085,41 @@ static ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response_trasfer( ogs_asn_uint32_to_OCTET_STRING(sess->gnb_n3_teid, &gTPTunnel->gTP_TEID); associatedQosFlowList = &dLQosFlowPerTNLInformation->associatedQosFlowList; - associatedQosFlowItem = - CALLOC(1, sizeof(struct NGAP_AssociatedQosFlowItem)); - ASN_SEQUENCE_ADD(&associatedQosFlowList->list, associatedQosFlowItem); - associatedQosFlowItem->qosFlowIdentifier = qos_flow->qfi; + ogs_list_for_each(&sess->bearer_list, qos_flow) { + associatedQosFlowItem = + CALLOC(1, sizeof(struct NGAP_AssociatedQosFlowItem)); + ASN_SEQUENCE_ADD(&associatedQosFlowList->list, associatedQosFlowItem); + + associatedQosFlowItem->qosFlowIdentifier = qos_flow->qfi; + } return ogs_asn_encode( &asn_DEF_NGAP_PDUSessionResourceSetupResponseTransfer, &message); } + +static ogs_pkbuf_t *testngap_build_pdu_session_resource_modify_response_trasfer( + test_bearer_t *qos_flow) +{ + ogs_assert(qos_flow); + + NGAP_PDUSessionResourceModifyResponseTransfer_t message; + + NGAP_QosFlowAddOrModifyResponseList_t *qosFlowAddOrModifyResponseList; + NGAP_QosFlowAddOrModifyResponseItem_t *qosFlowAddOrModifyResponseItem; + + memset(&message, 0, sizeof(message)); + + message.qosFlowAddOrModifyResponseList = + qosFlowAddOrModifyResponseList = + CALLOC(1, sizeof(struct NGAP_QosFlowAddOrModifyResponseList)); + qosFlowAddOrModifyResponseItem = + CALLOC(1, sizeof(struct NGAP_QosFlowAddOrModifyResponseItem)); + ASN_SEQUENCE_ADD(&qosFlowAddOrModifyResponseList->list, + qosFlowAddOrModifyResponseItem); + + qosFlowAddOrModifyResponseItem->qosFlowIdentifier = qos_flow->qfi; + + return ogs_asn_encode( + &asn_DEF_NGAP_PDUSessionResourceModifyResponseTransfer, &message); +} diff --git a/tests/common/ngap-build.h b/tests/common/ngap-build.h index d236c078c..536bd02fa 100644 --- a/tests/common/ngap-build.h +++ b/tests/common/ngap-build.h @@ -44,6 +44,8 @@ ogs_pkbuf_t *testngap_build_ue_context_release_complete(test_ue_t *test_ue); ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response( test_sess_t *sess); +ogs_pkbuf_t *testngap_build_pdu_session_resource_modify_response( + test_bearer_t *qos_flow); ogs_pkbuf_t *testngap_build_pdu_session_resource_release_response( test_sess_t *sess); diff --git a/tests/common/ngap-handler.c b/tests/common/ngap-handler.c index 9563c72d9..ec906ad82 100644 --- a/tests/common/ngap-handler.c +++ b/tests/common/ngap-handler.c @@ -342,6 +342,117 @@ void testngap_handle_pdu_session_resource_setup_request( } } +void testngap_handle_pdu_session_resource_modify_request( + test_ue_t *test_ue, ogs_ngap_message_t *message) +{ + test_sess_t *sess = NULL; + test_bearer_t *qos_flow = NULL; + int rv, i, j, k, l; + char buf[OGS_ADDRSTRLEN]; + + NGAP_NGAP_PDU_t pdu; + NGAP_InitiatingMessage_t *initiatingMessage = NULL; + NGAP_PDUSessionResourceModifyRequest_t *PDUSessionResourceModifyRequest; + + NGAP_PDUSessionResourceModifyListModReq_t *PDUSessionList = NULL; + NGAP_PDUSessionResourceModifyItemModReq_t *PDUSessionItem = NULL; + + NGAP_PDUSessionResourceModifyRequestIEs_t *ie = NULL; + NGAP_NAS_PDU_t *NAS_PDU = NULL; + + NGAP_PDUSessionResourceModifyRequestTransfer_t n2sm_message; + NGAP_PDUSessionResourceModifyRequestTransferIEs_t *ie2 = NULL; + NGAP_UPTransportLayerInformation_t *UPTransportLayerInformation = NULL; + NGAP_GTPTunnel_t *gTPTunnel = NULL; + NGAP_PDUSessionType_t *PDUSessionType = NULL; + NGAP_QosFlowAddOrModifyRequestList_t *QosFlowAddOrModifyRequestList = NULL; + NGAP_QosFlowAddOrModifyRequestItem_t *QosFlowAddOrModifyRequestItem = NULL; + OCTET_STRING_t *transfer = NULL; + ogs_pkbuf_t *n2smbuf = NULL; + + ogs_assert(test_ue); + ogs_assert(message); + + initiatingMessage = message->choice.initiatingMessage; + ogs_assert(initiatingMessage); + PDUSessionResourceModifyRequest = + &initiatingMessage->value.choice.PDUSessionResourceModifyRequest; + ogs_assert(PDUSessionResourceModifyRequest); + + for (i = 0; i < PDUSessionResourceModifyRequest->protocolIEs.list.count; + i++) { + ie = PDUSessionResourceModifyRequest->protocolIEs.list.array[i]; + switch (ie->id) { + case NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModReq: + PDUSessionList = + &ie->value.choice.PDUSessionResourceModifyListModReq; + ogs_assert(PDUSessionList); + for (j = 0; j < PDUSessionList->list.count; j++) { + PDUSessionItem = (NGAP_PDUSessionResourceModifyItemModReq_t *) + PDUSessionList->list.array[j]; + ogs_assert(PDUSessionItem); + + sess = test_sess_find_by_psi( + test_ue, PDUSessionItem->pDUSessionID); + ogs_assert(sess); + + if (PDUSessionItem->nAS_PDU) + testngap_send_to_nas(test_ue, PDUSessionItem->nAS_PDU); + transfer = &PDUSessionItem-> + pDUSessionResourceModifyRequestTransfer; + ogs_assert(transfer); + + n2smbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN); + ogs_assert(n2smbuf); + ogs_pkbuf_put_data(n2smbuf, transfer->buf, transfer->size); + + rv = ogs_asn_decode( + &asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, + &n2sm_message, sizeof(n2sm_message), n2smbuf); + ogs_assert(rv == OGS_OK); + + for (k = 0; k < n2sm_message.protocolIEs.list.count; k++) { + ie2 = n2sm_message.protocolIEs.list.array[k]; + switch (ie2->id) { + case NGAP_ProtocolIE_ID_id_QosFlowAddOrModifyRequestList: + QosFlowAddOrModifyRequestList = + &ie2->value.choice.QosFlowAddOrModifyRequestList; + ogs_assert(QosFlowAddOrModifyRequestList); + for (l = 0; + l < QosFlowAddOrModifyRequestList->list.count; + l++) { + QosFlowAddOrModifyRequestItem = + (struct NGAP_QosFlowAddOrModifyRequestItem *) + QosFlowAddOrModifyRequestList->list.array[l]; + ogs_assert(QosFlowAddOrModifyRequestItem); + qos_flow = test_qos_flow_find_by_sess_qfi(sess, + QosFlowAddOrModifyRequestItem-> + qosFlowIdentifier); + if (!qos_flow) + qos_flow = test_qos_flow_add(sess); + + qos_flow->qfi = QosFlowAddOrModifyRequestItem-> + qosFlowIdentifier; + } + break; + default: + break; + } + } + + ogs_asn_free( + &asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer, + &n2sm_message); + + ogs_pkbuf_free(n2smbuf); + } + break; + default: + break; + } + } +} + void testngap_handle_pdu_session_resource_release_command( test_ue_t *test_ue, ogs_ngap_message_t *message) { diff --git a/tests/common/ngap-handler.h b/tests/common/ngap-handler.h index a34db3ed6..77f6a7b1f 100644 --- a/tests/common/ngap-handler.h +++ b/tests/common/ngap-handler.h @@ -35,6 +35,8 @@ void testngap_handle_ue_release_context_command( test_ue_t *test_ue, ogs_ngap_message_t *message); void testngap_handle_pdu_session_resource_setup_request( test_ue_t *test_ue, ogs_ngap_message_t *message); +void testngap_handle_pdu_session_resource_modify_request( + test_ue_t *test_ue, ogs_ngap_message_t *message); void testngap_handle_pdu_session_resource_release_command( test_ue_t *test_ue, ogs_ngap_message_t *message); diff --git a/tests/common/ngap-path.c b/tests/common/ngap-path.c index 1e17c1d1c..f2b3e397a 100644 --- a/tests/common/ngap-path.c +++ b/tests/common/ngap-path.c @@ -56,6 +56,9 @@ void testngap_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf) case NGAP_ProcedureCode_id_PDUSessionResourceSetup: testngap_handle_pdu_session_resource_setup_request(test_ue, pdu); break; + case NGAP_ProcedureCode_id_PDUSessionResourceModify: + testngap_handle_pdu_session_resource_modify_request(test_ue, pdu); + break; case NGAP_ProcedureCode_id_PDUSessionResourceRelease: testngap_handle_pdu_session_resource_release_command(test_ue, pdu); break; diff --git a/tests/core/conv-test.c b/tests/core/conv-test.c index 1afc09adf..b93d2f9d9 100644 --- a/tests/core/conv-test.c +++ b/tests/core/conv-test.c @@ -148,6 +148,123 @@ static void conv_test7(abts_case *tc, void *data) ABTS_TRUE(tc, strcmp("001010123456819", out) == 0); } +static void conv_test8(abts_case *tc, void *data) +{ + char *str = NULL; + uint64_t x; + + str = ogs_uint64_to_0string(0); + ABTS_STR_EQUAL(tc, "0000000000000000", str); + ogs_free(str); + + str = ogs_uint64_to_0string(1); + ABTS_STR_EQUAL(tc, "0000000000000001", str); + ogs_free(str); + + x = 0; + str = ogs_uint64_to_string(0); + ABTS_STR_EQUAL(tc, "", str); + ABTS_INT_EQUAL(tc, x, ogs_uint64_from_string(str)); + ABTS_INT_EQUAL(tc, x, ogs_uint64_from_string("0")); + ogs_free(str); + + x = 1; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "1", str); + ABTS_INT_EQUAL(tc, x, ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x12; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "12", str); + ABTS_INT_EQUAL(tc, x, ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x123; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "123", str); + ABTS_INT_EQUAL(tc, x, ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x1234; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "1234", str); + ABTS_INT_EQUAL(tc, x, ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x12345; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "12345", str); + ABTS_INT_EQUAL(tc, x, ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x123456; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "123456", str); + ABTS_INT_EQUAL(tc, x, ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x1234567; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "1234567", str); + ABTS_INT_EQUAL(tc, x, ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x12345678; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "12345678", str); + ABTS_INT_EQUAL(tc, x, ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x123456789; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "123456789", str); + ABTS_TRUE(tc, x == ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x123456789a; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "123456789a", str); + ABTS_TRUE(tc, x == ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x123456789ab; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "123456789ab", str); + ABTS_TRUE(tc, x == ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x123456789abc; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "123456789abc", str); + ABTS_TRUE(tc, x == ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x123456789abcd; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "123456789abcd", str); + ABTS_TRUE(tc, x == ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x123456789abcde; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "123456789abcde", str); + ABTS_TRUE(tc, x == ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x123456789abcdef; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "123456789abcdef", str); + ABTS_TRUE(tc, x == ogs_uint64_from_string(str)); + ogs_free(str); + + x = 0x120456789abcdef0; + str = ogs_uint64_to_string(x); + ABTS_STR_EQUAL(tc, "120456789abcdef0", str); + ABTS_TRUE(tc, x == ogs_uint64_from_string(str)); + ogs_free(str); +} + abts_suite *test_conv(abts_suite *suite) { suite = ADD_SUITE(suite) @@ -158,6 +275,7 @@ abts_suite *test_conv(abts_suite *suite) abts_run_test(suite, conv_test5, NULL); abts_run_test(suite, conv_test6, NULL); abts_run_test(suite, conv_test7, NULL); + abts_run_test(suite, conv_test8, NULL); return suite; } diff --git a/tests/meson.build b/tests/meson.build index 520fa08bf..47d96ad44 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -24,6 +24,7 @@ subdir('common') subdir('app') subdir('unit') subdir('registration') +subdir('vonr') subdir('minimal') subdir('attach') subdir('volte') diff --git a/tests/vonr/abts-main.c b/tests/vonr/abts-main.c new file mode 100644 index 000000000..79c0bc3be --- /dev/null +++ b/tests/vonr/abts-main.c @@ -0,0 +1,66 @@ +/* + * 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 "test-app.h" + +abts_suite *test_qos_flow(abts_suite *suite); + +const struct testlist { + abts_suite *(*func)(abts_suite *suite); +} alltests[] = { + {test_qos_flow}, + {NULL}, +}; + +static void terminate(void) +{ + ogs_msleep(50); + + test_child_terminate(); + app_terminate(); + + test_5gc_final(); + ogs_app_terminate(); +} + +static void initialize(const char *const argv[]) +{ + int rv; + + rv = ogs_app_initialize(NULL, NULL, argv); + ogs_assert(rv == OGS_OK); + test_5gc_init(); + + rv = app_initialize(argv); + ogs_assert(rv == OGS_OK); +} + +int main(int argc, const char *const argv[]) +{ + int i; + abts_suite *suite = NULL; + + atexit(terminate); + test_app_run(argc, argv, "vonr.yaml", initialize); + + for (i = 0; alltests[i].func; i++) + suite = alltests[i].func(suite); + + return abts_report(suite); +} diff --git a/tests/vonr/meson.build b/tests/vonr/meson.build new file mode 100644 index 000000000..a37393d74 --- /dev/null +++ b/tests/vonr/meson.build @@ -0,0 +1,31 @@ +# 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 . + +test5gc_vonr_sources = files(''' + abts-main.c + qos-flow-test.c +'''.split()) + +test5gc_vonr_exe = executable('vonr', + sources : test5gc_vonr_sources, + c_args : testunit_core_cc_flags, + dependencies : libtest5gc_dep) + +test('vonr', + test5gc_vonr_exe, + is_parallel : false, + suite: '5gc') diff --git a/tests/vonr/qos-flow-test.c b/tests/vonr/qos-flow-test.c new file mode 100644 index 000000000..aeb7ff3a6 --- /dev/null +++ b/tests/vonr/qos-flow-test.c @@ -0,0 +1,501 @@ +/* + * 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 "test-common.h" + +static void test1_func(abts_case *tc, void *data) +{ + int rv; + ogs_socknode_t *ngap; + ogs_socknode_t *gtpu; + ogs_pkbuf_t *gmmbuf; + ogs_pkbuf_t *gsmbuf; + ogs_pkbuf_t *nasbuf; + ogs_pkbuf_t *sendbuf; + ogs_pkbuf_t *recvbuf; + ogs_ngap_message_t message; + int i; + + uint8_t tmp[OGS_MAX_SDU_LEN]; + char *_gtp_payload = "34ff0024" + "0000000100000085 010002004500001c 0c0b000040015a7a 0a2d00010a2d0002" + "00000964cd7c291f"; + + ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci; + test_ue_t *test_ue = NULL; + test_sess_t *sess = NULL; + test_bearer_t *qos_flow = NULL; + + const char *_k_string = "70d49a71dd1a2b806a25abe0ef749f1e"; + uint8_t k[OGS_KEY_LEN]; + const char *_opc_string = "6f1bf53d624b3a43af6592854e2444c7"; + uint8_t opc[OGS_KEY_LEN]; + + mongoc_collection_t *collection = NULL; + bson_t *doc = NULL; + int64_t count = 0; + bson_error_t error; + const char *json = + "{" + "\"_id\" : { \"$oid\" : \"597223158b8861d7605378c6\" }, " + "\"imsi\" : \"901700000021309\"," + "\"ambr\" : { " + "\"uplink\" : { \"$numberLong\" : \"1024000\" }, " + "\"downlink\" : { \"$numberLong\" : \"1024000\" } " + "}," + "\"pdn\" : [" + "{" + "\"apn\" : \"internet\", " + "\"_id\" : { \"$oid\" : \"597223158b8861d7605378c7\" }, " + "\"ambr\" : {" + "\"uplink\" : { \"$numberLong\" : \"1024000\" }, " + "\"downlink\" : { \"$numberLong\" : \"1024000\" } " + "}," + "\"qos\" : { " + "\"qci\" : 9, " + "\"arp\" : { " + "\"priority_level\" : 8," + "\"pre_emption_vulnerability\" : 1, " + "\"pre_emption_capability\" : 1" + "} " + "}, " + "\"type\" : 2," + "\"pcc_rule\" : [" + "{" + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2d\" }," + "\"qos\" : {" + "\"qci\" : 1," + "\"gbr\" : {" + "\"downlink\" : { \"$numberLong\" : \"64\" }," + "\"uplink\" : { \"$numberLong\" : \"44\" }" + "}," + "\"mbr\" : {" + "\"downlink\" : { \"$numberLong\" : \"64\" }," + "\"uplink\" : { \"$numberLong\" : \"44\" }" + "}," + "\"arp\" : {" + "\"priority_level\" : 3," + "\"pre_emption_vulnerability\" : 0," + "\"pre_emption_capability\" : 0 }" + "}," + "\"flow\" : [" + "{ \"direction\" : 2," + "\"description\" : \"permit out udp from 10.200.136.98/32 23454 to assigned 1-65535\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd31\" } }," + "{ \"direction\" : 1," + "\"description\" : \"permit out icmp from any to assigned\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd30\" } }," + "{ \"direction\" : 2," + "\"description\" : \"permit out udp from 10.200.136.98/32 23455 to assigned 1-65535\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2f\" } }," + "{ \"direction\" : 1," + "\"description\" : \"permit out udp from 10.200.136.98/32 1-65535 to assigned 50021\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2e\" } }" + "]" + "}" + "]" + "}" + "]," + "\"security\" : { " + "\"k\" : \"70d49a71dd1a2b806a25abe0ef749f1e\", " + "\"opc\" : \"6f1bf53d624b3a43af6592854e2444c7\", " + "\"amf\" : \"8000\", " + "\"sqn\" : { \"$numberLong\" : \"25235952177090\" } " + "}, " + "\"subscribed_rau_tau_timer\" : 12," + "\"network_access_mode\" : 2, " + "\"subscriber_status\" : 0, " + "\"access_restriction_data\" : 32, " + "\"__v\" : 0 " + "}"; + + /* Setup Test UE & Session Context */ + memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci)); + + mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI; + mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI; + mobile_identity_suci.routing_indicator1 = 0; + mobile_identity_suci.routing_indicator2 = 0xf; + mobile_identity_suci.routing_indicator3 = 0xf; + mobile_identity_suci.routing_indicator4 = 0xf; + mobile_identity_suci.protection_scheme_id = OGS_NAS_5GS_NULL_SCHEME; + mobile_identity_suci.home_network_pki_value = 0; + mobile_identity_suci.scheme_output[0] = 0; + mobile_identity_suci.scheme_output[1] = 0; + mobile_identity_suci.scheme_output[2] = 0x20; + mobile_identity_suci.scheme_output[3] = 0x31; + mobile_identity_suci.scheme_output[4] = 0x90; + + test_ue = test_ue_add_by_suci(&mobile_identity_suci, 13); + ogs_assert(test_ue); + + test_ue->nr_cgi.cell_id = 0x40001; + + test_ue->nas.registration.type = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE; + test_ue->nas.registration.follow_on_request = 1; + test_ue->nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL; + + OGS_HEX(_k_string, strlen(_k_string), test_ue->k); + OGS_HEX(_opc_string, strlen(_opc_string), test_ue->opc); + + sess = test_sess_add_by_dnn_and_psi(test_ue, "internet", 5); + ogs_assert(sess); + + /* gNB connects to AMF */ + ngap = testngap_client(AF_INET); + ABTS_PTR_NOTNULL(tc, ngap); + + /* gNB connects to UPF */ + gtpu = test_gtpu_server(1, AF_INET); + ABTS_PTR_NOTNULL(tc, gtpu); + + /* Send NG-Setup Reqeust */ + sendbuf = testngap_build_ng_setup_request(0x4000, 22); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive NG-Setup Response */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /********** Insert Subscriber in Database */ + collection = mongoc_client_get_collection( + ogs_mongoc()->client, ogs_mongoc()->name, "subscribers"); + ABTS_PTR_NOTNULL(tc, collection); + doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi)); + ABTS_PTR_NOTNULL(tc, doc); + + count = mongoc_collection_count ( + collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error); + if (count) { + ABTS_TRUE(tc, mongoc_collection_remove(collection, + MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error)) + } + bson_destroy(doc); + + doc = bson_new_from_json((const uint8_t *)json, -1, &error);; + ABTS_PTR_NOTNULL(tc, doc); + ABTS_TRUE(tc, mongoc_collection_insert(collection, + MONGOC_INSERT_NONE, doc, NULL, &error)); + bson_destroy(doc); + + doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi)); + ABTS_PTR_NOTNULL(tc, doc); + do { + count = mongoc_collection_count ( + collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error); + } while (count == 0); + bson_destroy(doc); + + /* Send Registration request */ + test_ue->registration_request_param.guti = 1; + gmmbuf = testgmm_build_registration_request(test_ue, NULL); + ABTS_PTR_NOTNULL(tc, gmmbuf); + + test_ue->registration_request_param.gmm_capability = 1; + test_ue->registration_request_param.requested_nssai = 1; + test_ue->registration_request_param.last_visited_registered_tai = 1; + test_ue->registration_request_param.ue_usage_setting = 1; + nasbuf = testgmm_build_registration_request(test_ue, NULL); + ABTS_PTR_NOTNULL(tc, nasbuf); + + sendbuf = testngap_build_initial_ue_message(test_ue, gmmbuf, false); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Identity request */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send Identity response */ + gmmbuf = testgmm_build_identity_response(test_ue); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Authentication request */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send Authentication response */ + gmmbuf = testgmm_build_authentication_response(test_ue); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send Security mode complete */ + gmmbuf = testgmm_build_security_mode_complete(test_ue, nasbuf); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Initial context setup request */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send UE radio capability info indication */ + sendbuf = testngap_build_ue_radio_capability_info_indication(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Initial context setup response */ + sendbuf = testngap_build_initial_context_setup_response(test_ue, NULL); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Registration complete */ + gmmbuf = testgmm_build_registration_complete(test_ue); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Configuration update command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send PDU session establishment request */ + sess->ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + sess->ul_nas_transport_param.dnn = 1; + sess->ul_nas_transport_param.s_nssai = 1; + + gsmbuf = testgsm_build_pdu_session_establishment_request(sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive PDU session establishment accept */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send GTP-U ICMP Packet */ + qos_flow = test_qos_flow_find_by_ue_qfi(test_ue, 1); + ogs_assert(qos_flow); + rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send PDU session resource setup response */ + sendbuf = testngap_build_pdu_session_resource_setup_response(sess); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Send GTP-U ICMP Packet */ + rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Receive PDU session modification command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send GTP-U ICMP Packet */ + qos_flow = test_qos_flow_find_by_ue_qfi(test_ue, 2); + ogs_assert(qos_flow); + + /* Send PDU session resource modify response */ + sendbuf = testngap_build_pdu_session_resource_modify_response(qos_flow); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send PDU session resource modify complete */ + sess->ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_MODIFICATION_REQUEST; + sess->ul_nas_transport_param.dnn = 0; + sess->ul_nas_transport_param.s_nssai = 0; + + gsmbuf = testgsm_build_pdu_session_modification_complete(sess); + ABTS_PTR_NOTNULL(tc, gsmbuf); + gmmbuf = testgmm_build_ul_nas_transport(sess, + OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Waiting for creating dedicated QoS flow in PFCP protocol */ + ogs_msleep(100); + + /* Send GTP-U ICMP Packet */ + rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu); + ABTS_PTR_NOTNULL(tc, recvbuf); + /* For checking qos_flow_identifier == 2 */ + ABTS_TRUE(tc, memcmp(recvbuf->data, + OGS_HEX(_gtp_payload, strlen(_gtp_payload), tmp), 20) == 0); + ogs_pkbuf_free(recvbuf); + + /* Send UE context release request */ + sendbuf = testngap_build_ue_context_release_request(test_ue, + NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_user_inactivity, + true); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive UE context release command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send UE context release complete */ + sendbuf = testngap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* + * Send Service request Using InitialUEMessage + * - Uplink Data Status + */ + test_ue->service_request_param.integrity_protected = 0; + test_ue->service_request_param.uplink_data_status = 1; + test_ue->service_request_param. + psimask.uplink_data_status = 1 << sess->psi; + test_ue->service_request_param.pdu_session_status = 0; + nasbuf = testgmm_build_service_request(test_ue, NULL); + ABTS_PTR_NOTNULL(tc, nasbuf); + + test_ue->service_request_param.integrity_protected = 1; + test_ue->service_request_param.uplink_data_status = 0; + test_ue->service_request_param.pdu_session_status = 0; + gmmbuf = testgmm_build_service_request(test_ue, nasbuf); + ABTS_PTR_NOTNULL(tc, gmmbuf); + + sendbuf = testngap_build_initial_ue_message(test_ue, gmmbuf, true); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Service accept */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, 0x0000, test_ue->pdu_session_status); + ABTS_INT_EQUAL(tc, 0x0000, test_ue->pdu_session_reactivation_result); + + /* Send GTP-U ICMP Packet */ + rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Initial context setup response */ + sendbuf = testngap_build_initial_context_setup_response(test_ue, sess); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive GTP-U ICMP Packet */ + recvbuf = testgnb_gtpu_read(gtpu); + ABTS_PTR_NOTNULL(tc, recvbuf); + /* For checking qos_flow_identifier == 2 */ + ABTS_TRUE(tc, memcmp(recvbuf->data, + OGS_HEX(_gtp_payload, strlen(_gtp_payload), tmp), 20) == 0); + ogs_pkbuf_free(recvbuf); + + /* Send De-registration request */ + gmmbuf = testgmm_build_de_registration_request(test_ue, 1); + ABTS_PTR_NOTNULL(tc, gmmbuf); + sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive UE context release command */ + recvbuf = testgnb_ngap_read(ngap); + ABTS_PTR_NOTNULL(tc, recvbuf); + testngap_recv(test_ue, recvbuf); + + /* Send UE context release complete */ + sendbuf = testngap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testgnb_ngap_send(ngap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(300); + + /********** Remove Subscriber in Database */ + doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi)); + ABTS_PTR_NOTNULL(tc, doc); + ABTS_TRUE(tc, mongoc_collection_remove(collection, + MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error)) + bson_destroy(doc); + + mongoc_collection_destroy(collection); + + /* gNB disonncect from UPF */ + testgnb_gtpu_close(gtpu); + + /* gNB disonncect from AMF */ + testgnb_ngap_close(ngap); + + /* Clear Test UE Context */ + test_ue_remove(test_ue); +} + +abts_suite *test_qos_flow(abts_suite *suite) +{ + suite = ADD_SUITE(suite) + + abts_run_test(suite, test1_func, NULL); + + return suite; +}