diff --git a/configs/cups.yaml.in b/configs/cups.yaml.in index 21729e82d..b7df8db13 100644 --- a/configs/cups.yaml.in +++ b/configs/cups.yaml.in @@ -108,7 +108,7 @@ nrf: upf: pfcp: - addr: 127.0.0.4 + - addr: 127.0.0.4 gtpu: - addr: - 127.0.0.4 diff --git a/configs/open5gs/amf.yaml.in b/configs/open5gs/amf.yaml.in index 27ded0b19..4574e0ce9 100644 --- a/configs/open5gs/amf.yaml.in +++ b/configs/open5gs/amf.yaml.in @@ -165,6 +165,7 @@ amf: - addr: 127.0.0.2 port: 7777 ngap: + - addr: 127.0.0.2 guami: - plmn_id: mcc: 901 @@ -279,9 +280,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 # diff --git a/configs/open5gs/ausf.yaml.in b/configs/open5gs/ausf.yaml.in index 8a7c77e03..5b48c3cbe 100644 --- a/configs/open5gs/ausf.yaml.in +++ b/configs/open5gs/ausf.yaml.in @@ -156,9 +156,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 # diff --git a/configs/open5gs/hss.yaml.in b/configs/open5gs/hss.yaml.in index 5c7b61580..2c7ec4769 100644 --- a/configs/open5gs/hss.yaml.in +++ b/configs/open5gs/hss.yaml.in @@ -86,9 +86,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 # diff --git a/configs/open5gs/mme.yaml.in b/configs/open5gs/mme.yaml.in index 77ca2aa50..ce436aeeb 100644 --- a/configs/open5gs/mme.yaml.in +++ b/configs/open5gs/mme.yaml.in @@ -255,31 +255,29 @@ mme: # # # o Round-Robin -# (If `selection_mode` is omitted, the default mode is Round-Robin) # -# selection_mode: rr # gtpc: # addr: 127.0.0.2 # addr: 127.0.2.2 # addr: 127.0.4.2 # -# o SGW selection by eNodeB TAC (either single TAC or multiple TACs) +# o SGW selection by eNodeB TAC +# (either single TAC or multiple TACs, DECIMAL representation) # -# selection_mode: tac # gtpc: # - addr: 127.0.0.2 # tac: 26000 # - addr: 127.0.2.2 # tac: [25000, 27000, 28000] # -# o SGW selection by eNodeB ID (either single enb_id or multiple enb_ids, decimal or hex representation) +# o SGW selection by e_cell_id(28bit) +# (either single or multiple e_cell_id, HEX representation) # -# selection_mode: enb_id # gtpc: # - addr: 127.0.0.2 -# enb_id: 463 +# e_cell_id: abcde01 # - addr: 127.0.2.2 -# enb_id: [0x12345, 9413, 0x98765] +# e_cell_id: [12345, a9413, 98765] # sgw: gtpc: @@ -388,9 +386,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 # diff --git a/configs/open5gs/nrf.yaml.in b/configs/open5gs/nrf.yaml.in index e8c6f6b7b..55f6d7728 100644 --- a/configs/open5gs/nrf.yaml.in +++ b/configs/open5gs/nrf.yaml.in @@ -128,9 +128,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 # diff --git a/configs/open5gs/pcrf.yaml.in b/configs/open5gs/pcrf.yaml.in index ba5a93f1a..a510a9048 100644 --- a/configs/open5gs/pcrf.yaml.in +++ b/configs/open5gs/pcrf.yaml.in @@ -85,9 +85,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 # diff --git a/configs/open5gs/pgw.yaml.in b/configs/open5gs/pgw.yaml.in index 1bdf52567..850cba59f 100644 --- a/configs/open5gs/pgw.yaml.in +++ b/configs/open5gs/pgw.yaml.in @@ -225,9 +225,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 # diff --git a/configs/open5gs/sgw.yaml.in b/configs/open5gs/sgw.yaml.in index 4cdd52d16..4d2329563 100644 --- a/configs/open5gs/sgw.yaml.in +++ b/configs/open5gs/sgw.yaml.in @@ -122,9 +122,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 # diff --git a/configs/open5gs/smf.yaml.in b/configs/open5gs/smf.yaml.in index 5d568a829..390a86f52 100644 --- a/configs/open5gs/smf.yaml.in +++ b/configs/open5gs/smf.yaml.in @@ -263,41 +263,39 @@ nrf: # # # o Round-Robin -# (If `upf_selection_mode` is omitted in smf/pfcp, -# the default mode is Round-Robin) -# # upf: # pfcp: # - addr: 127.0.0.4 # - addr: 127.0.0.12 # -# o UPF selection by eNodeB TAC (either single TAC or multiple TACs) +# o UPF selection by eNodeB TAC +# (either single TAC or multiple TACs, DECIMAL representation) # # upf: # pfcp: # - addr: 127.0.0.4 -# tac: 1 < either single TAC or multiple TACs +# tac: 1 # - addr: 127.0.0.12 # tac: [3,5,8] # -# o SGW selection by UE's APN (either single APN or multiple APNs) +# o UPF selection by UE's DNN/APN (either single DNN/APN or multiple DNNs/APNs) # # upf: # pfcp: # - addr: 127.0.0.4 -# apn: ims < either single APN or multiple APNs +# dnn: ims # - addr: 127.0.0.12 # apn: [internet, web] # -# o SGW selection by eNodeB ID -# (either single enb_id or multiple enb_ids, decimal or hex representation) +# o UPF selection by CellID(e_cell_id: 28bit, nr_cell_id: 36bit) +# (either single enb_id or multiple enb_ids, HEX representation) # # upf: # pfcp: # - addr: 127.0.0.4 -# enb_id: 463 < either single enb_id or multiple enb_id, -# - addr: 127.0.0.12 can be entered in decimal or hex format -# enb_id: [0x12345, 9413] +# e_cell_id: 463 +# - addr: 127.0.0.12 +# nr_cell_id: [123456789, 9413] # upf: pfcp: @@ -359,9 +357,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 # diff --git a/configs/open5gs/udm.yaml.in b/configs/open5gs/udm.yaml.in index 8b0fad773..a5c2971dc 100644 --- a/configs/open5gs/udm.yaml.in +++ b/configs/open5gs/udm.yaml.in @@ -156,9 +156,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 # diff --git a/configs/open5gs/udr.yaml.in b/configs/open5gs/udr.yaml.in index c1303f2fe..b333ef87f 100644 --- a/configs/open5gs/udr.yaml.in +++ b/configs/open5gs/udr.yaml.in @@ -158,9 +158,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 # diff --git a/configs/open5gs/upf.yaml.in b/configs/open5gs/upf.yaml.in index 9e5870550..0eb4e356b 100644 --- a/configs/open5gs/upf.yaml.in +++ b/configs/open5gs/upf.yaml.in @@ -61,6 +61,9 @@ upf: pfcp: - addr: 127.0.0.4 gtpu: + - addr: + - 127.0.0.4 + - ::1 pdn: # @@ -134,9 +137,9 @@ max: # 8192: 128 # big: 8 # -# o Memory of Packet Buffering in SGW -# - Maximum Number of packet(SDU size = 8Kbytes) pool in SGW -# - SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes +# o Memory of Packet Buffering in UPF/SGW +# - Maximum Number of packet(SDU size = 8Kbytes) pool in UPF/SGW +# - UPF/SGW Memory Usage : 65536 * 8Kbytes = 512Mbytes # # packet: 65536 pool: diff --git a/lib/core/ogs-3gpp-types.c b/lib/core/ogs-3gpp-types.c index 0c52e3d9f..8c8265a40 100644 --- a/lib/core/ogs-3gpp-types.c +++ b/lib/core/ogs-3gpp-types.c @@ -130,14 +130,18 @@ ogs_amf_id_t *ogs_amf_id_from_string(ogs_amf_id_t *amf_id, const char *hex) return amf_id; } -char *ogs_amf_id_to_string(ogs_amf_id_t *amf_id, char *buf) +#define OGS_AMFIDSTRLEN (sizeof(ogs_amf_id_t)*2+1) +char *ogs_amf_id_to_string(ogs_amf_id_t *amf_id) { + char *str = NULL; ogs_assert(amf_id); - ogs_assert(buf); - ogs_hex_to_ascii(amf_id, sizeof(ogs_amf_id_t), buf, OGS_AMFIDSTRLEN); + str = ogs_calloc(1, OGS_AMFIDSTRLEN); + ogs_assert(str); - return buf; + ogs_hex_to_ascii(amf_id, sizeof(ogs_amf_id_t), str, OGS_AMFIDSTRLEN); + + return str; } uint8_t ogs_amf_region_id(ogs_amf_id_t *amf_id) @@ -167,29 +171,6 @@ ogs_amf_id_t *ogs_amf_id_build(ogs_amf_id_t *amf_id, return amf_id; } -char *ogs_s_nssai_sd_to_string(ogs_uint24_t sd) -{ - if (sd.v != OGS_S_NSSAI_NO_SD_VALUE) - return ogs_msprintf("%06x", sd.v); - else - return NULL; -} - -ogs_uint24_t ogs_s_nssai_sd_from_string(const char *hex) -{ - ogs_uint24_t sd; - char hexbuf[sizeof(ogs_uint24_t)]; - - sd.v = OGS_S_NSSAI_NO_SD_VALUE; - if (hex == NULL) - return sd; - - OGS_HEX(hex, strlen(hex), hexbuf); - memcpy(&sd, hexbuf, 3); - - return ogs_be24toh(sd); -} - char *ogs_supi_from_suci(char *suci) { #define MAX_SUCI_TOKEN 16 @@ -269,6 +250,25 @@ char *ogs_id_get_value(char *str) return ueid; } +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); +} + +ogs_uint24_t ogs_s_nssai_sd_from_string(const char *hex) +{ + ogs_uint24_t sd; + + sd.v = OGS_S_NSSAI_NO_SD_VALUE; + if (hex == NULL) + return sd; + + return ogs_uint24_from_string((char *)hex); +} + int ogs_fqdn_build(char *dst, char *src, int length) { int i = 0, j = 0; diff --git a/lib/core/ogs-3gpp-types.h b/lib/core/ogs-3gpp-types.h index 0b6b1c0cf..19a4f370c 100644 --- a/lib/core/ogs-3gpp-types.h +++ b/lib/core/ogs-3gpp-types.h @@ -51,6 +51,7 @@ extern "C" { #define OGS_MAX_MSISDN_LEN \ OGS_BCD_TO_BUFFER_LEN(OGS_MAX_MSISDN_BCD_LEN) +#define OGS_MAX_NUM_OF_CELL_ID 16 #define OGS_MAX_NUM_OF_ENB_ID 16 #define OGS_MAX_NUM_OF_APN 16 #define OGS_MAX_NUM_OF_HOSTNAME 16 @@ -80,46 +81,6 @@ extern "C" { #define OGS_ACCESS_TYPE_NON_3GPP 2 #define OGS_ACCESS_TYPE_BOTH_3GPP_AND_NON_3GPP 3 -typedef struct ogs_uint24_s { - uint32_t v:24; -} __attribute__ ((packed)) ogs_uint24_t; - -static ogs_inline ogs_uint24_t ogs_be24toh(ogs_uint24_t x) -{ - uint32_t tmp = x.v; - tmp = be32toh(tmp); - x.v = tmp >> 8; - return x; -} - -static ogs_inline ogs_uint24_t ogs_htobe24(ogs_uint24_t x) -{ - uint32_t tmp = x.v; - tmp = htobe32(tmp); - x.v = tmp >> 8; - return x; -} - -static ogs_inline ogs_uint24_t ogs_uint24_from_string(char *str) -{ - ogs_uint24_t x; - - ogs_assert(str); - OGS_HEX(str, strlen(str), &x); - return ogs_be24toh(x); -} - -#define OGS_24BITSTRLEN (sizeof(ogs_uint24_t)*2+1) -static ogs_inline char *ogs_uint24_to_string(ogs_uint24_t x, char *str) -{ - ogs_assert(str); - - x = ogs_htobe24(x); - ogs_hex_to_ascii(&x, sizeof(x), str, OGS_24BITSTRLEN); - - return str; -} - /************************************ * PLMN_ID Structure */ #define OGS_MAX_NUM_OF_PLMN 6 @@ -157,11 +118,15 @@ ED2(uint8_t set2:2;, uint8_t pointer:6;) } __attribute__ ((packed)) ogs_amf_id_t; +typedef struct ogs_guami_s { + ogs_plmn_id_t plmn_id; + ogs_amf_id_t amf_id; +} ogs_guami_t; + uint32_t ogs_amf_id_hexdump(ogs_amf_id_t *amf_id); -#define OGS_AMFIDSTRLEN (sizeof(ogs_amf_id_t)*2+1) ogs_amf_id_t *ogs_amf_id_from_string(ogs_amf_id_t *amf_id, const char *hex); -char *ogs_amf_id_to_string(ogs_amf_id_t *amf_id, char *buf); +char *ogs_amf_id_to_string(ogs_amf_id_t *amf_id); uint8_t ogs_amf_region_id(ogs_amf_id_t *amf_id); uint16_t ogs_amf_set_id(ogs_amf_id_t *amf_id); diff --git a/lib/core/ogs-conv.c b/lib/core/ogs-conv.c index 3cef05a8a..bfc7af084 100644 --- a/lib/core/ogs-conv.c +++ b/lib/core/ogs-conv.c @@ -155,3 +155,65 @@ char ogs_from_hex(char ch) { return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10; } + +char *ogs_uint24_to_string(ogs_uint24_t x) +{ + return ogs_msprintf("%06x", x.v); +} + +char *ogs_uint28_to_string(uint32_t x) +{ + return ogs_msprintf("%07x", x); +} + +char *ogs_uint32_to_string(uint32_t x) +{ + return ogs_msprintf("%08x", x); +} + +char *ogs_uint36_to_string(uint64_t x) +{ + return ogs_msprintf("%09llx", (long long)x); +} + +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); +} + +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 x; + + ogs_assert(str); + + x = 0; + ogs_ascii_to_hex(str, strlen(str), &x, 5); + + return be64toh(x) >> 28; +} diff --git a/lib/core/ogs-conv.h b/lib/core/ogs-conv.h index 324da27ee..3a27c30d3 100644 --- a/lib/core/ogs-conv.h +++ b/lib/core/ogs-conv.h @@ -39,6 +39,16 @@ 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); + +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); + #ifdef __cplusplus } #endif diff --git a/lib/core/ogs-macros.h b/lib/core/ogs-macros.h index edec277b4..769b5d646 100644 --- a/lib/core/ogs-macros.h +++ b/lib/core/ogs-macros.h @@ -124,6 +124,26 @@ extern "C" { #endif #endif +typedef struct ogs_uint24_s { + uint32_t v:24; +} __attribute__ ((packed)) ogs_uint24_t; + +static ogs_inline ogs_uint24_t ogs_be24toh(ogs_uint24_t x) +{ + uint32_t tmp = x.v; + tmp = be32toh(tmp); + x.v = tmp >> 8; + return x; +} + +static ogs_inline ogs_uint24_t ogs_htobe24(ogs_uint24_t x) +{ + uint32_t tmp = x.v; + tmp = htobe32(tmp); + x.v = tmp >> 8; + return x; +} + #if OGS_BYTE_ORDER == OGS_BIG_ENDIAN #define ED2(x1, x2) x1 x2 #define ED3(x1, x2, x3) x1 x2 x3 diff --git a/lib/core/ogs-time.c b/lib/core/ogs-time.c index 84fc3c080..a72a1ce2b 100644 --- a/lib/core/ogs-time.c +++ b/lib/core/ogs-time.c @@ -36,7 +36,6 @@ * The following code is stolen from mongodb-c-driver * https://github.com/mongodb/mongo-c-driver/blob/master/src/libbson/src/bson/bson-clock.c */ - int ogs_gettimeofday(struct timeval *tv) { #if defined(_WIN32) @@ -84,6 +83,56 @@ int ogs_gettimeofday(struct timeval *tv) #endif } +ogs_time_t ogs_time_now(void) +{ + int rc; + struct timeval tv; + + rc = ogs_gettimeofday(&tv); + ogs_assert(rc == 0); + + return tv.tv_sec * OGS_USEC_PER_SEC + tv.tv_usec; +} + +/* The following code is stolen from APR library */ +int ogs_time_from_lt(ogs_time_t *t, struct tm *tm, int tm_usec) +{ + ogs_time_t year = tm->tm_year; + ogs_time_t days; + static const int dayoffset[12] = + {306, 337, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275}; + + if (tm->tm_mon < 0 || tm->tm_mon >= 12) + return OGS_ERROR; + + /* shift new year to 1st March in order to make leap year calc easy */ + + if (tm->tm_mon < 2) + year--; + + /* Find number of days since 1st March 1900 (in the Gregorian calendar). */ + + days = year * 365 + year / 4 - year / 100 + (year / 100 + 3) / 4; + days += dayoffset[tm->tm_mon] + tm->tm_mday - 1; + days -= 25508; /* 1 jan 1970 is 25508 days since 1 mar 1900 */ + days = ((days * 24 + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec; + + if (days < 0) { + return OGS_ERROR; + } + *t = days * OGS_USEC_PER_SEC + tm_usec; + + return OGS_OK; +} + +int ogs_time_from_gmt(ogs_time_t *t, struct tm *tm, int tm_usec) +{ + int status = ogs_time_from_lt(t, tm, tm_usec); + if (status == OGS_OK) + *t -= (ogs_time_t) tm->tm_gmtoff * OGS_USEC_PER_SEC; + return status; +} + int ogs_timezone(void) { #if defined(_WIN32) @@ -109,18 +158,14 @@ int ogs_timezone(void) #else struct timeval tv; struct tm tm; - time_t t1, t2; int ret; ret = ogs_gettimeofday(&tv); ogs_assert(ret == 0); - t1 = tv.tv_sec; - ogs_gmtime(t1, &tm); - tm.tm_isdst = 0; - t2 = mktime(&tm); + ogs_localtime(tv.tv_sec, &tm); - return difftime(t1, t2); + return tm.tm_gmtoff; #endif } @@ -162,6 +207,7 @@ ogs_time_t ogs_get_monotonic_time(void) void ogs_localtime(time_t s, struct tm *tm) { ogs_assert(tm); + memset(tm, 0, sizeof(*tm)); #if (HAVE_LOCALTIME_R) (void)localtime_r(&s, tm); @@ -176,6 +222,7 @@ void ogs_localtime(time_t s, struct tm *tm) void ogs_gmtime(time_t s, struct tm *tm) { ogs_assert(tm); + memset(tm, 0, sizeof(*tm)); #if (HAVE_LOCALTIME_R) (void)gmtime_r(&s, tm); @@ -208,4 +255,3 @@ void ogs_usleep(time_t usec) req = rem; #endif } - diff --git a/lib/core/ogs-time.h b/lib/core/ogs-time.h index f19aa6fe5..26e83fc9c 100644 --- a/lib/core/ogs-time.h +++ b/lib/core/ogs-time.h @@ -34,7 +34,7 @@ typedef int64_t ogs_time_t; #define OGS_NO_WAIT_TIME (0) /** number of microseconds per second */ -#define OGS_USEC_PER_SEC (1000000) +#define OGS_USEC_PER_SEC (1000000L) /** @return ogs_time_t as a second */ #define ogs_time_sec(time) ((time) / OGS_USEC_PER_SEC) @@ -56,6 +56,10 @@ typedef int64_t ogs_time_t; int ogs_gettimeofday(struct timeval *tv); +ogs_time_t ogs_time_now(void); /* This returns GMT */ +int ogs_time_from_lt(ogs_time_t *t, struct tm *tm, int tm_usec); +int ogs_time_from_gmt(ogs_time_t *t, struct tm *tm, int tm_usec); + /** @return number of microseconds since an arbitrary point */ ogs_time_t ogs_get_monotonic_time(void); /** @return the GMT offset in seconds */ @@ -67,9 +71,6 @@ void ogs_gmtime(time_t s, struct tm *tm); void ogs_msleep(time_t msec); void ogs_usleep(time_t usec); -#define OGS_TIME_ISO8601_FORMATTED_LENGTH 128 -#define OGS_TIME_ISO8601_FORMAT "%Y-%m-%dT%H:%M:%S%z" - #define ogs_mktime mktime #define ogs_strptime strptime #define ogs_strftime strftime diff --git a/lib/gtp/conv.c b/lib/gtp/conv.c index 2970e35f1..9612271df 100644 --- a/lib/gtp/conv.c +++ b/lib/gtp/conv.c @@ -19,41 +19,6 @@ #include "ogs-gtp.h" -void ogs_gtp_bearers_in_create_indirect_tunnel_request( - ogs_gtp_tlv_bearer_context_t *bearers[][OGS_GTP_MAX_INDIRECT_TUNNEL], - ogs_gtp_create_indirect_data_forwarding_tunnel_request_t *req) -{ - - (*bearers)[0] = &req->bearer_context_0; - (*bearers)[1] = &req->bearer_context_1; - (*bearers)[2] = &req->bearer_context_2; - (*bearers)[3] = &req->bearer_context_3; - (*bearers)[4] = &req->bearer_context_4; - (*bearers)[5] = &req->bearer_context_5; - (*bearers)[6] = &req->bearer_context_6; - (*bearers)[7] = &req->bearer_context_7; - (*bearers)[8] = &req->bearer_context_8; - (*bearers)[9] = &req->bearer_context_9; - (*bearers)[10] = &req->bearer_context_10; -} - -void ogs_gtp_bearers_in_create_indirect_tunnel_response( - ogs_gtp_tlv_bearer_context_t *bearers[][OGS_GTP_MAX_INDIRECT_TUNNEL], - ogs_gtp_create_indirect_data_forwarding_tunnel_response_t *rsp) -{ - (*bearers)[0] = &rsp->bearer_context_0; - (*bearers)[1] = &rsp->bearer_context_1; - (*bearers)[2] = &rsp->bearer_context_2; - (*bearers)[3] = &rsp->bearer_context_3; - (*bearers)[4] = &rsp->bearer_context_4; - (*bearers)[5] = &rsp->bearer_context_5; - (*bearers)[6] = &rsp->bearer_context_6; - (*bearers)[7] = &rsp->bearer_context_7; - (*bearers)[8] = &rsp->bearer_context_8; - (*bearers)[9] = &rsp->bearer_context_9; - (*bearers)[10] = &rsp->bearer_context_10; -} - int ogs_gtp_f_teid_to_sockaddr( ogs_gtp_f_teid_t *f_teid, uint16_t port, ogs_sockaddr_t **list) { diff --git a/lib/gtp/conv.h b/lib/gtp/conv.h index 0ff883af5..84dd9f201 100644 --- a/lib/gtp/conv.h +++ b/lib/gtp/conv.h @@ -28,16 +28,6 @@ extern "C" { #endif -#define OGS_GTP_MAX_INDIRECT_TUNNEL 11 - -/* Create Indirect Data Forwarding Tunnel Request/Response */ -void ogs_gtp_bearers_in_create_indirect_tunnel_request( - ogs_gtp_tlv_bearer_context_t *bearers[][OGS_GTP_MAX_INDIRECT_TUNNEL], - ogs_gtp_create_indirect_data_forwarding_tunnel_request_t *req); -void ogs_gtp_bearers_in_create_indirect_tunnel_response( - ogs_gtp_tlv_bearer_context_t *bearers[][OGS_GTP_MAX_INDIRECT_TUNNEL], - ogs_gtp_create_indirect_data_forwarding_tunnel_response_t *rsp); - int ogs_gtp_f_teid_to_sockaddr( ogs_gtp_f_teid_t *f_teid, uint16_t port, ogs_sockaddr_t **list); int ogs_gtp_sockaddr_to_f_teid(ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6, diff --git a/lib/gtp/message.c b/lib/gtp/message.c index 1ba9040db..8b3deeca9 100644 --- a/lib/gtp/message.c +++ b/lib/gtp/message.c @@ -20,7 +20,7 @@ /******************************************************************************* * This file had been created by gtp-tlv.py script v0.1.0 * Please do not modify this file but regenerate it via script. - * Created on: 2020-06-30 21:17:14.937085 by acetcom + * Created on: 2020-07-08 16:42:53.180060 by acetcom * from 29274-g30.docx ******************************************************************************/ @@ -1868,357 +1868,6 @@ ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_1 = } }; -ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_2 = -{ - OGS_TLV_COMPOUND, - "Bearer Context", - OGS_GTP_BEARER_CONTEXT_TYPE, - 0, - 2, - sizeof(ogs_gtp_tlv_bearer_context_t), - { - &ogs_gtp_tlv_desc_ebi_0, - &ogs_gtp_tlv_desc_bearer_tft_0, - &ogs_gtp_tlv_desc_f_teid_0, - &ogs_gtp_tlv_desc_f_teid_1, - &ogs_gtp_tlv_desc_f_teid_2, - &ogs_gtp_tlv_desc_f_teid_3, - &ogs_gtp_tlv_desc_f_teid_4, - &ogs_gtp_tlv_desc_f_teid_5, - &ogs_gtp_tlv_desc_f_teid_6, - &ogs_gtp_tlv_desc_bearer_qos_0, - &ogs_gtp_tlv_desc_f_teid_7, - &ogs_gtp_tlv_desc_cause_0, - &ogs_gtp_tlv_desc_charging_id_0, - &ogs_gtp_tlv_desc_bearer_flags_0, - &ogs_gtp_tlv_desc_pco_0, - &ogs_gtp_tlv_desc_epco_0, - &ogs_gtp_tlv_desc_maximum_packet_loss_rate_0, - &ogs_gtp_tlv_desc_f_teid_8, - &ogs_gtp_tlv_desc_f_teid_9, - &ogs_gtp_tlv_desc_f_teid_10, - &ogs_gtp_tlv_desc_f_teid_11, - &ogs_gtp_tlv_desc_ran_nas_cause_0, - &ogs_gtp_tlv_desc_apco_0, - &ogs_gtp_tlv_desc_f_container_0, - &ogs_gtp_tlv_desc_ti_0, - &ogs_gtp_tlv_desc_packet_flow_id_0, - NULL, - } -}; - -ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_3 = -{ - OGS_TLV_COMPOUND, - "Bearer Context", - OGS_GTP_BEARER_CONTEXT_TYPE, - 0, - 3, - sizeof(ogs_gtp_tlv_bearer_context_t), - { - &ogs_gtp_tlv_desc_ebi_0, - &ogs_gtp_tlv_desc_bearer_tft_0, - &ogs_gtp_tlv_desc_f_teid_0, - &ogs_gtp_tlv_desc_f_teid_1, - &ogs_gtp_tlv_desc_f_teid_2, - &ogs_gtp_tlv_desc_f_teid_3, - &ogs_gtp_tlv_desc_f_teid_4, - &ogs_gtp_tlv_desc_f_teid_5, - &ogs_gtp_tlv_desc_f_teid_6, - &ogs_gtp_tlv_desc_bearer_qos_0, - &ogs_gtp_tlv_desc_f_teid_7, - &ogs_gtp_tlv_desc_cause_0, - &ogs_gtp_tlv_desc_charging_id_0, - &ogs_gtp_tlv_desc_bearer_flags_0, - &ogs_gtp_tlv_desc_pco_0, - &ogs_gtp_tlv_desc_epco_0, - &ogs_gtp_tlv_desc_maximum_packet_loss_rate_0, - &ogs_gtp_tlv_desc_f_teid_8, - &ogs_gtp_tlv_desc_f_teid_9, - &ogs_gtp_tlv_desc_f_teid_10, - &ogs_gtp_tlv_desc_f_teid_11, - &ogs_gtp_tlv_desc_ran_nas_cause_0, - &ogs_gtp_tlv_desc_apco_0, - &ogs_gtp_tlv_desc_f_container_0, - &ogs_gtp_tlv_desc_ti_0, - &ogs_gtp_tlv_desc_packet_flow_id_0, - NULL, - } -}; - -ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_4 = -{ - OGS_TLV_COMPOUND, - "Bearer Context", - OGS_GTP_BEARER_CONTEXT_TYPE, - 0, - 4, - sizeof(ogs_gtp_tlv_bearer_context_t), - { - &ogs_gtp_tlv_desc_ebi_0, - &ogs_gtp_tlv_desc_bearer_tft_0, - &ogs_gtp_tlv_desc_f_teid_0, - &ogs_gtp_tlv_desc_f_teid_1, - &ogs_gtp_tlv_desc_f_teid_2, - &ogs_gtp_tlv_desc_f_teid_3, - &ogs_gtp_tlv_desc_f_teid_4, - &ogs_gtp_tlv_desc_f_teid_5, - &ogs_gtp_tlv_desc_f_teid_6, - &ogs_gtp_tlv_desc_bearer_qos_0, - &ogs_gtp_tlv_desc_f_teid_7, - &ogs_gtp_tlv_desc_cause_0, - &ogs_gtp_tlv_desc_charging_id_0, - &ogs_gtp_tlv_desc_bearer_flags_0, - &ogs_gtp_tlv_desc_pco_0, - &ogs_gtp_tlv_desc_epco_0, - &ogs_gtp_tlv_desc_maximum_packet_loss_rate_0, - &ogs_gtp_tlv_desc_f_teid_8, - &ogs_gtp_tlv_desc_f_teid_9, - &ogs_gtp_tlv_desc_f_teid_10, - &ogs_gtp_tlv_desc_f_teid_11, - &ogs_gtp_tlv_desc_ran_nas_cause_0, - &ogs_gtp_tlv_desc_apco_0, - &ogs_gtp_tlv_desc_f_container_0, - &ogs_gtp_tlv_desc_ti_0, - &ogs_gtp_tlv_desc_packet_flow_id_0, - NULL, - } -}; - -ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_5 = -{ - OGS_TLV_COMPOUND, - "Bearer Context", - OGS_GTP_BEARER_CONTEXT_TYPE, - 0, - 5, - sizeof(ogs_gtp_tlv_bearer_context_t), - { - &ogs_gtp_tlv_desc_ebi_0, - &ogs_gtp_tlv_desc_bearer_tft_0, - &ogs_gtp_tlv_desc_f_teid_0, - &ogs_gtp_tlv_desc_f_teid_1, - &ogs_gtp_tlv_desc_f_teid_2, - &ogs_gtp_tlv_desc_f_teid_3, - &ogs_gtp_tlv_desc_f_teid_4, - &ogs_gtp_tlv_desc_f_teid_5, - &ogs_gtp_tlv_desc_f_teid_6, - &ogs_gtp_tlv_desc_bearer_qos_0, - &ogs_gtp_tlv_desc_f_teid_7, - &ogs_gtp_tlv_desc_cause_0, - &ogs_gtp_tlv_desc_charging_id_0, - &ogs_gtp_tlv_desc_bearer_flags_0, - &ogs_gtp_tlv_desc_pco_0, - &ogs_gtp_tlv_desc_epco_0, - &ogs_gtp_tlv_desc_maximum_packet_loss_rate_0, - &ogs_gtp_tlv_desc_f_teid_8, - &ogs_gtp_tlv_desc_f_teid_9, - &ogs_gtp_tlv_desc_f_teid_10, - &ogs_gtp_tlv_desc_f_teid_11, - &ogs_gtp_tlv_desc_ran_nas_cause_0, - &ogs_gtp_tlv_desc_apco_0, - &ogs_gtp_tlv_desc_f_container_0, - &ogs_gtp_tlv_desc_ti_0, - &ogs_gtp_tlv_desc_packet_flow_id_0, - NULL, - } -}; - -ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_6 = -{ - OGS_TLV_COMPOUND, - "Bearer Context", - OGS_GTP_BEARER_CONTEXT_TYPE, - 0, - 6, - sizeof(ogs_gtp_tlv_bearer_context_t), - { - &ogs_gtp_tlv_desc_ebi_0, - &ogs_gtp_tlv_desc_bearer_tft_0, - &ogs_gtp_tlv_desc_f_teid_0, - &ogs_gtp_tlv_desc_f_teid_1, - &ogs_gtp_tlv_desc_f_teid_2, - &ogs_gtp_tlv_desc_f_teid_3, - &ogs_gtp_tlv_desc_f_teid_4, - &ogs_gtp_tlv_desc_f_teid_5, - &ogs_gtp_tlv_desc_f_teid_6, - &ogs_gtp_tlv_desc_bearer_qos_0, - &ogs_gtp_tlv_desc_f_teid_7, - &ogs_gtp_tlv_desc_cause_0, - &ogs_gtp_tlv_desc_charging_id_0, - &ogs_gtp_tlv_desc_bearer_flags_0, - &ogs_gtp_tlv_desc_pco_0, - &ogs_gtp_tlv_desc_epco_0, - &ogs_gtp_tlv_desc_maximum_packet_loss_rate_0, - &ogs_gtp_tlv_desc_f_teid_8, - &ogs_gtp_tlv_desc_f_teid_9, - &ogs_gtp_tlv_desc_f_teid_10, - &ogs_gtp_tlv_desc_f_teid_11, - &ogs_gtp_tlv_desc_ran_nas_cause_0, - &ogs_gtp_tlv_desc_apco_0, - &ogs_gtp_tlv_desc_f_container_0, - &ogs_gtp_tlv_desc_ti_0, - &ogs_gtp_tlv_desc_packet_flow_id_0, - NULL, - } -}; - -ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_7 = -{ - OGS_TLV_COMPOUND, - "Bearer Context", - OGS_GTP_BEARER_CONTEXT_TYPE, - 0, - 7, - sizeof(ogs_gtp_tlv_bearer_context_t), - { - &ogs_gtp_tlv_desc_ebi_0, - &ogs_gtp_tlv_desc_bearer_tft_0, - &ogs_gtp_tlv_desc_f_teid_0, - &ogs_gtp_tlv_desc_f_teid_1, - &ogs_gtp_tlv_desc_f_teid_2, - &ogs_gtp_tlv_desc_f_teid_3, - &ogs_gtp_tlv_desc_f_teid_4, - &ogs_gtp_tlv_desc_f_teid_5, - &ogs_gtp_tlv_desc_f_teid_6, - &ogs_gtp_tlv_desc_bearer_qos_0, - &ogs_gtp_tlv_desc_f_teid_7, - &ogs_gtp_tlv_desc_cause_0, - &ogs_gtp_tlv_desc_charging_id_0, - &ogs_gtp_tlv_desc_bearer_flags_0, - &ogs_gtp_tlv_desc_pco_0, - &ogs_gtp_tlv_desc_epco_0, - &ogs_gtp_tlv_desc_maximum_packet_loss_rate_0, - &ogs_gtp_tlv_desc_f_teid_8, - &ogs_gtp_tlv_desc_f_teid_9, - &ogs_gtp_tlv_desc_f_teid_10, - &ogs_gtp_tlv_desc_f_teid_11, - &ogs_gtp_tlv_desc_ran_nas_cause_0, - &ogs_gtp_tlv_desc_apco_0, - &ogs_gtp_tlv_desc_f_container_0, - &ogs_gtp_tlv_desc_ti_0, - &ogs_gtp_tlv_desc_packet_flow_id_0, - NULL, - } -}; - -ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_8 = -{ - OGS_TLV_COMPOUND, - "Bearer Context", - OGS_GTP_BEARER_CONTEXT_TYPE, - 0, - 8, - sizeof(ogs_gtp_tlv_bearer_context_t), - { - &ogs_gtp_tlv_desc_ebi_0, - &ogs_gtp_tlv_desc_bearer_tft_0, - &ogs_gtp_tlv_desc_f_teid_0, - &ogs_gtp_tlv_desc_f_teid_1, - &ogs_gtp_tlv_desc_f_teid_2, - &ogs_gtp_tlv_desc_f_teid_3, - &ogs_gtp_tlv_desc_f_teid_4, - &ogs_gtp_tlv_desc_f_teid_5, - &ogs_gtp_tlv_desc_f_teid_6, - &ogs_gtp_tlv_desc_bearer_qos_0, - &ogs_gtp_tlv_desc_f_teid_7, - &ogs_gtp_tlv_desc_cause_0, - &ogs_gtp_tlv_desc_charging_id_0, - &ogs_gtp_tlv_desc_bearer_flags_0, - &ogs_gtp_tlv_desc_pco_0, - &ogs_gtp_tlv_desc_epco_0, - &ogs_gtp_tlv_desc_maximum_packet_loss_rate_0, - &ogs_gtp_tlv_desc_f_teid_8, - &ogs_gtp_tlv_desc_f_teid_9, - &ogs_gtp_tlv_desc_f_teid_10, - &ogs_gtp_tlv_desc_f_teid_11, - &ogs_gtp_tlv_desc_ran_nas_cause_0, - &ogs_gtp_tlv_desc_apco_0, - &ogs_gtp_tlv_desc_f_container_0, - &ogs_gtp_tlv_desc_ti_0, - &ogs_gtp_tlv_desc_packet_flow_id_0, - NULL, - } -}; - -ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_9 = -{ - OGS_TLV_COMPOUND, - "Bearer Context", - OGS_GTP_BEARER_CONTEXT_TYPE, - 0, - 9, - sizeof(ogs_gtp_tlv_bearer_context_t), - { - &ogs_gtp_tlv_desc_ebi_0, - &ogs_gtp_tlv_desc_bearer_tft_0, - &ogs_gtp_tlv_desc_f_teid_0, - &ogs_gtp_tlv_desc_f_teid_1, - &ogs_gtp_tlv_desc_f_teid_2, - &ogs_gtp_tlv_desc_f_teid_3, - &ogs_gtp_tlv_desc_f_teid_4, - &ogs_gtp_tlv_desc_f_teid_5, - &ogs_gtp_tlv_desc_f_teid_6, - &ogs_gtp_tlv_desc_bearer_qos_0, - &ogs_gtp_tlv_desc_f_teid_7, - &ogs_gtp_tlv_desc_cause_0, - &ogs_gtp_tlv_desc_charging_id_0, - &ogs_gtp_tlv_desc_bearer_flags_0, - &ogs_gtp_tlv_desc_pco_0, - &ogs_gtp_tlv_desc_epco_0, - &ogs_gtp_tlv_desc_maximum_packet_loss_rate_0, - &ogs_gtp_tlv_desc_f_teid_8, - &ogs_gtp_tlv_desc_f_teid_9, - &ogs_gtp_tlv_desc_f_teid_10, - &ogs_gtp_tlv_desc_f_teid_11, - &ogs_gtp_tlv_desc_ran_nas_cause_0, - &ogs_gtp_tlv_desc_apco_0, - &ogs_gtp_tlv_desc_f_container_0, - &ogs_gtp_tlv_desc_ti_0, - &ogs_gtp_tlv_desc_packet_flow_id_0, - NULL, - } -}; - -ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_10 = -{ - OGS_TLV_COMPOUND, - "Bearer Context", - OGS_GTP_BEARER_CONTEXT_TYPE, - 0, - 10, - sizeof(ogs_gtp_tlv_bearer_context_t), - { - &ogs_gtp_tlv_desc_ebi_0, - &ogs_gtp_tlv_desc_bearer_tft_0, - &ogs_gtp_tlv_desc_f_teid_0, - &ogs_gtp_tlv_desc_f_teid_1, - &ogs_gtp_tlv_desc_f_teid_2, - &ogs_gtp_tlv_desc_f_teid_3, - &ogs_gtp_tlv_desc_f_teid_4, - &ogs_gtp_tlv_desc_f_teid_5, - &ogs_gtp_tlv_desc_f_teid_6, - &ogs_gtp_tlv_desc_bearer_qos_0, - &ogs_gtp_tlv_desc_f_teid_7, - &ogs_gtp_tlv_desc_cause_0, - &ogs_gtp_tlv_desc_charging_id_0, - &ogs_gtp_tlv_desc_bearer_flags_0, - &ogs_gtp_tlv_desc_pco_0, - &ogs_gtp_tlv_desc_epco_0, - &ogs_gtp_tlv_desc_maximum_packet_loss_rate_0, - &ogs_gtp_tlv_desc_f_teid_8, - &ogs_gtp_tlv_desc_f_teid_9, - &ogs_gtp_tlv_desc_f_teid_10, - &ogs_gtp_tlv_desc_f_teid_11, - &ogs_gtp_tlv_desc_ran_nas_cause_0, - &ogs_gtp_tlv_desc_apco_0, - &ogs_gtp_tlv_desc_f_container_0, - &ogs_gtp_tlv_desc_ti_0, - &ogs_gtp_tlv_desc_packet_flow_id_0, - NULL, - } -}; - ogs_tlv_desc_t ogs_gtp_tlv_desc_pdn_connection_0 = { OGS_TLV_COMPOUND, @@ -2911,16 +2560,7 @@ ogs_tlv_desc_t ogs_gtp_tlv_desc_create_indirect_data_forwarding_tunnel_request = &ogs_gtp_tlv_desc_indication_0, &ogs_gtp_tlv_desc_f_teid_0, &ogs_gtp_tlv_desc_bearer_context_0, - &ogs_gtp_tlv_desc_bearer_context_1, - &ogs_gtp_tlv_desc_bearer_context_2, - &ogs_gtp_tlv_desc_bearer_context_3, - &ogs_gtp_tlv_desc_bearer_context_4, - &ogs_gtp_tlv_desc_bearer_context_5, - &ogs_gtp_tlv_desc_bearer_context_6, - &ogs_gtp_tlv_desc_bearer_context_7, - &ogs_gtp_tlv_desc_bearer_context_8, - &ogs_gtp_tlv_desc_bearer_context_9, - &ogs_gtp_tlv_desc_bearer_context_10, + &ogs_tlv_desc_more8, &ogs_gtp_tlv_desc_recovery_0, NULL, }}; @@ -2933,16 +2573,7 @@ ogs_tlv_desc_t ogs_gtp_tlv_desc_create_indirect_data_forwarding_tunnel_response &ogs_gtp_tlv_desc_cause_0, &ogs_gtp_tlv_desc_f_teid_0, &ogs_gtp_tlv_desc_bearer_context_0, - &ogs_gtp_tlv_desc_bearer_context_1, - &ogs_gtp_tlv_desc_bearer_context_2, - &ogs_gtp_tlv_desc_bearer_context_3, - &ogs_gtp_tlv_desc_bearer_context_4, - &ogs_gtp_tlv_desc_bearer_context_5, - &ogs_gtp_tlv_desc_bearer_context_6, - &ogs_gtp_tlv_desc_bearer_context_7, - &ogs_gtp_tlv_desc_bearer_context_8, - &ogs_gtp_tlv_desc_bearer_context_9, - &ogs_gtp_tlv_desc_bearer_context_10, + &ogs_tlv_desc_more8, &ogs_gtp_tlv_desc_recovery_0, NULL, }}; diff --git a/lib/gtp/message.h b/lib/gtp/message.h index fa5e84ff0..f3af07427 100644 --- a/lib/gtp/message.h +++ b/lib/gtp/message.h @@ -20,7 +20,7 @@ /******************************************************************************* * This file had been created by gtp-tlv.py script v0.1.0 * Please do not modify this file but regenerate it via script. - * Created on: 2020-06-30 21:17:14.929915 by acetcom + * Created on: 2020-07-08 16:42:53.173072 by acetcom * from 29274-g30.docx ******************************************************************************/ @@ -432,15 +432,6 @@ extern ogs_tlv_desc_t ogs_gtp_tlv_desc_remote_ue_context_0; extern ogs_tlv_desc_t ogs_gtp_tlv_desc_v2x_context_0; extern ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_0; extern ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_1; -extern ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_2; -extern ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_3; -extern ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_4; -extern ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_5; -extern ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_6; -extern ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_7; -extern ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_8; -extern ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_9; -extern ogs_tlv_desc_t ogs_gtp_tlv_desc_bearer_context_10; extern ogs_tlv_desc_t ogs_gtp_tlv_desc_pdn_connection_0; extern ogs_tlv_desc_t ogs_gtp_tlv_desc_overload_control_information_0; extern ogs_tlv_desc_t ogs_gtp_tlv_desc_overload_control_information_1; @@ -1167,34 +1158,14 @@ typedef struct ogs_gtp_create_indirect_data_forwarding_tunnel_request_s { ogs_gtp_tlv_mei_t me_identity; ogs_gtp_tlv_indication_t indication_flags; ogs_gtp_tlv_f_teid_t sender_f_teid_for_control_plane; - ogs_gtp_tlv_bearer_context_t bearer_context_0; - ogs_gtp_tlv_bearer_context_t bearer_context_1; - ogs_gtp_tlv_bearer_context_t bearer_context_2; - ogs_gtp_tlv_bearer_context_t bearer_context_3; - ogs_gtp_tlv_bearer_context_t bearer_context_4; - ogs_gtp_tlv_bearer_context_t bearer_context_5; - ogs_gtp_tlv_bearer_context_t bearer_context_6; - ogs_gtp_tlv_bearer_context_t bearer_context_7; - ogs_gtp_tlv_bearer_context_t bearer_context_8; - ogs_gtp_tlv_bearer_context_t bearer_context_9; - ogs_gtp_tlv_bearer_context_t bearer_context_10; + ogs_gtp_tlv_bearer_context_t bearer_contexts[8]; ogs_gtp_tlv_recovery_t recovery; } ogs_gtp_create_indirect_data_forwarding_tunnel_request_t; typedef struct ogs_gtp_create_indirect_data_forwarding_tunnel_response_s { ogs_gtp_tlv_cause_t cause; ogs_gtp_tlv_f_teid_t sender_f_teid_for_control_plane; - ogs_gtp_tlv_bearer_context_t bearer_context_0; - ogs_gtp_tlv_bearer_context_t bearer_context_1; - ogs_gtp_tlv_bearer_context_t bearer_context_2; - ogs_gtp_tlv_bearer_context_t bearer_context_3; - ogs_gtp_tlv_bearer_context_t bearer_context_4; - ogs_gtp_tlv_bearer_context_t bearer_context_5; - ogs_gtp_tlv_bearer_context_t bearer_context_6; - ogs_gtp_tlv_bearer_context_t bearer_context_7; - ogs_gtp_tlv_bearer_context_t bearer_context_8; - ogs_gtp_tlv_bearer_context_t bearer_context_9; - ogs_gtp_tlv_bearer_context_t bearer_context_10; + ogs_gtp_tlv_bearer_context_t bearer_contexts[8]; ogs_gtp_tlv_recovery_t recovery; } ogs_gtp_create_indirect_data_forwarding_tunnel_response_t; diff --git a/lib/gtp/support/29274-g30.docx b/lib/gtp/support/29274-g30.docx index 3cabb4778..ea2f989bf 100644 Binary files a/lib/gtp/support/29274-g30.docx and b/lib/gtp/support/29274-g30.docx differ diff --git a/lib/gtp/support/cache/tlv-msg-166.py b/lib/gtp/support/cache/tlv-msg-166.py index 8b85d21b0..126a9fd39 100644 --- a/lib/gtp/support/cache/tlv-msg-166.py +++ b/lib/gtp/support/cache/tlv-msg-166.py @@ -3,16 +3,6 @@ ies.append({ "ie_type" : "IMSI", "ie_value" : "IMSI", "presence" : "C", "instanc ies.append({ "ie_type" : "MEI", "ie_value" : "ME Identity", "presence" : "C", "instance" : "0", "comment" : "This IE shall be included by the MME/SGSN if the SGW that the MME/SGSN selects for indirect data forwarding is different from the SGW already in use for the UE as the anchor point and if one of the following condition is satisfied:- If the UE is emergency or RLOS attached and the UE is UICCless; or- If the UE is emergency or RLOS attached and the IMSI is not authenticated"}) ies.append({ "ie_type" : "Indication", "ie_value" : "Indication Flags", "presence" : "CO", "instance" : "0", "comment" : "This IE shall be included if any one of the applicable flags is set to 1.Applicable flags are:Unauthenticated IMSI: This flag shall be set to 1 if the IMSI present in the message is not authenticated and is for an emergency or RLOS attached UE."}) ies.append({ "ie_type" : "F-TEID", "ie_value" : "Sender F-TEID for Control Plane", "presence" : "C", "instance" : "0", "comment" : "This IE shall be included by the MME/SGSN if the SGW that the MME/SGSN selects for indirect data forwarding is different from the SGW already in use for the UE as the anchor point.See NOTE1."}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 0", "presence" : "M", "instance" : "0", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 1", "presence" : "O", "instance" : "1", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 2", "presence" : "O", "instance" : "2", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 3", "presence" : "O", "instance" : "3", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 4", "presence" : "O", "instance" : "4", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 5", "presence" : "O", "instance" : "5", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 6", "presence" : "O", "instance" : "6", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 7", "presence" : "O", "instance" : "7", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 8", "presence" : "O", "instance" : "8", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 9", "presence" : "O", "instance" : "9", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 10", "presence" : "O", "instance" : "10", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) +ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Contexts", "presence" : "M", "instance" : "0", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) ies.append({ "ie_type" : "Recovery", "ie_value" : "Recovery", "presence" : "CO", "instance" : "0", "comment" : "This IE shall be included if contacting the peer for the first time."}) msg_list[key]["ies"] = ies diff --git a/lib/gtp/support/cache/tlv-msg-167.py b/lib/gtp/support/cache/tlv-msg-167.py index 8ffdb423c..fffc8d71a 100644 --- a/lib/gtp/support/cache/tlv-msg-167.py +++ b/lib/gtp/support/cache/tlv-msg-167.py @@ -1,25 +1,6 @@ ies = [] ies.append({ "ie_type" : "Cause", "ie_value" : "Cause", "presence" : "M", "instance" : "0", "comment" : ""}) ies.append({ "ie_type" : "F-TEID", "ie_value" : "Sender F-TEID for Control Plane", "presence" : "C", "instance" : "0", "comment" : "This IE shall be included by an SGW if the SGW receives a Sender F-TEID for Control Plane IE from an MME/SGSN in a Create Indirect Data Forwarding Tunnel Request message.See also NOTE 1 in Table 7.2.18-1."}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 0", "presence" : "M", "instance" : "0", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 1", "presence" : "O", "instance" : "1", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -type_list["Bearer Context"]["max_instance"] = "2" -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 2", "presence" : "O", "instance" : "2", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -type_list["Bearer Context"]["max_instance"] = "3" -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 3", "presence" : "O", "instance" : "3", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -type_list["Bearer Context"]["max_instance"] = "4" -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 4", "presence" : "O", "instance" : "4", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -type_list["Bearer Context"]["max_instance"] = "5" -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 5", "presence" : "O", "instance" : "5", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -type_list["Bearer Context"]["max_instance"] = "6" -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 6", "presence" : "O", "instance" : "6", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -type_list["Bearer Context"]["max_instance"] = "7" -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 7", "presence" : "O", "instance" : "7", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -type_list["Bearer Context"]["max_instance"] = "8" -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 8", "presence" : "O", "instance" : "8", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -type_list["Bearer Context"]["max_instance"] = "9" -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 9", "presence" : "O", "instance" : "9", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) -type_list["Bearer Context"]["max_instance"] = "10" -ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Context 10", "presence" : "O", "instance" : "10", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) +ies.append({ "ie_type" : "Bearer Context", "ie_value" : "Bearer Contexts", "presence" : "M", "instance" : "0", "comment" : "Several IEs with this type and instance value may be included as necessary to represent a list of Bearers"}) ies.append({ "ie_type" : "Recovery", "ie_value" : "Recovery", "presence" : "CO", "instance" : "0", "comment" : "This IE shall be included if contacting the peer for the first time"}) msg_list[key]["ies"] = ies diff --git a/lib/gtp/support/gtp-tlv.py b/lib/gtp/support/gtp-tlv.py index b8d61b8b0..799ac0384 100644 --- a/lib/gtp/support/gtp-tlv.py +++ b/lib/gtp/support/gtp-tlv.py @@ -527,8 +527,12 @@ for (k, v) in sorted_msg_list: if "ies" in msg_list[k]: f.write("typedef struct ogs_gtp_" + v_lower(k) + "_s {\n") for ies in msg_list[k]["ies"]: - f.write(" ogs_gtp_tlv_" + v_lower(ies["ie_type"]) + "_t " + \ - v_lower(ies["ie_value"]) + ";\n") + if (k == 'Create Indirect Data Forwarding Tunnel Request' or k == 'Create Indirect Data Forwarding Tunnel Response') and ies["ie_value"] == 'Bearer Contexts': + f.write(" ogs_gtp_tlv_" + v_lower(ies["ie_type"]) + "_t " + \ + v_lower(ies["ie_value"]) + "[8];\n") + else: + f.write(" ogs_gtp_tlv_" + v_lower(ies["ie_type"]) + "_t " + \ + v_lower(ies["ie_value"]) + ";\n") f.write("} ogs_gtp_" + v_lower(k) + "_t;\n") f.write("\n") @@ -613,7 +617,9 @@ for (k, v) in sorted_msg_list: f.write(" \"%s\",\n" % k) f.write(" 0, 0, 0, 0, {\n") for ies in msg_list[k]["ies"]: - f.write(" &ogs_gtp_tlv_desc_%s_%s,\n" % (v_lower(ies["ie_type"]), v_lower(ies["instance"]))) + f.write(" &ogs_gtp_tlv_desc_%s_%s,\n" % (v_lower(ies["ie_type"]), v_lower(ies["instance"]))) + if (k == 'Create Indirect Data Forwarding Tunnel Request' or k == 'Create Indirect Data Forwarding Tunnel Response') and ies["ie_value"] == 'Bearer Contexts': + f.write(" &ogs_tlv_desc_more8,\n") f.write(" NULL,\n") f.write("}};\n\n") f.write("\n") diff --git a/lib/gtp/types.h b/lib/gtp/types.h index 1f648ead0..cb4deaf6f 100644 --- a/lib/gtp/types.h +++ b/lib/gtp/types.h @@ -30,6 +30,8 @@ extern "C" { #define OGS_GTPV1U_EXTENSION_HEADER_LEN 4 +#define OGS_GTP_MAX_INDIRECT_TUNNEL 8 + typedef struct ogs_gtp_extension_header_s { #define OGS_GTP_EXTENSION_HEADER_TYPE_PDU_SESSION_CONTAINER 0x85 #define OGS_GTP_EXTENSION_HEADER_TYPE_NO_MORE_EXTENSION_HEADERS 0x0 @@ -412,10 +414,10 @@ int16_t ogs_gtp_build_uli(ogs_tlv_octet_t *octet, #define OGS_GTP_F_TEID_S11_MME_GTP_U 38 #define OGS_GTP_F_TEID_S11_SGW_GTP_U 39 -#define OGS_GTP_F_TEID_HDR_LEN 5 -#define OGS_GTP_F_TEID_IPV4_LEN OGS_IPV4_LEN+OGS_GTP_F_TEID_HDR_LEN -#define OGS_GTP_F_TEID_IPV6_LEN OGS_IPV6_LEN+OGS_GTP_F_TEID_HDR_LEN -#define OGS_GTP_F_TEID_IPV4V6_LEN OGS_IPV4V6_LEN+OGS_GTP_F_TEID_HDR_LEN +#define OGS_GTP_F_TEID_HDR_LEN 5 +#define OGS_GTP_F_TEID_IPV4_LEN OGS_IPV4_LEN+OGS_GTP_F_TEID_HDR_LEN +#define OGS_GTP_F_TEID_IPV6_LEN OGS_IPV6_LEN+OGS_GTP_F_TEID_HDR_LEN +#define OGS_GTP_F_TEID_IPV4V6_LEN OGS_IPV4V6_LEN+OGS_GTP_F_TEID_HDR_LEN typedef struct ogs_gtp_f_teid_s { ED3(uint8_t ipv4:1;, uint8_t ipv6:1;, @@ -477,4 +479,3 @@ ED2(uint8_t spare:6;, #endif #endif /* OGS_GTP_TYPES_H */ - diff --git a/lib/nas/common/types.h b/lib/nas/common/types.h index 8bd52a874..6413e88b8 100644 --- a/lib/nas/common/types.h +++ b/lib/nas/common/types.h @@ -380,7 +380,7 @@ typedef uint8_t ogs_nas_time_zone_t; * See subclause 10.5.3.9 in 3GPP TS 24.008 [13]. * 9.2.3.11 TPServiceCentreTimeStamp (TPSCTS) in 3GPP TS 23.040 [90] * O TV 8 */ -#define OGS_OGS_NAS_TIME_TO_BCD(x) OGS_TIME_TO_BCD(x) +#define OGS_NAS_TIME_TO_BCD(x) OGS_TIME_TO_BCD(x) typedef struct ogs_nas_time_zone_and_time_s { uint8_t year; uint8_t mon; @@ -393,7 +393,7 @@ typedef struct ogs_nas_time_zone_and_time_s { * the first bit (bit 3 of the seventh octet of * the TP-Service-Centre-Time-Stamp field) represents * the algebraic sign of this difference (0: positive, 1: negative). */ - uint8_t timezone; + uint8_t timezone; } ogs_nas_time_zone_and_time_t; /* 9.9.3.33 Tracking area identity list diff --git a/lib/pfcp/context.c b/lib/pfcp/context.c index 8edb32459..8d83a63e6 100644 --- a/lib/pfcp/context.c +++ b/lib/pfcp/context.c @@ -242,22 +242,6 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote) dev = ogs_yaml_iter_value(&pfcp_iter); } else if (!strcmp(pfcp_key, "apn")) { /* Skip */ - } else if (!strcmp(pfcp_key, "upf_selection_mode")) { - ogs_assert(ogs_yaml_iter_type(&pfcp_iter) != - YAML_SCALAR_NODE); - const char *upf_selection_mode = ogs_yaml_iter_value(&pfcp_iter); - - if (!strcmp(upf_selection_mode, "rr")) - self.upf_selection_mode = UPF_SELECT_RR; - else if (!strcmp(upf_selection_mode, "tac")) - self.upf_selection_mode = UPF_SELECT_TAC; - else if (!strcmp(upf_selection_mode, "apn")) - self.upf_selection_mode = UPF_SELECT_APN; - else if (!strcmp(upf_selection_mode, "enb_id")) - self.upf_selection_mode = UPF_SELECT_ENB_ID; - else - ogs_warn("unknown upf_selection_mode `%s`", - upf_selection_mode); } else ogs_warn("unknown key `%s`", pfcp_key); } @@ -453,10 +437,12 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote) uint16_t port = self.pfcp_port; uint16_t tac[OGS_MAX_NUM_OF_TAI] = {0,}; uint8_t num_of_tac = 0; - const char * apn[OGS_MAX_NUM_OF_APN]; + const char *apn[OGS_MAX_NUM_OF_APN]; uint8_t num_of_apn = 0; - uint32_t enb_id[OGS_MAX_NUM_OF_ENB_ID] = {0,}; - uint8_t num_of_enb_id = 0; + uint32_t e_cell_id[OGS_MAX_NUM_OF_CELL_ID] = {0,}; + uint8_t num_of_e_cell_id = 0; + uint32_t nr_cell_id[OGS_MAX_NUM_OF_CELL_ID] = {0,}; + uint8_t num_of_nr_cell_id = 0; if (ogs_yaml_iter_type(&pfcp_array) == YAML_MAPPING_NODE) { @@ -537,7 +523,8 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote) } while ( ogs_yaml_iter_type(&tac_iter) == YAML_SEQUENCE_NODE); - } else if (!strcmp(pfcp_key, "apn")) { + } else if (!strcmp(pfcp_key, "apn") || + !strcmp(pfcp_key, "dnn")) { ogs_yaml_iter_t apn_iter; ogs_yaml_iter_recurse(&pfcp_iter, &apn_iter); ogs_assert(ogs_yaml_iter_type(&apn_iter) != @@ -562,38 +549,62 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote) } while ( ogs_yaml_iter_type(&apn_iter) == YAML_SEQUENCE_NODE); - } else if (!strcmp(pfcp_key, "enb_id")) { - ogs_yaml_iter_t enb_id_iter; - ogs_yaml_iter_recurse(&pfcp_iter, &enb_id_iter); - ogs_assert(ogs_yaml_iter_type(&enb_id_iter) != - YAML_MAPPING_NODE); + } else if (!strcmp(pfcp_key, "e_cell_id")) { + ogs_yaml_iter_t e_cell_id_iter; + ogs_yaml_iter_recurse( + &pfcp_iter, &e_cell_id_iter); + ogs_assert(ogs_yaml_iter_type( + &e_cell_id_iter) != YAML_MAPPING_NODE); do { const char *v = NULL; - ogs_assert(num_of_enb_id <= + ogs_assert(num_of_e_cell_id <= OGS_MAX_NUM_OF_ENB_ID); - if (ogs_yaml_iter_type(&enb_id_iter) == + if (ogs_yaml_iter_type(&e_cell_id_iter) == YAML_SEQUENCE_NODE) { - if (!ogs_yaml_iter_next(&enb_id_iter)) + if (!ogs_yaml_iter_next( + &e_cell_id_iter)) break; } - v = ogs_yaml_iter_value(&enb_id_iter); + v = ogs_yaml_iter_value(&e_cell_id_iter); if (v) { - if (strncmp(v,"0x",2)) { - // integer enb_id - enb_id[num_of_enb_id] = atoi(v); - } else { - // hex enb_id - enb_id[num_of_enb_id] = strtol(v, NULL, 16); - } - num_of_enb_id++; + e_cell_id[num_of_e_cell_id] + = ogs_uint28_from_string((char*)v); + num_of_e_cell_id++; } } while ( - ogs_yaml_iter_type(&enb_id_iter) == + ogs_yaml_iter_type(&e_cell_id_iter) == + YAML_SEQUENCE_NODE); + } else if (!strcmp(pfcp_key, "nr_cell_id")) { + ogs_yaml_iter_t nr_cell_id_iter; + ogs_yaml_iter_recurse( + &pfcp_iter, &nr_cell_id_iter); + ogs_assert(ogs_yaml_iter_type( + &nr_cell_id_iter) != YAML_MAPPING_NODE); + + do { + const char *v = NULL; + + ogs_assert(num_of_nr_cell_id <= + OGS_MAX_NUM_OF_ENB_ID); + if (ogs_yaml_iter_type(&nr_cell_id_iter) == + YAML_SEQUENCE_NODE) { + if (!ogs_yaml_iter_next( + &nr_cell_id_iter)) + break; + } + + v = ogs_yaml_iter_value(&nr_cell_id_iter); + if (v) { + nr_cell_id[num_of_nr_cell_id] + = ogs_uint28_from_string((char*)v); + num_of_nr_cell_id++; + } + } while ( + ogs_yaml_iter_type(&nr_cell_id_iter) == YAML_SEQUENCE_NODE); - } else ogs_warn("unknown key `%s`", pfcp_key); } @@ -622,10 +633,15 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote) if (num_of_apn != 0) memcpy(node->apn, apn, sizeof(node->apn)); - node->num_of_enb_id = num_of_enb_id; - if (num_of_enb_id != 0) - memcpy(node->enb_id, enb_id, sizeof(node->enb_id)); + node->num_of_e_cell_id = num_of_e_cell_id; + if (num_of_e_cell_id != 0) + memcpy(node->e_cell_id, e_cell_id, + sizeof(node->e_cell_id)); + node->num_of_nr_cell_id = num_of_nr_cell_id; + if (num_of_nr_cell_id != 0) + memcpy(node->nr_cell_id, nr_cell_id, + sizeof(node->nr_cell_id)); } while (ogs_yaml_iter_type(&pfcp_array) == YAML_SEQUENCE_NODE); } diff --git a/lib/pfcp/context.h b/lib/pfcp/context.h index fad872886..75d46938f 100644 --- a/lib/pfcp/context.h +++ b/lib/pfcp/context.h @@ -33,13 +33,6 @@ extern "C" { typedef struct ogs_pfcp_node_s ogs_pfcp_node_t; -typedef enum { - UPF_SELECT_RR = 0, /* Default UPF Selection Method */ - UPF_SELECT_TAC, /* Select UPF by enb_tac */ - UPF_SELECT_APN, /* Select UPF by UE's APN */ - UPF_SELECT_ENB_ID, /* Select UPF by enb_id */ -} upf_select_e; - typedef struct ogs_pfcp_context_s { uint32_t pfcp_port; /* PFCP local port */ const char *tun_ifname; /* PFCP TUN Interface Name */ @@ -54,8 +47,7 @@ typedef struct ogs_pfcp_context_s { uint32_t pfcp_started; /* UTC time when the PFCP entity started */ ogs_list_t n4_list; /* PFCP Node List */ - upf_select_e upf_selection_mode; /* Selection algorithm for selecting UPF */ - ogs_pfcp_node_t *node; /* Iterator for Peer round-robin */ + ogs_pfcp_node_t *node; /* Iterator for Peer round-robin */ ogs_list_t dev_list; /* Tun Device List */ ogs_list_t subnet_list; /* UE Subnet List */ @@ -89,8 +81,10 @@ typedef struct ogs_pfcp_node_s { uint8_t num_of_tac; const char* apn[OGS_MAX_APN_LEN]; uint8_t num_of_apn; - uint32_t enb_id[OGS_MAX_NUM_OF_ENB_ID]; - uint8_t num_of_enb_id; + uint32_t e_cell_id[OGS_MAX_NUM_OF_CELL_ID]; + uint8_t num_of_e_cell_id; + uint32_t nr_cell_id[OGS_MAX_NUM_OF_CELL_ID]; + uint8_t num_of_nr_cell_id; ogs_list_t gtpu_resource_list; /* User Plane IP Resource Information */ } ogs_pfcp_node_t; diff --git a/lib/sbi/client.c b/lib/sbi/client.c index ce00c1789..24e428aa3 100644 --- a/lib/sbi/client.c +++ b/lib/sbi/client.c @@ -52,6 +52,7 @@ typedef struct connection_s { char error[CURL_ERROR_SIZE]; ogs_sbi_client_t *client; + ogs_sbi_client_cb_f client_cb; } connection_t; static OGS_POOL(client_pool, ogs_sbi_client_t); @@ -227,7 +228,8 @@ static char *add_params_to_uri(CURL *easy, char *uri, ogs_hash_t *params) return uri; } -static connection_t *connection_add(ogs_sbi_client_t *client, +static connection_t *connection_add( + ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb, ogs_sbi_request_t *request, void *data) { ogs_hash_index_t *hi; @@ -236,13 +238,18 @@ static connection_t *connection_add(ogs_sbi_client_t *client, CURLMcode rc; ogs_assert(client); + ogs_assert(client_cb); ogs_assert(request); + ogs_assert(request->h.method); ogs_pool_alloc(&connection_pool, &conn); ogs_assert(conn); memset(conn, 0, sizeof(connection_t)); - ogs_assert(request->h.method); + conn->client = client; + conn->client_cb = client_cb; + conn->data = data; + conn->method = ogs_strdup(request->h.method); conn->num_of_header = ogs_hash_count(request->http.headers); @@ -265,6 +272,8 @@ static connection_t *connection_add(ogs_sbi_client_t *client, ogs_sbi_self()->timer_mgr, connection_timer_expired, conn); ogs_assert(conn->timer); + ogs_list_add(&client->connection_list, conn); + /* If http response is not received within 1 second, * we will discard this request. */ ogs_timer_start(conn->timer, ogs_time_from_sec(1)); @@ -314,11 +323,6 @@ static connection_t *connection_add(ogs_sbi_client_t *client, rc = curl_multi_add_handle(client->multi, conn->easy); mcode_or_die("connection_add: curl_multi_add_handle", rc); - conn->client = client; - conn->data = data; - - ogs_list_add(&client->connection_list, conn); - return conn; } @@ -435,13 +439,8 @@ static void check_multi_info(ogs_sbi_client_t *client) ogs_sbi_header_set(response->http.headers, OGS_SBI_LOCATION, conn->location); - if (client->cb) - client->cb(response, conn->data); - else { - ogs_fatal("client callback is not registered"); - ogs_sbi_response_free(response); - ogs_assert_if_reached(); - } + ogs_assert(conn->client_cb); + conn->client_cb(response, conn->data); } else ogs_warn("[%d] %s", res, conn->error); @@ -455,7 +454,8 @@ static void check_multi_info(ogs_sbi_client_t *client) } void ogs_sbi_client_send_request( - ogs_sbi_client_t *client, ogs_sbi_request_t *request, void *data) + ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb, + ogs_sbi_request_t *request, void *data) { connection_t *conn = NULL; @@ -465,52 +465,12 @@ void ogs_sbi_client_send_request( if (request->h.uri == NULL) { request->h.uri = ogs_sbi_client_uri(client, &request->h); } + ogs_debug("[%s] %s", request->h.method, request->h.uri); - conn = connection_add(client, request, data); + conn = connection_add(client, client_cb, request, data); ogs_assert(conn); } -void ogs_sbi_client_send_request_to_nf_instance( - ogs_sbi_nf_instance_t *nf_instance, - ogs_sbi_request_t *request, void *data) -{ - ogs_sbi_client_t *client = NULL; - - ogs_assert(request); - ogs_assert(nf_instance); - - if (request->h.uri == NULL) { - client = ogs_sbi_client_find_by_service_name(nf_instance, - request->h.service.name, request->h.api.version); - if (!client) { - ogs_error("[%s] Cannot find client [%s:%s]", - nf_instance->id, - request->h.service.name, request->h.api.version); - return; - } - } else { - ogs_sockaddr_t *addr = NULL; - char buf[OGS_ADDRSTRLEN]; - - addr = ogs_sbi_getaddr_from_uri(request->h.uri); - if (!addr) { - ogs_error("[%s] Invalid confirmation URL [%s]", - nf_instance->id, request->h.uri); - return; - } - client = ogs_sbi_client_find(addr); - if (!client) { - ogs_error("[%s] Cannot find client [%s:%d]", nf_instance->id, - OGS_ADDR(addr, buf), OGS_PORT(addr)); - ogs_freeaddrinfo(addr); - return; - } - ogs_freeaddrinfo(addr); - } - - ogs_sbi_client_send_request(client, request, data); -} - static size_t write_cb(void *contents, size_t size, size_t nmemb, void *data) { size_t realsize = 0; diff --git a/lib/sbi/client.h b/lib/sbi/client.h index ee527775b..1a5728c25 100644 --- a/lib/sbi/client.h +++ b/lib/sbi/client.h @@ -36,6 +36,9 @@ extern "C" { __pCLIENT->reference_count++; \ (__cTX)->client = __pCLIENT; \ } while(0) + +typedef int (*ogs_sbi_client_cb_f)(ogs_sbi_response_t *response, void *data); + typedef struct ogs_sbi_client_s { ogs_lnode_t lnode; @@ -46,7 +49,7 @@ typedef struct ogs_sbi_client_s { const char *pem; } tls; - int (*cb)(ogs_sbi_response_t *response, void *data); + ogs_sbi_client_cb_f cb; /* Only used when NF send to NRF */ ogs_timer_t *t_curl; /* timer for CURL */ ogs_list_t connection_list; /* CURL connection list */ @@ -67,9 +70,7 @@ void ogs_sbi_client_remove(ogs_sbi_client_t *client); ogs_sbi_client_t *ogs_sbi_client_find(ogs_sockaddr_t *addr); void ogs_sbi_client_send_request( - ogs_sbi_client_t *client, ogs_sbi_request_t *request, void *data); -void ogs_sbi_client_send_request_to_nf_instance( - ogs_sbi_nf_instance_t *nf_instance, + ogs_sbi_client_t *client, ogs_sbi_client_cb_f client_cb, ogs_sbi_request_t *request, void *data); #ifdef __cplusplus diff --git a/lib/sbi/context.h b/lib/sbi/context.h index f80d3a6e1..5c33ac987 100644 --- a/lib/sbi/context.h +++ b/lib/sbi/context.h @@ -121,6 +121,8 @@ typedef struct ogs_sbi_object_s { ogs_sbi_session_t *session; void *nf_state_registered; + + ogs_sbi_client_cb_f client_cb; } ogs_sbi_object_t; typedef struct ogs_sbi_nf_service_s { diff --git a/lib/sbi/conv.c b/lib/sbi/conv.c index 578d6b9a6..c704a0e53 100644 --- a/lib/sbi/conv.c +++ b/lib/sbi/conv.c @@ -230,3 +230,303 @@ uint64_t ogs_sbi_bitrate_from_string(char *str) END return bitrate; } + +#define MAX_TIMESTR_LEN 128 + +char *ogs_sbi_localtime_string(ogs_time_t timestamp) +{ + struct tm tm; + + char datetime[MAX_TIMESTR_LEN]; + char timezone[MAX_TIMESTR_LEN]; + + ogs_localtime(ogs_time_sec(timestamp), &tm); + ogs_strftime(datetime, sizeof datetime, "%Y-%m-%dT%H:%M:%S", &tm); + ogs_strftime(timezone, sizeof timezone, "%z", &tm); + + return ogs_msprintf("%s.%06lld%s", + datetime, (long long)ogs_time_usec(timestamp), timezone); +} + +char *ogs_sbi_gmtime_string(ogs_time_t timestamp) +{ + struct tm tm; + + char datetime[MAX_TIMESTR_LEN]; + + ogs_gmtime(ogs_time_sec(timestamp), &tm); + ogs_strftime(datetime, sizeof datetime, "%Y-%m-%dT%H:%M:%S", &tm); + + return ogs_msprintf("%s.%06lldZ", + datetime, (long long)ogs_time_usec(timestamp)); +} + +char *ogs_sbi_timezone_string(int tm_gmtoff) +{ + struct tm tm; + + char timezone[MAX_TIMESTR_LEN]; + + memset(&tm, 0, sizeof(tm)); + tm.tm_gmtoff = tm_gmtoff; + ogs_strftime(timezone, sizeof timezone, "%z", &tm); + + return ogs_msprintf("%s", timezone); +} + +bool ogs_sbi_time_from_string(ogs_time_t *timestamp, char *str) +{ + int rv, i, j, k; + struct tm tm; + bool is_seconds; + char seconds[MAX_TIMESTR_LEN]; + char subsecs[MAX_TIMESTR_LEN]; + ogs_time_t usecs; + + ogs_assert(str); + ogs_assert(timestamp); + + memset(seconds, 0, sizeof seconds); + memset(subsecs, 0, sizeof subsecs); + + is_seconds = true; + i = 0; j = 0, k = 0; + while(str[i]) { + if (is_seconds == true && str[i] == '.') + is_seconds = false; + else if (is_seconds == false && (str[i] < '0' || str[i] > '9')) + is_seconds = true; + + if (is_seconds == true) seconds[j++] = str[i]; + else subsecs[k++] = str[i]; + + i++; + } + + memset(&tm, 0, sizeof(tm)); + ogs_strptime(seconds, "%Y-%m-%dT%H:%M:%S%z", &tm); + usecs = (ogs_time_t)(atof(subsecs) * 1000000); + + rv = ogs_time_from_gmt(timestamp, &tm, usecs); + if (rv != OGS_OK) { + ogs_error("Cannot convert time [%s]", str); + return false; + } + + return true; +} + +OpenAPI_plmn_id_t *ogs_sbi_build_plmn_id(ogs_plmn_id_t *plmn_id) +{ + OpenAPI_plmn_id_t *PlmnId = NULL; + + ogs_assert(plmn_id); + + PlmnId = ogs_calloc(1, sizeof(*PlmnId)); + ogs_assert(PlmnId); + + PlmnId->mcc = ogs_plmn_id_mcc_string(plmn_id); + ogs_assert(PlmnId->mcc); + PlmnId->mnc = ogs_plmn_id_mnc_string(plmn_id); + ogs_assert(PlmnId->mnc); + + return PlmnId; +} + +bool ogs_sbi_parse_plmn_id( + ogs_plmn_id_t *plmn_id, OpenAPI_plmn_id_t *PlmnId) +{ + ogs_assert(plmn_id); + ogs_assert(PlmnId); + ogs_assert(PlmnId->mcc); + ogs_assert(PlmnId->mnc); + + ogs_plmn_id_build(plmn_id, + atoi(PlmnId->mcc), atoi(PlmnId->mnc), strlen(PlmnId->mnc)); + + return true; +} + +void ogs_sbi_free_plmn_id(OpenAPI_plmn_id_t *PlmnId) +{ + ogs_assert(PlmnId); + + if (PlmnId->mcc) + ogs_free(PlmnId->mcc); + if (PlmnId->mnc) + ogs_free(PlmnId->mnc); + + ogs_free(PlmnId); +} + +OpenAPI_plmn_id_nid_t *ogs_sbi_build_plmn_id_nid(ogs_plmn_id_t *plmn_id) +{ + OpenAPI_plmn_id_nid_t *PlmnIdNid = NULL; + + ogs_assert(plmn_id); + + PlmnIdNid = ogs_calloc(1, sizeof(*PlmnIdNid)); + ogs_assert(PlmnIdNid); + + PlmnIdNid->mcc = ogs_plmn_id_mcc_string(plmn_id); + ogs_assert(PlmnIdNid->mcc); + PlmnIdNid->mnc = ogs_plmn_id_mnc_string(plmn_id); + ogs_assert(PlmnIdNid->mnc); + + return PlmnIdNid; +} + +bool ogs_sbi_parse_plmn_id_nid( + ogs_plmn_id_t *plmn_id, OpenAPI_plmn_id_nid_t *PlmnIdNid) +{ + ogs_assert(plmn_id); + ogs_assert(PlmnIdNid); + ogs_assert(PlmnIdNid->mcc); + ogs_assert(PlmnIdNid->mnc); + + ogs_plmn_id_build(plmn_id, + atoi(PlmnIdNid->mcc), atoi(PlmnIdNid->mnc), strlen(PlmnIdNid->mnc)); + + return true; +} + +void ogs_sbi_free_plmn_id_nid(OpenAPI_plmn_id_nid_t *PlmnIdNid) +{ + ogs_assert(PlmnIdNid); + + if (PlmnIdNid->mcc) + ogs_free(PlmnIdNid->mcc); + if (PlmnIdNid->mnc) + ogs_free(PlmnIdNid->mnc); + if (PlmnIdNid->nid) + ogs_free(PlmnIdNid->nid); + + ogs_free(PlmnIdNid); +} + +OpenAPI_guami_t *ogs_sbi_build_guami(ogs_guami_t *guami) +{ + OpenAPI_guami_t *Guami = NULL; + + ogs_assert(guami); + + Guami = ogs_calloc(1, sizeof(*Guami)); + ogs_assert(Guami); + + Guami->plmn_id = ogs_sbi_build_plmn_id(&guami->plmn_id); + ogs_assert(Guami->plmn_id); + Guami->amf_id = ogs_amf_id_to_string(&guami->amf_id); + ogs_assert(Guami->amf_id); + + return Guami; +} + +bool ogs_sbi_parse_guami(ogs_guami_t *guami, OpenAPI_guami_t *Guami) +{ + ogs_assert(guami); + ogs_assert(Guami); + ogs_assert(Guami->amf_id); + ogs_assert(Guami->plmn_id); + + ogs_amf_id_from_string(&guami->amf_id, Guami->amf_id); + ogs_sbi_parse_plmn_id(&guami->plmn_id, Guami->plmn_id); + + return true; +} + +void ogs_sbi_free_guami(OpenAPI_guami_t *Guami) +{ + ogs_assert(Guami); + + if (Guami->plmn_id) + ogs_sbi_free_plmn_id(Guami->plmn_id); + if (Guami->amf_id) + ogs_free(Guami->amf_id); + ogs_free(Guami); +} + +OpenAPI_nr_location_t *ogs_sbi_build_nr_location( + ogs_5gs_tai_t *tai, ogs_nr_cgi_t *nr_cgi) +{ + OpenAPI_nr_location_t *NrLocation = NULL; + OpenAPI_tai_t *Tai = NULL; + OpenAPI_ncgi_t *Ncgi = NULL; + + ogs_assert(tai); + ogs_assert(nr_cgi); + + 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); + + 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); + + NrLocation = ogs_calloc(1, sizeof(*NrLocation)); + ogs_assert(NrLocation); + NrLocation->tai = Tai; + NrLocation->ncgi = Ncgi; + + return NrLocation; +} + +bool ogs_sbi_parse_nr_location(ogs_5gs_tai_t *tai, ogs_nr_cgi_t *nr_cgi, + OpenAPI_nr_location_t *NrLocation) +{ + OpenAPI_tai_t *Tai = NULL; + OpenAPI_ncgi_t *Ncgi = NULL; + + ogs_assert(tai); + ogs_assert(nr_cgi); + ogs_assert(NrLocation); + + Tai = NrLocation->tai; + if (Tai) { + if (Tai->plmn_id) + ogs_sbi_parse_plmn_id(&tai->plmn_id, Tai->plmn_id); + if (Tai->tac) + tai->tac = ogs_uint24_from_string(Tai->tac); + } + + Ncgi = NrLocation->ncgi; + if (Ncgi) { + 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); + + } + + return true; +} + +void ogs_sbi_free_nr_location(OpenAPI_nr_location_t *NrLocation) +{ + OpenAPI_tai_t *Tai = NULL; + OpenAPI_ncgi_t *Ncgi = NULL; + + ogs_assert(NrLocation); + + Tai = NrLocation->tai; + if (Tai) { + if (Tai->plmn_id) + ogs_sbi_free_plmn_id(Tai->plmn_id); + if (Tai->tac) + ogs_free(Tai->tac); + ogs_free(Tai); + } + + Ncgi = NrLocation->ncgi; + if (Ncgi) { + if (Ncgi->plmn_id) + ogs_sbi_free_plmn_id(Ncgi->plmn_id); + if (Ncgi->nr_cell_id) + ogs_free(Ncgi->nr_cell_id); + ogs_free(Ncgi); + } + + ogs_free(NrLocation); +} diff --git a/lib/sbi/conv.h b/lib/sbi/conv.h index 909a74fe7..f730a2022 100644 --- a/lib/sbi/conv.h +++ b/lib/sbi/conv.h @@ -46,6 +46,31 @@ ogs_sockaddr_t *ogs_sbi_getaddr_from_uri(char *uri); char *ogs_sbi_bitrate_to_string(uint64_t bitrate, int unit); uint64_t ogs_sbi_bitrate_from_string(char *str); +char *ogs_sbi_localtime_string(ogs_time_t time); +char *ogs_sbi_gmtime_string(ogs_time_t time); +char *ogs_sbi_timezone_string(int tm_offset); +bool ogs_sbi_time_from_string(ogs_time_t *time, char *str); + +OpenAPI_plmn_id_t *ogs_sbi_build_plmn_id(ogs_plmn_id_t *plmn_id); +bool ogs_sbi_parse_plmn_id( + ogs_plmn_id_t *plmn_id, OpenAPI_plmn_id_t *PlmnId); +void ogs_sbi_free_plmn_id(OpenAPI_plmn_id_t *PlmnId); + +OpenAPI_plmn_id_nid_t *ogs_sbi_build_plmn_id_nid(ogs_plmn_id_t *plmn_id); +bool ogs_sbi_parse_plmn_id_nid( + ogs_plmn_id_t *plmn_id, OpenAPI_plmn_id_nid_t *PlmnIdNid); +void ogs_sbi_free_plmn_id_nid(OpenAPI_plmn_id_nid_t *PlmnIdNid); + +OpenAPI_guami_t *ogs_sbi_build_guami(ogs_guami_t *guami); +bool ogs_sbi_parse_guami(ogs_guami_t *guami, OpenAPI_guami_t *Guami); +void ogs_sbi_free_guami(OpenAPI_guami_t *Guami); + +OpenAPI_nr_location_t *ogs_sbi_build_nr_location( + ogs_5gs_tai_t *tai, ogs_nr_cgi_t *nr_cgi); +bool ogs_sbi_parse_nr_location(ogs_5gs_tai_t *tai, ogs_nr_cgi_t *nr_cgi, + OpenAPI_nr_location_t *NrLocation); +void ogs_sbi_free_nr_location(OpenAPI_nr_location_t *NrLocation); + #ifdef __cplusplus } #endif diff --git a/lib/sbi/meson.build b/lib/sbi/meson.build index de501606d..607bf254c 100644 --- a/lib/sbi/meson.build +++ b/lib/sbi/meson.build @@ -31,6 +31,7 @@ libsbi_sources = files(''' nnrf-build.c nnrf-handler.c + path.c '''.split()) diff --git a/lib/sbi/message.c b/lib/sbi/message.c index 417d93637..d66c18d24 100644 --- a/lib/sbi/message.c +++ b/lib/sbi/message.c @@ -524,6 +524,7 @@ int ogs_sbi_parse_header( message->h.method = header->method; message->h.uri = header->uri; ogs_assert(message->h.uri); + ogs_debug("[%s] %s", message->h.method, message->h.uri); uri = ogs_strdup(header->uri); ogs_assert(uri); @@ -721,6 +722,7 @@ static char *build_json(ogs_sbi_message_t *message) if (item) { content = cJSON_Print(item); ogs_assert(content); + ogs_log_print(OGS_LOG_TRACE, "%s", content); cJSON_Delete(item); } @@ -738,6 +740,7 @@ static int parse_json(ogs_sbi_message_t *message, if (!json) return OGS_OK; + ogs_log_print(OGS_LOG_TRACE, "%s", json); item = cJSON_Parse(json); if (!item) { ogs_error("JSON parse error"); diff --git a/lib/sbi/ogs-sbi.h b/lib/sbi/ogs-sbi.h index 31e7d2fec..339a943c7 100644 --- a/lib/sbi/ogs-sbi.h +++ b/lib/sbi/ogs-sbi.h @@ -77,6 +77,7 @@ #include "sbi/nnrf-build.h" #include "sbi/nnrf-handler.h" + #include "sbi/path.h" #undef OGS_SBI_INSIDE diff --git a/lib/sbi/path.c b/lib/sbi/path.c index 0e44d2eac..699a25b65 100644 --- a/lib/sbi/path.c +++ b/lib/sbi/path.c @@ -60,22 +60,52 @@ static ogs_sbi_nf_instance_t *find_or_discover_nf_instance( } void ogs_sbi_send( - ogs_sbi_object_t *sbi_object, ogs_sbi_nf_instance_t *nf_instance) + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_object_t *sbi_object) { ogs_sbi_request_t *request = NULL; + ogs_sbi_client_t *client = NULL; ogs_assert(sbi_object); request = sbi_object->request; ogs_assert(request); ogs_assert(sbi_object->client_wait.duration); + ogs_assert(sbi_object->client_cb); ogs_assert(nf_instance); + if (request->h.uri == NULL) { + client = ogs_sbi_client_find_by_service_name(nf_instance, + request->h.service.name, request->h.api.version); + if (!client) { + ogs_error("[%s] Cannot find client [%s:%s]", + nf_instance->id, + request->h.service.name, request->h.api.version); + return; + } + } else { + ogs_sockaddr_t *addr = NULL; + char buf[OGS_ADDRSTRLEN]; + + addr = ogs_sbi_getaddr_from_uri(request->h.uri); + if (!addr) { + ogs_error("[%s] Invalid URL [%s]", nf_instance->id, request->h.uri); + return; + } + client = ogs_sbi_client_find(addr); + if (!client) { + ogs_error("[%s] Cannot find client [%s:%d]", nf_instance->id, + OGS_ADDR(addr, buf), OGS_PORT(addr)); + ogs_freeaddrinfo(addr); + return; + } + ogs_freeaddrinfo(addr); + } + ogs_timer_start(sbi_object->client_wait.timer, sbi_object->client_wait.duration); - ogs_sbi_client_send_request_to_nf_instance( - nf_instance, sbi_object->request, sbi_object); + ogs_sbi_client_send_request( + client, sbi_object->client_cb, request, sbi_object); } bool ogs_sbi_discover_and_send( @@ -102,7 +132,7 @@ bool ogs_sbi_discover_and_send( if (nrf == false && nf == false) return false; if (!nf_instance) return true; - ogs_sbi_send(sbi_object, nf_instance); + ogs_sbi_send(nf_instance, sbi_object); return true; } @@ -118,7 +148,7 @@ void ogs_nnrf_nfm_send_nf_register(ogs_sbi_nf_instance_t *nf_instance) request = ogs_nnrf_nfm_build_register(nf_instance); ogs_assert(request); - ogs_sbi_client_send_request(client, request, nf_instance); + ogs_sbi_client_send_request(client, client->cb, request, nf_instance); ogs_sbi_request_free(request); } @@ -133,7 +163,7 @@ void ogs_nnrf_nfm_send_nf_update(ogs_sbi_nf_instance_t *nf_instance) request = ogs_nnrf_nfm_build_update(nf_instance); ogs_assert(request); - ogs_sbi_client_send_request(client, request, nf_instance); + ogs_sbi_client_send_request(client, client->cb, request, nf_instance); ogs_sbi_request_free(request); } @@ -148,7 +178,7 @@ void ogs_nnrf_nfm_send_nf_de_register(ogs_sbi_nf_instance_t *nf_instance) request = ogs_nnrf_nfm_build_de_register(nf_instance); ogs_assert(request); - ogs_sbi_client_send_request(client, request, nf_instance); + ogs_sbi_client_send_request(client, client->cb, request, nf_instance); ogs_sbi_request_free(request); } @@ -170,7 +200,7 @@ void ogs_nnrf_nfm_send_nf_status_subscribe(ogs_sbi_client_t *client, request = ogs_nnrf_nfm_build_status_subscribe(subscription); ogs_assert(request); - ogs_sbi_client_send_request(client, request, subscription); + ogs_sbi_client_send_request(client, client->cb, request, subscription); ogs_sbi_request_free(request); } @@ -186,7 +216,7 @@ void ogs_nnrf_nfm_send_nf_status_unsubscribe( request = ogs_nnrf_nfm_build_status_unsubscribe(subscription); ogs_assert(request); - ogs_sbi_client_send_request(client, request, subscription); + ogs_sbi_client_send_request(client, client->cb, request, subscription); ogs_sbi_request_free(request); } @@ -204,6 +234,6 @@ void ogs_nnrf_disc_send_nf_discover(ogs_sbi_nf_instance_t *nf_instance, request = ogs_nnrf_disc_build_discover( target_nf_type, nf_instance->nf_type); ogs_assert(request); - ogs_sbi_client_send_request(client, request, data); + ogs_sbi_client_send_request(client, client->cb, request, data); ogs_sbi_request_free(request); } diff --git a/lib/sbi/path.h b/lib/sbi/path.h index 0886f4b29..f15cfe832 100644 --- a/lib/sbi/path.h +++ b/lib/sbi/path.h @@ -30,7 +30,7 @@ typedef ogs_sbi_request_t *(*ogs_sbi_build_f)( ogs_sbi_object_t *sbi_object, void *data); void ogs_sbi_send( - ogs_sbi_object_t *sbi_object, ogs_sbi_nf_instance_t *nf_instance); + ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_object_t *sbi_object); bool ogs_sbi_discover_and_send( OpenAPI_nf_type_e nf_type, ogs_sbi_object_t *sbi_object, void *data, ogs_sbi_build_f build); diff --git a/src/amf/context.h b/src/amf/context.h index 481437b3c..8d6de8c5f 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -46,11 +46,6 @@ typedef struct amf_ue_s amf_ue_t; typedef uint32_t amf_m_tmsi_t; -typedef struct amf_guami_s { - ogs_plmn_id_t plmn_id; - ogs_amf_id_t amf_id; -} amf_guami_t; - typedef struct amf_context_s { ogs_queue_t *queue; /* Queue for processing UPF control */ ogs_timer_mgr_t *timer_mgr; /* Timer Manager */ @@ -60,7 +55,7 @@ typedef struct amf_context_s { /* Served GUAMI */ uint8_t num_of_served_guami; - amf_guami_t served_guami[MAX_NUM_OF_SERVED_GUAMI]; + ogs_guami_t served_guami[MAX_NUM_OF_SERVED_GUAMI]; /* Served TAI */ uint8_t num_of_served_tai; @@ -265,9 +260,10 @@ struct amf_ue_s { int guti_present; /* UE Info */ - amf_guami_t *guami; + ogs_guami_t *guami; ogs_5gs_tai_t tai; ogs_nr_cgi_t nr_cgi; + ogs_time_t ue_location_timestamp; ogs_plmn_id_t last_visited_plmn_id; ogs_nas_ue_usage_setting_t ue_usage_setting; diff --git a/src/amf/gmm-build.c b/src/amf/gmm-build.c index cb54e34bd..8870e041a 100644 --- a/src/amf/gmm-build.c +++ b/src/amf/gmm-build.c @@ -463,14 +463,14 @@ ogs_pkbuf_t *gmm_build_configuration_update_command(amf_ue_t *amf_ue, int red) ogs_gmtime(tv.tv_sec, &gmt); ogs_localtime(tv.tv_sec, &local); - ogs_debug(" GMT Time[Y:M:D H:M:S GMT] - %d:%d:%d, %d:%d:%d, %d", + ogs_debug(" GMT Time[Y:M:D H:M:S GMT:DST] - %d:%d:%d, %d:%d:%d, %d:%d", gmt.tm_year, gmt.tm_mon, gmt.tm_mday, gmt.tm_hour, gmt.tm_min, gmt.tm_sec, - (int)gmt.tm_gmtoff); - ogs_debug(" LOCAL Time[Y:M:D H:M:S GMT] - %d:%d:%d, %d:%d:%d, %d", + (int)gmt.tm_gmtoff, gmt.tm_isdst); + ogs_debug(" LOCAL Time[Y:M:D H:M:S GMT:DST] - %d:%d:%d, %d:%d:%d, %d:%d", local.tm_year, local.tm_mon, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec, - (int)local.tm_gmtoff); + (int)local.tm_gmtoff, local.tm_isdst); memset(&message, 0, sizeof(message)); message.h.security_header_type = @@ -491,23 +491,23 @@ ogs_pkbuf_t *gmm_build_configuration_update_command(amf_ue_t *amf_ue, int red) configuration_update_command->presencemask |= OGS_NAS_5GS_CONFIGURATION_UPDATE_COMMAND_UNIVERSAL_TIME_AND_LOCAL_TIME_ZONE_PRESENT; universal_time_and_local_time_zone->year = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_year % 100); + OGS_NAS_TIME_TO_BCD(gmt.tm_year % 100); universal_time_and_local_time_zone->mon = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_mon+1); + OGS_NAS_TIME_TO_BCD(gmt.tm_mon+1); universal_time_and_local_time_zone->mday = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_mday); + OGS_NAS_TIME_TO_BCD(gmt.tm_mday); universal_time_and_local_time_zone->hour = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_hour); + OGS_NAS_TIME_TO_BCD(gmt.tm_hour); universal_time_and_local_time_zone->min = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_min); + OGS_NAS_TIME_TO_BCD(gmt.tm_min); universal_time_and_local_time_zone->sec = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_sec); + OGS_NAS_TIME_TO_BCD(gmt.tm_sec); if (local.tm_gmtoff >= 0) { universal_time_and_local_time_zone->timezone = - OGS_OGS_NAS_TIME_TO_BCD(local.tm_gmtoff / 900); + OGS_NAS_TIME_TO_BCD(local.tm_gmtoff / 900); } else { universal_time_and_local_time_zone->timezone = - OGS_OGS_NAS_TIME_TO_BCD((-local.tm_gmtoff) / 900); + OGS_NAS_TIME_TO_BCD((-local.tm_gmtoff) / 900); universal_time_and_local_time_zone->timezone |= 0x08; } ogs_debug(" Timezone:0x%x", diff --git a/src/amf/gmm-handler.c b/src/amf/gmm-handler.c index 787a99cd4..a0b493340 100644 --- a/src/amf/gmm-handler.c +++ b/src/amf/gmm-handler.c @@ -140,6 +140,7 @@ int gmm_handle_registration_request(amf_ue_t *amf_ue, /* Copy TAI and ECGI from ran_ue */ memcpy(&amf_ue->tai, &ran_ue->saved.tai, sizeof(ogs_5gs_tai_t)); memcpy(&amf_ue->nr_cgi, &ran_ue->saved.nr_cgi, sizeof(ogs_nr_cgi_t)); + amf_ue->ue_location_timestamp = ogs_time_now(); /* Check TAI */ served_tai_index = amf_find_served_tai(&amf_ue->tai); @@ -317,9 +318,14 @@ int gmm_handle_registration_update(amf_ue_t *amf_ue, int gmm_handle_service_request(amf_ue_t *amf_ue, ogs_nas_5gs_service_request_t *service_request) { + int served_tai_index = 0; + + ran_ue_t *ran_ue = NULL; ogs_nas_key_set_identifier_t *ngksi = NULL; ogs_assert(amf_ue); + ran_ue = amf_ue->ran_ue; + ogs_assert(ran_ue); ngksi = &service_request->ngksi; ogs_assert(ngksi); @@ -357,6 +363,35 @@ int gmm_handle_service_request(amf_ue_t *amf_ue, amf_ue->nhcc = 1; } + ogs_debug(" OLD TAI[PLMN_ID:%06x,TAC:%d]", + ogs_plmn_id_hexdump(&amf_ue->tai.plmn_id), amf_ue->tai.tac.v); + ogs_debug(" OLD NR_CGI[PLMN_ID:%06x,CELL_ID:0x%llx]", + ogs_plmn_id_hexdump(&amf_ue->nr_cgi.plmn_id), + (long long)amf_ue->nr_cgi.cell_id); + ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]", + ogs_plmn_id_hexdump(&ran_ue->saved.tai.plmn_id), + ran_ue->saved.tai.tac.v); + ogs_debug(" NR_CGI[PLMN_ID:%06x,CELL_ID:0x%llx]", + ogs_plmn_id_hexdump(&ran_ue->saved.nr_cgi.plmn_id), + (long long)ran_ue->saved.nr_cgi.cell_id); + + /* Copy TAI and ECGI from ran_ue */ + memcpy(&amf_ue->tai, &ran_ue->saved.tai, sizeof(ogs_5gs_tai_t)); + memcpy(&amf_ue->nr_cgi, &ran_ue->saved.nr_cgi, sizeof(ogs_nr_cgi_t)); + amf_ue->ue_location_timestamp = ogs_time_now(); + + /* Check TAI */ + served_tai_index = amf_find_served_tai(&amf_ue->tai); + if (served_tai_index < 0) { + /* Send Registration Reject */ + ogs_warn("Cannot find Served TAI[PLMN_ID:%06x,TAC:%d]", + ogs_plmn_id_hexdump(&amf_ue->tai.plmn_id), amf_ue->tai.tac.v); + nas_5gs_send_registration_reject(amf_ue, + OGS_5GMM_CAUSE_TRACKING_AREA_NOT_ALLOWED); + return OGS_ERROR; + } + ogs_debug(" SERVED_TAI_INDEX[%d]", served_tai_index); + ogs_debug("[%s] 5G-S_GUTI[AMF_ID:0x%x,M_TMSI:0x%x]", AMF_UE_HAVE_SUCI(amf_ue) ? amf_ue->suci : "Unknown ID", ogs_amf_id_hexdump(&amf_ue->guti.amf_id), amf_ue->guti.m_tmsi); @@ -917,6 +952,12 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue, memset(¶m, 0, sizeof(param)); param.n1smbuf = sess->payload_container; + if (gsm_header->message_type == + OGS_NAS_5GS_PDU_SESSION_RELEASE_COMPLETE) { + param.ue_location = true; + param.ue_timezone = true; + } + amf_sess_sbi_discover_and_send( OpenAPI_nf_type_SMF, sess, ¶m, amf_nsmf_pdu_session_build_update_sm_context); diff --git a/src/amf/nnrf-handler.c b/src/amf/nnrf-handler.c index c72b7029a..2f478b500 100644 --- a/src/amf/nnrf-handler.c +++ b/src/amf/nnrf-handler.c @@ -68,39 +68,24 @@ void amf_nnrf_handle_nf_status_subscribe( subscription, SubscriptionData->subscription_id); if (SubscriptionData->validity_time) { - struct timeval tv; - struct tm local, next; - ogs_time_t diff, duration; - - memset(&next, 0, sizeof(next)); - if (ogs_strptime(SubscriptionData->validity_time, - OGS_TIME_ISO8601_FORMAT, &next)) { - ogs_gettimeofday(&tv); - ogs_localtime(tv.tv_sec, &local); - diff = ogs_mktime(&next) - ogs_mktime(&local); -#define VALIDITY_MARGIN 5 /* 5 seconds */ -#define VALIDITY_MINIMUM 60 /* 60 seconds */ - duration = diff - (int)VALIDITY_MARGIN; - - if (duration < (int)VALIDITY_MINIMUM) { - char buf[64]; - strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", &local); - ogs_warn("[%s] Validation period [%lld seconds, " - "(%lld)(%lld)(%s)(%s)] is too small", subscription->id, - (long long)diff, - (long long)ogs_mktime(&next), - (long long)ogs_mktime(&local), - SubscriptionData->validity_time, buf); +#define VALIDITY_MARGIN (5 * OGS_USEC_PER_SEC) /* 5 seconds */ +#define VALIDITY_MINIMUM (3600 * OGS_USEC_PER_SEC) /* 3600 seconds */ + ogs_time_t time, duration; + if (ogs_sbi_time_from_string( + &time, SubscriptionData->validity_time) == true) { + duration = time - ogs_time_now() - VALIDITY_MARGIN; + if (duration < VALIDITY_MINIMUM) { duration = VALIDITY_MINIMUM; ogs_warn("[%s] Forced to %d seconds", - subscription->id, VALIDITY_MINIMUM); + subscription->id, (int)ogs_time_sec(VALIDITY_MINIMUM)); } - subscription->t_validity = ogs_timer_add(amf_self()->timer_mgr, amf_timer_subscription_validity, subscription); ogs_assert(subscription->t_validity); - ogs_timer_start( - subscription->t_validity, ogs_time_from_sec(duration)); + ogs_timer_start(subscription->t_validity, duration); + } else { + ogs_error("Cannot parse validitiyTime [%s]", + SubscriptionData->validity_time); } } } @@ -194,8 +179,6 @@ bool amf_nnrf_handle_nf_status_notify( return false; } - amf_sbi_setup_client_callback(nf_instance); - } else if (NotificationData->event == OpenAPI_notification_event_type_NF_DEREGISTERED) { nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); @@ -287,8 +270,6 @@ void amf_nnrf_handle_nf_discover( continue; } - amf_sbi_setup_client_callback(nf_instance); - if (!OGS_SBI_NF_INSTANCE_GET( sbi_object->nf_types, nf_instance->nf_type)) ogs_sbi_nf_types_associate(sbi_object->nf_types, @@ -343,6 +324,6 @@ void amf_nnrf_handle_nf_discover( OpenAPI_nf_type_ToString(sbi_object->nf_type)); } } else { - ogs_sbi_send(sbi_object, nf_instance); + ogs_sbi_send(nf_instance, sbi_object); } } diff --git a/src/amf/nsmf-build.c b/src/amf/nsmf-build.c index 92f7ff852..6943fd572 100644 --- a/src/amf/nsmf-build.c +++ b/src/amf/nsmf-build.c @@ -28,15 +28,13 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context( ogs_sbi_server_t *server = NULL; ogs_sbi_header_t header; - char buf[OGS_AMFIDSTRLEN]; amf_ue_t *amf_ue = NULL; OpenAPI_sm_context_create_data_t SmContextCreateData; - OpenAPI_plmn_id_nid_t plmn_id_nid; - OpenAPI_snssai_t s_nssai; - OpenAPI_snssai_t hplmn_snssai; + OpenAPI_snssai_t sNssai; + OpenAPI_snssai_t hplmnSnssai; OpenAPI_ref_to_binary_data_t n1SmMsg; - OpenAPI_guami_t guami; + OpenAPI_user_location_t ueLocation; ogs_assert(sess); amf_ue = sess->amf_ue; @@ -54,10 +52,8 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context( SmContextCreateData.serving_nf_id = ogs_sbi_self()->nf_instance_id; - plmn_id_nid.mcc = ogs_plmn_id_mcc_string(&amf_ue->tai.plmn_id); - plmn_id_nid.mnc = ogs_plmn_id_mnc_string(&amf_ue->tai.plmn_id); - plmn_id_nid.nid = NULL; - SmContextCreateData.serving_network = &plmn_id_nid; + SmContextCreateData.serving_network = + ogs_sbi_build_plmn_id_nid(&amf_ue->tai.plmn_id); SmContextCreateData.supi = amf_ue->supi; SmContextCreateData.pei = amf_ue->pei; @@ -70,24 +66,20 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context( SmContextCreateData.pdu_session_id = sess->psi; SmContextCreateData.dnn = sess->dnn; - memset(&s_nssai, 0, sizeof(s_nssai)); - s_nssai.sst = sess->s_nssai.sst; - s_nssai.sd = ogs_s_nssai_sd_to_string(sess->s_nssai.sd); - SmContextCreateData.s_nssai = &s_nssai; + memset(&sNssai, 0, sizeof(sNssai)); + sNssai.sst = sess->s_nssai.sst; + sNssai.sd = ogs_s_nssai_sd_to_string(sess->s_nssai.sd); + SmContextCreateData.s_nssai = &sNssai; - memset(&hplmn_snssai, 0, sizeof(hplmn_snssai)); + memset(&hplmnSnssai, 0, sizeof(hplmnSnssai)); if (sess->s_nssai.mapped_hplmn_sst) { - hplmn_snssai.sst = sess->s_nssai.mapped_hplmn_sst; - hplmn_snssai.sd = ogs_s_nssai_sd_to_string( + hplmnSnssai.sst = sess->s_nssai.mapped_hplmn_sst; + hplmnSnssai.sd = ogs_s_nssai_sd_to_string( sess->s_nssai.mapped_hplmn_sd); - SmContextCreateData.hplmn_snssai = &hplmn_snssai; + SmContextCreateData.hplmn_snssai = &hplmnSnssai; } - ogs_assert(amf_ue->guami); - guami.amf_id = ogs_amf_id_to_string(&amf_ue->guami->amf_id, buf); - guami.plmn_id = (OpenAPI_plmn_id_t *)&plmn_id_nid; - SmContextCreateData.guami = &guami; - + SmContextCreateData.guami = ogs_sbi_build_guami(amf_ue->guami); SmContextCreateData.an_type = amf_ue->nas.access_type; memset(&header, 0, sizeof(header)); @@ -106,6 +98,16 @@ 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; + memset(&ueLocation, 0, sizeof(ueLocation)); + ueLocation.nr_location = ogs_sbi_build_nr_location( + &amf_ue->tai, &amf_ue->nr_cgi); + ogs_assert(ueLocation.nr_location); + ueLocation.nr_location->ue_location_timestamp = + ogs_sbi_gmtime_string(amf_ue->ue_location_timestamp); + + SmContextCreateData.ue_location = &ueLocation; + SmContextCreateData.ue_time_zone = ogs_sbi_timezone_string(ogs_timezone()); + message.SmContextCreateData = &SmContextCreateData; message.part[message.num_of_part].pkbuf = sess->payload_container; @@ -123,16 +125,25 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context( request = ogs_sbi_build_request(&message); ogs_assert(request); - ogs_free(plmn_id_nid.mcc); - ogs_free(plmn_id_nid.mnc); + if (SmContextCreateData.serving_network) + ogs_sbi_free_plmn_id_nid(SmContextCreateData.serving_network); ogs_free(SmContextCreateData.sm_context_status_uri); ogs_free(header.resource.component[2]); - if (s_nssai.sd) - ogs_free(s_nssai.sd); - if (hplmn_snssai.sd) - ogs_free(hplmn_snssai.sd); + if (sNssai.sd) + ogs_free(sNssai.sd); + if (hplmnSnssai.sd) + ogs_free(hplmnSnssai.sd); + if (SmContextCreateData.guami) + ogs_sbi_free_guami(SmContextCreateData.guami); if (SmContextCreateData.gpsi) ogs_free(SmContextCreateData.gpsi); + if (ueLocation.nr_location) { + if (ueLocation.nr_location->ue_location_timestamp) + ogs_free(ueLocation.nr_location->ue_location_timestamp); + ogs_sbi_free_nr_location(ueLocation.nr_location); + } + if (SmContextCreateData.ue_time_zone) + ogs_free(SmContextCreateData.ue_time_zone); return request; } @@ -148,10 +159,15 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_update_sm_context( OpenAPI_ref_to_binary_data_t n1SmMsg; OpenAPI_ref_to_binary_data_t n2SmInfo; OpenAPI_ng_ap_cause_t ngApCause; + OpenAPI_user_location_t ueLocation; + + amf_ue_t *amf_ue = NULL; ogs_assert(param); ogs_assert(sess); ogs_assert(sess->sm_context_ref); + amf_ue = sess->amf_ue; + ogs_assert(amf_ue); memset(&message, 0, sizeof(message)); message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST; @@ -211,9 +227,32 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_update_sm_context( message.SmContextUpdateData = &SmContextUpdateData; } + memset(&ueLocation, 0, sizeof(ueLocation)); + if (param->ue_location) { + ueLocation.nr_location = ogs_sbi_build_nr_location( + &amf_ue->tai, &amf_ue->nr_cgi); + ogs_assert(ueLocation.nr_location); + ueLocation.nr_location->ue_location_timestamp = + ogs_sbi_gmtime_string(amf_ue->ue_location_timestamp); + + SmContextUpdateData.ue_location = &ueLocation; + } + if (param->ue_timezone) { + SmContextUpdateData.ue_time_zone = + ogs_sbi_timezone_string(ogs_timezone()); + } + request = ogs_sbi_build_request(&message); ogs_assert(request); + if (ueLocation.nr_location) { + if (ueLocation.nr_location->ue_location_timestamp) + ogs_free(ueLocation.nr_location->ue_location_timestamp); + ogs_sbi_free_nr_location(ueLocation.nr_location); + } + if (SmContextUpdateData.ue_time_zone) + ogs_free(SmContextUpdateData.ue_time_zone); + return request; } @@ -223,8 +262,15 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_release_sm_context( ogs_sbi_message_t message; ogs_sbi_request_t *request = NULL; + amf_ue_t *amf_ue = NULL; + + OpenAPI_sm_context_release_data_t SmContextReleaseData; + OpenAPI_user_location_t ueLocation; + ogs_assert(sess); ogs_assert(sess->sm_context_ref); + amf_ue = sess->amf_ue; + ogs_assert(amf_ue); memset(&message, 0, sizeof(message)); message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST; @@ -235,8 +281,30 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_release_sm_context( message.h.resource.component[1] = sess->sm_context_ref; message.h.resource.component[2] = (char *)OGS_SBI_RESOURCE_NAME_RELEASE; + memset(&SmContextReleaseData, 0, sizeof(SmContextReleaseData)); + + memset(&ueLocation, 0, sizeof(ueLocation)); + ueLocation.nr_location = ogs_sbi_build_nr_location( + &amf_ue->tai, &amf_ue->nr_cgi); + ogs_assert(ueLocation.nr_location); + ueLocation.nr_location->ue_location_timestamp = + ogs_sbi_gmtime_string(amf_ue->ue_location_timestamp); + + SmContextReleaseData.ue_location = &ueLocation; + SmContextReleaseData.ue_time_zone = ogs_sbi_timezone_string(ogs_timezone()); + + message.SmContextReleaseData = &SmContextReleaseData; + request = ogs_sbi_build_request(&message); ogs_assert(request); + if (ueLocation.nr_location) { + if (ueLocation.nr_location->ue_location_timestamp) + ogs_free(ueLocation.nr_location->ue_location_timestamp); + ogs_sbi_free_nr_location(ueLocation.nr_location); + } + if (SmContextReleaseData.ue_time_zone) + ogs_free(SmContextReleaseData.ue_time_zone); + return request; } diff --git a/src/amf/nsmf-build.h b/src/amf/nsmf-build.h index 4e5c6619f..bcc1ae69c 100644 --- a/src/amf/nsmf-build.h +++ b/src/amf/nsmf-build.h @@ -35,6 +35,14 @@ typedef struct amf_nsmf_pdu_session_update_sm_context_param_s { int group; int value; } ngApCause; + union { + struct { + ED3(uint8_t ue_location:1;, + uint8_t ue_timezone:1;, + uint8_t spare:6;) + }; + uint8_t indications; + }; } amf_nsmf_pdu_session_update_sm_context_param_t; ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context( diff --git a/src/amf/nudm-build.c b/src/amf/nudm-build.c index 42183cf9d..2025ebaee 100644 --- a/src/amf/nudm-build.c +++ b/src/amf/nudm-build.c @@ -27,11 +27,7 @@ ogs_sbi_request_t *amf_nudm_uecm_build_registration( ogs_sbi_request_t *request = NULL; ogs_sbi_server_t *server = NULL; - char buf[OGS_AMFIDSTRLEN]; - OpenAPI_amf3_gpp_access_registration_t Amf3GppAccessRegistration; - OpenAPI_plmn_id_t plmn_id; - OpenAPI_guami_t guami; ogs_assert(amf_ue); ogs_assert(amf_ue->supi); @@ -63,14 +59,7 @@ ogs_sbi_request_t *amf_nudm_uecm_build_registration( ogs_sbi_server_uri(server, &header); ogs_assert(Amf3GppAccessRegistration.dereg_callback_uri); - plmn_id.mcc = ogs_plmn_id_mcc_string(&amf_ue->tai.plmn_id); - plmn_id.mnc = ogs_plmn_id_mnc_string(&amf_ue->tai.plmn_id); - - ogs_assert(amf_ue->guami); - guami.amf_id = ogs_amf_id_to_string(&amf_ue->guami->amf_id, buf); - guami.plmn_id = &plmn_id; - Amf3GppAccessRegistration.guami = &guami; - + Amf3GppAccessRegistration.guami = ogs_sbi_build_guami(amf_ue->guami); Amf3GppAccessRegistration.rat_type = OpenAPI_rat_type_NR; message.Amf3GppAccessRegistration = &Amf3GppAccessRegistration; @@ -78,8 +67,8 @@ ogs_sbi_request_t *amf_nudm_uecm_build_registration( request = ogs_sbi_build_request(&message); ogs_assert(request); - ogs_free(plmn_id.mcc); - ogs_free(plmn_id.mnc); + if (Amf3GppAccessRegistration.guami) + ogs_sbi_free_guami(Amf3GppAccessRegistration.guami); ogs_free(Amf3GppAccessRegistration.dereg_callback_uri); return request; diff --git a/src/amf/sbi-path.c b/src/amf/sbi-path.c index 3dbd086e8..1ad8c80a1 100644 --- a/src/amf/sbi-path.c +++ b/src/amf/sbi-path.c @@ -76,19 +76,36 @@ int amf_sbi_open(void) ogs_sbi_server_start_all(server_cb); + /* + * The connection between NF and NRF is a little special. + * + * NF and NRF share nf_instance. I get the NRF EndPoint(client) information + * the configuration file via lib/sbi/context.c. + * + * ogs_sbi_self()->nf_instance_id means NF's InstanceId. + */ ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) { ogs_sbi_nf_service_t *service = NULL; + ogs_sbi_client_t *client = NULL; + /* Build NF instance information. It will be transmitted to NRF. */ ogs_sbi_nf_instance_build_default(nf_instance, amf_self()->nf_type); + /* Build NF service information. It will be transmitted to NRF. */ service = ogs_sbi_nf_service_build_default(nf_instance, (char*)OGS_SBI_SERVICE_NAME_NAMF_COMM); ogs_assert(service); ogs_sbi_nf_service_add_version(service, (char*)OGS_SBI_API_V1, (char*)OGS_SBI_API_V1_0_0, NULL); + /* Client callback is only used when NF sends to NRF */ + client = nf_instance->client; + ogs_assert(client); + client->cb = client_cb; + + /* NFRegister is sent and the response is received + * by the above client callback. */ amf_nf_fsm_init(nf_instance); - amf_sbi_setup_client_callback(nf_instance); } return OGS_OK; @@ -99,24 +116,6 @@ void amf_sbi_close(void) ogs_sbi_server_stop_all(); } -void amf_sbi_setup_client_callback(ogs_sbi_nf_instance_t *nf_instance) -{ - ogs_sbi_client_t *client = NULL; - ogs_sbi_nf_service_t *nf_service = NULL; - ogs_assert(nf_instance); - - client = nf_instance->client; - ogs_assert(client); - - client->cb = client_cb; - - ogs_list_for_each(&nf_instance->nf_service_list, nf_service) { - client = nf_service->client; - if (client) - client->cb = client_cb; - } -} - void amf_ue_sbi_discover_and_send( OpenAPI_nf_type_e nf_type, amf_ue_t *amf_ue, void *data, ogs_sbi_request_t *(*build)(amf_ue_t *amf_ue, void *data)) @@ -127,6 +126,7 @@ void amf_ue_sbi_discover_and_send( amf_ue->sbi.nf_state_registered = amf_nf_state_registered; amf_ue->sbi.client_wait.duration = amf_timer_cfg(AMF_TIMER_SBI_CLIENT_WAIT)->duration; + amf_ue->sbi.client_cb = client_cb; if (ogs_sbi_discover_and_send( nf_type, &amf_ue->sbi, data, (ogs_sbi_build_f)build) != true) { @@ -146,6 +146,7 @@ void amf_sess_sbi_discover_and_send( sess->sbi.nf_state_registered = amf_nf_state_registered; sess->sbi.client_wait.duration = amf_timer_cfg(AMF_TIMER_SBI_CLIENT_WAIT)->duration; + sess->sbi.client_cb = client_cb; if (ogs_sbi_discover_and_send( nf_type, &sess->sbi, data, (ogs_sbi_build_f)build) != true) { @@ -184,6 +185,8 @@ void amf_sbi_send_deactivate_session( param.upCnxState = sess->ueUpCnxState; param.ngApCause.group = group; param.ngApCause.value = cause; + param.ue_location = true; + param.ue_timezone = true; amf_sess_sbi_discover_and_send( OpenAPI_nf_type_SMF, sess, ¶m, amf_nsmf_pdu_session_build_update_sm_context); diff --git a/src/amf/sbi-path.h b/src/amf/sbi-path.h index 2b689bc90..0fb28e9bd 100644 --- a/src/amf/sbi-path.h +++ b/src/amf/sbi-path.h @@ -31,8 +31,6 @@ extern "C" { int amf_sbi_open(void); void amf_sbi_close(void); -void amf_sbi_setup_client_callback(ogs_sbi_nf_instance_t *nf_instance); - void amf_ue_sbi_discover_and_send( OpenAPI_nf_type_e nf_type, amf_ue_t *amf_ue, void *data, ogs_sbi_request_t *(*build)(amf_ue_t *amf_ue, void *data)); diff --git a/src/ausf/nnrf-handler.c b/src/ausf/nnrf-handler.c index cf543b941..afe779526 100644 --- a/src/ausf/nnrf-handler.c +++ b/src/ausf/nnrf-handler.c @@ -66,39 +66,24 @@ void ausf_nnrf_handle_nf_status_subscribe( subscription, SubscriptionData->subscription_id); if (SubscriptionData->validity_time) { - struct timeval tv; - struct tm local, next; - ogs_time_t diff, duration; - - memset(&next, 0, sizeof(next)); - if (ogs_strptime(SubscriptionData->validity_time, - OGS_TIME_ISO8601_FORMAT, &next)) { - ogs_gettimeofday(&tv); - ogs_localtime(tv.tv_sec, &local); - diff = ogs_mktime(&next) - ogs_mktime(&local); -#define VALIDITY_MARGIN 5 /* 5 seconds */ -#define VALIDITY_MINIMUM 60 /* 60 seconds */ - duration = diff - (int)VALIDITY_MARGIN; - - if (duration < (int)VALIDITY_MINIMUM) { - char buf[64]; - strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", &local); - ogs_warn("[%s] Validation period [%lld seconds, " - "(%lld)(%lld)(%s)(%s)] is too small", subscription->id, - (long long)diff, - (long long)ogs_mktime(&next), - (long long)ogs_mktime(&local), - SubscriptionData->validity_time, buf); +#define VALIDITY_MARGIN (5 * OGS_USEC_PER_SEC) /* 5 seconds */ +#define VALIDITY_MINIMUM (3600 * OGS_USEC_PER_SEC) /* 3600 seconds */ + ogs_time_t time, duration; + if (ogs_sbi_time_from_string( + &time, SubscriptionData->validity_time) == true) { + duration = time - ogs_time_now() - VALIDITY_MARGIN; + if (duration < VALIDITY_MINIMUM) { duration = VALIDITY_MINIMUM; ogs_warn("[%s] Forced to %d seconds", - subscription->id, VALIDITY_MINIMUM); + subscription->id, (int)ogs_time_sec(VALIDITY_MINIMUM)); } - subscription->t_validity = ogs_timer_add(ausf_self()->timer_mgr, ausf_timer_subscription_validity, subscription); ogs_assert(subscription->t_validity); - ogs_timer_start( - subscription->t_validity, ogs_time_from_sec(duration)); + ogs_timer_start(subscription->t_validity, duration); + } else { + ogs_error("Cannot parse validitiyTime [%s]", + SubscriptionData->validity_time); } } } @@ -192,8 +177,6 @@ bool ausf_nnrf_handle_nf_status_notify( return false; } - ausf_sbi_setup_client_callback(nf_instance); - } else if (NotificationData->event == OpenAPI_notification_event_type_NF_DEREGISTERED) { nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); @@ -285,8 +268,6 @@ void ausf_nnrf_handle_nf_discover( continue; } - ausf_sbi_setup_client_callback(nf_instance); - if (!OGS_SBI_NF_INSTANCE_GET( sbi_object->nf_types, nf_instance->nf_type)) ogs_sbi_nf_types_associate(sbi_object->nf_types, @@ -319,6 +300,6 @@ void ausf_nnrf_handle_nf_discover( "(NF discover) No NF", OpenAPI_nf_type_ToString(sbi_object->nf_type)); } else { - ogs_sbi_send(sbi_object, nf_instance); + ogs_sbi_send(nf_instance, sbi_object); } } diff --git a/src/ausf/nudm-build.c b/src/ausf/nudm-build.c index bc36979f4..09126c257 100644 --- a/src/ausf/nudm-build.c +++ b/src/ausf/nudm-build.c @@ -71,10 +71,6 @@ ogs_sbi_request_t *ausf_nudm_ueau_build_result_confirmation_inform( ogs_sbi_message_t message; ogs_sbi_request_t *request = NULL; - char buf[OGS_TIME_ISO8601_FORMATTED_LENGTH]; - struct timeval tv; - struct tm local; - OpenAPI_auth_event_t *AuthEvent = NULL; ogs_assert(ausf_ue); @@ -89,11 +85,7 @@ ogs_sbi_request_t *ausf_nudm_ueau_build_result_confirmation_inform( AuthEvent = ogs_calloc(1, sizeof(*AuthEvent)); ogs_assert(AuthEvent); - ogs_gettimeofday(&tv); - ogs_localtime(tv.tv_sec, &local); - ogs_strftime(buf, OGS_TIME_ISO8601_FORMATTED_LENGTH, - OGS_TIME_ISO8601_FORMAT, &local); - AuthEvent->time_stamp = buf; + AuthEvent->time_stamp = ogs_sbi_localtime_string(ogs_time_now()); AuthEvent->nf_instance_id = ogs_sbi_self()->nf_instance_id; if (ausf_ue->auth_result == OpenAPI_auth_result_AUTHENTICATION_SUCCESS) @@ -108,6 +100,8 @@ ogs_sbi_request_t *ausf_nudm_ueau_build_result_confirmation_inform( request = ogs_sbi_build_request(&message); ogs_assert(request); + if (AuthEvent->time_stamp) + ogs_free(AuthEvent->time_stamp); ogs_free(AuthEvent); return request; diff --git a/src/ausf/sbi-path.c b/src/ausf/sbi-path.c index a4e96c773..0256ee41a 100644 --- a/src/ausf/sbi-path.c +++ b/src/ausf/sbi-path.c @@ -73,19 +73,37 @@ int ausf_sbi_open(void) ogs_sbi_server_start_all(server_cb); + /* + * The connection between NF and NRF is a little special. + * + * NF and NRF share nf_instance. I get the NRF EndPoint(client) information + * the configuration file via lib/sbi/context.c. + * And, the NFService information will be transmitted to NRF. + * + * ogs_sbi_self()->nf_instance_id means NF's InstanceId. + */ ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) { ogs_sbi_nf_service_t *service = NULL; + ogs_sbi_client_t *client = NULL; + /* Build NF instance information. It will be transmitted to NRF. */ ogs_sbi_nf_instance_build_default(nf_instance, ausf_self()->nf_type); + /* Build NF service information. It will be transmitted to NRF. */ service = ogs_sbi_nf_service_build_default(nf_instance, (char*)OGS_SBI_SERVICE_NAME_NAUSF_AUTH); ogs_assert(service); ogs_sbi_nf_service_add_version(service, (char*)OGS_SBI_API_V1, (char*)OGS_SBI_API_V1_0_0, NULL); + /* Client callback is only used when NF sends to NRF */ + client = nf_instance->client; + ogs_assert(client); + client->cb = client_cb; + + /* NFRegister is sent and the response is received + * by the above client callback. */ ausf_nf_fsm_init(nf_instance); - ausf_sbi_setup_client_callback(nf_instance); } return OGS_OK; @@ -96,24 +114,6 @@ void ausf_sbi_close(void) ogs_sbi_server_stop_all(); } -void ausf_sbi_setup_client_callback(ogs_sbi_nf_instance_t *nf_instance) -{ - ogs_sbi_client_t *client = NULL; - ogs_sbi_nf_service_t *nf_service = NULL; - ogs_assert(nf_instance); - - client = nf_instance->client; - ogs_assert(client); - - client->cb = client_cb; - - ogs_list_for_each(&nf_instance->nf_service_list, nf_service) { - client = nf_service->client; - if (client) - client->cb = client_cb; - } -} - void ausf_sbi_discover_and_send( OpenAPI_nf_type_e nf_type, ausf_ue_t *ausf_ue, void *data, ogs_sbi_request_t *(*build)(ausf_ue_t *ausf_ue, void *data)) @@ -128,6 +128,7 @@ void ausf_sbi_discover_and_send( ausf_ue->sbi.nf_state_registered = ausf_nf_state_registered; ausf_ue->sbi.client_wait.duration = ausf_timer_cfg(AUSF_TIMER_SBI_CLIENT_WAIT)->duration; + ausf_ue->sbi.client_cb = client_cb; if (ogs_sbi_discover_and_send( nf_type, &ausf_ue->sbi, data, (ogs_sbi_build_f)build) != true) { diff --git a/src/ausf/sbi-path.h b/src/ausf/sbi-path.h index a1e564ff7..ac2461c70 100644 --- a/src/ausf/sbi-path.h +++ b/src/ausf/sbi-path.h @@ -29,8 +29,6 @@ extern "C" { int ausf_sbi_open(void); void ausf_sbi_close(void); -void ausf_sbi_setup_client_callback(ogs_sbi_nf_instance_t *nf_instance); - void ausf_sbi_discover_and_send( OpenAPI_nf_type_e nf_type, ausf_ue_t *ausf_ue, void *data, ogs_sbi_request_t *(*build)(ausf_ue_t *ausf_ue, void *data)); diff --git a/src/mme/emm-handler.c b/src/mme/emm-handler.c index 70b8f87e9..cf2ee7565 100644 --- a/src/mme/emm-handler.c +++ b/src/mme/emm-handler.c @@ -227,14 +227,14 @@ int emm_handle_attach_complete( ogs_assert(mme_ue); - ogs_debug(" GMT Time[Y:M:D H:M:S GMT] - %d:%d:%d, %d:%d:%d, %d", + ogs_debug(" GMT Time[Y:M:D H:M:S GMT:DST] - %d:%d:%d, %d:%d:%d, %d:%d", gmt.tm_year, gmt.tm_mon, gmt.tm_mday, gmt.tm_hour, gmt.tm_min, gmt.tm_sec, - (int)gmt.tm_gmtoff); - ogs_debug(" LOCAL Time[Y:M:D H:M:S GMT] - %d:%d:%d, %d:%d:%d, %d", + (int)gmt.tm_gmtoff, gmt.tm_isdst); + ogs_debug(" LOCAL Time[Y:M:D H:M:S GMT:DST] - %d:%d:%d, %d:%d:%d, %d:%d", local.tm_year, local.tm_mon, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec, - (int)local.tm_gmtoff); + (int)local.tm_gmtoff, local.tm_isdst); rv = nas_eps_send_emm_to_esm( mme_ue, &attach_complete->esm_message_container); @@ -254,23 +254,23 @@ int emm_handle_attach_complete( emm_information->presencemask |= OGS_NAS_EPS_EMM_INFORMATION_UNIVERSAL_TIME_AND_LOCAL_TIME_ZONE_PRESENT; universal_time_and_local_time_zone->year = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_year % 100); + OGS_NAS_TIME_TO_BCD(gmt.tm_year % 100); universal_time_and_local_time_zone->mon = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_mon+1); + OGS_NAS_TIME_TO_BCD(gmt.tm_mon+1); universal_time_and_local_time_zone->mday = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_mday); + OGS_NAS_TIME_TO_BCD(gmt.tm_mday); universal_time_and_local_time_zone->hour = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_hour); + OGS_NAS_TIME_TO_BCD(gmt.tm_hour); universal_time_and_local_time_zone->min = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_min); + OGS_NAS_TIME_TO_BCD(gmt.tm_min); universal_time_and_local_time_zone->sec = - OGS_OGS_NAS_TIME_TO_BCD(gmt.tm_sec); + OGS_NAS_TIME_TO_BCD(gmt.tm_sec); if (local.tm_gmtoff >= 0) { universal_time_and_local_time_zone->timezone = - OGS_OGS_NAS_TIME_TO_BCD(local.tm_gmtoff / 900); + OGS_NAS_TIME_TO_BCD(local.tm_gmtoff / 900); } else { universal_time_and_local_time_zone->timezone = - OGS_OGS_NAS_TIME_TO_BCD((-local.tm_gmtoff) / 900); + OGS_NAS_TIME_TO_BCD((-local.tm_gmtoff) / 900); universal_time_and_local_time_zone->timezone |= 0x08; } ogs_debug(" Timezone:0x%x", diff --git a/src/mme/mme-context.c b/src/mme/mme-context.c index 5559526f1..a0de6bdad 100644 --- a/src/mme/mme-context.c +++ b/src/mme/mme-context.c @@ -1408,8 +1408,8 @@ int mme_context_parse_config() uint16_t port = self.gtpc_port; uint16_t tac[OGS_MAX_NUM_OF_TAI] = {0,}; uint8_t num_of_tac = 0; - uint32_t enb_id[OGS_MAX_NUM_OF_ENB_ID] = {0,}; - uint8_t num_of_enb_id = 0; + uint32_t e_cell_id[OGS_MAX_NUM_OF_CELL_ID] = {0,}; + uint8_t num_of_e_cell_id = 0; if (ogs_yaml_iter_type(>pc_array) == YAML_MAPPING_NODE) { @@ -1490,35 +1490,32 @@ int mme_context_parse_config() } while ( ogs_yaml_iter_type(&tac_iter) == YAML_SEQUENCE_NODE); - } else if (!strcmp(gtpc_key, "enb_id")) { - ogs_yaml_iter_t enb_id_iter; - ogs_yaml_iter_recurse(>pc_iter, &enb_id_iter); - ogs_assert(ogs_yaml_iter_type(&enb_id_iter) != - YAML_MAPPING_NODE); + } else if (!strcmp(gtpc_key, "e_cell_id")) { + ogs_yaml_iter_t e_cell_id_iter; + ogs_yaml_iter_recurse(>pc_iter, + &e_cell_id_iter); + ogs_assert(ogs_yaml_iter_type(&e_cell_id_iter) + != YAML_MAPPING_NODE); do { const char *v = NULL; - ogs_assert(num_of_enb_id <= - OGS_MAX_NUM_OF_ENB_ID); - if (ogs_yaml_iter_type(&enb_id_iter) == + ogs_assert(num_of_e_cell_id <= + OGS_MAX_NUM_OF_CELL_ID); + if (ogs_yaml_iter_type(&e_cell_id_iter) == YAML_SEQUENCE_NODE) { - if (!ogs_yaml_iter_next(&enb_id_iter)) + if (!ogs_yaml_iter_next( + &e_cell_id_iter)) break; } - v = ogs_yaml_iter_value(&enb_id_iter); + v = ogs_yaml_iter_value(&e_cell_id_iter); if (v) { - if (strncmp(v,"0x",2)) { - // integer enb_id - enb_id[num_of_enb_id] = atoi(v); - } else { - // hex enb_id - enb_id[num_of_enb_id] = strtol(v, NULL, 16); - } - num_of_enb_id++; + e_cell_id[num_of_e_cell_id] + = ogs_uint28_from_string((char*)v); + num_of_e_cell_id++; } } while ( - ogs_yaml_iter_type(&enb_id_iter) == + ogs_yaml_iter_type(&e_cell_id_iter) == YAML_SEQUENCE_NODE); } else ogs_warn("unknown key `%s`", gtpc_key); @@ -1543,25 +1540,13 @@ int mme_context_parse_config() if (num_of_tac != 0) memcpy(sgw->tac, tac, sizeof(sgw->tac)); - sgw->num_of_enb_id = num_of_enb_id; - if (num_of_enb_id != 0) - memcpy(sgw->enb_id, enb_id, sizeof(sgw->enb_id)); + sgw->num_of_e_cell_id = num_of_e_cell_id; + if (num_of_e_cell_id != 0) + memcpy(sgw->e_cell_id, e_cell_id, + sizeof(sgw->e_cell_id)); } while (ogs_yaml_iter_type(>pc_array) == YAML_SEQUENCE_NODE); - } else if (!strcmp(mme_key, "selection_mode")) { - const char *selection_mode = - ogs_yaml_iter_value(&sgw_iter); - - if (!strcmp(selection_mode, "rr")) - self.sgw_selection = SGW_SELECT_RR; - else if (!strcmp(selection_mode, "tac")) - self.sgw_selection = SGW_SELECT_TAC; - else if (!strcmp(selection_mode, "enb_id")) - self.sgw_selection = SGW_SELECT_ENB_ID; - else - ogs_warn("unknown sgw_selection mode `%s`", - selection_mode); } } } else if (!strcmp(root_key, "pgw") || !strcmp(root_key, "smf")) { @@ -2195,6 +2180,42 @@ static int mme_ue_new_guti(mme_ue_t *mme_ue) return OGS_OK; } +static bool compare_ue_info(mme_sgw_t *node, enb_ue_t *enb_ue) +{ + int i; + + ogs_assert(node); + ogs_assert(enb_ue); + + for (i = 0; i < node->num_of_tac; i++) + if (node->tac[i] == enb_ue->saved.tai.tac) return true; + + for (i = 0; i < node->num_of_e_cell_id; i++) + if (node->e_cell_id[i] == enb_ue->saved.e_cgi.cell_id) return true; + + return false; +} + +static mme_sgw_t *selected_sgw_node(mme_sgw_t *current, enb_ue_t *enb_ue) +{ + mme_sgw_t *next, *node; + + ogs_assert(current); + ogs_assert(enb_ue); + + next = ogs_list_next(current); + for (node = next; node; node = ogs_list_next(node)) { + if (compare_ue_info(node, enb_ue) == true) return node; + } + + for (node = ogs_list_first(&mme_self()->sgw_list); + node != next; node = ogs_list_next(node)) { + if (compare_ue_info(node, enb_ue) == true) return node; + } + + return next ? next : ogs_list_first(&mme_self()->sgw_list); +} + mme_ue_t *mme_ue_add(enb_ue_t *enb_ue) { mme_enb_t *enb = NULL; @@ -2220,160 +2241,19 @@ mme_ue_t *mme_ue_add(enb_ue_t *enb_ue) /* Create New GUTI */ mme_ue_new_guti(mme_ue); - // on first UE connection, initialise at top of SGW list - // for subsequent UE connections, begin from current position + /* + * When used for the first time, if last node is set, + * the search is performed from the first SGW in a round-robin manner. + */ if (mme_self()->sgw == NULL) - mme_self()->sgw = ogs_list_first(&mme_self()->sgw_list); + mme_self()->sgw = ogs_list_last(&mme_self()->sgw_list); - if (mme_self()->sgw_selection == SGW_SELECT_RR) { - /* Select SGW with round-robin manner */ - ogs_debug("Select SGW by RR"); + /* setup GTP path with selected SGW */ + mme_self()->sgw = selected_sgw_node(mme_self()->sgw, enb_ue); + ogs_assert(mme_self()->sgw); + OGS_SETUP_GTP_NODE(mme_ue, mme_self()->sgw->gnode); + ogs_debug("UE using SGW on IP[%s]", OGS_ADDR(&mme_ue->gnode->addr, buf)); - // list SGW used - OGS_ADDR(&mme_self()->sgw->gnode->addr, buf); - ogs_debug("UE using SGW on IP[%s]", - buf); - // setup GTP path with selected SGW - ogs_assert(mme_self()->sgw); - OGS_SETUP_GTP_NODE(mme_ue, mme_self()->sgw->gnode); - // iterate to next SGW in list for next UE attach (RR) - mme_self()->sgw = ogs_list_next(mme_self()->sgw); - - } else if (mme_self()->sgw_selection == SGW_SELECT_TAC) { - /* Select SGW by eNB TAC */ - ogs_debug("Select SGW by enb_tac,(RR)"); - /* - - starting from list position of last used SGW, search down list for a SGW that serves the enb_tac - - if suitable SGW found - - use it - - if no suitable SGW found, keep searching - - if bottom of list reached, reset search to top of list - - if completed full cyclic search of list and still not found a suitable SGW, use default (first) - */ - - int i, found=0, numreset=0;; - char startSGWIP[OGS_ADDRSTRLEN]; - OGS_ADDR(&mme_self()->sgw->gnode->addr, startSGWIP); - - // search SGW list, find next SGW that serves the TAC || use default (first) if not found - while (!found) { - // (when end of SGW list reached, reset search to top of SGW list) - if(mme_self()->sgw == NULL){ - mme_self()->sgw = ogs_list_first(&mme_self()->sgw_list); - numreset = 1; - } - // search SGW list, find next SGW that serves the TAC - while(mme_self()->sgw && !found) { - // if cyclic list check complete and still not found a SGW, break - OGS_ADDR(&mme_self()->sgw->gnode->addr, buf); - if (numreset == 1 && !strcmp(buf,startSGWIP)) { - break; - } - // search from current list position - for (i = 0; i < mme_self()->sgw->num_of_tac && !found; i++){ - found = mme_self()->sgw->tac[i] == enb_ue->saved.tai.tac ? 1: 0; - } - if(found){ - // found a SGW that serves the TAC - OGS_ADDR(&mme_self()->sgw->gnode->addr, buf); - ogs_debug("SGW on IP[%s] serves enb_tac[%d] - use it", - buf, enb_ue->saved.tai.tac); - } else { - // not found, check next SGW in list - mme_self()->sgw = ogs_list_next(mme_self()->sgw); - } - } - // after checking from the top of the list and not finding a suitable SGW - if (!found && numreset == 1 ){ - // default to first in list - ogs_warn("No SGW found that serves enb_tac[%d], defaulting to first SGW in mme.yaml list", - enb_ue->saved.tai.tac); - mme_self()->sgw = ogs_list_first(&mme_self()->sgw_list); - break; - } - } - - // list SGW used - OGS_ADDR(&mme_self()->sgw->gnode->addr, buf); - ogs_debug("UE using SGW on IP[%s]", - buf); - - // setup GTP path with selected SGW - ogs_assert(mme_self()->sgw); - OGS_SETUP_GTP_NODE(mme_ue, mme_self()->sgw->gnode); - - // iterate to next SGW in list for next UE attach (RR) - mme_self()->sgw = ogs_list_next(mme_self()->sgw); - - } else if (mme_self()->sgw_selection == SGW_SELECT_ENB_ID) { - /* Select SGW by eNB_ID */ - ogs_debug("Select SGW by enb_id,(RR)"); - /* - - starting from list position of last used SGW, search down list for a SGW that serves the enb_id - - if suitable SGW found - - use it - - if no suitable SGW found, keep searching - - if bottom of list reached, reset search to top of list - - if completed full cyclic search of list and still not found a suitable SGW, use default (first) - */ - - int i, found=0, numreset=0; - char startSGWIP[OGS_ADDRSTRLEN]; - OGS_ADDR(&mme_self()->sgw->gnode->addr, startSGWIP); - - // search SGW list, find next SGW that serves the enb_id || use default (first) if not found - while (!found) { - // (when end of SGW list reached, reset search to top of SGW list) - if(mme_self()->sgw == NULL){ - mme_self()->sgw = ogs_list_first(&mme_self()->sgw_list); - numreset = 1; - } - // search SGW list, find next SGW that serves the enb_id - while(mme_self()->sgw && !found) { - // if cyclic list check complete and still not found a SGW, break - OGS_ADDR(&mme_self()->sgw->gnode->addr, buf); - if (numreset == 1 && !strcmp(buf,startSGWIP)) { - break; - } - // search from current list position - for (i = 0; i < mme_self()->sgw->num_of_enb_id && !found; i++){ - found = mme_self()->sgw->enb_id[i] == enb->enb_id ? 1: 0; - } - if(found){ - // found a SGW that serves the enb_id - OGS_ADDR(&mme_self()->sgw->gnode->addr, buf); - ogs_debug("SGW on IP[%s] serves enb_id[%d]/[0x%02x] - use it", - buf, enb->enb_id, enb->enb_id); - } else { - // not found, check next SGW in list - mme_self()->sgw = ogs_list_next(mme_self()->sgw); - } - } - // after checking from the top of the list and not finding a suitable SGW - if (!found && numreset == 1 ){ - // default to first in list - ogs_warn("No SGW found that serves enb_id[%d]/[0x%02x], defaulting to first SGW in mme.yaml list", - enb->enb_id, enb->enb_id); - mme_self()->sgw = ogs_list_first(&mme_self()->sgw_list); - break; - } - } - - // list SGW used - OGS_ADDR(&mme_self()->sgw->gnode->addr, buf); - ogs_debug("UE using SGW on IP[%s]", - buf); - - // setup GTP path with selected SGW - ogs_assert(mme_self()->sgw); - OGS_SETUP_GTP_NODE(mme_ue, mme_self()->sgw->gnode); - - // iterate to next SGW in list for next UE attach (RR) - mme_self()->sgw = ogs_list_next(mme_self()->sgw); - - } else - ogs_assert_if_reached(); - /* Clear VLR */ mme_ue->csmap = NULL; mme_ue->vlr_ostream_id = 0; diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h index 4548b6ae0..7ec4a4ebd 100644 --- a/src/mme/mme-context.h +++ b/src/mme/mme-context.h @@ -60,12 +60,6 @@ typedef struct ogs_diam_config_s ogs_diam_config_t; typedef uint32_t mme_m_tmsi_t; typedef uint32_t mme_p_tmsi_t; -typedef enum { - SGW_SELECT_RR = 0, /* Default SGW Selection Method */ - SGW_SELECT_TAC, - SGW_SELECT_ENB_ID, -} sgw_select_e; - typedef struct served_gummei_s { uint32_t num_of_plmn_id; ogs_plmn_id_t plmn_id[OGS_MAX_NUM_OF_PLMN]; @@ -139,9 +133,6 @@ typedef struct mme_context_s { /* MME Name */ const char *mme_name; - /* SGW Selection */ - sgw_select_e sgw_selection; - /* S1SetupResponse */ uint8_t relative_capacity; @@ -171,8 +162,8 @@ typedef struct mme_sgw_s { uint16_t tac[OGS_MAX_NUM_OF_TAI]; uint8_t num_of_tac; - uint32_t enb_id[OGS_MAX_NUM_OF_ENB_ID]; - uint8_t num_of_enb_id; + uint32_t e_cell_id[OGS_MAX_NUM_OF_CELL_ID]; + uint8_t num_of_e_cell_id; ogs_gtp_node_t *gnode; } mme_sgw_t; diff --git a/src/mme/mme-s11-build.c b/src/mme/mme-s11-build.c index 9b1adb207..815aee237 100644 --- a/src/mme/mme-s11-build.c +++ b/src/mme/mme-s11-build.c @@ -139,7 +139,8 @@ ogs_pkbuf_t *mme_s11_build_create_session_request( pgw_addr6 = mme_self()->pgw_addr6; } - rv = ogs_gtp_sockaddr_to_f_teid(pgw_addr, pgw_addr6, &pgw_s5c_teid, &len); + rv = ogs_gtp_sockaddr_to_f_teid( + pgw_addr, pgw_addr6, &pgw_s5c_teid, &len); ogs_assert(rv == OGS_OK); req->pgw_s5_s8_address_for_control_plane_or_pmip.presence = 1; req->pgw_s5_s8_address_for_control_plane_or_pmip.data = &pgw_s5c_teid; @@ -162,7 +163,11 @@ ogs_pkbuf_t *mme_s11_build_create_session_request( pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV6 || pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV4V6) { req->pdn_type.u8 = ((pdn->pdn_type + 1) & sess->request_type.type); - ogs_assert(req->pdn_type.u8 != 0); + if (req->pdn_type.u8 == 0) { + ogs_fatal("Cannot derive PDN Type [UE:%d,HSS:%d]", + sess->request_type.type, pdn->pdn_type); + ogs_assert_if_reached(); + } } else if (pdn->pdn_type == OGS_DIAM_PDN_TYPE_IPV4_OR_IPV6) { req->pdn_type.u8 = sess->request_type.type; } else { @@ -673,7 +678,6 @@ ogs_pkbuf_t *mme_s11_build_create_indirect_data_forwarding_tunnel_request( ogs_gtp_create_indirect_data_forwarding_tunnel_request_t *req = >p_message.create_indirect_data_forwarding_tunnel_request; - ogs_gtp_tlv_bearer_context_t *bearers[OGS_GTP_MAX_INDIRECT_TUNNEL]; ogs_gtp_f_teid_t dl_teid[OGS_GTP_MAX_INDIRECT_TUNNEL]; ogs_gtp_f_teid_t ul_teid[OGS_GTP_MAX_INDIRECT_TUNNEL]; int len; @@ -684,7 +688,6 @@ ogs_pkbuf_t *mme_s11_build_create_indirect_data_forwarding_tunnel_request( ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]", mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid); - ogs_gtp_bearers_in_create_indirect_tunnel_request(&bearers, req); memset(>p_message, 0, sizeof(ogs_gtp_message_t)); i = 0; @@ -700,10 +703,9 @@ ogs_pkbuf_t *mme_s11_build_create_indirect_data_forwarding_tunnel_request( rv = ogs_gtp_ip_to_f_teid( &bearer->enb_dl_ip, &dl_teid[i], &len); ogs_assert(rv == OGS_OK); - ogs_assert(bearers[i]); - bearers[i]->s1_u_enodeb_f_teid.presence = 1; - bearers[i]->s1_u_enodeb_f_teid.data = &dl_teid[i]; - bearers[i]->s1_u_enodeb_f_teid.len = len; + req->bearer_contexts[i].s1_u_enodeb_f_teid.presence = 1; + req->bearer_contexts[i].s1_u_enodeb_f_teid.data = &dl_teid[i]; + req->bearer_contexts[i].s1_u_enodeb_f_teid.len = len; } if (MME_HAVE_ENB_UL_INDIRECT_TUNNEL(bearer)) { @@ -714,17 +716,16 @@ ogs_pkbuf_t *mme_s11_build_create_indirect_data_forwarding_tunnel_request( rv = ogs_gtp_ip_to_f_teid( &bearer->enb_ul_ip, &ul_teid[i], &len); ogs_assert(rv == OGS_OK); - ogs_assert(bearers[i]); - bearers[i]->s12_rnc_f_teid.presence = 1; - bearers[i]->s12_rnc_f_teid.data = &ul_teid[i]; - bearers[i]->s12_rnc_f_teid.len = len; + req->bearer_contexts[i].s12_rnc_f_teid.presence = 1; + req->bearer_contexts[i].s12_rnc_f_teid.data = &ul_teid[i]; + req->bearer_contexts[i].s12_rnc_f_teid.len = len; } if (MME_HAVE_ENB_DL_INDIRECT_TUNNEL(bearer) || MME_HAVE_ENB_UL_INDIRECT_TUNNEL(bearer)) { - bearers[i]->presence = 1; - bearers[i]->eps_bearer_id.presence = 1; - bearers[i]->eps_bearer_id.u8 = bearer->ebi; + req->bearer_contexts[i].presence = 1; + req->bearer_contexts[i].eps_bearer_id.presence = 1; + req->bearer_contexts[i].eps_bearer_id.u8 = bearer->ebi; i++; } @@ -763,80 +764,80 @@ ogs_pkbuf_t *mme_s11_build_bearer_resource_command( ogs_assert(mme_ue); ogs_assert(nas_message); - switch (nas_message->esm.h.message_type) { - case OGS_NAS_EPS_BEARER_RESOURCE_ALLOCATION_REQUEST: - allocation = &nas_message->esm.bearer_resource_allocation_request; - qos = &allocation->required_traffic_flow_qos; - tad = &allocation->traffic_flow_aggregate; - break; - case OGS_NAS_EPS_BEARER_RESOURCE_MODIFICATION_REQUEST: - modification = &nas_message->esm.bearer_resource_modification_request; - if (modification->presencemask & - OGS_NAS_EPS_BEARER_RESOURCE_MODIFICATION_REQUEST_REQUIRED_TRAFFIC_FLOW_QOS_PRESENT) { - qos = &modification->required_traffic_flow_qos; - } - tad = &modification->traffic_flow_aggregate; - break; - default: - ogs_error("Invalid NAS ESM Type[%d]", - nas_message->esm.h.message_type); - return NULL; + switch (nas_message->esm.h.message_type) { + case OGS_NAS_EPS_BEARER_RESOURCE_ALLOCATION_REQUEST: + allocation = &nas_message->esm.bearer_resource_allocation_request; + qos = &allocation->required_traffic_flow_qos; + tad = &allocation->traffic_flow_aggregate; + break; + case OGS_NAS_EPS_BEARER_RESOURCE_MODIFICATION_REQUEST: + modification = &nas_message->esm.bearer_resource_modification_request; + if (modification->presencemask & + OGS_NAS_EPS_BEARER_RESOURCE_MODIFICATION_REQUEST_REQUIRED_TRAFFIC_FLOW_QOS_PRESENT) { + qos = &modification->required_traffic_flow_qos; } - - linked_bearer = mme_linked_bearer(bearer); - ogs_assert(linked_bearer); - - ogs_debug("[MME] Bearer Resource Command"); - ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]", - mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid); - - memset(>p_message, 0, sizeof(ogs_gtp_message_t)); - - /* Linked Bearer Context : EBI */ - cmd->linked_eps_bearer_id.presence = 1; - cmd->linked_eps_bearer_id.u8 = bearer->ebi; - - /* Procedure Transaction ID(PTI) */ - cmd->procedure_transaction_id.presence = 1; - cmd->procedure_transaction_id.u8 = sess->pti; - - /* Flow Quality of Service(QoS) */ - if (qos) { - memset(&flow_qos, 0, sizeof(flow_qos)); - flow_qos.qci = qos->qci; - - /* Octet 4 - * - * In UE to network direction: - * 00000000 Subscribed maximum bit rate - * - * In network to UE direction: - * 00000000 Reserved - */ - flow_qos.ul_mbr = qos->ul_mbr == 0 ? bearer->qos.mbr.uplink : - ogs_gtp_qos_to_bps( - qos->ul_mbr, qos->ul_mbr_extended, qos->ul_mbr_extended2); - flow_qos.dl_mbr = qos->dl_mbr == 0 ? bearer->qos.mbr.downlink : - ogs_gtp_qos_to_bps( - qos->dl_mbr, qos->dl_mbr_extended, qos->dl_mbr_extended2); - flow_qos.ul_gbr = qos->ul_gbr == 0 ? bearer->qos.gbr.uplink : - ogs_gtp_qos_to_bps( - qos->ul_gbr, qos->ul_gbr_extended, qos->ul_gbr_extended2); - flow_qos.dl_gbr = qos->dl_gbr == 0 ? bearer->qos.gbr.downlink : - ogs_gtp_qos_to_bps( - qos->dl_gbr, qos->dl_gbr_extended, qos->dl_gbr_extended2); - - ogs_gtp_build_flow_qos( - &cmd->flow_quality_of_service, - &flow_qos, flow_qos_buf, GTP_FLOW_QOS_LEN); - cmd->flow_quality_of_service.presence = 1; - } - - /* Traffic Aggregate Description(TAD) */ - cmd->traffic_aggregate_description.presence = 1; - cmd->traffic_aggregate_description.data = tad->buffer; - cmd->traffic_aggregate_description.len = tad->length; - - gtp_message.h.type = type; - return ogs_gtp_build_msg(>p_message); + tad = &modification->traffic_flow_aggregate; + break; + default: + ogs_error("Invalid NAS ESM Type[%d]", + nas_message->esm.h.message_type); + return NULL; } + + linked_bearer = mme_linked_bearer(bearer); + ogs_assert(linked_bearer); + + ogs_debug("[MME] Bearer Resource Command"); + ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]", + mme_ue->mme_s11_teid, mme_ue->sgw_s11_teid); + + memset(>p_message, 0, sizeof(ogs_gtp_message_t)); + + /* Linked Bearer Context : EBI */ + cmd->linked_eps_bearer_id.presence = 1; + cmd->linked_eps_bearer_id.u8 = bearer->ebi; + + /* Procedure Transaction ID(PTI) */ + cmd->procedure_transaction_id.presence = 1; + cmd->procedure_transaction_id.u8 = sess->pti; + + /* Flow Quality of Service(QoS) */ + if (qos) { + memset(&flow_qos, 0, sizeof(flow_qos)); + flow_qos.qci = qos->qci; + + /* Octet 4 + * + * In UE to network direction: + * 00000000 Subscribed maximum bit rate + * + * In network to UE direction: + * 00000000 Reserved + */ + flow_qos.ul_mbr = qos->ul_mbr == 0 ? bearer->qos.mbr.uplink : + ogs_gtp_qos_to_bps( + qos->ul_mbr, qos->ul_mbr_extended, qos->ul_mbr_extended2); + flow_qos.dl_mbr = qos->dl_mbr == 0 ? bearer->qos.mbr.downlink : + ogs_gtp_qos_to_bps( + qos->dl_mbr, qos->dl_mbr_extended, qos->dl_mbr_extended2); + flow_qos.ul_gbr = qos->ul_gbr == 0 ? bearer->qos.gbr.uplink : + ogs_gtp_qos_to_bps( + qos->ul_gbr, qos->ul_gbr_extended, qos->ul_gbr_extended2); + flow_qos.dl_gbr = qos->dl_gbr == 0 ? bearer->qos.gbr.downlink : + ogs_gtp_qos_to_bps( + qos->dl_gbr, qos->dl_gbr_extended, qos->dl_gbr_extended2); + + ogs_gtp_build_flow_qos( + &cmd->flow_quality_of_service, + &flow_qos, flow_qos_buf, GTP_FLOW_QOS_LEN); + cmd->flow_quality_of_service.presence = 1; + } + + /* Traffic Aggregate Description(TAD) */ + cmd->traffic_aggregate_description.presence = 1; + cmd->traffic_aggregate_description.data = tad->buffer; + cmd->traffic_aggregate_description.len = tad->length; + + gtp_message.h.type = type; + return ogs_gtp_build_msg(>p_message); +} diff --git a/src/mme/mme-s11-handler.c b/src/mme/mme-s11-handler.c index dadf68494..ad610458b 100644 --- a/src/mme/mme-s11-handler.c +++ b/src/mme/mme-s11-handler.c @@ -762,7 +762,6 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response( enb_ue_t *source_ue = NULL; int i; - ogs_gtp_tlv_bearer_context_t *bearers[OGS_GTP_MAX_INDIRECT_TUNNEL]; ogs_gtp_f_teid_t *teid = NULL; ogs_assert(xact); @@ -796,28 +795,26 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response( return; } - ogs_gtp_bearers_in_create_indirect_tunnel_response(&bearers, rsp); - - for (i = 0; bearers[i]->presence; i++) { - if (bearers[i]->eps_bearer_id.presence == 0) { + for (i = 0; rsp->bearer_contexts[i].presence; i++) { + if (rsp->bearer_contexts[i].eps_bearer_id.presence == 0) { ogs_error("No EBI"); return; } bearer = mme_bearer_find_by_ue_ebi(mme_ue, - bearers[i]->eps_bearer_id.u8); + rsp->bearer_contexts[i].eps_bearer_id.u8); ogs_expect_or_return(bearer); - if (bearers[i]->s4_u_sgsn_f_teid.presence) { - teid = bearers[i]->s4_u_sgsn_f_teid.data; + if (rsp->bearer_contexts[i].s4_u_sgsn_f_teid.presence) { + teid = rsp->bearer_contexts[i].s4_u_sgsn_f_teid.data; ogs_assert(teid); bearer->sgw_dl_teid = ntohl(teid->teid); rv = ogs_gtp_f_teid_to_ip(teid, &bearer->sgw_dl_ip); ogs_expect_or_return(rv == OGS_OK); } - if (bearers[i]->s2b_u_epdg_f_teid_5.presence) { - teid = bearers[i]->s2b_u_epdg_f_teid_5.data; + if (rsp->bearer_contexts[i].s2b_u_epdg_f_teid_5.presence) { + teid = rsp->bearer_contexts[i].s2b_u_epdg_f_teid_5.data; ogs_assert(teid); bearer->sgw_ul_teid = ntohl(teid->teid); diff --git a/src/mme/s1ap-handler.c b/src/mme/s1ap-handler.c index f7695b4f0..7a7d2fc13 100644 --- a/src/mme/s1ap-handler.c +++ b/src/mme/s1ap-handler.c @@ -1410,7 +1410,8 @@ void s1ap_handle_handover_required(mme_enb_t *enb, ogs_s1ap_message_t *message) Source_ToTarget_TransparentContainer); } -void s1ap_handle_handover_request_ack(mme_enb_t *enb, ogs_s1ap_message_t *message) +void s1ap_handle_handover_request_ack( + mme_enb_t *enb, ogs_s1ap_message_t *message) { int rv; char buf[OGS_ADDRSTRLEN]; diff --git a/src/nrf/nnrf-handler.c b/src/nrf/nnrf-handler.c index 19a7225cc..8514a9e47 100644 --- a/src/nrf/nnrf-handler.c +++ b/src/nrf/nnrf-handler.c @@ -179,18 +179,8 @@ bool nrf_nnrf_handle_nf_status_subscribe( ogs_freeaddrinfo(addr); if (subscription->time.validity) { - char buf[OGS_TIME_ISO8601_FORMATTED_LENGTH]; - struct timeval tv; - struct tm local; - - ogs_gettimeofday(&tv); - tv.tv_sec += subscription->time.validity; - ogs_localtime(tv.tv_sec, &local); - - ogs_strftime(buf, OGS_TIME_ISO8601_FORMATTED_LENGTH, - OGS_TIME_ISO8601_FORMAT, &local); - - SubscriptionData->validity_time = ogs_strdup(buf); + SubscriptionData->validity_time = ogs_sbi_localtime_string( + ogs_time_now() + ogs_time_from_sec(subscription->time.validity)); subscription->t_validity = ogs_timer_add(nrf_self()->timer_mgr, nrf_timer_subscription_validity, subscription); diff --git a/src/nrf/sbi-path.c b/src/nrf/sbi-path.c index 3c5e4a47e..a09ffae25 100644 --- a/src/nrf/sbi-path.c +++ b/src/nrf/sbi-path.c @@ -91,12 +91,11 @@ void nrf_nnrf_nfm_send_nf_status_notify(ogs_sbi_subscription_t *subscription, ogs_assert(subscription); client = subscription->client; ogs_assert(client); - client->cb = client_notify_cb; request = nrf_nnrf_nfm_build_nf_status_notify( client, subscription, event, nf_instance); ogs_assert(request); - ogs_sbi_client_send_request(client, request, NULL); + ogs_sbi_client_send_request(client, client_notify_cb, request, NULL); ogs_sbi_request_free(request); } diff --git a/src/sgw/sgw-s11-handler.c b/src/sgw/sgw-s11-handler.c index c29a5a7ae..2f57520b3 100644 --- a/src/sgw/sgw-s11-handler.c +++ b/src/sgw/sgw-s11-handler.c @@ -974,8 +974,6 @@ void sgw_s11_handle_create_indirect_data_forwarding_tunnel_request( sgw_tunnel_t *tunnel = NULL; ogs_gtp_cause_t cause; - ogs_gtp_tlv_bearer_context_t *req_bearers[OGS_GTP_MAX_INDIRECT_TUNNEL]; - ogs_gtp_tlv_bearer_context_t *rsp_bearers[OGS_GTP_MAX_INDIRECT_TUNNEL]; ogs_gtp_f_teid_t *req_teid = NULL; ogs_gtp_f_teid_t rsp_dl_teid[OGS_GTP_MAX_INDIRECT_TUNNEL]; ogs_gtp_f_teid_t rsp_ul_teid[OGS_GTP_MAX_INDIRECT_TUNNEL]; @@ -1011,21 +1009,18 @@ void sgw_s11_handle_create_indirect_data_forwarding_tunnel_request( ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]", sgw_ue->mme_s11_teid, sgw_ue->sgw_s11_teid); - ogs_gtp_bearers_in_create_indirect_tunnel_request(&req_bearers, req); - ogs_gtp_bearers_in_create_indirect_tunnel_response(&rsp_bearers, rsp); - - for (i = 0; req_bearers[i]->presence; i++) { - if (req_bearers[i]->eps_bearer_id.presence == 0) { + for (i = 0; req->bearer_contexts[i].presence; i++) { + if (req->bearer_contexts[i].eps_bearer_id.presence == 0) { ogs_error("No EBI"); return; } bearer = sgw_bearer_find_by_ue_ebi(sgw_ue, - req_bearers[i]->eps_bearer_id.u8); + req->bearer_contexts[i].eps_bearer_id.u8); ogs_assert(bearer); - if (req_bearers[i]->s1_u_enodeb_f_teid.presence) { - req_teid = req_bearers[i]->s1_u_enodeb_f_teid.data; + if (req->bearer_contexts[i].s1_u_enodeb_f_teid.presence) { + req_teid = req->bearer_contexts[i].s1_u_enodeb_f_teid.data; ogs_assert(req_teid); tunnel = sgw_tunnel_add(bearer, @@ -1056,16 +1051,16 @@ void sgw_s11_handle_create_indirect_data_forwarding_tunnel_request( rv = ogs_gtp_sockaddr_to_f_teid(sgw_self()->gtpu_addr, sgw_self()->gtpu_addr6, &rsp_dl_teid[i], &len); ogs_assert(len > 0); - rsp_bearers[i]->s4_u_sgsn_f_teid.presence = 1; - rsp_bearers[i]->s4_u_sgsn_f_teid.data = &rsp_dl_teid[i]; - rsp_bearers[i]->s4_u_sgsn_f_teid.len = len; + rsp->bearer_contexts[i].s4_u_sgsn_f_teid.presence = 1; + rsp->bearer_contexts[i].s4_u_sgsn_f_teid.data = &rsp_dl_teid[i]; + rsp->bearer_contexts[i].s4_u_sgsn_f_teid.len = len; ogs_debug(" SGW_DL_TEID[%d] ENB_DL_TEID[%d]", tunnel->local_teid, tunnel->remote_teid); } - if (req_bearers[i]->s12_rnc_f_teid.presence) { - req_teid = req_bearers[i]->s12_rnc_f_teid.data; + if (req->bearer_contexts[i].s12_rnc_f_teid.presence) { + req_teid = req->bearer_contexts[i].s12_rnc_f_teid.data; ogs_assert(req_teid); tunnel = sgw_tunnel_add(bearer, @@ -1097,22 +1092,22 @@ void sgw_s11_handle_create_indirect_data_forwarding_tunnel_request( rv = ogs_gtp_sockaddr_to_f_teid(sgw_self()->gtpu_addr, sgw_self()->gtpu_addr6, &rsp_ul_teid[i], &len); ogs_assert(rv == OGS_OK); - rsp_bearers[i]->s2b_u_epdg_f_teid_5.presence = 1; - rsp_bearers[i]->s2b_u_epdg_f_teid_5.data = &rsp_ul_teid[i]; - rsp_bearers[i]->s2b_u_epdg_f_teid_5.len = len; + rsp->bearer_contexts[i].s2b_u_epdg_f_teid_5.presence = 1; + rsp->bearer_contexts[i].s2b_u_epdg_f_teid_5.data = &rsp_ul_teid[i]; + rsp->bearer_contexts[i].s2b_u_epdg_f_teid_5.len = len; ogs_debug(" SGW_UL_TEID[%d] ENB_UL_TEID[%d]", tunnel->local_teid, tunnel->remote_teid); } - if (req_bearers[i]->s1_u_enodeb_f_teid.presence || - req_bearers[i]->s12_rnc_f_teid.presence) { - rsp_bearers[i]->presence = 1; - rsp_bearers[i]->eps_bearer_id.presence = 1; - rsp_bearers[i]->eps_bearer_id.u8 = bearer->ebi; + if (req->bearer_contexts[i].s1_u_enodeb_f_teid.presence || + req->bearer_contexts[i].s12_rnc_f_teid.presence) { + rsp->bearer_contexts[i].presence = 1; + rsp->bearer_contexts[i].eps_bearer_id.presence = 1; + rsp->bearer_contexts[i].eps_bearer_id.u8 = bearer->ebi; - rsp_bearers[i]->cause.presence = 1; - rsp_bearers[i]->cause.data = &cause; - rsp_bearers[i]->cause.len = sizeof(cause); + rsp->bearer_contexts[i].cause.presence = 1; + rsp->bearer_contexts[i].cause.data = &cause; + rsp->bearer_contexts[i].cause.len = sizeof(cause); } } diff --git a/src/smf/context.c b/src/smf/context.c index bde8f61d3..53e982df7 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -598,8 +598,55 @@ smf_ue_t *smf_ue_find_by_imsi(uint8_t *imsi, int imsi_len) return (smf_ue_t *)ogs_hash_get(self.imsi_hash, imsi, imsi_len); } +static bool compare_ue_info(ogs_pfcp_node_t *node, smf_sess_t *sess) +{ + int i; + + ogs_assert(node); + ogs_assert(sess); + + for (i = 0; i < node->num_of_tac; i++) + if (node->tac[i] == sess->e_tai.tac || + node->tac[i] == sess->nr_tai.tac.v) return true; + + for (i = 0; i < node->num_of_e_cell_id; i++) + if (node->e_cell_id[i] == sess->e_cgi.cell_id) return true; + + for (i = 0; i < node->num_of_nr_cell_id; i++) + if (node->nr_cell_id[i] == sess->nr_cgi.cell_id) return true; + + for (i = 0; i < node->num_of_apn; i++) + if (strcmp(node->apn[i], sess->pdn.apn) == 0) return true; + + return false; +} + +static ogs_pfcp_node_t *selected_upf_node( + ogs_pfcp_node_t *current, smf_sess_t *sess) +{ + ogs_pfcp_node_t *next, *node; + + ogs_assert(current); + ogs_assert(sess); + + next = ogs_list_next(current); + for (node = next; node; node = ogs_list_next(node)) { + if (OGS_FSM_CHECK(&node->sm, smf_pfcp_state_associated) && + compare_ue_info(node, sess) == true) return node; + } + + for (node = ogs_list_first(&ogs_pfcp_self()->n4_list); + node != next; node = ogs_list_next(node)) { + if (OGS_FSM_CHECK(&node->sm, smf_pfcp_state_associated) && + compare_ue_info(node, sess) == true) return node; + } + + return next ? next : ogs_list_first(&ogs_pfcp_self()->n4_list); +} + + smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, - uint8_t pdn_type, uint8_t ebi, ogs_paa_t *paa, ogs_gtp_create_session_request_t *req) + uint8_t pdn_type, uint8_t ebi, ogs_paa_t *paa, ogs_gtp_uli_t *uli) { ogs_debug("smf_sess_add_by_apn"); smf_event_t e; @@ -615,6 +662,7 @@ smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, ogs_assert(smf_ue); ogs_assert(apn); ogs_assert(paa); + ogs_assert(uli); ogs_pool_alloc(&smf_sess_pool, &sess); if (!sess) { @@ -674,342 +722,30 @@ smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, } else ogs_assert_if_reached(); + memcpy(&sess->e_tai, &uli->tai, sizeof(sess->e_tai)); + memcpy(&sess->e_cgi, &uli->e_cgi, sizeof(sess->e_cgi)); + ogs_info("UE IMSI:[%s] APN:[%s] IPv4:[%s] IPv6:[%s]", sess->imsi_bcd, apn, sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "", sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : ""); - // on first UE connection, initialise at top of UPF (PFCP) list - // for subsequent UE connections, begin from current position + /* + * When used for the first time, if last node is set, + * the search is performed from the first SGW in a round-robin manner. + */ if (ogs_pfcp_self()->node == NULL) - ogs_pfcp_self()->node = ogs_list_first(&ogs_pfcp_self()->n4_list); + ogs_pfcp_self()->node = ogs_list_last(&ogs_pfcp_self()->n4_list); - if (ogs_pfcp_self()->upf_selection_mode == UPF_SELECT_RR) { - /* Select UPF (PFCP) with round-robin manner */ - ogs_debug("Select UPF by RR"); - /* - - starting from list position of last used UPF, search down list for next PFCP associated UPF - - if PFCP associated UPF found - - use it - - if no associated UPF found, keep searching - - if bottom of list reached, reset search to top of list - - if completed full cyclic search of list and still not found a UPF, use default (first) - */ + /* setup GTP session with selected UPF */ + ogs_pfcp_self()->node = selected_upf_node(ogs_pfcp_self()->node, sess); + ogs_assert(ogs_pfcp_self()->node); + OGS_SETUP_PFCP_NODE(sess, ogs_pfcp_self()->node); + ogs_debug("UE using UPF on IP[%s]", + OGS_ADDR(&ogs_pfcp_self()->node->addr, buf)); - int connect=0, numreset=0; - char startUPFIP[OGS_ADDRSTRLEN]; - OGS_ADDR(&ogs_pfcp_self()->node->addr, startUPFIP); - - //search UPF list, find next UPF that is associated - while (!connect) - { - // (when end of UPF (PFCP) list reached, reset search to top of UPF list) - if(ogs_pfcp_self()->node == NULL){ - ogs_pfcp_self()->node = ogs_list_first(&ogs_pfcp_self()->n4_list); - numreset = 1; - } - // search UPF (PFCP) list, find next UPF that is associated - while(ogs_pfcp_self()->node && !connect) { - // if cyclic list check complete and still not found a UPF, break - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - if (numreset == 1 && !strcmp(buf,startUPFIP)) { - break; - } - // has UPF associated over PFCP? - if (OGS_FSM_CHECK( &ogs_pfcp_self()->node->sm, smf_pfcp_state_associated) ){ - // then use it - connect = 1; - } else { - // else check next UPF in list - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - ogs_debug("UPF on IP[%s] is not PFCP associated", - buf); - ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); - } - } - // after checking from the top of the list and not finding a suitable UPF - if (!connect && numreset == 1 ){ - // default to first in list - ogs_error("No UPF (PFCP) is currently PFCP associated"); - ogs_error("Defaulting to first UPF (PFCP) in smf.yaml list"); - ogs_pfcp_self()->node = ogs_list_first(&ogs_pfcp_self()->n4_list); - break; - } - } - - // list UPF used - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - ogs_debug("UE using UPF on IP[%s]", - buf); - - // setup GTP session with selected UPF - ogs_assert(ogs_pfcp_self()->node); - OGS_SETUP_PFCP_NODE(sess, ogs_pfcp_self()->node); - - // iterate to next UPF in list for next UE attach (RR) - ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); - - - } else if (ogs_pfcp_self()->upf_selection_mode == UPF_SELECT_TAC) { - /* Select UPF by eNB/gNB TAC */ - ogs_debug("Select UPF by UE's enb_tac,(RR)"); - /* - - starting from list position of last used UPF, search down list for a UPF that serves the enb_tac **AND** is PFCP associated - - if suitable UPF found - - if PFCP associated - - use it - - else keep searching - - if no suitable UPF found, keep searching - - if bottom of list reached, reset search to top of list - - if completed full cyclic search of list and still not found a UPF, use default (first) - */ - - int i, found=0, numreset=0; - char startUPFIP[OGS_ADDRSTRLEN]; - OGS_ADDR(&ogs_pfcp_self()->node->addr, startUPFIP); - - // fetch the user location information from the incoming S5c request - ogs_gtp_uli_t uli; - ogs_gtp_parse_uli(&uli, &req->user_location_information); - - //ogs_info("UE enb_tac: [%d]", uli.tai.tac); - - //search UPF list, find next UPF that serves the enb_tac **AND** is associated - while (!found) - { - // (when end of UPF (PFCP) list reached, reset search to top of UPF list) - if(ogs_pfcp_self()->node == NULL){ - ogs_pfcp_self()->node = ogs_list_first(&ogs_pfcp_self()->n4_list); - numreset = 1; - } - // search UPF list, find next UPF that serves the enb_tac **AND** is associated - while(ogs_pfcp_self()->node && !found) { - // if cyclic list check complete and still not found a UPF, break - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - if (numreset == 1 && !strcmp(buf,startUPFIP)) { - break; - } - // search from current list position - for (i = 0; i < ogs_pfcp_self()->node->num_of_tac && !found; i++){ - found = ogs_pfcp_self()->node->tac[i] == uli.tai.tac ? 1: 0; - } - if(found){ - // has UPF associated over PFCP? - if (!OGS_FSM_CHECK( &ogs_pfcp_self()->node->sm, smf_pfcp_state_associated )){ - // no - keep searching - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - ogs_warn("UPF on IP[%s] serves enb_tac[%d] - but is **NOT** associated", - buf, uli.tai.tac); - found = 0; - ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); - } else { - // found a UPF that serves the enb_tac **AND** is associated - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - ogs_debug("UPF on IP[%s] serves enb_tac[%d] - and is associated, use it", - buf, uli.tai.tac); - } - } else { - // not found, check next UPF in list - ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); - } - } - // after checking from the top of the list and not finding a suitable UPF - if (!found && numreset == 1 ){ - // default to first in list - ogs_error("No UPF that serves enb_tac[%d] is currently PFCP associated", - uli.tai.tac); - ogs_error("Defaulting to first UPF (PFCP) in smf.yaml list"); - ogs_pfcp_self()->node = ogs_list_first(&ogs_pfcp_self()->n4_list); - break; - } - } - - // list UPF used - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - ogs_debug("UE using UPF on IP[%s]", - buf); - - // setup GTP session with selected UPF - ogs_assert(ogs_pfcp_self()->node); - OGS_SETUP_PFCP_NODE(sess, ogs_pfcp_self()->node); - - // iterate to next UPF in list for next UE attach (RR) - ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); - - } else if (ogs_pfcp_self()->upf_selection_mode == UPF_SELECT_APN) { - /* Select UPF by UE APN */ - ogs_debug("Select UPF by UE's apn,(RR)"); - /* - - starting from list position of last used UPF, search down list for a UPF that serves the UE's APN **AND** is PFCP associated - - if suitable UPF found - - if PFCP associated - - use it - - else keep searching - - if no suitable UPF found, keep searching - - if bottom of list reached, reset search to top of list - - if completed full cyclic search of list and still not found a UPF, use default (first) - */ - - int i, found=0, numreset=0; - char startUPFIP[OGS_ADDRSTRLEN]; - OGS_ADDR(&ogs_pfcp_self()->node->addr, startUPFIP); - - //ogs_info("UE apn: [%s]", apn); - - // search UPF list, find next UPF that serves the ue_apn **AND** is associated - while (!found) - { - // (when end of UPF (PFCP) list reached, reset search to top of UPF list) - if(ogs_pfcp_self()->node == NULL){ - ogs_pfcp_self()->node = ogs_list_first(&ogs_pfcp_self()->n4_list); - numreset = 1; - } - // search UPF list, find next UPF that serves the ue_apn **AND** is associated - while(ogs_pfcp_self()->node && !found) { - // if cyclic list check complete and still not found a UPF, break - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - if (numreset == 1 && !strcmp(buf,startUPFIP)) { - break; - } - // search from current list position - for (i = 0; i < ogs_pfcp_self()->node->num_of_apn && !found; i++){ - found = strncmp( ogs_pfcp_self()->node->apn[i], apn, OGS_MAX_APN_LEN ) ? 0: 1; - } - if(found){ - // has UPF associated over PFCP? - if (!OGS_FSM_CHECK( &ogs_pfcp_self()->node->sm, smf_pfcp_state_associated )){ - // no - keep searching - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - ogs_warn("UPF on IP[%s] serves ue_apn[%s] - but is **NOT** associated", - buf, apn); - found = 0; - ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); - } else { - // found a UPF that serves the ue_apn **AND** is associated - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - ogs_debug("UPF on IP[%s] serves ue_apn[%s] - and is associated, use it", - buf, apn); - } - } else { - // not found, check next UPF in list - ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); - } - } - // after checking from the top of the list and not finding a suitable UPF - if (!found && numreset == 1 ){ - // default to first in list - ogs_error("No UPF that serves ue_apn[%s] is currently PFCP associated", - apn); - ogs_error("Defaulting to first UPF (PFCP) in smf.yaml list"); - ogs_pfcp_self()->node = ogs_list_first(&ogs_pfcp_self()->n4_list); - break; - } - } - - // list UPF used - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - ogs_debug("UE using UPF on IP[%s]", - buf); - - // setup GTP session with selected UPF - ogs_assert(ogs_pfcp_self()->node); - OGS_SETUP_PFCP_NODE(sess, ogs_pfcp_self()->node); - - // iterate to next UPF in list for next UE attach (RR) - ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); - - } else if (ogs_pfcp_self()->upf_selection_mode == UPF_SELECT_ENB_ID) { - /* Select UPF by eNB/gNB ID */ - ogs_debug("Select UPF by UE's enb_id,(RR)"); - /* - - starting from list position of last used UPF, search down list for a UPF that serves the enb_id **AND** is PFCP associated - - if suitable UPF found - - if PFCP associated - - use it - - else keep searching - - if no suitable UPF found, keep searching - - if bottom of list reached, reset search to top of list - - if completed full cyclic search of list and still not found a UPF, use default (first) - */ - - int i, found=0, numreset=0; - char startUPFIP[OGS_ADDRSTRLEN]; - OGS_ADDR(&ogs_pfcp_self()->node->addr, startUPFIP); - - // fetch the user location information from the incoming S5c request - ogs_gtp_uli_t uli; - ogs_gtp_parse_uli(&uli, &req->user_location_information); - - int UE_enb_id = ((uli.e_cgi.cell_id & 0xfffff00) >> 8); //shift 2 bytes right - //int UE_cell_id = (uli.e_cgi.cell_id & 0x00000ff); - // e_cgi.cell_id = [enb_id, cell_id] [20bit, 8bit] - - //ogs_info("UE enb_id: [0x%02x]", UE_enb_id); - - //search UPF list, find next UPF that serves the enb_id **AND** is associated - while (!found) - { - // (when end of UPF (PFCP) list reached, reset search to top of UPF list) - if(ogs_pfcp_self()->node == NULL){ - ogs_pfcp_self()->node = ogs_list_first(&ogs_pfcp_self()->n4_list); - numreset = 1; - } - // search UPF list, find next UPF that serves the enb_id **AND** is associated - while(ogs_pfcp_self()->node && !found) { - // if cyclic list check complete and still not found a UPF, break - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - if (numreset == 1 && !strcmp(buf,startUPFIP)) { - break; - } - // search from current list position - for (i = 0; i < ogs_pfcp_self()->node->num_of_enb_id && !found; i++){ - found = ogs_pfcp_self()->node->enb_id[i] == UE_enb_id ? 1: 0; - } - if(found){ - // has UPF associated over PFCP? - if (!OGS_FSM_CHECK( &ogs_pfcp_self()->node->sm, smf_pfcp_state_associated )){ - // no - keep searching - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - ogs_warn("UPF on IP[%s] serves enb_id[%d]/[0x%02x] - but is **NOT** associated", - buf, UE_enb_id, UE_enb_id); - found = 0; - ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); - } else { - // found a UPF that serves the enb_id **AND** is associated - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - ogs_debug("UPF on IP[%s] serves enb_id[%d]/[0x%02x] - and is associated, use it", - buf, UE_enb_id, UE_enb_id); - } - } else { - // not found, check next UPF in list - ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); - } - } - // after checking from the top of the list and not finding a suitable UPF - if (!found && numreset == 1 ){ - // default to first in list - ogs_error("No UPF that serves enb_id[%d]/[0x%02x] is currently PFCP associated", - UE_enb_id, UE_enb_id); - ogs_error("Defaulting to first UPF (PFCP) in smf.yaml list"); - ogs_pfcp_self()->node = ogs_list_first(&ogs_pfcp_self()->n4_list); - break; - } - } - - // list UPF used - OGS_ADDR(&ogs_pfcp_self()->node->addr, buf); - ogs_debug("UE using UPF on IP[%s]", - buf); - - // setup GTP session with selected UPF - ogs_assert(ogs_pfcp_self()->node); - OGS_SETUP_PFCP_NODE(sess, ogs_pfcp_self()->node); - - // iterate to next UPF in list for next UE attach (RR) - ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); - - } else - ogs_assert_if_reached(); + /* iterate to next UPF in list for next UE attach */ + ogs_pfcp_self()->node = ogs_list_next(ogs_pfcp_self()->node); /* Set Default Bearer */ ogs_list_init(&sess->bearer_list); @@ -1045,6 +781,7 @@ smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp_message_t *message) smf_sess_t *sess = NULL; ogs_paa_t *paa = NULL; char apn[OGS_MAX_APN_LEN]; + ogs_gtp_uli_t uli; ogs_gtp_create_session_request_t *req = &message->create_session_request; @@ -1070,7 +807,12 @@ smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp_message_t *message) } if (req->pdn_address_allocation.presence == 0) { - ogs_error("No PAA Type"); + ogs_error("No PAA"); + return NULL; + } + + if (req->user_location_information.presence == 0) { + ogs_error("No UE Location Information"); return NULL; } @@ -1083,6 +825,8 @@ smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp_message_t *message) paa = (ogs_paa_t *)req->pdn_address_allocation.data; + ogs_gtp_parse_uli(&uli, &req->user_location_information); + /* * 7.2.1 in 3GPP TS 29.274 Release 15 * @@ -1116,7 +860,7 @@ smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp_message_t *message) } sess = smf_sess_add_by_apn(smf_ue, apn, req->pdn_type.u8, - req->bearer_contexts_to_be_created.eps_bearer_id.u8, paa, req); + req->bearer_contexts_to_be_created.eps_bearer_id.u8, paa, &uli); return sess; } @@ -1471,6 +1215,7 @@ smf_bearer_t *smf_bearer_add(smf_sess_t *sess) ul_far->dst_if = OGS_PFCP_INTERFACE_CORE; ogs_pfcp_pdr_associate_far(ul_pdr, ul_far); + ogs_assert(sess->pfcp_node); resource = ogs_pfcp_gtpu_resource_find( &sess->pfcp_node->gtpu_resource_list, sess->pdn.apn, OGS_PFCP_INTERFACE_ACCESS); diff --git a/src/smf/context.h b/src/smf/context.h index c684567ec..85a752fc4 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -176,7 +176,15 @@ typedef struct smf_sess_s { /* PLMN ID & NID */ ogs_plmn_id_t plmn_id; - char *nid; + + /* LTE Location */ + ogs_eps_tai_t e_tai; + ogs_e_cgi_t e_cgi; + + /* NR Location */ + ogs_5gs_tai_t nr_tai; + ogs_nr_cgi_t nr_cgi; + ogs_time_t ue_location_timestamp; /* S_NSSAI & DNN */ ogs_s_nssai_t s_nssai; @@ -297,7 +305,7 @@ smf_ue_t *smf_ue_find_by_imsi(uint8_t *imsi, int imsi_len); smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp_message_t *message); smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn, - uint8_t pdn_type, uint8_t ebi, ogs_paa_t *addr, ogs_gtp_create_session_request_t *message); + uint8_t pdn_type, uint8_t ebi, ogs_paa_t *paa, ogs_gtp_uli_t *uli); smf_sess_t *smf_sess_add_by_sbi_message(ogs_sbi_message_t *message); smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi); diff --git a/src/smf/gsm-sm.c b/src/smf/gsm-sm.c index 7e3422363..4dec04283 100644 --- a/src/smf/gsm-sm.c +++ b/src/smf/gsm-sm.c @@ -77,8 +77,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) smf_nsmf_handle_update_sm_context(sess, sbi_message); break; CASE(OGS_SBI_RESOURCE_NAME_RELEASE) - smf_5gc_pfcp_send_session_deletion_request(sess, - OGS_PFCP_5GC_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT); + smf_nsmf_handle_release_sm_context(sess, sbi_message); break; DEFAULT smf_nsmf_handle_create_sm_context(sess, sbi_message); diff --git a/src/smf/nnrf-handler.c b/src/smf/nnrf-handler.c index 3e9d098ab..57fd6b851 100644 --- a/src/smf/nnrf-handler.c +++ b/src/smf/nnrf-handler.c @@ -66,39 +66,24 @@ void smf_nnrf_handle_nf_status_subscribe( subscription, SubscriptionData->subscription_id); if (SubscriptionData->validity_time) { - struct timeval tv; - struct tm local, next; - ogs_time_t diff, duration; - - memset(&next, 0, sizeof(next)); - if (ogs_strptime(SubscriptionData->validity_time, - OGS_TIME_ISO8601_FORMAT, &next)) { - ogs_gettimeofday(&tv); - ogs_localtime(tv.tv_sec, &local); - diff = ogs_mktime(&next) - ogs_mktime(&local); -#define VALIDITY_MARGIN 5 /* 5 seconds */ -#define VALIDITY_MINIMUM 60 /* 60 seconds */ - duration = diff - (int)VALIDITY_MARGIN; - - if (duration < (int)VALIDITY_MINIMUM) { - char buf[64]; - strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", &local); - ogs_warn("[%s] Validation period [%lld seconds, " - "(%lld)(%lld)(%s)(%s)] is too small", subscription->id, - (long long)diff, - (long long)ogs_mktime(&next), - (long long)ogs_mktime(&local), - SubscriptionData->validity_time, buf); +#define VALIDITY_MARGIN (5 * OGS_USEC_PER_SEC) /* 5 seconds */ +#define VALIDITY_MINIMUM (3600 * OGS_USEC_PER_SEC) /* 3600 seconds */ + ogs_time_t time, duration; + if (ogs_sbi_time_from_string( + &time, SubscriptionData->validity_time) == true) { + duration = time - ogs_time_now() - VALIDITY_MARGIN; + if (duration < VALIDITY_MINIMUM) { duration = VALIDITY_MINIMUM; ogs_warn("[%s] Forced to %d seconds", - subscription->id, VALIDITY_MINIMUM); + subscription->id, (int)ogs_time_sec(VALIDITY_MINIMUM)); } - subscription->t_validity = ogs_timer_add(smf_self()->timer_mgr, smf_timer_subscription_validity, subscription); ogs_assert(subscription->t_validity); - ogs_timer_start( - subscription->t_validity, ogs_time_from_sec(duration)); + ogs_timer_start(subscription->t_validity, duration); + } else { + ogs_error("Cannot parse validitiyTime [%s]", + SubscriptionData->validity_time); } } } @@ -192,8 +177,6 @@ bool smf_nnrf_handle_nf_status_notify( return false; } - smf_sbi_setup_client_callback(nf_instance); - } else if (NotificationData->event == OpenAPI_notification_event_type_NF_DEREGISTERED) { nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); @@ -285,8 +268,6 @@ void smf_nnrf_handle_nf_discover( continue; } - smf_sbi_setup_client_callback(nf_instance); - if (!OGS_SBI_NF_INSTANCE_GET( sbi_object->nf_types, nf_instance->nf_type)) ogs_sbi_nf_types_associate(sbi_object->nf_types, @@ -319,6 +300,6 @@ void smf_nnrf_handle_nf_discover( "(NF discover) No NF", OpenAPI_nf_type_ToString(sbi_object->nf_type)); } else { - ogs_sbi_send(sbi_object, nf_instance); + ogs_sbi_send(nf_instance, sbi_object); } } diff --git a/src/smf/nsmf-handler.c b/src/smf/nsmf-handler.c index cbbf85318..e230a2e46 100644 --- a/src/smf/nsmf-handler.c +++ b/src/smf/nsmf-handler.c @@ -35,6 +35,7 @@ bool smf_nsmf_handle_create_sm_context( ogs_sockaddr_t *addr = NULL; OpenAPI_sm_context_create_data_t *SmContextCreateData = NULL; + OpenAPI_nr_location_t *NrLocation = NULL; OpenAPI_snssai_t *sNssai = NULL; OpenAPI_plmn_id_nid_t *servingNetwork = NULL; OpenAPI_ref_to_binary_data_t *n1SmMsg = NULL; @@ -82,6 +83,31 @@ bool smf_nsmf_handle_create_sm_context( return false; } + if (!SmContextCreateData->ue_location || + !SmContextCreateData->ue_location->nr_location) { + ogs_error("[%s:%d] No UeLocation", smf_ue->supi, sess->psi); + n1smbuf = gsm_build_pdu_session_establishment_reject(sess, + OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION); + smf_sbi_send_sm_context_create_error(session, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + "No UeLocation", smf_ue->supi, n1smbuf); + return false; + } + + NrLocation = SmContextCreateData->ue_location->nr_location; + if (!NrLocation->tai || + !NrLocation->tai->plmn_id || !NrLocation->tai->tac || + !NrLocation->ncgi || + !NrLocation->ncgi->plmn_id || !NrLocation->ncgi->nr_cell_id) { + ogs_error("[%s:%d] No NrLocation", smf_ue->supi, sess->psi); + n1smbuf = gsm_build_pdu_session_establishment_reject(sess, + OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION); + smf_sbi_send_sm_context_create_error(session, + OGS_SBI_HTTP_STATUS_BAD_REQUEST, + "No UeLocation", smf_ue->supi, n1smbuf); + return false; + } + n1SmMsg = SmContextCreateData->n1_sm_msg; if (!n1SmMsg || !n1SmMsg->content_id) { ogs_error("[%s:%d] No n1SmMsg", smf_ue->supi, sess->psi); @@ -129,10 +155,11 @@ bool smf_nsmf_handle_create_sm_context( return false; } - ogs_plmn_id_build(&sess->plmn_id, - atoi(servingNetwork->mcc), atoi(servingNetwork->mnc), - strlen(servingNetwork->mnc)); - sess->nid = servingNetwork->nid; + ogs_sbi_parse_plmn_id_nid(&sess->plmn_id, servingNetwork); + 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, + NrLocation->ue_location_timestamp); sess->s_nssai.sst = sNssai->sst; sess->s_nssai.sd = ogs_s_nssai_sd_from_string(sNssai->sd); @@ -212,6 +239,28 @@ bool smf_nsmf_handle_update_sm_context( return false; } + if (SmContextUpdateData->ue_location && + SmContextUpdateData->ue_location->nr_location) { + OpenAPI_nr_location_t *NrLocation = + SmContextUpdateData->ue_location->nr_location; + if (NrLocation->tai && + NrLocation->tai->plmn_id && NrLocation->tai->tac && + NrLocation->ncgi && + NrLocation->ncgi->plmn_id && NrLocation->ncgi->nr_cell_id) { + + 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, + NrLocation->ue_location_timestamp); + + ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]", + ogs_plmn_id_hexdump(&sess->nr_tai.plmn_id), sess->nr_tai.tac.v); + ogs_debug(" NR_CGI[PLMN_ID:%06x,CELL_ID:0x%llx]", + ogs_plmn_id_hexdump(&sess->nr_cgi.plmn_id), + (long long)sess->nr_cgi.cell_id); + } + } + if (SmContextUpdateData->n1_sm_msg) { n1SmMsg = SmContextUpdateData->n1_sm_msg; if (!n1SmMsg || !n1SmMsg->content_id) { @@ -447,3 +496,44 @@ bool smf_nsmf_handle_update_sm_context( return true; } + +bool smf_nsmf_handle_release_sm_context( + smf_sess_t *sess, ogs_sbi_message_t *message) +{ + OpenAPI_sm_context_release_data_t *SmContextReleaseData = NULL; + + ogs_assert(sess); + ogs_assert(message); + + SmContextReleaseData = message->SmContextReleaseData; + if (SmContextReleaseData) { + if (SmContextReleaseData->ue_location && + SmContextReleaseData->ue_location->nr_location) { + OpenAPI_nr_location_t *NrLocation = + SmContextReleaseData->ue_location->nr_location; + if (NrLocation->tai && + NrLocation->tai->plmn_id && NrLocation->tai->tac && + NrLocation->ncgi && + NrLocation->ncgi->plmn_id && NrLocation->ncgi->nr_cell_id) { + + 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, + NrLocation->ue_location_timestamp); + + ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]", + ogs_plmn_id_hexdump(&sess->nr_tai.plmn_id), + sess->nr_tai.tac.v); + ogs_debug(" NR_CGI[PLMN_ID:%06x,CELL_ID:0x%llx]", + ogs_plmn_id_hexdump(&sess->nr_cgi.plmn_id), + (long long)sess->nr_cgi.cell_id); + } + } + } + + smf_5gc_pfcp_send_session_deletion_request(sess, + OGS_PFCP_5GC_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT); + + return true; +} diff --git a/src/smf/nsmf-handler.h b/src/smf/nsmf-handler.h index 0e544ddaf..03f4f6e59 100644 --- a/src/smf/nsmf-handler.h +++ b/src/smf/nsmf-handler.h @@ -30,6 +30,8 @@ bool smf_nsmf_handle_create_sm_context( smf_sess_t *sess, ogs_sbi_message_t *message); bool smf_nsmf_handle_update_sm_context( smf_sess_t *sess, ogs_sbi_message_t *message); +bool smf_nsmf_handle_release_sm_context( + smf_sess_t *sess, ogs_sbi_message_t *message); #ifdef __cplusplus } diff --git a/src/smf/sbi-path.c b/src/smf/sbi-path.c index 0ed586732..c91e40e1e 100644 --- a/src/smf/sbi-path.c +++ b/src/smf/sbi-path.c @@ -75,19 +75,37 @@ int smf_sbi_open(void) ogs_sbi_server_start_all(server_cb); + /* + * The connection between NF and NRF is a little special. + * + * NF and NRF share nf_instance. I get the NRF EndPoint(client) information + * the configuration file via lib/sbi/context.c. + * And, the NFService information will be transmitted to NRF. + * + * ogs_sbi_self()->nf_instance_id means NF's InstanceId. + */ ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) { ogs_sbi_nf_service_t *service = NULL; + ogs_sbi_client_t *client = NULL; + /* Build NF instance information. It will be transmitted to NRF. */ ogs_sbi_nf_instance_build_default(nf_instance, smf_self()->nf_type); + /* Build NF service information. It will be transmitted to NRF. */ service = ogs_sbi_nf_service_build_default(nf_instance, (char*)OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION); ogs_assert(service); ogs_sbi_nf_service_add_version(service, (char*)OGS_SBI_API_V1, (char*)OGS_SBI_API_V1_0_0, NULL); + /* Client callback is only used when NF sends to NRF */ + client = nf_instance->client; + ogs_assert(client); + client->cb = client_cb; + + /* NFRegister is sent and the response is received + * by the above client callback. */ smf_nf_fsm_init(nf_instance); - smf_sbi_setup_client_callback(nf_instance); } return OGS_OK; @@ -98,24 +116,6 @@ void smf_sbi_close(void) ogs_sbi_server_stop_all(); } -void smf_sbi_setup_client_callback(ogs_sbi_nf_instance_t *nf_instance) -{ - ogs_sbi_client_t *client = NULL; - ogs_sbi_nf_service_t *nf_service = NULL; - ogs_assert(nf_instance); - - client = nf_instance->client; - ogs_assert(client); - - client->cb = client_cb; - - ogs_list_for_each(&nf_instance->nf_service_list, nf_service) { - client = nf_service->client; - if (client) - client->cb = client_cb; - } -} - void smf_sbi_discover_and_send( OpenAPI_nf_type_e nf_type, smf_sess_t *sess, void *data, ogs_sbi_request_t *(*build)(smf_sess_t *sess, void *data)) @@ -135,6 +135,7 @@ void smf_sbi_discover_and_send( sess->sbi.nf_state_registered = smf_nf_state_registered; sess->sbi.client_wait.duration = smf_timer_cfg(SMF_TIMER_SBI_CLIENT_WAIT)->duration; + sess->sbi.client_cb = client_cb; if (ogs_sbi_discover_and_send( nf_type, &sess->sbi, data, (ogs_sbi_build_f)build) != true) { @@ -361,7 +362,6 @@ void smf_sbi_send_sm_context_update_error( ogs_pkbuf_free(n2smbuf); } -#if 0 static int client_notify_cb(ogs_sbi_response_t *response, void *data) { int rv; @@ -386,7 +386,6 @@ static int client_notify_cb(ogs_sbi_response_t *response, void *data) ogs_sbi_response_free(response); return OGS_OK; } -#endif void smf_sbi_send_sm_context_status_notify(smf_sess_t *sess) { @@ -400,6 +399,6 @@ void smf_sbi_send_sm_context_status_notify(smf_sess_t *sess) request = smf_namf_callback_build_sm_context_status(sess, NULL); ogs_assert(request); - ogs_sbi_client_send_request(client, request, NULL); + ogs_sbi_client_send_request(client, client_notify_cb, request, NULL); ogs_sbi_request_free(request); } diff --git a/src/smf/sbi-path.h b/src/smf/sbi-path.h index d115692a4..649f1324f 100644 --- a/src/smf/sbi-path.h +++ b/src/smf/sbi-path.h @@ -32,7 +32,6 @@ extern "C" { int smf_sbi_open(void); void smf_sbi_close(void); -void smf_sbi_setup_client_callback(ogs_sbi_nf_instance_t *nf_instance); void smf_sbi_send(smf_sess_t *sess, ogs_sbi_nf_instance_t *nf_instance); void smf_sbi_discover_and_send( OpenAPI_nf_type_e nf_type, smf_sess_t *sess, void *data, diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c index d3018aa1b..a154b1e8c 100644 --- a/src/smf/smf-sm.c +++ b/src/smf/smf-sm.c @@ -538,6 +538,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) break; DEFAULT + ogs_error("Invalid service name [%s]", sbi_message.h.service.name); + ogs_assert_if_reached(); END ogs_sbi_message_free(&sbi_message); diff --git a/src/udm/context.h b/src/udm/context.h index 6df42fed4..133568544 100644 --- a/src/udm/context.h +++ b/src/udm/context.h @@ -74,8 +74,7 @@ struct udm_ue_s { uint8_t rand[OGS_RAND_LEN]; uint8_t sqn[OGS_SQN_LEN]; - ogs_amf_id_t amf_id; - ogs_plmn_id_t serving_plmn_id; + ogs_guami_t guami; OpenAPI_auth_type_e auth_type; diff --git a/src/udm/nnrf-handler.c b/src/udm/nnrf-handler.c index 7d514b88c..620bd9f3a 100644 --- a/src/udm/nnrf-handler.c +++ b/src/udm/nnrf-handler.c @@ -66,39 +66,24 @@ void udm_nnrf_handle_nf_status_subscribe( subscription, SubscriptionData->subscription_id); if (SubscriptionData->validity_time) { - struct timeval tv; - struct tm local, next; - ogs_time_t diff, duration; - - memset(&next, 0, sizeof(next)); - if (ogs_strptime(SubscriptionData->validity_time, - OGS_TIME_ISO8601_FORMAT, &next)) { - ogs_gettimeofday(&tv); - ogs_localtime(tv.tv_sec, &local); - diff = ogs_mktime(&next) - ogs_mktime(&local); -#define VALIDITY_MARGIN 5 /* 5 seconds */ -#define VALIDITY_MINIMUM 60 /* 60 seconds */ - duration = diff - (int)VALIDITY_MARGIN; - - if (duration < (int)VALIDITY_MINIMUM) { - char buf[64]; - strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", &local); - ogs_warn("[%s] Validation period [%lld seconds, " - "(%lld)(%lld)(%s)(%s)] is too small", subscription->id, - (long long)diff, - (long long)ogs_mktime(&next), - (long long)ogs_mktime(&local), - SubscriptionData->validity_time, buf); +#define VALIDITY_MARGIN (5 * OGS_USEC_PER_SEC) /* 5 seconds */ +#define VALIDITY_MINIMUM (3600 * OGS_USEC_PER_SEC) /* 3600 seconds */ + ogs_time_t time, duration; + if (ogs_sbi_time_from_string( + &time, SubscriptionData->validity_time) == true) { + duration = time - ogs_time_now() - VALIDITY_MARGIN; + if (duration < VALIDITY_MINIMUM) { duration = VALIDITY_MINIMUM; ogs_warn("[%s] Forced to %d seconds", - subscription->id, VALIDITY_MINIMUM); + subscription->id, (int)ogs_time_sec(VALIDITY_MINIMUM)); } - subscription->t_validity = ogs_timer_add(udm_self()->timer_mgr, udm_timer_subscription_validity, subscription); ogs_assert(subscription->t_validity); - ogs_timer_start( - subscription->t_validity, ogs_time_from_sec(duration)); + ogs_timer_start(subscription->t_validity, duration); + } else { + ogs_error("Cannot parse validitiyTime [%s]", + SubscriptionData->validity_time); } } } @@ -192,8 +177,6 @@ bool udm_nnrf_handle_nf_status_notify( return false; } - udm_sbi_setup_client_callback(nf_instance); - } else if (NotificationData->event == OpenAPI_notification_event_type_NF_DEREGISTERED) { nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); @@ -285,8 +268,6 @@ void udm_nnrf_handle_nf_discover( continue; } - udm_sbi_setup_client_callback(nf_instance); - if (!OGS_SBI_NF_INSTANCE_GET( sbi_object->nf_types, nf_instance->nf_type)) ogs_sbi_nf_types_associate(sbi_object->nf_types, @@ -319,6 +300,6 @@ void udm_nnrf_handle_nf_discover( "(NF discover) No NF", OpenAPI_nf_type_ToString(sbi_object->nf_type)); } else { - ogs_sbi_send(sbi_object, nf_instance); + ogs_sbi_send(nf_instance, sbi_object); } } diff --git a/src/udm/nudm-handler.c b/src/udm/nudm-handler.c index 8c53d3957..fd90e06aa 100644 --- a/src/udm/nudm-handler.c +++ b/src/udm/nudm-handler.c @@ -196,8 +196,7 @@ bool udm_nudm_uecm_handle_registration( ogs_sbi_session_t *session = NULL; OpenAPI_amf3_gpp_access_registration_t *Amf3GppAccessRegistration = NULL; - OpenAPI_guami_t *guami = NULL; - OpenAPI_plmn_id_t *serving_plmn_id = NULL; + OpenAPI_guami_t *Guami = NULL; ogs_assert(udm_ue); session = udm_ue->sbi.session; @@ -220,37 +219,36 @@ bool udm_nudm_uecm_handle_registration( return false; } - guami = Amf3GppAccessRegistration->guami; - if (!guami) { + Guami = Amf3GppAccessRegistration->guami; + if (!Guami) { ogs_error("[%s] No Guami", udm_ue->supi); ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_BAD_REQUEST, message, "No Guami", udm_ue->supi); return false; } - if (!guami->amf_id) { + if (!Guami->amf_id) { ogs_error("[%s] No Guami.AmfId", udm_ue->supi); ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_BAD_REQUEST, message, "No Guami.AmfId", udm_ue->supi); return false; } - serving_plmn_id = guami->plmn_id; - if (!serving_plmn_id) { + if (!Guami->plmn_id) { ogs_error("[%s] No PlmnId", udm_ue->supi); ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_BAD_REQUEST, message, "No PlmnId", udm_ue->supi); return false; } - if (!serving_plmn_id->mnc) { + if (!Guami->plmn_id->mnc) { ogs_error("[%s] No PlmnId.Mnc", udm_ue->supi); ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_BAD_REQUEST, message, "No PlmnId.Mnc", udm_ue->supi); return false; } - if (!serving_plmn_id->mcc) { + if (!Guami->plmn_id->mcc) { ogs_error("[%s] No PlmnId.Mcc", udm_ue->supi); ogs_sbi_server_send_error(session, OGS_SBI_HTTP_STATUS_BAD_REQUEST, message, "No PlmnId.Mcc", udm_ue->supi); @@ -262,10 +260,7 @@ bool udm_nudm_uecm_handle_registration( udm_ue->dereg_callback_uri = ogs_strdup( Amf3GppAccessRegistration->dereg_callback_uri); - ogs_amf_id_from_string(&udm_ue->amf_id, guami->amf_id); - ogs_plmn_id_build(&udm_ue->serving_plmn_id, - atoi(serving_plmn_id->mcc), atoi(serving_plmn_id->mnc), - strlen(serving_plmn_id->mnc)); + ogs_sbi_parse_guami(&udm_ue->guami, Guami); udm_ue->amf_3gpp_access_registration = OpenAPI_amf3_gpp_access_registration_copy( diff --git a/src/udm/nudr-build.c b/src/udm/nudr-build.c index c712a45b8..7d481224f 100644 --- a/src/udm/nudr-build.c +++ b/src/udm/nudr-build.c @@ -162,7 +162,7 @@ ogs_sbi_request_t *udm_nudr_dr_build_query_subscription_provisioned( (char *)OGS_SBI_RESOURCE_NAME_SUBSCRIPTION_DATA; sendmsg.h.resource.component[1] = udm_ue->supi; sendmsg.h.resource.component[2] = - (char *)ogs_plmn_id_to_string(&udm_ue->serving_plmn_id, buf); + (char *)ogs_plmn_id_to_string(&udm_ue->guami.plmn_id, buf); sendmsg.h.resource.component[3] = (char *)OGS_SBI_RESOURCE_NAME_PROVISIONED_DATA; sendmsg.h.resource.component[4] = recvmsg->h.resource.component[1]; diff --git a/src/udm/sbi-path.c b/src/udm/sbi-path.c index 29ce90a7b..bfbbd73f0 100644 --- a/src/udm/sbi-path.c +++ b/src/udm/sbi-path.c @@ -73,11 +73,23 @@ int udm_sbi_open(void) ogs_sbi_server_start_all(server_cb); + /* + * The connection between NF and NRF is a little special. + * + * NF and NRF share nf_instance. I get the NRF EndPoint(client) information + * the configuration file via lib/sbi/context.c. + * And, the NFService information will be transmitted to NRF. + * + * ogs_sbi_self()->nf_instance_id means NF's InstanceId. + */ ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) { ogs_sbi_nf_service_t *service = NULL; + ogs_sbi_client_t *client = NULL; + /* Build NF instance information. It will be transmitted to NRF. */ ogs_sbi_nf_instance_build_default(nf_instance, udm_self()->nf_type); + /* Build NF service information. It will be transmitted to NRF. */ service = ogs_sbi_nf_service_build_default(nf_instance, (char*)OGS_SBI_SERVICE_NAME_NUDM_UEAU); ogs_assert(service); @@ -94,8 +106,14 @@ int udm_sbi_open(void) ogs_sbi_nf_service_add_version(service, (char*)OGS_SBI_API_V2, (char*)OGS_SBI_API_V2_0_0, NULL); + /* Client callback is only used when NF sends to NRF */ + client = nf_instance->client; + ogs_assert(client); + client->cb = client_cb; + + /* NFRegister is sent and the response is received + * by the above client callback. */ udm_nf_fsm_init(nf_instance); - udm_sbi_setup_client_callback(nf_instance); } return OGS_OK; @@ -106,24 +124,6 @@ void udm_sbi_close(void) ogs_sbi_server_stop_all(); } -void udm_sbi_setup_client_callback(ogs_sbi_nf_instance_t *nf_instance) -{ - ogs_sbi_client_t *client = NULL; - ogs_sbi_nf_service_t *nf_service = NULL; - ogs_assert(nf_instance); - - client = nf_instance->client; - ogs_assert(client); - - client->cb = client_cb; - - ogs_list_for_each(&nf_instance->nf_service_list, nf_service) { - client = nf_service->client; - if (client) - client->cb = client_cb; - } -} - void udm_sbi_discover_and_send( OpenAPI_nf_type_e nf_type, udm_ue_t *udm_ue, void *data, ogs_sbi_request_t *(*build)(udm_ue_t *udm_ue, void *data)) @@ -138,6 +138,7 @@ void udm_sbi_discover_and_send( udm_ue->sbi.nf_state_registered = udm_nf_state_registered; udm_ue->sbi.client_wait.duration = udm_timer_cfg(UDM_TIMER_SBI_CLIENT_WAIT)->duration; + udm_ue->sbi.client_cb = client_cb; if (ogs_sbi_discover_and_send( nf_type, &udm_ue->sbi, data, (ogs_sbi_build_f)build) != true) { diff --git a/src/udm/sbi-path.h b/src/udm/sbi-path.h index 7faeb5b46..466250e7d 100644 --- a/src/udm/sbi-path.h +++ b/src/udm/sbi-path.h @@ -31,8 +31,6 @@ extern "C" { int udm_sbi_open(void); void udm_sbi_close(void); -void udm_sbi_setup_client_callback(ogs_sbi_nf_instance_t *nf_instance); - void udm_sbi_discover_and_send( OpenAPI_nf_type_e nf_type, udm_ue_t *udm_ue, void *data, ogs_sbi_request_t *(*build)(udm_ue_t *udm_ue, void *data)); diff --git a/src/udr/nnrf-handler.c b/src/udr/nnrf-handler.c index f2cbf06b2..4625abb23 100644 --- a/src/udr/nnrf-handler.c +++ b/src/udr/nnrf-handler.c @@ -66,39 +66,24 @@ void udr_nnrf_handle_nf_status_subscribe( subscription, SubscriptionData->subscription_id); if (SubscriptionData->validity_time) { - struct timeval tv; - struct tm local, next; - ogs_time_t diff, duration; - - memset(&next, 0, sizeof(next)); - if (ogs_strptime(SubscriptionData->validity_time, - OGS_TIME_ISO8601_FORMAT, &next)) { - ogs_gettimeofday(&tv); - ogs_localtime(tv.tv_sec, &local); - diff = ogs_mktime(&next) - ogs_mktime(&local); -#define VALIDITY_MARGIN 5 /* 5 seconds */ -#define VALIDITY_MINIMUM 60 /* 60 seconds */ - duration = diff - (int)VALIDITY_MARGIN; - - if (duration < (int)VALIDITY_MINIMUM) { - char buf[64]; - strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", &local); - ogs_warn("[%s] Validation period [%lld seconds, " - "(%lld)(%lld)(%s)(%s)] is too small", subscription->id, - (long long)diff, - (long long)ogs_mktime(&next), - (long long)ogs_mktime(&local), - SubscriptionData->validity_time, buf); +#define VALIDITY_MARGIN (5 * OGS_USEC_PER_SEC) /* 5 seconds */ +#define VALIDITY_MINIMUM (3600 * OGS_USEC_PER_SEC) /* 3600 seconds */ + ogs_time_t time, duration; + if (ogs_sbi_time_from_string( + &time, SubscriptionData->validity_time) == true) { + duration = time - ogs_time_now() - VALIDITY_MARGIN; + if (duration < VALIDITY_MINIMUM) { duration = VALIDITY_MINIMUM; ogs_warn("[%s] Forced to %d seconds", - subscription->id, VALIDITY_MINIMUM); + subscription->id, (int)ogs_time_sec(VALIDITY_MINIMUM)); } - subscription->t_validity = ogs_timer_add(udr_self()->timer_mgr, udr_timer_subscription_validity, subscription); ogs_assert(subscription->t_validity); - ogs_timer_start( - subscription->t_validity, ogs_time_from_sec(duration)); + ogs_timer_start(subscription->t_validity, duration); + } else { + ogs_error("Cannot parse validitiyTime [%s]", + SubscriptionData->validity_time); } } } @@ -192,8 +177,6 @@ bool udr_nnrf_handle_nf_status_notify( return false; } - udr_sbi_setup_client_callback(nf_instance); - } else if (NotificationData->event == OpenAPI_notification_event_type_NF_DEREGISTERED) { nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id); diff --git a/src/udr/sbi-path.c b/src/udr/sbi-path.c index 06b8a6ac7..4fd2f611c 100644 --- a/src/udr/sbi-path.c +++ b/src/udr/sbi-path.c @@ -73,19 +73,37 @@ int udr_sbi_open(void) ogs_sbi_server_start_all(server_cb); + /* + * The connection between NF and NRF is a little special. + * + * NF and NRF share nf_instance. I get the NRF EndPoint(client) information + * the configuration file via lib/sbi/context.c. + * And, the NFService information will be transmitted to NRF. + * + * ogs_sbi_self()->nf_instance_id means NF's InstanceId. + */ ogs_list_for_each(&ogs_sbi_self()->nf_instance_list, nf_instance) { ogs_sbi_nf_service_t *service = NULL; + ogs_sbi_client_t *client = NULL; + /* Build NF instance information. It will be transmitted to NRF. */ ogs_sbi_nf_instance_build_default(nf_instance, udr_self()->nf_type); + /* Build NF service information. It will be transmitted to NRF. */ service = ogs_sbi_nf_service_build_default(nf_instance, (char*)OGS_SBI_SERVICE_NAME_NUDR_DR); ogs_assert(service); ogs_sbi_nf_service_add_version(service, (char*)OGS_SBI_API_V1, (char*)OGS_SBI_API_V1_0_0, NULL); + /* Client callback is only used when NF sends to NRF */ + client = nf_instance->client; + ogs_assert(client); + client->cb = client_cb; + + /* NFRegister is sent and the response is received + * by the above client callback. */ udr_nf_fsm_init(nf_instance); - udr_sbi_setup_client_callback(nf_instance); } return OGS_OK; @@ -95,21 +113,3 @@ void udr_sbi_close(void) { ogs_sbi_server_stop_all(); } - -void udr_sbi_setup_client_callback(ogs_sbi_nf_instance_t *nf_instance) -{ - ogs_sbi_client_t *client = NULL; - ogs_sbi_nf_service_t *nf_service = NULL; - ogs_assert(nf_instance); - - client = nf_instance->client; - ogs_assert(client); - - client->cb = client_cb; - - ogs_list_for_each(&nf_instance->nf_service_list, nf_service) { - client = nf_service->client; - if (client) - client->cb = client_cb; - } -} diff --git a/src/udr/sbi-path.h b/src/udr/sbi-path.h index c027d2cac..75ac470e0 100644 --- a/src/udr/sbi-path.h +++ b/src/udr/sbi-path.h @@ -29,8 +29,6 @@ extern "C" { int udr_sbi_open(void); void udr_sbi_close(void); -void udr_sbi_setup_client_callback(ogs_sbi_nf_instance_t *nf_instance); - #ifdef __cplusplus } #endif diff --git a/src/upf/gtp-path.c b/src/upf/gtp-path.c index ec8328d16..b31d7d908 100644 --- a/src/upf/gtp-path.c +++ b/src/upf/gtp-path.c @@ -376,7 +376,7 @@ static void upf_gtp_send_to_gnb(ogs_pfcp_far_t *far, ogs_pkbuf_t *sendbuf) gtp_h->teid = htobe32(far->outer_header_creation.teid); /* Send to gNB */ - ogs_debug("[UPF] SEND GPU-U to gNB[%s] : TEID[0x%x]", + ogs_debug("SEND GPU-U to gNB[%s] : TEID[0x%x]", OGS_ADDR(&gnode->addr, buf), far->outer_header_creation.teid); rv = ogs_gtp_sendto(gnode, sendbuf); if (rv != OGS_OK) @@ -478,7 +478,7 @@ static int upf_gtp_handle_slaac(upf_sess_t *sess, ogs_pkbuf_t *recvbuf) struct icmp6_hdr *icmp_h = (struct icmp6_hdr *)(recvbuf->data + sizeof(struct ip6_hdr)); if (icmp_h->icmp6_type == ND_ROUTER_SOLICIT) { - ogs_debug("[UPF] Router Solict"); + ogs_debug(" Router Solict"); if (sess->ipv6) { rv = upf_gtp_send_router_advertisement( sess, ip6_h->ip6_src.s6_addr); @@ -581,7 +581,7 @@ static int upf_gtp_send_router_advertisement( upf_gtp_handle_pdr(pdr, pkbuf); - ogs_debug("[UPF] Router Advertisement"); + ogs_debug(" Router Advertisement"); ogs_pkbuf_free(pkbuf); return rv; diff --git a/src/upf/n4-build.c b/src/upf/n4-build.c index d03c92fd4..cc9de5133 100644 --- a/src/upf/n4-build.c +++ b/src/upf/n4-build.c @@ -33,7 +33,7 @@ ogs_pkbuf_t *upf_n4_build_association_setup_request(uint8_t type) [OGS_PFCP_MAX_USER_PLANE_IP_RESOURCE_INFO_LEN]; int i = 0; - ogs_debug("[UPF] Association Setup Request"); + ogs_debug("Association Setup Request"); req = &pfcp_message.pfcp_association_setup_request; memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); @@ -84,7 +84,7 @@ ogs_pkbuf_t *upf_n4_build_association_setup_response(uint8_t type, [OGS_PFCP_MAX_USER_PLANE_IP_RESOURCE_INFO_LEN]; int i = 0; - ogs_debug("[UPF] Association Setup Response"); + ogs_debug("Association Setup Response"); rsp = &pfcp_message.pfcp_association_setup_response; memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); @@ -136,7 +136,7 @@ ogs_pkbuf_t *upf_n4_build_session_establishment_response(uint8_t type, ogs_pfcp_f_seid_t f_seid; int len = 0; - ogs_debug("[UPF] Session Establishment Response"); + ogs_debug("Session Establishment Response"); rsp = &pfcp_message.pfcp_session_establishment_response; memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); @@ -185,7 +185,7 @@ ogs_pkbuf_t *upf_n4_build_session_modification_response(uint8_t type, int i = 0; - ogs_debug("[UPF] Session Modification Response"); + ogs_debug("Session Modification Response"); rsp = &pfcp_message.pfcp_session_modification_response; memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); @@ -214,7 +214,7 @@ ogs_pkbuf_t *upf_n4_build_session_deletion_response(uint8_t type, ogs_pfcp_message_t pfcp_message; ogs_pfcp_session_deletion_response_t *rsp = NULL; - ogs_debug("[UPF] Session Deletion Response"); + ogs_debug("Session Deletion Response"); rsp = &pfcp_message.pfcp_session_deletion_response; memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); diff --git a/src/upf/n4-handler.c b/src/upf/n4-handler.c index 333fe26a6..c0472e37c 100644 --- a/src/upf/n4-handler.c +++ b/src/upf/n4-handler.c @@ -553,7 +553,7 @@ void upf_n4_handle_session_establishment_request( ogs_assert(xact); ogs_assert(req); - ogs_debug("[UPF] Session Establishment Request"); + ogs_debug("Session Establishment Request"); cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED; @@ -615,7 +615,7 @@ void upf_n4_handle_session_modification_request( ogs_assert(xact); ogs_assert(req); - ogs_debug("[UPF] Session Modification Request"); + ogs_debug("Session Modification Request"); cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED; @@ -711,7 +711,7 @@ void upf_n4_handle_session_deletion_request( ogs_assert(xact); ogs_assert(req); - ogs_debug("[UPF] Session Deletion Request"); + ogs_debug("Session Deletion Request"); if (!sess) { ogs_warn("No Context"); diff --git a/src/upf/rule-match.c b/src/upf/rule-match.c index 44d8e4ad6..335ae451c 100644 --- a/src/upf/rule-match.c +++ b/src/upf/rule-match.c @@ -144,10 +144,10 @@ ogs_pfcp_pdr_t *upf_pdr_find_by_packet(ogs_pkbuf_t *pkt) } else ogs_error("Invalid IP version = %d", ip_h->ip_v); - ogs_debug("[UPF] PROTO:%d SRC:%08x %08x %08x %08x", + ogs_debug("PROTO:%d SRC:%08x %08x %08x %08x", proto, be32toh(src_addr[0]), be32toh(src_addr[1]), be32toh(src_addr[2]), be32toh(src_addr[3])); - ogs_debug("[UPF] HLEN:%d DST:%08x %08x %08x %08x", + ogs_debug("HLEN:%d DST:%08x %08x %08x %08x", ip_hlen, be32toh(dst_addr[0]), be32toh(dst_addr[1]), be32toh(dst_addr[2]), be32toh(dst_addr[3])); @@ -159,18 +159,16 @@ ogs_pfcp_pdr_t *upf_pdr_find_by_packet(ogs_pkbuf_t *pkt) ogs_pfcp_far_t *far = NULL; if (ip_h && sess->ipv4) - ogs_debug("[UPF] PAA IPv4:%s", - OGS_INET_NTOP(&sess->ipv4->addr, buf)); + ogs_debug("PAA IPv4:%s", OGS_INET_NTOP(&sess->ipv4->addr, buf)); if (ip6_h && sess->ipv6) - ogs_debug("[UPF] PAA IPv6:%s", - OGS_INET6_NTOP(&sess->ipv6->addr, buf)); + ogs_debug("PAA IPv6:%s", OGS_INET6_NTOP(&sess->ipv6->addr, buf)); /* Save the default PDR */ default_pdr = ogs_pfcp_sess_default_pdr(&sess->pfcp); ogs_assert(default_pdr); /* Found */ - ogs_debug("[UPF] Found Session : Default PDR-ID[%d]", default_pdr->id); + ogs_debug("Found Session : Default PDR-ID[%d]", default_pdr->id); ogs_list_for_each(&sess->sdf_filter_list, sdf_filter) { int k; @@ -313,7 +311,7 @@ ogs_pfcp_pdr_t *upf_pdr_find_by_packet(ogs_pkbuf_t *pkt) return default_pdr; } else { - ogs_debug("[UPF] No Session"); + ogs_debug("No Session"); } return NULL; diff --git a/tests/00101/issues-482-test.c b/tests/00101/issues-482-test.c index ec646f1b4..41429e3af 100644 --- a/tests/00101/issues-482-test.c +++ b/tests/00101/issues-482-test.c @@ -210,13 +210,13 @@ static void test1_func(abts_case *tc, void *data) test_self()->nr_cgi.cell_id = 0x000000ce7; /* Send Registration request */ - test_ue.registration_request_type.guti = 1; + test_ue.registration_request_param.guti = 1; gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 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); @@ -309,6 +309,11 @@ static void test1_func(abts_case *tc, void *data) testngap_recv(&test_ue, recvbuf); /* Send PDU session establishment request */ + test_sess.ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + test_sess.ul_nas_transport_param.dnn = 1; + test_sess.ul_nas_transport_param.s_nssai = 1; + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, diff --git a/tests/00101/meson.build b/tests/00101/meson.build index 6ab8fd0e8..8dcbe6df7 100644 --- a/tests/00101/meson.build +++ b/tests/00101/meson.build @@ -15,12 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -test00101_sources = files(''' +test5gc_00101_sources = files(''' abts-main.c issues-482-test.c '''.split()) -test00101_exe = executable('00101', - sources : test00101_sources, - c_args : testcore_cc_flags, +test5gc_00101_exe = executable('00101', + sources : test5gc_00101_sources, + c_args : testunit_core_cc_flags, dependencies : libtest5gc_dep) diff --git a/tests/23504/meson.build b/tests/23504/meson.build index dc5b30cd1..3be51d9db 100644 --- a/tests/23504/meson.build +++ b/tests/23504/meson.build @@ -15,12 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -test23504_sources = files(''' +test5gc_23504_sources = files(''' abts-main.c r16-test.c '''.split()) -test23504_exe = executable('23504', - sources : test23504_sources, - c_args : testcore_cc_flags, +test5gc_23504_exe = executable('23504', + sources : test5gc_23504_sources, + c_args : testunit_core_cc_flags, dependencies : libtestepc_dep) diff --git a/tests/common/context.h b/tests/common/context.h index 99b0b7b78..6c1ad7213 100644 --- a/tests/common/context.h +++ b/tests/common/context.h @@ -59,7 +59,7 @@ typedef struct test_context_s { typedef struct test_sess_s test_sess_t; -typedef struct test_registration_request_type_s { +typedef struct test_registration_request_param_s { union { struct { ED8(uint8_t integrity_protected:1;, @@ -78,9 +78,9 @@ typedef struct test_registration_request_type_s { uint16_t uplink_data_status; uint16_t allowed_pdu_session_status; } psimask; -} __attribute__ ((packed)) test_registration_request_type_t; +} __attribute__ ((packed)) test_registration_request_param_t; -typedef struct test_service_request_type_s { +typedef struct test_service_request_param_s { union { struct { ED6(uint8_t integrity_protected:1;, @@ -98,7 +98,19 @@ typedef struct test_service_request_type_s { uint16_t uplink_data_status; uint16_t allowed_pdu_session_status; } psimask; -} __attribute__ ((packed)) test_service_request_type_t; +} __attribute__ ((packed)) test_service_request_param_t; + +typedef struct test_ul_nas_transport_param_s { + union { + struct { + ED4(uint8_t request_type:4;, + uint8_t dnn:1;, + uint8_t s_nssai:1;, + uint8_t reserved:2;) + }; + uint8_t value; + }; +} __attribute__ ((packed)) test_ul_nas_transport_param_t; typedef struct test_ue_s { uint32_t ran_ue_ngap_id; /* eNB-UE-NGAP-ID received from eNB */ @@ -170,8 +182,8 @@ typedef struct test_ue_s { int security_context_available; int mac_failed; - test_registration_request_type_t registration_request_type; - test_service_request_type_t service_request_type; + test_registration_request_param_t registration_request_param; + test_service_request_param_t service_request_param; uint8_t gmm_message_type; /* Last received 5GMM message type */ uint16_t pdu_session_status; @@ -193,6 +205,8 @@ typedef struct test_sess_s { ogs_ip_t gnb_n3_ip; uint32_t gnb_n3_teid; + test_ul_nas_transport_param_t ul_nas_transport_param; + test_ue_t *test_ue; } test_sess_t; diff --git a/tests/common/gmm-build.c b/tests/common/gmm-build.c index b6a49e721..eb8b4ca74 100644 --- a/tests/common/gmm-build.c +++ b/tests/common/gmm-build.c @@ -62,7 +62,7 @@ ogs_pkbuf_t *testgmm_build_registration_request( ogs_assert(sess); memset(&message, 0, sizeof(message)); - if (test_ue->registration_request_type.integrity_protected) { + if (test_ue->registration_request_param.integrity_protected) { message.h.security_header_type = OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED; message.h.extended_protocol_discriminator = @@ -74,7 +74,7 @@ ogs_pkbuf_t *testgmm_build_registration_request( registration_type->data = test_ue->nas.data; - if (test_ue->registration_request_type.guti) { + if (test_ue->registration_request_param.guti) { ogs_nas_5gs_nas_guti_to_mobilty_identity_guti( &test_ue->nas_guti, &mobile_identity_guti); registration_request->mobile_identity.length = @@ -89,34 +89,34 @@ ogs_pkbuf_t *testgmm_build_registration_request( &test_ue->mobile_identity_suci; } - if (test_ue->registration_request_type.uplink_data_status) { + if (test_ue->registration_request_param.uplink_data_status) { registration_request->presencemask |= OGS_NAS_5GS_REGISTRATION_REQUEST_UPLINK_DATA_STATUS_PRESENT; uplink_data_status->length = 2; uplink_data_status->psi |= - test_ue->registration_request_type.psimask.uplink_data_status << 8; + test_ue->registration_request_param.psimask.uplink_data_status << 8; uplink_data_status->psi |= - test_ue->registration_request_type.psimask.uplink_data_status >> 8; + test_ue->registration_request_param.psimask.uplink_data_status >> 8; } - if (test_ue->registration_request_type.pdu_session_status) { + if (test_ue->registration_request_param.pdu_session_status) { registration_request->presencemask |= OGS_NAS_5GS_REGISTRATION_REQUEST_PDU_SESSION_STATUS_PRESENT; pdu_session_status->length = 2; pdu_session_status->psi |= - test_ue->registration_request_type.psimask.pdu_session_status << 8; + test_ue->registration_request_param.psimask.pdu_session_status << 8; pdu_session_status->psi |= - test_ue->registration_request_type.psimask.pdu_session_status >> 8; + test_ue->registration_request_param.psimask.pdu_session_status >> 8; } - if (test_ue->registration_request_type.allowed_pdu_session_status) { + if (test_ue->registration_request_param.allowed_pdu_session_status) { registration_request->presencemask |= OGS_NAS_5GS_REGISTRATION_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT; allowed_pdu_session_status->length = 2; allowed_pdu_session_status->psi |= test_ue-> - registration_request_type.psimask.allowed_pdu_session_status << 8; + registration_request_param.psimask.allowed_pdu_session_status << 8; allowed_pdu_session_status->psi |= test_ue-> - registration_request_type.psimask.allowed_pdu_session_status >> 8; + registration_request_param.psimask.allowed_pdu_session_status >> 8; } registration_request->presencemask |= @@ -144,7 +144,7 @@ ogs_pkbuf_t *testgmm_build_registration_request( s1_ue_network_capability->n1_mode = 1; s1_ue_network_capability->dual_connectivity_with_nr = 1; - if (test_ue->registration_request_type.requested_nssai) { + if (test_ue->registration_request_param.requested_nssai) { /* Set Requested NSSAI */ registration_request->presencemask |= OGS_NAS_5GS_REGISTRATION_REQUEST_REQUESTED_NSSAI_PRESENT; @@ -157,7 +157,7 @@ ogs_pkbuf_t *testgmm_build_registration_request( } } - if (test_ue->registration_request_type.last_visited_registered_tai) { + if (test_ue->registration_request_param.last_visited_registered_tai) { /* Set Last visited registered TAI */ registration_request->presencemask |= OGS_NAS_5GS_REGISTRATION_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT; @@ -166,7 +166,7 @@ ogs_pkbuf_t *testgmm_build_registration_request( last_visited_registered_tai->tac.v = test_self()->tai.tac.v; } - if (test_ue->registration_request_type.ue_usage_setting) { + if (test_ue->registration_request_param.ue_usage_setting) { /* Set UE's usage setting */ registration_request->presencemask |= OGS_NAS_5GS_REGISTRATION_REQUEST_UE_USAGE_SETTING_PRESENT; @@ -182,7 +182,7 @@ ogs_pkbuf_t *testgmm_build_registration_request( ogs_pkbuf_free(nasbuf); } - if (test_ue->registration_request_type.integrity_protected) + if (test_ue->registration_request_param.integrity_protected) return test_nas_5gs_security_encode(test_ue, &message); else return ogs_nas_5gs_plain_encode(&message); @@ -232,11 +232,11 @@ ogs_pkbuf_t *testgmm_build_service_request( uplink_data_status = &service_request->uplink_data_status; memset(&message, 0, sizeof(message)); - if (test_ue->service_request_type.integrity_protected) { + if (test_ue->service_request_param.integrity_protected) { message.h.extended_protocol_discriminator = OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM; - if (test_ue->service_request_type.ciphered) + if (test_ue->service_request_param.ciphered) message.h.security_header_type = OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED; else @@ -248,7 +248,7 @@ ogs_pkbuf_t *testgmm_build_service_request( OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM; message.gmm.h.message_type = OGS_NAS_5GS_SERVICE_REQUEST; - service_request->ngksi.type = test_ue->service_request_type.service_type; + service_request->ngksi.type = test_ue->service_request_param.service_type; service_request->ngksi.tsc = test_ue->nas.tsc; service_request->ngksi.value = test_ue->nas.ksi; @@ -286,37 +286,37 @@ ogs_pkbuf_t *testgmm_build_service_request( ogs_pkbuf_free(nasbuf); } - if (test_ue->service_request_type.uplink_data_status) { + if (test_ue->service_request_param.uplink_data_status) { service_request->presencemask |= OGS_NAS_5GS_SERVICE_REQUEST_UPLINK_DATA_STATUS_PRESENT; uplink_data_status->length = 2; uplink_data_status->psi |= - test_ue->service_request_type.psimask.uplink_data_status << 8; + test_ue->service_request_param.psimask.uplink_data_status << 8; uplink_data_status->psi |= - test_ue->service_request_type.psimask.uplink_data_status >> 8; + test_ue->service_request_param.psimask.uplink_data_status >> 8; } - if (test_ue->service_request_type.pdu_session_status) { + if (test_ue->service_request_param.pdu_session_status) { service_request->presencemask |= OGS_NAS_5GS_SERVICE_REQUEST_PDU_SESSION_STATUS_PRESENT; pdu_session_status->length = 2; pdu_session_status->psi |= - test_ue->service_request_type.psimask.pdu_session_status << 8; + test_ue->service_request_param.psimask.pdu_session_status << 8; pdu_session_status->psi |= - test_ue->service_request_type.psimask.pdu_session_status >> 8; + test_ue->service_request_param.psimask.pdu_session_status >> 8; } - if (test_ue->service_request_type.allowed_pdu_session_status) { + if (test_ue->service_request_param.allowed_pdu_session_status) { service_request->presencemask |= OGS_NAS_5GS_SERVICE_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT; allowed_pdu_session_status->length = 2; allowed_pdu_session_status->psi |= test_ue-> - service_request_type.psimask.allowed_pdu_session_status << 8; + service_request_param.psimask.allowed_pdu_session_status << 8; allowed_pdu_session_status->psi |= test_ue-> - service_request_type.psimask.allowed_pdu_session_status >> 8; + service_request_param.psimask.allowed_pdu_session_status >> 8; } - if (test_ue->service_request_type.integrity_protected) + if (test_ue->service_request_param.integrity_protected) return test_nas_5gs_security_encode(test_ue, &message); else return ogs_nas_5gs_plain_encode(&message); @@ -574,10 +574,7 @@ ogs_pkbuf_t *testgmm_build_ul_nas_transport(test_sess_t *test_sess, ogs_nas_payload_container_t *payload_container = NULL; ogs_nas_pdu_session_identity_2_t *pdu_session_id = NULL; ogs_nas_request_type_t *request_type = NULL; -#define S_NSSAI_PRECENSE 0 -#if S_NSSAI_PRECENSE ogs_nas_s_nssai_t *nas_s_nssai = NULL; -#endif ogs_assert(test_sess); test_ue = test_sess->test_ue; @@ -589,9 +586,7 @@ ogs_pkbuf_t *testgmm_build_ul_nas_transport(test_sess_t *test_sess, payload_container = &ul_nas_transport->payload_container; pdu_session_id = &ul_nas_transport->pdu_session_id; request_type = &ul_nas_transport->request_type; -#if S_NSSAI_PRECENSE nas_s_nssai = &ul_nas_transport->s_nssai; -#endif memset(&message, 0, sizeof(message)); message.h.security_header_type = @@ -612,22 +607,26 @@ ogs_pkbuf_t *testgmm_build_ul_nas_transport(test_sess_t *test_sess, OGS_NAS_5GS_UL_NAS_TRANSPORT_PDU_SESSION_ID_PRESENT; *pdu_session_id = test_sess->psi; - ul_nas_transport->presencemask |= - OGS_NAS_5GS_UL_NAS_TRANSPORT_REQUEST_TYPE_PRESENT; - request_type->value = OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + if (test_sess->ul_nas_transport_param.request_type) { + ul_nas_transport->presencemask |= + OGS_NAS_5GS_UL_NAS_TRANSPORT_REQUEST_TYPE_PRESENT; + request_type->value = test_sess->ul_nas_transport_param.request_type; + } -#if S_NSSAI_PRECENSE - ul_nas_transport->presencemask |= - OGS_NAS_5GS_UL_NAS_TRANSPORT_S_NSSAI_PRESENT; - ogs_nas_build_s_nssai( - nas_s_nssai, &test_self()->plmn_support[0].s_nssai[0]); -#endif + if (test_sess->ul_nas_transport_param.s_nssai) { + ul_nas_transport->presencemask |= + OGS_NAS_5GS_UL_NAS_TRANSPORT_S_NSSAI_PRESENT; + ogs_nas_build_s_nssai( + nas_s_nssai, &test_self()->plmn_support[0].s_nssai[0]); + } - ul_nas_transport->presencemask |= - OGS_NAS_5GS_UL_NAS_TRANSPORT_DNN_PRESENT; - ul_nas_transport->dnn.length = strlen(test_sess->dnn); - ogs_cpystrn(ul_nas_transport->dnn.value, test_sess->dnn, - ogs_min(ul_nas_transport->dnn.length, OGS_MAX_DNN_LEN) + 1); + if (test_sess->ul_nas_transport_param.dnn) { + ul_nas_transport->presencemask |= + OGS_NAS_5GS_UL_NAS_TRANSPORT_DNN_PRESENT; + ul_nas_transport->dnn.length = strlen(test_sess->dnn); + ogs_cpystrn(ul_nas_transport->dnn.value, test_sess->dnn, + ogs_min(ul_nas_transport->dnn.length, OGS_MAX_DNN_LEN) + 1); + } pkbuf = test_nas_5gs_security_encode(test_ue, &message); ogs_pkbuf_free(payload); diff --git a/tests/common/meson.build b/tests/common/meson.build index de3ea8a57..417e06d4a 100644 --- a/tests/common/meson.build +++ b/tests/common/meson.build @@ -43,7 +43,7 @@ libtestcommon_inc = include_directories('.') libtestcommon = static_library('testcomon', sources : libtestcommon_sources, - c_args : testcore_cc_flags, + c_args : testunit_core_cc_flags, include_directories : [libtestcommon_inc, testinc, srcinc], dependencies : [libcore_dep, libapp_dep, diff --git a/tests/core/list-test.c b/tests/core/list-test.c index a97f721b9..6e298d753 100644 --- a/tests/core/list-test.c +++ b/tests/core/list-test.c @@ -315,6 +315,109 @@ static void list_test5(abts_case *tc, void *data) } } +lt_type1 *find_rr(lt_type1 *current, int m1) +{ + lt_type1 *next, *node; + + ogs_assert(current); + + next = ogs_list_next(current); + for (node = next; node; node = ogs_list_next(node)) { + if (node->m1 == m1) return node; + } + + for (node = ogs_list_first(&tlist1); + node != next; node = ogs_list_next(node)) { + if (node->m1 == m1) return node; + } + + return next ? next : ogs_list_first(&tlist1); +} + +static void list_test6(abts_case *tc, void *data) +{ + int i; + lt_type1 *iter, *tmp, node[SIZE_OF_lt_type1]; + + for (i = 0; i < SIZE_OF_lt_type1; i++) + node[i].m1 = i/3; + + ogs_list_init(&tlist1); + + for (i = 0; i < 10; i++) + ogs_list_add(&tlist1, &node[i]); + ABTS_INT_EQUAL(tc, 10, ogs_list_count(&tlist1)); + + iter = ogs_list_last(&tlist1); + ABTS_INT_EQUAL(tc, 3, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 0, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 0, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 0, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 1, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 1, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 1, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 3, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 0, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 0, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 0, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 1, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 1, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 1, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 3, iter->m1); + iter = find_rr(iter, 2); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 2); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 3); + ABTS_INT_EQUAL(tc, 3, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 0, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 0, iter->m1); + iter = find_rr(iter, 2); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 3); + ABTS_INT_EQUAL(tc, 3, iter->m1); + iter = find_rr(iter, 0); + ABTS_INT_EQUAL(tc, 0, iter->m1); + iter = find_rr(iter, 2); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 2, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 3, iter->m1); + iter = find_rr(iter, 9); + ABTS_INT_EQUAL(tc, 0, iter->m1); +} + abts_suite *test_list(abts_suite *suite) { suite = ADD_SUITE(suite) @@ -324,6 +427,7 @@ abts_suite *test_list(abts_suite *suite) abts_run_test(suite, list_test3, NULL); abts_run_test(suite, list_test4, NULL); abts_run_test(suite, list_test5, NULL); + abts_run_test(suite, list_test6, NULL); return suite; } diff --git a/tests/core/meson.build b/tests/core/meson.build index 155b553ec..d605d0656 100644 --- a/tests/core/meson.build +++ b/tests/core/meson.build @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -testcore_sources = files(''' +testunit_core_sources = files(''' list-test.c pool-test.c strings-test.c @@ -37,9 +37,9 @@ testcore_sources = files(''' abts-main.c '''.split()) -testcore_cc_flags = [] +testunit_core_cc_flags = [] if cc.get_id() == 'gcc' or cc.get_id() == 'clang' - testcore_cc_flags += cc.get_supported_arguments([ + testunit_core_cc_flags += cc.get_supported_arguments([ '-Wno-missing-prototypes', '-Wno-missing-declarations', '-Wno-discarded-qualifiers', @@ -48,9 +48,9 @@ if cc.get_id() == 'gcc' or cc.get_id() == 'clang' '-Wno-deprecated-declarations']) endif -testcore_exe = executable('core', - sources : testcore_sources, - c_args : testcore_cc_flags, +testunit_core_exe = executable('core', + sources : testunit_core_sources, + c_args : testunit_core_cc_flags, dependencies : libcore_dep) -test('core', testcore_exe, is_parallel : false, suite: 'unit') +test('core', testunit_core_exe, is_parallel : false, suite: 'unit') diff --git a/tests/core/time-test.c b/tests/core/time-test.c index 46a9935cc..49e1439b7 100644 --- a/tests/core/time-test.c +++ b/tests/core/time-test.c @@ -20,6 +20,9 @@ #include "ogs-core.h" #include "core/abts.h" +/* 2002-09-14 12:05:36.186711 -25200 [257 Sat]. */ +static ogs_time_t now = 1032030336186711L; + static void test_now(abts_case *tc, void *data) { struct timeval tv; @@ -38,21 +41,63 @@ static void test_now(abts_case *tc, void *data) #define STR_SIZE 100 -static void test_strftime(abts_case *tc, void *data) +static void test_gmtstr(abts_case *tc, void *data) { struct tm tm; - char str[STR_SIZE+1]; - time_t now = (time_t)1542100786; + char *str = NULL; - ogs_gmtime(now, &tm); - strftime(str, sizeof str, "%Y/%m/%d %H:%M:%S", &tm); - ABTS_STR_EQUAL(tc, "2018/11/13 09:19:46", str); + char datetime[STR_SIZE]; - ogs_localtime(now, &tm); - strftime(str, sizeof str, "%Y/%m/%d %H:%M:%S", &tm); -#if 0 /* FIXME */ - ABTS_STR_EQUAL(tc, "2018/11/13 18:19:46", str); -#endif + ogs_gmtime(ogs_time_sec(now), &tm); + ogs_strftime(datetime, sizeof datetime, "%Y-%m-%dT%H:%M:%S", &tm); + + str = ogs_msprintf("%s.%06lldZ", + datetime, (long long)ogs_time_usec(now)); + ogs_assert(str); + + ABTS_STR_EQUAL(tc, "2002-09-14T19:05:36.186711Z", str); + + ogs_free(str); +} + +static void test_get_gmt(abts_case *tc, void *data) +{ + int rv; + struct tm xt; + ogs_time_t imp; + int64_t hr_off_64; + + ogs_gmtime(ogs_time_sec(now), &xt); + rv = ogs_time_from_lt(&imp, &xt, ogs_time_usec(now)); + ABTS_TRUE(tc, rv == OGS_OK); + hr_off_64 = (int64_t) xt.tm_gmtoff * OGS_USEC_PER_SEC; + ABTS_TRUE(tc, now + hr_off_64 == imp); +} + +static void test_get_lt(abts_case *tc, void *data) +{ + int rv; + struct tm xt; + ogs_time_t imp; + int64_t hr_off_64; + + ogs_localtime(ogs_time_sec(now), &xt); + rv = ogs_time_from_lt(&imp, &xt, ogs_time_usec(now)); + ABTS_TRUE(tc, rv == OGS_OK); + hr_off_64 = (int64_t) xt.tm_gmtoff * OGS_USEC_PER_SEC; + ABTS_TRUE(tc, now + hr_off_64 == imp); +} + +static void test_imp_gmt(abts_case *tc, void *data) +{ + int rv; + struct tm xt; + ogs_time_t imp; + + ogs_gmtime(ogs_time_sec(now), &xt); + rv = ogs_time_from_gmt(&imp, &xt, ogs_time_usec(now)); + ABTS_TRUE(tc, rv == OGS_OK); + ABTS_TRUE(tc, now == imp); } abts_suite *test_time(abts_suite *suite) @@ -60,7 +105,10 @@ abts_suite *test_time(abts_suite *suite) suite = ADD_SUITE(suite) abts_run_test(suite, test_now, NULL); - abts_run_test(suite, test_strftime, NULL); + abts_run_test(suite, test_gmtstr, NULL); + abts_run_test(suite, test_get_gmt, NULL); + abts_run_test(suite, test_get_lt, NULL); + abts_run_test(suite, test_imp_gmt, NULL); return suite; } diff --git a/tests/crypt/meson.build b/tests/crypt/meson.build index 8b16f8eb5..3946954e6 100644 --- a/tests/crypt/meson.build +++ b/tests/crypt/meson.build @@ -15,16 +15,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -testcrypt_sources = files(''' +testunit_crypt_sources = files(''' aes-test.c sha-test.c base64-test.c abts-main.c '''.split()) -testcrypt_exe = executable('crypt', - sources : testcrypt_sources, - c_args : testcore_cc_flags, +testunit_crypt_exe = executable('crypt', + sources : testunit_crypt_sources, + c_args : testunit_core_cc_flags, dependencies : libcrypt_dep) -test('crypt', testcrypt_exe, is_parallel : false, suite: 'unit') +test('crypt', testunit_crypt_exe, is_parallel : false, suite: 'unit') diff --git a/tests/csfb/meson.build b/tests/csfb/meson.build index 40d5e66f1..67e98ac7f 100644 --- a/tests/csfb/meson.build +++ b/tests/csfb/meson.build @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -testcsfb_sources = files(''' +testepc_csfb_sources = files(''' abts-main.c mo-idle-test.c mt-idle-test.c @@ -26,9 +26,9 @@ testcsfb_sources = files(''' crash-test.c '''.split()) -testcsfb_exe = executable('csfb', - sources : testcsfb_sources, - c_args : testcore_cc_flags, +testepc_csfb_exe = executable('csfb', + sources : testepc_csfb_sources, + c_args : testunit_core_cc_flags, dependencies : libtestepc_dep) -test('csfb', testcsfb_exe, is_parallel : false, suite: 'epc') +test('csfb', testepc_csfb_exe, is_parallel : false, suite: 'epc') diff --git a/tests/cups/meson.build b/tests/cups/meson.build index 6db152471..2f7702dd6 100644 --- a/tests/cups/meson.build +++ b/tests/cups/meson.build @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -testcups_sources = files(''' +test5gc_cups_sources = files(''' pcscf-fd-path.h pcscf-fd-path.c @@ -23,10 +23,10 @@ testcups_sources = files(''' cups-test.c '''.split()) -testcups_exe = executable('cups', - sources : testcups_sources, - c_args : [testcore_cc_flags, +test5gc_cups_exe = executable('cups', + sources : test5gc_cups_sources, + c_args : [testunit_core_cc_flags, '-DFD_EXT_DIR="@0@"'.format(freediameter_extensions_builddir)], dependencies : libtestepc_dep) -test('cups', testcups_exe, is_parallel : false, suite: '5gc') +test('cups', test5gc_cups_exe, is_parallel : false, suite: '5gc') diff --git a/tests/epc-simple/abts-main.c b/tests/epc/abts-main.c similarity index 100% rename from tests/epc-simple/abts-main.c rename to tests/epc/abts-main.c diff --git a/tests/epc-simple/attach-test.c b/tests/epc/attach-test.c similarity index 100% rename from tests/epc-simple/attach-test.c rename to tests/epc/attach-test.c diff --git a/tests/epc-simple/crash-test.c b/tests/epc/crash-test.c similarity index 100% rename from tests/epc-simple/crash-test.c rename to tests/epc/crash-test.c diff --git a/tests/epc-simple/handover-test.c b/tests/epc/handover-test.c similarity index 100% rename from tests/epc-simple/handover-test.c rename to tests/epc/handover-test.c diff --git a/tests/epc-simple/meson.build b/tests/epc/meson.build similarity index 80% rename from tests/epc-simple/meson.build rename to tests/epc/meson.build index 39cfdeda0..5c34f642f 100644 --- a/tests/epc-simple/meson.build +++ b/tests/epc/meson.build @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -testepc_simple_sources = files(''' +testepc_epc_sources = files(''' abts-main.c s1setup-test.c attach-test.c @@ -25,9 +25,9 @@ testepc_simple_sources = files(''' '''.split()) -testepc_simple_exe = executable('simple', - sources : testepc_simple_sources, - c_args : testcore_cc_flags, +testepc_epc_exe = executable('epc', + sources : testepc_epc_sources, + c_args : testunit_core_cc_flags, dependencies : libtestepc_dep) -test('simple', testepc_simple_exe, is_parallel : false, suite: 'epc') +test('epc', testepc_epc_exe, is_parallel : false, suite: 'epc') diff --git a/tests/epc-simple/s1setup-test.c b/tests/epc/s1setup-test.c similarity index 100% rename from tests/epc-simple/s1setup-test.c rename to tests/epc/s1setup-test.c diff --git a/tests/epc-simple/volte-test.c b/tests/epc/volte-test.c similarity index 100% rename from tests/epc-simple/volte-test.c rename to tests/epc/volte-test.c diff --git a/tests/meson.build b/tests/meson.build index 7423acd77..e1777fbf1 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -23,7 +23,7 @@ subdir('sctp') subdir('common') subdir('app') subdir('unit') -subdir('epc-simple') +subdir('epc') subdir('mnc3') subdir('volte') subdir('csfb') diff --git a/tests/minimal/meson.build b/tests/minimal/meson.build index 5fd3ac602..d5d0a64f2 100644 --- a/tests/minimal/meson.build +++ b/tests/minimal/meson.build @@ -15,12 +15,12 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -testminimal_sources = files(''' +test5gc_minimal_sources = files(''' abts-main.c minimal-test.c '''.split()) -testminimal_exe = executable('minimal', - sources : testminimal_sources, - c_args : testcore_cc_flags, +test5gc_minimal_exe = executable('minimal', + sources : test5gc_minimal_sources, + c_args : testunit_core_cc_flags, dependencies : libtest5gc_dep) diff --git a/tests/minimal/minimal-test.c b/tests/minimal/minimal-test.c index a016aaf88..3a513c575 100644 --- a/tests/minimal/minimal-test.c +++ b/tests/minimal/minimal-test.c @@ -257,6 +257,11 @@ static void test1_func(abts_case *tc, void *data) testngap_recv(&test_ue, recvbuf); /* Send PDU session establishment request */ + test_sess.ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + test_sess.ul_nas_transport_param.dnn = 1; + test_sess.ul_nas_transport_param.s_nssai = 1; + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, diff --git a/tests/mnc3/meson.build b/tests/mnc3/meson.build index 83cfd8b28..d19f76a38 100644 --- a/tests/mnc3/meson.build +++ b/tests/mnc3/meson.build @@ -15,14 +15,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -testmnc3_sources = files(''' +testepc_mnc3_sources = files(''' abts-main.c mnc3-test.c '''.split()) -testmnc3_exe = executable('mnc3', - sources : testmnc3_sources, - c_args : testcore_cc_flags, +testepc_mnc3_exe = executable('mnc3', + sources : testepc_mnc3_sources, + c_args : testunit_core_cc_flags, dependencies : libtestepc_dep) -test('mnc3', testmnc3_exe, is_parallel : false, suite: 'epc') +test('mnc3', testepc_mnc3_exe, is_parallel : false, suite: 'epc') diff --git a/tests/registration/dereg-test.c b/tests/registration/dereg-test.c index e1b42188c..eea250861 100644 --- a/tests/registration/dereg-test.c +++ b/tests/registration/dereg-test.c @@ -212,9 +212,9 @@ static void test1_func(abts_case *tc, void *data) gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 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); @@ -290,6 +290,11 @@ static void test1_func(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, OGS_OK, rv); /* Send PDU session establishment request */ + test_sess.ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + test_sess.ul_nas_transport_param.dnn = 1; + test_sess.ul_nas_transport_param.s_nssai = 1; + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, @@ -566,9 +571,9 @@ static void test2_func(abts_case *tc, void *data) gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 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); @@ -644,6 +649,11 @@ static void test2_func(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, OGS_OK, rv); /* Send PDU session establishment request */ + test_sess.ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + test_sess.ul_nas_transport_param.dnn = 1; + test_sess.ul_nas_transport_param.s_nssai = 1; + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, @@ -692,6 +702,10 @@ static void test2_func(abts_case *tc, void *data) ogs_msleep(100); /* Send PDU Session release request */ + test_sess.ul_nas_transport_param.request_type = 0; + test_sess.ul_nas_transport_param.dnn = 0; + test_sess.ul_nas_transport_param.s_nssai = 0; + gsmbuf = testgsm_build_pdu_session_release_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, @@ -716,6 +730,10 @@ static void test2_func(abts_case *tc, void *data) ogs_msleep(100); /* Send PDU session resource release complete */ + test_sess.ul_nas_transport_param.request_type = 0; + test_sess.ul_nas_transport_param.dnn = 0; + test_sess.ul_nas_transport_param.s_nssai = 0; + gsmbuf = testgsm_build_pdu_session_release_complete(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, diff --git a/tests/registration/gmm-status-test.c b/tests/registration/gmm-status-test.c index b7da8ddd9..a75bfe22f 100644 --- a/tests/registration/gmm-status-test.c +++ b/tests/registration/gmm-status-test.c @@ -208,9 +208,9 @@ static void test1_func(abts_case *tc, void *data) gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 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); @@ -278,6 +278,11 @@ static void test1_func(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, OGS_OK, rv); /* Send PDU session establishment request */ + test_sess.ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + test_sess.ul_nas_transport_param.dnn = 1; + test_sess.ul_nas_transport_param.s_nssai = 1; + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, diff --git a/tests/registration/guti-test.c b/tests/registration/guti-test.c index 17c6392b6..25b0f63a7 100644 --- a/tests/registration/guti-test.c +++ b/tests/registration/guti-test.c @@ -205,13 +205,13 @@ static void test1_func(abts_case *tc, void *data) bson_destroy(doc); /* Send Registration request */ - test_ue.registration_request_type.guti = 1; + test_ue.registration_request_param.guti = 1; gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 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); @@ -298,6 +298,11 @@ static void test1_func(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, OGS_OK, rv); /* Send PDU session establishment request */ + test_sess.ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + test_sess.ul_nas_transport_param.dnn = 1; + test_sess.ul_nas_transport_param.s_nssai = 1; + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, @@ -350,15 +355,15 @@ static void test1_func(abts_case *tc, void *data) OGS_NAS_5GS_REGISTRATION_TYPE_MOBILITY_UPDATING; /* Send Registration request : Uplink Data Status */ - test_ue.registration_request_type.integrity_protected = 0; - test_ue.registration_request_type.uplink_data_status = 1; - test_ue.registration_request_type.psimask.uplink_data_status = + test_ue.registration_request_param.integrity_protected = 0; + test_ue.registration_request_param.uplink_data_status = 1; + test_ue.registration_request_param.psimask.uplink_data_status = 1 << test_sess.psi; nasbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, nasbuf); - test_ue.registration_request_type.integrity_protected = 1; - test_ue.registration_request_type.uplink_data_status = 0; + test_ue.registration_request_param.integrity_protected = 1; + test_ue.registration_request_param.uplink_data_status = 0; gmmbuf = testgmm_build_registration_request(&test_ue, nasbuf); ABTS_PTR_NOTNULL(tc, gmmbuf); @@ -402,8 +407,8 @@ static void test1_func(abts_case *tc, void *data) gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.integrity_protected = 0; - test_ue.registration_request_type.uplink_data_status = 0; + test_ue.registration_request_param.integrity_protected = 0; + test_ue.registration_request_param.uplink_data_status = 0; nasbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, nasbuf); @@ -484,6 +489,11 @@ static void test1_func(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, OGS_OK, rv); /* Send PDU session establishment request */ + test_sess.ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + test_sess.ul_nas_transport_param.dnn = 1; + test_sess.ul_nas_transport_param.s_nssai = 1; + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, diff --git a/tests/registration/identity-test.c b/tests/registration/identity-test.c index 0a1c4f4af..c22d32807 100644 --- a/tests/registration/identity-test.c +++ b/tests/registration/identity-test.c @@ -208,9 +208,9 @@ static void test1_func(abts_case *tc, void *data) gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 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); @@ -284,6 +284,11 @@ static void test1_func(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, OGS_OK, rv); /* Send PDU session establishment request */ + test_sess.ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + test_sess.ul_nas_transport_param.dnn = 1; + test_sess.ul_nas_transport_param.s_nssai = 1; + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, @@ -314,9 +319,9 @@ static void test1_func(abts_case *tc, void *data) OGS_NAS_5GS_REGISTRATION_TYPE_MOBILITY_UPDATING; /* Send Registration request */ - test_ue.registration_request_type.integrity_protected = 1; - test_ue.registration_request_type.guti = 1; - test_ue.registration_request_type.uplink_data_status = 1; + test_ue.registration_request_param.integrity_protected = 1; + test_ue.registration_request_param.guti = 1; + test_ue.registration_request_param.uplink_data_status = 1; gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); diff --git a/tests/registration/idle-test.c b/tests/registration/idle-test.c index 59eeaa08e..2c0ae470a 100644 --- a/tests/registration/idle-test.c +++ b/tests/registration/idle-test.c @@ -208,9 +208,9 @@ static void test1_func(abts_case *tc, void *data) gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 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); @@ -284,6 +284,11 @@ static void test1_func(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, OGS_OK, rv); /* Send PDU session establishment request */ + test_sess.ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + test_sess.ul_nas_transport_param.dnn = 1; + test_sess.ul_nas_transport_param.s_nssai = 1; + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, @@ -360,15 +365,15 @@ static void test1_func(abts_case *tc, void *data) * Send Service request Using InitialUEMessage * - PDU Session Status */ - test_ue.service_request_type.integrity_protected = 0; - test_ue.service_request_type.pdu_session_status = 1; - test_ue.service_request_type.psimask.pdu_session_status = + test_ue.service_request_param.integrity_protected = 0; + test_ue.service_request_param.pdu_session_status = 1; + test_ue.service_request_param.psimask.pdu_session_status = 1 << test_sess.psi; nasbuf = testgmm_build_service_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, nasbuf); - test_ue.service_request_type.integrity_protected = 1; - test_ue.service_request_type.pdu_session_status = 0; + test_ue.service_request_param.integrity_protected = 1; + test_ue.service_request_param.pdu_session_status = 0; gmmbuf = testgmm_build_service_request(&test_ue, nasbuf); ABTS_PTR_NOTNULL(tc, gmmbuf); @@ -438,17 +443,17 @@ static void test1_func(abts_case *tc, void *data) * Send Service request Using InitialUEMessage * - Uplink Data Status */ - test_ue.service_request_type.integrity_protected = 0; - test_ue.service_request_type.uplink_data_status = 1; - test_ue.service_request_type. + 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 << test_sess.psi; - test_ue.service_request_type.pdu_session_status = 0; + 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_type.integrity_protected = 1; - test_ue.service_request_type.uplink_data_status = 0; - test_ue.service_request_type.pdu_session_status = 0; + 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); @@ -699,9 +704,9 @@ static void test2_func(abts_case *tc, void *data) gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 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); @@ -801,13 +806,13 @@ static void test2_func(abts_case *tc, void *data) * Send Service request Using InitialUEMessage * - PDU Session Status */ - test_ue.service_request_type.integrity_protected = 0; - test_ue.service_request_type.pdu_session_status = 1; + test_ue.service_request_param.integrity_protected = 0; + test_ue.service_request_param.pdu_session_status = 1; nasbuf = testgmm_build_service_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, nasbuf); - test_ue.service_request_type.integrity_protected = 1; - test_ue.service_request_type.pdu_session_status = 0; + test_ue.service_request_param.integrity_protected = 1; + 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); @@ -1038,9 +1043,9 @@ static void test3_func(abts_case *tc, void *data) gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 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); @@ -1116,6 +1121,11 @@ static void test3_func(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, OGS_OK, rv); /* Send PDU session establishment request */ + test_sess.ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + test_sess.ul_nas_transport_param.dnn = 1; + test_sess.ul_nas_transport_param.s_nssai = 1; + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, @@ -1168,19 +1178,19 @@ static void test3_func(abts_case *tc, void *data) * - Uplink Data Status * - PDU Session Status */ - test_ue.service_request_type.integrity_protected = 0; - test_ue.service_request_type.uplink_data_status = 1; - test_ue.service_request_type.psimask.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 << test_sess.psi; - test_ue.service_request_type.pdu_session_status = 1; - test_ue.service_request_type.psimask.pdu_session_status = + test_ue.service_request_param.pdu_session_status = 1; + test_ue.service_request_param.psimask.pdu_session_status = 1 << test_sess.psi; nasbuf = testgmm_build_service_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, nasbuf); - test_ue.service_request_type.integrity_protected = 1; - test_ue.service_request_type.uplink_data_status = 0; - test_ue.service_request_type.pdu_session_status = 0; + 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); @@ -1218,10 +1228,10 @@ static void test3_func(abts_case *tc, void *data) * Send Service request Using UplinkNASTransport * - Uplink Data Status */ - test_ue.service_request_type.integrity_protected = 1; - test_ue.service_request_type.ciphered = 1; - test_ue.service_request_type.uplink_data_status = 1; - test_ue.service_request_type.psimask.uplink_data_status = + test_ue.service_request_param.integrity_protected = 1; + test_ue.service_request_param.ciphered = 1; + test_ue.service_request_param.uplink_data_status = 1; + test_ue.service_request_param.psimask.uplink_data_status = 1 << test_sess.psi; gmmbuf = testgmm_build_service_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); @@ -1459,13 +1469,13 @@ static void test4_func(abts_case *tc, void *data) bson_destroy(doc); /* Send Registration request */ - test_ue.registration_request_type.guti = 1; + test_ue.registration_request_param.guti = 1; gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 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); @@ -1578,13 +1588,13 @@ static void test4_func(abts_case *tc, void *data) * Send Service request Using InitialUEMessage * - PDU Session Status */ - test_ue.service_request_type.integrity_protected = 0; - test_ue.service_request_type.pdu_session_status = 1; + test_ue.service_request_param.integrity_protected = 0; + test_ue.service_request_param.pdu_session_status = 1; nasbuf = testgmm_build_service_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, nasbuf); - test_ue.service_request_type.integrity_protected = 1; - test_ue.service_request_type.pdu_session_status = 0; + test_ue.service_request_param.integrity_protected = 1; + test_ue.service_request_param.pdu_session_status = 0; gmmbuf = testgmm_build_service_request(&test_ue, nasbuf); ABTS_PTR_NOTNULL(tc, gmmbuf); @@ -1606,6 +1616,11 @@ static void test4_func(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, OGS_OK, rv); /* Send PDU session establishment request */ + test_sess.ul_nas_transport_param.request_type = + OGS_NAS_5GS_REQUEST_TYPE_INITIAL; + test_sess.ul_nas_transport_param.dnn = 1; + test_sess.ul_nas_transport_param.s_nssai = 1; + gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess); ABTS_PTR_NOTNULL(tc, gsmbuf); gmmbuf = testgmm_build_ul_nas_transport(&test_sess, @@ -1647,19 +1662,19 @@ static void test4_func(abts_case *tc, void *data) * - Uplink Data Status * - PDU Session Status */ - test_ue.service_request_type.integrity_protected = 0; - test_ue.service_request_type.uplink_data_status = 1; - test_ue.service_request_type.psimask.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 << test_sess.psi; - test_ue.service_request_type.pdu_session_status = 1; - test_ue.service_request_type.psimask.pdu_session_status = + test_ue.service_request_param.pdu_session_status = 1; + test_ue.service_request_param.psimask.pdu_session_status = 1 << test_sess.psi; nasbuf = testgmm_build_service_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, nasbuf); - test_ue.service_request_type.integrity_protected = 1; - test_ue.service_request_type.uplink_data_status = 0; - test_ue.service_request_type.pdu_session_status = 0; + 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); @@ -1700,10 +1715,10 @@ static void test4_func(abts_case *tc, void *data) * Send Service request Using UplinkNASTransport * - Uplink Data Status */ - test_ue.service_request_type.integrity_protected = 1; - test_ue.service_request_type.ciphered = 1; - test_ue.service_request_type.uplink_data_status = 1; - test_ue.service_request_type.psimask.uplink_data_status = + test_ue.service_request_param.integrity_protected = 1; + test_ue.service_request_param.ciphered = 1; + test_ue.service_request_param.uplink_data_status = 1; + test_ue.service_request_param.psimask.uplink_data_status = 1 << test_sess.psi; gmmbuf = testgmm_build_service_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); @@ -1748,10 +1763,10 @@ static void test4_func(abts_case *tc, void *data) * Send Service request Using UplinkNASTransport * - Uplink Data Status */ - test_ue.service_request_type.integrity_protected = 1; - test_ue.service_request_type.ciphered = 1; - test_ue.service_request_type.uplink_data_status = 1; - test_ue.service_request_type.psimask.uplink_data_status = + test_ue.service_request_param.integrity_protected = 1; + test_ue.service_request_param.ciphered = 1; + test_ue.service_request_param.uplink_data_status = 1; + test_ue.service_request_param.psimask.uplink_data_status = 1 << test_sess.psi; gmmbuf = testgmm_build_service_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); diff --git a/tests/registration/meson.build b/tests/registration/meson.build index 5ae7b4297..571182577 100644 --- a/tests/registration/meson.build +++ b/tests/registration/meson.build @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -testregistration_sources = files(''' +test5gc_registration_sources = files(''' abts-main.c guti-test.c auth-test.c @@ -26,7 +26,7 @@ testregistration_sources = files(''' ue-context-test.c '''.split()) -testregistration_exe = executable('registration', - sources : testregistration_sources, - c_args : testcore_cc_flags, +test5gc_registration_exe = executable('registration', + sources : test5gc_registration_sources, + c_args : testunit_core_cc_flags, dependencies : libtest5gc_dep) diff --git a/tests/registration/ue-context-test.c b/tests/registration/ue-context-test.c index dbe9c00a0..1146cc6a2 100644 --- a/tests/registration/ue-context-test.c +++ b/tests/registration/ue-context-test.c @@ -208,9 +208,9 @@ static void test1_func(abts_case *tc, void *data) gmmbuf = testgmm_build_registration_request(&test_ue, NULL); ABTS_PTR_NOTNULL(tc, gmmbuf); - test_ue.registration_request_type.requested_nssai = 1; - test_ue.registration_request_type.last_visited_registered_tai = 1; - test_ue.registration_request_type.ue_usage_setting = 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); diff --git a/tests/sctp/meson.build b/tests/sctp/meson.build index 20eb7c18b..3789b8596 100644 --- a/tests/sctp/meson.build +++ b/tests/sctp/meson.build @@ -15,14 +15,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -testsctp_sources = files(''' +testsystem_sctp_sources = files(''' abts-main.c sctp-test.c '''.split()) -testsctp_exe = executable('sctp', - sources : testsctp_sources, - c_args : testcore_cc_flags, +testsystem_sctp_exe = executable('sctp', + sources : testsystem_sctp_sources, + c_args : testunit_core_cc_flags, dependencies : libsctp_dep) -test('sctp', testsctp_exe, is_parallel : false, suite: 'system') +test('sctp', testsystem_sctp_exe, is_parallel : false, suite: 'system') diff --git a/tests/unit/meson.build b/tests/unit/meson.build index e248c461b..707de4260 100644 --- a/tests/unit/meson.build +++ b/tests/unit/meson.build @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -testunit_sources = files(''' +testunit_unit_sources = files(''' abts-main.c s1ap-message-test.c nas-message-test.c @@ -25,9 +25,9 @@ testunit_sources = files(''' crash-test.c '''.split()) -testunit_exe = executable('unit', - sources : testunit_sources, - c_args : [testcore_cc_flags, sbi_cc_flags], +testunit_unit_exe = executable('unit', + sources : testunit_unit_sources, + c_args : [testunit_core_cc_flags, sbi_cc_flags], dependencies : [libtestepc_dep, libsbi_dep]) -test('unit', testunit_exe, is_parallel : false, suite: 'unit') +test('unit', testunit_unit_exe, is_parallel : false, suite: 'unit') diff --git a/tests/volte/meson.build b/tests/volte/meson.build index 05bba6f03..029fb162d 100644 --- a/tests/volte/meson.build +++ b/tests/volte/meson.build @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -testvolte_sources = files(''' +testepc_volte_sources = files(''' pcscf-fd-path.h pcscf-fd-path.c @@ -23,10 +23,10 @@ testvolte_sources = files(''' volte-test.c '''.split()) -testvolte_exe = executable('volte', - sources : testvolte_sources, - c_args : [testcore_cc_flags, +testepc_volte_exe = executable('volte', + sources : testepc_volte_sources, + c_args : [testunit_core_cc_flags, '-DFD_EXT_DIR="@0@"'.format(freediameter_extensions_builddir)], dependencies : libtestepc_dep) -test('volte', testvolte_exe, is_parallel : false, suite: 'epc') +test('volte', testepc_volte_exe, is_parallel : false, suite: 'epc')