5gc: Paging was added

This commit is contained in:
Sukchan Lee 2021-01-18 11:48:35 -05:00
parent 408c378b94
commit c9363b1320
69 changed files with 6394 additions and 934 deletions

6
debian/changelog vendored
View File

@ -1,3 +1,9 @@
open5gs (2.1.4) unstable; urgency=medium
* Paging added
-- Sukchan Lee <acetcom@gmail.com> Mon, 18 Jan 2021 15:53:28 +0000
open5gs (2.1.3) unstable; urgency=medium
* Bug Fixed

View File

@ -365,7 +365,8 @@ typedef struct ogs_pcc_rule_s {
ogs_assert((__dST)->id); \
} \
for (__iNDEX = 0; __iNDEX < (__sRC)->num_of_flow; __iNDEX++) { \
(__dST)->flow[__iNDEX].direction = (__sRC)->flow[__iNDEX].direction; \
(__dST)->flow[__iNDEX].direction = \
(__sRC)->flow[__iNDEX].direction; \
(__dST)->flow[__iNDEX].description = \
ogs_strdup((__sRC)->flow[__iNDEX].description); \
ogs_assert((__dST)->flow[__iNDEX].description); \

View File

@ -133,6 +133,9 @@ void ogs_sbi_message_free(ogs_sbi_message_t *message)
if (message->N1N2MessageTransferRspData)
OpenAPI_n1_n2_message_transfer_rsp_data_free(
message->N1N2MessageTransferRspData);
if (message->N1N2MsgTxfrFailureNotification)
OpenAPI_n1_n2_msg_txfr_failure_notification_free(
message->N1N2MsgTxfrFailureNotification);
if (message->SmContextStatusNotification)
OpenAPI_sm_context_status_notification_free(
message->SmContextStatusNotification);
@ -712,6 +715,10 @@ static char *build_json(ogs_sbi_message_t *message)
item = OpenAPI_n1_n2_message_transfer_rsp_data_convertToJSON(
message->N1N2MessageTransferRspData);
ogs_assert(item);
} else if (message->N1N2MsgTxfrFailureNotification) {
item = OpenAPI_n1_n2_msg_txfr_failure_notification_convertToJSON(
message->N1N2MsgTxfrFailureNotification);
ogs_assert(item);
} else if (message->SmContextStatusNotification) {
item = OpenAPI_sm_context_status_notification_convertToJSON(
message->SmContextStatusNotification);
@ -1381,6 +1388,25 @@ static int parse_json(ogs_sbi_message_t *message,
END
break;
CASE(OGS_SBI_SERVICE_NAME_NSMF_CALLBACK)
SWITCH(message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_N1_N2_FAILURE_NOTIFY)
message->N1N2MsgTxfrFailureNotification =
OpenAPI_n1_n2_msg_txfr_failure_notification_parseFromJSON(
item);
if (!message->N1N2MsgTxfrFailureNotification) {
rv = OGS_ERROR;
ogs_error("JSON parse error");
}
break;
DEFAULT
rv = OGS_ERROR;
ogs_error("Unknown resource name [%s]",
message->h.resource.component[1]);
END
break;
DEFAULT
rv = OGS_ERROR;
ogs_error("Not implemented API name [%s]",

View File

@ -125,6 +125,7 @@ extern "C" {
#define OGS_SBI_SERVICE_NAME_NSMF_CALLBACK "nsmf-callback"
#define OGS_SBI_RESOURCE_NAME_SM_POLICY_NOTIFY "sm-policy-notify"
#define OGS_SBI_RESOURCE_NAME_N1_N2_FAILURE_NOTIFY "n1-n2-failure-notify"
#define OGS_SBI_SERVICE_NAME_NAMF_COMM "namf-comm"
#define OGS_SBI_RESOURCE_NAME_UE_CONTEXTS "ue-contexts"
@ -321,6 +322,8 @@ typedef struct ogs_sbi_message_s {
SessionManagementSubscriptionData;
OpenAPI_n1_n2_message_transfer_req_data_t *N1N2MessageTransferReqData;
OpenAPI_n1_n2_message_transfer_rsp_data_t *N1N2MessageTransferRspData;
OpenAPI_n1_n2_msg_txfr_failure_notification_t
*N1N2MsgTxfrFailureNotification;
OpenAPI_sm_context_status_notification_t *SmContextStatusNotification;
OpenAPI_policy_association_request_t *PolicyAssociationRequest;
OpenAPI_policy_association_t *PolicyAssociation;

View File

@ -58,6 +58,7 @@
#include "model/session_management_subscription_data.h"
#include "model/n1_n2_message_transfer_req_data.h"
#include "model/n1_n2_message_transfer_rsp_data.h"
#include "model/n1_n2_msg_txfr_failure_notification.h"
#include "model/sm_context_status_notification.h"
#include "model/policy_association.h"
#include "model/am_policy_data.h"

View File

@ -16,7 +16,7 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
project('open5gs', 'c',
version : '2.1.3',
version : '2.1.4',
license : 'AGPL-3.0-or-later',
meson_version : '>= 0.43.0',
default_options : [
@ -24,7 +24,7 @@ project('open5gs', 'c',
],
)
libogslib_version = '2.1.3'
libogslib_version = '2.1.4'
prefix = get_option('prefix')
bindir = join_paths(prefix, get_option('bindir'))

View File

@ -64,7 +64,7 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_sbi_object_t *sbi_object = NULL;
ogs_sbi_xact_t *sbi_xact = NULL;
int state = AMF_UPDATE_SM_CONTEXT_NO_STATE;
int state = AMF_SESS_SM_CONTEXT_NO_STATE;
ogs_sbi_stream_t *stream = NULL;
ogs_sbi_request_t *sbi_request = NULL;

View File

@ -1179,6 +1179,12 @@ void amf_ue_remove(amf_ue_t *amf_ue)
/* Clear Transparent Container */
OGS_ASN_CLEAR_DATA(&amf_ue->container);
/* Clear Paging Info */
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
/* Clear N2 Transfer */
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, pdu_session_resource_setup_request);
/* Delete All Timers */
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
ogs_timer_delete(amf_ue->t3513.timer);
@ -1517,6 +1523,21 @@ void amf_sess_remove(amf_sess_t *sess)
if (sess->pdu_session_establishment_accept)
ogs_pkbuf_free(sess->pdu_session_establishment_accept);
if (sess->transfer.pdu_session_resource_setup_request)
ogs_pkbuf_free(sess->transfer.pdu_session_resource_setup_request);
sess->transfer.pdu_session_resource_setup_request = NULL;
if (sess->transfer.path_switch_request_ack)
ogs_pkbuf_free(sess->transfer.path_switch_request_ack);
sess->transfer.path_switch_request_ack = NULL;
if (sess->transfer.pdu_session_resource_release_command)
ogs_pkbuf_free(sess->transfer.pdu_session_resource_release_command);
sess->transfer.pdu_session_resource_release_command = NULL;
if (sess->paging.client)
ogs_sbi_client_remove(sess->paging.client);
OGS_NAS_CLEAR_DATA(&sess->ue_pco);
OGS_TLV_CLEAR_DATA(&sess->pgw_pco);
@ -1568,7 +1589,24 @@ int amf_sess_xact_count(amf_ue_t *amf_ue)
return xact_count;
}
bool amf_sess_transfer_needed(amf_ue_t *amf_ue)
int amf_sess_xact_state_count(amf_ue_t *amf_ue, int state)
{
amf_sess_t *sess = NULL;
ogs_sbi_xact_t *xact = NULL;
int xact_count = 0;
ogs_assert(amf_ue);
ogs_assert(state);
ogs_list_for_each(&amf_ue->sess_list, sess) {
ogs_list_for_each(&sess->sbi.xact_list, xact)
if (xact->state == state) xact_count++;
}
return xact_count;
}
bool amf_pdu_res_setup_req_transfer_needed(amf_ue_t *amf_ue)
{
amf_sess_t *sess = NULL;

View File

@ -262,6 +262,7 @@ struct amf_ue_s {
/* UE Info */
ogs_guami_t *guami;
uint16_t gnb_ostream_id;
ogs_5gs_tai_t tai;
ogs_nr_cgi_t nr_cgi;
ogs_time_t ue_location_timestamp;
@ -447,7 +448,71 @@ typedef struct amf_sess_s {
struct {
ogs_pkbuf_t *pdu_session_resource_setup_request;
ogs_pkbuf_t *path_switch_request_ack;
ogs_pkbuf_t *pdu_session_resource_release_command;
} transfer;
#define AMF_SESS_STORE_N2_TRANSFER(__sESS, __n2Type, __n2Buf) \
do { \
ogs_assert(__sESS); \
ogs_assert((__sESS)->amf_ue); \
if (sess->transfer.__n2Type) { \
ogs_warn("[%s:%d] N2 transfer message duplicated. Overwritten", \
((__sESS)->amf_ue)->supi, sess->psi); \
ogs_pkbuf_free(sess->transfer.__n2Type); \
} \
sess->transfer.__n2Type = __n2Buf; \
ogs_assert(sess->transfer.__n2Type); \
} while(0);
#define AMF_UE_CLEAR_N2_TRANSFER(__aMF, __n2Type) \
do { \
amf_sess_t *sess = NULL; \
ogs_list_for_each(&((__aMF)->sess_list), sess) { \
if (sess->transfer.__n2Type) { \
ogs_pkbuf_free(sess->transfer.__n2Type); \
sess->transfer.__n2Type = NULL; \
} \
} \
} while(0);
struct {
/* Paging Ongoing */
bool ongoing;
/* Location in N1N2MessageTransferRspData */
char *location;
/* last Received n1-n2-trasfer-failure-notification-uri from SMF */
char *n1n2_failure_txf_notif_uri;
/* notification client */
ogs_sbi_client_t *client;
} paging;
#define AMF_SESS_STORE_PAGING_INFO(__sESS, __lOCATION, __uRI) \
do { \
ogs_assert(__sESS); \
ogs_assert(__lOCATION); \
ogs_assert(__uRI); \
AMF_SESS_CLEAR_PAGING_INFO(__sESS) \
(__sESS)->paging.ongoing = true; \
((__sESS)->paging.location) = ogs_strdup(__lOCATION); \
((__sESS)->paging.n1n2_failure_txf_notif_uri) = ogs_strdup(__uRI); \
} while(0);
#define AMF_SESS_CLEAR_PAGING_INFO(__sESS) \
do { \
if ((__sESS)->paging.ongoing == true) { \
ogs_assert((__sESS)->paging.location); \
ogs_free((__sESS)->paging.location); \
((__sESS)->paging.location) = NULL; \
ogs_assert((__sESS)->paging.n1n2_failure_txf_notif_uri); \
ogs_free((__sESS)->paging.n1n2_failure_txf_notif_uri); \
((__sESS)->paging.n1n2_failure_txf_notif_uri) = NULL; \
((__sESS)->paging.ongoing) = false; \
} \
} while(0);
#define AMF_UE_CLEAR_PAGING_INFO(__aMF) \
do { \
amf_sess_t *sess = NULL; \
ogs_list_for_each(&((__aMF)->sess_list), sess) { \
AMF_SESS_CLEAR_PAGING_INFO(sess); \
} \
} while(0);
/* last payload for sending back to the UE */
uint8_t payload_container_type;
@ -470,6 +535,7 @@ typedef struct amf_sess_s {
/* Save Protocol Configuration Options from PGW */
ogs_tlv_octet_t pgw_pco;
} amf_sess_t;
void amf_context_init(void);
@ -577,11 +643,14 @@ amf_sess_t *amf_sess_find_by_dnn(amf_ue_t *amf_ue, char *dnn);
amf_ue_t *amf_ue_cycle(amf_ue_t *amf_ue);
amf_sess_t *amf_sess_cycle(amf_sess_t *sess);
#define SESSION_SYNC_DONE(__aMF) (amf_sess_xact_count(__aMF) == 0)
#define SESSION_SYNC_DONE(__aMF, __sTATE) \
(amf_sess_xact_state_count(__aMF, __sTATE) == 0)
int amf_sess_xact_count(amf_ue_t *amf_ue);
int amf_sess_xact_state_count(amf_ue_t *amf_ue, int state);
#define SESSION_TRANSFER_NEEDED(__aMF) (amf_sess_transfer_needed(__aMF) == true)
bool amf_sess_transfer_needed(amf_ue_t *amf_ue);
#define PDU_RES_SETUP_REQ_TRANSFER_NEEDED(__aMF) \
(amf_pdu_res_setup_req_transfer_needed(__aMF) == true)
bool amf_pdu_res_setup_req_transfer_needed(amf_ue_t *amf_ue);
int amf_find_served_tai(ogs_5gs_tai_t *tai);
ogs_s_nssai_t *amf_find_s_nssai(

View File

@ -102,8 +102,11 @@ int gmm_handle_registration_request(amf_ue_t *amf_ue,
/*
* REGISTRATION_REQUEST
* SERVICE_REQUEST
* Clear N2 Transfer
* Clear Timer and Message
*/
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, pdu_session_resource_setup_request);
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
if (SECURITY_CONTEXT_IS_VALID(amf_ue)) {
@ -126,7 +129,8 @@ int gmm_handle_registration_request(amf_ue_t *amf_ue,
ogs_plmn_id_hexdump(&ran_ue->saved.nr_cgi.plmn_id),
(long long)ran_ue->saved.nr_cgi.cell_id);
/* Copy TAI and ECGI from ran_ue */
/* Copy Stream-No/TAI/ECGI from enb_ue */
amf_ue->gnb_ostream_id = ran_ue->gnb_ostream_id;
memcpy(&amf_ue->tai, &ran_ue->saved.tai, sizeof(ogs_5gs_tai_t));
memcpy(&amf_ue->nr_cgi, &ran_ue->saved.nr_cgi, sizeof(ogs_nr_cgi_t));
amf_ue->ue_location_timestamp = ogs_time_now();
@ -269,36 +273,6 @@ int gmm_handle_registration_update(amf_ue_t *amf_ue,
ogs_error("Not implemented for Allowed PDU Session Status IE");
}
if ((registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_UPLINK_DATA_STATUS_PRESENT) == 0) {
amf_ue->nas.present.uplink_data_status = 0;
} else {
amf_ue->nas.present.uplink_data_status = 1;
psimask = 0;
psimask |= uplink_data_status->psi << 8;
psimask |= uplink_data_status->psi >> 8;
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (psimask & (1 << sess->psi)) {
#if REMOVED
/*
* TS23.502
* 4.2.3.2 UE Triggered Service Request
*
* Step 4. The Nsmf_PDUSession_UpdateSMContext Request is invoked:
*
* - If the UE identifies List Of PDU Sessions To Be Activated
* in the Service Request message;
* if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED)
*/
#endif
if (SESSION_CONTEXT_IN_SMF(sess))
amf_sbi_send_activating_session(sess);
}
}
}
if ((registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_PDU_SESSION_STATUS_PRESENT) == 0) {
amf_ue->nas.present.pdu_session_status = 0;
@ -318,6 +292,24 @@ int gmm_handle_registration_update(amf_ue_t *amf_ue,
}
}
if ((registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_UPLINK_DATA_STATUS_PRESENT) == 0) {
amf_ue->nas.present.uplink_data_status = 0;
} else {
amf_ue->nas.present.uplink_data_status = 1;
psimask = 0;
psimask |= uplink_data_status->psi << 8;
psimask |= uplink_data_status->psi >> 8;
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (psimask & (1 << sess->psi)) {
if (SESSION_CONTEXT_IN_SMF(sess))
amf_sbi_send_activating_session(sess);
}
}
}
return OGS_OK;
}
@ -346,8 +338,10 @@ int gmm_handle_service_request(amf_ue_t *amf_ue,
/*
* REGISTRATION_REQUEST
* SERVICE_REQUEST
* Clear Paging Info
* Clear Timer and Message
*/
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
if (SECURITY_CONTEXT_IS_VALID(amf_ue)) {
@ -370,7 +364,8 @@ int gmm_handle_service_request(amf_ue_t *amf_ue,
ogs_plmn_id_hexdump(&ran_ue->saved.nr_cgi.plmn_id),
(long long)ran_ue->saved.nr_cgi.cell_id);
/* Copy TAI and ECGI from ran_ue */
/* Copy Stream-No/TAI/ECGI from enb_ue */
amf_ue->gnb_ostream_id = ran_ue->gnb_ostream_id;
memcpy(&amf_ue->tai, &ran_ue->saved.tai, sizeof(ogs_5gs_tai_t));
memcpy(&amf_ue->nr_cgi, &ran_ue->saved.nr_cgi, sizeof(ogs_nr_cgi_t));
amf_ue->ue_location_timestamp = ogs_time_now();
@ -423,44 +418,6 @@ int gmm_handle_service_update(amf_ue_t *amf_ue,
xact_count = amf_sess_xact_count(amf_ue);
if ((service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT) == 0) {
amf_ue->nas.present.allowed_pdu_session_status = 0;
} else {
amf_ue->nas.present.allowed_pdu_session_status = 1;
ogs_error("Not implemented for Allowed PDU Session Status IE");
}
if ((service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_UPLINK_DATA_STATUS_PRESENT) == 0) {
amf_ue->nas.present.uplink_data_status = 0;
} else {
amf_ue->nas.present.uplink_data_status = 1;
psimask = 0;
psimask |= uplink_data_status->psi << 8;
psimask |= uplink_data_status->psi >> 8;
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (psimask & (1 << sess->psi)) {
#if REMOVED
/*
* TS23.502
* 4.2.3.2 UE Triggered Service Request
*
* Step 4. The Nsmf_PDUSession_UpdateSMContext Request is invoked:
*
* - If the UE identifies List Of PDU Sessions To Be Activated
* in the Service Request message;
* if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED)
*/
#endif
if (SESSION_CONTEXT_IN_SMF(sess))
amf_sbi_send_activating_session(sess);
}
}
}
/*
* TS24.501
* 5.6.1.5 Service request procedure not accepted by the network
@ -495,6 +452,32 @@ int gmm_handle_service_update(amf_ue_t *amf_ue,
}
}
if ((service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT) == 0) {
amf_ue->nas.present.allowed_pdu_session_status = 0;
} else {
amf_ue->nas.present.allowed_pdu_session_status = 1;
ogs_error("Not implemented for Allowed PDU Session Status IE");
}
if ((service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_UPLINK_DATA_STATUS_PRESENT) == 0) {
amf_ue->nas.present.uplink_data_status = 0;
} else {
amf_ue->nas.present.uplink_data_status = 1;
psimask = 0;
psimask |= uplink_data_status->psi << 8;
psimask |= uplink_data_status->psi >> 8;
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (psimask & (1 << sess->psi)) {
if (SESSION_CONTEXT_IN_SMF(sess))
amf_sbi_send_activating_session(sess);
}
}
}
if (amf_sess_xact_count(amf_ue) == xact_count)
nas_5gs_send_service_accept(amf_ue);
@ -527,8 +510,7 @@ int gmm_handle_deregistration_request(amf_ue_t *amf_ue,
ogs_info("[%s] SUCI", amf_ue->suci);
amf_sbi_send_release_all_sessions(
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
amf_sbi_send_release_all_sessions(amf_ue, AMF_SESS_SM_CONTEXT_NO_STATE);
if (ogs_list_count(&amf_ue->sess_list) == 0)
nas_5gs_send_de_registration_accept(amf_ue);
@ -810,7 +792,7 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
}
amf_sess_sbi_discover_and_send(OpenAPI_nf_type_SMF,
sess, AMF_UPDATE_SM_CONTEXT_NO_STATE, NULL,
sess, AMF_SESS_SM_CONTEXT_NO_STATE, NULL,
amf_nsmf_pdu_session_build_create_sm_context);
} else {

View File

@ -64,6 +64,8 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, pdu_session_resource_setup_request);
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
break;
case OGS_FSM_EXIT_SIG:
@ -159,7 +161,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
} else {
amf_sbi_send_release_all_sessions(
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
amf_ue, AMF_SESS_SM_CONTEXT_NO_STATE);
if (amf_sess_xact_count(amf_ue) == xact_count) {
amf_ue_sbi_discover_and_send(
OpenAPI_nf_type_AUSF, amf_ue, NULL,
@ -226,7 +228,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
}
amf_sbi_send_release_all_sessions(
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
amf_ue, AMF_SESS_SM_CONTEXT_NO_STATE);
if (amf_sess_xact_count(amf_ue) == xact_count) {
amf_ue_sbi_discover_and_send(OpenAPI_nf_type_AUSF, amf_ue, NULL,
amf_nausf_auth_build_authenticate);
@ -335,20 +337,32 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
case AMF_TIMER_T3513:
if (amf_ue->t3513.retry_count >=
amf_timer_cfg(AMF_TIMER_T3513)->max_count) {
amf_sess_t *sess = NULL;
/* Paging failed */
ogs_warn("[%s] Paging failed. Stop", amf_ue->supi);
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (sess->paging.ongoing == true) {
amf_sbi_send_n1_n2_failure_notify(
sess, OpenAPI_n1_n2_message_transfer_cause_UE_NOT_RESPONDING);
}
}
/* Clear Paging Info */
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
/* Clear N2 Transfer */
AMF_UE_CLEAR_N2_TRANSFER(
amf_ue, pdu_session_resource_setup_request);
/* Clear t3513 Timers */
CLEAR_AMF_UE_TIMER(amf_ue->t3513);
} else {
amf_ue->t3513.retry_count++;
/*
* If t3513 is timeout, the saved pkbuf is used.
* We don't have to set CNDomain.
* So, we just set CNDomain to 0
*/
#if 0
ngap_send_paging(amf_ue, 0);
#endif
/* If t3513 is timeout, the saved pkbuf is used. */
ngap_send_paging(amf_ue);
}
break;
@ -700,13 +714,6 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
} else if (amf_ue->nas.message_type ==
OGS_NAS_5GS_SERVICE_REQUEST) {
OGS_FSM_TRAN(s, &gmm_state_registered);
#if 0
} else if (amf_ue->nas.message_type ==
OGS_NAS_5GS_SERVICE_REQUEST ||
amf_ue->nas.message_type ==
AMF_EPS_TYPE_TAU_REQUEST) {
OGS_FSM_TRAN(s, &gmm_state_registered);
#endif
} else {
ogs_fatal("Invalid OGS_NAS_5GS[%d]", amf_ue->nas.message_type);
ogs_assert_if_reached();
@ -926,16 +933,10 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
if (amf_ue->guti_present == 0)
OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_registered);
/*
* Do not use nas_5gs_send_registration_accept()
* instead of nas_5gs_send_accept() here.
*
* nas_5gs_send_service_accept() could be used later.
* The reason is why the design could be changed to handle this.
*
* So we'll use nas_5gs_send_accept() at this point.
*/
nas_5gs_send_accept(amf_ue);
/* If nas_5gs_send_service_accept() used, we need change it. */
ogs_assert(amf_ue->nas.message_type ==
OGS_NAS_5GS_REGISTRATION_REQUEST);
nas_5gs_send_registration_accept(amf_ue);
break;
DEFAULT
@ -1001,7 +1002,7 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
}
amf_sbi_send_release_all_sessions(
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
amf_ue, AMF_SESS_SM_CONTEXT_NO_STATE);
if (amf_sess_xact_count(amf_ue) == xact_count) {
amf_ue_sbi_discover_and_send(OpenAPI_nf_type_AUSF, amf_ue, NULL,
amf_nausf_auth_build_authenticate);
@ -1066,10 +1067,11 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, pdu_session_resource_setup_request);
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
amf_sbi_send_release_all_sessions(
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
amf_sbi_send_release_all_sessions(amf_ue, AMF_SESS_SM_CONTEXT_NO_STATE);
if (ogs_list_count(&amf_ue->sess_list) == 0)
ngap_send_amf_ue_context_release_command(amf_ue,
@ -1126,7 +1128,7 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
} else {
amf_sbi_send_release_all_sessions(
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
amf_ue, AMF_SESS_SM_CONTEXT_NO_STATE);
if (amf_sess_xact_count(amf_ue) == xact_count) {
amf_ue_sbi_discover_and_send(
OpenAPI_nf_type_AUSF, amf_ue, NULL,

View File

@ -30,11 +30,10 @@ int amf_namf_comm_handle_n1_n2_message_transfer(
int status;
amf_ue_t *amf_ue = NULL;
ran_ue_t *ran_ue = NULL;
amf_sess_t *sess = NULL;
ogs_pkbuf_t *n1smbuf = NULL;
ogs_pkbuf_t *n2smbuf = NULL;
ogs_pkbuf_t *n1buf = NULL;
ogs_pkbuf_t *n2buf = NULL;
ogs_pkbuf_t *gmmbuf = NULL;
ogs_pkbuf_t *ngapbuf = NULL;
@ -63,47 +62,6 @@ int amf_namf_comm_handle_n1_n2_message_transfer(
return OGS_ERROR;
}
n1MessageContainer = N1N2MessageTransferReqData->n1_message_container;
if (!n1MessageContainer) {
ogs_error("No n1MessageContainer");
return OGS_ERROR;
}
n1MessageContent = n1MessageContainer->n1_message_content;
if (!n1MessageContent || !n1MessageContent->content_id) {
ogs_error("No n1MessageContent");
return OGS_ERROR;
}
n2InfoContainer = N1N2MessageTransferReqData->n2_info_container;
if (!n2InfoContainer) {
ogs_error("No n2InfoContainer");
return OGS_ERROR;
}
smInfo = n2InfoContainer->sm_info;
if (!smInfo) {
ogs_error("No smInfo");
return OGS_ERROR;
}
n2InfoContent = smInfo->n2_info_content;
if (!n2InfoContent) {
ogs_error("No n2InfoContent");
return OGS_ERROR;
}
switch (n2InfoContent->ngap_ie_type) {
case OpenAPI_ngap_ie_type_PDU_RES_SETUP_REQ:
case OpenAPI_ngap_ie_type_PDU_RES_MOD_REQ:
break;
default:
ogs_error("Not implemented ngap_ie_type[%d]",
n2InfoContent->ngap_ie_type);
return OGS_ERROR;
}
ngapData = n2InfoContent->ngap_data;
if (!ngapData || !ngapData->content_id) {
ogs_error("No ngapData");
return OGS_ERROR;
}
pdu_session_id = N1N2MessageTransferReqData->pdu_session_id;
if (pdu_session_id == OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED) {
ogs_error("No PDU Session Identity");
@ -122,9 +80,6 @@ int amf_namf_comm_handle_n1_n2_message_transfer(
return OGS_ERROR;
}
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
ogs_assert(ran_ue);
sess = amf_sess_find_by_psi(amf_ue, pdu_session_id);
if (!sess) {
ogs_error("[%s] No PDU Session Context [%d]",
@ -132,82 +87,278 @@ int amf_namf_comm_handle_n1_n2_message_transfer(
return OGS_ERROR;
}
n1smbuf = ogs_sbi_find_part_by_content_id(
recvmsg, n1MessageContent->content_id);
if (!n1smbuf) {
ogs_error("[%s] No N1 SM Content", amf_ue->supi);
return OGS_ERROR;
n1MessageContainer = N1N2MessageTransferReqData->n1_message_container;
if (n1MessageContainer) {
n1MessageContent = n1MessageContainer->n1_message_content;
if (!n1MessageContent || !n1MessageContent->content_id) {
ogs_error("No n1MessageContent");
return OGS_ERROR;
}
n1buf = ogs_sbi_find_part_by_content_id(
recvmsg, n1MessageContent->content_id);
if (!n1buf) {
ogs_error("[%s] No N1 SM Content", amf_ue->supi);
return OGS_ERROR;
}
/*
* NOTE : The pkbuf created in the SBI message will be removed
* from ogs_sbi_message_free(), so it must be copied.
*/
n1buf = ogs_pkbuf_copy(n1buf);
ogs_assert(n1buf);
}
/*
* NOTE : The pkbuf created in the SBI message will be removed
* from ogs_sbi_message_free(), so it must be copied.
*/
n1smbuf = ogs_pkbuf_copy(n1smbuf);
ogs_assert(n1smbuf);
n2smbuf = ogs_sbi_find_part_by_content_id(recvmsg, ngapData->content_id);
if (!n2smbuf) {
ogs_error("[%s] No N2 SM Content", amf_ue->supi);
return OGS_ERROR;
n2InfoContainer = N1N2MessageTransferReqData->n2_info_container;
if (n2InfoContainer) {
smInfo = n2InfoContainer->sm_info;
if (!smInfo) {
ogs_error("No smInfo");
return OGS_ERROR;
}
n2InfoContent = smInfo->n2_info_content;
if (!n2InfoContent) {
ogs_error("No n2InfoContent");
return OGS_ERROR;
}
ngapData = n2InfoContent->ngap_data;
if (!ngapData || !ngapData->content_id) {
ogs_error("No ngapData");
return OGS_ERROR;
}
n2buf = ogs_sbi_find_part_by_content_id(
recvmsg, ngapData->content_id);
if (!n2buf) {
ogs_error("[%s] No N2 SM Content", amf_ue->supi);
return OGS_ERROR;
}
/*
* NOTE : The pkbuf created in the SBI message will be removed
* from ogs_sbi_message_free(), so it must be copied.
*/
n2buf = ogs_pkbuf_copy(n2buf);
ogs_assert(n2buf);
}
/*
* NOTE : The pkbuf created in the SBI message will be removed
* from ogs_sbi_message_free(), so it must be copied.
*/
n2smbuf = ogs_pkbuf_copy(n2smbuf);
ogs_assert(n2smbuf);
status = OGS_SBI_HTTP_STATUS_OK;
gmmbuf = gmm_build_dl_nas_transport(sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0);
ogs_assert(gmmbuf);
switch (n2InfoContent->ngap_ie_type) {
case OpenAPI_ngap_ie_type_PDU_RES_SETUP_REQ:
if (sess->pdu_session_establishment_accept) {
ogs_pkbuf_free(sess->pdu_session_establishment_accept);
sess->pdu_session_establishment_accept = NULL;
case OpenAPI_ngap_ie_type_PDU_RES_MOD_REQ:
case OpenAPI_ngap_ie_type_PDU_RES_REL_CMD:
/* N1 SM Message */
if (n1buf) {
gmmbuf = gmm_build_dl_nas_transport(sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1buf, 0, 0);
ogs_assert(gmmbuf);
}
break;
default:
ogs_error("Not implemented ngap_ie_type[%d]",
n2InfoContent->ngap_ie_type);
return OGS_ERROR;
}
memset(&sendmsg, 0, sizeof(sendmsg));
status = OGS_SBI_HTTP_STATUS_OK;
memset(&N1N2MessageTransferRspData, 0, sizeof(N1N2MessageTransferRspData));
N1N2MessageTransferRspData.cause =
OpenAPI_n1_n2_message_transfer_cause_N1_N2_TRANSFER_INITIATED;
sendmsg.N1N2MessageTransferRspData = &N1N2MessageTransferRspData;
switch (n2InfoContent->ngap_ie_type) {
case OpenAPI_ngap_ie_type_PDU_RES_SETUP_REQ:
if (!n2buf) {
ogs_error("[%s] No N2 SM Content", amf_ue->supi);
return OGS_ERROR;
}
if (ran_ue->initial_context_setup_request_sent == true) {
ngapbuf = ngap_sess_build_pdu_session_resource_setup_request(
sess, gmmbuf, n2smbuf);
ogs_assert(ngapbuf);
} else {
ngapbuf = ngap_sess_build_initial_context_setup_request(
sess, gmmbuf, n2smbuf);
ogs_assert(ngapbuf);
if (gmmbuf) {
ran_ue_t *ran_ue = NULL;
ran_ue->initial_context_setup_request_sent = true;
}
/***********************************
* 4.3.2 PDU Session Establishment *
***********************************/
if (SESSION_CONTEXT_IN_SMF(sess)) {
/*
* [1-CLIENT] /nsmf-pdusession/v1/sm-contexts
* [2-SERVER] /namf-comm/v1/ue-contexts/{supi}/n1-n2-messages
*
* If [2-SERVER] arrives after [1-CLIENT],
* sm-context-ref is created in [1-CLIENT].
* So, the PDU session establishment accpet can be transmitted now.
*/
if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK) {
ogs_error("nas_5gs_send_to_gnb() failed");
status = OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR;
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
ogs_assert(ran_ue);
if (sess->pdu_session_establishment_accept) {
ogs_pkbuf_free(sess->pdu_session_establishment_accept);
sess->pdu_session_establishment_accept = NULL;
}
if (ran_ue->initial_context_setup_request_sent == true) {
ngapbuf = ngap_sess_build_pdu_session_resource_setup_request(
sess, gmmbuf, n2buf);
ogs_assert(ngapbuf);
} else {
ngapbuf = ngap_sess_build_initial_context_setup_request(
sess, gmmbuf, n2buf);
ogs_assert(ngapbuf);
ran_ue->initial_context_setup_request_sent = true;
}
if (SESSION_CONTEXT_IN_SMF(sess)) {
/*
* [1-CLIENT] /nsmf-pdusession/v1/sm-contexts
* [2-SERVER] /namf-comm/v1/ue-contexts/{supi}/n1-n2-messages
*
* If [2-SERVER] arrives after [1-CLIENT],
* sm-context-ref is created in [1-CLIENT].
* So, the PDU session establishment accpet can be transmitted.
*/
if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK)
ogs_error("nas_5gs_send_to_gnb() failed");
} else {
sess->pdu_session_establishment_accept = ngapbuf;
}
} else {
sess->pdu_session_establishment_accept = ngapbuf;
/*********************************************
* 4.2.3.3 Network Triggered Service Request *
*********************************************/
if (CM_IDLE(amf_ue)) {
ogs_sbi_server_t *server = NULL;
ogs_sbi_header_t header;
ogs_sbi_client_t *client = NULL;
ogs_sockaddr_t *addr = NULL;
if (!N1N2MessageTransferReqData->n1n2_failure_txf_notif_uri) {
ogs_error("[%s:%d] No n1-n2-failure-notification-uri",
amf_ue->supi, sess->psi);
return OGS_ERROR;
}
addr = ogs_sbi_getaddr_from_uri(
N1N2MessageTransferReqData->n1n2_failure_txf_notif_uri);
if (!addr) {
ogs_error("[%s:%d] Invalid URI [%s]",
amf_ue->supi, sess->psi,
N1N2MessageTransferReqData->
n1n2_failure_txf_notif_uri);
return OGS_ERROR;;
}
client = ogs_sbi_client_find(addr);
if (!client) {
client = ogs_sbi_client_add(addr);
ogs_assert(client);
}
OGS_SETUP_SBI_CLIENT(&sess->paging, client);
ogs_freeaddrinfo(addr);
status = OGS_SBI_HTTP_STATUS_ACCEPTED;
N1N2MessageTransferRspData.cause =
OpenAPI_n1_n2_message_transfer_cause_ATTEMPTING_TO_REACH_UE;
/* Location */
server = ogs_sbi_server_from_stream(stream);
ogs_assert(server);
memset(&header, 0, sizeof(header));
header.service.name = (char *)OGS_SBI_SERVICE_NAME_NAMF_COMM;
header.api.version = (char *)OGS_SBI_API_V1;
header.resource.component[0] =
(char *)OGS_SBI_RESOURCE_NAME_UE_CONTEXTS;
header.resource.component[1] = amf_ue->supi;
header.resource.component[2] =
(char *)OGS_SBI_RESOURCE_NAME_N1_N2_MESSAGES;
header.resource.component[3] = sess->sm_context_ref;
sendmsg.http.location = ogs_sbi_server_uri(server, &header);
/* Store Paging Info */
AMF_SESS_STORE_PAGING_INFO(
sess, sendmsg.http.location,
N1N2MessageTransferReqData->n1n2_failure_txf_notif_uri);
/* Store N2 Transfer message */
AMF_SESS_STORE_N2_TRANSFER(
sess, pdu_session_resource_setup_request, n2buf);
ngap_send_paging(amf_ue);
} else if (CM_CONNECTED(amf_ue)) {
ngap_send_pdu_resource_setup_request(sess, n2buf);
} else {
ogs_fatal("[%s] Invalid AMF-UE state", amf_ue->supi);
ogs_assert_if_reached();
}
}
break;
case OpenAPI_ngap_ie_type_PDU_RES_MOD_REQ:
ngapbuf = ngap_build_pdu_session_resource_modify_request(
sess, gmmbuf, n2smbuf);
ogs_assert(ngapbuf);
if (!gmmbuf) {
ogs_error("[%s] No N1 SM Content", amf_ue->supi);
return OGS_ERROR;
}
if (!n2buf) {
ogs_error("[%s] No N2 SM Content", amf_ue->supi);
return OGS_ERROR;
}
if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK) {
ogs_error("nas_5gs_send_to_gnb() failed");
status = OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR;
if (CM_IDLE(amf_ue)) {
ogs_fatal("[%s] IDLE state is not implemented", amf_ue->supi);
ogs_assert_if_reached();
} else if (CM_CONNECTED(amf_ue)) {
ngapbuf = ngap_build_pdu_session_resource_modify_request(
sess, gmmbuf, n2buf);
ogs_assert(ngapbuf);
if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK)
ogs_error("nas_5gs_send_to_gnb() failed");
} else {
ogs_fatal("[%s] Invalid AMF-UE state", amf_ue->supi);
ogs_assert_if_reached();
}
break;
case OpenAPI_ngap_ie_type_PDU_RES_REL_CMD:
if (!n2buf) {
ogs_error("[%s] No N2 SM Content", amf_ue->supi);
return OGS_ERROR;
}
if (CM_IDLE(amf_ue)) {
if (gmmbuf)
ogs_pkbuf_free(gmmbuf);
if (n2buf)
ogs_pkbuf_free(n2buf);
if (N1N2MessageTransferReqData->skip_ind == true) {
N1N2MessageTransferRspData.cause =
OpenAPI_n1_n2_message_transfer_cause_N1_MSG_NOT_TRANSFERRED;
} else {
ogs_fatal("[%s] No skipInd", amf_ue->supi);
ogs_assert_if_reached();
}
} else if (CM_CONNECTED(amf_ue)) {
ngapbuf = ngap_build_pdu_session_resource_release_command(
sess, NULL, n2buf);
ogs_assert(ngapbuf);
if (nas_5gs_send_to_gnb(amf_ue, ngapbuf) != OGS_OK)
ogs_error("nas_5gs_send_to_gnb() failed");
} else {
ogs_fatal("[%s] Invalid AMF-UE state", amf_ue->supi);
ogs_assert_if_reached();
}
break;
@ -217,21 +368,13 @@ int amf_namf_comm_handle_n1_n2_message_transfer(
ogs_assert_if_reached();
}
memset(&sendmsg, 0, sizeof(sendmsg));
if (status == OGS_SBI_HTTP_STATUS_OK) {
memset(&N1N2MessageTransferRspData, 0,
sizeof(N1N2MessageTransferRspData));
N1N2MessageTransferRspData.cause =
OpenAPI_n1_n2_message_transfer_cause_N1_N2_TRANSFER_INITIATED;
sendmsg.N1N2MessageTransferRspData = &N1N2MessageTransferRspData;
}
response = ogs_sbi_build_response(&sendmsg, status);
ogs_assert(response);
ogs_sbi_server_send_response(stream, response);
if (sendmsg.http.location)
ogs_free(sendmsg.http.location);
return OGS_OK;
}
@ -322,7 +465,7 @@ int amf_namf_callback_handle_sm_context_status(
ogs_debug("[%s:%d] SM context remove", amf_ue->supi, sess->psi);
amf_nsmf_pdu_session_handle_release_sm_context(
sess, AMF_RELEASE_SM_CONTEXT_NO_STATE);
sess, AMF_SESS_SM_CONTEXT_NO_STATE);
}
cleanup:

View File

@ -89,7 +89,7 @@ void nas_5gs_send_registration_accept(amf_ue_t *amf_ue)
ran_ue->initial_context_setup_request_sent = true;
} else {
if (SESSION_TRANSFER_NEEDED(amf_ue)) {
if (PDU_RES_SETUP_REQ_TRANSFER_NEEDED(amf_ue)) {
ngapbuf = ngap_ue_build_pdu_session_resource_setup_request(
amf_ue, gmmbuf);
ogs_expect_or_return(ngapbuf);
@ -141,8 +141,7 @@ void nas_5gs_send_service_accept(amf_ue_t *amf_ue)
if (ran_ue->ue_context_requested == true &&
ran_ue->initial_context_setup_request_sent == false) {
ngapbuf = ngap_ue_build_initial_context_setup_request(
amf_ue, gmmbuf);
ngapbuf = ngap_ue_build_initial_context_setup_request(amf_ue, gmmbuf);
ogs_expect_or_return(ngapbuf);
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
@ -150,7 +149,7 @@ void nas_5gs_send_service_accept(amf_ue_t *amf_ue)
ran_ue->initial_context_setup_request_sent = true;
} else {
if (SESSION_TRANSFER_NEEDED(amf_ue)) {
if (PDU_RES_SETUP_REQ_TRANSFER_NEEDED(amf_ue)) {
ngapbuf = ngap_ue_build_pdu_session_resource_setup_request(
amf_ue, gmmbuf);
ogs_expect_or_return(ngapbuf);
@ -179,22 +178,6 @@ void nas_5gs_send_service_reject(
ogs_expect(rv == OGS_OK);
}
void nas_5gs_send_accept(amf_ue_t *amf_ue)
{
ogs_assert(amf_ue);
switch(amf_ue->nas.message_type) {
case OGS_NAS_5GS_REGISTRATION_REQUEST:
nas_5gs_send_registration_accept(amf_ue);
break;
case OGS_NAS_5GS_SERVICE_REQUEST:
nas_5gs_send_service_accept(amf_ue);
break;
default:
ogs_error("Unknown message type [%d]", amf_ue->nas.message_type);
}
}
void nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue)
{
ran_ue_t *ran_ue = NULL;

View File

@ -40,8 +40,6 @@ void nas_5gs_send_service_accept(amf_ue_t *amf_ue);
void nas_5gs_send_service_reject(
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause);
void nas_5gs_send_accept(amf_ue_t *amf_ue);
void nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue);
void nas_5gs_send_identity_request(amf_ue_t *amf_ue);

View File

@ -240,8 +240,7 @@ ogs_pkbuf_t *ngap_build_downlink_nas_transport(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
@ -389,8 +388,7 @@ ogs_pkbuf_t *ngap_ue_build_initial_context_setup_request(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
@ -659,7 +657,7 @@ ogs_pkbuf_t *ngap_ue_build_initial_context_setup_request(
}
ogs_pkbuf_t *ngap_sess_build_initial_context_setup_request(
amf_sess_t *sess, ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf)
amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf)
{
int i, j;
@ -752,12 +750,14 @@ ogs_pkbuf_t *ngap_sess_build_initial_context_setup_request(
GUAMI = &ie->value.choice.GUAMI;
if (n1smbuf && n2smbuf) {
if (gmmbuf || n2smbuf) {
NGAP_NAS_PDU_t *nAS_PDU = NULL;
OCTET_STRING_t *transfer = NULL;
NGAP_S_NSSAI_t *s_NSSAI = NULL;
NGAP_SST_t *sST = NULL;
ogs_assert(n2smbuf);
ie = CALLOC(1, sizeof(NGAP_InitialContextSetupRequestIEs_t));
ASN_SEQUENCE_ADD(&InitialContextSetupRequest->protocolIEs, ie);
@ -771,13 +771,15 @@ ogs_pkbuf_t *ngap_sess_build_initial_context_setup_request(
sizeof(struct NGAP_PDUSessionResourceSetupItemCxtReq));
ASN_SEQUENCE_ADD(&PDUSessionList->list, PDUSessionItem);
PDUSessionItem->nAS_PDU = nAS_PDU = CALLOC(1, sizeof(*nAS_PDU));
ogs_assert(nAS_PDU);
if (gmmbuf) {
PDUSessionItem->nAS_PDU = nAS_PDU = CALLOC(1, sizeof(*nAS_PDU));
ogs_assert(nAS_PDU);
nAS_PDU->size = n1smbuf->len;
nAS_PDU->buf = CALLOC(nAS_PDU->size, sizeof(uint8_t));
memcpy(nAS_PDU->buf, n1smbuf->data, nAS_PDU->size);
ogs_pkbuf_free(n1smbuf);
nAS_PDU->size = gmmbuf->len;
nAS_PDU->buf = CALLOC(nAS_PDU->size, sizeof(uint8_t));
memcpy(nAS_PDU->buf, gmmbuf->data, nAS_PDU->size);
ogs_pkbuf_free(gmmbuf);
}
PDUSessionItem->pDUSessionID = sess->psi;
@ -973,8 +975,7 @@ ogs_pkbuf_t *ngap_build_ue_context_modification_request(amf_ue_t *amf_ue)
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
@ -1106,8 +1107,7 @@ ogs_pkbuf_t *ngap_build_ue_context_release_command(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UEContextRelease;
@ -1175,7 +1175,6 @@ ogs_pkbuf_t *ngap_ue_build_pdu_session_resource_setup_request(
NGAP_PDUSessionResourceSetupListSUReq_t *PDUSessionList = NULL;
NGAP_PDUSessionResourceSetupItemSUReq_t *PDUSessionItem = NULL;
ogs_assert(gmmbuf);
ogs_assert(amf_ue);
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
ogs_assert(ran_ue);
@ -1220,20 +1219,22 @@ ogs_pkbuf_t *ngap_ue_build_pdu_session_resource_setup_request(
asn_uint642INTEGER(AMF_UE_NGAP_ID, ran_ue->amf_ue_ngap_id);
*RAN_UE_NGAP_ID = ran_ue->ran_ue_ngap_id;
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestIEs_t));
ASN_SEQUENCE_ADD(&PDUSessionResourceSetupRequest->protocolIEs, ie);
if (gmmbuf) {
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestIEs_t));
ASN_SEQUENCE_ADD(&PDUSessionResourceSetupRequest->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU;
ie->criticality = NGAP_Criticality_reject;
ie->value.present =
NGAP_PDUSessionResourceSetupRequestIEs__value_PR_NAS_PDU;
ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU;
ie->criticality = NGAP_Criticality_reject;
ie->value.present =
NGAP_PDUSessionResourceSetupRequestIEs__value_PR_NAS_PDU;
NAS_PDU = &ie->value.choice.NAS_PDU;
NAS_PDU = &ie->value.choice.NAS_PDU;
NAS_PDU->size = gmmbuf->len;
NAS_PDU->buf = CALLOC(NAS_PDU->size, sizeof(uint8_t));
memcpy(NAS_PDU->buf, gmmbuf->data, NAS_PDU->size);
ogs_pkbuf_free(gmmbuf);
NAS_PDU->size = gmmbuf->len;
NAS_PDU->buf = CALLOC(NAS_PDU->size, sizeof(uint8_t));
memcpy(NAS_PDU->buf, gmmbuf->data, NAS_PDU->size);
ogs_pkbuf_free(gmmbuf);
}
ogs_list_for_each(&amf_ue->sess_list, sess) {
NGAP_S_NSSAI_t *s_NSSAI = NULL;
@ -1302,7 +1303,6 @@ ogs_pkbuf_t *ngap_sess_build_pdu_session_resource_setup_request(
NGAP_SST_t *sST = NULL;
OCTET_STRING_t *transfer = NULL;
ogs_assert(gmmbuf);
ogs_assert(n2smbuf);
ogs_assert(sess);
@ -1366,12 +1366,15 @@ ogs_pkbuf_t *ngap_sess_build_pdu_session_resource_setup_request(
PDUSessionItem->pDUSessionID = sess->psi;
PDUSessionItem->pDUSessionNAS_PDU =
pDUSessionNAS_PDU = CALLOC(1, sizeof(NGAP_NAS_PDU_t));
pDUSessionNAS_PDU->size = gmmbuf->len;
pDUSessionNAS_PDU->buf = CALLOC(pDUSessionNAS_PDU->size, sizeof(uint8_t));
memcpy(pDUSessionNAS_PDU->buf, gmmbuf->data, pDUSessionNAS_PDU->size);
ogs_pkbuf_free(gmmbuf);
if (gmmbuf) {
PDUSessionItem->pDUSessionNAS_PDU =
pDUSessionNAS_PDU = CALLOC(1, sizeof(NGAP_NAS_PDU_t));
pDUSessionNAS_PDU->size = gmmbuf->len;
pDUSessionNAS_PDU->buf =
CALLOC(pDUSessionNAS_PDU->size, sizeof(uint8_t));
memcpy(pDUSessionNAS_PDU->buf, gmmbuf->data, pDUSessionNAS_PDU->size);
ogs_pkbuf_free(gmmbuf);
}
s_NSSAI = &PDUSessionItem->s_NSSAI;
sST = &s_NSSAI->sST;
@ -1507,7 +1510,6 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command(
NGAP_PDUSessionResourceToReleaseItemRelCmd_t *PDUSessionItem = NULL;
OCTET_STRING_t *transfer = NULL;
ogs_assert(gmmbuf);
ogs_assert(n2smbuf);
ogs_assert(sess);
@ -1550,15 +1552,28 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command(
RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID;
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceReleaseCommandIEs_t));
ASN_SEQUENCE_ADD(&PDUSessionResourceReleaseCommand->protocolIEs, ie);
ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld]",
ran_ue->ran_ue_ngap_id, (long long)ran_ue->amf_ue_ngap_id);
ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present =
NGAP_PDUSessionResourceReleaseCommandIEs__value_PR_NAS_PDU;
asn_uint642INTEGER(AMF_UE_NGAP_ID, ran_ue->amf_ue_ngap_id);
*RAN_UE_NGAP_ID = ran_ue->ran_ue_ngap_id;
NAS_PDU = &ie->value.choice.NAS_PDU;
if (gmmbuf) {
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceReleaseCommandIEs_t));
ASN_SEQUENCE_ADD(&PDUSessionResourceReleaseCommand->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present =
NGAP_PDUSessionResourceReleaseCommandIEs__value_PR_NAS_PDU;
NAS_PDU = &ie->value.choice.NAS_PDU;
NAS_PDU->size = gmmbuf->len;
NAS_PDU->buf = CALLOC(NAS_PDU->size, sizeof(uint8_t));
memcpy(NAS_PDU->buf, gmmbuf->data, NAS_PDU->size);
ogs_pkbuf_free(gmmbuf);
}
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceReleaseCommandIEs_t));
ASN_SEQUENCE_ADD(&PDUSessionResourceReleaseCommand->protocolIEs, ie);
@ -1569,17 +1584,6 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command(
PDUSessionList = &ie->value.choice.PDUSessionResourceToReleaseListRelCmd;
ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld]",
ran_ue->ran_ue_ngap_id, (long long)ran_ue->amf_ue_ngap_id);
asn_uint642INTEGER(AMF_UE_NGAP_ID, ran_ue->amf_ue_ngap_id);
*RAN_UE_NGAP_ID = ran_ue->ran_ue_ngap_id;
NAS_PDU->size = gmmbuf->len;
NAS_PDU->buf = CALLOC(NAS_PDU->size, sizeof(uint8_t));
memcpy(NAS_PDU->buf, gmmbuf->data, NAS_PDU->size);
ogs_pkbuf_free(gmmbuf);
PDUSessionItem =
CALLOC(1, sizeof(struct NGAP_PDUSessionResourceToReleaseItemRelCmd));
ASN_SEQUENCE_ADD(&PDUSessionList->list, PDUSessionItem);
@ -1595,9 +1599,7 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command(
return ogs_ngap_encode(&pdu);
}
#if 0
ogs_pkbuf_t *ngap_build_paging(
amf_ue_t *amf_ue, NGAP_CNDomain_t cn_domain)
ogs_pkbuf_t *ngap_build_paging(amf_ue_t *amf_ue)
{
NGAP_NGAP_PDU_t pdu;
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
@ -1605,26 +1607,20 @@ ogs_pkbuf_t *ngap_build_paging(
NGAP_PagingIEs_t *ie = NULL;
NGAP_UEIdentityIndexValue_t *UEIdentityIndexValue = NULL;
NGAP_UEPagingID_t *UEPagingID = NULL;
NGAP_CNDomain_t *CNDomain = NULL;
NGAP_TAIList_t *TAIList = NULL;
NGAP_TAIItemIEs_t *item = NULL;
NGAP_TAIItem_t *tai_item = NULL;
uint16_t index_value;
uint64_t ue_imsi_value = 0;
int i = 0;
ogs_assert(amf_ue);
NGAP_UEPagingIdentity_t *UEPagingIdentity = NULL;
NGAP_FiveG_S_TMSI_t *fiveG_S_TMSI = NULL;
NGAP_AMFSetID_t *aMFSetID = NULL;
NGAP_AMFPointer_t *aMFPointer = NULL;
NGAP_FiveG_TMSI_t *fiveG_TMSI = NULL;
NGAP_TAIListForPaging_t *TAIList = NULL;
NGAP_TAIListForPagingItem_t *TAIItem = NULL;
NGAP_TAI_t *tAI = NULL;
ogs_debug("Paging");
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_Paging;
@ -1636,89 +1632,46 @@ ogs_pkbuf_t *ngap_build_paging(
ie = CALLOC(1, sizeof(NGAP_PagingIEs_t));
ASN_SEQUENCE_ADD(&Paging->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_UEIdentityIndexValue;
ie->id = NGAP_ProtocolIE_ID_id_UEPagingIdentity;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_PagingIEs__value_PR_UEIdentityIndexValue;
ie->value.present = NGAP_PagingIEs__value_PR_UEPagingIdentity;
UEIdentityIndexValue = &ie->value.choice.UEIdentityIndexValue;
UEPagingIdentity = &ie->value.choice.UEPagingIdentity;
UEPagingIdentity->present = NGAP_UEPagingIdentity_PR_fiveG_S_TMSI;
UEPagingIdentity->choice.fiveG_S_TMSI = fiveG_S_TMSI =
CALLOC(1, sizeof(NGAP_FiveG_S_TMSI_t));
ogs_assert(fiveG_S_TMSI);
aMFSetID = &fiveG_S_TMSI->aMFSetID;
aMFPointer = &fiveG_S_TMSI->aMFPointer;
fiveG_TMSI = &fiveG_S_TMSI->fiveG_TMSI;
ogs_ngap_uint16_to_AMFSetID(
ogs_amf_set_id(&amf_ue->guti.amf_id), aMFSetID);
ogs_ngap_uint8_to_AMFPointer(
ogs_amf_pointer(&amf_ue->guti.amf_id), aMFPointer);
ogs_asn_uint32_to_OCTET_STRING(amf_ue->guti.m_tmsi, fiveG_TMSI);
ie = CALLOC(1, sizeof(NGAP_PagingIEs_t));
ASN_SEQUENCE_ADD(&Paging->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_UEPagingID;
ie->id = NGAP_ProtocolIE_ID_id_TAIListForPaging;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_PagingIEs__value_PR_UEPagingID;
ie->value.present = NGAP_PagingIEs__value_PR_TAIListForPaging;
UEPagingID = &ie->value.choice.UEPagingID;
TAIList = &ie->value.choice.TAIListForPaging;
ie = CALLOC(1, sizeof(NGAP_PagingIEs_t));
ASN_SEQUENCE_ADD(&Paging->protocolIEs, ie);
TAIItem = CALLOC(1, sizeof(NGAP_TAIListForPagingItem_t));
ASN_SEQUENCE_ADD(&TAIList->list, TAIItem);
ie->id = NGAP_ProtocolIE_ID_id_CNDomain;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_PagingIEs__value_PR_CNDomain;
CNDomain = &ie->value.choice.CNDomain;
ie = CALLOC(1, sizeof(NGAP_PagingIEs_t));
ASN_SEQUENCE_ADD(&Paging->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_TAIList;
ie->criticality = NGAP_Criticality_ignore;
ie->value.present = NGAP_PagingIEs__value_PR_TAIList;
TAIList = &ie->value.choice.TAIList;
/* Set UE Identity Index value : IMSI mod 4096 */
UEIdentityIndexValue->size = 2;
UEIdentityIndexValue->buf =
CALLOC(UEIdentityIndexValue->size, sizeof(uint8_t));
/* Conver string to value */
for (i = 0; i < strlen(amf_ue->imsi_bcd); i++) {
ue_imsi_value = ue_imsi_value*10 + (amf_ue->imsi_bcd[i] - '0');
}
/* index(10bit) = ue_imsi_value mod 1024 */
index_value = ue_imsi_value % 1024;
UEIdentityIndexValue->buf[0] = index_value >> 2;
UEIdentityIndexValue->buf[1] = (index_value & 0x3f) << 6;
UEIdentityIndexValue->bits_unused = 6;
/* Set Paging Identity */
UEPagingID->present = NGAP_UEPagingID_PR_s_TMSI;
UEPagingID->choice.s_TMSI =
CALLOC(1, sizeof(NGAP_S_TMSI_t));
ogs_asn_uint8_to_OCTET_STRING(amf_ue->guti.amf_code,
&UEPagingID->choice.s_TMSI->mMEC);
ogs_asn_uint32_to_OCTET_STRING(amf_ue->guti.m_tmsi,
&UEPagingID->choice.s_TMSI->m_TMSI);
ogs_debug(" AMF_CODE[%d] M_TMSI[0x%x]",
amf_ue->guti.amf_code, amf_ue->guti.m_tmsi);
ogs_debug(" CN_DOMAIN[%s]",
cn_domain == NGAP_CNDomain_cs ? "CS" :
cn_domain == NGAP_CNDomain_ps ? "PS" : "Unknown");
*CNDomain = cn_domain;
item = CALLOC(1, sizeof(NGAP_TAIItemIEs_t));
ASN_SEQUENCE_ADD(&TAIList->list, item);
item->id = NGAP_ProtocolIE_ID_id_TAIItem;
item->criticality = NGAP_Criticality_ignore;
item->value.present = NGAP_TAIItemIEs__value_PR_TAIItem;
tai_item = &item->value.choice.TAIItem;
ogs_asn_buffer_to_OCTET_STRING(&amf_ue->tai.plmn_id, sizeof(ogs_plmn_id_t),
&tai_item->tAI.pLMNidentity);
ogs_asn_uint16_to_OCTET_STRING(amf_ue->tai.tac, &tai_item->tAI.tAC);
tAI = &TAIItem->tAI;
ogs_ngap_5gs_tai_to_ASN(&amf_ue->tai, tAI);
return ogs_ngap_encode(&pdu);
}
#if 0
ogs_pkbuf_t *ngap_build_amf_configuration_transfer(
NGAP_SONConfigurationTransfer_t *son_configuration_transfer)
{
@ -1737,8 +1690,7 @@ ogs_pkbuf_t *ngap_build_amf_configuration_transfer(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
@ -2217,8 +2169,7 @@ ogs_pkbuf_t *ngap_build_handover_request(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
@ -2500,8 +2451,7 @@ ogs_pkbuf_t *ngap_build_amf_status_transfer(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_AMFStatusTransfer;
@ -2574,8 +2524,7 @@ ogs_pkbuf_t *ngap_build_error_indication(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_ErrorIndication;
@ -2648,8 +2597,7 @@ ogs_pkbuf_t *ngap_build_s1_reset(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_Reset;

View File

@ -36,7 +36,7 @@ ogs_pkbuf_t *ngap_build_downlink_nas_transport(
ogs_pkbuf_t *ngap_ue_build_initial_context_setup_request(
amf_ue_t *amf_ue, ogs_pkbuf_t *gmmbuf);
ogs_pkbuf_t *ngap_sess_build_initial_context_setup_request(
amf_sess_t *sess, ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf);
amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf);
ogs_pkbuf_t *ngap_build_ue_context_modification_request(amf_ue_t *amf_ue);
ogs_pkbuf_t *ngap_build_ue_context_release_command(
ran_ue_t *ran_ue, NGAP_Cause_PR group, long cause);
@ -50,10 +50,7 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_modify_request(
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command(
amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf);
#if 0
ogs_pkbuf_t *ngap_build_paging(
amf_ue_t *amf_ue, NGAP_CNDomain_t cn_domain);
#endif
ogs_pkbuf_t *ngap_build_paging(amf_ue_t *amf_ue);
ogs_pkbuf_t *ngap_build_amf_configuration_transfer(
NGAP_SONConfigurationTransfer_t *son_configuration_transfer);

View File

@ -1876,7 +1876,8 @@ void ngap_handle_path_switch_request(
ogs_ngap_ASN_to_5gs_tai(
&UserLocationInformationNR->tAI, &ran_ue->saved.tai);
/* Copy TAI and ECGI from ran_ue */
/* Copy Stream-No/TAI/ECGI from enb_ue */
amf_ue->gnb_ostream_id = ran_ue->gnb_ostream_id;
memcpy(&amf_ue->tai, &ran_ue->saved.tai, sizeof(ogs_5gs_tai_t));
memcpy(&amf_ue->nr_cgi, &ran_ue->saved.nr_cgi, sizeof(ogs_nr_cgi_t));

View File

@ -320,42 +320,78 @@ void ngap_send_amf_ue_context_release_command(
}
}
#if 0
void ngap_send_paging(amf_ue_t *amf_ue, NGAP_CNDomain_t cn_domain)
void ngap_send_paging(amf_ue_t *amf_ue)
{
ogs_pkbuf_t *ngapbuf = NULL;
amf_gnb_t *gnb = NULL;
int i;
int i, j;
int rv;
/* Find enB with matched TAI */
ogs_list_for_each(&amf_self()->gnb_list, gnb) {
for (i = 0; i < gnb->num_of_supported_ta_list; i++) {
for (j = 0; j < gnb->supported_ta_list[i].num_of_bplmn_list; j++) {
if (memcmp(&gnb->supported_ta_list[i].bplmn_list[j].plmn_id,
&amf_ue->tai.plmn_id, OGS_PLMN_ID_LEN) == 0 &&
gnb->supported_ta_list[i].tac.v == amf_ue->tai.tac.v) {
if (memcmp(&gnb->supported_ta_list[i], &amf_ue->tai,
sizeof(ogs_5gs_tai_t)) == 0) {
if (amf_ue->t3513.pkbuf) {
ngapbuf = amf_ue->t3513.pkbuf;
} else {
ngapbuf = ngap_build_paging(amf_ue);
ogs_expect_or_return(ngapbuf);
}
if (amf_ue->t3413.pkbuf) {
ngapbuf = amf_ue->t3413.pkbuf;
} else {
ngapbuf = ngap_build_paging(amf_ue, cn_domain);
ogs_expect_or_return(ngapbuf);
amf_ue->t3513.pkbuf = ogs_pkbuf_copy(ngapbuf);
ogs_assert(amf_ue->t3513.pkbuf);
rv = ngap_send_to_gnb(gnb, ngapbuf, amf_ue->gnb_ostream_id);
ogs_expect(rv == OGS_OK);
}
amf_ue->t3413.pkbuf = ogs_pkbuf_copy(ngapbuf);
ogs_assert(amf_ue->t3413.pkbuf);
rv = ngap_send_to_gnb(gnb, ngapbuf, NGAP_NON_UE_SIGNALLING);
ogs_expect(rv == OGS_OK);
}
}
}
/* Start T3413 */
ogs_timer_start(amf_ue->t3413.timer,
amf_timer_cfg(AMF_TIMER_T3413)->duration);
/* Start T3513 */
ogs_timer_start(amf_ue->t3513.timer,
amf_timer_cfg(AMF_TIMER_T3513)->duration);
}
void ngap_send_pdu_resource_setup_request(
amf_sess_t *sess, ogs_pkbuf_t *n2smbuf)
{
int rv;
ran_ue_t *ran_ue = NULL;
amf_ue_t *amf_ue = NULL;
ogs_pkbuf_t *ngapbuf = NULL;
ogs_assert(sess);
amf_ue = sess->amf_ue;
ogs_assert(amf_ue);
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
ogs_assert(ran_ue);
if (ran_ue->ue_context_requested == true &&
ran_ue->initial_context_setup_request_sent == false) {
ngapbuf = ngap_sess_build_initial_context_setup_request(
sess, NULL, n2smbuf);
ogs_expect_or_return(ngapbuf);
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
ogs_expect_or_return(rv == OGS_OK);
ran_ue->initial_context_setup_request_sent = true;
} else {
ngapbuf = ngap_sess_build_pdu_session_resource_setup_request(
sess, NULL, n2smbuf);
ogs_expect_or_return(ngapbuf);
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
ogs_expect_or_return(rv == OGS_OK);
}
}
#if 0
void ngap_send_amf_configuration_transfer(
amf_gnb_t *target_gnb,
NGAP_SONConfigurationTransfer_t *SONConfigurationTransfer)

View File

@ -60,9 +60,9 @@ void ngap_send_amf_ue_context_release_command(
amf_ue_t *amf_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay);
#if 0
void ngap_send_paging(amf_ue_t *amf_ue, NGAP_CNDomain_t cn_domain);
#endif
void ngap_send_paging(amf_ue_t *amf_ue);
void ngap_send_pdu_resource_setup_request(
amf_sess_t *sess, ogs_pkbuf_t *n2smbuf);
void ngap_send_amf_configuration_transfer(
amf_gnb_t *target_gnb,

View File

@ -182,8 +182,7 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_update_sm_context(
message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST;
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION;
message.h.api.version = (char *)OGS_SBI_API_V1;
message.h.resource.component[0] =
(char *)OGS_SBI_RESOURCE_NAME_SM_CONTEXTS;
message.h.resource.component[0] = (char *)OGS_SBI_RESOURCE_NAME_SM_CONTEXTS;
message.h.resource.component[1] = sess->sm_context_ref;
message.h.resource.component[2] = (char *)OGS_SBI_RESOURCE_NAME_MODIFY;
@ -317,3 +316,48 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_release_sm_context(
return request;
}
ogs_sbi_request_t *amf_nsmf_callback_build_n1_n2_failure_notify(
amf_sess_t *sess, OpenAPI_n1_n2_message_transfer_cause_e cause)
{
ogs_sbi_message_t message;
ogs_sbi_request_t *request = NULL;
OpenAPI_n1_n2_msg_txfr_failure_notification_t
N1N2MsgTxfrFailureNotification;
ogs_assert(sess);
ogs_assert(sess->paging.ongoing == true);
ogs_assert(sess->paging.location);
ogs_assert(sess->paging.n1n2_failure_txf_notif_uri);
ogs_assert(cause);
memset(&message, 0, sizeof(message));
message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST;
message.h.uri = sess->paging.n1n2_failure_txf_notif_uri;
memset(&N1N2MsgTxfrFailureNotification,
0, sizeof(N1N2MsgTxfrFailureNotification));
N1N2MsgTxfrFailureNotification.cause = cause;
if (sess->paging.location) {
N1N2MsgTxfrFailureNotification.n1n2_msg_data_uri =
sess->paging.location;
} else {
/* TS29.518 6.1.6.2.30 Type: N1N2MsgTxfrFailureNotification
*
* If no Location header was returned when the N1/N2
* message transfer was initiated, e.g. when a 200 OK
* response was sent for a UE in RRC inactive state,
* this IE shall be set to a dummy URI, i.e. an URI with
* no authority and an empty path (e.g. "http:").
*/
N1N2MsgTxfrFailureNotification.n1n2_msg_data_uri = (char *)"http:";
}
message.N1N2MsgTxfrFailureNotification = &N1N2MsgTxfrFailureNotification;
request = ogs_sbi_build_request(&message);
ogs_assert(request);
return request;
}

View File

@ -52,6 +52,9 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_update_sm_context(
ogs_sbi_request_t *amf_nsmf_pdu_session_build_release_sm_context(
amf_sess_t *sess, void *data);
ogs_sbi_request_t *amf_nsmf_callback_build_n1_n2_failure_notify(
amf_sess_t *sess, OpenAPI_n1_n2_message_transfer_cause_e cause);
#ifdef __cplusplus
}
#endif

View File

@ -193,40 +193,41 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
* To Deliver N2 SM Content to gNB Temporarily,
* Store N2 SM Context in Session Context
*/
if (sess->transfer.pdu_session_resource_setup_request) {
/*
* It should not be reached this way.
* If the problem occurred, free the old n2smbuf
*/
ogs_error("[%s:%d] N2 SM Content is duplicated",
amf_ue->supi, sess->psi);
ogs_pkbuf_free(
sess->transfer.pdu_session_resource_setup_request);
}
/*
* NOTE : The pkbuf created in the SBI message will be removed
* from ogs_sbi_message_free().
* So it must be copied and push a event queue.
*/
sess->transfer.pdu_session_resource_setup_request =
ogs_pkbuf_copy(n2smbuf);
ogs_assert(sess->transfer.pdu_session_resource_setup_request);
AMF_SESS_STORE_N2_TRANSFER(
sess, pdu_session_resource_setup_request,
ogs_pkbuf_copy(n2smbuf));
if (SESSION_SYNC_DONE(amf_ue)) {
nas_5gs_send_accept(amf_ue);
switch(amf_ue->nas.message_type) {
case OGS_NAS_5GS_REGISTRATION_REQUEST:
if (SESSION_SYNC_DONE(amf_ue,
AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) &&
SESSION_SYNC_DONE(amf_ue,
AMF_UPDATE_SM_CONTEXT_ACTIVATING)) {
nas_5gs_send_registration_accept(amf_ue);
/*
* After sending accept message, N2 SM context is freed
* For checking memory, NULL pointer should be set to n2smbuf.
*/
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (sess->transfer.pdu_session_resource_setup_request) {
ogs_pkbuf_free(sess->
transfer.pdu_session_resource_setup_request);
sess->transfer.pdu_session_resource_setup_request =
NULL;
}
/* After sending accept message,
* N2 tranfer message is freed */
AMF_UE_CLEAR_N2_TRANSFER(
amf_ue, pdu_session_resource_setup_request);
}
break;
case OGS_NAS_5GS_SERVICE_REQUEST:
if (SESSION_SYNC_DONE(amf_ue,
AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) &&
SESSION_SYNC_DONE(amf_ue,
AMF_UPDATE_SM_CONTEXT_ACTIVATING)) {
nas_5gs_send_service_accept(amf_ue);
/* After sending accept message,
* N2 tranfer message is freed */
AMF_UE_CLEAR_N2_TRANSFER(
amf_ue, pdu_session_resource_setup_request);
}
break;
default:
ogs_error("Unknown message type [%d]",
amf_ue->nas.message_type);
ogs_assert_if_reached();
}
break;
@ -274,38 +275,15 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
* To Deliver N2 SM Content to gNB Temporarily,
* Store N2 SM Context in Session Context
*/
if (sess->transfer.path_switch_request_ack) {
/*
* It should not be reached this way.
* If the problem occurred, free the old n2smbuf
*/
ogs_error("[%s:%d] N2 SM Content is duplicated",
amf_ue->supi, sess->psi);
ogs_pkbuf_free(sess->transfer.path_switch_request_ack);
}
/*
* NOTE : The pkbuf created in the SBI message will be removed
* from ogs_sbi_message_free().
* So it must be copied and push a event queue.
*/
sess->transfer.path_switch_request_ack =
ogs_pkbuf_copy(n2smbuf);
ogs_assert(sess->transfer.path_switch_request_ack);
AMF_SESS_STORE_N2_TRANSFER(
sess, path_switch_request_ack,
ogs_pkbuf_copy(n2smbuf));
if (SESSION_SYNC_DONE(amf_ue)) {
if (SESSION_SYNC_DONE(amf_ue, state)) {
ngap_send_path_switch_ack(sess);
/*
* After sending ack message, N2 SM context is freed
* For checking memory, NULL pointer should be set to n2smbuf.
*/
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (sess->transfer.path_switch_request_ack) {
ogs_pkbuf_free(
sess->transfer.path_switch_request_ack);
sess->transfer.path_switch_request_ack = NULL;
}
}
/* After sending ack message, N2 SM context is freed */
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, path_switch_request_ack);
}
break;
@ -351,7 +329,7 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
* 6. UEContextReleaseComplete
*/
if (SESSION_SYNC_DONE(amf_ue)) {
if (SESSION_SYNC_DONE(amf_ue, state)) {
ngap_send_amf_ue_context_release_command(amf_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_NG_REMOVE_AND_UNLINK, 0);
@ -360,6 +338,7 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
} else if (state == AMF_UPDATE_SM_CONTEXT_ACTIVATING) {
/* Not reached here */
ogs_assert_if_reached();
} else if (state == AMF_UPDATE_SM_CONTEXT_N2_RELEASED) {
@ -394,7 +373,7 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
*/
/* Nothing to do */
if (SESSION_SYNC_DONE(amf_ue)) {
if (SESSION_SYNC_DONE(amf_ue, state)) {
ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue);
if (ran_ue) {
ogs_debug(" SUPI[%s]", amf_ue->supi);
@ -421,7 +400,7 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
ogs_debug("[%s:%d] SM context remove", amf_ue->supi, sess->psi);
amf_nsmf_pdu_session_handle_release_sm_context(
sess, AMF_RELEASE_SM_CONTEXT_NO_STATE);
sess, AMF_SESS_SM_CONTEXT_NO_STATE);
}
}
} else {
@ -510,92 +489,112 @@ int amf_nsmf_pdu_session_handle_release_sm_context(amf_sess_t *sess, int state)
amf_sess_remove(sess);
/* Check last session */
if (ogs_list_count(&amf_ue->sess_list) == 0) {
if (state == AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE) {
/*
* 1. Initial context setup failure
* 2. Release All SM contexts
* 3. UE Context release command
* 4. UE Context release complete
*/
ngap_send_amf_ue_context_release_command(amf_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0);
} else if (state == AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) {
/*
* 1. Registration request
* 2. Release All SM contexts
* 3. Registration accept
*/
if (state == AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) {
/*
* 1. Registration request
* 2. Release All SM contexts
* 3. Registration accept
*/
if (SESSION_SYNC_DONE(amf_ue,
AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) &&
SESSION_SYNC_DONE(amf_ue, AMF_UPDATE_SM_CONTEXT_ACTIVATING))
nas_5gs_send_registration_accept(amf_ue);
} else if (state == AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) {
/*
* 1. Service request
* 2. Release All SM contexts
* 3. Service accept
*/
} else if (state == AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) {
/*
* 1. Service request
* 2. Release All SM contexts
* 3. Service accept
*/
if (SESSION_SYNC_DONE(amf_ue, AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) &&
SESSION_SYNC_DONE(amf_ue, AMF_UPDATE_SM_CONTEXT_ACTIVATING))
nas_5gs_send_service_accept(amf_ue);
} else {
/* NO_STATE */
} else {
if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_authentication)) {
/* Check last session */
if (ogs_list_count(&amf_ue->sess_list) == 0) {
amf_ue_sbi_discover_and_send(OpenAPI_nf_type_AUSF, amf_ue, NULL,
amf_nausf_auth_build_authenticate);
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_de_registered)) {
if (state == AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE) {
/*
* 1. PDU session release request
* 2. PDUSessionResourceReleaseCommand +
* PDU session release command
* 3. PDUSessionResourceReleaseREsponse
* 4. PDU session release complete
* 5. Deregistration request
* 6. UEContextReleaseCommand
* 7. UEContextReleaseComplete
*/
nas_5gs_send_de_registration_accept(amf_ue);
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_registered)) {
/*
* 1. PDU session release request
* 2. PDUSessionResourceReleaseCommand +
* PDU session release command
* 3. PDUSessionResourceReleaseREsponse
* 4. PDU session release complete
*
* No Deregistration request in the above step
*
* So, Nothing to do!
*/
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_exception)) {
/*
* 1. GMM Exception
* 1. Initial context setup failure
* 2. Release All SM contexts
* 3. UE Context release command
* 4. UE Context release complete
*/
ngap_send_amf_ue_context_release_command(amf_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0);
} else if (OGS_FSM_CHECK(&amf_ue->sm,
gmm_state_initial_context_setup)) {
ogs_fatal("Release SM Context in initial-context-setup");
} else if (state == AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) {
/* Not reached here */
ogs_assert_if_reached();
} else if (OGS_FSM_CHECK(
&amf_ue->sm, gmm_state_security_mode)) {
ogs_fatal("Release SM Context in security-mode");
} else if (state == AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) {
/* Not reached here */
ogs_assert_if_reached();
} else {
ogs_fatal("Release SM Context : INVALID STATE");
ogs_assert_if_reached();
/* NO_STATE */
if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_authentication)) {
amf_ue_sbi_discover_and_send(
OpenAPI_nf_type_AUSF, amf_ue, NULL,
amf_nausf_auth_build_authenticate);
} else if (OGS_FSM_CHECK(&amf_ue->sm,
gmm_state_de_registered)) {
/*
* 1. PDU session release request
* 2. PDUSessionResourceReleaseCommand +
* PDU session release command
* 3. PDUSessionResourceReleaseREsponse
* 4. PDU session release complete
* 5. Deregistration request
* 6. UEContextReleaseCommand
* 7. UEContextReleaseComplete
*/
nas_5gs_send_de_registration_accept(amf_ue);
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_registered)) {
/*
* 1. PDU session release request
* 2. PDUSessionResourceReleaseCommand +
* PDU session release command
* 3. PDUSessionResourceReleaseREsponse
* 4. PDU session release complete
*
* No Deregistration request in the above step
*
* So, Nothing to do!
*/
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_exception)) {
/*
* 1. GMM Exception
* 2. Release All SM contexts
* 3. UE Context release command
* 4. UE Context release complete
*/
ngap_send_amf_ue_context_release_command(amf_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
} else if (OGS_FSM_CHECK(&amf_ue->sm,
gmm_state_initial_context_setup)) {
ogs_fatal("Release SM Context in initial-context-setup");
ogs_assert_if_reached();
} else if (OGS_FSM_CHECK(
&amf_ue->sm, gmm_state_security_mode)) {
ogs_fatal("Release SM Context in security-mode");
ogs_assert_if_reached();
} else {
ogs_fatal("Release SM Context : INVALID STATE");
ogs_assert_if_reached();
}
}
}
}

View File

@ -25,15 +25,14 @@
int amf_nudm_sdm_handle_provisioned(
amf_ue_t *amf_ue, ogs_sbi_message_t *recvmsg)
{
int i;
ogs_assert(amf_ue);
ogs_assert(recvmsg);
SWITCH(recvmsg->h.resource.component[1])
CASE(OGS_SBI_RESOURCE_NAME_AM_DATA)
if (recvmsg->AccessAndMobilitySubscriptionData) {
OpenAPI_ambr_rm_t *ue_ambr =
recvmsg->AccessAndMobilitySubscriptionData->
subscribed_ue_ambr;
OpenAPI_list_t *gpsiList =
recvmsg->AccessAndMobilitySubscriptionData->gpsis;
OpenAPI_ambr_rm_t *SubscribedUeAmbr =
@ -42,15 +41,14 @@ int amf_nudm_sdm_handle_provisioned(
recvmsg->AccessAndMobilitySubscriptionData->subscribed_dnn_list;
OpenAPI_lnode_t *node = NULL;
if (ue_ambr) {
amf_ue->ue_ambr.uplink =
ogs_sbi_bitrate_from_string(ue_ambr->uplink);
amf_ue->ue_ambr.downlink =
ogs_sbi_bitrate_from_string(ue_ambr->downlink);
/* Clear MSISDN */
for (i = 0; i < amf_ue->num_of_msisdn; i++) {
ogs_assert(amf_ue->msisdn[i]);
ogs_free(amf_ue->msisdn[i]);
}
amf_ue->num_of_msisdn = 0;
if (gpsiList) {
amf_ue->num_of_msisdn = 0;
OpenAPI_list_for_each(gpsiList, node) {
if (node->data) {
char *gpsi = NULL;
@ -75,6 +73,10 @@ int amf_nudm_sdm_handle_provisioned(
}
}
/* Clear Subscribed-UE-AMBR */
amf_ue->ue_ambr.uplink = 0;
amf_ue->ue_ambr.downlink = 0;
if (SubscribedUeAmbr) {
amf_ue->ue_ambr.uplink =
ogs_sbi_bitrate_from_string(SubscribedUeAmbr->uplink);
@ -82,6 +84,13 @@ int amf_nudm_sdm_handle_provisioned(
ogs_sbi_bitrate_from_string(SubscribedUeAmbr->downlink);
}
/* Clear Subscribed-DNN */
for (i = 0; i < amf_ue->num_of_subscribed_dnn; i++) {
ogs_assert(amf_ue->subscribed_dnn[i]);
ogs_free(amf_ue->subscribed_dnn[i]);
}
amf_ue->num_of_subscribed_dnn = 0;
if (SubscribedDnnList) {
OpenAPI_list_for_each(SubscribedDnnList, node) {
if (node->data) {

View File

@ -273,3 +273,44 @@ void amf_sbi_send_release_all_sessions(amf_ue_t *amf_ue, int state)
amf_sbi_send_release_session(sess, state);
}
}
static int client_notify_cb(ogs_sbi_response_t *response, void *data)
{
int rv;
ogs_sbi_message_t message;
ogs_assert(response);
rv = ogs_sbi_parse_response(&message, response);
if (rv != OGS_OK) {
ogs_error("cannot parse HTTP response");
ogs_sbi_message_free(&message);
ogs_sbi_response_free(response);
return OGS_ERROR;
}
if (message.res_status != OGS_SBI_HTTP_STATUS_NO_CONTENT)
ogs_error("N1-N2-Message Transfer Failure Notification failed [%d]",
message.res_status);
ogs_sbi_message_free(&message);
ogs_sbi_response_free(response);
return OGS_OK;
}
void amf_sbi_send_n1_n2_failure_notify(
amf_sess_t *sess, OpenAPI_n1_n2_message_transfer_cause_e cause)
{
ogs_sbi_request_t *request = NULL;
ogs_sbi_client_t *client = NULL;
ogs_assert(cause);
ogs_assert(sess);
client = sess->paging.client;
ogs_assert(client);
request = amf_nsmf_callback_build_n1_n2_failure_notify(sess, cause);
ogs_assert(request);
ogs_sbi_client_send_request(client, client_notify_cb, request, NULL);
}

View File

@ -37,14 +37,17 @@ void amf_ue_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
amf_ue_t *amf_ue, void *data,
ogs_sbi_request_t *(*build)(amf_ue_t *amf_ue, void *data));
#define AMF_UPDATE_SM_CONTEXT_NO_STATE 0
#define AMF_UPDATE_SM_CONTEXT_ACTIVATED 1
#define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 2
#define AMF_UPDATE_SM_CONTEXT_ACTIVATING 3
#define AMF_UPDATE_SM_CONTEXT_MODIFIED 4
#define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 5
#define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 6
#define AMF_UPDATE_SM_CONTEXT_NG_RESET 7
#define AMF_SESS_SM_CONTEXT_NO_STATE 0
#define AMF_UPDATE_SM_CONTEXT_ACTIVATED 1
#define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 2
#define AMF_UPDATE_SM_CONTEXT_ACTIVATING 3
#define AMF_UPDATE_SM_CONTEXT_MODIFIED 4
#define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 5
#define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 6
#define AMF_UPDATE_SM_CONTEXT_NG_RESET 7
#define AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE 8
#define AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT 9
#define AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT 10
void amf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
amf_sess_t *sess, int state, void *data,
ogs_sbi_request_t *(*build)(amf_sess_t *sess, void *data));
@ -57,13 +60,12 @@ void amf_sbi_send_deactivate_all_sessions(
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);
#define AMF_RELEASE_SM_CONTEXT_NO_STATE 0
#define AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE 1
#define AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT 2
#define AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT 3
void amf_sbi_send_release_session(amf_sess_t *sess, int state);
void amf_sbi_send_release_all_sessions(amf_ue_t *amf_ue, int state);
void amf_sbi_send_n1_n2_failure_notify(
amf_sess_t *sess, OpenAPI_n1_n2_message_transfer_cause_e cause);
#ifdef __cplusplus
}
#endif

View File

@ -99,7 +99,8 @@ int emm_handle_attach_request(mme_ue_t *mme_ue,
ogs_plmn_id_hexdump(&enb_ue->saved.e_cgi.plmn_id),
enb_ue->saved.e_cgi.cell_id);
/* Copy TAI and ECGI from enb_ue */
/* Copy Stream-No/TAI/ECGI from enb_ue */
mme_ue->enb_ostream_id = enb_ue->enb_ostream_id;
memcpy(&mme_ue->tai, &enb_ue->saved.tai, sizeof(ogs_eps_tai_t));
memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));
@ -489,7 +490,8 @@ int emm_handle_tau_request(mme_ue_t *mme_ue,
ogs_plmn_id_hexdump(&enb_ue->saved.e_cgi.plmn_id),
enb_ue->saved.e_cgi.cell_id);
/* Copy TAI and ECGI from enb_ue */
/* Copy Stream-No/TAI/ECGI from enb_ue */
mme_ue->enb_ostream_id = enb_ue->enb_ostream_id;
memcpy(&mme_ue->tai, &enb_ue->saved.tai, sizeof(ogs_eps_tai_t));
memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));
@ -605,7 +607,8 @@ int emm_handle_extended_service_request(mme_ue_t *mme_ue,
ogs_plmn_id_hexdump(&enb_ue->saved.e_cgi.plmn_id),
enb_ue->saved.e_cgi.cell_id);
/* Copy TAI and ECGI from enb_ue */
/* Copy Stream-No/TAI/ECGI from enb_ue */
mme_ue->enb_ostream_id = enb_ue->enb_ostream_id;
memcpy(&mme_ue->tai, &enb_ue->saved.tai, sizeof(ogs_eps_tai_t));
memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));

View File

@ -325,6 +325,7 @@ struct mme_ue_s {
uint16_t vlr_ostream_id; /* SCTP output stream id for VLR */
/* UE Info */
uint16_t enb_ostream_id;
ogs_eps_tai_t tai;
ogs_e_cgi_t e_cgi;
ogs_plmn_id_t last_visited_plmn_id;

View File

@ -200,12 +200,11 @@ ogs_pkbuf_t *s1ap_build_downlink_nas_transport(
ogs_assert(emmbuf);
ogs_assert(enb_ue);
ogs_debug("[MME] DownlinkNASTransport");
ogs_debug("DownlinkNASTransport");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
@ -288,12 +287,11 @@ ogs_pkbuf_t *s1ap_build_initial_context_setup_request(
subscription_data = &mme_ue->subscription_data;
ogs_assert(subscription_data);
ogs_debug("[MME] Initial context setup request");
ogs_debug("Initial context setup request");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
@ -641,12 +639,11 @@ ogs_pkbuf_t *s1ap_build_ue_context_modification_request(mme_ue_t *mme_ue)
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_assert(enb_ue);
ogs_debug("[MME] UE context modification request");
ogs_debug("UE context modification request");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
@ -782,8 +779,7 @@ ogs_pkbuf_t *s1ap_build_ue_context_release_command(
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_UEContextRelease;
@ -864,8 +860,7 @@ ogs_pkbuf_t *s1ap_build_e_rab_setup_request(
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_E_RABSetup;
@ -994,11 +989,10 @@ ogs_pkbuf_t *s1ap_build_e_rab_modify_request(
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_assert(enb_ue);
ogs_debug("[MME] E-RAB modify request");
ogs_debug("E-RAB modify request");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_E_RABModify;
@ -1125,12 +1119,11 @@ ogs_pkbuf_t *s1ap_build_e_rab_release_command(
subscription_data = &mme_ue->subscription_data;
ogs_assert(subscription_data);
ogs_debug("[MME] E-RAB release command");
ogs_debug("E-RAB release command");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_E_RABRelease;
@ -1250,12 +1243,11 @@ ogs_pkbuf_t *s1ap_build_paging(
ogs_assert(mme_ue);
ogs_debug("[MME] Paging");
ogs_debug("Paging");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_Paging;
@ -1318,8 +1310,7 @@ ogs_pkbuf_t *s1ap_build_paging(
/* Set Paging Identity */
UEPagingID->present = S1AP_UEPagingID_PR_s_TMSI;
UEPagingID->choice.s_TMSI =
CALLOC(1, sizeof(S1AP_S_TMSI_t));
UEPagingID->choice.s_TMSI = CALLOC(1, sizeof(S1AP_S_TMSI_t));
ogs_asn_uint8_to_OCTET_STRING(mme_ue->guti.mme_code,
&UEPagingID->choice.s_TMSI->mMEC);
@ -1364,12 +1355,11 @@ ogs_pkbuf_t *s1ap_build_mme_configuration_transfer(
ogs_assert(son_configuration_transfer);
ogs_debug("[MME] MME Configuration Transfer");
ogs_debug("MME Configuration Transfer");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
@ -1415,7 +1405,7 @@ ogs_pkbuf_t *s1ap_build_path_switch_ack(mme_ue_t *mme_ue)
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_assert(enb_ue);
ogs_debug("[MME] Path switch acknowledge");
ogs_debug("Path switch acknowledge");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome;
@ -1492,7 +1482,7 @@ ogs_pkbuf_t *s1ap_build_path_switch_failure(
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
S1AP_Cause_t *Cause = NULL;
ogs_debug("[MME] Path switch failure");
ogs_debug("Path switch failure");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_unsuccessfulOutcome;
@ -1574,7 +1564,7 @@ ogs_pkbuf_t *s1ap_build_handover_command(enb_ue_t *source_ue)
ogs_assert(source_ue);
mme_ue = source_ue->mme_ue;
ogs_debug("[MME] Handover command");
ogs_debug("Handover command");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome;
@ -1732,7 +1722,7 @@ ogs_pkbuf_t *s1ap_build_handover_preparation_failure(
ogs_assert(source_ue);
ogs_assert(cause);
ogs_debug("[MME] Handover preparation failure");
ogs_debug("Handover preparation failure");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_unsuccessfulOutcome;
@ -1830,12 +1820,11 @@ ogs_pkbuf_t *s1ap_build_handover_request(
subscription_data = &mme_ue->subscription_data;
ogs_assert(subscription_data);
ogs_debug("[MME] Handover request");
ogs_debug("Handover request");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
@ -2040,7 +2029,7 @@ ogs_pkbuf_t *s1ap_build_handover_cancel_ack(enb_ue_t *source_ue)
ogs_assert(source_ue);
ogs_debug("[MME] Handover cancel acknowledge");
ogs_debug("Handover cancel acknowledge");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome;
@ -2105,12 +2094,11 @@ ogs_pkbuf_t *s1ap_build_mme_status_transfer(
ogs_assert(target_ue);
ogs_assert(enb_statustransfer_transparentContainer);
ogs_debug("[MME] MME status transfer");
ogs_debug("MME status transfer");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_MMEStatusTransfer;
@ -2178,14 +2166,13 @@ ogs_pkbuf_t *s1ap_build_write_replace_warning_request(sbc_pws_data_t *sbc_pws)
S1AP_DataCodingScheme_t *DataCodingScheme = NULL;
S1AP_WarningMessageContents_t *WarningMessageContents = NULL;
ogs_debug("[MME] Write-replace warning request");
ogs_debug("Write-replace warning request");
ogs_assert(sbc_pws);
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
@ -2316,14 +2303,13 @@ ogs_pkbuf_t *s1ap_build_kill_request(sbc_pws_data_t *sbc_pws)
S1AP_MessageIdentifier_t *MessageIdentifier = NULL;
S1AP_SerialNumber_t *SerialNumber = NULL;
ogs_debug("[MME] Kill request");
ogs_debug("Kill request");
ogs_assert(sbc_pws);
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_Kill;

View File

@ -1331,7 +1331,8 @@ void s1ap_handle_path_switch_request(
ogs_plmn_id_hexdump(&enb_ue->saved.e_cgi.plmn_id),
enb_ue->saved.e_cgi.cell_id);
/* Copy TAI and ECGI from enb_ue */
/* Copy Stream-No/TAI/ECGI from enb_ue */
mme_ue->enb_ostream_id = enb_ue->enb_ostream_id;
memcpy(&mme_ue->tai, &enb_ue->saved.tai, sizeof(ogs_eps_tai_t));
memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));
@ -2046,7 +2047,8 @@ void s1ap_handle_handover_notification(
ogs_plmn_id_hexdump(&target_ue->saved.e_cgi.plmn_id),
target_ue->saved.e_cgi.cell_id);
/* Copy TAI and ECGI from enb_ue */
/* Copy Stream-No/TAI/ECGI from enb_ue */
mme_ue->enb_ostream_id = target_ue->enb_ostream_id;
memcpy(&mme_ue->tai, &target_ue->saved.tai, sizeof(ogs_eps_tai_t));
memcpy(&mme_ue->e_cgi, &target_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));

View File

@ -341,7 +341,7 @@ void s1ap_send_paging(mme_ue_t *mme_ue, S1AP_CNDomain_t cn_domain)
mme_ue->t3413.pkbuf = ogs_pkbuf_copy(s1apbuf);
ogs_assert(mme_ue->t3413.pkbuf);
rv = s1ap_send_to_enb(enb, s1apbuf, S1AP_NON_UE_SIGNALLING);
rv = s1ap_send_to_enb(enb, s1apbuf, mme_ue->enb_ostream_id);
ogs_expect(rv == OGS_OK);
}
}

View File

@ -687,7 +687,7 @@ sgwc_bearer_t *sgwc_bearer_find_by_error_indication_report(
sgwc_sess_t *sess,
ogs_pfcp_tlv_error_indication_report_t *error_indication_report)
{
ogs_pfcp_f_teid_t *remote_f_teid;
ogs_pfcp_f_teid_t *remote_f_teid = NULL;
sgwc_bearer_t *bearer = NULL;
sgwc_tunnel_t *tunnel = NULL;

View File

@ -75,6 +75,7 @@ void smf_context_init(void)
self.imsi_hash = ogs_hash_make();
self.ipv4_hash = ogs_hash_make();
self.ipv6_hash = ogs_hash_make();
self.n1n2message_hash = ogs_hash_make();
context_initialized = 1;
}
@ -93,6 +94,8 @@ void smf_context_final(void)
ogs_hash_destroy(self.ipv4_hash);
ogs_assert(self.ipv6_hash);
ogs_hash_destroy(self.ipv6_hash);
ogs_assert(self.n1n2message_hash);
ogs_hash_destroy(self.n1n2message_hash);
ogs_pool_final(&smf_ue_pool);
ogs_pool_final(&smf_bearer_pool);
@ -1011,6 +1014,91 @@ void smf_sess_set_ue_ip(smf_sess_t *sess)
}
}
void smf_sess_set_paging_n1n2message_location(
smf_sess_t *sess, char *n1n2message_location)
{
ogs_assert(sess);
ogs_assert(n1n2message_location);
if (sess->paging.n1n2message_location) {
ogs_hash_set(self.n1n2message_hash,
sess->paging.n1n2message_location,
strlen(sess->paging.n1n2message_location),
NULL);
ogs_free(sess->paging.n1n2message_location);
}
sess->paging.n1n2message_location = ogs_strdup(n1n2message_location);
ogs_assert(sess->paging.n1n2message_location);
ogs_hash_set(self.n1n2message_hash,
sess->paging.n1n2message_location,
strlen(sess->paging.n1n2message_location),
sess);
}
smf_sess_t *smf_sess_find_by_error_indication_report(
smf_ue_t *smf_ue,
ogs_pfcp_tlv_error_indication_report_t *error_indication_report)
{
smf_sess_t *sess = NULL;
ogs_pfcp_f_teid_t *remote_f_teid = NULL;
uint32_t teid;
uint16_t len; /* OGS_IPV4_LEN or OGS_IPV6_LEN */
uint32_t addr[4];
ogs_assert(smf_ue);
ogs_assert(error_indication_report);
if (error_indication_report->presence == 0) {
ogs_error("No Error Indication Report");
return NULL;
}
if (error_indication_report->remote_f_teid.presence == 0) {
ogs_error("No Remote F-TEID");
return NULL;
}
remote_f_teid = error_indication_report->remote_f_teid.data;
ogs_assert(remote_f_teid);
teid = be32toh(remote_f_teid->teid);
if (remote_f_teid->ipv4 && remote_f_teid->ipv6) {
ogs_error("User plane should not set both IPv4 and IPv6");
return NULL;
} else if (remote_f_teid->ipv4) {
len = OGS_IPV4_LEN;
memcpy(addr, &remote_f_teid->addr, len);
} else if (remote_f_teid->ipv6) {
len = OGS_IPV6_LEN;
memcpy(addr, remote_f_teid->addr6, len);
} else {
ogs_error("No IPv4 and IPv6");
return NULL;
}
ogs_list_for_each(&smf_ue->sess_list, sess) {
if (teid == sess->gnb_n3_teid) {
if (len == OGS_IPV4_LEN && sess->gnb_n3_ip.ipv4 &&
memcmp(addr, &sess->gnb_n3_ip.addr, len) == 0) {
return sess;
} else if (len == OGS_IPV6_LEN && sess->gnb_n3_ip.ipv6 &&
memcmp(addr, sess->gnb_n3_ip.addr6, len) == 0) {
return sess;
}
}
}
ogs_error("Cannot find the session context "
"[TEID:%d,LEN:%d,ADDR:%08x %08x %08x %08x]",
teid, len, be32toh(addr[0]), be32toh(addr[1]),
be32toh(addr[2]), be32toh(addr[3]));
return NULL;
}
void smf_sess_remove(smf_sess_t *sess)
{
int i;
@ -1056,6 +1144,14 @@ void smf_sess_remove(smf_sess_t *sess)
ogs_pfcp_ue_ip_free(sess->ipv6);
}
if (sess->paging.n1n2message_location) {
ogs_hash_set(self.n1n2message_hash,
sess->paging.n1n2message_location,
strlen(sess->paging.n1n2message_location),
NULL);
ogs_free(sess->paging.n1n2message_location);
}
if (sess->sm_context_ref)
ogs_free(sess->sm_context_ref);
@ -1171,6 +1267,15 @@ smf_sess_t *smf_sess_find_by_ipv6(uint32_t *addr6)
return (smf_sess_t *)ogs_hash_get(self.ipv6_hash, addr6, OGS_IPV6_LEN);
}
smf_sess_t *smf_sess_find_by_paging_n1n2message_location(
char *n1n2message_location)
{
ogs_assert(self.n1n2message_hash);
ogs_assert(n1n2message_location);
return (smf_sess_t *)ogs_hash_get(self.n1n2message_hash,
n1n2message_location, strlen(n1n2message_location));
}
smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess)
{
smf_bearer_t *qos_flow = NULL;

View File

@ -82,6 +82,7 @@ typedef struct smf_context_s {
ogs_hash_t *imsi_hash; /* hash table (IMSI) */
ogs_hash_t *ipv4_hash; /* hash table (IPv4 Address) */
ogs_hash_t *ipv6_hash; /* hash table (IPv6 Address) */
ogs_hash_t *n1n2message_hash; /* hash table (N1N2Message Location) */
uint16_t mtu; /* MTU to advertise in PCO */
@ -273,6 +274,8 @@ typedef struct smf_sess_s {
ogs_tlv_octet_t ue_pco;
ogs_tlv_octet_t user_location_information;
ogs_tlv_octet_t ue_timezone;
bool create_session_response_apn_ambr;
bool create_session_response_bearer_qos;
} gtp; /* Saved from S5-C */
struct {
@ -282,14 +285,23 @@ typedef struct smf_sess_s {
ogs_pcc_rule_t pcc_rule[OGS_MAX_NUM_OF_PCC_RULE]; /* Saved from Gx */
int num_of_pcc_rule;
/* Paging */
struct {
bool create_session_response_apn_ambr;
bool create_session_response_bearer_qos;
} gtp_5gc;
bool ue_requested_pdu_session_establishment_done;
char *n1n2message_location;
} paging;
/* Release Holding timer of SMF session context */
ogs_timer_t *t_release_holding;
/* State */
#define SMF_NGAP_STATE_NONE 0
#define SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED 1
#define SMF_NGAP_STATE_ERROR_INDICATION_RECEIVED_FROM_5G_AN 2
struct {
int pdu_session_resource_release;
} ngap_state;
ogs_list_t bearer_list;
ogs_gtp_node_t *gnode;
@ -319,6 +331,8 @@ smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi);
void smf_sess_select_upf(smf_sess_t *sess);
void smf_sess_set_ue_ip(smf_sess_t *sess);
void smf_sess_set_paging_n1n2message_location(
smf_sess_t *sess, char *n1n2message_location);
void smf_sess_remove(smf_sess_t *sess);
void smf_sess_remove_all(smf_ue_t *smf_ue);
@ -331,6 +345,11 @@ smf_sess_t *smf_sess_find_by_psi(smf_ue_t *smf_ue, uint8_t psi);
smf_sess_t *smf_sess_find_by_sm_context_ref(char *sm_context_ref);
smf_sess_t *smf_sess_find_by_ipv4(uint32_t addr);
smf_sess_t *smf_sess_find_by_ipv6(uint32_t *addr6);
smf_sess_t *smf_sess_find_by_paging_n1n2message_location(
char *n1n2message_location);
smf_sess_t *smf_sess_find_by_error_indication_report(
smf_ue_t *smf_ue,
ogs_pfcp_tlv_error_indication_report_t *error_indication_report);
smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess);
smf_bearer_t *smf_qos_flow_find_by_qfi(smf_sess_t *sess, uint8_t qfi);

View File

@ -26,6 +26,7 @@
#include "gsm-handler.h"
#include "ngap-handler.h"
#include "pfcp-path.h"
#include "ngap-path.h"
void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
{
@ -40,7 +41,7 @@ void smf_gsm_state_final(ogs_fsm_t *s, smf_event_t *e)
void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
{
int rv;
int rv, ngap_state;
char *strerror = NULL;
smf_ue_t *smf_ue = NULL;
smf_sess_t *sess = NULL;
@ -184,13 +185,6 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
SWITCH(sbi_message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXTS)
if (sbi_message->res_status != OGS_SBI_HTTP_STATUS_OK &&
sbi_message->res_status != OGS_SBI_HTTP_STATUS_ACCEPTED) {
ogs_error("[%s:%d] HTTP response error [%d]",
smf_ue->supi, sess->psi, sbi_message->res_status);
break;
}
smf_namf_comm_handler_n1_n2_message_transfer(
sess, e->sbi.state, sbi_message);
break;
@ -206,7 +200,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
DEFAULT
ogs_error("[%s:%d] Invalid API name [%s]",
smf_ue->supi, sess->psi, sbi_message->h.service.name);
ogs_assert_if_reached();
END
break;
@ -269,9 +263,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, strerror, NULL);
ogs_free(strerror);
break;
}
break;
case SMF_EVT_NGAP_MESSAGE:
@ -307,7 +299,33 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
break;
case OpenAPI_n2_sm_info_type_PDU_RES_REL_RSP:
smf_sbi_send_response(stream, OGS_SBI_HTTP_STATUS_NO_CONTENT);
ngap_state = sess->ngap_state.pdu_session_resource_release;
/* Clear NGAP State */
sess->ngap_state.pdu_session_resource_release = SMF_NGAP_STATE_NONE;
if (ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED) {
smf_sbi_send_response(stream, OGS_SBI_HTTP_STATUS_NO_CONTENT);
} else if (ngap_state ==
SMF_NGAP_STATE_ERROR_INDICATION_RECEIVED_FROM_5G_AN) {
smf_n1_n2_message_transfer_param_t param;
smf_sbi_send_response(stream, OGS_SBI_HTTP_STATUS_NO_CONTENT);
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_TRIGGERED_SERVICE_REQUEST;
param.n2smbuf =
ngap_build_pdu_session_resource_setup_request_transfer(
sess);
ogs_assert(param.n2smbuf);
param.n1n2_failure_txf_notif_uri = true;
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
} else {
ogs_fatal("Invalid state [%d]", ngap_state);
ogs_assert_if_reached();
}
break;
case OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ:
@ -323,12 +341,10 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
default:
ogs_error("Unknown message[%d]", e->ngap.type);
}
break;
default:
ogs_error("Unknown event [%s]", smf_event_get_name(e));
break;
}
}

View File

@ -77,7 +77,7 @@ void smf_gx_handle_cca_initial_request(
/* APN-AMBR
* if PCRF changes APN-AMBR, this should be included. */
sess->gtp_5gc.create_session_response_apn_ambr = false;
sess->gtp.create_session_response_apn_ambr = false;
if ((gx_message->session_data.pdn.ambr.uplink &&
(sess->pdn.ambr.uplink / 1000) !=
(gx_message->session_data.pdn.ambr.uplink / 1000)) ||
@ -88,12 +88,12 @@ void smf_gx_handle_cca_initial_request(
sess->pdn.ambr.downlink = gx_message->session_data.pdn.ambr.downlink;
sess->pdn.ambr.uplink = gx_message->session_data.pdn.ambr.uplink;
sess->gtp_5gc.create_session_response_apn_ambr = true;
sess->gtp.create_session_response_apn_ambr = true;
}
/* Bearer QoS
* if PCRF changes Bearer QoS, this should be included. */
sess->gtp_5gc.create_session_response_bearer_qos = false;
sess->gtp.create_session_response_bearer_qos = false;
if ((gx_message->session_data.pdn.qos.qci &&
sess->pdn.qos.qci != gx_message->session_data.pdn.qos.qci) ||
(gx_message->session_data.pdn.qos.arp.priority_level &&
@ -112,7 +112,7 @@ void smf_gx_handle_cca_initial_request(
sess->pdn.qos.arp.pre_emption_vulnerability =
gx_message->session_data.pdn.qos.arp.pre_emption_vulnerability;
sess->gtp_5gc.create_session_response_bearer_qos = true;
sess->gtp.create_session_response_bearer_qos = true;
}
bearer = smf_default_bearer_in_sess(sess);

View File

@ -64,6 +64,7 @@ static uint8_t gtp_cause_from_pfcp(uint8_t pfcp_cause)
return OGS_GTP_CAUSE_SYSTEM_FAILURE;
}
static int sbi_status_from_pfcp(uint8_t pfcp_cause)
{
switch (pfcp_cause) {
@ -102,8 +103,7 @@ void smf_5gc_n4_handle_session_establishment_response(
{
int i;
ogs_pkbuf_t *n1smbuf = NULL;
ogs_pkbuf_t *n2smbuf = NULL;
smf_n1_n2_message_transfer_param_t param;
ogs_sbi_stream_t *stream = NULL;
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
@ -190,14 +190,15 @@ void smf_5gc_n4_handle_session_establishment_response(
ogs_assert(up_f_seid);
sess->upf_n4_seid = be64toh(up_f_seid->seid);
n1smbuf = gsm_build_pdu_session_establishment_accept(sess);
ogs_assert(n1smbuf);
n2smbuf = ngap_build_pdu_session_resource_setup_request_transfer(sess);
ogs_assert(n2smbuf);
memset(&param, 0, sizeof(param));
param.state = SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT;
param.n1smbuf = gsm_build_pdu_session_establishment_accept(sess);
ogs_assert(param.n1smbuf);
param.n2smbuf = ngap_build_pdu_session_resource_setup_request_transfer(
sess);
ogs_assert(param.n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer(
sess, SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT,
n1smbuf, n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
}
void smf_5gc_n4_handle_session_modification_response(
@ -298,36 +299,51 @@ void smf_5gc_n4_handle_session_modification_response(
}
if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
if (flags & OGS_PFCP_MODIFY_PATH_SWITCH) {
if (flags & OGS_PFCP_MODIFY_PATH_SWITCH) {
ogs_pkbuf_t *n2smbuf =
ngap_build_path_switch_request_ack_transfer(sess);
ogs_assert(n2smbuf);
smf_sbi_send_sm_context_updated_data_with_n2buf(sess, stream,
smf_sbi_send_sm_context_updated_data_n2smbuf(sess, stream,
OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ_ACK, n2smbuf);
} else {
/* ACTIVATED Is NOT Included in RESPONSE */
smf_sbi_send_sm_context_updated_data(sess, stream, 0);
} else {
sess->paging.ue_requested_pdu_session_establishment_done = true;
smf_sbi_send_http_status_no_content(stream);
}
} else if (flags & OGS_PFCP_MODIFY_DEACTIVATE) {
/* Only ACTIVING & DEACTIVATED is Included */
smf_sbi_send_sm_context_updated_data(
sess, stream, OpenAPI_up_cnx_state_DEACTIVATED);
if (flags & OGS_PFCP_MODIFY_ERROR_INDICATION) {
smf_n1_n2_message_transfer_param_t param;
memset(&param, 0, sizeof(param));
param.state = SMF_ERROR_INDICATON_RECEIVED_FROM_5G_AN;
param.n2smbuf =
ngap_build_pdu_session_resource_release_command_transfer(
sess, SMF_NGAP_STATE_ERROR_INDICATION_RECEIVED_FROM_5G_AN,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(param.n2smbuf);
param.skip_ind = true;
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
} else {
/* Only ACTIVING & DEACTIVATED is Included */
smf_sbi_send_sm_context_updated_data_up_cnx_state(
sess, stream, OpenAPI_up_cnx_state_DEACTIVATED);
}
} else if (flags & OGS_PFCP_MODIFY_CREATE) {
ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL;
smf_n1_n2_message_transfer_param_t param;
ogs_assert(qos_flow);
n1smbuf = gsm_build_qos_flow_modification_command(
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION;
param.n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED);
ogs_assert(n1smbuf);
n2smbuf = ngap_build_qos_flow_resource_modify_request_transfer(
ogs_assert(param.n1smbuf);
param.n2smbuf = ngap_build_qos_flow_resource_modify_request_transfer(
qos_flow);
ogs_assert(n2smbuf);
ogs_assert(param.n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer(
sess, SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION,
n1smbuf, n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
}
}
@ -381,9 +397,19 @@ void smf_5gc_n4_handle_session_deletion_response(
ogs_assert(sess);
if (trigger == OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED) {
ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL;
smf_sbi_send_sm_context_updated_data_in_session_deletion(sess, stream);
n1smbuf = gsm_build_pdu_session_release_command(
sess, OGS_5GSM_CAUSE_REGULAR_DEACTIVATION);
ogs_assert(n1smbuf);
n2smbuf = ngap_build_pdu_session_resource_release_command_transfer(
sess, SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(n2smbuf);
smf_sbi_send_sm_context_updated_data_n1_n2_message(sess, stream,
n1smbuf, OpenAPI_n2_sm_info_type_PDU_RES_REL_CMD, n2smbuf);
} else {
memset(&sendmsg, 0, sizeof(sendmsg));
@ -643,3 +669,143 @@ void smf_epc_n4_handle_session_deletion_response(
SMF_SESS_CLEAR(sess);
}
void smf_n4_handle_session_report_request(
smf_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact,
ogs_pfcp_session_report_request_t *pfcp_req)
{
smf_bearer_t *qos_flow = NULL;
ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_report_type_t report_type;
uint8_t cause_value = 0;
uint16_t pdr_id = 0;
ogs_assert(pfcp_xact);
ogs_assert(pfcp_req);
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
}
if (pfcp_req->report_type.presence == 0) {
ogs_error("No Report Type");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_pfcp_send_error_message(pfcp_xact, 0,
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
cause_value, 0);
return;
}
ogs_assert(sess);
report_type.value = pfcp_req->report_type.u8;
if (report_type.downlink_data_report) {
ogs_pfcp_downlink_data_service_information_t *info = NULL;
uint8_t paging_policy_indication_value = 0;
uint8_t qfi = 0;
if (pfcp_req->downlink_data_report.presence) {
if (pfcp_req->downlink_data_report.
downlink_data_service_information.presence) {
info = pfcp_req->downlink_data_report.
downlink_data_service_information.data;
if (info) {
if (info->qfii && info->ppi) {
paging_policy_indication_value =
info->paging_policy_indication_value;
qfi = info->qfi;
} else if (info->qfii) {
qfi = info->qfi;
} else if (info->ppi) {
paging_policy_indication_value =
info->paging_policy_indication_value;
} else {
ogs_error("Invalid Downlink Data Service Information");
}
if (paging_policy_indication_value) {
ogs_warn("Not implement - "
"Paging Policy Indication Value");
ogs_pfcp_send_error_message(pfcp_xact, 0,
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
OGS_GTP_CAUSE_SERVICE_NOT_SUPPORTED, 0);
return;
}
if (qfi) {
qos_flow = smf_qos_flow_find_by_qfi(sess, qfi);
if (!qos_flow)
ogs_error("Cannot find the QoS Flow[%d]", qfi);
}
} else {
ogs_error("No Info");
}
}
if (pfcp_req->downlink_data_report.pdr_id.presence) {
pdr = ogs_pfcp_pdr_find(&sess->pfcp,
pfcp_req->downlink_data_report.pdr_id.u16);
if (!pdr)
ogs_error("Cannot find the PDR-ID[%d]", pdr_id);
} else {
ogs_error("No PDR-ID");
}
} else {
ogs_error("No Downlink Data Report");
}
if (!pdr || !qos_flow) {
ogs_error("No Context [%p:%p]", pdr, qos_flow);
ogs_pfcp_send_error_message(pfcp_xact, 0,
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
cause_value, 0);
}
smf_pfcp_send_session_report_response(
pfcp_xact, sess, OGS_PFCP_CAUSE_REQUEST_ACCEPTED);
if (sess->paging.ue_requested_pdu_session_establishment_done == true) {
smf_n1_n2_message_transfer_param_t param;
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_TRIGGERED_SERVICE_REQUEST;
param.n2smbuf =
ngap_build_pdu_session_resource_setup_request_transfer(sess);
ogs_assert(param.n2smbuf);
param.n1n2_failure_txf_notif_uri = true;
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
}
} else if (report_type.error_indication_report) {
smf_ue_t *smf_ue = sess->smf_ue;
smf_sess_t *error_indication_session = NULL;
ogs_assert(smf_ue);
smf_pfcp_send_session_report_response(
pfcp_xact, sess, OGS_PFCP_CAUSE_REQUEST_ACCEPTED);
error_indication_session = smf_sess_find_by_error_indication_report(
smf_ue, &pfcp_req->error_indication_report);
if (!error_indication_session) return;
smf_5gc_pfcp_send_session_modification_request(
error_indication_session, NULL,
OGS_PFCP_MODIFY_DEACTIVATE|OGS_PFCP_MODIFY_ERROR_INDICATION);
} else {
ogs_error("Not supported Report Type[%d]", report_type.value);
smf_pfcp_send_session_report_response(
pfcp_xact, sess, OGS_PFCP_CAUSE_SYSTEM_FAILURE);
}
}

View File

@ -46,6 +46,10 @@ void smf_epc_n4_handle_session_deletion_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_deletion_response_t *rsp);
void smf_n4_handle_session_report_request(
smf_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact,
ogs_pfcp_session_report_request_t *pfcp_req);
#ifdef __cplusplus
}
#endif

View File

@ -22,7 +22,7 @@
#include "ngap-build.h"
ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
smf_sess_t *sess, smf_n1_n2_message_transfer_data_t *data)
smf_sess_t *sess, smf_n1_n2_message_transfer_param_t *param)
{
int i;
smf_ue_t *smf_ue = NULL;
@ -30,6 +30,9 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
ogs_sbi_message_t message;
ogs_sbi_request_t *request = NULL;
ogs_sbi_server_t *server = NULL;
ogs_sbi_header_t header;
OpenAPI_n1_n2_message_transfer_req_data_t N1N2MessageTransferReqData;
OpenAPI_n1_message_container_t n1MessageContainer;
@ -45,10 +48,9 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
ogs_assert(smf_ue);
ogs_assert(smf_ue->supi);
ogs_assert(data);
ogs_assert(data->state);
ogs_assert(data->n1smbuf);
ogs_assert(data->n2smbuf);
ogs_assert(param);
ogs_assert(param->state);
ogs_assert(param->n1smbuf || param->n2smbuf);
memset(&message, 0, sizeof(message));
message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST;
@ -62,46 +64,18 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
memset(&N1N2MessageTransferReqData, 0, sizeof(N1N2MessageTransferReqData));
N1N2MessageTransferReqData.pdu_session_id = sess->psi;
N1N2MessageTransferReqData.n1_message_container = &n1MessageContainer;
N1N2MessageTransferReqData.n2_info_container = &n2InfoContainer;
memset(&n1MessageContainer, 0, sizeof(n1MessageContainer));
n1MessageContainer.n1_message_class = OpenAPI_n1_message_class_SM;
n1MessageContainer.n1_message_content = &n1MessageContent;
if (param->n1smbuf) {
N1N2MessageTransferReqData.n1_message_container = &n1MessageContainer;
memset(&n1MessageContent, 0, sizeof(n1MessageContent));
n1MessageContent.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
memset(&n1MessageContainer, 0, sizeof(n1MessageContainer));
n1MessageContainer.n1_message_class = OpenAPI_n1_message_class_SM;
n1MessageContainer.n1_message_content = &n1MessageContent;
memset(&n2InfoContainer, 0, sizeof(n2InfoContainer));
n2InfoContainer.n2_information_class = OpenAPI_n2_information_class_SM;
n2InfoContainer.sm_info = &smInfo;
memset(&n1MessageContent, 0, sizeof(n1MessageContent));
n1MessageContent.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
memset(&smInfo, 0, sizeof(smInfo));
smInfo.pdu_session_id = sess->psi;
smInfo.n2_info_content = &n2InfoContent;
memset(&n2InfoContent, 0, sizeof(n2InfoContent));
switch (data->state) {
case SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT:
n2InfoContent.ngap_ie_type = OpenAPI_ngap_ie_type_PDU_RES_SETUP_REQ;
break;
case SMF_NETWORK_REQUESTED_PDU_SESSION_MODIFICATION:
case SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION:
n2InfoContent.ngap_ie_type = OpenAPI_ngap_ie_type_PDU_RES_MOD_REQ;
break;
default:
ogs_fatal("Unexpected state [%d]", data->state);
ogs_assert_if_reached();
}
n2InfoContent.ngap_data = &ngapData;
memset(&ngapData, 0, sizeof(ngapData));
ngapData.content_id = (char *)OGS_SBI_CONTENT_NGAP_SM_ID;
message.num_of_part = 0;
message.part[message.num_of_part].pkbuf = data->n1smbuf;
if (message.part[message.num_of_part].pkbuf) {
message.part[message.num_of_part].pkbuf = param->n1smbuf;
message.part[message.num_of_part].content_id =
(char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
message.part[message.num_of_part].content_type =
@ -109,8 +83,40 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
message.num_of_part++;
}
message.part[message.num_of_part].pkbuf = data->n2smbuf;
if (message.part[message.num_of_part].pkbuf) {
if (param->n2smbuf) {
N1N2MessageTransferReqData.n2_info_container = &n2InfoContainer;
memset(&n2InfoContainer, 0, sizeof(n2InfoContainer));
n2InfoContainer.n2_information_class = OpenAPI_n2_information_class_SM;
n2InfoContainer.sm_info = &smInfo;
memset(&smInfo, 0, sizeof(smInfo));
smInfo.pdu_session_id = sess->psi;
smInfo.n2_info_content = &n2InfoContent;
memset(&n2InfoContent, 0, sizeof(n2InfoContent));
switch (param->state) {
case SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT:
case SMF_NETWORK_TRIGGERED_SERVICE_REQUEST:
n2InfoContent.ngap_ie_type = OpenAPI_ngap_ie_type_PDU_RES_SETUP_REQ;
break;
case SMF_NETWORK_REQUESTED_PDU_SESSION_MODIFICATION:
case SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION:
n2InfoContent.ngap_ie_type = OpenAPI_ngap_ie_type_PDU_RES_MOD_REQ;
break;
case SMF_ERROR_INDICATON_RECEIVED_FROM_5G_AN:
n2InfoContent.ngap_ie_type = OpenAPI_ngap_ie_type_PDU_RES_REL_CMD;
break;
default:
ogs_fatal("Unexpected state [%d]", param->state);
ogs_assert_if_reached();
}
n2InfoContent.ngap_data = &ngapData;
memset(&ngapData, 0, sizeof(ngapData));
ngapData.content_id = (char *)OGS_SBI_CONTENT_NGAP_SM_ID;
message.part[message.num_of_part].pkbuf = param->n2smbuf;
message.part[message.num_of_part].content_id =
(char *)OGS_SBI_CONTENT_NGAP_SM_ID;
message.part[message.num_of_part].content_type =
@ -118,6 +124,23 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
message.num_of_part++;
}
if (param->n1n2_failure_txf_notif_uri == true) {
server = ogs_list_first(&ogs_sbi_self()->server_list);
ogs_assert(server);
memset(&header, 0, sizeof(header));
header.service.name = (char *)OGS_SBI_SERVICE_NAME_NSMF_CALLBACK;
header.api.version = (char *)OGS_SBI_API_V1;
header.resource.component[0] =
(char *)OGS_SBI_RESOURCE_NAME_N1_N2_FAILURE_NOTIFY;
N1N2MessageTransferReqData.n1n2_failure_txf_notif_uri =
ogs_sbi_server_uri(server, &header);
ogs_assert(N1N2MessageTransferReqData.n1n2_failure_txf_notif_uri);
}
if (param->skip_ind == true)
N1N2MessageTransferReqData.skip_ind = 1;
request = ogs_sbi_build_request(&message);
ogs_assert(request);
@ -125,6 +148,9 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
if (message.part[i].pkbuf)
ogs_pkbuf_free(message.part[i].pkbuf);
if (N1N2MessageTransferReqData.n1n2_failure_txf_notif_uri)
ogs_free(N1N2MessageTransferReqData.n1n2_failure_txf_notif_uri);
return request;
}

View File

@ -26,19 +26,24 @@
extern "C" {
#endif
typedef struct smf_n1_n2_message_transfer_data_s {
typedef struct smf_n1_n2_message_transfer_param_s {
#define SMF_N1_N2_MESSAGE_TRANSFER_NO_STATE 0
#define SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT 1
#define SMF_NETWORK_REQUESTED_PDU_SESSION_MODIFICATION 2
#define SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION 3
#define SMF_NETWORK_TRIGGERED_SERVICE_REQUEST 4
#define SMF_ERROR_INDICATON_RECEIVED_FROM_5G_AN 5
int state;
ogs_pkbuf_t *n1smbuf;
ogs_pkbuf_t *n2smbuf;
} smf_n1_n2_message_transfer_data_t;
bool n1n2_failure_txf_notif_uri;
bool skip_ind;
} smf_n1_n2_message_transfer_param_t;
ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
smf_sess_t *sess, smf_n1_n2_message_transfer_data_t *data);
smf_sess_t *sess, smf_n1_n2_message_transfer_param_t *param);
ogs_sbi_request_t *smf_namf_callback_build_sm_context_status(
smf_sess_t *sess, void *data);

View File

@ -18,23 +18,136 @@
*/
#include "sbi-path.h"
#include "ngap-path.h"
#include "binding.h"
#include "namf-handler.h"
bool smf_namf_comm_handler_n1_n2_message_transfer(
smf_sess_t *sess, int state, ogs_sbi_message_t *recvmsg)
{
smf_ue_t *smf_ue = NULL;
OpenAPI_n1_n2_message_transfer_rsp_data_t *N1N2MessageTransferRspData;
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
ogs_assert(state);
ogs_assert(recvmsg);
switch (state) {
case SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT:
smf_qos_flow_binding(sess, NULL);
if (recvmsg->res_status == OGS_SBI_HTTP_STATUS_OK) {
smf_qos_flow_binding(sess, NULL);
} else {
ogs_error("[%s:%d] HTTP response error [%d]",
smf_ue->supi, sess->psi, recvmsg->res_status);
}
break;
case SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION:
/* Nothing */
if (recvmsg->res_status == OGS_SBI_HTTP_STATUS_OK) {
/* Nothing */
} else {
ogs_error("[%s:%d] HTTP response error [%d]",
smf_ue->supi, sess->psi, recvmsg->res_status);
}
break;
case SMF_NETWORK_TRIGGERED_SERVICE_REQUEST:
N1N2MessageTransferRspData = recvmsg->N1N2MessageTransferRspData;
if (!N1N2MessageTransferRspData) {
ogs_error("No N1N2MessageTransferRspData [status:%d]",
recvmsg->res_status);
break;
}
if (recvmsg->res_status == OGS_SBI_HTTP_STATUS_OK) {
if (N1N2MessageTransferRspData->cause ==
OpenAPI_n1_n2_message_transfer_cause_N1_N2_TRANSFER_INITIATED) {
/* Nothing */
} else {
ogs_error("Not implemented [cause:%d]",
N1N2MessageTransferRspData->cause);
ogs_assert_if_reached();
}
} else if (recvmsg->res_status == OGS_SBI_HTTP_STATUS_ACCEPTED) {
if (N1N2MessageTransferRspData->cause ==
OpenAPI_n1_n2_message_transfer_cause_ATTEMPTING_TO_REACH_UE) {
if (recvmsg->http.location)
smf_sess_set_paging_n1n2message_location(
sess, recvmsg->http.location);
else
ogs_error("No HTTP Location");
} else {
ogs_error("Not implemented [cause:%d]",
N1N2MessageTransferRspData->cause);
ogs_assert_if_reached();
}
} else {
/*
* TODO:
*
* TS23.502 4.2.3.3 Network Triggered Service Request
*
* 3c. [Conditional] SMF responds to the UPF
*
* If the SMF receives an indication from the AMF that the UE is
* unreachable or reachable only for regulatory prioritized service
* and the SMF determines that Extended Buffering does not apply,
* the SMF may, based on network policies, either:
*
* - indicate to the UPF to stop sending Data Notifications;
* - indicate to the UPF to stop buffering DL data and
* discard the buffered data;
* - indicate to the UPF to stop sending Data Notifications and
* stop buffering DL data and discard the buffered data; or
* - refrains from sending further Namf_Communication_N1N2MessageTransfer
* message for DL data to the AMF while the UE is unreachable.
*/
ogs_error("[%s:%d] HTTP response error [status:%d cause:%d]",
smf_ue->supi, sess->psi, recvmsg->res_status,
N1N2MessageTransferRspData->cause);
}
break;
case SMF_ERROR_INDICATON_RECEIVED_FROM_5G_AN:
N1N2MessageTransferRspData = recvmsg->N1N2MessageTransferRspData;
if (!N1N2MessageTransferRspData) {
ogs_error("No N1N2MessageTransferRspData [status:%d]",
recvmsg->res_status);
break;
}
if (recvmsg->res_status == OGS_SBI_HTTP_STATUS_OK) {
if (N1N2MessageTransferRspData->cause ==
OpenAPI_n1_n2_message_transfer_cause_N1_MSG_NOT_TRANSFERRED) {
smf_n1_n2_message_transfer_param_t param;
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_TRIGGERED_SERVICE_REQUEST;
param.n2smbuf =
ngap_build_pdu_session_resource_setup_request_transfer(
sess);
ogs_assert(param.n2smbuf);
param.n1n2_failure_txf_notif_uri = true;
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
} else if (N1N2MessageTransferRspData->cause ==
OpenAPI_n1_n2_message_transfer_cause_N1_N2_TRANSFER_INITIATED) {
/* Nothing */
} else {
ogs_error("Not implemented [cause:%d]",
N1N2MessageTransferRspData->cause);
ogs_assert_if_reached();
}
} else {
ogs_error("[%s:%d] HTTP response error [status:%d cause:%d]",
smf_ue->supi, sess->psi, recvmsg->res_status,
N1N2MessageTransferRspData->cause);
}
break;
default:
@ -44,3 +157,63 @@ bool smf_namf_comm_handler_n1_n2_message_transfer(
return true;
}
bool smf_namf_comm_handler_n1_n2_message_transfer_failure_notify(
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
{
OpenAPI_n1_n2_msg_txfr_failure_notification_t
*N1N2MsgTxfrFailureNotification = NULL;
smf_sess_t *sess = NULL;
ogs_assert(stream);
ogs_assert(recvmsg);
N1N2MsgTxfrFailureNotification = recvmsg->N1N2MsgTxfrFailureNotification;
if (!N1N2MsgTxfrFailureNotification) {
ogs_error("No N1N2MsgTxfrFailureNotification");
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No N1N2MsgTxfrFailureNotification", NULL);
return false;
}
if (!N1N2MsgTxfrFailureNotification->cause) {
ogs_error("No Cause");
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No Cause", NULL);
return false;
}
if (!N1N2MsgTxfrFailureNotification->n1n2_msg_data_uri) {
ogs_error("No n1n2MsgDataUri");
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
recvmsg, "No n1n2MsgDataUri", NULL);
return false;
}
sess = smf_sess_find_by_paging_n1n2message_location(
N1N2MsgTxfrFailureNotification->n1n2_msg_data_uri);
if (!sess) {
ogs_error("Not found");
ogs_sbi_server_send_error(stream, OGS_SBI_HTTP_STATUS_NOT_FOUND,
recvmsg, N1N2MsgTxfrFailureNotification->n1n2_msg_data_uri, NULL);
return false;
}
/*
* TODO:
*
* TS23.502 4.2.3.3 Network Triggered Service Request
*
* 5. [Conditional] AMF to SMF:
* Namf_Communication_N1N2Transfer Failure Notification.
*
* When a Namf_Communication_N1N2Transfer Failure Notification
* is received, SMF informs the UPF (if applicable).
*
* Procedure for pause of charging at SMF is specified in clause 4.4.4.
*/
smf_sbi_send_http_status_no_content(stream);
return true;
}

View File

@ -29,6 +29,9 @@ extern "C" {
bool smf_namf_comm_handler_n1_n2_message_transfer(
smf_sess_t *sess, int state, ogs_sbi_message_t *recvmsg);
bool smf_namf_comm_handler_n1_n2_message_transfer_failure_notify(
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg);
#ifdef __cplusplus
}
#endif

View File

@ -276,11 +276,15 @@ ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer(
}
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer(
NGAP_Cause_PR group, long cause)
smf_sess_t *sess, int state, NGAP_Cause_PR group, long cause)
{
NGAP_PDUSessionResourceReleaseCommandTransfer_t message;
NGAP_Cause_t *Cause = NULL;
ogs_assert(sess);
ogs_assert(state);
sess->ngap_state.pdu_session_resource_release = state;
ogs_debug("PDUSessionResourceReleaseCommandTransfer");
memset(&message, 0,
sizeof(NGAP_PDUSessionResourceReleaseCommandTransfer_t));

View File

@ -33,7 +33,7 @@ ogs_pkbuf_t *ngap_build_qos_flow_resource_modify_request_transfer(
smf_bearer_t *qos_flow);
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer(
NGAP_Cause_PR group, long cause);
smf_sess_t *sess, int state, NGAP_Cause_PR group, long cause);
ogs_pkbuf_t *ngap_build_path_switch_request_ack_transfer(smf_sess_t *sess);

View File

@ -141,7 +141,7 @@ int ngap_handle_pdu_session_resource_setup_response_transfer(
sess, stream, OGS_PFCP_MODIFY_ACTIVATE);
} else {
/* ACTIVATED Is NOT Included in RESPONSE */
smf_sbi_send_sm_context_updated_data(sess, stream, 0);
smf_sbi_send_http_status_no_content(stream);
}
rv = OGS_OK;
@ -343,7 +343,7 @@ int ngap_handle_pdu_session_resource_to_be_switched_dl_transfer(
OGS_PFCP_MODIFY_END_MARKER);
} else {
/* ACTIVATED Is NOT Included in RESPONSE */
smf_sbi_send_sm_context_updated_data(sess, stream, 0);
smf_sbi_send_http_status_no_content(stream);
}
rv = OGS_OK;

View File

@ -440,14 +440,12 @@ bool smf_nsmf_handle_update_sm_context(
} else {
char *strerror = ogs_msprintf("[%s:%d] Invalid upCnxState [%d]",
smf_ue->supi, sess->psi,
SmContextUpdateData->up_cnx_state);
smf_ue->supi, sess->psi, SmContextUpdateData->up_cnx_state);
ogs_assert(strerror);
ogs_error("%s", strerror);
smf_sbi_send_sm_context_update_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, strerror,
NULL, NULL, NULL);
OGS_SBI_HTTP_STATUS_BAD_REQUEST, strerror, NULL, NULL, NULL);
ogs_free(strerror);
return false;

View File

@ -285,7 +285,8 @@ void smf_5gc_pfcp_send_session_modification_request(
ogs_pfcp_xact_t *xact = NULL;
ogs_assert(sess);
ogs_assert(stream);
if ((flags & OGS_PFCP_MODIFY_ERROR_INDICATION) == 0)
ogs_assert(stream);
memset(&h, 0, sizeof(ogs_pfcp_header_t));
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
@ -456,3 +457,26 @@ void smf_epc_pfcp_send_session_deletion_request(
rv = ogs_pfcp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
}
void smf_pfcp_send_session_report_response(
ogs_pfcp_xact_t *xact, smf_sess_t *sess, uint8_t cause)
{
int rv;
ogs_pkbuf_t *sxabuf = NULL;
ogs_pfcp_header_t h;
ogs_assert(xact);
memset(&h, 0, sizeof(ogs_pfcp_header_t));
h.type = OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE;
h.seid = sess->upf_n4_seid;
sxabuf = ogs_pfcp_build_session_report_response(h.type, cause);
ogs_expect_or_return(sxabuf);
rv = ogs_pfcp_xact_update_tx(xact, &h, sxabuf);
ogs_expect_or_return(rv == OGS_OK);
rv = ogs_pfcp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
}

View File

@ -45,6 +45,9 @@ void smf_epc_pfcp_send_bearer_modification_request(
void smf_epc_pfcp_send_session_deletion_request(
smf_sess_t *sess, void *gtp_xact);
void smf_pfcp_send_session_report_response(
ogs_pfcp_xact_t *xact, smf_sess_t *sess, uint8_t cause);
#ifdef __cplusplus
}
#endif

View File

@ -249,6 +249,16 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
sess, xact, &message->pfcp_session_deletion_response);
break;
case OGS_PFCP_SESSION_REPORT_REQUEST_TYPE:
if (!message->h.seid_presence) {
ogs_error("No SEID");
break;
}
smf_n4_handle_session_report_request(
sess, xact, &message->pfcp_session_report_request);
break;
default:
ogs_error("Not implemented PFCP message type[%d]",
message->h.type);

View File

@ -93,7 +93,7 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
/* APN-AMBR
* if PCRF changes APN-AMBR, this should be included. */
if (sess->gtp_5gc.create_session_response_apn_ambr == true) {
if (sess->gtp.create_session_response_apn_ambr == true) {
memset(&ambr, 0, sizeof(ogs_gtp_ambr_t));
ambr.uplink = htobe32(sess->pdn.ambr.uplink / 1000);
ambr.downlink = htobe32(sess->pdn.ambr.downlink / 1000);
@ -125,7 +125,7 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
/* Bearer QoS
* if PCRF changes Bearer QoS, this should be included. */
if (sess->gtp_5gc.create_session_response_bearer_qos == true) {
if (sess->gtp.create_session_response_bearer_qos == true) {
memset(&bearer_qos, 0, sizeof(bearer_qos));
bearer_qos.qci = sess->pdn.qos.qci;
bearer_qos.priority_level = sess->pdn.qos.arp.priority_level;

View File

@ -152,32 +152,25 @@ void smf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
}
void smf_namf_comm_send_n1_n2_message_transfer(
smf_sess_t *sess, int state,
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf)
smf_sess_t *sess, smf_n1_n2_message_transfer_param_t *param)
{
ogs_sbi_xact_t *xact = NULL;
smf_ue_t *smf_ue = NULL;
smf_n1_n2_message_transfer_data_t data;
ogs_assert(state);
ogs_assert(n1smbuf);
ogs_assert(n2smbuf);
ogs_assert(param);
ogs_assert(param->state);
ogs_assert(param->n1smbuf || param->n2smbuf);
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
memset(&data, 0, sizeof(data));
data.state = state;
data.n1smbuf = n1smbuf;
data.n2smbuf = n2smbuf;
xact = ogs_sbi_xact_add(OpenAPI_nf_type_AMF, &sess->sbi,
(ogs_sbi_build_f)smf_namf_comm_build_n1_n2_message_transfer,
sess, &data, smf_timer_sbi_client_wait_expire);
sess, param, smf_timer_sbi_client_wait_expire);
ogs_assert(xact);
xact->state = state;
xact->state = param->state;
ogs_sbi_discover_and_send(xact,
(ogs_fsm_handler_t)smf_nf_state_registered, client_cb);
@ -240,38 +233,11 @@ void smf_sbi_send_sm_context_create_error(
ogs_pkbuf_free(n1smbuf);
}
void smf_sbi_send_sm_context_updated_data(smf_sess_t *sess,
ogs_sbi_stream_t *stream, OpenAPI_up_cnx_state_e up_cnx_state)
{
int status;
ogs_sbi_message_t sendmsg;
ogs_sbi_response_t *response = NULL;
OpenAPI_sm_context_updated_data_t SmContextUpdatedData;
ogs_assert(sess);
ogs_assert(stream);
memset(&sendmsg, 0, sizeof(sendmsg));
if (up_cnx_state) {
memset(&SmContextUpdatedData, 0, sizeof(SmContextUpdatedData));
SmContextUpdatedData.up_cnx_state = up_cnx_state;
sendmsg.SmContextUpdatedData = &SmContextUpdatedData;
status = OGS_SBI_HTTP_STATUS_OK;
} else {
status = OGS_SBI_HTTP_STATUS_NO_CONTENT;
}
response = ogs_sbi_build_response(&sendmsg, status);
ogs_assert(response);
ogs_sbi_server_send_response(stream, response);
}
void smf_sbi_send_sm_context_updated_data_in_session_deletion(
smf_sess_t *sess, ogs_sbi_stream_t *stream)
void smf_sbi_send_sm_context_updated_data(
smf_sess_t *sess, ogs_sbi_stream_t *stream,
OpenAPI_up_cnx_state_e up_cnx_state,
ogs_pkbuf_t *n1smbuf,
OpenAPI_n2_sm_info_type_e n2type, ogs_pkbuf_t *n2smbuf)
{
int i;
@ -285,41 +251,41 @@ void smf_sbi_send_sm_context_updated_data_in_session_deletion(
ogs_assert(sess);
ogs_assert(stream);
ogs_assert(up_cnx_state != OpenAPI_up_cnx_state_NULL || n1smbuf || n2smbuf);
memset(&sendmsg, 0, sizeof(sendmsg));
memset(&SmContextUpdatedData, 0, sizeof(SmContextUpdatedData));
sendmsg.num_of_part = 0;
/* up_cnx_state */
SmContextUpdatedData.up_cnx_state = up_cnx_state;
n1SmMsg.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
SmContextUpdatedData.n1_sm_msg = &n1SmMsg;
/* n1smbuf */
if (n1smbuf) {
n1SmMsg.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
SmContextUpdatedData.n1_sm_msg = &n1SmMsg;
sendmsg.part[sendmsg.num_of_part].pkbuf =
gsm_build_pdu_session_release_command(
sess, OGS_5GSM_CAUSE_REGULAR_DEACTIVATION);
if (sendmsg.part[sendmsg.num_of_part].pkbuf) {
sendmsg.part[sendmsg.num_of_part].content_id =
(char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
sendmsg.part[sendmsg.num_of_part].content_type =
(char *)OGS_SBI_CONTENT_5GNAS_TYPE;
sendmsg.part[sendmsg.num_of_part].pkbuf = n1smbuf;
sendmsg.num_of_part++;
}
SmContextUpdatedData.n2_sm_info_type =
OpenAPI_n2_sm_info_type_PDU_RES_REL_CMD;
SmContextUpdatedData.n2_sm_info = &n2SmInfo;
/* n2smbuf */
if (n2smbuf) {
ogs_assert(n2type);
SmContextUpdatedData.n2_sm_info_type = n2type;
memset(&n2SmInfo, 0, sizeof(n2SmInfo));
n2SmInfo.content_id = (char *)OGS_SBI_CONTENT_NGAP_SM_ID;
n2SmInfo.content_id = (char *)OGS_SBI_CONTENT_NGAP_SM_ID;
SmContextUpdatedData.n2_sm_info = &n2SmInfo;
sendmsg.part[sendmsg.num_of_part].pkbuf =
ngap_build_pdu_session_resource_release_command_transfer(
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
if (sendmsg.part[sendmsg.num_of_part].pkbuf) {
sendmsg.part[sendmsg.num_of_part].content_id =
(char *)OGS_SBI_CONTENT_NGAP_SM_ID;
sendmsg.part[sendmsg.num_of_part].content_type =
(char *)OGS_SBI_CONTENT_NGAP_TYPE;
sendmsg.part[sendmsg.num_of_part].pkbuf = n2smbuf;
sendmsg.num_of_part++;
}
@ -327,6 +293,7 @@ void smf_sbi_send_sm_context_updated_data_in_session_deletion(
response = ogs_sbi_build_response(&sendmsg, OGS_SBI_HTTP_STATUS_OK);
ogs_assert(response);
ogs_sbi_server_send_response(stream, response);
for (i = 0; i < sendmsg.num_of_part; i++)
@ -426,51 +393,8 @@ void smf_sbi_send_sm_context_status_notify(smf_sess_t *sess)
ogs_assert(sess);
client = sess->namf.client;
ogs_assert(client);
client->cb = client_cb;
request = smf_namf_callback_build_sm_context_status(sess, NULL);
ogs_assert(request);
ogs_sbi_client_send_request(client, client_notify_cb, request, NULL);
}
void smf_sbi_send_sm_context_updated_data_with_n2buf(
smf_sess_t *sess, ogs_sbi_stream_t *stream,
OpenAPI_n2_sm_info_type_e n2_sm_info_type, ogs_pkbuf_t *n2smbuf)
{
ogs_sbi_message_t sendmsg;
ogs_sbi_response_t *response = NULL;
OpenAPI_sm_context_updated_data_t SmContextUpdatedData;
OpenAPI_ref_to_binary_data_t n2SmInfo;
ogs_assert(sess);
ogs_assert(stream);
memset(&sendmsg, 0, sizeof(sendmsg));
memset(&SmContextUpdatedData, 0, sizeof(SmContextUpdatedData));
sendmsg.num_of_part = 0;
sendmsg.SmContextUpdatedData = &SmContextUpdatedData;
if (n2smbuf) {
SmContextUpdatedData.n2_sm_info_type = n2_sm_info_type;
SmContextUpdatedData.n2_sm_info = &n2SmInfo;
n2SmInfo.content_id = (char *)OGS_SBI_CONTENT_NGAP_SM_ID;
sendmsg.part[sendmsg.num_of_part].content_id =
(char *)OGS_SBI_CONTENT_NGAP_SM_ID;
sendmsg.part[sendmsg.num_of_part].content_type =
(char *)OGS_SBI_CONTENT_NGAP_TYPE;
sendmsg.part[sendmsg.num_of_part].pkbuf = n2smbuf;
sendmsg.num_of_part++;
}
response = ogs_sbi_build_response(&sendmsg, OGS_SBI_HTTP_STATUS_OK);
ogs_assert(response);
ogs_sbi_server_send_response(stream, response);
if (n2smbuf)
ogs_pkbuf_free(n2smbuf);
}

View File

@ -40,26 +40,39 @@ void smf_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
ogs_sbi_request_t *(*build)(smf_sess_t *sess, void *data));
void smf_namf_comm_send_n1_n2_message_transfer(
smf_sess_t *sess, int state,
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf);
smf_sess_t *sess, smf_n1_n2_message_transfer_param_t *param);
#define smf_sbi_send_http_status_no_content(__sTREAM) \
smf_sbi_send_response(__sTREAM, OGS_SBI_HTTP_STATUS_NO_CONTENT);
void smf_sbi_send_response(ogs_sbi_stream_t *stream, int status);
void smf_sbi_send_sm_context_create_error(
ogs_sbi_stream_t *stream,
int status, const char *title, const char *detail,
ogs_pkbuf_t *n1smbuf);
void smf_sbi_send_sm_context_updated_data(smf_sess_t *sess,
ogs_sbi_stream_t *stream, OpenAPI_up_cnx_state_e up_cnx_state);
void smf_sbi_send_sm_context_updated_data_in_session_deletion(
smf_sess_t *sess, ogs_sbi_stream_t *stream);
#define smf_sbi_send_sm_context_updated_data_up_cnx_state( \
__sESS, __sTREAM, __uPCnxState) \
smf_sbi_send_sm_context_updated_data(\
__sESS, __sTREAM, __uPCnxState, NULL, 0, NULL)
#define smf_sbi_send_sm_context_updated_data_n2smbuf( \
__sESS, __sTREAM, __n2Type, __n2SmBuf) \
smf_sbi_send_sm_context_updated_data(\
__sESS, __sTREAM, 0, NULL, __n2Type, __n2SmBuf)
#define smf_sbi_send_sm_context_updated_data_n1_n2_message( \
__sESS, __sTREAM, __n1SmBuf, __n2Type, __n2SmBuf) \
smf_sbi_send_sm_context_updated_data(\
__sESS, __sTREAM, 0, __n1SmBuf, __n2Type, __n2SmBuf)
void smf_sbi_send_sm_context_updated_data(
smf_sess_t *sess, ogs_sbi_stream_t *stream,
OpenAPI_up_cnx_state_e up_cnx_state,
ogs_pkbuf_t *n1smbuf,
OpenAPI_n2_sm_info_type_e n2type, ogs_pkbuf_t *n2smbuf);
void smf_sbi_send_sm_context_update_error(
ogs_sbi_stream_t *stream,
int status, const char *title, const char *detail,
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf);
void smf_sbi_send_sm_context_updated_data_with_n2buf(
smf_sess_t *sess, ogs_sbi_stream_t *stream,
OpenAPI_n2_sm_info_type_e n2_sm_info_type, ogs_pkbuf_t *n2smbuf);
void smf_sbi_send_sm_context_status_notify(smf_sess_t *sess);

View File

@ -25,6 +25,7 @@
#include "s5c-handler.h"
#include "gx-handler.h"
#include "nnrf-handler.h"
#include "namf-handler.h"
void smf_state_initial(ogs_fsm_t *s, smf_event_t *e)
{
@ -199,8 +200,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
sess, gx_message, gtp_xact);
break;
default:
ogs_error("Not implemented(%d)",
gx_message->cc_request_type);
ogs_error("Not implemented(%d)", gx_message->cc_request_type);
break;
}
@ -299,11 +299,9 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
break;
DEFAULT
ogs_error("Invalid HTTP method [%s]",
sbi_message.h.method);
ogs_error("Invalid HTTP method [%s]", sbi_message.h.method);
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_FORBIDDEN,
&sbi_message,
OGS_SBI_HTTP_STATUS_FORBIDDEN, &sbi_message,
"Invalid HTTP method", sbi_message.h.method);
END
break;
@ -388,17 +386,24 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
break;
CASE(OGS_SBI_SERVICE_NAME_NSMF_CALLBACK)
SWITCH(sbi_message.h.resource.component[1])
CASE(OGS_SBI_RESOURCE_NAME_SM_POLICY_NOTIFY)
/* TODO */
SWITCH(sbi_message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_N1_N2_FAILURE_NOTIFY)
smf_namf_comm_handler_n1_n2_message_transfer_failure_notify(
stream, &sbi_message);
break;
DEFAULT
ogs_error("Invalid resource name [%s]",
sbi_message.h.resource.component[1]);
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &sbi_message,
"Invalid resource name",
sbi_message.h.resource.component[1]);
SWITCH(sbi_message.h.resource.component[1])
CASE(OGS_SBI_RESOURCE_NAME_SM_POLICY_NOTIFY)
/* TODO */
DEFAULT
ogs_error("Invalid resource name [%s]",
sbi_message.h.resource.component[1]);
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &sbi_message,
"Invalid resource name",
sbi_message.h.resource.component[1]);
END
END
break;

View File

@ -37,6 +37,7 @@
#include "event.h"
#include "gtp-path.h"
#include "pfcp-path.h"
#include "rule-match.h"
#define UPF_GTP_HANDLED 1
@ -52,6 +53,8 @@ static void _gtpv1_tun_recv_cb(short when, ogs_socket_t fd, void *data)
{
ogs_pkbuf_t *recvbuf = NULL;
int n;
upf_sess_t *sess = NULL;
ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_user_plane_report_t report;
@ -74,6 +77,18 @@ static void _gtpv1_tun_recv_cb(short when, ogs_socket_t fd, void *data)
if (pdr) {
/* Unicast */
ogs_pfcp_up_handle_pdr(pdr, recvbuf, &report);
if (report.type.downlink_data_report) {
ogs_assert(pdr->sess);
sess = UPF_SESS(pdr->sess);
ogs_assert(sess);
report.downlink_data.pdr_id = pdr->id;
if (pdr->qer && pdr->qer->qfi)
report.downlink_data.qfi = pdr->qer->qfi; /* for 5GC */
upf_pfcp_send_session_report_request(sess, &report);
}
} else {
if (ogs_app()->parameter.multicast) {
upf_gtp_handle_multicast(recvbuf);
@ -89,13 +104,13 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
ssize_t size;
char buf[OGS_ADDRSTRLEN];
upf_sess_t *sess = NULL;
ogs_pkbuf_t *pkbuf = NULL;
ogs_sockaddr_t from;
ogs_gtp_header_t *gtp_h = NULL;
#if 0
ogs_pfcp_user_plane_report_t report;
#endif
uint32_t teid;
uint8_t qfi;
@ -188,7 +203,24 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
/* Nothing */
} else if (gtp_h->type == OGS_GTPU_MSGTYPE_ERR_IND) {
/* TODO */
ogs_pfcp_far_t *far = NULL;
far = ogs_pfcp_far_find_by_error_indication(pkbuf);
if (far) {
ogs_pfcp_up_handle_error_indication(far, &report);
if (report.type.error_indication_report) {
ogs_assert(far->sess);
sess = UPF_SESS(far->sess);
ogs_assert(sess);
upf_pfcp_send_session_report_request(sess, &report);
}
} else {
ogs_error("[DROP] Cannot find FAR by Error-Indication");
ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
}
} else if (gtp_h->type == OGS_GTPU_MSGTYPE_GPDU) {
int rv;

View File

@ -431,3 +431,39 @@ void upf_n4_handle_session_deletion_request(
upf_sess_remove(sess);
}
void upf_n4_handle_session_report_response(
upf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_report_response_t *rsp)
{
uint8_t cause_value = 0;
ogs_assert(xact);
ogs_assert(rsp);
ogs_pfcp_xact_commit(xact);
ogs_debug("Session report resopnse");
cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
}
if (rsp->cause.presence) {
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
ogs_error("PFCP Cause[%d] : Not Accepted", rsp->cause.u8);
cause_value = rsp->cause.u8;
}
} else {
ogs_error("No Cause");
cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
}
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
ogs_error("Cause request not accepted[%d]", cause_value);
return;
}
}

View File

@ -36,6 +36,10 @@ void upf_n4_handle_session_deletion_request(
upf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_deletion_request_t *req);
void upf_n4_handle_session_report_response(
upf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_report_response_t *rsp);
#ifdef __cplusplus
}
#endif

View File

@ -250,3 +250,46 @@ void upf_pfcp_send_session_deletion_response(ogs_pfcp_xact_t *xact,
rv = ogs_pfcp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
}
static void sess_timeout(ogs_pfcp_xact_t *xact, void *data)
{
uint8_t type;
ogs_assert(xact);
type = xact->seq[0].type;
switch (type) {
case OGS_PFCP_SESSION_REPORT_REQUEST_TYPE:
ogs_error("No PFCP session report response");
break;
default:
ogs_error("Not implemented [type:%d]", type);
break;
}
}
void upf_pfcp_send_session_report_request(
upf_sess_t *sess, ogs_pfcp_user_plane_report_t *report)
{
int rv;
ogs_pkbuf_t *n4buf = NULL;
ogs_pfcp_header_t h;
ogs_pfcp_xact_t *xact = NULL;
ogs_assert(sess);
ogs_assert(report);
memset(&h, 0, sizeof(ogs_pfcp_header_t));
h.type = OGS_PFCP_SESSION_REPORT_REQUEST_TYPE;
h.seid = sess->smf_n4_seid;
n4buf = ogs_pfcp_build_session_report_request(h.type, report);
ogs_expect_or_return(n4buf);
xact = ogs_pfcp_xact_local_create(
sess->pfcp_node, &h, n4buf, sess_timeout, sess);
ogs_expect_or_return(xact);
rv = ogs_pfcp_xact_commit(xact);
ogs_expect(rv == OGS_OK);
}

View File

@ -38,6 +38,9 @@ void upf_pfcp_send_session_modification_response(
void upf_pfcp_send_session_deletion_response(ogs_pfcp_xact_t *xact,
upf_sess_t *sess);
void upf_pfcp_send_session_report_request(
upf_sess_t *sess, ogs_pfcp_user_plane_report_t *report);
#ifdef __cplusplus
}
#endif

View File

@ -224,6 +224,10 @@ void upf_pfcp_state_associated(ogs_fsm_t *s, upf_event_t *e)
upf_n4_handle_session_deletion_request(
sess, xact, &message->pfcp_session_deletion_request);
break;
case OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE:
upf_n4_handle_session_report_response(
sess, xact, &message->pfcp_session_report_response);
break;
default:
ogs_error("Not implemented PFCP message type[%d]",
message->h.type);

View File

@ -66,6 +66,7 @@ void testngap_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
testngap_handle_pdu_session_resource_release_command(test_ue, pdu);
break;
case NGAP_ProcedureCode_id_ErrorIndication:
case NGAP_ProcedureCode_id_Paging:
/* Nothing */
break;
default:

View File

@ -23,6 +23,7 @@ abts_suite *test_guti(abts_suite *suite);
abts_suite *test_auth(abts_suite *suite);
abts_suite *test_idle(abts_suite *suite);
abts_suite *test_dereg(abts_suite *suite);
abts_suite *test_paging(abts_suite *suite);
abts_suite *test_identity(abts_suite *suite);
abts_suite *test_gmm_status(abts_suite *suite);
abts_suite *test_ue_context(abts_suite *suite);
@ -34,6 +35,7 @@ const struct testlist {
{test_auth},
{test_idle},
{test_dereg},
{test_paging},
{test_identity},
{test_gmm_status},
{test_ue_context},

View File

@ -902,18 +902,22 @@ static void test3_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive PDU session release command */
/* Receive PDUSessionResourceReleaseCommand +
* DL NAS transport +
* PDU session release command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send PDU session resource release response */
/* Send PDUSessionResourceReleaseResponse */
sendbuf = testngap_build_pdu_session_resource_release_response(sess);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send PDU session resource release complete */
/* Send UplinkNASTransport +
* UL NAS trasnport +
* PDU session resource release complete */
sess->ul_nas_transport_param.request_type = 0;
sess->ul_nas_transport_param.dnn = 0;
sess->ul_nas_transport_param.s_nssai = 0;
@ -1365,19 +1369,22 @@ static void test4_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive PDU session release command */
/* Receive PDUSessionResourceReleaseCommand +
* DL NAS transport +
* PDU session release command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send PDU session resource release response */
sendbuf =
testngap_build_pdu_session_resource_release_response(sess);
/* Send PDUSessionResourceReleaseResponse */
sendbuf = testngap_build_pdu_session_resource_release_response(sess);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send PDU session resource release complete */
/* Send UplinkNASTransport +
* UL NAS trasnport +
* PDU session resource release complete */
sess->ul_nas_transport_param.request_type = 0;
sess->ul_nas_transport_param.dnn = 0;
sess->ul_nas_transport_param.s_nssai = 0;

View File

@ -404,6 +404,7 @@ static void test1_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* TODO : we need to analyze it */
ogs_msleep(100);
/* Send Identity response */

View File

@ -316,6 +316,7 @@ static void test1_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* TODO : we need to analyze it */
ogs_msleep(100);
/* Send De-registration request */
@ -358,7 +359,15 @@ static void test1_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* TODO :
*
* I can't remeber why do I add the following sleep
* At this point, this commented out.
* I'll need to analyze it later.
*/
#if 0
ogs_msleep(100);
#endif
/* INVALID SUCI */
test_ue->mobile_identity_suci.scheme_output[0] = 0x99;
@ -375,6 +384,8 @@ static void test1_func(abts_case *tc, void *data)
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
ABTS_INT_EQUAL(tc,
OGS_NAS_5GS_REGISTRATION_REJECT, test_ue->gmm_message_type);
/* Receive UE context release command */
recvbuf = testgnb_ngap_read(ngap);

View File

@ -313,10 +313,6 @@ static void test1_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/*
* Send InitialUEMessage +
* Service request
@ -357,10 +353,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Wait to setup N3 data connection.
* Otherwise, network-triggered service request is initiated */
ogs_msleep(100);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);
@ -384,10 +379,6 @@ static void test1_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send UE context release complete */
sendbuf = testngap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
@ -436,10 +427,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Wait to setup N3 data connection.
* Otherwise, network-triggered service request is initiated */
ogs_msleep(100);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);
@ -2496,10 +2486,6 @@ static void test6_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/*
* Send InitialUEMessage +
* Service request
@ -2542,10 +2528,9 @@ static void test6_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Wait to setup N3 data connection.
* Otherwise, network-triggered service request is initiated */
ogs_msleep(100);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);

View File

@ -21,6 +21,7 @@ test5gc_registration_sources = files('''
auth-test.c
idle-test.c
dereg-test.c
paging-test.c
identity-test.c
gmm-status-test.c
ue-context-test.c

File diff suppressed because it is too large Load Diff

View File

@ -954,18 +954,22 @@ static void test3_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive PDU session release command */
/* Receive PDUSessionResourceReleaseCommand +
* DL NAS transport +
* PDU session release command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send PDU session resource release response */
/* Send PDUSessionResourceReleaseResponse */
sendbuf = testngap_build_pdu_session_resource_release_response(sess);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send PDU session resource release complete */
/* Send UplinkNASTransport +
* UL NAS trasnport +
* PDU session resource release complete */
sess->ul_nas_transport_param.request_type = 0;
sess->ul_nas_transport_param.dnn = 0;
sess->ul_nas_transport_param.s_nssai = 0;
@ -1425,10 +1429,6 @@ static void test4_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send UE context release complete */
sendbuf = testngap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
@ -1476,10 +1476,9 @@ static void test4_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Wait to setup N3 data connection.
* Otherwise, network-triggered service request is initiated */
ogs_msleep(100);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);

View File

@ -447,16 +447,20 @@ static void test1_func(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, 0x0000, test_ue->pdu_session_status);
ABTS_INT_EQUAL(tc, 0x0000, test_ue->pdu_session_reactivation_result);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Initial context setup response */
sendbuf = testngap_build_initial_context_setup_response(test_ue, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Wait to setup N3 data connection.
* Otherwise, network-triggered service request is initiated */
ogs_msleep(100);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);

File diff suppressed because it is too large Load Diff