forked from acouzens/open5gs
Compare commits
14 Commits
f66c65b9cf
...
390a9dd637
Author | SHA1 | Date |
---|---|---|
Sukchan Lee | 390a9dd637 | |
Sukchan Lee | 7c14073533 | |
Sukchan Lee | cf4ad1f248 | |
Sukchan Lee | a667525041 | |
Sukchan Lee | 1dc4300203 | |
Pau Espin | 3b5e851f5d | |
Pau Espin | d0b31177cc | |
Pau Espin | 6420e80fe6 | |
Pau Espin | ca5a29dbe3 | |
Pau Espin | 12158eebb8 | |
Matej Gradišar | e1820e4e54 | |
Pau Espin | ea122da9fc | |
Pau Espin | 32a275b9a8 | |
Pau Espin | 10a0647f09 |
|
@ -334,7 +334,7 @@ Change back to the srsRAN source directory and copy the main config example as w
|
||||||
```bash
|
```bash
|
||||||
$ cp srsenb/enb.conf.example srsenb/enb.conf
|
$ cp srsenb/enb.conf.example srsenb/enb.conf
|
||||||
$ cp srsenb/rr.conf.example srsenb/rr.conf
|
$ cp srsenb/rr.conf.example srsenb/rr.conf
|
||||||
$ cp srsenb/drb.conf.example srsenb/drb.conf
|
$ cp srsenb/rb.conf.example srsenb/rb.conf
|
||||||
$ cp srsenb/sib.conf.example srsenb/sib.conf
|
$ cp srsenb/sib.conf.example srsenb/sib.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -199,6 +199,8 @@ void ogs_timer_mgr_expire(ogs_timer_mgr_t *manager)
|
||||||
ogs_list_add(&list, &this->lnode);
|
ogs_list_add(&list, &this->lnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* You should not perform a delete on a timer using ogs_timer_delete()
|
||||||
|
* in a callback function this->cb(). */
|
||||||
ogs_list_for_each(&list, lnode) {
|
ogs_list_for_each(&list, lnode) {
|
||||||
this = ogs_rb_entry(lnode, ogs_timer_t, lnode);
|
this = ogs_rb_entry(lnode, ogs_timer_t, lnode);
|
||||||
ogs_timer_stop(this);
|
ogs_timer_stop(this);
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "ogs-core.h"
|
||||||
|
|
||||||
#define NUM_ECC_DIGITS (ECC_BYTES/8)
|
#define NUM_ECC_DIGITS (ECC_BYTES/8)
|
||||||
#define MAX_TRIES 16
|
#define MAX_TRIES 16
|
||||||
|
|
||||||
|
@ -82,6 +84,7 @@ static int getRandomNumber(uint64_t *p_vli)
|
||||||
HCRYPTPROV l_prov;
|
HCRYPTPROV l_prov;
|
||||||
if(!CryptAcquireContext(&l_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
|
if(!CryptAcquireContext(&l_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
|
||||||
{
|
{
|
||||||
|
ogs_error("CryptAcquireContext() failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,9 +110,11 @@ static int getRandomNumber(uint64_t *p_vli)
|
||||||
int l_fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
|
int l_fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
|
||||||
if(l_fd == -1)
|
if(l_fd == -1)
|
||||||
{
|
{
|
||||||
|
ogs_error("open(/dev/urandom) failed");
|
||||||
l_fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
|
l_fd = open("/dev/random", O_RDONLY | O_CLOEXEC);
|
||||||
if(l_fd == -1)
|
if(l_fd == -1)
|
||||||
{
|
{
|
||||||
|
ogs_error("open(/dev/random) failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,6 +127,7 @@ static int getRandomNumber(uint64_t *p_vli)
|
||||||
if(l_read <= 0)
|
if(l_read <= 0)
|
||||||
{ // read failed
|
{ // read failed
|
||||||
close(l_fd);
|
close(l_fd);
|
||||||
|
ogs_error("read() failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
l_left -= l_read;
|
l_left -= l_read;
|
||||||
|
@ -1073,6 +1079,7 @@ int ecc_make_key(uint8_t p_publicKey[ECC_BYTES+1], uint8_t p_privateKey[ECC_BYTE
|
||||||
{
|
{
|
||||||
if(!getRandomNumber(l_private) || (l_tries++ >= MAX_TRIES))
|
if(!getRandomNumber(l_private) || (l_tries++ >= MAX_TRIES))
|
||||||
{
|
{
|
||||||
|
ogs_error("getRandomNumber() failed [%d]", l_tries);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(vli_isZero(l_private))
|
if(vli_isZero(l_private))
|
||||||
|
@ -1096,6 +1103,45 @@ int ecc_make_key(uint8_t p_publicKey[ECC_BYTES+1], uint8_t p_privateKey[ECC_BYTE
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define CURVE_A_32 {0xFFFFFFFFFFFFFFFCull, 0x00000000FFFFFFFFull, 0x0000000000000000ull, 0xFFFFFFFF00000001ull}
|
||||||
|
|
||||||
|
static int ecdh_validate_pubkey(EccPoint l_public, uint64_t l_private[NUM_ECC_DIGITS]) {
|
||||||
|
uint64_t left[NUM_ECC_DIGITS];
|
||||||
|
uint64_t right[NUM_ECC_DIGITS];
|
||||||
|
uint64_t curve_a[NUM_ECC_DIGITS] = CURVE_A_32;
|
||||||
|
/*
|
||||||
|
* To ensure l_public is a valid point on the curve, we need to check:
|
||||||
|
* y^2 % p == (x^3 + a * x + b) % p)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Compute y^2 % p and store in `left` */
|
||||||
|
vli_modSquare_fast(left, l_public.y);
|
||||||
|
|
||||||
|
/* Compute x^3 and store in `right` */
|
||||||
|
vli_modSquare_fast(right, l_public.x);
|
||||||
|
vli_modMult_fast(right, right, l_public.x);
|
||||||
|
|
||||||
|
/* Compute a * x and store in `curve_a` */
|
||||||
|
vli_modMult_fast(curve_a, curve_a, l_public.x);
|
||||||
|
/* Store ((a * x) + b) % p in `curve_a */
|
||||||
|
vli_modAdd(curve_a, curve_a, curve_b, curve_p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Combine x^3 and ((a * x) + b) to make (x^3 + a * x + b) % p);
|
||||||
|
* store in `right`
|
||||||
|
*/
|
||||||
|
vli_modAdd(right, right, curve_a, curve_p);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < NUM_ECC_DIGITS; i++) {
|
||||||
|
if (left[i] != right[i]) {
|
||||||
|
return 0; // y^2 % p != (x^3 + a * x + b) % p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int ecdh_shared_secret(const uint8_t p_publicKey[ECC_BYTES+1], const uint8_t p_privateKey[ECC_BYTES], uint8_t p_secret[ECC_BYTES])
|
int ecdh_shared_secret(const uint8_t p_publicKey[ECC_BYTES+1], const uint8_t p_privateKey[ECC_BYTES], uint8_t p_secret[ECC_BYTES])
|
||||||
{
|
{
|
||||||
EccPoint l_public;
|
EccPoint l_public;
|
||||||
|
@ -1104,12 +1150,23 @@ int ecdh_shared_secret(const uint8_t p_publicKey[ECC_BYTES+1], const uint8_t p_p
|
||||||
|
|
||||||
if(!getRandomNumber(l_random))
|
if(!getRandomNumber(l_random))
|
||||||
{
|
{
|
||||||
|
ogs_error("getRandomNumber() failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecc_point_decompress(&l_public, p_publicKey);
|
ecc_point_decompress(&l_public, p_publicKey);
|
||||||
ecc_bytes2native(l_private, p_privateKey);
|
ecc_bytes2native(l_private, p_privateKey);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate received public key `p_publicKey` is a valid point
|
||||||
|
* on curve P-256
|
||||||
|
*/
|
||||||
|
if (!ecdh_validate_pubkey(l_public, l_private))
|
||||||
|
{
|
||||||
|
ogs_error("ecdh_validate_pubkey() failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
EccPoint l_product;
|
EccPoint l_product;
|
||||||
EccPoint_mult(&l_product, &l_public, l_private, l_random);
|
EccPoint_mult(&l_product, &l_public, l_private, l_random);
|
||||||
|
|
||||||
|
@ -1202,6 +1259,7 @@ int ecdsa_sign(const uint8_t p_privateKey[ECC_BYTES], const uint8_t p_hash[ECC_B
|
||||||
{
|
{
|
||||||
if(!getRandomNumber(k) || (l_tries++ >= MAX_TRIES))
|
if(!getRandomNumber(k) || (l_tries++ >= MAX_TRIES))
|
||||||
{
|
{
|
||||||
|
ogs_error("getRandomNumber() failed [%d]", l_tries);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(vli_isZero(k))
|
if(vli_isZero(k))
|
||||||
|
@ -1256,11 +1314,13 @@ int ecdsa_verify(const uint8_t p_publicKey[ECC_BYTES+1], const uint8_t p_hash[EC
|
||||||
|
|
||||||
if(vli_isZero(l_r) || vli_isZero(l_s))
|
if(vli_isZero(l_r) || vli_isZero(l_s))
|
||||||
{ /* r, s must not be 0. */
|
{ /* r, s must not be 0. */
|
||||||
|
ogs_error("r, s must not be 0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vli_cmp(curve_n, l_r) != 1 || vli_cmp(curve_n, l_s) != 1)
|
if(vli_cmp(curve_n, l_r) != 1 || vli_cmp(curve_n, l_s) != 1)
|
||||||
{ /* r, s must be < n. */
|
{ /* r, s must be < n. */
|
||||||
|
ogs_error("r, s must be < n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,8 @@ typedef struct ogs_diam_gy_message_s {
|
||||||
uint32_t time_threshold;
|
uint32_t time_threshold;
|
||||||
uint32_t volume_threshold;
|
uint32_t volume_threshold;
|
||||||
ogs_diam_gy_service_unit_t granted;
|
ogs_diam_gy_service_unit_t granted;
|
||||||
|
uint32_t result_code;
|
||||||
|
uint32_t *err;
|
||||||
} cca;
|
} cca;
|
||||||
};
|
};
|
||||||
} ogs_diam_gy_message_t;
|
} ogs_diam_gy_message_t;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -128,16 +128,3 @@ int ogs_gtp_sendto(ogs_gtp_node_t *gnode, ogs_pkbuf_t *pkbuf)
|
||||||
|
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ogs_gtp_send_error_message(
|
|
||||||
ogs_gtp_xact_t *xact, uint32_t teid, uint8_t type, uint8_t cause_value)
|
|
||||||
{
|
|
||||||
switch (xact->gtp_version) {
|
|
||||||
case 1:
|
|
||||||
ogs_gtp1_send_error_message(xact, teid, type, cause_value);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
ogs_gtp2_send_error_message(xact, teid, type, cause_value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -72,9 +72,6 @@ int ogs_gtp_connect(ogs_sock_t *ipv4, ogs_sock_t *ipv6, ogs_gtp_node_t *gnode);
|
||||||
int ogs_gtp_send(ogs_gtp_node_t *gnode, ogs_pkbuf_t *pkbuf);
|
int ogs_gtp_send(ogs_gtp_node_t *gnode, ogs_pkbuf_t *pkbuf);
|
||||||
int ogs_gtp_sendto(ogs_gtp_node_t *gnode, ogs_pkbuf_t *pkbuf);
|
int ogs_gtp_sendto(ogs_gtp_node_t *gnode, ogs_pkbuf_t *pkbuf);
|
||||||
|
|
||||||
void ogs_gtp_send_error_message(
|
|
||||||
ogs_gtp_xact_t *xact, uint32_t teid, uint8_t type, uint8_t cause_value);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This file had been created by gtp-tlv.py script v0.1.0
|
* This file had been created by gtp-tlv.py script v0.1.0
|
||||||
* Please do not modify this file but regenerate it via script.
|
* Please do not modify this file but regenerate it via script.
|
||||||
* Created on: 2023-08-26 16:35:12.648272 by acetcom
|
* Created on: 2024-03-23 07:21:22.444548 by acetcom
|
||||||
* from 29274-h70.docx
|
* from 29274-h70.docx
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This file had been created by gtp-tlv.py script v0.1.0
|
* This file had been created by gtp-tlv.py script v0.1.0
|
||||||
* Please do not modify this file but regenerate it via script.
|
* Please do not modify this file but regenerate it via script.
|
||||||
* Created on: 2023-08-26 16:35:12.642445 by acetcom
|
* Created on: 2024-03-23 07:21:22.438775 by acetcom
|
||||||
* from 29274-h70.docx
|
* from 29274-h70.docx
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -44,6 +44,9 @@ typedef struct ogs_gtp2_header_s {
|
||||||
struct {
|
struct {
|
||||||
#define OGS_GTP2_VERSION_0 0
|
#define OGS_GTP2_VERSION_0 0
|
||||||
#define OGS_GTP2_VERSION_1 1
|
#define OGS_GTP2_VERSION_1 1
|
||||||
|
|
||||||
|
#define OGS_GTP2_TEID_NO_PRESENCE 0
|
||||||
|
#define OGS_GTP2_TEID_PRESENCE 1
|
||||||
ED4(uint8_t version:3;,
|
ED4(uint8_t version:3;,
|
||||||
uint8_t piggybacked:1;,
|
uint8_t piggybacked:1;,
|
||||||
uint8_t teid_presence:1;,
|
uint8_t teid_presence:1;,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -160,8 +160,8 @@ ogs_pkbuf_t *ogs_gtp2_handle_echo_req(ogs_pkbuf_t *pkb)
|
||||||
return pkb_resp;
|
return pkb_resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ogs_gtp2_send_error_message(
|
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
|
||||||
ogs_gtp_xact_t *xact, uint32_t teid, uint8_t type, uint8_t cause_value)
|
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
ogs_gtp2_message_t errmsg;
|
ogs_gtp2_message_t errmsg;
|
||||||
|
@ -170,6 +170,7 @@ void ogs_gtp2_send_error_message(
|
||||||
ogs_pkbuf_t *pkbuf = NULL;
|
ogs_pkbuf_t *pkbuf = NULL;
|
||||||
|
|
||||||
memset(&errmsg, 0, sizeof(ogs_gtp2_message_t));
|
memset(&errmsg, 0, sizeof(ogs_gtp2_message_t));
|
||||||
|
errmsg.h.teid_presence = teid_presence;
|
||||||
errmsg.h.teid = teid;
|
errmsg.h.teid = teid;
|
||||||
errmsg.h.type = type;
|
errmsg.h.type = type;
|
||||||
|
|
||||||
|
@ -257,7 +258,7 @@ void ogs_gtp2_send_echo_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_ECHO_REQUEST_TYPE;
|
h.type = OGS_GTP2_ECHO_REQUEST_TYPE;
|
||||||
h.teid = 0;
|
h.teid_presence = OGS_GTP2_TEID_NO_PRESENCE;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_echo_request(h.type, recovery, features);
|
pkbuf = ogs_gtp2_build_echo_request(h.type, recovery, features);
|
||||||
if (!pkbuf) {
|
if (!pkbuf) {
|
||||||
|
@ -284,7 +285,7 @@ void ogs_gtp2_send_echo_response(ogs_gtp_xact_t *xact,
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_ECHO_RESPONSE_TYPE;
|
h.type = OGS_GTP2_ECHO_RESPONSE_TYPE;
|
||||||
h.teid = 0;
|
h.teid_presence = OGS_GTP2_TEID_NO_PRESENCE;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_echo_response(h.type, recovery, features);
|
pkbuf = ogs_gtp2_build_echo_response(h.type, recovery, features);
|
||||||
if (!pkbuf) {
|
if (!pkbuf) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -36,8 +36,8 @@ int ogs_gtp2_send_user_plane(
|
||||||
ogs_pkbuf_t *pkbuf);
|
ogs_pkbuf_t *pkbuf);
|
||||||
|
|
||||||
ogs_pkbuf_t *ogs_gtp2_handle_echo_req(ogs_pkbuf_t *pkb);
|
ogs_pkbuf_t *ogs_gtp2_handle_echo_req(ogs_pkbuf_t *pkb);
|
||||||
void ogs_gtp2_send_error_message(
|
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
|
||||||
ogs_gtp_xact_t *xact, uint32_t teid, uint8_t type, uint8_t cause_value);
|
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
|
||||||
|
|
||||||
void ogs_gtp2_send_echo_request(
|
void ogs_gtp2_send_echo_request(
|
||||||
ogs_gtp_node_t *gnode, uint8_t recovery, uint8_t features);
|
ogs_gtp_node_t *gnode, uint8_t recovery, uint8_t features);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
# Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
|
|
||||||
# This file is part of Open5GS.
|
# This file is part of Open5GS.
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ def write_file(f, string):
|
||||||
def output_header_to_file(f):
|
def output_header_to_file(f):
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
f.write("""/*
|
f.write("""/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -461,6 +461,9 @@ typedef struct ogs_gtp2_header_s {
|
||||||
struct {
|
struct {
|
||||||
#define OGS_GTP2_VERSION_0 0
|
#define OGS_GTP2_VERSION_0 0
|
||||||
#define OGS_GTP2_VERSION_1 1
|
#define OGS_GTP2_VERSION_1 1
|
||||||
|
|
||||||
|
#define OGS_GTP2_TEID_NO_PRESENCE 0
|
||||||
|
#define OGS_GTP2_TEID_PRESENCE 1
|
||||||
ED4(uint8_t version:3;,
|
ED4(uint8_t version:3;,
|
||||||
uint8_t piggybacked:1;,
|
uint8_t piggybacked:1;,
|
||||||
uint8_t teid_presence:1;,
|
uint8_t teid_presence:1;,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||||
* Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
* Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||||
|
* Copyright (C) 2023-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -407,7 +408,7 @@ int ogs_gtp_xact_update_tx(ogs_gtp_xact_t *xact,
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdesc->type > OGS_GTP2_VERSION_NOT_SUPPORTED_INDICATION_TYPE) {
|
if (hdesc->teid_presence) {
|
||||||
gtp_hlen = OGS_GTPV2C_HEADER_LEN;
|
gtp_hlen = OGS_GTPV2C_HEADER_LEN;
|
||||||
} else {
|
} else {
|
||||||
gtp_hlen = OGS_GTPV2C_HEADER_LEN - OGS_GTP2_TEID_LEN;
|
gtp_hlen = OGS_GTPV2C_HEADER_LEN - OGS_GTP2_TEID_LEN;
|
||||||
|
@ -420,12 +421,12 @@ int ogs_gtp_xact_update_tx(ogs_gtp_xact_t *xact,
|
||||||
h->version = 2;
|
h->version = 2;
|
||||||
h->type = hdesc->type;
|
h->type = hdesc->type;
|
||||||
|
|
||||||
if (hdesc->type > OGS_GTP2_VERSION_NOT_SUPPORTED_INDICATION_TYPE) {
|
if (hdesc->teid_presence) {
|
||||||
h->teid_presence = 1;
|
h->teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h->teid = htobe32(hdesc->teid);
|
h->teid = htobe32(hdesc->teid);
|
||||||
h->sqn = OGS_GTP2_XID_TO_SQN(xact->xid);
|
h->sqn = OGS_GTP2_XID_TO_SQN(xact->xid);
|
||||||
} else {
|
} else {
|
||||||
h->teid_presence = 0;
|
h->teid_presence = OGS_GTP2_TEID_NO_PRESENCE;
|
||||||
h->sqn_only = OGS_GTP2_XID_TO_SQN(xact->xid);
|
h->sqn_only = OGS_GTP2_XID_TO_SQN(xact->xid);
|
||||||
}
|
}
|
||||||
h->length = htobe16(pkbuf->len - 4);
|
h->length = htobe16(pkbuf->len - 4);
|
||||||
|
|
|
@ -968,3 +968,21 @@ int ogs_nas_parse_qos_rules(
|
||||||
|
|
||||||
return (int)(rule-first);
|
return (int)(rule-first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ogs_nas_5gs_guti_is_valid(ogs_nas_5gs_guti_t *guti)
|
||||||
|
{
|
||||||
|
if ((guti->amf_id.region !=0) &&
|
||||||
|
(guti->amf_id.set2 !=0) &&
|
||||||
|
(guti->m_tmsi != 0) &&
|
||||||
|
((guti->nas_plmn_id.mcc1) !=0 ||
|
||||||
|
(guti->nas_plmn_id.mcc2) !=0 ||
|
||||||
|
(guti->nas_plmn_id.mcc3) !=0) &&
|
||||||
|
((guti->nas_plmn_id.mnc1) !=0 ||
|
||||||
|
(guti->nas_plmn_id.mnc2) !=0 ||
|
||||||
|
(guti->nas_plmn_id.mnc3) !=0)) {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -1192,6 +1192,8 @@ typedef struct ogs_nas_rsn_s {
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
} __attribute__ ((packed)) ogs_nas_rsn_t;
|
} __attribute__ ((packed)) ogs_nas_rsn_t;
|
||||||
|
|
||||||
|
bool ogs_nas_5gs_guti_is_valid(ogs_nas_5gs_guti_t *guti);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -870,6 +870,11 @@ ogs_pfcp_node_t *ogs_pfcp_node_new(ogs_sockaddr_t *sa_list)
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ogs_pfcp_node_t *ogs_pfcp_node_cycle(ogs_pfcp_node_t *node)
|
||||||
|
{
|
||||||
|
return ogs_pool_cycle(&ogs_pfcp_node_pool, node);
|
||||||
|
}
|
||||||
|
|
||||||
void ogs_pfcp_node_free(ogs_pfcp_node_t *node)
|
void ogs_pfcp_node_free(ogs_pfcp_node_t *node)
|
||||||
{
|
{
|
||||||
ogs_assert(node);
|
ogs_assert(node);
|
||||||
|
|
|
@ -393,6 +393,7 @@ ogs_pfcp_context_t *ogs_pfcp_self(void);
|
||||||
int ogs_pfcp_context_parse_config(const char *local, const char *remote);
|
int ogs_pfcp_context_parse_config(const char *local, const char *remote);
|
||||||
|
|
||||||
ogs_pfcp_node_t *ogs_pfcp_node_new(ogs_sockaddr_t *sa_list);
|
ogs_pfcp_node_t *ogs_pfcp_node_new(ogs_sockaddr_t *sa_list);
|
||||||
|
ogs_pfcp_node_t *ogs_pfcp_node_cycle(ogs_pfcp_node_t *node);
|
||||||
void ogs_pfcp_node_free(ogs_pfcp_node_t *node);
|
void ogs_pfcp_node_free(ogs_pfcp_node_t *node);
|
||||||
|
|
||||||
ogs_pfcp_node_t *ogs_pfcp_node_add(
|
ogs_pfcp_node_t *ogs_pfcp_node_add(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This file had been created by pfcp-tlv.py script v0.1.0
|
* This file had been created by pfcp-tlv.py script v0.1.0
|
||||||
* Please do not modify this file but regenerate it via script.
|
* Please do not modify this file but regenerate it via script.
|
||||||
* Created on: 2024-01-19 23:36:01.346970 by acetcom
|
* Created on: 2024-03-23 07:20:44.691773 by acetcom
|
||||||
* from 29244-h71-modified.docx
|
* from 29244-h71-modified.docx
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* This file had been created by pfcp-tlv.py script v0.1.0
|
* This file had been created by pfcp-tlv.py script v0.1.0
|
||||||
* Please do not modify this file but regenerate it via script.
|
* Please do not modify this file but regenerate it via script.
|
||||||
* Created on: 2024-01-19 23:36:01.327925 by acetcom
|
* Created on: 2024-03-23 07:20:44.672650 by acetcom
|
||||||
* from 29244-h71-modified.docx
|
* from 29244-h71-modified.docx
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@ extern "C" {
|
||||||
typedef struct ogs_pfcp_header_s {
|
typedef struct ogs_pfcp_header_s {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
|
#define OGS_PFCP_SEID_NO_PRESENCE 0
|
||||||
|
#define OGS_PFCP_SEID_PRESENCE 1
|
||||||
ED4(uint8_t version:3;,
|
ED4(uint8_t version:3;,
|
||||||
uint8_t spare1:3;,
|
uint8_t spare1:3;,
|
||||||
uint8_t mp:1;,
|
uint8_t mp:1;,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -140,7 +140,7 @@ int ogs_pfcp_send_heartbeat_request(ogs_pfcp_node_t *node,
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_HEARTBEAT_REQUEST_TYPE;
|
h.type = OGS_PFCP_HEARTBEAT_REQUEST_TYPE;
|
||||||
h.seid = 0;
|
h.seid_presence = OGS_PFCP_SEID_NO_PRESENCE;
|
||||||
|
|
||||||
xact = ogs_pfcp_xact_local_create(node, cb, node);
|
xact = ogs_pfcp_xact_local_create(node, cb, node);
|
||||||
if (!xact) {
|
if (!xact) {
|
||||||
|
@ -176,7 +176,7 @@ int ogs_pfcp_send_heartbeat_response(ogs_pfcp_xact_t *xact)
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_HEARTBEAT_RESPONSE_TYPE;
|
h.type = OGS_PFCP_HEARTBEAT_RESPONSE_TYPE;
|
||||||
h.seid = 0;
|
h.seid_presence = OGS_PFCP_SEID_NO_PRESENCE;
|
||||||
|
|
||||||
pkbuf = ogs_pfcp_build_heartbeat_response(h.type);
|
pkbuf = ogs_pfcp_build_heartbeat_response(h.type);
|
||||||
if (!pkbuf) {
|
if (!pkbuf) {
|
||||||
|
@ -217,7 +217,7 @@ int ogs_pfcp_cp_send_association_setup_request(ogs_pfcp_node_t *node,
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE;
|
h.type = OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE;
|
||||||
h.seid = 0;
|
h.seid_presence = OGS_PFCP_SEID_NO_PRESENCE;
|
||||||
|
|
||||||
xact = ogs_pfcp_xact_local_create(node, cb, node);
|
xact = ogs_pfcp_xact_local_create(node, cb, node);
|
||||||
if (!xact) {
|
if (!xact) {
|
||||||
|
@ -254,7 +254,7 @@ int ogs_pfcp_cp_send_association_setup_response(ogs_pfcp_xact_t *xact,
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE;
|
h.type = OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE;
|
||||||
h.seid = 0;
|
h.seid_presence = OGS_PFCP_SEID_NO_PRESENCE;
|
||||||
|
|
||||||
pkbuf = ogs_pfcp_cp_build_association_setup_response(h.type, cause);
|
pkbuf = ogs_pfcp_cp_build_association_setup_response(h.type, cause);
|
||||||
if (!pkbuf) {
|
if (!pkbuf) {
|
||||||
|
@ -286,7 +286,7 @@ int ogs_pfcp_up_send_association_setup_request(ogs_pfcp_node_t *node,
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE;
|
h.type = OGS_PFCP_ASSOCIATION_SETUP_REQUEST_TYPE;
|
||||||
h.seid = 0;
|
h.seid_presence = OGS_PFCP_SEID_NO_PRESENCE;
|
||||||
|
|
||||||
xact = ogs_pfcp_xact_local_create(node, cb, node);
|
xact = ogs_pfcp_xact_local_create(node, cb, node);
|
||||||
if (!xact) {
|
if (!xact) {
|
||||||
|
@ -323,7 +323,7 @@ int ogs_pfcp_up_send_association_setup_response(ogs_pfcp_xact_t *xact,
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE;
|
h.type = OGS_PFCP_ASSOCIATION_SETUP_RESPONSE_TYPE;
|
||||||
h.seid = 0;
|
h.seid_presence = OGS_PFCP_SEID_NO_PRESENCE;
|
||||||
|
|
||||||
pkbuf = ogs_pfcp_up_build_association_setup_response(h.type, cause);
|
pkbuf = ogs_pfcp_up_build_association_setup_response(h.type, cause);
|
||||||
if (!pkbuf) {
|
if (!pkbuf) {
|
||||||
|
@ -468,7 +468,7 @@ void ogs_pfcp_send_buffered_packet(ogs_pfcp_pdr_t *pdr)
|
||||||
}
|
}
|
||||||
|
|
||||||
void ogs_pfcp_send_error_message(
|
void ogs_pfcp_send_error_message(
|
||||||
ogs_pfcp_xact_t *xact, uint64_t seid, uint8_t type,
|
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
|
||||||
uint8_t cause_value, uint16_t offending_ie_value)
|
uint8_t cause_value, uint16_t offending_ie_value)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -480,6 +480,7 @@ void ogs_pfcp_send_error_message(
|
||||||
ogs_assert(xact);
|
ogs_assert(xact);
|
||||||
|
|
||||||
memset(&errmsg, 0, sizeof(ogs_pfcp_message_t));
|
memset(&errmsg, 0, sizeof(ogs_pfcp_message_t));
|
||||||
|
errmsg.h.seid_presence = seid_presence;
|
||||||
errmsg.h.seid = seid;
|
errmsg.h.seid = seid;
|
||||||
errmsg.h.type = type;
|
errmsg.h.type = type;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -86,7 +86,7 @@ int ogs_pfcp_send_end_marker(ogs_pfcp_pdr_t *pdr);
|
||||||
void ogs_pfcp_send_buffered_packet(ogs_pfcp_pdr_t *pdr);
|
void ogs_pfcp_send_buffered_packet(ogs_pfcp_pdr_t *pdr);
|
||||||
|
|
||||||
void ogs_pfcp_send_error_message(
|
void ogs_pfcp_send_error_message(
|
||||||
ogs_pfcp_xact_t *xact, uint64_t seid, uint8_t type,
|
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
|
||||||
uint8_t cause_value, uint16_t offending_ie_value);
|
uint8_t cause_value, uint16_t offending_ie_value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
# Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
|
|
||||||
# This file is part of Open5GS.
|
# This file is part of Open5GS.
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ def write_file(f, string):
|
||||||
def output_header_to_file(f):
|
def output_header_to_file(f):
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
f.write("""/*
|
f.write("""/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -541,6 +541,8 @@ extern "C" {
|
||||||
typedef struct ogs_pfcp_header_s {
|
typedef struct ogs_pfcp_header_s {
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
|
#define OGS_PFCP_SEID_NO_PRESENCE 0
|
||||||
|
#define OGS_PFCP_SEID_PRESENCE 1
|
||||||
ED4(uint8_t version:3;,
|
ED4(uint8_t version:3;,
|
||||||
uint8_t spare1:3;,
|
uint8_t spare1:3;,
|
||||||
uint8_t mp:1;,
|
uint8_t mp:1;,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -161,11 +161,6 @@ static ogs_pfcp_xact_t *ogs_pfcp_xact_remote_create(
|
||||||
return xact;
|
return xact;
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_pfcp_xact_t *ogs_pfcp_xact_cycle(ogs_pfcp_xact_t *xact)
|
|
||||||
{
|
|
||||||
return ogs_pool_cycle(&pool, xact);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ogs_pfcp_xact_delete_all(ogs_pfcp_node_t *node)
|
void ogs_pfcp_xact_delete_all(ogs_pfcp_node_t *node)
|
||||||
{
|
{
|
||||||
ogs_pfcp_xact_t *xact = NULL, *next_xact = NULL;
|
ogs_pfcp_xact_t *xact = NULL, *next_xact = NULL;
|
||||||
|
@ -251,7 +246,7 @@ int ogs_pfcp_xact_update_tx(ogs_pfcp_xact_t *xact,
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hdesc->type >= OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE) {
|
if (hdesc->seid_presence) {
|
||||||
pfcp_hlen = OGS_PFCP_HEADER_LEN;
|
pfcp_hlen = OGS_PFCP_HEADER_LEN;
|
||||||
} else {
|
} else {
|
||||||
pfcp_hlen = OGS_PFCP_HEADER_LEN - OGS_PFCP_SEID_LEN;
|
pfcp_hlen = OGS_PFCP_HEADER_LEN - OGS_PFCP_SEID_LEN;
|
||||||
|
@ -264,7 +259,7 @@ int ogs_pfcp_xact_update_tx(ogs_pfcp_xact_t *xact,
|
||||||
h->version = OGS_PFCP_VERSION;
|
h->version = OGS_PFCP_VERSION;
|
||||||
h->type = hdesc->type;
|
h->type = hdesc->type;
|
||||||
|
|
||||||
if (h->type >= OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE) {
|
if (hdesc->seid_presence) {
|
||||||
h->seid_presence = 1;
|
h->seid_presence = 1;
|
||||||
h->seid = htobe64(hdesc->seid);
|
h->seid = htobe64(hdesc->seid);
|
||||||
h->sqn = OGS_PFCP_XID_TO_SQN(xact->xid);
|
h->sqn = OGS_PFCP_XID_TO_SQN(xact->xid);
|
||||||
|
|
|
@ -133,7 +133,6 @@ void ogs_pfcp_xact_final(void);
|
||||||
|
|
||||||
ogs_pfcp_xact_t *ogs_pfcp_xact_local_create(ogs_pfcp_node_t *node,
|
ogs_pfcp_xact_t *ogs_pfcp_xact_local_create(ogs_pfcp_node_t *node,
|
||||||
void (*cb)(ogs_pfcp_xact_t *xact, void *data), void *data);
|
void (*cb)(ogs_pfcp_xact_t *xact, void *data), void *data);
|
||||||
ogs_pfcp_xact_t *ogs_pfcp_xact_cycle(ogs_pfcp_xact_t *xact);
|
|
||||||
void ogs_pfcp_xact_delete_all(ogs_pfcp_node_t *node);
|
void ogs_pfcp_xact_delete_all(ogs_pfcp_node_t *node);
|
||||||
|
|
||||||
int ogs_pfcp_xact_update_tx(ogs_pfcp_xact_t *xact,
|
int ogs_pfcp_xact_update_tx(ogs_pfcp_xact_t *xact,
|
||||||
|
|
|
@ -85,6 +85,8 @@ extern "C" {
|
||||||
|
|
||||||
#define OGS_MAX_NUM_OF_ALGORITHM 8
|
#define OGS_MAX_NUM_OF_ALGORITHM 8
|
||||||
|
|
||||||
|
#define OGS_MAX_5G_GUTI_LEN 28
|
||||||
|
|
||||||
#define OGS_MAX_NUM_OF_SERVED_GUMMEI 8 /* maxnoofRATs: 8 */
|
#define OGS_MAX_NUM_OF_SERVED_GUMMEI 8 /* maxnoofRATs: 8 */
|
||||||
#define OGS_MAX_NUM_OF_SERVED_GUAMI 256 /* maxnoofServedGUAMIs: 256 */
|
#define OGS_MAX_NUM_OF_SERVED_GUAMI 256 /* maxnoofServedGUAMIs: 256 */
|
||||||
#define OGS_MAX_NUM_OF_SUPPORTED_TA 256 /* maxnoofTACs: 256 */
|
#define OGS_MAX_NUM_OF_SUPPORTED_TA 256 /* maxnoofTACs: 256 */
|
||||||
|
@ -271,10 +273,11 @@ ogs_amf_id_t *ogs_amf_id_build(ogs_amf_id_t *amf_id,
|
||||||
#define OGS_PROTECTION_SCHEME_PROFILE_B 2
|
#define OGS_PROTECTION_SCHEME_PROFILE_B 2
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
* SUPI/GPSI */
|
* SUPI/GPSI/GUTI */
|
||||||
#define OGS_ID_SUPI_TYPE_IMSI "imsi"
|
#define OGS_ID_SUPI_TYPE_IMSI "imsi"
|
||||||
#define OGS_ID_GPSI_TYPE_MSISDN "msisdn"
|
#define OGS_ID_GPSI_TYPE_MSISDN "msisdn"
|
||||||
#define OGS_ID_SUPI_TYPE_IMEISV "imeisv"
|
#define OGS_ID_SUPI_TYPE_IMEISV "imeisv"
|
||||||
|
#define OGS_ID_5G_GUTI_TYPE "5g-guti"
|
||||||
char *ogs_id_get_type(const char *str);
|
char *ogs_id_get_type(const char *str);
|
||||||
char *ogs_id_get_value(const char *str);
|
char *ogs_id_get_value(const char *str);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ static OGS_POOL(xact_pool, ogs_sbi_xact_t);
|
||||||
static OGS_POOL(subscription_spec_pool, ogs_sbi_subscription_spec_t);
|
static OGS_POOL(subscription_spec_pool, ogs_sbi_subscription_spec_t);
|
||||||
static OGS_POOL(subscription_data_pool, ogs_sbi_subscription_data_t);
|
static OGS_POOL(subscription_data_pool, ogs_sbi_subscription_data_t);
|
||||||
static OGS_POOL(smf_info_pool, ogs_sbi_smf_info_t);
|
static OGS_POOL(smf_info_pool, ogs_sbi_smf_info_t);
|
||||||
|
static OGS_POOL(amf_info_pool, ogs_sbi_amf_info_t);
|
||||||
static OGS_POOL(nf_info_pool, ogs_sbi_nf_info_t);
|
static OGS_POOL(nf_info_pool, ogs_sbi_nf_info_t);
|
||||||
|
|
||||||
void ogs_sbi_context_init(OpenAPI_nf_type_e nf_type)
|
void ogs_sbi_context_init(OpenAPI_nf_type_e nf_type)
|
||||||
|
@ -61,6 +62,7 @@ void ogs_sbi_context_init(OpenAPI_nf_type_e nf_type)
|
||||||
ogs_pool_init(&subscription_data_pool, ogs_app()->pool.subscription);
|
ogs_pool_init(&subscription_data_pool, ogs_app()->pool.subscription);
|
||||||
|
|
||||||
ogs_pool_init(&smf_info_pool, ogs_app()->pool.nf);
|
ogs_pool_init(&smf_info_pool, ogs_app()->pool.nf);
|
||||||
|
ogs_pool_init(&amf_info_pool, ogs_app()->pool.nf);
|
||||||
|
|
||||||
ogs_pool_init(&nf_info_pool, ogs_app()->pool.nf * OGS_MAX_NUM_OF_NF_INFO);
|
ogs_pool_init(&nf_info_pool, ogs_app()->pool.nf * OGS_MAX_NUM_OF_NF_INFO);
|
||||||
|
|
||||||
|
@ -107,6 +109,7 @@ void ogs_sbi_context_final(void)
|
||||||
ogs_pool_final(&nf_instance_pool);
|
ogs_pool_final(&nf_instance_pool);
|
||||||
ogs_pool_final(&nf_service_pool);
|
ogs_pool_final(&nf_service_pool);
|
||||||
ogs_pool_final(&smf_info_pool);
|
ogs_pool_final(&smf_info_pool);
|
||||||
|
ogs_pool_final(&amf_info_pool);
|
||||||
|
|
||||||
ogs_pool_final(&nf_info_pool);
|
ogs_pool_final(&nf_info_pool);
|
||||||
|
|
||||||
|
@ -1530,7 +1533,13 @@ ogs_sbi_nf_info_t *ogs_sbi_nf_info_add(
|
||||||
|
|
||||||
static void amf_info_free(ogs_sbi_amf_info_t *amf_info)
|
static void amf_info_free(ogs_sbi_amf_info_t *amf_info)
|
||||||
{
|
{
|
||||||
/* Nothing */
|
ogs_assert(amf_info);
|
||||||
|
|
||||||
|
amf_info->num_of_guami = 0;
|
||||||
|
amf_info->num_of_nr_tai = 0;
|
||||||
|
amf_info->num_of_nr_tai_range = 0;
|
||||||
|
|
||||||
|
ogs_pool_free(&amf_info_pool, amf_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void smf_info_free(ogs_sbi_smf_info_t *smf_info)
|
static void smf_info_free(ogs_sbi_smf_info_t *smf_info)
|
||||||
|
@ -1621,6 +1630,26 @@ ogs_sbi_nf_info_t *ogs_sbi_nf_info_find(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ogs_sbi_check_amf_info_guami(
|
||||||
|
ogs_sbi_amf_info_t *amf_info, ogs_guami_t *guami)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ogs_assert(amf_info);
|
||||||
|
ogs_assert(guami);
|
||||||
|
|
||||||
|
for (i = 0; i < amf_info->num_of_guami; i++) {
|
||||||
|
if ((memcmp(&amf_info->guami[i].amf_id, &guami->amf_id,
|
||||||
|
sizeof(ogs_amf_id_t)) == 0) &&
|
||||||
|
(memcmp(&amf_info->guami[i].plmn_id, &guami->plmn_id,
|
||||||
|
OGS_PLMN_ID_LEN) == 0)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool ogs_sbi_check_smf_info_slice(
|
bool ogs_sbi_check_smf_info_slice(
|
||||||
ogs_sbi_smf_info_t *smf_info, ogs_s_nssai_t *s_nssai, char *dnn)
|
ogs_sbi_smf_info_t *smf_info, ogs_s_nssai_t *s_nssai, char *dnn)
|
||||||
{
|
{
|
||||||
|
@ -1964,6 +1993,13 @@ bool ogs_sbi_discovery_option_is_matched(
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (nf_info->nf_type) {
|
switch (nf_info->nf_type) {
|
||||||
|
case OpenAPI_nf_type_AMF:
|
||||||
|
if (requester_nf_type == OpenAPI_nf_type_AMF &&
|
||||||
|
discovery_option->target_guami &&
|
||||||
|
ogs_sbi_check_amf_info_guami(&nf_info->amf,
|
||||||
|
discovery_option->target_guami) == false)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
case OpenAPI_nf_type_SMF:
|
case OpenAPI_nf_type_SMF:
|
||||||
if (discovery_option->num_of_snssais && discovery_option->dnn &&
|
if (discovery_option->num_of_snssais && discovery_option->dnn &&
|
||||||
ogs_sbi_check_smf_info_slice(&nf_info->smf,
|
ogs_sbi_check_smf_info_slice(&nf_info->smf,
|
||||||
|
|
|
@ -341,8 +341,8 @@ typedef struct ogs_sbi_sepp_info_s {
|
||||||
} ogs_sbi_sepp_info_t;
|
} ogs_sbi_sepp_info_t;
|
||||||
|
|
||||||
typedef struct ogs_sbi_amf_info_s {
|
typedef struct ogs_sbi_amf_info_s {
|
||||||
int amf_set_id;
|
uint8_t amf_set_id;
|
||||||
int amf_region_id;
|
uint16_t amf_region_id;
|
||||||
|
|
||||||
int num_of_guami;
|
int num_of_guami;
|
||||||
ogs_guami_t guami[OGS_MAX_NUM_OF_SERVED_GUAMI];
|
ogs_guami_t guami[OGS_MAX_NUM_OF_SERVED_GUAMI];
|
||||||
|
@ -437,6 +437,8 @@ void ogs_sbi_nf_info_remove_all(ogs_list_t *list);
|
||||||
ogs_sbi_nf_info_t *ogs_sbi_nf_info_find(
|
ogs_sbi_nf_info_t *ogs_sbi_nf_info_find(
|
||||||
ogs_list_t *list, OpenAPI_nf_type_e nf_type);
|
ogs_list_t *list, OpenAPI_nf_type_e nf_type);
|
||||||
|
|
||||||
|
bool ogs_sbi_check_amf_info_guami(
|
||||||
|
ogs_sbi_amf_info_t *amf_info, ogs_guami_t *guami);
|
||||||
bool ogs_sbi_check_smf_info_slice(
|
bool ogs_sbi_check_smf_info_slice(
|
||||||
ogs_sbi_smf_info_t *smf_info, ogs_s_nssai_t *s_nssai, char *dnn);
|
ogs_sbi_smf_info_t *smf_info, ogs_s_nssai_t *s_nssai, char *dnn);
|
||||||
bool ogs_sbi_check_smf_info_tai(
|
bool ogs_sbi_check_smf_info_tai(
|
||||||
|
|
|
@ -189,6 +189,10 @@ void ogs_sbi_message_free(ogs_sbi_message_t *message)
|
||||||
OpenAPI_sec_negotiate_req_data_free(message->SecNegotiateReqData);
|
OpenAPI_sec_negotiate_req_data_free(message->SecNegotiateReqData);
|
||||||
if (message->SecNegotiateRspData)
|
if (message->SecNegotiateRspData)
|
||||||
OpenAPI_sec_negotiate_rsp_data_free(message->SecNegotiateRspData);
|
OpenAPI_sec_negotiate_rsp_data_free(message->SecNegotiateRspData);
|
||||||
|
if (message->UeContextTransferReqData)
|
||||||
|
OpenAPI_ue_context_transfer_req_data_free(message->UeContextTransferReqData);
|
||||||
|
if (message->UeContextTransferRspData)
|
||||||
|
OpenAPI_ue_context_transfer_rsp_data_free(message->UeContextTransferRspData);
|
||||||
|
|
||||||
/* HTTP Part */
|
/* HTTP Part */
|
||||||
for (i = 0; i < message->num_of_part; i++) {
|
for (i = 0; i < message->num_of_part; i++) {
|
||||||
|
@ -282,6 +286,7 @@ ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message)
|
||||||
int i;
|
int i;
|
||||||
ogs_sbi_request_t *request = NULL;
|
ogs_sbi_request_t *request = NULL;
|
||||||
OpenAPI_nf_type_e nf_type = OpenAPI_nf_type_NULL;
|
OpenAPI_nf_type_e nf_type = OpenAPI_nf_type_NULL;
|
||||||
|
|
||||||
char sender_timestamp[OGS_SBI_RFC7231_DATE_LEN];
|
char sender_timestamp[OGS_SBI_RFC7231_DATE_LEN];
|
||||||
char *max_rsp_time = NULL;
|
char *max_rsp_time = NULL;
|
||||||
|
|
||||||
|
@ -389,6 +394,18 @@ ogs_sbi_request_t *ogs_sbi_build_request(ogs_sbi_message_t *message)
|
||||||
OGS_SBI_PARAM_REQUESTER_NF_INSTANCE_ID,
|
OGS_SBI_PARAM_REQUESTER_NF_INSTANCE_ID,
|
||||||
discovery_option->requester_nf_instance_id);
|
discovery_option->requester_nf_instance_id);
|
||||||
}
|
}
|
||||||
|
if (discovery_option->target_guami) {
|
||||||
|
char *v = ogs_sbi_discovery_option_build_guami(discovery_option);
|
||||||
|
if (v) {
|
||||||
|
ogs_sbi_header_set(request->http.params,
|
||||||
|
OGS_SBI_PARAM_GUAMI, v);
|
||||||
|
ogs_free(v);
|
||||||
|
} else {
|
||||||
|
ogs_warn("build failed: service-names[%d:%s]",
|
||||||
|
discovery_option->num_of_service_names,
|
||||||
|
discovery_option->service_names[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ogs_sbi_self()->discovery_config.no_service_names == false &&
|
if (ogs_sbi_self()->discovery_config.no_service_names == false &&
|
||||||
discovery_option->num_of_service_names) {
|
discovery_option->num_of_service_names) {
|
||||||
|
|
||||||
|
@ -817,9 +834,14 @@ int ogs_sbi_parse_request(
|
||||||
ogs_sbi_discovery_option_parse_snssais(discovery_option, v);
|
ogs_sbi_discovery_option_parse_snssais(discovery_option, v);
|
||||||
discovery_option_presence = true;
|
discovery_option_presence = true;
|
||||||
}
|
}
|
||||||
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_GUAMI)) {
|
||||||
|
char *v = ogs_hash_this_val(hi);
|
||||||
|
if (v) {
|
||||||
|
ogs_sbi_discovery_option_parse_guami(discovery_option, v);
|
||||||
|
discovery_option_presence = true;
|
||||||
|
}
|
||||||
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_DNN)) {
|
} else if (!strcmp(ogs_hash_this_key(hi), OGS_SBI_PARAM_DNN)) {
|
||||||
char *v = ogs_hash_this_val(hi);
|
char *v = ogs_hash_this_val(hi);
|
||||||
|
|
||||||
if (v) {
|
if (v) {
|
||||||
ogs_sbi_discovery_option_set_dnn(discovery_option, v);
|
ogs_sbi_discovery_option_set_dnn(discovery_option, v);
|
||||||
discovery_option_presence = true;
|
discovery_option_presence = true;
|
||||||
|
@ -1340,6 +1362,14 @@ static char *build_json(ogs_sbi_message_t *message)
|
||||||
item = OpenAPI_sec_negotiate_rsp_data_convertToJSON(
|
item = OpenAPI_sec_negotiate_rsp_data_convertToJSON(
|
||||||
message->SecNegotiateRspData);
|
message->SecNegotiateRspData);
|
||||||
ogs_assert(item);
|
ogs_assert(item);
|
||||||
|
} else if (message->UeContextTransferReqData) {
|
||||||
|
item = OpenAPI_ue_context_transfer_req_data_convertToJSON(
|
||||||
|
message->UeContextTransferReqData);
|
||||||
|
ogs_assert(item);
|
||||||
|
} else if (message->UeContextTransferRspData) {
|
||||||
|
item = OpenAPI_ue_context_transfer_rsp_data_convertToJSON(
|
||||||
|
message->UeContextTransferRspData);
|
||||||
|
ogs_assert(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item) {
|
if (item) {
|
||||||
|
@ -2082,6 +2112,27 @@ static int parse_json(ogs_sbi_message_t *message,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_TRANSFER)
|
||||||
|
if (message->res_status == 0) {
|
||||||
|
message->UeContextTransferReqData =
|
||||||
|
OpenAPI_ue_context_transfer_req_data_parseFromJSON(item);
|
||||||
|
if (!message->UeContextTransferReqData) {
|
||||||
|
rv = OGS_ERROR;
|
||||||
|
ogs_error("JSON parse error");
|
||||||
|
}
|
||||||
|
} else if (message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||||||
|
message->UeContextTransferRspData =
|
||||||
|
OpenAPI_ue_context_transfer_rsp_data_parseFromJSON(item);
|
||||||
|
if (!message->UeContextTransferRspData) {
|
||||||
|
rv = OGS_ERROR;
|
||||||
|
ogs_error("JSON parse error");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ogs_error("HTTP ERROR Status : %d",
|
||||||
|
message->res_status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
DEFAULT
|
DEFAULT
|
||||||
rv = OGS_ERROR;
|
rv = OGS_ERROR;
|
||||||
ogs_error("Unknown resource name [%s]",
|
ogs_error("Unknown resource name [%s]",
|
||||||
|
@ -2889,6 +2940,8 @@ void ogs_sbi_discovery_option_free(
|
||||||
ogs_free(discovery_option->requester_nf_instance_id);
|
ogs_free(discovery_option->requester_nf_instance_id);
|
||||||
if (discovery_option->dnn)
|
if (discovery_option->dnn)
|
||||||
ogs_free(discovery_option->dnn);
|
ogs_free(discovery_option->dnn);
|
||||||
|
if (discovery_option->target_guami)
|
||||||
|
ogs_free(discovery_option->target_guami);
|
||||||
|
|
||||||
for (i = 0; i < discovery_option->num_of_service_names; i++)
|
for (i = 0; i < discovery_option->num_of_service_names; i++)
|
||||||
ogs_free(discovery_option->service_names[i]);
|
ogs_free(discovery_option->service_names[i]);
|
||||||
|
@ -3129,6 +3182,71 @@ void ogs_sbi_discovery_option_parse_snssais(
|
||||||
ogs_free(v);
|
ogs_free(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *ogs_sbi_discovery_option_build_guami(
|
||||||
|
ogs_sbi_discovery_option_t *discovery_option)
|
||||||
|
{
|
||||||
|
OpenAPI_guami_t *Guami = NULL;
|
||||||
|
cJSON *guamiItem = NULL;
|
||||||
|
char *v = NULL;
|
||||||
|
|
||||||
|
ogs_assert(discovery_option);
|
||||||
|
ogs_assert(discovery_option->target_guami);
|
||||||
|
|
||||||
|
Guami = ogs_sbi_build_guami(discovery_option->target_guami);
|
||||||
|
ogs_assert(Guami);
|
||||||
|
guamiItem = OpenAPI_guami_convertToJSON(Guami);
|
||||||
|
ogs_assert(guamiItem);
|
||||||
|
ogs_sbi_free_guami(Guami);
|
||||||
|
|
||||||
|
v = cJSON_PrintUnformatted(guamiItem);
|
||||||
|
ogs_expect(v);
|
||||||
|
cJSON_Delete(guamiItem);
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ogs_sbi_discovery_option_parse_guami(
|
||||||
|
ogs_sbi_discovery_option_t *discovery_option, char *guami)
|
||||||
|
{
|
||||||
|
OpenAPI_guami_t *Guami = NULL;
|
||||||
|
cJSON *guamItem = NULL;
|
||||||
|
char *v = NULL;
|
||||||
|
|
||||||
|
ogs_assert(discovery_option);
|
||||||
|
ogs_assert(guami);
|
||||||
|
|
||||||
|
v = ogs_sbi_url_decode(guami);
|
||||||
|
if (!v) {
|
||||||
|
ogs_error("ogs_sbi_url_decode() failed : guami[%s]", guami);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
guamItem = cJSON_Parse(v);
|
||||||
|
if (!guamItem) {
|
||||||
|
ogs_error("Cannot parse guami[%s]", guami);
|
||||||
|
ogs_free(v);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Guami = OpenAPI_guami_parseFromJSON(guamItem);
|
||||||
|
|
||||||
|
if (Guami) {
|
||||||
|
ogs_guami_t *ogs_guami = NULL;
|
||||||
|
|
||||||
|
discovery_option->target_guami = ogs_malloc(sizeof(*ogs_guami));
|
||||||
|
ogs_assert(discovery_option->target_guami);
|
||||||
|
|
||||||
|
ogs_sbi_parse_guami(discovery_option->target_guami, Guami);
|
||||||
|
OpenAPI_guami_free(Guami);
|
||||||
|
} else {
|
||||||
|
ogs_error("OpenAPI_guami_parseFromJSON() failed : guami[%s]",
|
||||||
|
guami);
|
||||||
|
}
|
||||||
|
cJSON_Delete(guamItem);
|
||||||
|
|
||||||
|
ogs_free(v);
|
||||||
|
}
|
||||||
|
|
||||||
void ogs_sbi_discovery_option_set_tai(
|
void ogs_sbi_discovery_option_set_tai(
|
||||||
ogs_sbi_discovery_option_t *discovery_option, ogs_5gs_tai_t *tai)
|
ogs_sbi_discovery_option_t *discovery_option, ogs_5gs_tai_t *tai)
|
||||||
{
|
{
|
||||||
|
|
|
@ -124,6 +124,7 @@ extern "C" {
|
||||||
|
|
||||||
#define OGS_SBI_RESOURCE_NAME_UE_CONTEXTS "ue-contexts"
|
#define OGS_SBI_RESOURCE_NAME_UE_CONTEXTS "ue-contexts"
|
||||||
#define OGS_SBI_RESOURCE_NAME_N1_N2_MESSAGES "n1-n2-messages"
|
#define OGS_SBI_RESOURCE_NAME_N1_N2_MESSAGES "n1-n2-messages"
|
||||||
|
#define OGS_SBI_RESOURCE_NAME_TRANSFER "transfer"
|
||||||
|
|
||||||
#define OGS_SBI_RESOURCE_NAME_SM_CONTEXT_STATUS "sm-context-status"
|
#define OGS_SBI_RESOURCE_NAME_SM_CONTEXT_STATUS "sm-context-status"
|
||||||
#define OGS_SBI_RESOURCE_NAME_AM_POLICY_NOTIFY "am-policy-notify"
|
#define OGS_SBI_RESOURCE_NAME_AM_POLICY_NOTIFY "am-policy-notify"
|
||||||
|
@ -295,6 +296,8 @@ extern "C" {
|
||||||
OGS_SBI_CUSTOM_DISCOVERY_COMMON OGS_SBI_PARAM_REQUESTER_PLMN_LIST
|
OGS_SBI_CUSTOM_DISCOVERY_COMMON OGS_SBI_PARAM_REQUESTER_PLMN_LIST
|
||||||
#define OGS_SBI_CUSTOM_DISCOVERY_REQUESTER_FEATURES \
|
#define OGS_SBI_CUSTOM_DISCOVERY_REQUESTER_FEATURES \
|
||||||
OGS_SBI_CUSTOM_DISCOVERY_COMMON OGS_SBI_PARAM_REQUESTER_FEATURES
|
OGS_SBI_CUSTOM_DISCOVERY_COMMON OGS_SBI_PARAM_REQUESTER_FEATURES
|
||||||
|
#define OGS_SBI_CUSTOM_DISCOVERY_GUAMI \
|
||||||
|
OGS_SBI_CUSTOM_DISCOVERY_COMMON OGS_SBI_PARAM_GUAMI
|
||||||
#define OGS_SBI_CUSTOM_PRODUCER_ID \
|
#define OGS_SBI_CUSTOM_PRODUCER_ID \
|
||||||
OGS_SBI_CUSTOM_3GPP_COMMON "Producer-Id"
|
OGS_SBI_CUSTOM_3GPP_COMMON "Producer-Id"
|
||||||
#define OGS_SBI_CUSTOM_OCI \
|
#define OGS_SBI_CUSTOM_OCI \
|
||||||
|
@ -330,6 +333,7 @@ extern "C" {
|
||||||
#define OGS_SBI_PARAM_PLMN_ID "plmn-id"
|
#define OGS_SBI_PARAM_PLMN_ID "plmn-id"
|
||||||
#define OGS_SBI_PARAM_SINGLE_NSSAI "single-nssai"
|
#define OGS_SBI_PARAM_SINGLE_NSSAI "single-nssai"
|
||||||
#define OGS_SBI_PARAM_SNSSAI "snssai"
|
#define OGS_SBI_PARAM_SNSSAI "snssai"
|
||||||
|
#define OGS_SBI_PARAM_GUAMI "guami"
|
||||||
#define OGS_SBI_PARAM_SNSSAIS "snssais"
|
#define OGS_SBI_PARAM_SNSSAIS "snssais"
|
||||||
#define OGS_SBI_PARAM_TAI "tai"
|
#define OGS_SBI_PARAM_TAI "tai"
|
||||||
#define OGS_SBI_PARAM_SLICE_INFO_REQUEST_FOR_PDU_SESSION \
|
#define OGS_SBI_PARAM_SLICE_INFO_REQUEST_FOR_PDU_SESSION \
|
||||||
|
@ -431,6 +435,8 @@ typedef struct ogs_sbi_discovery_option_s {
|
||||||
bool tai_presence;
|
bool tai_presence;
|
||||||
ogs_5gs_tai_t tai;
|
ogs_5gs_tai_t tai;
|
||||||
|
|
||||||
|
ogs_guami_t *target_guami;
|
||||||
|
|
||||||
int num_of_target_plmn_list;
|
int num_of_target_plmn_list;
|
||||||
ogs_plmn_id_t target_plmn_list[OGS_MAX_NUM_OF_PLMN];
|
ogs_plmn_id_t target_plmn_list[OGS_MAX_NUM_OF_PLMN];
|
||||||
int num_of_requester_plmn_list;
|
int num_of_requester_plmn_list;
|
||||||
|
@ -542,6 +548,8 @@ typedef struct ogs_sbi_message_s {
|
||||||
OpenAPI_smf_registration_t *SmfRegistration;
|
OpenAPI_smf_registration_t *SmfRegistration;
|
||||||
OpenAPI_sec_negotiate_req_data_t *SecNegotiateReqData;
|
OpenAPI_sec_negotiate_req_data_t *SecNegotiateReqData;
|
||||||
OpenAPI_sec_negotiate_rsp_data_t *SecNegotiateRspData;
|
OpenAPI_sec_negotiate_rsp_data_t *SecNegotiateRspData;
|
||||||
|
OpenAPI_ue_context_transfer_req_data_t *UeContextTransferReqData;
|
||||||
|
OpenAPI_ue_context_transfer_rsp_data_t *UeContextTransferRspData;
|
||||||
|
|
||||||
ogs_sbi_links_t *links;
|
ogs_sbi_links_t *links;
|
||||||
|
|
||||||
|
@ -641,6 +649,11 @@ char *ogs_sbi_discovery_option_build_snssais(
|
||||||
void ogs_sbi_discovery_option_parse_snssais(
|
void ogs_sbi_discovery_option_parse_snssais(
|
||||||
ogs_sbi_discovery_option_t *discovery_option, char *snssais);
|
ogs_sbi_discovery_option_t *discovery_option, char *snssais);
|
||||||
|
|
||||||
|
char *ogs_sbi_discovery_option_build_guami(
|
||||||
|
ogs_sbi_discovery_option_t *discovery_option);
|
||||||
|
void ogs_sbi_discovery_option_parse_guami(
|
||||||
|
ogs_sbi_discovery_option_t *discovery_option, char *guami);
|
||||||
|
|
||||||
void ogs_sbi_discovery_option_set_tai(
|
void ogs_sbi_discovery_option_set_tai(
|
||||||
ogs_sbi_discovery_option_t *discovery_option, ogs_5gs_tai_t *tai);
|
ogs_sbi_discovery_option_t *discovery_option, ogs_5gs_tai_t *tai);
|
||||||
char *ogs_sbi_discovery_option_build_tai(
|
char *ogs_sbi_discovery_option_build_tai(
|
||||||
|
|
|
@ -27,6 +27,8 @@ static void handle_scp_info(
|
||||||
ogs_sbi_nf_instance_t *nf_instance, OpenAPI_scp_info_t *ScpInfo);
|
ogs_sbi_nf_instance_t *nf_instance, OpenAPI_scp_info_t *ScpInfo);
|
||||||
static void handle_sepp_info(
|
static void handle_sepp_info(
|
||||||
ogs_sbi_nf_instance_t *nf_instance, OpenAPI_sepp_info_t *SeppInfo);
|
ogs_sbi_nf_instance_t *nf_instance, OpenAPI_sepp_info_t *SeppInfo);
|
||||||
|
static void handle_amf_info(
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance, OpenAPI_amf_info_t *AmfInfo);
|
||||||
|
|
||||||
void ogs_nnrf_nfm_handle_nf_register(
|
void ogs_nnrf_nfm_handle_nf_register(
|
||||||
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg)
|
ogs_sbi_nf_instance_t *nf_instance, ogs_sbi_message_t *recvmsg)
|
||||||
|
@ -256,7 +258,14 @@ void ogs_nnrf_nfm_handle_nf_profile(
|
||||||
if (SmfInfoMap && SmfInfoMap->value)
|
if (SmfInfoMap && SmfInfoMap->value)
|
||||||
handle_smf_info(nf_instance, SmfInfoMap->value);
|
handle_smf_info(nf_instance, SmfInfoMap->value);
|
||||||
}
|
}
|
||||||
|
if (NFProfile->amf_info)
|
||||||
|
handle_amf_info(nf_instance, NFProfile->amf_info);
|
||||||
|
|
||||||
|
OpenAPI_list_for_each(NFProfile->amf_info_list, node) {
|
||||||
|
OpenAPI_map_t *AmfInfoMap = node->data;
|
||||||
|
if (AmfInfoMap && AmfInfoMap->value)
|
||||||
|
handle_amf_info(nf_instance, AmfInfoMap->value);
|
||||||
|
}
|
||||||
if (NFProfile->scp_info)
|
if (NFProfile->scp_info)
|
||||||
handle_scp_info(nf_instance, NFProfile->scp_info);
|
handle_scp_info(nf_instance, NFProfile->scp_info);
|
||||||
if (NFProfile->sepp_info)
|
if (NFProfile->sepp_info)
|
||||||
|
@ -653,6 +662,100 @@ static void handle_sepp_info(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_amf_info(
|
||||||
|
ogs_sbi_nf_instance_t *nf_instance, OpenAPI_amf_info_t *AmfInfo)
|
||||||
|
{
|
||||||
|
ogs_sbi_nf_info_t *nf_info = NULL;
|
||||||
|
OpenAPI_list_t *GuamiList = NULL;
|
||||||
|
OpenAPI_guami_t *GuamiAmfInfoItem = NULL;
|
||||||
|
OpenAPI_list_t *TaiList = NULL;
|
||||||
|
OpenAPI_tai_t *TaiItem = NULL;
|
||||||
|
OpenAPI_list_t *TaiRangeList = NULL;
|
||||||
|
OpenAPI_tai_range_t *TaiRangeItem = NULL;
|
||||||
|
OpenAPI_list_t *TacRangeList = NULL;
|
||||||
|
OpenAPI_tac_range_t *TacRangeItem = NULL;
|
||||||
|
OpenAPI_lnode_t *node = NULL, *node2 = NULL;
|
||||||
|
|
||||||
|
ogs_assert(nf_instance);
|
||||||
|
ogs_assert(AmfInfo);
|
||||||
|
|
||||||
|
nf_info = ogs_sbi_nf_info_add(
|
||||||
|
&nf_instance->nf_info_list, OpenAPI_nf_type_AMF);
|
||||||
|
ogs_assert(nf_info);
|
||||||
|
|
||||||
|
nf_info->amf.amf_set_id = ogs_uint64_from_string(AmfInfo->amf_set_id);
|
||||||
|
nf_info->amf.amf_region_id = ogs_uint64_from_string(AmfInfo->amf_region_id);
|
||||||
|
GuamiList = AmfInfo->guami_list;
|
||||||
|
|
||||||
|
OpenAPI_list_for_each(GuamiList, node) {
|
||||||
|
GuamiAmfInfoItem = node->data;
|
||||||
|
if (GuamiAmfInfoItem) {
|
||||||
|
ogs_assert(nf_info->amf.num_of_guami < OGS_MAX_NUM_OF_SERVED_GUAMI);
|
||||||
|
|
||||||
|
if (GuamiAmfInfoItem->amf_id && GuamiAmfInfoItem->plmn_id &&
|
||||||
|
GuamiAmfInfoItem->plmn_id->mnc &&
|
||||||
|
GuamiAmfInfoItem->plmn_id->mcc) {
|
||||||
|
|
||||||
|
ogs_sbi_parse_guami(
|
||||||
|
&nf_info->amf.guami[nf_info->amf.num_of_guami],
|
||||||
|
GuamiAmfInfoItem);
|
||||||
|
nf_info->amf.num_of_guami++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TaiList = AmfInfo->tai_list;
|
||||||
|
OpenAPI_list_for_each(TaiList, node) {
|
||||||
|
TaiItem = node->data;
|
||||||
|
if (TaiItem && TaiItem->plmn_id && TaiItem->tac) {
|
||||||
|
ogs_5gs_tai_t *nr_tai = NULL;
|
||||||
|
ogs_assert(nf_info->amf.num_of_nr_tai < OGS_MAX_NUM_OF_TAI);
|
||||||
|
nr_tai = &nf_info->amf.nr_tai[nf_info->amf.num_of_nr_tai];
|
||||||
|
ogs_assert(nr_tai);
|
||||||
|
ogs_sbi_parse_plmn_id(&nr_tai->plmn_id, TaiItem->plmn_id);
|
||||||
|
nr_tai->tac = ogs_uint24_from_string(TaiItem->tac);
|
||||||
|
nf_info->amf.num_of_nr_tai++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TaiRangeList = AmfInfo->tai_range_list;
|
||||||
|
OpenAPI_list_for_each(TaiRangeList, node) {
|
||||||
|
TaiRangeItem = node->data;
|
||||||
|
if (TaiRangeItem && TaiRangeItem->plmn_id &&
|
||||||
|
TaiRangeItem->tac_range_list) {
|
||||||
|
ogs_assert(nf_info->amf.num_of_nr_tai_range <
|
||||||
|
OGS_MAX_NUM_OF_TAI);
|
||||||
|
|
||||||
|
ogs_sbi_parse_plmn_id(
|
||||||
|
&nf_info->amf.nr_tai_range
|
||||||
|
[nf_info->amf.num_of_nr_tai_range].plmn_id,
|
||||||
|
TaiRangeItem->plmn_id);
|
||||||
|
|
||||||
|
TacRangeList = TaiRangeItem->tac_range_list;
|
||||||
|
OpenAPI_list_for_each(TacRangeList, node2) {
|
||||||
|
TacRangeItem = node2->data;
|
||||||
|
if (TacRangeItem &&
|
||||||
|
TacRangeItem->start && TacRangeItem->end) {
|
||||||
|
int tac_index = nf_info->amf.nr_tai_range
|
||||||
|
[nf_info->amf.num_of_nr_tai_range].num_of_tac_range;
|
||||||
|
ogs_assert(tac_index < OGS_MAX_NUM_OF_TAI);
|
||||||
|
|
||||||
|
nf_info->amf.nr_tai_range
|
||||||
|
[nf_info->amf.num_of_nr_tai_range].start[tac_index] =
|
||||||
|
ogs_uint24_from_string(TacRangeItem->start);
|
||||||
|
nf_info->amf.nr_tai_range
|
||||||
|
[nf_info->amf.num_of_nr_tai_range].end[tac_index] =
|
||||||
|
ogs_uint24_from_string(TacRangeItem->end);
|
||||||
|
|
||||||
|
nf_info->amf.nr_tai_range
|
||||||
|
[nf_info->amf.num_of_nr_tai_range].num_of_tac_range++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nf_info->amf.num_of_nr_tai_range++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_validity_time(
|
static void handle_validity_time(
|
||||||
ogs_sbi_subscription_data_t *subscription_data,
|
ogs_sbi_subscription_data_t *subscription_data,
|
||||||
char *validity_time, const char *action)
|
char *validity_time, const char *action)
|
||||||
|
|
|
@ -84,6 +84,8 @@
|
||||||
#include "model/sec_negotiate_rsp_data.h"
|
#include "model/sec_negotiate_rsp_data.h"
|
||||||
#include "model/patch_item.h"
|
#include "model/patch_item.h"
|
||||||
#include "model/ue_authentication_ctx.h"
|
#include "model/ue_authentication_ctx.h"
|
||||||
|
#include "model/ue_context_transfer_req_data.h"
|
||||||
|
#include "model/ue_context_transfer_rsp_data.h"
|
||||||
|
|
||||||
#include "custom/links.h"
|
#include "custom/links.h"
|
||||||
|
|
||||||
|
|
|
@ -422,6 +422,33 @@ int ogs_sbi_discover_and_send(ogs_sbi_xact_t *xact)
|
||||||
discovery_option->tai.tac.v);
|
discovery_option->tai.tac.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (discovery_option && discovery_option->target_guami) {
|
||||||
|
bool rc = false;
|
||||||
|
char *v = ogs_sbi_discovery_option_build_guami(discovery_option);
|
||||||
|
ogs_expect(v);
|
||||||
|
|
||||||
|
if (v) {
|
||||||
|
char *encoded = ogs_sbi_url_encode(v);
|
||||||
|
ogs_expect(encoded);
|
||||||
|
|
||||||
|
if (encoded) {
|
||||||
|
ogs_sbi_header_set(request->http.headers,
|
||||||
|
OGS_SBI_CUSTOM_DISCOVERY_GUAMI, encoded);
|
||||||
|
ogs_free(encoded);
|
||||||
|
|
||||||
|
rc = true;
|
||||||
|
}
|
||||||
|
ogs_free(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc == false)
|
||||||
|
ogs_error("build failed: guami[PLMN_ID:%06x,AMF_ID:%x]",
|
||||||
|
ogs_plmn_id_hexdump(
|
||||||
|
&discovery_option->target_guami->plmn_id),
|
||||||
|
ogs_amf_id_hexdump(
|
||||||
|
&discovery_option->target_guami->amf_id));
|
||||||
|
}
|
||||||
|
|
||||||
if (discovery_option &&
|
if (discovery_option &&
|
||||||
discovery_option->requester_features) {
|
discovery_option->requester_features) {
|
||||||
char *v = ogs_uint64_to_string(
|
char *v = ogs_uint64_to_string(
|
||||||
|
|
|
@ -180,6 +180,22 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
|
||||||
END
|
END
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_TRANSFER)
|
||||||
|
SWITCH(sbi_message.h.method)
|
||||||
|
CASE(OGS_SBI_HTTP_METHOD_POST)
|
||||||
|
amf_namf_comm_handle_ue_context_transfer_request(
|
||||||
|
stream, &sbi_message);
|
||||||
|
break;
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid HTTP method [%s]",
|
||||||
|
sbi_message.h.method);
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_FORBIDDEN, &sbi_message,
|
||||||
|
"Invalid HTTP method", sbi_message.h.method));
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
DEFAULT
|
DEFAULT
|
||||||
ogs_error("Invalid resource name [%s]",
|
ogs_error("Invalid resource name [%s]",
|
||||||
sbi_message.h.resource.component[2]);
|
sbi_message.h.resource.component[2]);
|
||||||
|
@ -375,6 +391,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
|
||||||
CASE(OGS_SBI_SERVICE_NAME_NUDM_UECM)
|
CASE(OGS_SBI_SERVICE_NAME_NUDM_UECM)
|
||||||
CASE(OGS_SBI_SERVICE_NAME_NUDM_SDM)
|
CASE(OGS_SBI_SERVICE_NAME_NUDM_SDM)
|
||||||
CASE(OGS_SBI_SERVICE_NAME_NPCF_AM_POLICY_CONTROL)
|
CASE(OGS_SBI_SERVICE_NAME_NPCF_AM_POLICY_CONTROL)
|
||||||
|
CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
|
||||||
sbi_xact = e->h.sbi.data;
|
sbi_xact = e->h.sbi.data;
|
||||||
ogs_assert(sbi_xact);
|
ogs_assert(sbi_xact);
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ static void stats_add_ran_ue(void);
|
||||||
static void stats_remove_ran_ue(void);
|
static void stats_remove_ran_ue(void);
|
||||||
static void stats_add_amf_session(void);
|
static void stats_add_amf_session(void);
|
||||||
static void stats_remove_amf_session(void);
|
static void stats_remove_amf_session(void);
|
||||||
|
static bool amf_namf_comm_parse_guti(ogs_nas_5gs_guti_t *guti, char *ue_context_id);
|
||||||
|
|
||||||
void amf_context_init(void)
|
void amf_context_init(void)
|
||||||
{
|
{
|
||||||
|
@ -1955,6 +1956,105 @@ amf_ue_t *amf_ue_find_by_message(ogs_nas_5gs_message_t *message)
|
||||||
return amf_ue;
|
return amf_ue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool amf_namf_comm_parse_guti(ogs_nas_5gs_guti_t *guti, char *ue_context_id)
|
||||||
|
{
|
||||||
|
#define MIN_LENGTH_OF_MNC 2
|
||||||
|
#define MAX_LENGTH_OF_MNC 3
|
||||||
|
#define LENGTH_OF_MCC 3
|
||||||
|
#define LENGTH_OF_AMF_ID 6
|
||||||
|
#define LENGTH_OF_TMSI 8
|
||||||
|
|
||||||
|
char amf_id_string[LENGTH_OF_AMF_ID + 1];
|
||||||
|
char tmsi_string[LENGTH_OF_TMSI + 1];
|
||||||
|
char mcc_string[LENGTH_OF_MCC + 1];
|
||||||
|
char mnc_string[MAX_LENGTH_OF_MNC + 1];
|
||||||
|
OpenAPI_plmn_id_t Plmn_id;
|
||||||
|
ogs_plmn_id_t plmn_id;
|
||||||
|
|
||||||
|
/* TS29.518 6.1.3.2.2 Guti pattern (27 or 28 characters):
|
||||||
|
"5g-guti-[0-9]{5,6}[0-9a-fA-F]{14}" */
|
||||||
|
|
||||||
|
short index = 8; /* start parsing guti after "5g-guti-" */
|
||||||
|
|
||||||
|
strncpy(mcc_string, &ue_context_id[index], LENGTH_OF_MCC);
|
||||||
|
mcc_string[LENGTH_OF_MCC] = '\0';
|
||||||
|
index += LENGTH_OF_MCC;
|
||||||
|
|
||||||
|
if (strlen(ue_context_id) == OGS_MAX_5G_GUTI_LEN - 1) {
|
||||||
|
/* mnc is 2 characters long */
|
||||||
|
mnc_string[MIN_LENGTH_OF_MNC] = '\0';
|
||||||
|
strncpy(mnc_string, &ue_context_id[index], MIN_LENGTH_OF_MNC);
|
||||||
|
index += MIN_LENGTH_OF_MNC;
|
||||||
|
} else if (strlen(ue_context_id) == OGS_MAX_5G_GUTI_LEN) {
|
||||||
|
/* mnc is 3 characters long */
|
||||||
|
mnc_string[MAX_LENGTH_OF_MNC] = '\0';
|
||||||
|
strncpy(mnc_string, &ue_context_id[index], MAX_LENGTH_OF_MNC);
|
||||||
|
index += MAX_LENGTH_OF_MNC;
|
||||||
|
} else {
|
||||||
|
ogs_error("Invalid Ue context id");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(amf_id_string, &ue_context_id[index], LENGTH_OF_AMF_ID);
|
||||||
|
amf_id_string[LENGTH_OF_AMF_ID] = '\0';
|
||||||
|
index += LENGTH_OF_AMF_ID;
|
||||||
|
|
||||||
|
strncpy(tmsi_string, &ue_context_id[index], LENGTH_OF_TMSI);
|
||||||
|
tmsi_string[LENGTH_OF_TMSI] = '\0';
|
||||||
|
|
||||||
|
memset(&Plmn_id, 0, sizeof(Plmn_id));
|
||||||
|
Plmn_id.mcc = mcc_string;
|
||||||
|
Plmn_id.mnc = mnc_string;
|
||||||
|
|
||||||
|
memset(&plmn_id, 0, sizeof(plmn_id));
|
||||||
|
ogs_sbi_parse_plmn_id(&plmn_id, &Plmn_id);
|
||||||
|
ogs_nas_from_plmn_id(&guti->nas_plmn_id, &plmn_id);
|
||||||
|
ogs_amf_id_from_string(&guti->amf_id, amf_id_string);
|
||||||
|
|
||||||
|
guti->m_tmsi = (u_int32_t)strtol(tmsi_string, NULL, 16);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
amf_ue_t *amf_ue_find_by_ue_context_id(char *ue_context_id)
|
||||||
|
{
|
||||||
|
amf_ue_t *amf_ue = NULL;
|
||||||
|
|
||||||
|
ogs_assert(ue_context_id);
|
||||||
|
|
||||||
|
if (strncmp(ue_context_id, OGS_ID_SUPI_TYPE_IMSI,
|
||||||
|
strlen(OGS_ID_SUPI_TYPE_IMSI)) == 0) {
|
||||||
|
|
||||||
|
amf_ue = amf_ue_find_by_supi(ue_context_id);
|
||||||
|
if (!amf_ue) {
|
||||||
|
ogs_info("[%s] Unknown UE by SUPI", ue_context_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (strncmp(ue_context_id, OGS_ID_5G_GUTI_TYPE,
|
||||||
|
strlen(OGS_ID_5G_GUTI_TYPE)) == 0) {
|
||||||
|
|
||||||
|
ogs_nas_5gs_guti_t guti;
|
||||||
|
memset(&guti, 0, sizeof(guti));
|
||||||
|
|
||||||
|
if (amf_namf_comm_parse_guti(&guti, ue_context_id) == false) {
|
||||||
|
ogs_error("amf_namf_comm_parse_guti() failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
amf_ue = amf_ue_find_by_guti(&guti);
|
||||||
|
if (!amf_ue) {
|
||||||
|
ogs_info("[%s] Unknown UE by GUTI", ue_context_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ogs_error("Unsupported UE context ID type");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return amf_ue;
|
||||||
|
}
|
||||||
|
|
||||||
void amf_ue_set_suci(amf_ue_t *amf_ue,
|
void amf_ue_set_suci(amf_ue_t *amf_ue,
|
||||||
ogs_nas_5gs_mobile_identity_t *mobile_identity)
|
ogs_nas_5gs_mobile_identity_t *mobile_identity)
|
||||||
{
|
{
|
||||||
|
|
|
@ -749,6 +749,7 @@ void amf_ue_fsm_fini(amf_ue_t *amf_ue);
|
||||||
amf_ue_t *amf_ue_find_by_guti(ogs_nas_5gs_guti_t *nas_guti);
|
amf_ue_t *amf_ue_find_by_guti(ogs_nas_5gs_guti_t *nas_guti);
|
||||||
amf_ue_t *amf_ue_find_by_suci(char *suci);
|
amf_ue_t *amf_ue_find_by_suci(char *suci);
|
||||||
amf_ue_t *amf_ue_find_by_supi(char *supi);
|
amf_ue_t *amf_ue_find_by_supi(char *supi);
|
||||||
|
amf_ue_t *amf_ue_find_by_ue_context_id(char *ue_context_id);
|
||||||
|
|
||||||
amf_ue_t *amf_ue_find_by_message(ogs_nas_5gs_message_t *message);
|
amf_ue_t *amf_ue_find_by_message(ogs_nas_5gs_message_t *message);
|
||||||
void amf_ue_set_suci(amf_ue_t *amf_ue,
|
void amf_ue_set_suci(amf_ue_t *amf_ue,
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#define OGS_LOG_DOMAIN __gmm_log_domain
|
#define OGS_LOG_DOMAIN __gmm_log_domain
|
||||||
|
|
||||||
static ogs_nas_5gmm_cause_t gmm_handle_nas_message_container(
|
static ogs_nas_5gmm_cause_t gmm_handle_nas_message_container(
|
||||||
amf_ue_t *amf_ue, uint8_t message_type,
|
ran_ue_t *ran_ue, amf_ue_t *amf_ue, uint8_t message_type,
|
||||||
ogs_nas_message_container_t *nas_message_container);
|
ogs_nas_message_container_t *nas_message_container);
|
||||||
|
|
||||||
static uint8_t gmm_cause_from_access_control(ogs_plmn_id_t *plmn_id);
|
static uint8_t gmm_cause_from_access_control(ogs_plmn_id_t *plmn_id);
|
||||||
|
@ -339,7 +339,8 @@ ogs_nas_5gmm_cause_t gmm_handle_registration_request(amf_ue_t *amf_ue,
|
||||||
return OGS_5GMM_CAUSE_REQUEST_ACCEPTED;
|
return OGS_5GMM_CAUSE_REQUEST_ACCEPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_nas_5gmm_cause_t gmm_handle_registration_update(amf_ue_t *amf_ue,
|
ogs_nas_5gmm_cause_t gmm_handle_registration_update(
|
||||||
|
ran_ue_t *ran_ue, amf_ue_t *amf_ue,
|
||||||
ogs_nas_5gs_registration_request_t *registration_request)
|
ogs_nas_5gs_registration_request_t *registration_request)
|
||||||
{
|
{
|
||||||
amf_sess_t *sess = NULL;
|
amf_sess_t *sess = NULL;
|
||||||
|
@ -352,6 +353,7 @@ ogs_nas_5gmm_cause_t gmm_handle_registration_update(amf_ue_t *amf_ue,
|
||||||
ogs_nas_5gs_update_type_t *update_type = NULL;
|
ogs_nas_5gs_update_type_t *update_type = NULL;
|
||||||
|
|
||||||
ogs_assert(amf_ue);
|
ogs_assert(amf_ue);
|
||||||
|
ogs_assert(ran_ue);
|
||||||
ogs_assert(registration_request);
|
ogs_assert(registration_request);
|
||||||
|
|
||||||
last_visited_registered_tai =
|
last_visited_registered_tai =
|
||||||
|
@ -376,7 +378,7 @@ ogs_nas_5gmm_cause_t gmm_handle_registration_update(amf_ue_t *amf_ue,
|
||||||
OGS_NAS_5GS_REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT) {
|
OGS_NAS_5GS_REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT) {
|
||||||
|
|
||||||
return gmm_handle_nas_message_container(
|
return gmm_handle_nas_message_container(
|
||||||
amf_ue, OGS_NAS_5GS_REGISTRATION_REQUEST,
|
ran_ue, amf_ue, OGS_NAS_5GS_REGISTRATION_REQUEST,
|
||||||
®istration_request->nas_message_container);
|
®istration_request->nas_message_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,7 +474,7 @@ ogs_nas_5gmm_cause_t gmm_handle_registration_update(amf_ue_t *amf_ue,
|
||||||
if ((psimask & (1 << sess->psi)) == 0) {
|
if ((psimask & (1 << sess->psi)) == 0) {
|
||||||
if (SESSION_CONTEXT_IN_SMF(sess))
|
if (SESSION_CONTEXT_IN_SMF(sess))
|
||||||
amf_sbi_send_release_session(
|
amf_sbi_send_release_session(
|
||||||
sess, AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT);
|
ran_ue, sess, AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,7 +493,8 @@ ogs_nas_5gmm_cause_t gmm_handle_registration_update(amf_ue_t *amf_ue,
|
||||||
if (psimask & (1 << sess->psi)) {
|
if (psimask & (1 << sess->psi)) {
|
||||||
if (SESSION_CONTEXT_IN_SMF(sess))
|
if (SESSION_CONTEXT_IN_SMF(sess))
|
||||||
amf_sbi_send_activating_session(
|
amf_sbi_send_activating_session(
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST);
|
ran_ue, sess,
|
||||||
|
AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -653,7 +656,8 @@ ogs_nas_5gmm_cause_t gmm_handle_service_request(amf_ue_t *amf_ue,
|
||||||
return OGS_5GMM_CAUSE_REQUEST_ACCEPTED;
|
return OGS_5GMM_CAUSE_REQUEST_ACCEPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_nas_5gmm_cause_t gmm_handle_service_update(amf_ue_t *amf_ue,
|
ogs_nas_5gmm_cause_t gmm_handle_service_update(
|
||||||
|
ran_ue_t *ran_ue, amf_ue_t *amf_ue,
|
||||||
ogs_nas_5gs_service_request_t *service_request)
|
ogs_nas_5gs_service_request_t *service_request)
|
||||||
{
|
{
|
||||||
amf_sess_t *sess = NULL;
|
amf_sess_t *sess = NULL;
|
||||||
|
@ -665,6 +669,8 @@ ogs_nas_5gmm_cause_t gmm_handle_service_update(amf_ue_t *amf_ue,
|
||||||
ogs_nas_allowed_pdu_session_status_t *allowed_pdu_session_status = NULL;
|
ogs_nas_allowed_pdu_session_status_t *allowed_pdu_session_status = NULL;
|
||||||
|
|
||||||
ogs_assert(amf_ue);
|
ogs_assert(amf_ue);
|
||||||
|
ogs_assert(ran_ue);
|
||||||
|
ogs_assert(service_request);
|
||||||
|
|
||||||
uplink_data_status = &service_request->uplink_data_status;
|
uplink_data_status = &service_request->uplink_data_status;
|
||||||
ogs_assert(uplink_data_status);
|
ogs_assert(uplink_data_status);
|
||||||
|
@ -677,7 +683,7 @@ ogs_nas_5gmm_cause_t gmm_handle_service_update(amf_ue_t *amf_ue,
|
||||||
OGS_NAS_5GS_SERVICE_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT) {
|
OGS_NAS_5GS_SERVICE_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT) {
|
||||||
|
|
||||||
return gmm_handle_nas_message_container(
|
return gmm_handle_nas_message_container(
|
||||||
amf_ue, OGS_NAS_5GS_SERVICE_REQUEST,
|
ran_ue, amf_ue, OGS_NAS_5GS_SERVICE_REQUEST,
|
||||||
&service_request->nas_message_container);
|
&service_request->nas_message_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,7 +718,7 @@ ogs_nas_5gmm_cause_t gmm_handle_service_update(amf_ue_t *amf_ue,
|
||||||
if ((psimask & (1 << sess->psi)) == 0) {
|
if ((psimask & (1 << sess->psi)) == 0) {
|
||||||
if (SESSION_CONTEXT_IN_SMF(sess))
|
if (SESSION_CONTEXT_IN_SMF(sess))
|
||||||
amf_sbi_send_release_session(
|
amf_sbi_send_release_session(
|
||||||
sess, AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT);
|
ran_ue, sess, AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -739,7 +745,8 @@ ogs_nas_5gmm_cause_t gmm_handle_service_update(amf_ue_t *amf_ue,
|
||||||
if (psimask & (1 << sess->psi)) {
|
if (psimask & (1 << sess->psi)) {
|
||||||
if (SESSION_CONTEXT_IN_SMF(sess))
|
if (SESSION_CONTEXT_IN_SMF(sess))
|
||||||
amf_sbi_send_activating_session(
|
amf_sbi_send_activating_session(
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST);
|
ran_ue, sess,
|
||||||
|
AMF_UPDATE_SM_CONTEXT_SERVICE_REQUEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -757,9 +764,12 @@ int gmm_handle_deregistration_request(amf_ue_t *amf_ue,
|
||||||
ogs_nas_5gs_deregistration_request_from_ue_t *deregistration_request)
|
ogs_nas_5gs_deregistration_request_from_ue_t *deregistration_request)
|
||||||
{
|
{
|
||||||
int r, state, xact_count = 0;
|
int r, state, xact_count = 0;
|
||||||
|
ran_ue_t *ran_ue = NULL;
|
||||||
ogs_nas_de_registration_type_t *de_registration_type = NULL;
|
ogs_nas_de_registration_type_t *de_registration_type = NULL;
|
||||||
|
|
||||||
ogs_assert(amf_ue);
|
ogs_assert(amf_ue);
|
||||||
|
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
||||||
|
ogs_assert(ran_ue);
|
||||||
ogs_assert(deregistration_request);
|
ogs_assert(deregistration_request);
|
||||||
|
|
||||||
de_registration_type = &deregistration_request->de_registration_type;
|
de_registration_type = &deregistration_request->de_registration_type;
|
||||||
|
@ -790,7 +800,7 @@ int gmm_handle_deregistration_request(amf_ue_t *amf_ue,
|
||||||
xact_count = amf_sess_xact_count(amf_ue);
|
xact_count = amf_sess_xact_count(amf_ue);
|
||||||
|
|
||||||
state = AMF_UE_INITIATED_DE_REGISTERED;
|
state = AMF_UE_INITIATED_DE_REGISTERED;
|
||||||
amf_sbi_send_release_all_sessions(amf_ue, state);
|
amf_sbi_send_release_all_sessions(ran_ue, amf_ue, state);
|
||||||
|
|
||||||
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
||||||
amf_sess_xact_count(amf_ue) == xact_count) {
|
amf_sess_xact_count(amf_ue) == xact_count) {
|
||||||
|
@ -884,6 +894,7 @@ ogs_nas_5gmm_cause_t gmm_handle_identity_response(amf_ue_t *amf_ue,
|
||||||
ogs_assert(amf_ue);
|
ogs_assert(amf_ue);
|
||||||
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
||||||
ogs_assert(ran_ue);
|
ogs_assert(ran_ue);
|
||||||
|
ogs_assert(identity_response);
|
||||||
|
|
||||||
mobile_identity = &identity_response->mobile_identity;
|
mobile_identity = &identity_response->mobile_identity;
|
||||||
|
|
||||||
|
@ -940,12 +951,15 @@ ogs_nas_5gmm_cause_t gmm_handle_identity_response(amf_ue_t *amf_ue,
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_nas_5gmm_cause_t gmm_handle_security_mode_complete(amf_ue_t *amf_ue,
|
ogs_nas_5gmm_cause_t gmm_handle_security_mode_complete(amf_ue_t *amf_ue,
|
||||||
ogs_nas_5gs_security_mode_complete_t *security_mode_complete)
|
ogs_nas_5gs_security_mode_complete_t *security_mode_complete)
|
||||||
{
|
{
|
||||||
|
ran_ue_t *ran_ue = NULL;
|
||||||
ogs_nas_5gs_mobile_identity_t *imeisv = NULL;
|
ogs_nas_5gs_mobile_identity_t *imeisv = NULL;
|
||||||
ogs_nas_mobile_identity_imeisv_t *mobile_identity_imeisv = NULL;
|
ogs_nas_mobile_identity_imeisv_t *mobile_identity_imeisv = NULL;
|
||||||
|
|
||||||
ogs_assert(amf_ue);
|
ogs_assert(amf_ue);
|
||||||
|
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
||||||
|
ogs_assert(ran_ue);
|
||||||
ogs_assert(security_mode_complete);
|
ogs_assert(security_mode_complete);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1021,7 +1035,7 @@ ogs_nas_5gmm_cause_t gmm_handle_security_mode_complete(amf_ue_t *amf_ue,
|
||||||
OGS_NAS_5GS_SECURITY_MODE_COMPLETE_NAS_MESSAGE_CONTAINER_PRESENT) {
|
OGS_NAS_5GS_SECURITY_MODE_COMPLETE_NAS_MESSAGE_CONTAINER_PRESENT) {
|
||||||
|
|
||||||
return gmm_handle_nas_message_container(
|
return gmm_handle_nas_message_container(
|
||||||
amf_ue, OGS_NAS_5GS_SECURITY_MODE_COMPLETE,
|
ran_ue, amf_ue, OGS_NAS_5GS_SECURITY_MODE_COMPLETE,
|
||||||
&security_mode_complete->nas_message_container);
|
&security_mode_complete->nas_message_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1316,14 +1330,15 @@ int gmm_handle_ul_nas_transport(ran_ue_t *ran_ue, amf_ue_t *amf_ue,
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION,
|
||||||
discovery_option,
|
discovery_option,
|
||||||
amf_nsmf_pdusession_build_create_sm_context,
|
amf_nsmf_pdusession_build_create_sm_context,
|
||||||
sess, AMF_CREATE_SM_CONTEXT_NO_STATE, NULL);
|
ran_ue, sess, AMF_CREATE_SM_CONTEXT_NO_STATE, NULL);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
} else {
|
} else {
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NNSSF_NSSELECTION,
|
OGS_SBI_SERVICE_TYPE_NNSSF_NSSELECTION,
|
||||||
discovery_option,
|
discovery_option,
|
||||||
amf_nnssf_nsselection_build_get, sess, 0, NULL);
|
amf_nnssf_nsselection_build_get,
|
||||||
|
ran_ue, sess, 0, NULL);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -1337,7 +1352,8 @@ int gmm_handle_ul_nas_transport(ran_ue_t *ran_ue, amf_ue_t *amf_ue,
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_DUPLICATED_PDU_SESSION_ID,
|
ran_ue, sess,
|
||||||
|
AMF_UPDATE_SM_CONTEXT_DUPLICATED_PDU_SESSION_ID,
|
||||||
¶m);
|
¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
@ -1366,7 +1382,8 @@ int gmm_handle_ul_nas_transport(ran_ue_t *ran_ue, amf_ue_t *amf_ue,
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_N1_RELEASED, ¶m);
|
ran_ue, sess,
|
||||||
|
AMF_UPDATE_SM_CONTEXT_N1_RELEASED, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1374,7 +1391,7 @@ int gmm_handle_ul_nas_transport(ran_ue_t *ran_ue, amf_ue_t *amf_ue,
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_MODIFIED, ¶m);
|
ran_ue, sess, AMF_UPDATE_SM_CONTEXT_MODIFIED, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -1440,7 +1457,7 @@ int gmm_handle_ul_nas_transport(ran_ue_t *ran_ue, amf_ue_t *amf_ue,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ogs_nas_5gmm_cause_t gmm_handle_nas_message_container(
|
static ogs_nas_5gmm_cause_t gmm_handle_nas_message_container(
|
||||||
amf_ue_t *amf_ue, uint8_t message_type,
|
ran_ue_t *ran_ue, amf_ue_t *amf_ue, uint8_t message_type,
|
||||||
ogs_nas_message_container_t *nas_message_container)
|
ogs_nas_message_container_t *nas_message_container)
|
||||||
{
|
{
|
||||||
int gmm_cause;
|
int gmm_cause;
|
||||||
|
@ -1449,6 +1466,7 @@ static ogs_nas_5gmm_cause_t gmm_handle_nas_message_container(
|
||||||
ogs_nas_5gs_message_t nas_message;
|
ogs_nas_5gs_message_t nas_message;
|
||||||
|
|
||||||
ogs_assert(amf_ue);
|
ogs_assert(amf_ue);
|
||||||
|
ogs_assert(ran_ue);
|
||||||
ogs_assert(nas_message_container);
|
ogs_assert(nas_message_container);
|
||||||
|
|
||||||
if (!nas_message_container->buffer || !nas_message_container->length) {
|
if (!nas_message_container->buffer || !nas_message_container->length) {
|
||||||
|
@ -1505,12 +1523,12 @@ static ogs_nas_5gmm_cause_t gmm_handle_nas_message_container(
|
||||||
case OGS_NAS_5GS_REGISTRATION_REQUEST:
|
case OGS_NAS_5GS_REGISTRATION_REQUEST:
|
||||||
ogs_debug("Registration request in NAS message container");
|
ogs_debug("Registration request in NAS message container");
|
||||||
gmm_cause = gmm_handle_registration_update(
|
gmm_cause = gmm_handle_registration_update(
|
||||||
amf_ue, &nas_message.gmm.registration_request);
|
ran_ue, amf_ue, &nas_message.gmm.registration_request);
|
||||||
break;
|
break;
|
||||||
case OGS_NAS_5GS_SERVICE_REQUEST:
|
case OGS_NAS_5GS_SERVICE_REQUEST:
|
||||||
ogs_debug("Service request in NAS message container");
|
ogs_debug("Service request in NAS message container");
|
||||||
gmm_cause = gmm_handle_service_update(
|
gmm_cause = gmm_handle_service_update(
|
||||||
amf_ue, &nas_message.gmm.service_request);
|
ran_ue, amf_ue, &nas_message.gmm.service_request);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ogs_error("Unknown message [%d]", nas_message.gmm.h.message_type);
|
ogs_error("Unknown message [%d]", nas_message.gmm.h.message_type);
|
||||||
|
@ -1520,6 +1538,243 @@ static ogs_nas_5gmm_cause_t gmm_handle_nas_message_container(
|
||||||
return gmm_cause;
|
return gmm_cause;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ogs_nas_5gmm_capability_t
|
||||||
|
amf_namf_comm_base64_decode_5gmm_capability(char *encoded)
|
||||||
|
{
|
||||||
|
ogs_nas_5gmm_capability_t gmm_capability;
|
||||||
|
char *gmm_capability_octets_string = NULL;
|
||||||
|
uint8_t gmm_capability_iei = 0;
|
||||||
|
|
||||||
|
memset(&gmm_capability, 0, sizeof(gmm_capability));
|
||||||
|
gmm_capability_octets_string =
|
||||||
|
(char*) ogs_calloc(sizeof(gmm_capability) + 1, sizeof(char));
|
||||||
|
ogs_assert(gmm_capability_octets_string);
|
||||||
|
|
||||||
|
int len = ogs_base64_decode(gmm_capability_octets_string, encoded);
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
ogs_error("Gmm capability not decoded");
|
||||||
|
|
||||||
|
ogs_assert(sizeof(gmm_capability_octets_string) <=
|
||||||
|
sizeof(gmm_capability) + 1);
|
||||||
|
|
||||||
|
gmm_capability_iei = // not copied anywhere for now
|
||||||
|
gmm_capability_octets_string[0];
|
||||||
|
if (gmm_capability_iei !=
|
||||||
|
OGS_NAS_5GS_REGISTRATION_REQUEST_5GMM_CAPABILITY_TYPE) {
|
||||||
|
ogs_error("Type of 5GMM capability IEI is incorrect");
|
||||||
|
}
|
||||||
|
memcpy(&gmm_capability,
|
||||||
|
gmm_capability_octets_string + 1,
|
||||||
|
sizeof(gmm_capability));
|
||||||
|
if (gmm_capability_octets_string) {
|
||||||
|
ogs_free(gmm_capability_octets_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gmm_capability;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ogs_nas_ue_security_capability_t
|
||||||
|
amf_namf_comm_base64_decode_ue_security_capability(char *encoded)
|
||||||
|
{
|
||||||
|
ogs_nas_ue_security_capability_t ue_security_capability;
|
||||||
|
char *ue_security_capability_octets_string = NULL;
|
||||||
|
uint8_t ue_security_capability_iei = 0;
|
||||||
|
|
||||||
|
memset(&ue_security_capability, 0, sizeof(ue_security_capability));
|
||||||
|
ue_security_capability_octets_string =
|
||||||
|
(char*) ogs_calloc(sizeof(ue_security_capability), sizeof(char));
|
||||||
|
ogs_assert(ue_security_capability_octets_string);
|
||||||
|
|
||||||
|
ogs_base64_decode(ue_security_capability_octets_string, encoded);
|
||||||
|
|
||||||
|
ogs_assert(sizeof(ue_security_capability_octets_string) <=
|
||||||
|
sizeof(ogs_nas_ue_security_capability_t) + 1);
|
||||||
|
|
||||||
|
ue_security_capability_iei = // not copied anywhere for now
|
||||||
|
ue_security_capability_octets_string[0];
|
||||||
|
if (ue_security_capability_iei !=
|
||||||
|
OGS_NAS_5GS_REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_TYPE) {
|
||||||
|
ogs_error("UE security capability IEI is incorrect");
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&ue_security_capability, ue_security_capability_octets_string + 1,
|
||||||
|
sizeof(ue_security_capability));
|
||||||
|
|
||||||
|
if (ue_security_capability_octets_string) {
|
||||||
|
ogs_free(ue_security_capability_octets_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ue_security_capability;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amf_namf_comm_decode_ue_mm_context_list(
|
||||||
|
amf_ue_t *amf_ue, OpenAPI_list_t *MmContextList) {
|
||||||
|
|
||||||
|
OpenAPI_lnode_t *node = NULL;
|
||||||
|
|
||||||
|
OpenAPI_list_for_each(MmContextList, node) {
|
||||||
|
|
||||||
|
OpenAPI_mm_context_t *MmContext = NULL;
|
||||||
|
OpenAPI_list_t *AllowedNssaiList = NULL;
|
||||||
|
OpenAPI_lnode_t *node1 = NULL;
|
||||||
|
OpenAPI_list_t *NssaiMappingList = NULL;
|
||||||
|
int num_of_s_nssai = 0;
|
||||||
|
int num_of_nssai_mapping = 0;
|
||||||
|
|
||||||
|
MmContext = node->data;
|
||||||
|
|
||||||
|
AllowedNssaiList = MmContext->allowed_nssai;
|
||||||
|
NssaiMappingList = MmContext->nssai_mapping_list;
|
||||||
|
|
||||||
|
OpenAPI_list_for_each(AllowedNssaiList, node1) {
|
||||||
|
OpenAPI_snssai_t *AllowedNssai = node1->data;
|
||||||
|
|
||||||
|
ogs_assert(num_of_s_nssai < OGS_MAX_NUM_OF_SLICE);
|
||||||
|
|
||||||
|
amf_ue->allowed_nssai.s_nssai[num_of_s_nssai].sst =
|
||||||
|
(uint8_t)AllowedNssai->sst;
|
||||||
|
amf_ue->allowed_nssai.s_nssai[num_of_s_nssai].sd =
|
||||||
|
ogs_s_nssai_sd_from_string(AllowedNssai->sd);
|
||||||
|
|
||||||
|
num_of_s_nssai++;
|
||||||
|
amf_ue->allowed_nssai.num_of_s_nssai = num_of_s_nssai;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenAPI_list_for_each(NssaiMappingList, node1) {
|
||||||
|
OpenAPI_nssai_mapping_t *NssaiMapping = node1->data;
|
||||||
|
OpenAPI_snssai_t *HSnssai = NssaiMapping->h_snssai;
|
||||||
|
|
||||||
|
ogs_assert(num_of_nssai_mapping < OGS_MAX_NUM_OF_SLICE);
|
||||||
|
|
||||||
|
amf_ue->allowed_nssai.s_nssai[num_of_nssai_mapping].
|
||||||
|
mapped_hplmn_sst = HSnssai->sst;
|
||||||
|
amf_ue->allowed_nssai.s_nssai[num_of_nssai_mapping].
|
||||||
|
mapped_hplmn_sd = ogs_s_nssai_sd_from_string(HSnssai->sd);
|
||||||
|
|
||||||
|
num_of_nssai_mapping++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MmContext->ue_security_capability) {
|
||||||
|
amf_ue->ue_security_capability =
|
||||||
|
amf_namf_comm_base64_decode_ue_security_capability(
|
||||||
|
MmContext->ue_security_capability);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amf_namf_comm_decode_ue_session_context_list(
|
||||||
|
amf_ue_t *amf_ue, OpenAPI_list_t *SessionContextList)
|
||||||
|
{
|
||||||
|
OpenAPI_lnode_t *node = NULL;
|
||||||
|
|
||||||
|
OpenAPI_list_for_each(SessionContextList, node) {
|
||||||
|
OpenAPI_pdu_session_context_t *PduSessionContext;
|
||||||
|
PduSessionContext = node->data;
|
||||||
|
amf_sess_t *sess = NULL;
|
||||||
|
|
||||||
|
sess = amf_sess_add(amf_ue, PduSessionContext->pdu_session_id);
|
||||||
|
ogs_assert(sess);
|
||||||
|
|
||||||
|
sess->sm_context_ref = PduSessionContext->sm_context_ref;
|
||||||
|
|
||||||
|
if (PduSessionContext->s_nssai) {
|
||||||
|
memset(&sess->s_nssai, 0, sizeof(sess->s_nssai));
|
||||||
|
|
||||||
|
sess->s_nssai.sst = PduSessionContext->s_nssai->sst;
|
||||||
|
sess->s_nssai.sd = ogs_s_nssai_sd_from_string(
|
||||||
|
PduSessionContext->s_nssai->sd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PduSessionContext->dnn)
|
||||||
|
sess->dnn = ogs_strdup(PduSessionContext->dnn);
|
||||||
|
if (PduSessionContext->access_type)
|
||||||
|
amf_ue->nas.access_type = (int)PduSessionContext->access_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int amf_namf_comm_handle_ue_context_transfer_response(
|
||||||
|
ogs_sbi_message_t *recvmsg, amf_ue_t *amf_ue)
|
||||||
|
{
|
||||||
|
OpenAPI_ue_context_t *UeContext = NULL;
|
||||||
|
|
||||||
|
ogs_error("V funkciji amf_namf_comm_handle_ue_context_transfer_response");
|
||||||
|
|
||||||
|
if (!recvmsg->UeContextTransferRspData) {
|
||||||
|
ogs_error("No UeContextTransferRspData");
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!recvmsg->UeContextTransferRspData->ue_context) {
|
||||||
|
ogs_error("No UE context");
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
UeContext = recvmsg->UeContextTransferRspData->ue_context;
|
||||||
|
|
||||||
|
if (UeContext->supi) {
|
||||||
|
amf_ue_set_supi(amf_ue, UeContext->supi);
|
||||||
|
if (!UeContext->supi_unauth_ind){
|
||||||
|
amf_ue->auth_result = OpenAPI_auth_result_AUTHENTICATION_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UeContext->pei) {
|
||||||
|
if (amf_ue->pei)
|
||||||
|
ogs_free(amf_ue->pei);
|
||||||
|
amf_ue->pei = ogs_strdup(UeContext->pei);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UeContext->sub_ue_ambr) {
|
||||||
|
amf_ue->ue_ambr.downlink =
|
||||||
|
ogs_sbi_bitrate_from_string(UeContext->sub_ue_ambr->downlink);
|
||||||
|
amf_ue->ue_ambr.uplink =
|
||||||
|
ogs_sbi_bitrate_from_string(UeContext->sub_ue_ambr->uplink);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UeContext->seaf_data) {
|
||||||
|
if (UeContext->seaf_data->ng_ksi->tsc != OpenAPI_sc_type_NULL) {
|
||||||
|
amf_ue->nas.ue.tsc =
|
||||||
|
(UeContext->seaf_data->ng_ksi->tsc == OpenAPI_sc_type_NATIVE) ? 0 : 1;
|
||||||
|
amf_ue->nas.ue.ksi = (uint8_t)UeContext->seaf_data->ng_ksi->ksi;
|
||||||
|
|
||||||
|
ogs_ascii_to_hex(
|
||||||
|
UeContext->seaf_data->key_amf->key_val,
|
||||||
|
strlen(UeContext->seaf_data->key_amf->key_val),
|
||||||
|
amf_ue->kamf,
|
||||||
|
sizeof(amf_ue->kamf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UeContext->_5g_mm_capability) {
|
||||||
|
ogs_nas_5gmm_capability_t gmm_capability;
|
||||||
|
|
||||||
|
gmm_capability = amf_namf_comm_base64_decode_5gmm_capability(
|
||||||
|
UeContext->_5g_mm_capability);
|
||||||
|
amf_ue->gmm_capability.lte_positioning_protocol_capability =
|
||||||
|
(bool)gmm_capability.lte_positioning_protocol_capability;
|
||||||
|
amf_ue->gmm_capability.ho_attach = (bool)gmm_capability.ho_attach;
|
||||||
|
amf_ue->gmm_capability.s1_mode = (bool)gmm_capability.s1_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UeContext->pcf_id) {
|
||||||
|
/* TODO */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO UeContext->pcfAmPolicyUri */
|
||||||
|
/* TODO UeContext->pcfUePolicyUri */
|
||||||
|
|
||||||
|
if (UeContext->mm_context_list)
|
||||||
|
amf_namf_comm_decode_ue_mm_context_list(amf_ue, UeContext->mm_context_list);
|
||||||
|
|
||||||
|
if (UeContext->session_context_list)
|
||||||
|
amf_namf_comm_decode_ue_session_context_list(amf_ue, UeContext->session_context_list);
|
||||||
|
|
||||||
|
/* TODO ueRadioCapability */
|
||||||
|
|
||||||
|
return OGS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t gmm_cause_from_access_control(ogs_plmn_id_t *plmn_id)
|
static uint8_t gmm_cause_from_access_control(ogs_plmn_id_t *plmn_id)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define GMM_HANDLER_H
|
#define GMM_HANDLER_H
|
||||||
|
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
#include "namf-handler.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -29,13 +30,15 @@ extern "C" {
|
||||||
ogs_nas_5gmm_cause_t gmm_handle_registration_request(amf_ue_t *amf_ue,
|
ogs_nas_5gmm_cause_t gmm_handle_registration_request(amf_ue_t *amf_ue,
|
||||||
ogs_nas_security_header_type_t h, NGAP_ProcedureCode_t ngap_code,
|
ogs_nas_security_header_type_t h, NGAP_ProcedureCode_t ngap_code,
|
||||||
ogs_nas_5gs_registration_request_t *registration_request);
|
ogs_nas_5gs_registration_request_t *registration_request);
|
||||||
ogs_nas_5gmm_cause_t gmm_handle_registration_update(amf_ue_t *amf_ue,
|
ogs_nas_5gmm_cause_t gmm_handle_registration_update(
|
||||||
|
ran_ue_t *ran_ue, amf_ue_t *amf_ue,
|
||||||
ogs_nas_5gs_registration_request_t *registration_request);
|
ogs_nas_5gs_registration_request_t *registration_request);
|
||||||
|
|
||||||
ogs_nas_5gmm_cause_t gmm_handle_service_request(amf_ue_t *amf_ue,
|
ogs_nas_5gmm_cause_t gmm_handle_service_request(amf_ue_t *amf_ue,
|
||||||
ogs_nas_security_header_type_t h, NGAP_ProcedureCode_t ngap_code,
|
ogs_nas_security_header_type_t h, NGAP_ProcedureCode_t ngap_code,
|
||||||
ogs_nas_5gs_service_request_t *service_request);
|
ogs_nas_5gs_service_request_t *service_request);
|
||||||
ogs_nas_5gmm_cause_t gmm_handle_service_update(amf_ue_t *amf_ue,
|
ogs_nas_5gmm_cause_t gmm_handle_service_update(
|
||||||
|
ran_ue_t *ran_ue, amf_ue_t *amf_ue,
|
||||||
ogs_nas_5gs_service_request_t *service_request);
|
ogs_nas_5gs_service_request_t *service_request);
|
||||||
|
|
||||||
int gmm_handle_deregistration_request(amf_ue_t *amf_ue,
|
int gmm_handle_deregistration_request(amf_ue_t *amf_ue,
|
||||||
|
|
141
src/amf/gmm-sm.c
141
src/amf/gmm-sm.c
|
@ -27,8 +27,10 @@
|
||||||
#include "nsmf-handler.h"
|
#include "nsmf-handler.h"
|
||||||
#include "nudm-handler.h"
|
#include "nudm-handler.h"
|
||||||
#include "npcf-handler.h"
|
#include "npcf-handler.h"
|
||||||
|
#include "namf-handler.h"
|
||||||
#include "sbi-path.h"
|
#include "sbi-path.h"
|
||||||
#include "amf-sm.h"
|
#include "amf-sm.h"
|
||||||
|
#include "namf-build.h"
|
||||||
|
|
||||||
#undef OGS_LOG_DOMAIN
|
#undef OGS_LOG_DOMAIN
|
||||||
#define OGS_LOG_DOMAIN __gmm_log_domain
|
#define OGS_LOG_DOMAIN __gmm_log_domain
|
||||||
|
@ -299,7 +301,7 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
|
||||||
AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED) {
|
AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED) {
|
||||||
|
|
||||||
int xact_count = amf_sess_xact_count(amf_ue);
|
int xact_count = amf_sess_xact_count(amf_ue);
|
||||||
amf_sbi_send_release_all_sessions(amf_ue, state);
|
amf_sbi_send_release_all_sessions(NULL, amf_ue, state);
|
||||||
|
|
||||||
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
||||||
amf_sess_xact_count(amf_ue) == xact_count) {
|
amf_sess_xact_count(amf_ue) == xact_count) {
|
||||||
|
@ -546,6 +548,59 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
|
||||||
END
|
END
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
|
||||||
|
SWITCH(sbi_message->h.resource.component[0])
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXTS)
|
||||||
|
SWITCH(sbi_message->h.resource.component[2])
|
||||||
|
CASE(OGS_SBI_RESOURCE_NAME_TRANSFER)
|
||||||
|
|
||||||
|
if (sbi_message->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||||||
|
r = amf_namf_comm_handle_ue_context_transfer_response(sbi_message, amf_ue);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
int xact_count = amf_sess_xact_count(amf_ue);
|
||||||
|
|
||||||
|
if (!AMF_UE_HAVE_SUCI(amf_ue)) {
|
||||||
|
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
|
||||||
|
r = nas_5gs_send_identity_request(amf_ue);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
amf_sbi_send_release_all_sessions(
|
||||||
|
amf_ue->ran_ue, amf_ue,
|
||||||
|
AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||||
|
|
||||||
|
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
||||||
|
amf_sess_xact_count(amf_ue) == xact_count) {
|
||||||
|
r = amf_ue_sbi_discover_and_send(
|
||||||
|
OGS_SBI_SERVICE_TYPE_NAUSF_AUTH, NULL,
|
||||||
|
amf_nausf_auth_build_authenticate,
|
||||||
|
amf_ue, 0, NULL);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
OGS_FSM_TRAN(s, &gmm_state_authentication);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid resource name [%s]",
|
||||||
|
sbi_message->h.resource.component[2]);
|
||||||
|
ogs_assert_if_reached();
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
|
DEFAULT
|
||||||
|
ogs_error("Invalid resource name [%s]",
|
||||||
|
sbi_message->h.resource.component[0]);
|
||||||
|
ogs_assert_if_reached();
|
||||||
|
END
|
||||||
|
break;
|
||||||
|
|
||||||
DEFAULT
|
DEFAULT
|
||||||
ogs_error("Invalid service name [%s]", sbi_message->h.service.name);
|
ogs_error("Invalid service name [%s]", sbi_message->h.service.name);
|
||||||
ogs_assert_if_reached();
|
ogs_assert_if_reached();
|
||||||
|
@ -829,7 +884,7 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e)
|
||||||
AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED) {
|
AMF_NETWORK_INITIATED_EXPLICIT_DE_REGISTERED) {
|
||||||
|
|
||||||
int xact_count = amf_sess_xact_count(amf_ue);
|
int xact_count = amf_sess_xact_count(amf_ue);
|
||||||
amf_sbi_send_release_all_sessions(amf_ue, state);
|
amf_sbi_send_release_all_sessions(NULL, amf_ue, state);
|
||||||
|
|
||||||
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
||||||
amf_sess_xact_count(amf_ue) == xact_count) {
|
amf_sess_xact_count(amf_ue) == xact_count) {
|
||||||
|
@ -1000,7 +1055,8 @@ void gmm_state_registered(ogs_fsm_t *s, amf_event_t *e)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
amf_sbi_send_release_all_sessions(amf_ue, state);
|
amf_sbi_send_release_all_sessions(
|
||||||
|
NULL, amf_ue, state);
|
||||||
|
|
||||||
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
||||||
amf_sess_xact_count(amf_ue) == xact_count) {
|
amf_sess_xact_count(amf_ue) == xact_count) {
|
||||||
|
@ -1136,6 +1192,9 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e,
|
||||||
amf_sess_t *sess = NULL;
|
amf_sess_t *sess = NULL;
|
||||||
ogs_nas_5gs_message_t *nas_message = NULL;
|
ogs_nas_5gs_message_t *nas_message = NULL;
|
||||||
ogs_nas_security_header_type_t h;
|
ogs_nas_security_header_type_t h;
|
||||||
|
ogs_nas_5gs_registration_request_t *registration_request = NULL;
|
||||||
|
ogs_nas_5gs_mobile_identity_header_t *mobile_identity_header = NULL;
|
||||||
|
ogs_nas_5gs_mobile_identity_t *mobile_identity = NULL;
|
||||||
|
|
||||||
ogs_assert(e);
|
ogs_assert(e);
|
||||||
|
|
||||||
|
@ -1194,6 +1253,66 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registration_request = &nas_message->gmm.registration_request;
|
||||||
|
mobile_identity = ®istration_request->mobile_identity;
|
||||||
|
mobile_identity_header =
|
||||||
|
(ogs_nas_5gs_mobile_identity_header_t *)mobile_identity->buffer;
|
||||||
|
|
||||||
|
/* Check if registration is done with GUTI */
|
||||||
|
if (mobile_identity_header && mobile_identity_header->type ==
|
||||||
|
OGS_NAS_5GS_MOBILE_IDENTITY_GUTI &&
|
||||||
|
ogs_nas_5gs_guti_is_valid(&amf_ue->current.guti)) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TS 23.502
|
||||||
|
* 4.2.2.2.2 General Registration
|
||||||
|
* (Without UDSF Deployment): If the UE's 5G-GUTI was included in the
|
||||||
|
* Registration Request and the serving AMF has changed since last
|
||||||
|
* Registration procedure, the new AMF may invoke the
|
||||||
|
* Namf_Communication_UEContextTransfer service operation on the
|
||||||
|
* old AMF including the complete Registration Request NAS message,
|
||||||
|
* which may be integrity protected, as well as the Access Type,
|
||||||
|
* to request the UE's SUPI and UE Context. See clause 5.2.2.2.2
|
||||||
|
* for details of this service operation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int state = e->h.sbi.state;
|
||||||
|
bool serving_guami = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Compare all serving guamis with guami from UE's GUTI */
|
||||||
|
for (i = 0; i < amf_self()->num_of_served_guami; i++) {
|
||||||
|
if ((memcmp(&amf_self()->served_guami[i].amf_id,
|
||||||
|
&amf_ue->current.guti.amf_id,
|
||||||
|
sizeof(ogs_amf_id_t)) == 0) &&
|
||||||
|
(memcmp(&amf_self()->served_guami[i].plmn_id,
|
||||||
|
&amf_ue->current.guti.nas_plmn_id,
|
||||||
|
OGS_PLMN_ID_LEN) == 0)) {
|
||||||
|
|
||||||
|
serving_guami = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!serving_guami) {
|
||||||
|
/* Guami from UE is not this AMF's serving guami - send UEContextTransfer */
|
||||||
|
ogs_sbi_discovery_option_t *discovery_option = NULL;
|
||||||
|
|
||||||
|
discovery_option = ogs_sbi_discovery_option_new();
|
||||||
|
ogs_assert(discovery_option);
|
||||||
|
|
||||||
|
memcpy(discovery_option->target_guami,
|
||||||
|
amf_ue->guami, sizeof(ogs_guami_t));
|
||||||
|
|
||||||
|
int r = amf_ue_sbi_discover_and_send(
|
||||||
|
OGS_SBI_SERVICE_TYPE_NAMF_COMM, discovery_option,
|
||||||
|
amf_namf_comm_build_ue_context_transfer,
|
||||||
|
amf_ue, state, nas_message);
|
||||||
|
ogs_expect(r == OGS_OK);
|
||||||
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!AMF_UE_HAVE_SUCI(amf_ue)) {
|
if (!AMF_UE_HAVE_SUCI(amf_ue)) {
|
||||||
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
|
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
|
||||||
r = nas_5gs_send_identity_request(amf_ue);
|
r = nas_5gs_send_identity_request(amf_ue);
|
||||||
|
@ -1212,7 +1331,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e,
|
||||||
CLEAR_NG_CONTEXT(amf_ue);
|
CLEAR_NG_CONTEXT(amf_ue);
|
||||||
|
|
||||||
gmm_cause = gmm_handle_registration_update(
|
gmm_cause = gmm_handle_registration_update(
|
||||||
amf_ue, &nas_message->gmm.registration_request);
|
ran_ue, amf_ue, &nas_message->gmm.registration_request);
|
||||||
if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) {
|
if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_error("[%s] gmm_handle_registration_update() "
|
ogs_error("[%s] gmm_handle_registration_update() "
|
||||||
"failed [%d]", amf_ue->suci, gmm_cause);
|
"failed [%d]", amf_ue->suci, gmm_cause);
|
||||||
|
@ -1271,7 +1390,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e,
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
amf_sbi_send_release_all_sessions(
|
amf_sbi_send_release_all_sessions(
|
||||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
ran_ue, amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||||
|
|
||||||
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
||||||
amf_sess_xact_count(amf_ue) == xact_count) {
|
amf_sess_xact_count(amf_ue) == xact_count) {
|
||||||
|
@ -1341,7 +1460,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e,
|
||||||
CLEAR_NG_CONTEXT(amf_ue);
|
CLEAR_NG_CONTEXT(amf_ue);
|
||||||
|
|
||||||
gmm_cause = gmm_handle_service_update(
|
gmm_cause = gmm_handle_service_update(
|
||||||
amf_ue, &nas_message->gmm.service_request);
|
ran_ue, amf_ue, &nas_message->gmm.service_request);
|
||||||
if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) {
|
if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_error("[%s] gmm_handle_service_update() failed [%d]",
|
ogs_error("[%s] gmm_handle_service_update() failed [%d]",
|
||||||
amf_ue->suci, gmm_cause);
|
amf_ue->suci, gmm_cause);
|
||||||
|
@ -1392,7 +1511,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e,
|
||||||
}
|
}
|
||||||
|
|
||||||
amf_sbi_send_release_all_sessions(
|
amf_sbi_send_release_all_sessions(
|
||||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
ran_ue, amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||||
|
|
||||||
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
||||||
amf_sess_xact_count(amf_ue) == xact_count) {
|
amf_sess_xact_count(amf_ue) == xact_count) {
|
||||||
|
@ -2296,7 +2415,7 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
|
||||||
}
|
}
|
||||||
|
|
||||||
amf_sbi_send_release_all_sessions(
|
amf_sbi_send_release_all_sessions(
|
||||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
ran_ue, amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||||
|
|
||||||
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
||||||
amf_sess_xact_count(amf_ue) == xact_count) {
|
amf_sess_xact_count(amf_ue) == xact_count) {
|
||||||
|
@ -2431,7 +2550,7 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
|
||||||
xact_count = amf_sess_xact_count(amf_ue);
|
xact_count = amf_sess_xact_count(amf_ue);
|
||||||
|
|
||||||
amf_sbi_send_release_all_sessions(
|
amf_sbi_send_release_all_sessions(
|
||||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
amf_ue->ran_ue, amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||||
|
|
||||||
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
||||||
amf_sess_xact_count(amf_ue) == xact_count) {
|
amf_sess_xact_count(amf_ue) == xact_count) {
|
||||||
|
@ -2492,7 +2611,7 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
|
||||||
CLEAR_NG_CONTEXT(amf_ue);
|
CLEAR_NG_CONTEXT(amf_ue);
|
||||||
|
|
||||||
gmm_cause = gmm_handle_registration_update(
|
gmm_cause = gmm_handle_registration_update(
|
||||||
amf_ue, &nas_message->gmm.registration_request);
|
ran_ue, amf_ue, &nas_message->gmm.registration_request);
|
||||||
if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) {
|
if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_error("[%s] gmm_handle_registration_update() "
|
ogs_error("[%s] gmm_handle_registration_update() "
|
||||||
"failed [%d]", amf_ue->suci, gmm_cause);
|
"failed [%d]", amf_ue->suci, gmm_cause);
|
||||||
|
@ -2543,7 +2662,7 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
amf_sbi_send_release_all_sessions(
|
amf_sbi_send_release_all_sessions(
|
||||||
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
ran_ue, amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
|
||||||
|
|
||||||
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
if (!AMF_SESSION_RELEASE_PENDING(amf_ue) &&
|
||||||
amf_sess_xact_count(amf_ue) == xact_count) {
|
amf_sess_xact_count(amf_ue) == xact_count) {
|
||||||
|
|
|
@ -40,6 +40,7 @@ libamf_sources = files('''
|
||||||
nnrf-build.c
|
nnrf-build.c
|
||||||
nnrf-handler.c
|
nnrf-handler.c
|
||||||
|
|
||||||
|
namf-build.c
|
||||||
namf-handler.c
|
namf-handler.c
|
||||||
sbi-path.c
|
sbi-path.c
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Open5GS.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "namf-build.h"
|
||||||
|
|
||||||
|
static char* ogs_guti_to_string(amf_ue_t *amf_ue)
|
||||||
|
{
|
||||||
|
ogs_plmn_id_t plmn_id;
|
||||||
|
char plmn_id_buff[OGS_PLMNIDSTRLEN];
|
||||||
|
char *amf_id = NULL;
|
||||||
|
char *tmsi = NULL;
|
||||||
|
char *guti = NULL;
|
||||||
|
|
||||||
|
memset(&plmn_id, 0, sizeof(plmn_id));
|
||||||
|
ogs_nas_to_plmn_id(&plmn_id, &amf_ue->current.guti.nas_plmn_id);
|
||||||
|
|
||||||
|
amf_id = ogs_amf_id_to_string(&amf_ue->current.guti.amf_id);
|
||||||
|
tmsi = ogs_uint32_to_0string(*(amf_ue->current.m_tmsi));
|
||||||
|
|
||||||
|
guti = ogs_msprintf("5g-guti-%s%s%s",
|
||||||
|
ogs_plmn_id_to_string(&plmn_id, plmn_id_buff),
|
||||||
|
amf_id,
|
||||||
|
tmsi);
|
||||||
|
|
||||||
|
/* TS29.518 6.1.3.2.2 Guti pattern (27 or 28 characters):
|
||||||
|
"5g-guti-[0-9]{5,6}[0-9a-fA-F]{14}" */
|
||||||
|
ogs_assert(strlen(guti) == (OGS_MAX_5G_GUTI_LEN - 1) ||
|
||||||
|
(strlen(guti)) == OGS_MAX_5G_GUTI_LEN);
|
||||||
|
|
||||||
|
ogs_free(amf_id);
|
||||||
|
ogs_free(tmsi);
|
||||||
|
|
||||||
|
return guti;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* amf_ue_to_context_id(amf_ue_t *amf_ue)
|
||||||
|
{
|
||||||
|
char *ue_context_id = NULL;
|
||||||
|
|
||||||
|
if (amf_ue->supi) {
|
||||||
|
ue_context_id = ogs_strdup(amf_ue->supi);
|
||||||
|
} else {
|
||||||
|
ue_context_id = ogs_guti_to_string(amf_ue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ue_context_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
ogs_sbi_request_t *amf_namf_comm_build_ue_context_transfer(
|
||||||
|
amf_ue_t *amf_ue, void *data)
|
||||||
|
{
|
||||||
|
ogs_sbi_message_t message;
|
||||||
|
ogs_sbi_request_t *request = NULL;
|
||||||
|
OpenAPI_ue_context_transfer_req_data_t UeContextTransferReqData;
|
||||||
|
char *ue_context_id = NULL;
|
||||||
|
|
||||||
|
ogs_assert(amf_ue);
|
||||||
|
|
||||||
|
ue_context_id = amf_ue_to_context_id(amf_ue);
|
||||||
|
ogs_assert(ue_context_id);
|
||||||
|
|
||||||
|
memset(&UeContextTransferReqData, 0, sizeof(UeContextTransferReqData));
|
||||||
|
UeContextTransferReqData.access_type = amf_ue->nas.access_type;
|
||||||
|
UeContextTransferReqData.reason = amf_ue->nas.registration.value;
|
||||||
|
|
||||||
|
memset(&message, 0, sizeof(message));
|
||||||
|
message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST;
|
||||||
|
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NAMF_COMM;
|
||||||
|
message.h.api.version = (char *)OGS_SBI_API_V1;
|
||||||
|
message.h.resource.component[0] =
|
||||||
|
(char *)OGS_SBI_RESOURCE_NAME_UE_CONTEXTS;
|
||||||
|
message.h.resource.component[1] = ue_context_id;
|
||||||
|
message.h.resource.component[2] =
|
||||||
|
(char *)OGS_SBI_RESOURCE_NAME_TRANSFER;
|
||||||
|
message.UeContextTransferReqData = &UeContextTransferReqData;
|
||||||
|
|
||||||
|
request = ogs_sbi_build_request(&message);
|
||||||
|
ogs_expect(request);
|
||||||
|
|
||||||
|
if (ue_context_id)
|
||||||
|
ogs_free(ue_context_id);
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Open5GS.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AMF_NAMF_BUILD_H
|
||||||
|
#define AMF_NAMF_BUILD_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "context.h"
|
||||||
|
|
||||||
|
ogs_sbi_request_t *amf_namf_comm_build_ue_context_transfer(
|
||||||
|
amf_ue_t *amf_ue, void *data);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* AMF_NAMF_BUILD_H */
|
|
@ -1079,3 +1079,396 @@ cleanup:
|
||||||
|
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *amf_namf_comm_base64_encode_ue_security_capability(
|
||||||
|
ogs_nas_ue_security_capability_t ue_security_capability)
|
||||||
|
{
|
||||||
|
char *enc = NULL;
|
||||||
|
int enc_len = 0;
|
||||||
|
|
||||||
|
char num_of_octets =
|
||||||
|
ue_security_capability.length +
|
||||||
|
sizeof(ue_security_capability.length) +
|
||||||
|
sizeof((uint8_t)OGS_NAS_5GS_REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_TYPE);
|
||||||
|
/* Security guarantee */
|
||||||
|
num_of_octets = ogs_min(
|
||||||
|
num_of_octets, sizeof(ue_security_capability) + 1);
|
||||||
|
/*
|
||||||
|
* size [sizeof(ue_security_capability) + 1] is a sum of lengths:
|
||||||
|
* ue_security_capability (9 octets) +
|
||||||
|
* type (1 octet)
|
||||||
|
*/
|
||||||
|
char security_octets_string[sizeof(ue_security_capability) + 1];
|
||||||
|
|
||||||
|
enc_len = ogs_base64_encode_len(num_of_octets);
|
||||||
|
|
||||||
|
enc = ogs_malloc(enc_len);
|
||||||
|
ogs_assert(enc);
|
||||||
|
memset(enc, 0, sizeof(*enc));
|
||||||
|
|
||||||
|
security_octets_string[0] =
|
||||||
|
(uint8_t)OGS_NAS_5GS_REGISTRATION_REQUEST_UE_SECURITY_CAPABILITY_TYPE;
|
||||||
|
memcpy(security_octets_string + 1, &ue_security_capability, num_of_octets);
|
||||||
|
ogs_base64_encode(enc , security_octets_string, num_of_octets);
|
||||||
|
|
||||||
|
return enc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *amf_namf_comm_base64_encode_5gmm_capability(amf_ue_t *amf_ue)
|
||||||
|
{
|
||||||
|
ogs_nas_5gmm_capability_t nas_gmm_capability;
|
||||||
|
int enc_len = 0;
|
||||||
|
char *enc = NULL;
|
||||||
|
|
||||||
|
memset(&nas_gmm_capability, 0, sizeof(nas_gmm_capability));
|
||||||
|
|
||||||
|
/* 1 octet is mandatory, n.3 from TS 24.501 V16.12.0, 9.11.3.1 */
|
||||||
|
nas_gmm_capability.length = 1;
|
||||||
|
nas_gmm_capability.lte_positioning_protocol_capability =
|
||||||
|
amf_ue->gmm_capability.lte_positioning_protocol_capability;
|
||||||
|
nas_gmm_capability.ho_attach = amf_ue->gmm_capability.ho_attach;
|
||||||
|
nas_gmm_capability.s1_mode = amf_ue->gmm_capability.s1_mode;
|
||||||
|
|
||||||
|
uint8_t num_of_octets =
|
||||||
|
nas_gmm_capability.length +
|
||||||
|
sizeof(nas_gmm_capability.length) +
|
||||||
|
sizeof((uint8_t)OGS_NAS_5GS_REGISTRATION_REQUEST_5GMM_CAPABILITY_TYPE);
|
||||||
|
|
||||||
|
/* Security guarantee. + 1 stands for 5GMM capability IEI */
|
||||||
|
num_of_octets = ogs_min(
|
||||||
|
num_of_octets, sizeof(ogs_nas_5gmm_capability_t) + 1);
|
||||||
|
|
||||||
|
char gmm_capability_octets_string[sizeof(ogs_nas_5gmm_capability_t) + 1];
|
||||||
|
|
||||||
|
enc_len = ogs_base64_encode_len(num_of_octets);
|
||||||
|
enc = ogs_malloc(enc_len);
|
||||||
|
ogs_assert(enc);
|
||||||
|
memset(enc, 0, sizeof(*enc));
|
||||||
|
|
||||||
|
/* Fill the bytes of data */
|
||||||
|
gmm_capability_octets_string[0] =
|
||||||
|
(uint8_t)OGS_NAS_5GS_REGISTRATION_REQUEST_5GMM_CAPABILITY_TYPE;
|
||||||
|
memcpy(gmm_capability_octets_string + 1, &nas_gmm_capability, num_of_octets);
|
||||||
|
ogs_base64_encode(enc, gmm_capability_octets_string, num_of_octets);
|
||||||
|
|
||||||
|
return enc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OpenAPI_list_t *amf_namf_comm_encode_ue_session_context_list(amf_ue_t *amf_ue)
|
||||||
|
{
|
||||||
|
ogs_assert(amf_ue);
|
||||||
|
|
||||||
|
amf_sess_t *sess = NULL;
|
||||||
|
OpenAPI_list_t *PduSessionList = NULL;
|
||||||
|
OpenAPI_pdu_session_context_t *PduSessionContext = NULL;
|
||||||
|
OpenAPI_snssai_t *sNSSAI = NULL;
|
||||||
|
|
||||||
|
PduSessionList = OpenAPI_list_create();
|
||||||
|
ogs_assert(PduSessionList);
|
||||||
|
|
||||||
|
ogs_list_for_each(&amf_ue->sess_list, sess) {
|
||||||
|
PduSessionContext = ogs_calloc(1, sizeof(*PduSessionContext));
|
||||||
|
ogs_assert(PduSessionContext);
|
||||||
|
|
||||||
|
sNSSAI = ogs_calloc(1, sizeof(*sNSSAI));
|
||||||
|
ogs_assert(sNSSAI);
|
||||||
|
|
||||||
|
PduSessionContext->pdu_session_id = sess->psi;
|
||||||
|
PduSessionContext->sm_context_ref = sess->sm_context_ref;
|
||||||
|
|
||||||
|
sNSSAI->sst = sess->s_nssai.sst;
|
||||||
|
sNSSAI->sd = ogs_s_nssai_sd_to_string(sess->s_nssai.sd);
|
||||||
|
PduSessionContext->s_nssai = sNSSAI;
|
||||||
|
|
||||||
|
PduSessionContext->dnn = sess->dnn;
|
||||||
|
PduSessionContext->access_type = (OpenAPI_access_type_e)amf_ue->nas.access_type;
|
||||||
|
|
||||||
|
OpenAPI_list_add(PduSessionList, PduSessionContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PduSessionList;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OpenAPI_list_t *amf_namf_comm_encode_ue_mm_context_list(amf_ue_t *amf_ue)
|
||||||
|
{
|
||||||
|
OpenAPI_list_t *MmContextList = NULL;
|
||||||
|
OpenAPI_mm_context_t *MmContext = NULL;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ogs_assert(amf_ue);
|
||||||
|
|
||||||
|
|
||||||
|
MmContextList = OpenAPI_list_create();
|
||||||
|
ogs_assert(MmContextList);
|
||||||
|
|
||||||
|
MmContext = ogs_malloc(sizeof(*MmContext));
|
||||||
|
ogs_assert(MmContext);
|
||||||
|
memset(MmContext, 0, sizeof(*MmContext));
|
||||||
|
|
||||||
|
MmContext->access_type = (OpenAPI_access_type_e)amf_ue->nas.access_type;
|
||||||
|
|
||||||
|
if ((OpenAPI_ciphering_algorithm_e)amf_ue->selected_enc_algorithm &&
|
||||||
|
(OpenAPI_integrity_algorithm_e)amf_ue->selected_int_algorithm) {
|
||||||
|
|
||||||
|
OpenAPI_nas_security_mode_t *NasSecurityMode;
|
||||||
|
|
||||||
|
NasSecurityMode = ogs_calloc(1, sizeof(*NasSecurityMode));
|
||||||
|
ogs_assert(NasSecurityMode);
|
||||||
|
|
||||||
|
NasSecurityMode->ciphering_algorithm =
|
||||||
|
(OpenAPI_ciphering_algorithm_e)amf_ue->selected_enc_algorithm;
|
||||||
|
NasSecurityMode->integrity_algorithm =
|
||||||
|
(OpenAPI_integrity_algorithm_e)amf_ue->selected_int_algorithm;
|
||||||
|
|
||||||
|
MmContext->nas_security_mode = NasSecurityMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amf_ue->dl_count > 0) {
|
||||||
|
MmContext->is_nas_downlink_count = true;
|
||||||
|
MmContext->nas_downlink_count = amf_ue->dl_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amf_ue->ul_count.i32 > 0) {
|
||||||
|
MmContext->is_nas_uplink_count = true;
|
||||||
|
MmContext->nas_uplink_count = amf_ue->ul_count.i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amf_ue->ue_security_capability.length > 0) {
|
||||||
|
MmContext->ue_security_capability =
|
||||||
|
amf_namf_comm_base64_encode_ue_security_capability(
|
||||||
|
amf_ue->ue_security_capability);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amf_ue->allowed_nssai.num_of_s_nssai) {
|
||||||
|
|
||||||
|
OpenAPI_list_t *AllowedNssaiList;
|
||||||
|
OpenAPI_list_t *NssaiMappingList;
|
||||||
|
|
||||||
|
/* This IE shall be present if the source AMF and the target AMF are
|
||||||
|
* in the same PLMN and if available. When present, this IE shall
|
||||||
|
* contain the allowed NSSAI for the access type.
|
||||||
|
*/
|
||||||
|
AllowedNssaiList = OpenAPI_list_create();
|
||||||
|
|
||||||
|
/* This IE shall be present if the source AMF and the target AMF are
|
||||||
|
* in the same PLMN and if available. When present, this IE shall
|
||||||
|
* contain the mapping of the allowed NSSAI for the UE.
|
||||||
|
*/
|
||||||
|
NssaiMappingList = OpenAPI_list_create();
|
||||||
|
|
||||||
|
ogs_assert(AllowedNssaiList);
|
||||||
|
ogs_assert(NssaiMappingList);
|
||||||
|
|
||||||
|
for (i = 0; i < amf_ue->allowed_nssai.num_of_s_nssai; i++) {
|
||||||
|
OpenAPI_snssai_t *AllowedNssai;
|
||||||
|
|
||||||
|
AllowedNssai = ogs_calloc(1, sizeof(*AllowedNssai));
|
||||||
|
ogs_assert(AllowedNssai);
|
||||||
|
|
||||||
|
AllowedNssai->sst = amf_ue->allowed_nssai.s_nssai[i].sst;
|
||||||
|
AllowedNssai->sd = ogs_s_nssai_sd_to_string(
|
||||||
|
amf_ue->allowed_nssai.s_nssai[i].sd);
|
||||||
|
|
||||||
|
OpenAPI_list_add(AllowedNssaiList, AllowedNssai);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < amf_ue->allowed_nssai.num_of_s_nssai; i++) {
|
||||||
|
OpenAPI_nssai_mapping_t *NssaiMapping;
|
||||||
|
OpenAPI_snssai_t *HSnssai;
|
||||||
|
OpenAPI_snssai_t *MappedSnssai;
|
||||||
|
|
||||||
|
NssaiMapping = ogs_calloc(1, sizeof(*NssaiMapping));
|
||||||
|
ogs_assert(NssaiMapping);
|
||||||
|
|
||||||
|
/* Indicates the S-NSSAI in home PLMN */
|
||||||
|
HSnssai = ogs_calloc(1, sizeof(*HSnssai));
|
||||||
|
ogs_assert(HSnssai);
|
||||||
|
|
||||||
|
HSnssai->sst =
|
||||||
|
amf_ue->allowed_nssai.s_nssai[i].mapped_hplmn_sst;
|
||||||
|
HSnssai->sd =
|
||||||
|
ogs_s_nssai_sd_to_string(
|
||||||
|
amf_ue->allowed_nssai.s_nssai[i].mapped_hplmn_sd);
|
||||||
|
NssaiMapping->h_snssai = HSnssai;
|
||||||
|
|
||||||
|
/* Indicates the mapped S-NSSAI in the serving PLMN */
|
||||||
|
MappedSnssai = ogs_calloc(1, sizeof(*MappedSnssai));
|
||||||
|
ogs_assert(MappedSnssai);
|
||||||
|
|
||||||
|
/* MappedSnssai must be defined, else
|
||||||
|
"nssaiMappingList" will not convert to json*/
|
||||||
|
MappedSnssai->sst = 0;
|
||||||
|
MappedSnssai->sd = ogs_strdup("");
|
||||||
|
NssaiMapping->mapped_snssai = MappedSnssai;
|
||||||
|
|
||||||
|
OpenAPI_list_add(NssaiMappingList, NssaiMapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
MmContext->allowed_nssai = AllowedNssaiList;
|
||||||
|
MmContext->nssai_mapping_list = NssaiMappingList;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenAPI_list_add(MmContextList, MmContext);
|
||||||
|
|
||||||
|
return MmContextList;
|
||||||
|
}
|
||||||
|
|
||||||
|
int amf_namf_comm_handle_ue_context_transfer_request(
|
||||||
|
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
|
||||||
|
{
|
||||||
|
ogs_sbi_response_t *response = NULL;
|
||||||
|
ogs_sbi_message_t sendmsg;
|
||||||
|
amf_ue_t *amf_ue = NULL;
|
||||||
|
|
||||||
|
OpenAPI_ambr_t *UeAmbr = NULL;
|
||||||
|
OpenAPI_list_t *MmContextList = NULL;
|
||||||
|
OpenAPI_mm_context_t *MmContext = NULL;
|
||||||
|
OpenAPI_list_t *SessionContextList = NULL;
|
||||||
|
OpenAPI_pdu_session_context_t *PduSessionContext = NULL;
|
||||||
|
OpenAPI_lnode_t *node = NULL;
|
||||||
|
OpenAPI_ue_context_t UeContext;
|
||||||
|
OpenAPI_seaf_data_t SeafData;
|
||||||
|
OpenAPI_ng_ksi_t Ng_ksi;
|
||||||
|
OpenAPI_key_amf_t Key_amf;
|
||||||
|
OpenAPI_sc_type_e Tsc_type;
|
||||||
|
|
||||||
|
OpenAPI_ue_context_transfer_rsp_data_t UeContextTransferRspData;
|
||||||
|
|
||||||
|
char *ue_context_id = NULL;
|
||||||
|
char *encoded_gmm_capability = NULL;
|
||||||
|
int status = OGS_SBI_HTTP_STATUS_OK;
|
||||||
|
char hxkamf_string[OGS_KEYSTRLEN(OGS_SHA256_DIGEST_SIZE)];
|
||||||
|
char *strerror = NULL;
|
||||||
|
|
||||||
|
ogs_assert(stream);
|
||||||
|
ogs_assert(recvmsg);
|
||||||
|
|
||||||
|
memset(&UeContextTransferRspData, 0, sizeof(UeContextTransferRspData));
|
||||||
|
memset(&UeContext, 0, sizeof(UeContext));
|
||||||
|
UeContextTransferRspData.ue_context = &UeContext;
|
||||||
|
|
||||||
|
memset(&sendmsg, 0, sizeof(sendmsg));
|
||||||
|
sendmsg.UeContextTransferRspData = &UeContextTransferRspData;
|
||||||
|
|
||||||
|
ue_context_id = recvmsg->h.resource.component[1];
|
||||||
|
if (!ue_context_id) {
|
||||||
|
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
|
||||||
|
strerror = ogs_msprintf("No UE context ID");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
amf_ue = amf_ue_find_by_ue_context_id(ue_context_id);
|
||||||
|
if (!amf_ue) {
|
||||||
|
status = OGS_SBI_HTTP_STATUS_NOT_FOUND;
|
||||||
|
strerror = ogs_msprintf("CONTEXT_NOT_FOUND");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amf_ue->supi) {
|
||||||
|
UeContext.supi = amf_ue->supi;
|
||||||
|
if (amf_ue->auth_result !=
|
||||||
|
OpenAPI_auth_result_AUTHENTICATION_SUCCESS) {
|
||||||
|
UeContext.is_supi_unauth_ind = true;
|
||||||
|
UeContext.supi_unauth_ind = amf_ue->auth_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO UeContext.gpsi_list */
|
||||||
|
|
||||||
|
if (amf_ue->pei) {
|
||||||
|
UeContext.pei = amf_ue->pei;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((amf_ue->ue_ambr.uplink > 0) || (amf_ue->ue_ambr.downlink > 0)) {
|
||||||
|
UeAmbr = ogs_malloc(sizeof(*UeAmbr));
|
||||||
|
ogs_assert(UeAmbr);
|
||||||
|
memset(UeAmbr, 0, sizeof(*UeAmbr));
|
||||||
|
|
||||||
|
if (amf_ue->ue_ambr.uplink > 0)
|
||||||
|
UeAmbr->uplink = ogs_sbi_bitrate_to_string(
|
||||||
|
amf_ue->ue_ambr.uplink, OGS_SBI_BITRATE_KBPS);
|
||||||
|
if (amf_ue->ue_ambr.downlink > 0)
|
||||||
|
UeAmbr->downlink = ogs_sbi_bitrate_to_string(
|
||||||
|
amf_ue->ue_ambr.downlink, OGS_SBI_BITRATE_KBPS);
|
||||||
|
UeContext.sub_ue_ambr = UeAmbr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((amf_ue->nas.ue.ksi != 0) && (amf_ue->nas.ue.tsc != 0)) {
|
||||||
|
memset(&SeafData, 0, sizeof(SeafData));
|
||||||
|
Tsc_type = (amf_ue->nas.ue.tsc == 0) ?
|
||||||
|
OpenAPI_sc_type_NATIVE : OpenAPI_sc_type_MAPPED;
|
||||||
|
|
||||||
|
memset(&Ng_ksi, 0, sizeof(Ng_ksi));
|
||||||
|
SeafData.ng_ksi = &Ng_ksi;
|
||||||
|
Ng_ksi.tsc = Tsc_type;
|
||||||
|
Ng_ksi.ksi = (int)amf_ue->nas.ue.ksi;
|
||||||
|
|
||||||
|
memset(&Key_amf, 0, sizeof(Key_amf));
|
||||||
|
SeafData.key_amf = &Key_amf;
|
||||||
|
OpenAPI_key_amf_type_e temp_key_type =
|
||||||
|
(OpenAPI_key_amf_type_e)OpenAPI_key_amf_type_KAMF;
|
||||||
|
Key_amf.key_type = temp_key_type;
|
||||||
|
ogs_hex_to_ascii(amf_ue->kamf, sizeof(amf_ue->kamf),
|
||||||
|
hxkamf_string, sizeof(hxkamf_string));
|
||||||
|
Key_amf.key_val = hxkamf_string;
|
||||||
|
UeContext.seaf_data = &SeafData;
|
||||||
|
}
|
||||||
|
|
||||||
|
encoded_gmm_capability = amf_namf_comm_base64_encode_5gmm_capability(amf_ue);
|
||||||
|
UeContext._5g_mm_capability = encoded_gmm_capability;
|
||||||
|
|
||||||
|
UeContext.pcf_id = amf_ue->sbi.service_type_array[
|
||||||
|
OGS_SBI_SERVICE_TYPE_NPCF_AM_POLICY_CONTROL].nf_instance->id;
|
||||||
|
|
||||||
|
/* TODO UeContext.pcfAmPolicyUri */
|
||||||
|
/* TODO UeContext.pcfUePolicyUri */
|
||||||
|
|
||||||
|
MmContextList = amf_namf_comm_encode_ue_mm_context_list(amf_ue);
|
||||||
|
UeContext.mm_context_list = MmContextList;
|
||||||
|
|
||||||
|
if (recvmsg->UeContextTransferReqData->reason ==
|
||||||
|
OpenAPI_transfer_reason_MOBI_REG) {
|
||||||
|
SessionContextList = amf_namf_comm_encode_ue_session_context_list(amf_ue);
|
||||||
|
UeContext.session_context_list = SessionContextList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO ueRadioCapability */
|
||||||
|
|
||||||
|
response = ogs_sbi_build_response(&sendmsg, status);
|
||||||
|
ogs_assert(response);
|
||||||
|
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
|
||||||
|
|
||||||
|
if (encoded_gmm_capability)
|
||||||
|
ogs_free(encoded_gmm_capability);
|
||||||
|
if (UeAmbr)
|
||||||
|
OpenAPI_ambr_free(UeAmbr);
|
||||||
|
|
||||||
|
if (SessionContextList) {
|
||||||
|
OpenAPI_list_for_each(SessionContextList, node) {
|
||||||
|
PduSessionContext = node->data;
|
||||||
|
OpenAPI_pdu_session_context_free(PduSessionContext);
|
||||||
|
}
|
||||||
|
OpenAPI_list_free(SessionContextList);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MmContextList) {
|
||||||
|
OpenAPI_list_for_each(MmContextList, node) {
|
||||||
|
MmContext = node->data;
|
||||||
|
OpenAPI_mm_context_free(MmContext);
|
||||||
|
}
|
||||||
|
OpenAPI_list_free(MmContextList);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OGS_OK;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
ogs_assert(strerror);
|
||||||
|
ogs_error("%s", strerror);
|
||||||
|
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(stream, status, NULL, strerror, NULL));
|
||||||
|
ogs_free(strerror);
|
||||||
|
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
|
@ -34,6 +34,10 @@ int amf_namf_callback_handle_dereg_notify(
|
||||||
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
|
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
|
||||||
int amf_namf_callback_handle_sdm_data_change_notify(
|
int amf_namf_callback_handle_sdm_data_change_notify(
|
||||||
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
|
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
|
||||||
|
int amf_namf_comm_handle_ue_context_transfer_request(
|
||||||
|
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
|
||||||
|
int amf_namf_comm_handle_ue_context_transfer_response(
|
||||||
|
ogs_sbi_message_t *recvmsg, amf_ue_t *amf_ue);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1018,7 +1018,7 @@ void ngap_handle_initial_context_setup_response(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_ACTIVATED, ¶m);
|
ran_ue, sess, AMF_UPDATE_SM_CONTEXT_ACTIVATED, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
|
||||||
|
@ -1248,7 +1248,7 @@ void ngap_handle_initial_context_setup_failure(
|
||||||
amf_ue->deactivation.cause = NGAP_CauseNas_normal_release;
|
amf_ue->deactivation.cause = NGAP_CauseNas_normal_release;
|
||||||
|
|
||||||
amf_sbi_send_deactivate_all_sessions(
|
amf_sbi_send_deactivate_all_sessions(
|
||||||
amf_ue, AMF_UPDATE_SM_CONTEXT_DEACTIVATED,
|
ran_ue, amf_ue, AMF_UPDATE_SM_CONTEXT_DEACTIVATED,
|
||||||
Cause->present, (int)Cause->choice.radioNetwork);
|
Cause->present, (int)Cause->choice.radioNetwork);
|
||||||
|
|
||||||
new_xact_count = amf_sess_xact_count(amf_ue);
|
new_xact_count = amf_sess_xact_count(amf_ue);
|
||||||
|
@ -1552,7 +1552,7 @@ void ngap_handle_ue_context_release_request(
|
||||||
|
|
||||||
if (!PDUSessionList) {
|
if (!PDUSessionList) {
|
||||||
amf_sbi_send_deactivate_all_sessions(
|
amf_sbi_send_deactivate_all_sessions(
|
||||||
amf_ue, AMF_UPDATE_SM_CONTEXT_DEACTIVATED,
|
ran_ue, amf_ue, AMF_UPDATE_SM_CONTEXT_DEACTIVATED,
|
||||||
Cause->present, (int)Cause->choice.radioNetwork);
|
Cause->present, (int)Cause->choice.radioNetwork);
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < PDUSessionList->list.count; i++) {
|
for (i = 0; i < PDUSessionList->list.count; i++) {
|
||||||
|
@ -1584,7 +1584,7 @@ void ngap_handle_ue_context_release_request(
|
||||||
PDUSessionItem->pDUSessionID);
|
PDUSessionItem->pDUSessionID);
|
||||||
if (SESSION_CONTEXT_IN_SMF(sess)) {
|
if (SESSION_CONTEXT_IN_SMF(sess)) {
|
||||||
amf_sbi_send_deactivate_session(
|
amf_sbi_send_deactivate_session(
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_DEACTIVATED,
|
ran_ue, sess, AMF_UPDATE_SM_CONTEXT_DEACTIVATED,
|
||||||
Cause->present, (int)Cause->choice.radioNetwork);
|
Cause->present, (int)Cause->choice.radioNetwork);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2002,7 +2002,7 @@ void ngap_handle_pdu_session_resource_setup_response(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_ACTIVATED, ¶m);
|
ran_ue, sess, AMF_UPDATE_SM_CONTEXT_ACTIVATED, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
|
||||||
|
@ -2128,7 +2128,7 @@ void ngap_handle_pdu_session_resource_setup_response(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_SETUP_FAIL, ¶m);
|
ran_ue, sess, AMF_UPDATE_SM_CONTEXT_SETUP_FAIL, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
|
||||||
|
@ -2321,7 +2321,7 @@ void ngap_handle_pdu_session_resource_modify_response(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_MODIFIED, ¶m);
|
ran_ue, sess, AMF_UPDATE_SM_CONTEXT_MODIFIED, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
|
||||||
|
@ -2508,7 +2508,7 @@ void ngap_handle_pdu_session_resource_release_response(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_N2_RELEASED, ¶m);
|
ran_ue, sess, AMF_UPDATE_SM_CONTEXT_N2_RELEASED, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
|
||||||
|
@ -2977,7 +2977,8 @@ void ngap_handle_path_switch_request(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_PATH_SWITCH_REQUEST, ¶m);
|
ran_ue, sess,
|
||||||
|
AMF_UPDATE_SM_CONTEXT_PATH_SWITCH_REQUEST, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
|
||||||
|
@ -3366,7 +3367,8 @@ void ngap_handle_handover_required(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_HANDOVER_REQUIRED, ¶m);
|
source_ue, sess,
|
||||||
|
AMF_UPDATE_SM_CONTEXT_HANDOVER_REQUIRED, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
|
||||||
|
@ -3607,7 +3609,8 @@ void ngap_handle_handover_request_ack(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_HANDOVER_REQ_ACK, ¶m);
|
target_ue, sess,
|
||||||
|
AMF_UPDATE_SM_CONTEXT_HANDOVER_REQ_ACK, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
|
||||||
|
@ -3879,7 +3882,7 @@ void ngap_handle_handover_cancel(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_HANDOVER_CANCEL, ¶m);
|
source_ue, sess, AMF_UPDATE_SM_CONTEXT_HANDOVER_CANCEL, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -4188,7 +4191,7 @@ void ngap_handle_handover_notification(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context,
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
sess, AMF_UPDATE_SM_CONTEXT_HANDOVER_NOTIFY, ¶m);
|
source_ue, sess, AMF_UPDATE_SM_CONTEXT_HANDOVER_NOTIFY, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -4604,7 +4607,7 @@ void ngap_handle_ng_reset(
|
||||||
old_xact_count = amf_sess_xact_count(amf_ue);
|
old_xact_count = amf_sess_xact_count(amf_ue);
|
||||||
|
|
||||||
amf_sbi_send_deactivate_all_sessions(
|
amf_sbi_send_deactivate_all_sessions(
|
||||||
amf_ue, AMF_REMOVE_S1_CONTEXT_BY_RESET_PARTIAL,
|
ran_ue, amf_ue, AMF_REMOVE_S1_CONTEXT_BY_RESET_PARTIAL,
|
||||||
NGAP_Cause_PR_radioNetwork,
|
NGAP_Cause_PR_radioNetwork,
|
||||||
NGAP_CauseRadioNetwork_failure_in_radio_interface_procedure);
|
NGAP_CauseRadioNetwork_failure_in_radio_interface_procedure);
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ int amf_nnssf_nsselection_handle_get(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, discovery_option,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, discovery_option,
|
||||||
amf_nsmf_pdusession_build_create_sm_context,
|
amf_nsmf_pdusession_build_create_sm_context,
|
||||||
sess, AMF_CREATE_SM_CONTEXT_NO_STATE, ¶m);
|
ran_ue, sess, AMF_CREATE_SM_CONTEXT_NO_STATE, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
} else {
|
} else {
|
||||||
|
@ -163,7 +163,8 @@ int amf_nnssf_nsselection_handle_get(
|
||||||
ogs_freeaddrinfo(addr6);
|
ogs_freeaddrinfo(addr6);
|
||||||
|
|
||||||
r = amf_sess_sbi_discover_by_nsi(
|
r = amf_sess_sbi_discover_by_nsi(
|
||||||
sess, OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, discovery_option);
|
ran_ue, sess,
|
||||||
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, discovery_option);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
|
@ -635,7 +635,7 @@ int amf_nsmf_pdusession_handle_update_sm_context(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_create_sm_context,
|
amf_nsmf_pdusession_build_create_sm_context,
|
||||||
sess, AMF_CREATE_SM_CONTEXT_NO_STATE, NULL);
|
ran_ue, sess, AMF_CREATE_SM_CONTEXT_NO_STATE, NULL);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -36,6 +36,7 @@ int amf_sbi_open(void)
|
||||||
ogs_sbi_nf_instance_build_default(nf_instance);
|
ogs_sbi_nf_instance_build_default(nf_instance);
|
||||||
ogs_sbi_nf_instance_add_allowed_nf_type(nf_instance, OpenAPI_nf_type_SCP);
|
ogs_sbi_nf_instance_add_allowed_nf_type(nf_instance, OpenAPI_nf_type_SCP);
|
||||||
ogs_sbi_nf_instance_add_allowed_nf_type(nf_instance, OpenAPI_nf_type_SMF);
|
ogs_sbi_nf_instance_add_allowed_nf_type(nf_instance, OpenAPI_nf_type_SMF);
|
||||||
|
ogs_sbi_nf_instance_add_allowed_nf_type(nf_instance, OpenAPI_nf_type_AMF);
|
||||||
|
|
||||||
/* Build NF service information. It will be transmitted to NRF. */
|
/* Build NF service information. It will be transmitted to NRF. */
|
||||||
if (ogs_sbi_nf_service_is_available(OGS_SBI_SERVICE_NAME_NAMF_COMM)) {
|
if (ogs_sbi_nf_service_is_available(OGS_SBI_SERVICE_NAME_NAMF_COMM)) {
|
||||||
|
@ -45,6 +46,7 @@ int amf_sbi_open(void)
|
||||||
ogs_sbi_nf_service_add_version(
|
ogs_sbi_nf_service_add_version(
|
||||||
service, OGS_SBI_API_V1, OGS_SBI_API_V1_0_0, NULL);
|
service, OGS_SBI_API_V1, OGS_SBI_API_V1_0_0, NULL);
|
||||||
ogs_sbi_nf_service_add_allowed_nf_type(service, OpenAPI_nf_type_SMF);
|
ogs_sbi_nf_service_add_allowed_nf_type(service, OpenAPI_nf_type_SMF);
|
||||||
|
ogs_sbi_nf_service_add_allowed_nf_type(service, OpenAPI_nf_type_AMF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize NRF NF Instance */
|
/* Initialize NRF NF Instance */
|
||||||
|
@ -156,30 +158,24 @@ int amf_sess_sbi_discover_and_send(
|
||||||
ogs_sbi_service_type_e service_type,
|
ogs_sbi_service_type_e service_type,
|
||||||
ogs_sbi_discovery_option_t *discovery_option,
|
ogs_sbi_discovery_option_t *discovery_option,
|
||||||
ogs_sbi_request_t *(*build)(amf_sess_t *sess, void *data),
|
ogs_sbi_request_t *(*build)(amf_sess_t *sess, void *data),
|
||||||
amf_sess_t *sess, int state, void *data)
|
ran_ue_t *ran_ue, amf_sess_t *sess, int state, void *data)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
int rv;
|
int rv;
|
||||||
ogs_sbi_xact_t *xact = NULL;
|
ogs_sbi_xact_t *xact = NULL;
|
||||||
|
|
||||||
amf_ue_t *amf_ue = NULL;
|
|
||||||
|
|
||||||
ogs_assert(service_type);
|
ogs_assert(service_type);
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
ogs_assert(build);
|
ogs_assert(build);
|
||||||
|
|
||||||
amf_ue = amf_ue_cycle(sess->amf_ue);
|
if (ran_ue) {
|
||||||
if (!amf_ue) {
|
sess->ran_ue = ran_ue_cycle(ran_ue);
|
||||||
ogs_error("UE(amf_ue) Context has already been removed");
|
if (!sess->ran_ue) {
|
||||||
return OGS_NOTFOUND;
|
ogs_error("NG context has already been removed");
|
||||||
}
|
return OGS_NOTFOUND;
|
||||||
|
}
|
||||||
sess->ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
} else
|
||||||
if (!sess->ran_ue) {
|
sess->ran_ue = NULL;
|
||||||
ogs_error("[%s] RAN-NG Context has already been removed",
|
|
||||||
amf_ue->supi);
|
|
||||||
return OGS_NOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
xact = ogs_sbi_xact_add(
|
xact = ogs_sbi_xact_add(
|
||||||
&sess->sbi, service_type, discovery_option,
|
&sess->sbi, service_type, discovery_option,
|
||||||
|
@ -219,6 +215,7 @@ static int client_discover_cb(
|
||||||
OpenAPI_nf_type_e requester_nf_type = OpenAPI_nf_type_NULL;
|
OpenAPI_nf_type_e requester_nf_type = OpenAPI_nf_type_NULL;
|
||||||
ogs_sbi_discovery_option_t *discovery_option = NULL;
|
ogs_sbi_discovery_option_t *discovery_option = NULL;
|
||||||
amf_ue_t *amf_ue = NULL;
|
amf_ue_t *amf_ue = NULL;
|
||||||
|
ran_ue_t *ran_ue = NULL;
|
||||||
amf_sess_t *sess = NULL;
|
amf_sess_t *sess = NULL;
|
||||||
|
|
||||||
xact = data;
|
xact = data;
|
||||||
|
@ -251,14 +248,30 @@ static int client_discover_cb(
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_assert(sess->sbi.type == OGS_SBI_OBJ_SESS_TYPE);
|
ogs_assert(sess->sbi.type == OGS_SBI_OBJ_SESS_TYPE);
|
||||||
amf_ue = sess->amf_ue;
|
amf_ue = amf_ue_cycle(sess->amf_ue);
|
||||||
ogs_assert(amf_ue);
|
if (!amf_ue) {
|
||||||
|
ogs_error("UE(amf-ue) context has already been removed");
|
||||||
|
ogs_sbi_xact_remove(xact);
|
||||||
|
if (response)
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
ran_ue = ran_ue_cycle(sess->ran_ue);
|
||||||
|
if (!ran_ue) {
|
||||||
|
ogs_error("[%s] NG context has already been removed", amf_ue->supi);
|
||||||
|
ogs_sbi_xact_remove(xact);
|
||||||
|
if (response)
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (status != OGS_OK) {
|
if (status != OGS_OK) {
|
||||||
ogs_log_message(
|
ogs_log_message(
|
||||||
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
status == OGS_DONE ? OGS_LOG_DEBUG : OGS_LOG_WARN, 0,
|
||||||
"client_discover_cb() failed [%d]", status);
|
"client_discover_cb() failed [%d]", status);
|
||||||
ogs_sbi_xact_remove(xact);
|
ogs_sbi_xact_remove(xact);
|
||||||
|
if (response)
|
||||||
|
ogs_sbi_response_free(response);
|
||||||
return OGS_ERROR;
|
return OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,7 +280,7 @@ static int client_discover_cb(
|
||||||
rv = ogs_sbi_parse_response(&message, response);
|
rv = ogs_sbi_parse_response(&message, response);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_error("cannot parse HTTP response");
|
ogs_error("cannot parse HTTP response");
|
||||||
r = nas_5gs_send_back_gsm_message(sess->ran_ue, sess,
|
r = nas_5gs_send_back_gsm_message(ran_ue, sess,
|
||||||
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED, AMF_NAS_BACKOFF_TIME);
|
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED, AMF_NAS_BACKOFF_TIME);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
@ -277,7 +290,7 @@ static int client_discover_cb(
|
||||||
|
|
||||||
if (message.res_status != OGS_SBI_HTTP_STATUS_OK) {
|
if (message.res_status != OGS_SBI_HTTP_STATUS_OK) {
|
||||||
ogs_error("NF-Discover failed [%d]", message.res_status);
|
ogs_error("NF-Discover failed [%d]", message.res_status);
|
||||||
r = nas_5gs_send_back_gsm_message(sess->ran_ue, sess,
|
r = nas_5gs_send_back_gsm_message(ran_ue, sess,
|
||||||
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED, AMF_NAS_BACKOFF_TIME);
|
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED, AMF_NAS_BACKOFF_TIME);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
@ -287,7 +300,7 @@ static int client_discover_cb(
|
||||||
|
|
||||||
if (!message.SearchResult) {
|
if (!message.SearchResult) {
|
||||||
ogs_error("No SearchResult");
|
ogs_error("No SearchResult");
|
||||||
r = nas_5gs_send_back_gsm_message(sess->ran_ue, sess,
|
r = nas_5gs_send_back_gsm_message(ran_ue, sess,
|
||||||
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED, AMF_NAS_BACKOFF_TIME);
|
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED, AMF_NAS_BACKOFF_TIME);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
@ -304,7 +317,7 @@ static int client_discover_cb(
|
||||||
ogs_error("[%s:%d] (NF discover) No [%s]",
|
ogs_error("[%s:%d] (NF discover) No [%s]",
|
||||||
amf_ue->supi, sess->psi,
|
amf_ue->supi, sess->psi,
|
||||||
ogs_sbi_service_type_to_name(service_type));
|
ogs_sbi_service_type_to_name(service_type));
|
||||||
r = nas_5gs_send_back_gsm_message(sess->ran_ue, sess,
|
r = nas_5gs_send_back_gsm_message(ran_ue, sess,
|
||||||
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
|
OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED,
|
||||||
AMF_NAS_BACKOFF_TIME);
|
AMF_NAS_BACKOFF_TIME);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
|
@ -316,7 +329,7 @@ static int client_discover_cb(
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
service_type, NULL,
|
service_type, NULL,
|
||||||
amf_nsmf_pdusession_build_create_sm_context,
|
amf_nsmf_pdusession_build_create_sm_context,
|
||||||
sess, AMF_CREATE_SM_CONTEXT_NO_STATE, NULL);
|
ran_ue, sess, AMF_CREATE_SM_CONTEXT_NO_STATE, NULL);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
|
||||||
|
@ -337,15 +350,13 @@ cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
int amf_sess_sbi_discover_by_nsi(
|
int amf_sess_sbi_discover_by_nsi(
|
||||||
amf_sess_t *sess,
|
ran_ue_t *ran_ue, amf_sess_t *sess,
|
||||||
ogs_sbi_service_type_e service_type,
|
ogs_sbi_service_type_e service_type,
|
||||||
ogs_sbi_discovery_option_t *discovery_option)
|
ogs_sbi_discovery_option_t *discovery_option)
|
||||||
{
|
{
|
||||||
ogs_sbi_xact_t *xact = NULL;
|
ogs_sbi_xact_t *xact = NULL;
|
||||||
ogs_sbi_client_t *client = NULL;
|
ogs_sbi_client_t *client = NULL;
|
||||||
|
|
||||||
amf_ue_t *amf_ue = NULL;
|
|
||||||
|
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
client = sess->nssf.nrf.client;
|
client = sess->nssf.nrf.client;
|
||||||
ogs_assert(client);
|
ogs_assert(client);
|
||||||
|
@ -354,18 +365,14 @@ int amf_sess_sbi_discover_by_nsi(
|
||||||
ogs_warn("Try to discover [%s]",
|
ogs_warn("Try to discover [%s]",
|
||||||
ogs_sbi_service_type_to_name(service_type));
|
ogs_sbi_service_type_to_name(service_type));
|
||||||
|
|
||||||
amf_ue = amf_ue_cycle(sess->amf_ue);
|
if (ran_ue) {
|
||||||
if (!amf_ue) {
|
sess->ran_ue = ran_ue_cycle(ran_ue);
|
||||||
ogs_error("UE(amf_ue) Context has already been removed");
|
if (!sess->ran_ue) {
|
||||||
return OGS_NOTFOUND;
|
ogs_error("NG context has already been removed");
|
||||||
}
|
return OGS_NOTFOUND;
|
||||||
|
}
|
||||||
sess->ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
} else
|
||||||
if (!sess->ran_ue) {
|
sess->ran_ue = NULL;
|
||||||
ogs_error("[%s] RAN-NG Context has already been removed",
|
|
||||||
amf_ue->supi);
|
|
||||||
return OGS_NOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
xact = ogs_sbi_xact_add(
|
xact = ogs_sbi_xact_add(
|
||||||
&sess->sbi, service_type, discovery_option, NULL, NULL, NULL);
|
&sess->sbi, service_type, discovery_option, NULL, NULL, NULL);
|
||||||
|
@ -386,7 +393,8 @@ int amf_sess_sbi_discover_by_nsi(
|
||||||
client, client_discover_cb, xact->request, xact) == true ? OGS_OK : OGS_ERROR;
|
client, client_discover_cb, xact->request, xact) == true ? OGS_OK : OGS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void amf_sbi_send_activating_session(amf_sess_t *sess, int state)
|
void amf_sbi_send_activating_session(
|
||||||
|
ran_ue_t *ran_ue, amf_sess_t *sess, int state)
|
||||||
{
|
{
|
||||||
amf_nsmf_pdusession_sm_context_param_t param;
|
amf_nsmf_pdusession_sm_context_param_t param;
|
||||||
int r;
|
int r;
|
||||||
|
@ -398,13 +406,14 @@ void amf_sbi_send_activating_session(amf_sess_t *sess, int state)
|
||||||
|
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context, sess, state, ¶m);
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
|
ran_ue, sess, state, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void amf_sbi_send_deactivate_session(
|
void amf_sbi_send_deactivate_session(
|
||||||
amf_sess_t *sess, int state, int group, int cause)
|
ran_ue_t *ran_ue, amf_sess_t *sess, int state, int group, int cause)
|
||||||
{
|
{
|
||||||
amf_nsmf_pdusession_sm_context_param_t param;
|
amf_nsmf_pdusession_sm_context_param_t param;
|
||||||
int r;
|
int r;
|
||||||
|
@ -420,13 +429,14 @@ void amf_sbi_send_deactivate_session(
|
||||||
|
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_update_sm_context, sess, state, ¶m);
|
amf_nsmf_pdusession_build_update_sm_context,
|
||||||
|
ran_ue, sess, state, ¶m);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
void amf_sbi_send_deactivate_all_sessions(
|
void amf_sbi_send_deactivate_all_sessions(
|
||||||
amf_ue_t *amf_ue, int state, int group, int cause)
|
ran_ue_t *ran_ue, amf_ue_t *amf_ue, int state, int group, int cause)
|
||||||
{
|
{
|
||||||
amf_sess_t *sess = NULL;
|
amf_sess_t *sess = NULL;
|
||||||
|
|
||||||
|
@ -434,7 +444,7 @@ void amf_sbi_send_deactivate_all_sessions(
|
||||||
|
|
||||||
ogs_list_for_each(&amf_ue->sess_list, sess) {
|
ogs_list_for_each(&amf_ue->sess_list, sess) {
|
||||||
if (SESSION_CONTEXT_IN_SMF(sess))
|
if (SESSION_CONTEXT_IN_SMF(sess))
|
||||||
amf_sbi_send_deactivate_session(sess, state, group, cause);
|
amf_sbi_send_deactivate_session(ran_ue, sess, state, group, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,13 +456,13 @@ void amf_sbi_send_deactivate_all_ue_in_gnb(amf_gnb_t *gnb, int state)
|
||||||
ogs_list_for_each_safe(&gnb->ran_ue_list, ran_ue_next, ran_ue) {
|
ogs_list_for_each_safe(&gnb->ran_ue_list, ran_ue_next, ran_ue) {
|
||||||
int old_xact_count = 0, new_xact_count = 0;
|
int old_xact_count = 0, new_xact_count = 0;
|
||||||
|
|
||||||
amf_ue = ran_ue->amf_ue;
|
amf_ue = amf_ue_cycle(ran_ue->amf_ue);
|
||||||
|
|
||||||
if (amf_ue) {
|
if (amf_ue) {
|
||||||
old_xact_count = amf_sess_xact_count(amf_ue);
|
old_xact_count = amf_sess_xact_count(amf_ue);
|
||||||
|
|
||||||
amf_sbi_send_deactivate_all_sessions(
|
amf_sbi_send_deactivate_all_sessions(
|
||||||
amf_ue, state, NGAP_Cause_PR_radioNetwork,
|
ran_ue, amf_ue, state, NGAP_Cause_PR_radioNetwork,
|
||||||
NGAP_CauseRadioNetwork_failure_in_radio_interface_procedure);
|
NGAP_CauseRadioNetwork_failure_in_radio_interface_procedure);
|
||||||
|
|
||||||
new_xact_count = amf_sess_xact_count(amf_ue);
|
new_xact_count = amf_sess_xact_count(amf_ue);
|
||||||
|
@ -480,7 +490,8 @@ void amf_sbi_send_deactivate_all_ue_in_gnb(amf_gnb_t *gnb, int state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void amf_sbi_send_release_session(amf_sess_t *sess, int state)
|
void amf_sbi_send_release_session(
|
||||||
|
ran_ue_t *ran_ue, amf_sess_t *sess, int state)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -488,7 +499,8 @@ void amf_sbi_send_release_session(amf_sess_t *sess, int state)
|
||||||
|
|
||||||
r = amf_sess_sbi_discover_and_send(
|
r = amf_sess_sbi_discover_and_send(
|
||||||
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
OGS_SBI_SERVICE_TYPE_NSMF_PDUSESSION, NULL,
|
||||||
amf_nsmf_pdusession_build_release_sm_context, sess, state, NULL);
|
amf_nsmf_pdusession_build_release_sm_context,
|
||||||
|
ran_ue, sess, state, NULL);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
|
||||||
|
@ -496,7 +508,8 @@ void amf_sbi_send_release_session(amf_sess_t *sess, int state)
|
||||||
CLEAR_SM_CONTEXT_REF(sess);
|
CLEAR_SM_CONTEXT_REF(sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void amf_sbi_send_release_all_sessions(amf_ue_t *amf_ue, int state)
|
void amf_sbi_send_release_all_sessions(
|
||||||
|
ran_ue_t *ran_ue, amf_ue_t *amf_ue, int state)
|
||||||
{
|
{
|
||||||
amf_sess_t *sess = NULL;
|
amf_sess_t *sess = NULL;
|
||||||
|
|
||||||
|
@ -504,7 +517,7 @@ void amf_sbi_send_release_all_sessions(amf_ue_t *amf_ue, int state)
|
||||||
|
|
||||||
ogs_list_for_each(&amf_ue->sess_list, sess) {
|
ogs_list_for_each(&amf_ue->sess_list, sess) {
|
||||||
if (SESSION_CONTEXT_IN_SMF(sess))
|
if (SESSION_CONTEXT_IN_SMF(sess))
|
||||||
amf_sbi_send_release_session(sess, state);
|
amf_sbi_send_release_session(ran_ue, sess, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,23 +74,26 @@ int amf_sess_sbi_discover_and_send(
|
||||||
ogs_sbi_service_type_e service_type,
|
ogs_sbi_service_type_e service_type,
|
||||||
ogs_sbi_discovery_option_t *discovery_option,
|
ogs_sbi_discovery_option_t *discovery_option,
|
||||||
ogs_sbi_request_t *(*build)(amf_sess_t *sess, void *data),
|
ogs_sbi_request_t *(*build)(amf_sess_t *sess, void *data),
|
||||||
amf_sess_t *sess, int state, void *data);
|
ran_ue_t *ran_ue, amf_sess_t *sess, int state, void *data);
|
||||||
|
|
||||||
int amf_sess_sbi_discover_by_nsi(
|
int amf_sess_sbi_discover_by_nsi(
|
||||||
amf_sess_t *sess,
|
ran_ue_t *ran_ue, amf_sess_t *sess,
|
||||||
ogs_sbi_service_type_e service_type,
|
ogs_sbi_service_type_e service_type,
|
||||||
ogs_sbi_discovery_option_t *discovery_option);
|
ogs_sbi_discovery_option_t *discovery_option);
|
||||||
|
|
||||||
void amf_sbi_send_activating_session(amf_sess_t *sess, int state);
|
void amf_sbi_send_activating_session(
|
||||||
|
ran_ue_t *ran_ue, amf_sess_t *sess, int state);
|
||||||
|
|
||||||
void amf_sbi_send_deactivate_session(
|
void amf_sbi_send_deactivate_session(
|
||||||
amf_sess_t *sess, int state, int group, int cause);
|
ran_ue_t *ran_ue, amf_sess_t *sess, int state, int group, int cause);
|
||||||
void amf_sbi_send_deactivate_all_sessions(
|
void amf_sbi_send_deactivate_all_sessions(
|
||||||
amf_ue_t *amf_ue, int state, int group, int cause);
|
ran_ue_t *ran_ue, amf_ue_t *amf_ue, int state, int group, int cause);
|
||||||
void amf_sbi_send_deactivate_all_ue_in_gnb(amf_gnb_t *gnb, int state);
|
void amf_sbi_send_deactivate_all_ue_in_gnb(amf_gnb_t *gnb, int state);
|
||||||
|
|
||||||
void amf_sbi_send_release_session(amf_sess_t *sess, int state);
|
void amf_sbi_send_release_session(
|
||||||
void amf_sbi_send_release_all_sessions(amf_ue_t *amf_ue, int state);
|
ran_ue_t *ran_ue, amf_sess_t *sess, int state);
|
||||||
|
void amf_sbi_send_release_all_sessions(
|
||||||
|
ran_ue_t *ran_ue, amf_ue_t *amf_ue, int state);
|
||||||
|
|
||||||
bool amf_sbi_send_n1_n2_failure_notify(
|
bool amf_sbi_send_n1_n2_failure_notify(
|
||||||
amf_sess_t *sess, OpenAPI_n1_n2_message_transfer_cause_e cause);
|
amf_sess_t *sess, OpenAPI_n1_n2_message_transfer_cause_e cause);
|
||||||
|
|
|
@ -236,13 +236,17 @@ int esm_handle_information_response(mme_sess_t *sess,
|
||||||
mme_csmap_t *csmap = mme_csmap_find_by_tai(&mme_ue->tai);
|
mme_csmap_t *csmap = mme_csmap_find_by_tai(&mme_ue->tai);
|
||||||
mme_ue->csmap = csmap;
|
mme_ue->csmap = csmap;
|
||||||
|
|
||||||
if (csmap) {
|
if (!csmap ||
|
||||||
ogs_assert(OGS_OK ==
|
mme_ue->network_access_mode ==
|
||||||
sgsap_send_location_update_request(mme_ue));
|
OGS_NETWORK_ACCESS_MODE_ONLY_PACKET ||
|
||||||
} else {
|
mme_ue->nas_eps.attach.value ==
|
||||||
|
OGS_NAS_ATTACH_TYPE_EPS_ATTACH) {
|
||||||
r = nas_eps_send_attach_accept(mme_ue);
|
r = nas_eps_send_attach_accept(mme_ue);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
} else {
|
||||||
|
ogs_assert(OGS_OK ==
|
||||||
|
sgsap_send_location_update_request(mme_ue));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ogs_assert(OGS_OK ==
|
ogs_assert(OGS_OK ==
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -254,6 +254,7 @@ int mme_gtp_send_create_session_request(mme_sess_t *sess, int create_action)
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_CREATE_SESSION_REQUEST_TYPE;
|
h.type = OGS_GTP2_CREATE_SESSION_REQUEST_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgw_ue->sgw_s11_teid;
|
h.teid = sgw_ue->sgw_s11_teid;
|
||||||
|
|
||||||
pkbuf = mme_s11_build_create_session_request(h.type, sess, create_action);
|
pkbuf = mme_s11_build_create_session_request(h.type, sess, create_action);
|
||||||
|
@ -293,6 +294,7 @@ int mme_gtp_send_modify_bearer_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgw_ue->sgw_s11_teid;
|
h.teid = sgw_ue->sgw_s11_teid;
|
||||||
|
|
||||||
pkbuf = mme_s11_build_modify_bearer_request(h.type, mme_ue, uli_presence);
|
pkbuf = mme_s11_build_modify_bearer_request(h.type, mme_ue, uli_presence);
|
||||||
|
@ -332,6 +334,7 @@ int mme_gtp_send_delete_session_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_DELETE_SESSION_REQUEST_TYPE;
|
h.type = OGS_GTP2_DELETE_SESSION_REQUEST_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgw_ue->sgw_s11_teid;
|
h.teid = sgw_ue->sgw_s11_teid;
|
||||||
|
|
||||||
s11buf = mme_s11_build_delete_session_request(h.type, sess, action);
|
s11buf = mme_s11_build_delete_session_request(h.type, sess, action);
|
||||||
|
@ -400,6 +403,7 @@ int mme_gtp_send_create_bearer_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE;
|
h.type = OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgw_ue->sgw_s11_teid;
|
h.teid = sgw_ue->sgw_s11_teid;
|
||||||
|
|
||||||
pkbuf = mme_s11_build_create_bearer_response(h.type, bearer, cause_value);
|
pkbuf = mme_s11_build_create_bearer_response(h.type, bearer, cause_value);
|
||||||
|
@ -445,6 +449,7 @@ int mme_gtp_send_update_bearer_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE;
|
h.type = OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgw_ue->sgw_s11_teid;
|
h.teid = sgw_ue->sgw_s11_teid;
|
||||||
|
|
||||||
pkbuf = mme_s11_build_update_bearer_response(h.type, bearer, cause_value);
|
pkbuf = mme_s11_build_update_bearer_response(h.type, bearer, cause_value);
|
||||||
|
@ -490,6 +495,7 @@ int mme_gtp_send_delete_bearer_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE;
|
h.type = OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgw_ue->sgw_s11_teid;
|
h.teid = sgw_ue->sgw_s11_teid;
|
||||||
|
|
||||||
pkbuf = mme_s11_build_delete_bearer_response(h.type, bearer, cause_value);
|
pkbuf = mme_s11_build_delete_bearer_response(h.type, bearer, cause_value);
|
||||||
|
@ -525,6 +531,7 @@ int mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue, int action)
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_RELEASE_ACCESS_BEARERS_REQUEST_TYPE;
|
h.type = OGS_GTP2_RELEASE_ACCESS_BEARERS_REQUEST_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgw_ue->sgw_s11_teid;
|
h.teid = sgw_ue->sgw_s11_teid;
|
||||||
|
|
||||||
pkbuf = mme_s11_build_release_access_bearers_request(h.type);
|
pkbuf = mme_s11_build_release_access_bearers_request(h.type);
|
||||||
|
@ -622,6 +629,7 @@ int mme_gtp_send_downlink_data_notification_ack(
|
||||||
/* Build Downlink data notification ack */
|
/* Build Downlink data notification ack */
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE;
|
h.type = OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgw_ue->sgw_s11_teid;
|
h.teid = sgw_ue->sgw_s11_teid;
|
||||||
|
|
||||||
s11buf = mme_s11_build_downlink_data_notification_ack(h.type, cause_value);
|
s11buf = mme_s11_build_downlink_data_notification_ack(h.type, cause_value);
|
||||||
|
@ -657,6 +665,7 @@ int mme_gtp_send_create_indirect_data_forwarding_tunnel_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE;
|
h.type = OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgw_ue->sgw_s11_teid;
|
h.teid = sgw_ue->sgw_s11_teid;
|
||||||
|
|
||||||
pkbuf = mme_s11_build_create_indirect_data_forwarding_tunnel_request(
|
pkbuf = mme_s11_build_create_indirect_data_forwarding_tunnel_request(
|
||||||
|
@ -696,6 +705,7 @@ int mme_gtp_send_delete_indirect_data_forwarding_tunnel_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE;
|
h.type = OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgw_ue->sgw_s11_teid;
|
h.teid = sgw_ue->sgw_s11_teid;
|
||||||
|
|
||||||
pkbuf = ogs_pkbuf_alloc(NULL, OGS_TLV_MAX_HEADROOM);
|
pkbuf = ogs_pkbuf_alloc(NULL, OGS_TLV_MAX_HEADROOM);
|
||||||
|
@ -738,6 +748,7 @@ int mme_gtp_send_bearer_resource_command(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE;
|
h.type = OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgw_ue->sgw_s11_teid;
|
h.teid = sgw_ue->sgw_s11_teid;
|
||||||
|
|
||||||
pkbuf = mme_s11_build_bearer_resource_command(h.type, bearer, nas_message);
|
pkbuf = mme_s11_build_bearer_resource_command(h.type, bearer, nas_message);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -427,17 +427,20 @@ void mme_s11_handle_create_session_response(
|
||||||
mme_csmap_t *csmap = mme_csmap_find_by_tai(&mme_ue->tai);
|
mme_csmap_t *csmap = mme_csmap_find_by_tai(&mme_ue->tai);
|
||||||
mme_ue->csmap = csmap;
|
mme_ue->csmap = csmap;
|
||||||
|
|
||||||
if (csmap) {
|
if (!csmap ||
|
||||||
ogs_assert(OGS_PDU_SESSION_TYPE_IS_VALID(
|
mme_ue->network_access_mode ==
|
||||||
session->paa.session_type));
|
OGS_NETWORK_ACCESS_MODE_ONLY_PACKET ||
|
||||||
ogs_assert(OGS_OK ==
|
mme_ue->nas_eps.attach.value ==
|
||||||
sgsap_send_location_update_request(mme_ue));
|
OGS_NAS_ATTACH_TYPE_EPS_ATTACH) {
|
||||||
} else {
|
|
||||||
ogs_assert(OGS_PDU_SESSION_TYPE_IS_VALID(
|
ogs_assert(OGS_PDU_SESSION_TYPE_IS_VALID(
|
||||||
session->paa.session_type));
|
session->paa.session_type));
|
||||||
r = nas_eps_send_attach_accept(mme_ue);
|
r = nas_eps_send_attach_accept(mme_ue);
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
|
} else {
|
||||||
|
ogs_assert(OGS_PDU_SESSION_TYPE_IS_VALID(
|
||||||
|
session->paa.session_type));
|
||||||
|
ogs_assert(OGS_OK == sgsap_send_location_update_request(mme_ue));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE) {
|
} else if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE) {
|
||||||
|
@ -820,7 +823,9 @@ void mme_s11_handle_create_bearer_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
ogs_gtp2_send_error_message(xact,
|
||||||
|
sgw_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -856,7 +861,9 @@ void mme_s11_handle_create_bearer_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
ogs_gtp2_send_error_message(xact,
|
||||||
|
sgw_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1012,7 +1019,9 @@ void mme_s11_handle_update_bearer_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
ogs_gtp2_send_error_message(xact,
|
||||||
|
sgw_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
||||||
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1183,7 +1192,9 @@ void mme_s11_handle_delete_bearer_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
ogs_gtp2_send_error_message(xact,
|
||||||
|
sgw_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
||||||
OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE,
|
OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
|
@ -1440,7 +1451,9 @@ void mme_s11_handle_downlink_data_notification(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
ogs_gtp2_send_error_message(xact,
|
||||||
|
sgw_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
||||||
OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE,
|
OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE,
|
||||||
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -210,11 +210,9 @@ void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
|
||||||
ogs_plmn_id_hexdump(&lai->nas_plmn_id), lai->lac);
|
ogs_plmn_id_hexdump(&lai->nas_plmn_id), lai->lac);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
|
r = nas_eps_send_attach_accept(mme_ue);
|
||||||
emm_cause, OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
|
|
||||||
ogs_expect(r == OGS_OK);
|
ogs_expect(r == OGS_OK);
|
||||||
ogs_assert(r != OGS_ERROR);
|
ogs_assert(r != OGS_ERROR);
|
||||||
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -830,6 +830,13 @@ bool nrf_nnrf_handle_nf_discover(
|
||||||
&discovery_option->tai.plmn_id),
|
&discovery_option->tai.plmn_id),
|
||||||
discovery_option->tai.tac.v);
|
discovery_option->tai.tac.v);
|
||||||
}
|
}
|
||||||
|
if (discovery_option->target_guami) {
|
||||||
|
ogs_debug("guami[PLMN_ID:%06x,AMF_ID:%x]",
|
||||||
|
ogs_plmn_id_hexdump(
|
||||||
|
&discovery_option->target_guami->plmn_id),
|
||||||
|
ogs_amf_id_hexdump(
|
||||||
|
&discovery_option->target_guami->amf_id));
|
||||||
|
}
|
||||||
if (discovery_option->num_of_target_plmn_list) {
|
if (discovery_option->num_of_target_plmn_list) {
|
||||||
for (i = 0; i < discovery_option->num_of_target_plmn_list; i++)
|
for (i = 0; i < discovery_option->num_of_target_plmn_list; i++)
|
||||||
ogs_debug("[%d] target-plmn-list[MCC:%03d,MNC:%03d]", i,
|
ogs_debug("[%d] target-plmn-list[MCC:%03d,MNC:%03d]", i,
|
||||||
|
|
|
@ -225,6 +225,9 @@ static int request_handler(ogs_sbi_request_t *request, void *data)
|
||||||
} else if (!strcasecmp(key, OGS_SBI_CUSTOM_DISCOVERY_SNSSAIS)) {
|
} else if (!strcasecmp(key, OGS_SBI_CUSTOM_DISCOVERY_SNSSAIS)) {
|
||||||
if (val)
|
if (val)
|
||||||
ogs_sbi_discovery_option_parse_snssais(discovery_option, val);
|
ogs_sbi_discovery_option_parse_snssais(discovery_option, val);
|
||||||
|
} else if (!strcasecmp(key, OGS_SBI_CUSTOM_DISCOVERY_GUAMI)) {
|
||||||
|
if (val)
|
||||||
|
ogs_sbi_discovery_option_parse_guami(discovery_option, val);
|
||||||
} else if (!strcasecmp(key, OGS_SBI_CUSTOM_DISCOVERY_DNN)) {
|
} else if (!strcasecmp(key, OGS_SBI_CUSTOM_DISCOVERY_DNN)) {
|
||||||
ogs_sbi_discovery_option_set_dnn(discovery_option, val);
|
ogs_sbi_discovery_option_set_dnn(discovery_option, val);
|
||||||
} else if (!strcasecmp(key, OGS_SBI_CUSTOM_DISCOVERY_TAI)) {
|
} else if (!strcasecmp(key, OGS_SBI_CUSTOM_DISCOVERY_TAI)) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -182,6 +182,7 @@ int sgwc_gtp_send_create_session_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE;
|
h.type = OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgwc_ue->mme_s11_teid;
|
h.teid = sgwc_ue->mme_s11_teid;
|
||||||
|
|
||||||
pkbuf = sgwc_s11_build_create_session_response(h.type, sess);
|
pkbuf = sgwc_s11_build_create_session_response(h.type, sess);
|
||||||
|
@ -229,6 +230,7 @@ int sgwc_gtp_send_downlink_data_notification(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_TYPE;
|
h.type = OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sgwc_ue->mme_s11_teid;
|
h.teid = sgwc_ue->mme_s11_teid;
|
||||||
|
|
||||||
pkbuf = sgwc_s11_build_downlink_data_notification(cause_value, bearer);
|
pkbuf = sgwc_s11_build_downlink_data_notification(cause_value, bearer);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -222,6 +222,7 @@ int sgwc_pfcp_send_bearer_to_modify_list(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->sgwu_sxa_seid;
|
h.seid = sess->sgwu_sxa_seid;
|
||||||
|
|
||||||
sxabuf = sgwc_sxa_build_bearer_to_modify_list(h.type, sess, xact);
|
sxabuf = sgwc_sxa_build_bearer_to_modify_list(h.type, sess, xact);
|
||||||
|
@ -302,6 +303,7 @@ int sgwc_pfcp_send_session_establishment_request(
|
||||||
* over N4 towards another SMF or another PFCP entity in the SMF
|
* over N4 towards another SMF or another PFCP entity in the SMF
|
||||||
* as specified in clause 5.22.2 and clause 5.22.3.
|
* as specified in clause 5.22.2 and clause 5.22.3.
|
||||||
*/
|
*/
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->sgwu_sxa_seid;
|
h.seid = sess->sgwu_sxa_seid;
|
||||||
|
|
||||||
sxabuf = sgwc_sxa_build_session_establishment_request(h.type, sess);
|
sxabuf = sgwc_sxa_build_session_establishment_request(h.type, sess);
|
||||||
|
@ -389,6 +391,7 @@ int sgwc_pfcp_send_bearer_modification_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->sgwu_sxa_seid;
|
h.seid = sess->sgwu_sxa_seid;
|
||||||
|
|
||||||
sxabuf = sgwc_sxa_build_bearer_to_modify_list(h.type, sess, xact);
|
sxabuf = sgwc_sxa_build_bearer_to_modify_list(h.type, sess, xact);
|
||||||
|
@ -437,6 +440,7 @@ int sgwc_pfcp_send_session_deletion_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->sgwu_sxa_seid;
|
h.seid = sess->sgwu_sxa_seid;
|
||||||
|
|
||||||
sxabuf = sgwc_sxa_build_session_deletion_request(h.type, sess);
|
sxabuf = sgwc_sxa_build_session_deletion_request(h.type, sess);
|
||||||
|
@ -466,6 +470,7 @@ int sgwc_pfcp_send_session_report_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE;
|
h.type = OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->sgwu_sxa_seid;
|
h.seid = sess->sgwu_sxa_seid;
|
||||||
|
|
||||||
sxabuf = ogs_pfcp_build_session_report_response(h.type, cause);
|
sxabuf = ogs_pfcp_build_session_report_response(h.type, cause);
|
||||||
|
|
|
@ -356,10 +356,6 @@ void sgwc_pfcp_state_associated(ogs_fsm_t *s, sgwc_event_t *e)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SGWC_EVT_SXA_NO_HEARTBEAT:
|
case SGWC_EVT_SXA_NO_HEARTBEAT:
|
||||||
|
|
||||||
/* 'node' context was removed in ogs_pfcp_xact_delete(xact)
|
|
||||||
* So, we should not use PFCP node here */
|
|
||||||
|
|
||||||
ogs_warn("No Heartbeat from SGW-U [%s]:%d",
|
ogs_warn("No Heartbeat from SGW-U [%s]:%d",
|
||||||
OGS_ADDR(addr, buf), OGS_PORT(addr));
|
OGS_ADDR(addr, buf), OGS_PORT(addr));
|
||||||
OGS_FSM_TRAN(s, sgwc_pfcp_state_will_associate);
|
OGS_FSM_TRAN(s, sgwc_pfcp_state_will_associate);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -173,8 +173,9 @@ void sgwc_s11_handle_create_session_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -214,8 +215,9 @@ void sgwc_s11_handle_create_session_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -262,8 +264,9 @@ void sgwc_s11_handle_create_session_request(
|
||||||
/* Check if selected SGW-U is associated with SGW-C */
|
/* Check if selected SGW-U is associated with SGW-C */
|
||||||
ogs_assert(sess->pfcp_node);
|
ogs_assert(sess->pfcp_node);
|
||||||
if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, sgwc_pfcp_state_associated)) {
|
if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, sgwc_pfcp_state_associated)) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING);
|
OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING);
|
||||||
return;
|
return;
|
||||||
|
@ -423,8 +426,9 @@ void sgwc_s11_handle_modify_bearer_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -531,8 +535,9 @@ void sgwc_s11_handle_modify_bearer_request(
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
ogs_error("No Bearer");
|
ogs_error("No Bearer");
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -609,8 +614,9 @@ void sgwc_s11_handle_delete_session_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -629,8 +635,9 @@ void sgwc_s11_handle_delete_session_request(
|
||||||
indication->operation_indication == 1 &&
|
indication->operation_indication == 1 &&
|
||||||
indication->scope_indication == 1) {
|
indication->scope_indication == 1) {
|
||||||
ogs_error("Invalid Indication");
|
ogs_error("Invalid Indication");
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE,
|
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_INVALID_MESSAGE_FORMAT);
|
OGS_GTP2_CAUSE_INVALID_MESSAGE_FORMAT);
|
||||||
return;
|
return;
|
||||||
|
@ -656,6 +663,7 @@ void sgwc_s11_handle_delete_session_request(
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
message->h.type = OGS_GTP2_DELETE_SESSION_REQUEST_TYPE;
|
message->h.type = OGS_GTP2_DELETE_SESSION_REQUEST_TYPE;
|
||||||
|
message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
message->h.teid = sess->pgw_s5c_teid;
|
message->h.teid = sess->pgw_s5c_teid;
|
||||||
|
|
||||||
gtpbuf = ogs_gtp2_build_msg(message);
|
gtpbuf = ogs_gtp2_build_msg(message);
|
||||||
|
@ -762,7 +770,9 @@ void sgwc_s11_handle_create_bearer_response(
|
||||||
sgwc_pfcp_send_bearer_modification_request(
|
sgwc_pfcp_send_bearer_modification_request(
|
||||||
bearer, NULL, NULL,
|
bearer, NULL, NULL,
|
||||||
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_REMOVE));
|
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_REMOVE));
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -781,7 +791,9 @@ void sgwc_s11_handle_create_bearer_response(
|
||||||
sgwc_pfcp_send_bearer_modification_request(
|
sgwc_pfcp_send_bearer_modification_request(
|
||||||
bearer, NULL, NULL,
|
bearer, NULL, NULL,
|
||||||
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_REMOVE));
|
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_REMOVE));
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -915,7 +927,9 @@ void sgwc_s11_handle_update_bearer_response(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -930,7 +944,9 @@ void sgwc_s11_handle_update_bearer_response(
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_error("GTP Bearer Cause [VALUE:%d]", cause_value);
|
ogs_error("GTP Bearer Cause [VALUE:%d]", cause_value);
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -940,7 +956,9 @@ void sgwc_s11_handle_update_bearer_response(
|
||||||
cause_value = cause->value;
|
cause_value = cause->value;
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_error("GTP Cause [Value:%d]", cause_value);
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -957,6 +975,7 @@ void sgwc_s11_handle_update_bearer_response(
|
||||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||||
|
|
||||||
message->h.type = OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE;
|
message->h.type = OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE;
|
||||||
|
message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
message->h.teid = sess->pgw_s5c_teid;
|
message->h.teid = sess->pgw_s5c_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(message);
|
pkbuf = ogs_gtp2_build_msg(message);
|
||||||
|
@ -1128,8 +1147,9 @@ void sgwc_s11_handle_release_access_bearers_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1235,8 +1255,9 @@ void sgwc_s11_handle_create_indirect_data_forwarding_tunnel_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
||||||
cause_value);
|
cause_value);
|
||||||
return;
|
return;
|
||||||
|
@ -1253,8 +1274,9 @@ void sgwc_s11_handle_create_indirect_data_forwarding_tunnel_request(
|
||||||
for (i = 0; req->bearer_contexts[i].presence; i++) {
|
for (i = 0; req->bearer_contexts[i].presence; i++) {
|
||||||
if (req->bearer_contexts[i].eps_bearer_id.presence == 0) {
|
if (req->bearer_contexts[i].eps_bearer_id.presence == 0) {
|
||||||
ogs_error("No EBI");
|
ogs_error("No EBI");
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
||||||
return;
|
return;
|
||||||
|
@ -1276,8 +1298,9 @@ void sgwc_s11_handle_create_indirect_data_forwarding_tunnel_request(
|
||||||
|
|
||||||
rv = ogs_gtp2_f_teid_to_ip(req_teid, &tunnel->remote_ip);
|
rv = ogs_gtp2_f_teid_to_ip(req_teid, &tunnel->remote_ip);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_gtp_send_error_message(s11_xact,
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
||||||
return;
|
return;
|
||||||
|
@ -1311,8 +1334,9 @@ void sgwc_s11_handle_create_indirect_data_forwarding_tunnel_request(
|
||||||
|
|
||||||
rv = ogs_gtp2_f_teid_to_ip(req_teid, &tunnel->remote_ip);
|
rv = ogs_gtp2_f_teid_to_ip(req_teid, &tunnel->remote_ip);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_gtp_send_error_message(s11_xact,
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
||||||
return;
|
return;
|
||||||
|
@ -1366,8 +1390,9 @@ void sgwc_s11_handle_delete_indirect_data_forwarding_tunnel_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
||||||
cause_value);
|
cause_value);
|
||||||
return;
|
return;
|
||||||
|
@ -1441,8 +1466,9 @@ void sgwc_s11_handle_bearer_resource_command(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1462,8 +1488,9 @@ void sgwc_s11_handle_bearer_resource_command(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1483,6 +1510,7 @@ void sgwc_s11_handle_bearer_resource_command(
|
||||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||||
|
|
||||||
message->h.type = OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE;
|
message->h.type = OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE;
|
||||||
|
message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
message->h.teid = sess->pgw_s5c_teid;
|
message->h.teid = sess->pgw_s5c_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(message);
|
pkbuf = ogs_gtp2_build_msg(message);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024444 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -122,8 +122,9 @@ void sgwc_s5c_handle_create_session_response(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -160,8 +161,9 @@ void sgwc_s5c_handle_create_session_response(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -185,8 +187,10 @@ void sgwc_s5c_handle_create_session_response(
|
||||||
bearer_cause = cause->value;
|
bearer_cause = cause->value;
|
||||||
if (bearer_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (bearer_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_error("GTP Bearer Cause [VALUE:%d]", bearer_cause);
|
ogs_error("GTP Bearer Cause [VALUE:%d]", bearer_cause);
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE :
|
||||||
|
OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, bearer_cause);
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, bearer_cause);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -199,8 +203,9 @@ void sgwc_s5c_handle_create_session_response(
|
||||||
session_cause !=
|
session_cause !=
|
||||||
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_SINGLE_ADDRESS_BEARER_ONLY) {
|
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_SINGLE_ADDRESS_BEARER_ONLY) {
|
||||||
ogs_error("GTP Cause [VALUE:%d]", session_cause);
|
ogs_error("GTP Cause [VALUE:%d]", session_cause);
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, session_cause);
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, session_cause);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -233,8 +238,10 @@ void sgwc_s5c_handle_create_session_response(
|
||||||
bearer = sgwc_bearer_find_by_sess_ebi(sess,
|
bearer = sgwc_bearer_find_by_sess_ebi(sess,
|
||||||
rsp->bearer_contexts_created[i].eps_bearer_id.u8);
|
rsp->bearer_contexts_created[i].eps_bearer_id.u8);
|
||||||
if (!bearer) {
|
if (!bearer) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE :
|
||||||
|
OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
||||||
return;
|
return;
|
||||||
|
@ -253,8 +260,10 @@ void sgwc_s5c_handle_create_session_response(
|
||||||
|
|
||||||
rv = ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &ul_tunnel->remote_ip);
|
rv = ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &ul_tunnel->remote_ip);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE :
|
||||||
|
OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
||||||
return;
|
return;
|
||||||
|
@ -354,13 +363,15 @@ void sgwc_s5c_handle_modify_bearer_response(
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||||
else
|
else
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,13 +387,15 @@ void sgwc_s5c_handle_modify_bearer_response(
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||||
else
|
else
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,13 +407,15 @@ void sgwc_s5c_handle_modify_bearer_response(
|
||||||
if (session_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (session_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_error("GTP Cause [VALUE:%d]", session_cause);
|
ogs_error("GTP Cause [VALUE:%d]", session_cause);
|
||||||
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, session_cause);
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, session_cause);
|
||||||
else
|
else
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, session_cause);
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, session_cause);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,6 +435,7 @@ void sgwc_s5c_handle_modify_bearer_response(
|
||||||
sgwc_gtp_send_create_session_response(sess, s11_xact));
|
sgwc_gtp_send_create_session_response(sess, s11_xact));
|
||||||
} else {
|
} else {
|
||||||
message->h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
message->h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
||||||
|
message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
message->h.teid = sgwc_ue->mme_s11_teid;
|
message->h.teid = sgwc_ue->mme_s11_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(message);
|
pkbuf = ogs_gtp2_build_msg(message);
|
||||||
|
@ -493,8 +509,9 @@ void sgwc_s5c_handle_delete_session_response(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -573,7 +590,9 @@ void sgwc_s5c_handle_create_bearer_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -601,7 +620,9 @@ void sgwc_s5c_handle_create_bearer_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -631,7 +652,9 @@ void sgwc_s5c_handle_create_bearer_request(
|
||||||
|
|
||||||
rv = ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &ul_tunnel->remote_ip);
|
rv = ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &ul_tunnel->remote_ip);
|
||||||
if (rv != OGS_OK) {
|
if (rv != OGS_OK) {
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE,
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
||||||
return;
|
return;
|
||||||
|
@ -709,7 +732,9 @@ void sgwc_s5c_handle_update_bearer_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -729,6 +754,7 @@ void sgwc_s5c_handle_update_bearer_request(
|
||||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||||
|
|
||||||
message->h.type = OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE;
|
message->h.type = OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE;
|
||||||
|
message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
message->h.teid = sgwc_ue->mme_s11_teid;
|
message->h.teid = sgwc_ue->mme_s11_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(message);
|
pkbuf = ogs_gtp2_build_msg(message);
|
||||||
|
@ -850,7 +876,9 @@ void sgwc_s5c_handle_delete_bearer_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -870,6 +898,7 @@ void sgwc_s5c_handle_delete_bearer_request(
|
||||||
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
sess->sgw_s5c_teid, sess->pgw_s5c_teid);
|
||||||
|
|
||||||
message->h.type = OGS_GTP2_DELETE_BEARER_REQUEST_TYPE;
|
message->h.type = OGS_GTP2_DELETE_BEARER_REQUEST_TYPE;
|
||||||
|
message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
message->h.teid = sgwc_ue->mme_s11_teid;
|
message->h.teid = sgwc_ue->mme_s11_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(message);
|
pkbuf = ogs_gtp2_build_msg(message);
|
||||||
|
@ -970,6 +999,8 @@ void sgwc_s5c_handle_bearer_resource_failure_indication(
|
||||||
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_gtp_send_error_message(s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -245,8 +245,9 @@ void sgwc_sxa_handle_session_establishment_response(
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
if (sess) sgwc_ue = sess->sgwc_ue;
|
if (sess) sgwc_ue = sess->sgwc_ue;
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -269,10 +270,11 @@ void sgwc_sxa_handle_session_establishment_response(
|
||||||
|
|
||||||
if (dl_tunnel->local_addr == NULL && dl_tunnel->local_addr6 == NULL) {
|
if (dl_tunnel->local_addr == NULL && dl_tunnel->local_addr6 == NULL) {
|
||||||
ogs_error("No UP F-TEID");
|
ogs_error("No UP F-TEID");
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CAUSE_GRE_KEY_NOT_FOUND);
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
||||||
|
OGS_GTP2_CAUSE_GRE_KEY_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,6 +349,7 @@ void sgwc_sxa_handle_session_establishment_response(
|
||||||
memset(&send_message, 0, sizeof(ogs_gtp2_message_t));
|
memset(&send_message, 0, sizeof(ogs_gtp2_message_t));
|
||||||
|
|
||||||
send_message.h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
send_message.h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
||||||
|
send_message.h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
send_message.h.teid = sess->pgw_s5c_teid;
|
send_message.h.teid = sess->pgw_s5c_teid;
|
||||||
|
|
||||||
/* Send Control Plane(DL) : SGW-S5C */
|
/* Send Control Plane(DL) : SGW-S5C */
|
||||||
|
@ -396,6 +399,7 @@ void sgwc_sxa_handle_session_establishment_response(
|
||||||
|
|
||||||
/* Create Session Request */
|
/* Create Session Request */
|
||||||
recv_message->h.type = OGS_GTP2_CREATE_SESSION_REQUEST_TYPE;
|
recv_message->h.type = OGS_GTP2_CREATE_SESSION_REQUEST_TYPE;
|
||||||
|
recv_message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
recv_message->h.teid = sess->pgw_s5c_teid;
|
recv_message->h.teid = sess->pgw_s5c_teid;
|
||||||
|
|
||||||
/* Send Control Plane(DL) : SGW-S5C */
|
/* Send Control Plane(DL) : SGW-S5C */
|
||||||
|
@ -581,9 +585,10 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
s5c_xact = pfcp_xact->assoc_xact;
|
s5c_xact = pfcp_xact->assoc_xact;
|
||||||
|
|
||||||
if (s5c_xact) {
|
if (s5c_xact) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE, cause_value);
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
|
OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
sgwc_bearer_remove(bearer);
|
sgwc_bearer_remove(bearer);
|
||||||
|
@ -591,8 +596,9 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
s5c_xact = pfcp_xact->assoc_xact;
|
s5c_xact = pfcp_xact->assoc_xact;
|
||||||
ogs_assert(s5c_xact);
|
ogs_assert(s5c_xact);
|
||||||
|
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s5c_xact,
|
||||||
s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->pgw_s5c_teid : 0,
|
||||||
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
|
|
||||||
|
|
||||||
|
@ -601,16 +607,20 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
s11_xact = pfcp_xact->assoc_xact;
|
s11_xact = pfcp_xact->assoc_xact;
|
||||||
ogs_assert(s11_xact);
|
ogs_assert(s11_xact);
|
||||||
|
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE :
|
||||||
|
OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||||
|
|
||||||
} else if (flags & OGS_PFCP_MODIFY_DL_ONLY) {
|
} else if (flags & OGS_PFCP_MODIFY_DL_ONLY) {
|
||||||
s11_xact = pfcp_xact->assoc_xact;
|
s11_xact = pfcp_xact->assoc_xact;
|
||||||
ogs_assert(s11_xact);
|
ogs_assert(s11_xact);
|
||||||
|
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE :
|
||||||
|
OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
} else {
|
} else {
|
||||||
ogs_fatal("Invalid modify_flags[0x%llx]", (long long)flags);
|
ogs_fatal("Invalid modify_flags[0x%llx]", (long long)flags);
|
||||||
|
@ -620,9 +630,10 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
s11_xact = pfcp_xact->assoc_xact;
|
s11_xact = pfcp_xact->assoc_xact;
|
||||||
ogs_assert(s11_xact);
|
ogs_assert(s11_xact);
|
||||||
|
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(s11_xact,
|
||||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE, cause_value);
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||||
|
OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE, cause_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
ogs_pfcp_xact_commit(pfcp_xact);
|
ogs_pfcp_xact_commit(pfcp_xact);
|
||||||
|
@ -694,6 +705,7 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
|
|
||||||
send_message.h.type =
|
send_message.h.type =
|
||||||
OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE;
|
OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE;
|
||||||
|
send_message.h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(&send_message);
|
pkbuf = ogs_gtp2_build_msg(&send_message);
|
||||||
|
@ -720,6 +732,7 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
if (s5c_xact) {
|
if (s5c_xact) {
|
||||||
ogs_assert(recv_message);
|
ogs_assert(recv_message);
|
||||||
recv_message->h.type = OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE;
|
recv_message->h.type = OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE;
|
||||||
|
recv_message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
recv_message->h.teid = sess->pgw_s5c_teid;
|
recv_message->h.teid = sess->pgw_s5c_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(recv_message);
|
pkbuf = ogs_gtp2_build_msg(recv_message);
|
||||||
|
@ -769,6 +782,7 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
gtp_req->bearer_contexts.s1_u_enodeb_f_teid.len = len;
|
gtp_req->bearer_contexts.s1_u_enodeb_f_teid.len = len;
|
||||||
|
|
||||||
recv_message->h.type = OGS_GTP2_CREATE_BEARER_REQUEST_TYPE;
|
recv_message->h.type = OGS_GTP2_CREATE_BEARER_REQUEST_TYPE;
|
||||||
|
recv_message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
recv_message->h.teid = sgwc_ue->mme_s11_teid;
|
recv_message->h.teid = sgwc_ue->mme_s11_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(recv_message);
|
pkbuf = ogs_gtp2_build_msg(recv_message);
|
||||||
|
@ -836,6 +850,7 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
gtp_rsp->bearer_contexts.s5_s8_u_pgw_f_teid.len = len;
|
gtp_rsp->bearer_contexts.s5_s8_u_pgw_f_teid.len = len;
|
||||||
|
|
||||||
recv_message->h.type = OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE;
|
recv_message->h.type = OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE;
|
||||||
|
recv_message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
recv_message->h.teid = sess->pgw_s5c_teid;
|
recv_message->h.teid = sess->pgw_s5c_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(recv_message);
|
pkbuf = ogs_gtp2_build_msg(recv_message);
|
||||||
|
@ -962,6 +977,7 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
|
|
||||||
send_message.h.type =
|
send_message.h.type =
|
||||||
OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE;
|
OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE;
|
||||||
|
send_message.h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(&send_message);
|
pkbuf = ogs_gtp2_build_msg(&send_message);
|
||||||
|
@ -1046,6 +1062,7 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
}
|
}
|
||||||
|
|
||||||
recv_message->h.type = OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE;
|
recv_message->h.type = OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE;
|
||||||
|
recv_message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
recv_message->h.teid = sgwc_ue->mme_s11_teid;
|
recv_message->h.teid = sgwc_ue->mme_s11_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(recv_message);
|
pkbuf = ogs_gtp2_build_msg(recv_message);
|
||||||
|
@ -1083,6 +1100,7 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
|
|
||||||
if (indication && indication->handover_indication) {
|
if (indication && indication->handover_indication) {
|
||||||
recv_message->h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
recv_message->h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
||||||
|
recv_message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
recv_message->h.teid = sess->pgw_s5c_teid;
|
recv_message->h.teid = sess->pgw_s5c_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(recv_message);
|
pkbuf = ogs_gtp2_build_msg(recv_message);
|
||||||
|
@ -1168,6 +1186,7 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
}
|
}
|
||||||
|
|
||||||
send_message.h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
send_message.h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
||||||
|
send_message.h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(&send_message);
|
pkbuf = ogs_gtp2_build_msg(&send_message);
|
||||||
|
@ -1233,6 +1252,7 @@ void sgwc_sxa_handle_session_modification_response(
|
||||||
|
|
||||||
send_message.h.type =
|
send_message.h.type =
|
||||||
OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE;
|
OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE;
|
||||||
|
send_message.h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(&send_message);
|
pkbuf = ogs_gtp2_build_msg(&send_message);
|
||||||
|
@ -1264,6 +1284,7 @@ void sgwc_sxa_handle_session_deletion_response(
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
uint8_t cause_value = 0;
|
uint8_t cause_value = 0;
|
||||||
|
int teid_presence = OGS_GTP2_TEID_NO_PRESENCE;
|
||||||
uint32_t teid = 0;
|
uint32_t teid = 0;
|
||||||
|
|
||||||
sgwc_ue_t *sgwc_ue = NULL;
|
sgwc_ue_t *sgwc_ue = NULL;
|
||||||
|
@ -1315,6 +1336,8 @@ void sgwc_sxa_handle_session_deletion_response(
|
||||||
* 2. SMF sends Delete Session Response to SGW/MME.
|
* 2. SMF sends Delete Session Response to SGW/MME.
|
||||||
*/
|
*/
|
||||||
if (sess) sgwc_ue = sess->sgwc_ue;
|
if (sess) sgwc_ue = sess->sgwc_ue;
|
||||||
|
teid_presence =
|
||||||
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE;
|
||||||
teid = sgwc_ue ? sgwc_ue->mme_s11_teid : 0;
|
teid = sgwc_ue ? sgwc_ue->mme_s11_teid : 0;
|
||||||
break;
|
break;
|
||||||
case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
|
case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
|
||||||
|
@ -1331,6 +1354,8 @@ void sgwc_sxa_handle_session_deletion_response(
|
||||||
* - Bearer Resource Command
|
* - Bearer Resource Command
|
||||||
* - Delete Bearer Request/Response with DEDICATED BEARER.
|
* - Delete Bearer Request/Response with DEDICATED BEARER.
|
||||||
*/
|
*/
|
||||||
|
teid_presence =
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE;
|
||||||
teid = sess ? sess->pgw_s5c_teid : 0;
|
teid = sess ? sess->pgw_s5c_teid : 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1340,8 +1365,8 @@ void sgwc_sxa_handle_session_deletion_response(
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
if (gtp_xact) {
|
if (gtp_xact) {
|
||||||
ogs_gtp_send_error_message(
|
ogs_gtp2_send_error_message(gtp_xact,
|
||||||
gtp_xact, teid, gtp_message->h.type, cause_value);
|
teid_presence, teid, gtp_message->h.type, cause_value);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1358,6 +1383,7 @@ void sgwc_sxa_handle_session_deletion_response(
|
||||||
* If gtp_message->h.type == OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE
|
* If gtp_message->h.type == OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE
|
||||||
* Then gtp_xact is S5C-XACT
|
* Then gtp_xact is S5C-XACT
|
||||||
*/
|
*/
|
||||||
|
gtp_message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
gtp_message->h.teid = teid;
|
gtp_message->h.teid = teid;
|
||||||
|
|
||||||
pkbuf = ogs_gtp2_build_msg(gtp_message);
|
pkbuf = ogs_gtp2_build_msg(gtp_message);
|
||||||
|
@ -1419,7 +1445,8 @@ void sgwc_sxa_handle_session_report_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_pfcp_send_error_message(pfcp_xact, 0,
|
ogs_pfcp_send_error_message(pfcp_xact,
|
||||||
|
OGS_PFCP_SEID_NO_PRESENCE, 0,
|
||||||
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
||||||
cause_value, 0);
|
cause_value, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -1431,7 +1458,9 @@ void sgwc_sxa_handle_session_report_request(
|
||||||
|
|
||||||
if (!sgwc_ue->gnode) {
|
if (!sgwc_ue->gnode) {
|
||||||
ogs_error("No SGWC-UE GTP Node");
|
ogs_error("No SGWC-UE GTP Node");
|
||||||
ogs_pfcp_send_error_message(pfcp_xact, sess ? sess->sgwu_sxa_seid : 0,
|
ogs_pfcp_send_error_message(pfcp_xact,
|
||||||
|
sess ? OGS_PFCP_SEID_PRESENCE : OGS_PFCP_SEID_NO_PRESENCE,
|
||||||
|
sess ? sess->sgwu_sxa_seid : 0,
|
||||||
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
||||||
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -180,6 +180,7 @@ int sgwu_pfcp_send_session_establishment_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE;
|
h.type = OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->sgwc_sxa_f_seid.seid;
|
h.seid = sess->sgwc_sxa_f_seid.seid;
|
||||||
|
|
||||||
sxabuf = sgwu_sxa_build_session_establishment_response(
|
sxabuf = sgwu_sxa_build_session_establishment_response(
|
||||||
|
@ -213,6 +214,7 @@ int sgwu_pfcp_send_session_modification_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE;
|
h.type = OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->sgwc_sxa_f_seid.seid;
|
h.seid = sess->sgwc_sxa_f_seid.seid;
|
||||||
|
|
||||||
sxabuf = sgwu_sxa_build_session_modification_response(
|
sxabuf = sgwu_sxa_build_session_modification_response(
|
||||||
|
@ -245,6 +247,7 @@ int sgwu_pfcp_send_session_deletion_response(ogs_pfcp_xact_t *xact,
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE;
|
h.type = OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->sgwc_sxa_f_seid.seid;
|
h.seid = sess->sgwc_sxa_f_seid.seid;
|
||||||
|
|
||||||
sxabuf = sgwu_sxa_build_session_deletion_response(h.type, sess);
|
sxabuf = sgwu_sxa_build_session_deletion_response(h.type, sess);
|
||||||
|
@ -295,6 +298,7 @@ int sgwu_pfcp_send_session_report_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_REPORT_REQUEST_TYPE;
|
h.type = OGS_PFCP_SESSION_REPORT_REQUEST_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->sgwc_sxa_f_seid.seid;
|
h.seid = sess->sgwc_sxa_f_seid.seid;
|
||||||
|
|
||||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess);
|
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess);
|
||||||
|
|
|
@ -318,10 +318,6 @@ void sgwu_pfcp_state_associated(ogs_fsm_t *s, sgwu_event_t *e)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SGWU_EVT_SXA_NO_HEARTBEAT:
|
case SGWU_EVT_SXA_NO_HEARTBEAT:
|
||||||
|
|
||||||
/* 'node' context was removed in ogs_pfcp_xact_delete(xact)
|
|
||||||
* So, we should not use PFCP node here */
|
|
||||||
|
|
||||||
ogs_warn("No Heartbeat from SGW-C [%s]:%d",
|
ogs_warn("No Heartbeat from SGW-C [%s]:%d",
|
||||||
OGS_ADDR(addr, buf), OGS_PORT(addr));
|
OGS_ADDR(addr, buf), OGS_PORT(addr));
|
||||||
OGS_FSM_TRAN(s, sgwu_pfcp_state_will_associate);
|
OGS_FSM_TRAN(s, sgwu_pfcp_state_will_associate);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -45,7 +45,8 @@ void sgwu_sxa_handle_session_establishment_request(
|
||||||
|
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
ogs_error("No Context");
|
ogs_error("No Context");
|
||||||
ogs_pfcp_send_error_message(xact, 0,
|
ogs_pfcp_send_error_message(xact,
|
||||||
|
OGS_PFCP_SEID_NO_PRESENCE, 0,
|
||||||
OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE,
|
||||||
OGS_PFCP_CAUSE_MANDATORY_IE_MISSING, 0);
|
OGS_PFCP_CAUSE_MANDATORY_IE_MISSING, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -142,7 +143,9 @@ void sgwu_sxa_handle_session_establishment_request(
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
ogs_pfcp_sess_clear(&sess->pfcp);
|
ogs_pfcp_sess_clear(&sess->pfcp);
|
||||||
ogs_pfcp_send_error_message(xact, sess ? sess->sgwu_sxa_seid : 0,
|
ogs_pfcp_send_error_message(xact,
|
||||||
|
sess ? OGS_PFCP_SEID_PRESENCE : OGS_PFCP_SEID_NO_PRESENCE,
|
||||||
|
sess ? sess->sgwu_sxa_seid : 0,
|
||||||
OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE,
|
||||||
cause_value, offending_ie_value);
|
cause_value, offending_ie_value);
|
||||||
}
|
}
|
||||||
|
@ -168,7 +171,8 @@ void sgwu_sxa_handle_session_modification_request(
|
||||||
|
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
ogs_error("No Context");
|
ogs_error("No Context");
|
||||||
ogs_pfcp_send_error_message(xact, 0,
|
ogs_pfcp_send_error_message(xact,
|
||||||
|
OGS_PFCP_SEID_NO_PRESENCE, 0,
|
||||||
OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE,
|
||||||
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -309,7 +313,9 @@ void sgwu_sxa_handle_session_modification_request(
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
ogs_pfcp_sess_clear(&sess->pfcp);
|
ogs_pfcp_sess_clear(&sess->pfcp);
|
||||||
ogs_pfcp_send_error_message(xact, sess ? sess->sgwu_sxa_seid : 0,
|
ogs_pfcp_send_error_message(xact,
|
||||||
|
sess ? OGS_PFCP_SEID_PRESENCE : OGS_PFCP_SEID_NO_PRESENCE,
|
||||||
|
sess ? sess->sgwu_sxa_seid : 0,
|
||||||
OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE,
|
||||||
cause_value, offending_ie_value);
|
cause_value, offending_ie_value);
|
||||||
}
|
}
|
||||||
|
@ -325,7 +331,8 @@ void sgwu_sxa_handle_session_deletion_request(
|
||||||
|
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
ogs_error("No Context");
|
ogs_error("No Context");
|
||||||
ogs_pfcp_send_error_message(xact, 0,
|
ogs_pfcp_send_error_message(xact,
|
||||||
|
OGS_PFCP_SEID_NO_PRESENCE, 0,
|
||||||
OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE,
|
||||||
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -363,6 +363,7 @@ void smf_bearer_binding(smf_sess_t *sess)
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE;
|
h.type = OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sess->sgw_s5c_teid;
|
h.teid = sess->sgw_s5c_teid;
|
||||||
|
|
||||||
pkbuf = smf_s5c_build_update_bearer_request(
|
pkbuf = smf_s5c_build_update_bearer_request(
|
||||||
|
@ -439,6 +440,7 @@ int smf_gtp2_send_create_bearer_request(smf_bearer_t *bearer)
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
|
|
||||||
h.type = OGS_GTP2_CREATE_BEARER_REQUEST_TYPE;
|
h.type = OGS_GTP2_CREATE_BEARER_REQUEST_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sess->sgw_s5c_teid;
|
h.teid = sess->sgw_s5c_teid;
|
||||||
|
|
||||||
memset(&tft, 0, sizeof tft);
|
memset(&tft, 0, sizeof tft);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
|
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -74,7 +73,9 @@ static void send_gtp_create_err_msg(const smf_sess_t *sess,
|
||||||
ogs_gtp1_send_error_message(gtp_xact, sess->sgw_s5c_teid,
|
ogs_gtp1_send_error_message(gtp_xact, sess->sgw_s5c_teid,
|
||||||
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE, gtp_cause);
|
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE, gtp_cause);
|
||||||
else
|
else
|
||||||
ogs_gtp2_send_error_message(gtp_xact, sess->sgw_s5c_teid,
|
ogs_gtp2_send_error_message(gtp_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess->sgw_s5c_teid,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, gtp_cause);
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, gtp_cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +86,9 @@ static void send_gtp_delete_err_msg(const smf_sess_t *sess,
|
||||||
ogs_gtp1_send_error_message(gtp_xact, sess->sgw_s5c_teid,
|
ogs_gtp1_send_error_message(gtp_xact, sess->sgw_s5c_teid,
|
||||||
OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE, gtp_cause);
|
OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE, gtp_cause);
|
||||||
else
|
else
|
||||||
ogs_gtp2_send_error_message(gtp_xact, sess->sgw_s5c_teid,
|
ogs_gtp2_send_error_message(gtp_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess->sgw_s5c_teid,
|
||||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, gtp_cause);
|
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, gtp_cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,6 +719,9 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
||||||
ogs_pfcp_xact_t *pfcp_xact = NULL;
|
ogs_pfcp_xact_t *pfcp_xact = NULL;
|
||||||
ogs_pfcp_message_t *pfcp_message = NULL;
|
ogs_pfcp_message_t *pfcp_message = NULL;
|
||||||
|
|
||||||
|
ogs_diam_gy_message_t *gy_message = NULL;
|
||||||
|
uint32_t diam_err;
|
||||||
|
|
||||||
ogs_nas_5gs_message_t *nas_message = NULL;
|
ogs_nas_5gs_message_t *nas_message = NULL;
|
||||||
|
|
||||||
ogs_sbi_stream_t *stream = NULL;
|
ogs_sbi_stream_t *stream = NULL;
|
||||||
|
@ -772,8 +778,10 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
||||||
sess, e->gtp_xact,
|
sess, e->gtp_xact,
|
||||||
>p2_message->delete_session_request);
|
>p2_message->delete_session_request);
|
||||||
if (gtp2_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (gtp2_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp2_send_error_message(e->gtp_xact, sess->sgw_s5c_teid,
|
ogs_gtp2_send_error_message(e->gtp_xact,
|
||||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, gtp2_cause);
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess->sgw_s5c_teid,
|
||||||
|
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, gtp2_cause);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
OGS_FSM_TRAN(s, smf_gsm_state_wait_pfcp_deletion);
|
OGS_FSM_TRAN(s, smf_gsm_state_wait_pfcp_deletion);
|
||||||
|
@ -829,6 +837,24 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SMF_EVT_GY_MESSAGE:
|
||||||
|
gy_message = e->gy_message;
|
||||||
|
ogs_assert(gy_message);
|
||||||
|
|
||||||
|
switch(gy_message->cmd_code) {
|
||||||
|
case OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL:
|
||||||
|
switch (gy_message->cc_request_type) {
|
||||||
|
case OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST:
|
||||||
|
ogs_assert(e->pfcp_xact);
|
||||||
|
diam_err = smf_gy_handle_cca_update_request(sess, gy_message, e->pfcp_xact);
|
||||||
|
if (diam_err != ER_DIAMETER_SUCCESS)
|
||||||
|
OGS_FSM_TRAN(s, smf_gsm_state_wait_pfcp_deletion);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case OGS_EVENT_SBI_SERVER:
|
case OGS_EVENT_SBI_SERVER:
|
||||||
sbi_message = e->h.sbi.message;
|
sbi_message = e->h.sbi.message;
|
||||||
ogs_assert(sbi_message);
|
ogs_assert(sbi_message);
|
||||||
|
@ -1465,7 +1491,6 @@ void smf_gsm_state_wait_epc_auth_release(ogs_fsm_t *s, smf_event_t *e)
|
||||||
case OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL:
|
case OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL:
|
||||||
switch(gy_message->cc_request_type) {
|
switch(gy_message->cc_request_type) {
|
||||||
case OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST:
|
case OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST:
|
||||||
ogs_assert(e->gtp_xact);
|
|
||||||
diam_err = smf_gy_handle_cca_termination_request(sess,
|
diam_err = smf_gy_handle_cca_termination_request(sess,
|
||||||
gy_message, e->gtp_xact);
|
gy_message, e->gtp_xact);
|
||||||
sess->sm_data.gy_ccr_term_in_flight = false;
|
sess->sm_data.gy_ccr_term_in_flight = false;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -444,6 +444,7 @@ int smf_gtp2_send_create_session_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE;
|
h.type = OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sess->sgw_s5c_teid;
|
h.teid = sess->sgw_s5c_teid;
|
||||||
|
|
||||||
pkbuf = smf_s5c_build_create_session_response(h.type, sess);
|
pkbuf = smf_s5c_build_create_session_response(h.type, sess);
|
||||||
|
@ -478,6 +479,7 @@ int smf_gtp2_send_modify_bearer_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sess->sgw_s5c_teid;
|
h.teid = sess->sgw_s5c_teid;
|
||||||
|
|
||||||
pkbuf = smf_s5c_build_modify_bearer_response(
|
pkbuf = smf_s5c_build_modify_bearer_response(
|
||||||
|
@ -511,6 +513,7 @@ int smf_gtp2_send_delete_session_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE;
|
h.type = OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sess->sgw_s5c_teid;
|
h.teid = sess->sgw_s5c_teid;
|
||||||
|
|
||||||
pkbuf = smf_s5c_build_delete_session_response(h.type, sess);
|
pkbuf = smf_s5c_build_delete_session_response(h.type, sess);
|
||||||
|
@ -548,6 +551,7 @@ int smf_gtp2_send_delete_bearer_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_DELETE_BEARER_REQUEST_TYPE;
|
h.type = OGS_GTP2_DELETE_BEARER_REQUEST_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sess->sgw_s5c_teid;
|
h.teid = sess->sgw_s5c_teid;
|
||||||
|
|
||||||
pkbuf = smf_s5c_build_delete_bearer_request(
|
pkbuf = smf_s5c_build_delete_bearer_request(
|
||||||
|
|
|
@ -149,7 +149,7 @@ uint32_t smf_gy_handle_cca_initial_request(
|
||||||
return ER_DIAMETER_SUCCESS;
|
return ER_DIAMETER_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smf_gy_handle_cca_update_request(
|
uint32_t smf_gy_handle_cca_update_request(
|
||||||
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
|
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
|
||||||
ogs_pfcp_xact_t *pfcp_xact)
|
ogs_pfcp_xact_t *pfcp_xact)
|
||||||
{
|
{
|
||||||
|
@ -175,10 +175,14 @@ void smf_gy_handle_cca_update_request(
|
||||||
if (gy_message->result_code != ER_DIAMETER_SUCCESS) {
|
if (gy_message->result_code != ER_DIAMETER_SUCCESS) {
|
||||||
ogs_warn("Gy CCA Update Diameter failure: res=%u err=%u",
|
ogs_warn("Gy CCA Update Diameter failure: res=%u err=%u",
|
||||||
gy_message->result_code, *gy_message->err);
|
gy_message->result_code, *gy_message->err);
|
||||||
// TODO: generate new gtp_xact from sess here? */
|
return gy_message->err ? *gy_message->err :
|
||||||
//ogs_assert(OGS_OK ==
|
ER_DIAMETER_AUTHENTICATION_REJECTED;
|
||||||
// smf_epc_pfcp_send_session_deletion_request(sess, gtp_xact));
|
}
|
||||||
return;
|
if (gy_message->cca.result_code != ER_DIAMETER_SUCCESS) {
|
||||||
|
ogs_warn("Gy CCA Update Diameter Multiple-Services-Credit-Control Result-Code=%u",
|
||||||
|
gy_message->cca.result_code);
|
||||||
|
return gy_message->cca.err ? *gy_message->cca.err :
|
||||||
|
ER_DIAMETER_AUTHENTICATION_REJECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bearer = smf_default_bearer_in_sess(sess);
|
bearer = smf_default_bearer_in_sess(sess);
|
||||||
|
@ -234,6 +238,7 @@ void smf_gy_handle_cca_update_request(
|
||||||
OGS_GTP1_CAUSE_REACTIACTION_REQUESTED);
|
OGS_GTP1_CAUSE_REACTIACTION_REQUESTED);
|
||||||
ogs_assert(rv == OGS_OK);
|
ogs_assert(rv == OGS_OK);
|
||||||
}
|
}
|
||||||
|
return ER_DIAMETER_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t smf_gy_handle_cca_termination_request(
|
uint32_t smf_gy_handle_cca_termination_request(
|
||||||
|
@ -242,7 +247,6 @@ uint32_t smf_gy_handle_cca_termination_request(
|
||||||
{
|
{
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
ogs_assert(gy_message);
|
ogs_assert(gy_message);
|
||||||
ogs_assert(gtp_xact);
|
|
||||||
|
|
||||||
ogs_debug("[SMF] Delete Session Response");
|
ogs_debug("[SMF] Delete Session Response");
|
||||||
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
|
ogs_debug(" SGW_S5C_TEID[0x%x] SMF_N4_TEID[0x%x]",
|
||||||
|
|
|
@ -30,7 +30,7 @@ extern "C" {
|
||||||
uint32_t smf_gy_handle_cca_initial_request(
|
uint32_t smf_gy_handle_cca_initial_request(
|
||||||
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
|
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
|
||||||
ogs_gtp_xact_t *gtp_xact);
|
ogs_gtp_xact_t *gtp_xact);
|
||||||
void smf_gy_handle_cca_update_request(
|
uint32_t smf_gy_handle_cca_update_request(
|
||||||
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
|
smf_sess_t *sess, ogs_diam_gy_message_t *gy_message,
|
||||||
ogs_pfcp_xact_t *pfcp_xact);
|
ogs_pfcp_xact_t *pfcp_xact);
|
||||||
uint32_t smf_gy_handle_cca_termination_request(
|
uint32_t smf_gy_handle_cca_termination_request(
|
||||||
|
|
|
@ -198,7 +198,7 @@ static void fill_qos_information(smf_sess_t *sess, struct avp *parent_avp)
|
||||||
union avp_value val;
|
union avp_value val;
|
||||||
struct avp *avpch1, *avpch2, *avpch3;
|
struct avp *avpch1, *avpch2, *avpch3;
|
||||||
|
|
||||||
ret = fd_msg_avp_new(ogs_diam_gx_qos_information, 0, &avpch1);
|
ret = fd_msg_avp_new(ogs_diam_gy_qos_information, 0, &avpch1);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
|
|
||||||
/* QoS-Class-Identifier */
|
/* QoS-Class-Identifier */
|
||||||
|
@ -325,41 +325,27 @@ static void fill_multiple_services_credit_control_ccr(smf_sess_t *sess,
|
||||||
/* QoS-Information */
|
/* QoS-Information */
|
||||||
fill_qos_information(sess, avp);
|
fill_qos_information(sess, avp);
|
||||||
|
|
||||||
/* 3GPP-RAT-Type, TS 29.061 16.4.7.2 21 */
|
|
||||||
/* GGSN: TS 29.060 7.7.50, PGW: TS 29.274 8.17 */
|
|
||||||
ret = fd_msg_avp_new(ogs_diam_gy_3gpp_rat_type, 0, &avpch1);
|
|
||||||
ogs_assert(ret == 0);
|
|
||||||
val.os.data = (uint8_t*)&sess->gtp_rat_type;
|
|
||||||
val.os.len = 1;
|
|
||||||
ret = fd_msg_avp_setvalue (avpch1, &val);
|
|
||||||
ogs_assert(ret == 0);
|
|
||||||
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
|
|
||||||
ogs_assert(ret == 0);
|
|
||||||
|
|
||||||
/* Multiple Services AVP add to req: */
|
/* Multiple Services AVP add to req: */
|
||||||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TS 32.299 7.2.192 Service-Information AVP for CCR */
|
/* TS 32.299 7.2.158 PS-Information AVP for CCR */
|
||||||
static void fill_service_information_ccr(smf_sess_t *sess,
|
static void fill_ps_information(smf_sess_t *sess, uint32_t cc_request_type,
|
||||||
uint32_t cc_request_type, struct msg *req)
|
struct avp *avp)
|
||||||
{
|
{
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
union avp_value val;
|
union avp_value val;
|
||||||
struct avp *avp;
|
|
||||||
struct avp *avpch1, *avpch2, *avpch3;
|
struct avp *avpch1, *avpch2, *avpch3;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
struct sockaddr_in6 sin6;
|
struct sockaddr_in6 sin6;
|
||||||
char buf[OGS_PLMNIDSTRLEN];
|
char buf[OGS_PLMNIDSTRLEN];
|
||||||
char digit;
|
char digit;
|
||||||
|
|
||||||
/* Service-Information, TS 32.299 sec 7.2.192 */
|
|
||||||
ret = fd_msg_avp_new(ogs_diam_gy_service_information, 0, &avp);
|
|
||||||
|
|
||||||
/* PS-Information, TS 32.299 sec 7.2.158 */
|
/* PS-Information, TS 32.299 sec 7.2.158 */
|
||||||
ret = fd_msg_avp_new(ogs_diam_gy_ps_information, 0, &avpch1);
|
ret = fd_msg_avp_new(ogs_diam_gy_ps_information, 0, &avpch1);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
|
||||||
/* 3GPP-Charging-Id, 3GPP TS 29.061 16.4.7.2 2 */
|
/* 3GPP-Charging-Id, 3GPP TS 29.061 16.4.7.2 2 */
|
||||||
ret = fd_msg_avp_new(ogs_diam_gy_3gpp_charging_id, 0, &avpch2);
|
ret = fd_msg_avp_new(ogs_diam_gy_3gpp_charging_id, 0, &avpch2);
|
||||||
|
@ -556,6 +542,17 @@ static void fill_service_information_ccr(smf_sess_t *sess,
|
||||||
/* 3GPP-User-Location-Info, 3GPP TS 29.061 16.4.7.2 22 */
|
/* 3GPP-User-Location-Info, 3GPP TS 29.061 16.4.7.2 22 */
|
||||||
smf_fd_msg_avp_add_3gpp_uli(sess, (struct msg *)avpch1);
|
smf_fd_msg_avp_add_3gpp_uli(sess, (struct msg *)avpch1);
|
||||||
|
|
||||||
|
/* 3GPP-RAT-Type, TS 29.061 16.4.7.2 21 */
|
||||||
|
/* GGSN: TS 29.060 7.7.50, PGW: TS 29.274 8.17 */
|
||||||
|
ret = fd_msg_avp_new(ogs_diam_gy_3gpp_rat_type, 0, &avpch2);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
val.os.data = (uint8_t*)&sess->gtp_rat_type;
|
||||||
|
val.os.len = 1;
|
||||||
|
ret = fd_msg_avp_setvalue(avpch2, &val);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
ret = fd_msg_avp_add(avpch1, MSG_BRW_LAST_CHILD, avpch2);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
|
||||||
if (sess->smf_ue->imeisv_len > 0) {
|
if (sess->smf_ue->imeisv_len > 0) {
|
||||||
/* User-Equipment-Info, 3GPP TS 32.299 7.1.17 */
|
/* User-Equipment-Info, 3GPP TS 32.299 7.1.17 */
|
||||||
ret = fd_msg_avp_new(ogs_diam_gy_user_equipment_info, 0, &avpch2);
|
ret = fd_msg_avp_new(ogs_diam_gy_user_equipment_info, 0, &avpch2);
|
||||||
|
@ -585,9 +582,25 @@ static void fill_service_information_ccr(smf_sess_t *sess,
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PS-Information AVP add to req: */
|
/* PS-Information AVP add to parent AVP (Service-Information): */
|
||||||
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
|
ret = fd_msg_avp_add (avp, MSG_BRW_LAST_CHILD, avpch1);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TS 32.299 7.2.192 Service-Information AVP for CCR */
|
||||||
|
static void fill_service_information_ccr(smf_sess_t *sess,
|
||||||
|
uint32_t cc_request_type, struct msg *req)
|
||||||
|
{
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
struct avp *avp;
|
||||||
|
|
||||||
|
/* Service-Information, TS 32.299 sec 7.2.192 */
|
||||||
|
ret = fd_msg_avp_new(ogs_diam_gy_service_information, 0, &avp);
|
||||||
|
ogs_assert(ret == 0);
|
||||||
|
|
||||||
|
/* PS-Information, TS 32.299 sec 7.2.158 */
|
||||||
|
fill_ps_information(sess, cc_request_type, avp);
|
||||||
|
|
||||||
/* Service-Information AVP add to req: */
|
/* Service-Information AVP add to req: */
|
||||||
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
ret = fd_msg_avp_add(req, MSG_BRW_LAST_CHILD, avp);
|
||||||
|
@ -612,7 +625,6 @@ void smf_gy_send_ccr(smf_sess_t *sess, void *xact,
|
||||||
const char *service_context_id = "32251@3gpp.org";
|
const char *service_context_id = "32251@3gpp.org";
|
||||||
uint32_t timestamp, req_slot;
|
uint32_t timestamp, req_slot;
|
||||||
|
|
||||||
ogs_assert(xact);
|
|
||||||
ogs_assert(sess);
|
ogs_assert(sess);
|
||||||
|
|
||||||
ogs_assert(sess->ipv4 || sess->ipv6);
|
ogs_assert(sess->ipv4 || sess->ipv6);
|
||||||
|
@ -1004,6 +1016,9 @@ static void smf_gy_cca_cb(void *data, struct msg **msg)
|
||||||
/* Set Credit Control Command */
|
/* Set Credit Control Command */
|
||||||
gy_message->cmd_code = OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL;
|
gy_message->cmd_code = OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL;
|
||||||
|
|
||||||
|
/* Initialize some values: */
|
||||||
|
gy_message->cca.result_code = ER_DIAMETER_SUCCESS;
|
||||||
|
|
||||||
/* Value of Result Code */
|
/* Value of Result Code */
|
||||||
ret = fd_msg_search_avp(*msg, ogs_diam_result_code, &avp);
|
ret = fd_msg_search_avp(*msg, ogs_diam_result_code, &avp);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
|
@ -1115,6 +1130,10 @@ static void smf_gy_cca_cb(void *data, struct msg **msg)
|
||||||
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
ret = fd_msg_avp_hdr(avpch1, &hdr);
|
||||||
ogs_assert(ret == 0);
|
ogs_assert(ret == 0);
|
||||||
switch (hdr->avp_code) {
|
switch (hdr->avp_code) {
|
||||||
|
case AC_RESULT_CODE:
|
||||||
|
gy_message->cca.result_code = hdr->avp_value->u32;
|
||||||
|
gy_message->cca.err = &gy_message->cca.result_code;
|
||||||
|
break;
|
||||||
case OGS_DIAM_GY_AVP_CODE_GRANTED_SERVICE_UNIT:
|
case OGS_DIAM_GY_AVP_CODE_GRANTED_SERVICE_UNIT:
|
||||||
rv = decode_granted_service_unit(
|
rv = decode_granted_service_unit(
|
||||||
&gy_message->cca.granted, avpch1, &error);
|
&gy_message->cca.granted, avpch1, &error);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -971,6 +971,7 @@ void smf_epc_n4_handle_session_modification_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.teid = sess->sgw_s5c_teid;
|
h.teid = sess->sgw_s5c_teid;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.type = OGS_GTP2_DELETE_BEARER_REQUEST_TYPE;
|
h.type = OGS_GTP2_DELETE_BEARER_REQUEST_TYPE;
|
||||||
|
|
||||||
pkbuf = smf_s5c_build_delete_bearer_request(
|
pkbuf = smf_s5c_build_delete_bearer_request(
|
||||||
|
@ -1182,7 +1183,8 @@ void smf_n4_handle_session_report_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_pfcp_send_error_message(pfcp_xact, 0,
|
ogs_pfcp_send_error_message(pfcp_xact,
|
||||||
|
OGS_PFCP_SEID_NO_PRESENCE, 0,
|
||||||
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
||||||
cause_value, 0);
|
cause_value, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -1222,7 +1224,8 @@ void smf_n4_handle_session_report_request(
|
||||||
if (paging_policy_indication_value) {
|
if (paging_policy_indication_value) {
|
||||||
ogs_warn("Not implement - "
|
ogs_warn("Not implement - "
|
||||||
"Paging Policy Indication Value");
|
"Paging Policy Indication Value");
|
||||||
ogs_pfcp_send_error_message(pfcp_xact, 0,
|
ogs_pfcp_send_error_message(pfcp_xact,
|
||||||
|
OGS_PFCP_SEID_NO_PRESENCE, 0,
|
||||||
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
||||||
OGS_PFCP_CAUSE_SERVICE_NOT_SUPPORTED, 0);
|
OGS_PFCP_CAUSE_SERVICE_NOT_SUPPORTED, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -1232,7 +1235,8 @@ void smf_n4_handle_session_report_request(
|
||||||
qos_flow = smf_qos_flow_find_by_qfi(sess, qfi);
|
qos_flow = smf_qos_flow_find_by_qfi(sess, qfi);
|
||||||
if (!qos_flow) {
|
if (!qos_flow) {
|
||||||
ogs_error("Cannot find the QoS Flow[%d]", qfi);
|
ogs_error("Cannot find the QoS Flow[%d]", qfi);
|
||||||
ogs_pfcp_send_error_message(pfcp_xact, 0,
|
ogs_pfcp_send_error_message(pfcp_xact,
|
||||||
|
OGS_PFCP_SEID_NO_PRESENCE, 0,
|
||||||
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
||||||
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -1257,7 +1261,8 @@ void smf_n4_handle_session_report_request(
|
||||||
|
|
||||||
if (!pdr) {
|
if (!pdr) {
|
||||||
ogs_error("No Context");
|
ogs_error("No Context");
|
||||||
ogs_pfcp_send_error_message(pfcp_xact, 0,
|
ogs_pfcp_send_error_message(pfcp_xact,
|
||||||
|
OGS_PFCP_SEID_NO_PRESENCE, 0,
|
||||||
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
||||||
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -222,8 +222,11 @@ static void sess_5gc_timeout(ogs_pfcp_xact_t *xact, void *data)
|
||||||
ogs_assert(xact);
|
ogs_assert(xact);
|
||||||
ogs_assert(data);
|
ogs_assert(data);
|
||||||
|
|
||||||
sess = data;
|
sess = smf_sess_cycle(data);
|
||||||
ogs_assert(sess);
|
if (!sess) {
|
||||||
|
ogs_warn("Session has already been removed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
smf_ue = sess->smf_ue;
|
smf_ue = sess->smf_ue;
|
||||||
ogs_assert(smf_ue);
|
ogs_assert(smf_ue);
|
||||||
|
|
||||||
|
@ -288,7 +291,21 @@ static void sess_5gc_timeout(ogs_pfcp_xact_t *xact, void *data)
|
||||||
|
|
||||||
ogs_free(strerror);
|
ogs_free(strerror);
|
||||||
|
|
||||||
smf_sess_remove(sess);
|
/* We mustn't remove sess here. Removing a session may delete PFCP xact
|
||||||
|
timers and we must not delete any timers from within a timer
|
||||||
|
callback. Instead, we shall emit a new event to trigger session
|
||||||
|
removal from pfcp-sm state machine. */
|
||||||
|
e = smf_event_new(SMF_EVT_N4_TIMER);
|
||||||
|
ogs_assert(e);
|
||||||
|
e->sess = sess;
|
||||||
|
e->h.timer_id = SMF_TIMER_PFCP_NO_DELETION_RESPONSE;
|
||||||
|
e->pfcp_node = sess->pfcp_node;
|
||||||
|
|
||||||
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
||||||
|
if (rv != OGS_OK) {
|
||||||
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
||||||
|
ogs_event_free(e);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ogs_error("Not implemented [type:%d]", type);
|
ogs_error("Not implemented [type:%d]", type);
|
||||||
|
@ -353,6 +370,7 @@ int smf_pfcp_send_modify_list(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->upf_n4_seid;
|
h.seid = sess->upf_n4_seid;
|
||||||
|
|
||||||
n4buf = (*modify_list)(h.type, sess, xact);
|
n4buf = (*modify_list)(h.type, sess, xact);
|
||||||
|
@ -430,6 +448,7 @@ int smf_5gc_pfcp_send_session_establishment_request(
|
||||||
* over N4 towards another SMF or another PFCP entity in the SMF
|
* over N4 towards another SMF or another PFCP entity in the SMF
|
||||||
* as specified in clause 5.22.2 and clause 5.22.3.
|
* as specified in clause 5.22.2 and clause 5.22.3.
|
||||||
*/
|
*/
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->upf_n4_seid;
|
h.seid = sess->upf_n4_seid;
|
||||||
|
|
||||||
n4buf = smf_n4_build_session_establishment_request(h.type, sess, xact);
|
n4buf = smf_n4_build_session_establishment_request(h.type, sess, xact);
|
||||||
|
@ -532,6 +551,7 @@ int smf_5gc_pfcp_send_session_deletion_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->upf_n4_seid;
|
h.seid = sess->upf_n4_seid;
|
||||||
|
|
||||||
n4buf = smf_n4_build_session_deletion_request(h.type, sess);
|
n4buf = smf_n4_build_session_deletion_request(h.type, sess);
|
||||||
|
@ -605,6 +625,7 @@ int smf_epc_pfcp_send_session_establishment_request(
|
||||||
* over N4 towards another SMF or another PFCP entity in the SMF
|
* over N4 towards another SMF or another PFCP entity in the SMF
|
||||||
* as specified in clause 5.22.2 and clause 5.22.3.
|
* as specified in clause 5.22.2 and clause 5.22.3.
|
||||||
*/
|
*/
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->upf_n4_seid;
|
h.seid = sess->upf_n4_seid;
|
||||||
|
|
||||||
n4buf = smf_n4_build_session_establishment_request(h.type, sess, xact);
|
n4buf = smf_n4_build_session_establishment_request(h.type, sess, xact);
|
||||||
|
@ -748,6 +769,7 @@ int smf_epc_pfcp_send_session_deletion_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->upf_n4_seid;
|
h.seid = sess->upf_n4_seid;
|
||||||
|
|
||||||
n4buf = smf_n4_build_session_deletion_request(h.type, sess);
|
n4buf = smf_n4_build_session_deletion_request(h.type, sess);
|
||||||
|
@ -846,6 +868,7 @@ int smf_pfcp_send_session_report_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE;
|
h.type = OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->upf_n4_seid;
|
h.seid = sess->upf_n4_seid;
|
||||||
|
|
||||||
sxabuf = ogs_pfcp_build_session_report_response(h.type, cause);
|
sxabuf = ogs_pfcp_build_session_report_response(h.type, cause);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -117,14 +117,21 @@ void smf_pfcp_state_will_associate(ogs_fsm_t *s, smf_event_t *e)
|
||||||
ogs_pfcp_cp_send_association_setup_request(node, node_timeout);
|
ogs_pfcp_cp_send_association_setup_request(node, node_timeout);
|
||||||
break;
|
break;
|
||||||
case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
|
case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
|
||||||
sess = e->sess;
|
sess = smf_sess_cycle(e->sess);
|
||||||
sess = smf_sess_cycle(sess);
|
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
ogs_warn("Session has already been removed");
|
ogs_warn("Session has already been removed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ogs_fsm_dispatch(&sess->sm, e);
|
ogs_fsm_dispatch(&sess->sm, e);
|
||||||
break;
|
break;
|
||||||
|
case SMF_TIMER_PFCP_NO_DELETION_RESPONSE:
|
||||||
|
sess = smf_sess_cycle(e->sess);
|
||||||
|
if (!sess) {
|
||||||
|
ogs_warn("Session has already been removed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SMF_SESS_CLEAR(sess);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ogs_error("Unknown timer[%s:%d]",
|
ogs_error("Unknown timer[%s:%d]",
|
||||||
smf_timer_get_name(e->h.timer_id), e->h.timer_id);
|
smf_timer_get_name(e->h.timer_id), e->h.timer_id);
|
||||||
|
@ -317,7 +324,8 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
|
||||||
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE,
|
OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE,
|
||||||
OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND);
|
OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND);
|
||||||
else
|
else
|
||||||
ogs_gtp2_send_error_message(gtp_xact, 0,
|
ogs_gtp2_send_error_message(gtp_xact,
|
||||||
|
OGS_GTP2_TEID_NO_PRESENCE, 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
||||||
break;
|
break;
|
||||||
|
@ -352,7 +360,8 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
|
||||||
OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE,
|
OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE,
|
||||||
OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND);
|
OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND);
|
||||||
else
|
else
|
||||||
ogs_gtp2_send_error_message(gtp_xact, 0,
|
ogs_gtp2_send_error_message(gtp_xact,
|
||||||
|
OGS_GTP2_TEID_NO_PRESENCE, 0,
|
||||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE,
|
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
||||||
break;
|
break;
|
||||||
|
@ -384,14 +393,21 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
|
||||||
ogs_pfcp_send_heartbeat_request(node, node_timeout));
|
ogs_pfcp_send_heartbeat_request(node, node_timeout));
|
||||||
break;
|
break;
|
||||||
case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
|
case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
|
||||||
sess = e->sess;
|
sess = smf_sess_cycle(e->sess);
|
||||||
sess = smf_sess_cycle(sess);
|
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
ogs_warn("Session has already been removed");
|
ogs_warn("Session has already been removed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ogs_fsm_dispatch(&sess->sm, e);
|
ogs_fsm_dispatch(&sess->sm, e);
|
||||||
break;
|
break;
|
||||||
|
case SMF_TIMER_PFCP_NO_DELETION_RESPONSE:
|
||||||
|
sess = smf_sess_cycle(e->sess);
|
||||||
|
if (!sess) {
|
||||||
|
ogs_warn("Session has already been removed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SMF_SESS_CLEAR(sess);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ogs_error("Unknown timer[%s:%d]",
|
ogs_error("Unknown timer[%s:%d]",
|
||||||
smf_timer_get_name(e->h.timer_id), e->h.timer_id);
|
smf_timer_get_name(e->h.timer_id), e->h.timer_id);
|
||||||
|
@ -399,12 +415,19 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SMF_EVT_N4_NO_HEARTBEAT:
|
case SMF_EVT_N4_NO_HEARTBEAT:
|
||||||
|
|
||||||
/* 'node' context was removed in ogs_pfcp_xact_delete(xact)
|
|
||||||
* So, we should not use PFCP node here */
|
|
||||||
|
|
||||||
ogs_warn("No Heartbeat from UPF [%s]:%d",
|
ogs_warn("No Heartbeat from UPF [%s]:%d",
|
||||||
OGS_ADDR(addr, buf), OGS_PORT(addr));
|
OGS_ADDR(addr, buf), OGS_PORT(addr));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reselect_upf() should not be executed on node_timeout
|
||||||
|
* because the timer cannot be deleted in the timer expiration function.
|
||||||
|
*
|
||||||
|
* Note that reselct_upf contains SMF_SESS_CLEAR.
|
||||||
|
*/
|
||||||
|
node = e->pfcp_node;
|
||||||
|
ogs_assert(node);
|
||||||
|
reselect_upf(node);
|
||||||
|
|
||||||
OGS_FSM_TRAN(s, smf_pfcp_state_will_associate);
|
OGS_FSM_TRAN(s, smf_pfcp_state_will_associate);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -548,7 +571,6 @@ static void node_timeout(ogs_pfcp_xact_t *xact, void *data)
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case OGS_PFCP_HEARTBEAT_REQUEST_TYPE:
|
case OGS_PFCP_HEARTBEAT_REQUEST_TYPE:
|
||||||
ogs_assert(data);
|
ogs_assert(data);
|
||||||
reselect_upf(data);
|
|
||||||
|
|
||||||
e = smf_event_new(SMF_EVT_N4_NO_HEARTBEAT);
|
e = smf_event_new(SMF_EVT_N4_NO_HEARTBEAT);
|
||||||
e->pfcp_node = data;
|
e->pfcp_node = data;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -504,7 +504,9 @@ void smf_s5c_handle_modify_bearer_request(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp2_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(gtp_xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->sgw_s5c_teid : 0,
|
||||||
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1186,7 +1188,9 @@ void smf_s5c_handle_bearer_resource_command(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp2_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->sgw_s5c_teid : 0,
|
||||||
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1211,7 +1215,9 @@ void smf_s5c_handle_bearer_resource_command(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
||||||
ogs_gtp2_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->sgw_s5c_teid : 0,
|
||||||
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1240,8 +1246,10 @@ void smf_s5c_handle_bearer_resource_command(
|
||||||
pf = smf_pf_find_by_id(bearer, tft.pf[i].identifier+1);
|
pf = smf_pf_find_by_id(bearer, tft.pf[i].identifier+1);
|
||||||
if (pf) {
|
if (pf) {
|
||||||
if (reconfigure_packet_filter(pf, &tft, i) < 0) {
|
if (reconfigure_packet_filter(pf, &tft, i) < 0) {
|
||||||
ogs_gtp2_send_error_message(
|
ogs_gtp2_send_error_message(xact,
|
||||||
xact, sess ? sess->sgw_s5c_teid : 0,
|
sess ? OGS_GTP2_TEID_PRESENCE :
|
||||||
|
OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->sgw_s5c_teid : 0,
|
||||||
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE,
|
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE,
|
||||||
OGS_GTP2_CAUSE_SEMANTIC_ERRORS_IN_PACKET_FILTER);
|
OGS_GTP2_CAUSE_SEMANTIC_ERRORS_IN_PACKET_FILTER);
|
||||||
return;
|
return;
|
||||||
|
@ -1309,8 +1317,9 @@ void smf_s5c_handle_bearer_resource_command(
|
||||||
ogs_assert(pf);
|
ogs_assert(pf);
|
||||||
|
|
||||||
if (reconfigure_packet_filter(pf, &tft, i) < 0) {
|
if (reconfigure_packet_filter(pf, &tft, i) < 0) {
|
||||||
ogs_gtp2_send_error_message(
|
ogs_gtp2_send_error_message(xact,
|
||||||
xact, sess ? sess->sgw_s5c_teid : 0,
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->sgw_s5c_teid : 0,
|
||||||
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE,
|
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE,
|
||||||
OGS_GTP2_CAUSE_SEMANTIC_ERRORS_IN_PACKET_FILTER);
|
OGS_GTP2_CAUSE_SEMANTIC_ERRORS_IN_PACKET_FILTER);
|
||||||
return;
|
return;
|
||||||
|
@ -1396,7 +1405,9 @@ void smf_s5c_handle_bearer_resource_command(
|
||||||
|
|
||||||
if (tft_update == 0 && tft_delete == 0 && qos_update == 0) {
|
if (tft_update == 0 && tft_delete == 0 && qos_update == 0) {
|
||||||
/* No modification */
|
/* No modification */
|
||||||
ogs_gtp2_send_error_message(xact, sess ? sess->sgw_s5c_teid : 0,
|
ogs_gtp2_send_error_message(xact,
|
||||||
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
||||||
|
sess ? sess->sgw_s5c_teid : 0,
|
||||||
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE,
|
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE,
|
||||||
OGS_GTP2_CAUSE_SERVICE_NOT_SUPPORTED);
|
OGS_GTP2_CAUSE_SERVICE_NOT_SUPPORTED);
|
||||||
return;
|
return;
|
||||||
|
@ -1422,6 +1433,7 @@ void smf_s5c_handle_bearer_resource_command(
|
||||||
} else {
|
} else {
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.teid = sess->sgw_s5c_teid;
|
h.teid = sess->sgw_s5c_teid;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.type = OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE;
|
h.type = OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE;
|
||||||
|
|
||||||
pkbuf = smf_s5c_build_update_bearer_request(
|
pkbuf = smf_s5c_build_update_bearer_request(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -144,7 +144,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
||||||
}
|
}
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
ogs_error("No Session");
|
ogs_error("No Session");
|
||||||
ogs_gtp2_send_error_message(gtp_xact, 0,
|
ogs_gtp2_send_error_message(gtp_xact,
|
||||||
|
OGS_GTP2_TEID_NO_PRESENCE, 0,
|
||||||
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
||||||
break;
|
break;
|
||||||
|
@ -158,7 +159,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
||||||
smf_metrics_inst_gtp_node_inc(smf_gnode->metrics, SMF_METR_GTP_NODE_CTR_S5C_RX_DELETESESSIONREQ);
|
smf_metrics_inst_gtp_node_inc(smf_gnode->metrics, SMF_METR_GTP_NODE_CTR_S5C_RX_DELETESESSIONREQ);
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
ogs_error("No Session");
|
ogs_error("No Session");
|
||||||
ogs_gtp2_send_error_message(gtp_xact, 0,
|
ogs_gtp2_send_error_message(gtp_xact,
|
||||||
|
OGS_GTP2_TEID_NO_PRESENCE, 0,
|
||||||
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE,
|
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE,
|
||||||
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
||||||
break;
|
break;
|
||||||
|
@ -328,23 +330,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
||||||
|
|
||||||
switch(gy_message->cmd_code) {
|
switch(gy_message->cmd_code) {
|
||||||
case OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL:
|
case OGS_DIAM_GY_CMD_CODE_CREDIT_CONTROL:
|
||||||
switch(gy_message->cc_request_type) {
|
ogs_fsm_dispatch(&sess->sm, e);
|
||||||
case OGS_DIAM_GY_CC_REQUEST_TYPE_INITIAL_REQUEST:
|
|
||||||
ogs_fsm_dispatch(&sess->sm, e);
|
|
||||||
break;
|
|
||||||
case OGS_DIAM_GY_CC_REQUEST_TYPE_UPDATE_REQUEST:
|
|
||||||
ogs_assert(e->pfcp_xact);
|
|
||||||
smf_gy_handle_cca_update_request(
|
|
||||||
sess, gy_message, e->pfcp_xact);
|
|
||||||
break;
|
|
||||||
case OGS_DIAM_GY_CC_REQUEST_TYPE_TERMINATION_REQUEST:
|
|
||||||
ogs_fsm_dispatch(&sess->sm, e);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ogs_error("Not implemented(%d)", gy_message->cc_request_type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case OGS_DIAM_GY_CMD_RE_AUTH:
|
case OGS_DIAM_GY_CMD_RE_AUTH:
|
||||||
smf_gy_handle_re_auth_request(sess, gy_message);
|
smf_gy_handle_re_auth_request(sess, gy_message);
|
||||||
|
|
|
@ -42,6 +42,8 @@ const char *smf_timer_get_name(int timer_id)
|
||||||
return "SMF_TIMER_PFCP_NO_HEARTBEAT";
|
return "SMF_TIMER_PFCP_NO_HEARTBEAT";
|
||||||
case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
|
case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
|
||||||
return "SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE";
|
return "SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE";
|
||||||
|
case SMF_TIMER_PFCP_NO_DELETION_RESPONSE:
|
||||||
|
return "SMF_TIMER_PFCP_NO_DELETION_RESPONSE";
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ typedef enum {
|
||||||
SMF_TIMER_PFCP_ASSOCIATION,
|
SMF_TIMER_PFCP_ASSOCIATION,
|
||||||
SMF_TIMER_PFCP_NO_HEARTBEAT,
|
SMF_TIMER_PFCP_NO_HEARTBEAT,
|
||||||
SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE,
|
SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE,
|
||||||
|
SMF_TIMER_PFCP_NO_DELETION_RESPONSE,
|
||||||
|
|
||||||
MAX_NUM_OF_SMF_TIMER,
|
MAX_NUM_OF_SMF_TIMER,
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -69,7 +69,8 @@ void upf_n4_handle_session_establishment_request(
|
||||||
|
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
ogs_error("No Context");
|
ogs_error("No Context");
|
||||||
ogs_pfcp_send_error_message(xact, 0,
|
ogs_pfcp_send_error_message(xact,
|
||||||
|
OGS_PFCP_SEID_NO_PRESENCE, 0,
|
||||||
OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE,
|
||||||
OGS_PFCP_CAUSE_MANDATORY_IE_MISSING, 0);
|
OGS_PFCP_CAUSE_MANDATORY_IE_MISSING, 0);
|
||||||
upf_metrics_inst_by_cause_add(OGS_PFCP_CAUSE_MANDATORY_IE_MISSING,
|
upf_metrics_inst_by_cause_add(OGS_PFCP_CAUSE_MANDATORY_IE_MISSING,
|
||||||
|
@ -214,7 +215,9 @@ cleanup:
|
||||||
upf_metrics_inst_by_cause_add(cause_value,
|
upf_metrics_inst_by_cause_add(cause_value,
|
||||||
UPF_METR_CTR_SM_N4SESSIONESTABFAIL, 1);
|
UPF_METR_CTR_SM_N4SESSIONESTABFAIL, 1);
|
||||||
ogs_pfcp_sess_clear(&sess->pfcp);
|
ogs_pfcp_sess_clear(&sess->pfcp);
|
||||||
ogs_pfcp_send_error_message(xact, sess ? sess->smf_n4_f_seid.seid : 0,
|
ogs_pfcp_send_error_message(xact,
|
||||||
|
sess ? OGS_PFCP_SEID_PRESENCE : OGS_PFCP_SEID_NO_PRESENCE,
|
||||||
|
sess ? sess->smf_n4_f_seid.seid : 0,
|
||||||
OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE,
|
||||||
cause_value, offending_ie_value);
|
cause_value, offending_ie_value);
|
||||||
}
|
}
|
||||||
|
@ -240,7 +243,8 @@ void upf_n4_handle_session_modification_request(
|
||||||
|
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
ogs_error("No Context");
|
ogs_error("No Context");
|
||||||
ogs_pfcp_send_error_message(xact, 0,
|
ogs_pfcp_send_error_message(xact,
|
||||||
|
OGS_PFCP_SEID_NO_PRESENCE, 0,
|
||||||
OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE,
|
||||||
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
||||||
return;
|
return;
|
||||||
|
@ -413,7 +417,9 @@ void upf_n4_handle_session_modification_request(
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
ogs_pfcp_sess_clear(&sess->pfcp);
|
ogs_pfcp_sess_clear(&sess->pfcp);
|
||||||
ogs_pfcp_send_error_message(xact, sess ? sess->smf_n4_f_seid.seid : 0,
|
ogs_pfcp_send_error_message(xact,
|
||||||
|
sess ? OGS_PFCP_SEID_PRESENCE : OGS_PFCP_SEID_NO_PRESENCE,
|
||||||
|
sess ? sess->smf_n4_f_seid.seid : 0,
|
||||||
OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE,
|
||||||
cause_value, offending_ie_value);
|
cause_value, offending_ie_value);
|
||||||
}
|
}
|
||||||
|
@ -431,7 +437,8 @@ void upf_n4_handle_session_deletion_request(
|
||||||
|
|
||||||
if (!sess) {
|
if (!sess) {
|
||||||
ogs_error("No Context");
|
ogs_error("No Context");
|
||||||
ogs_pfcp_send_error_message(xact, 0,
|
ogs_pfcp_send_error_message(xact,
|
||||||
|
OGS_PFCP_SEID_NO_PRESENCE, 0,
|
||||||
OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE,
|
OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE,
|
||||||
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -183,6 +183,7 @@ int upf_pfcp_send_session_establishment_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE;
|
h.type = OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->smf_n4_f_seid.seid;
|
h.seid = sess->smf_n4_f_seid.seid;
|
||||||
|
|
||||||
n4buf = upf_n4_build_session_establishment_response(
|
n4buf = upf_n4_build_session_establishment_response(
|
||||||
|
@ -216,6 +217,7 @@ int upf_pfcp_send_session_modification_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE;
|
h.type = OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->smf_n4_f_seid.seid;
|
h.seid = sess->smf_n4_f_seid.seid;
|
||||||
|
|
||||||
n4buf = upf_n4_build_session_modification_response(
|
n4buf = upf_n4_build_session_modification_response(
|
||||||
|
@ -248,6 +250,7 @@ int upf_pfcp_send_session_deletion_response(ogs_pfcp_xact_t *xact,
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE;
|
h.type = OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->smf_n4_f_seid.seid;
|
h.seid = sess->smf_n4_f_seid.seid;
|
||||||
|
|
||||||
n4buf = upf_n4_build_session_deletion_response(h.type, sess);
|
n4buf = upf_n4_build_session_deletion_response(h.type, sess);
|
||||||
|
@ -300,6 +303,7 @@ int upf_pfcp_send_session_report_request(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||||
h.type = OGS_PFCP_SESSION_REPORT_REQUEST_TYPE;
|
h.type = OGS_PFCP_SESSION_REPORT_REQUEST_TYPE;
|
||||||
|
h.seid_presence = OGS_PFCP_SEID_PRESENCE;
|
||||||
h.seid = sess->smf_n4_f_seid.seid;
|
h.seid = sess->smf_n4_f_seid.seid;
|
||||||
|
|
||||||
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess);
|
xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess);
|
||||||
|
|
|
@ -322,10 +322,6 @@ void upf_pfcp_state_associated(ogs_fsm_t *s, upf_event_t *e)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case UPF_EVT_N4_NO_HEARTBEAT:
|
case UPF_EVT_N4_NO_HEARTBEAT:
|
||||||
|
|
||||||
/* 'node' context was removed in ogs_pfcp_xact_delete(xact)
|
|
||||||
* So, we should not use PFCP node here */
|
|
||||||
|
|
||||||
ogs_warn("No Heartbeat from SMF [%s]:%d",
|
ogs_warn("No Heartbeat from SMF [%s]:%d",
|
||||||
OGS_ADDR(addr, buf), OGS_PORT(addr));
|
OGS_ADDR(addr, buf), OGS_PORT(addr));
|
||||||
OGS_FSM_TRAN(s, upf_pfcp_state_will_associate);
|
OGS_FSM_TRAN(s, upf_pfcp_state_will_associate);
|
||||||
|
|
|
@ -470,11 +470,84 @@ static void test2_func(abts_case *tc, void *data)
|
||||||
rv = testvlr_sgsap_send(sgsap, sendbuf);
|
rv = testvlr_sgsap_send(sgsap, sendbuf);
|
||||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||||
|
|
||||||
/* Receive Attach Reject */
|
/* Receive Initial Context Setup Request +
|
||||||
|
* Attach Accept +
|
||||||
|
* Activate Default Bearer Context Request */
|
||||||
recvbuf = testenb_s1ap_read(s1ap);
|
recvbuf = testenb_s1ap_read(s1ap);
|
||||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||||
tests1ap_recv(test_ue, recvbuf);
|
tests1ap_recv(test_ue, recvbuf);
|
||||||
|
|
||||||
|
/* Send Initial Context Setup Response */
|
||||||
|
sendbuf = test_s1ap_build_initial_context_setup_response(test_ue);
|
||||||
|
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||||
|
rv = testenb_s1ap_send(s1ap, sendbuf);
|
||||||
|
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||||
|
|
||||||
|
/* Send Attach Complete + Activate default EPS bearer cotext accept */
|
||||||
|
test_ue->nr_cgi.cell_id = 0x1234502;
|
||||||
|
bearer = test_bearer_find_by_ue_ebi(test_ue, 5);
|
||||||
|
ogs_assert(bearer);
|
||||||
|
esmbuf = testesm_build_activate_default_eps_bearer_context_accept(
|
||||||
|
bearer, false);
|
||||||
|
ABTS_PTR_NOTNULL(tc, esmbuf);
|
||||||
|
emmbuf = testemm_build_attach_complete(test_ue, esmbuf);
|
||||||
|
ABTS_PTR_NOTNULL(tc, emmbuf);
|
||||||
|
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
|
||||||
|
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||||
|
rv = testenb_s1ap_send(s1ap, sendbuf);
|
||||||
|
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||||
|
|
||||||
|
/* Receive EMM information */
|
||||||
|
recvbuf = testenb_s1ap_read(s1ap);
|
||||||
|
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||||
|
tests1ap_recv(test_ue, recvbuf);
|
||||||
|
|
||||||
|
/* Send UE Context Release Request */
|
||||||
|
sendbuf = test_s1ap_build_ue_context_release_request(test_ue,
|
||||||
|
S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_user_inactivity);
|
||||||
|
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||||
|
rv = testenb_s1ap_send(s1ap, sendbuf);
|
||||||
|
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||||
|
|
||||||
|
/* Receive UE Context Release Command */
|
||||||
|
recvbuf = testenb_s1ap_read(s1ap);
|
||||||
|
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||||
|
tests1ap_recv(test_ue, recvbuf);
|
||||||
|
|
||||||
|
/* Send UE Context Release Complete */
|
||||||
|
sendbuf = test_s1ap_build_ue_context_release_complete(test_ue);
|
||||||
|
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||||
|
rv = testenb_s1ap_send(s1ap, sendbuf);
|
||||||
|
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||||
|
|
||||||
|
/* Send Service Request */
|
||||||
|
emmbuf = testemm_build_service_request(test_ue);
|
||||||
|
ABTS_PTR_NOTNULL(tc, emmbuf);
|
||||||
|
sendbuf = test_s1ap_build_initial_ue_message(
|
||||||
|
test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Data, true);
|
||||||
|
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||||
|
rv = testenb_s1ap_send(s1ap, sendbuf);
|
||||||
|
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||||
|
|
||||||
|
/* Receive Initial Context Setup Request */
|
||||||
|
recvbuf = testenb_s1ap_read(s1ap);
|
||||||
|
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||||
|
tests1ap_recv(test_ue, recvbuf);
|
||||||
|
|
||||||
|
/* Send Initial Context Setup Response */
|
||||||
|
sendbuf = test_s1ap_build_initial_context_setup_response(test_ue);
|
||||||
|
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||||
|
rv = testenb_s1ap_send(s1ap, sendbuf);
|
||||||
|
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||||
|
|
||||||
|
/* Send Detach Request */
|
||||||
|
emmbuf = testemm_build_detach_request(test_ue, 1, true, true);
|
||||||
|
ABTS_PTR_NOTNULL(tc, emmbuf);
|
||||||
|
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
|
||||||
|
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||||
|
rv = testenb_s1ap_send(s1ap, sendbuf);
|
||||||
|
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||||
|
|
||||||
/* Receive UE Context Release Command */
|
/* Receive UE Context Release Command */
|
||||||
recvbuf = testenb_s1ap_read(s1ap);
|
recvbuf = testenb_s1ap_read(s1ap);
|
||||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
|
@ -135,6 +135,7 @@ int test_s2b_send_create_session_request(test_sess_t *sess, bool handover_ind)
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_CREATE_SESSION_REQUEST_TYPE;
|
h.type = OGS_GTP2_CREATE_SESSION_REQUEST_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sess->smf_s2b_c_teid;
|
h.teid = sess->smf_s2b_c_teid;
|
||||||
|
|
||||||
pkbuf = test_s2b_build_create_session_request(h.type, sess, handover_ind);
|
pkbuf = test_s2b_build_create_session_request(h.type, sess, handover_ind);
|
||||||
|
@ -166,6 +167,7 @@ int test_s2b_send_delete_session_request(test_sess_t *sess)
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_DELETE_SESSION_REQUEST_TYPE;
|
h.type = OGS_GTP2_DELETE_SESSION_REQUEST_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sess->smf_s2b_c_teid;
|
h.teid = sess->smf_s2b_c_teid;
|
||||||
|
|
||||||
pkbuf = test_s2b_build_delete_session_request(h.type, sess);
|
pkbuf = test_s2b_build_delete_session_request(h.type, sess);
|
||||||
|
@ -201,6 +203,7 @@ int test_s2b_send_create_bearer_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE;
|
h.type = OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sess->smf_s2b_c_teid;
|
h.teid = sess->smf_s2b_c_teid;
|
||||||
|
|
||||||
pkbuf = test_s2b_build_create_bearer_response(h.type, bearer);
|
pkbuf = test_s2b_build_create_bearer_response(h.type, bearer);
|
||||||
|
@ -236,6 +239,7 @@ int test_s2b_send_delete_bearer_response(
|
||||||
|
|
||||||
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
||||||
h.type = OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE;
|
h.type = OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE;
|
||||||
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
||||||
h.teid = sess->smf_s2b_c_teid;
|
h.teid = sess->smf_s2b_c_teid;
|
||||||
|
|
||||||
pkbuf = test_s2b_build_delete_bearer_response(h.type, bearer);
|
pkbuf = test_s2b_build_delete_bearer_response(h.type, bearer);
|
||||||
|
|
Loading…
Reference in New Issue