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 open5gs (2.1.3) unstable; urgency=medium
* Bug Fixed * Bug Fixed

View File

@ -365,7 +365,8 @@ typedef struct ogs_pcc_rule_s {
ogs_assert((__dST)->id); \ ogs_assert((__dST)->id); \
} \ } \
for (__iNDEX = 0; __iNDEX < (__sRC)->num_of_flow; __iNDEX++) { \ 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 = \ (__dST)->flow[__iNDEX].description = \
ogs_strdup((__sRC)->flow[__iNDEX].description); \ ogs_strdup((__sRC)->flow[__iNDEX].description); \
ogs_assert((__dST)->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) if (message->N1N2MessageTransferRspData)
OpenAPI_n1_n2_message_transfer_rsp_data_free( OpenAPI_n1_n2_message_transfer_rsp_data_free(
message->N1N2MessageTransferRspData); message->N1N2MessageTransferRspData);
if (message->N1N2MsgTxfrFailureNotification)
OpenAPI_n1_n2_msg_txfr_failure_notification_free(
message->N1N2MsgTxfrFailureNotification);
if (message->SmContextStatusNotification) if (message->SmContextStatusNotification)
OpenAPI_sm_context_status_notification_free( OpenAPI_sm_context_status_notification_free(
message->SmContextStatusNotification); message->SmContextStatusNotification);
@ -712,6 +715,10 @@ static char *build_json(ogs_sbi_message_t *message)
item = OpenAPI_n1_n2_message_transfer_rsp_data_convertToJSON( item = OpenAPI_n1_n2_message_transfer_rsp_data_convertToJSON(
message->N1N2MessageTransferRspData); message->N1N2MessageTransferRspData);
ogs_assert(item); 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) { } else if (message->SmContextStatusNotification) {
item = OpenAPI_sm_context_status_notification_convertToJSON( item = OpenAPI_sm_context_status_notification_convertToJSON(
message->SmContextStatusNotification); message->SmContextStatusNotification);
@ -1381,6 +1388,25 @@ static int parse_json(ogs_sbi_message_t *message,
END END
break; 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 DEFAULT
rv = OGS_ERROR; rv = OGS_ERROR;
ogs_error("Not implemented API name [%s]", 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_SERVICE_NAME_NSMF_CALLBACK "nsmf-callback"
#define OGS_SBI_RESOURCE_NAME_SM_POLICY_NOTIFY "sm-policy-notify" #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_SERVICE_NAME_NAMF_COMM "namf-comm"
#define OGS_SBI_RESOURCE_NAME_UE_CONTEXTS "ue-contexts" #define OGS_SBI_RESOURCE_NAME_UE_CONTEXTS "ue-contexts"
@ -321,6 +322,8 @@ typedef struct ogs_sbi_message_s {
SessionManagementSubscriptionData; SessionManagementSubscriptionData;
OpenAPI_n1_n2_message_transfer_req_data_t *N1N2MessageTransferReqData; OpenAPI_n1_n2_message_transfer_req_data_t *N1N2MessageTransferReqData;
OpenAPI_n1_n2_message_transfer_rsp_data_t *N1N2MessageTransferRspData; 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_sm_context_status_notification_t *SmContextStatusNotification;
OpenAPI_policy_association_request_t *PolicyAssociationRequest; OpenAPI_policy_association_request_t *PolicyAssociationRequest;
OpenAPI_policy_association_t *PolicyAssociation; OpenAPI_policy_association_t *PolicyAssociation;

View File

@ -58,6 +58,7 @@
#include "model/session_management_subscription_data.h" #include "model/session_management_subscription_data.h"
#include "model/n1_n2_message_transfer_req_data.h" #include "model/n1_n2_message_transfer_req_data.h"
#include "model/n1_n2_message_transfer_rsp_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/sm_context_status_notification.h"
#include "model/policy_association.h" #include "model/policy_association.h"
#include "model/am_policy_data.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/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
project('open5gs', 'c', project('open5gs', 'c',
version : '2.1.3', version : '2.1.4',
license : 'AGPL-3.0-or-later', license : 'AGPL-3.0-or-later',
meson_version : '>= 0.43.0', meson_version : '>= 0.43.0',
default_options : [ default_options : [
@ -24,7 +24,7 @@ project('open5gs', 'c',
], ],
) )
libogslib_version = '2.1.3' libogslib_version = '2.1.4'
prefix = get_option('prefix') prefix = get_option('prefix')
bindir = join_paths(prefix, get_option('bindir')) 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_object_t *sbi_object = NULL;
ogs_sbi_xact_t *sbi_xact = 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_stream_t *stream = NULL;
ogs_sbi_request_t *sbi_request = 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 */ /* Clear Transparent Container */
OGS_ASN_CLEAR_DATA(&amf_ue->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 */ /* Delete All Timers */
CLEAR_AMF_UE_ALL_TIMERS(amf_ue); CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
ogs_timer_delete(amf_ue->t3513.timer); 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) if (sess->pdu_session_establishment_accept)
ogs_pkbuf_free(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_NAS_CLEAR_DATA(&sess->ue_pco);
OGS_TLV_CLEAR_DATA(&sess->pgw_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; 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; amf_sess_t *sess = NULL;

View File

@ -262,6 +262,7 @@ struct amf_ue_s {
/* UE Info */ /* UE Info */
ogs_guami_t *guami; ogs_guami_t *guami;
uint16_t gnb_ostream_id;
ogs_5gs_tai_t tai; ogs_5gs_tai_t tai;
ogs_nr_cgi_t nr_cgi; ogs_nr_cgi_t nr_cgi;
ogs_time_t ue_location_timestamp; ogs_time_t ue_location_timestamp;
@ -447,7 +448,71 @@ typedef struct amf_sess_s {
struct { struct {
ogs_pkbuf_t *pdu_session_resource_setup_request; ogs_pkbuf_t *pdu_session_resource_setup_request;
ogs_pkbuf_t *path_switch_request_ack; ogs_pkbuf_t *path_switch_request_ack;
ogs_pkbuf_t *pdu_session_resource_release_command;
} transfer; } 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 */ /* last payload for sending back to the UE */
uint8_t payload_container_type; uint8_t payload_container_type;
@ -470,6 +535,7 @@ typedef struct amf_sess_s {
/* Save Protocol Configuration Options from PGW */ /* Save Protocol Configuration Options from PGW */
ogs_tlv_octet_t pgw_pco; ogs_tlv_octet_t pgw_pco;
} amf_sess_t; } amf_sess_t;
void amf_context_init(void); 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_ue_t *amf_ue_cycle(amf_ue_t *amf_ue);
amf_sess_t *amf_sess_cycle(amf_sess_t *sess); 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_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) #define PDU_RES_SETUP_REQ_TRANSFER_NEEDED(__aMF) \
bool amf_sess_transfer_needed(amf_ue_t *amf_ue); (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); int amf_find_served_tai(ogs_5gs_tai_t *tai);
ogs_s_nssai_t *amf_find_s_nssai( 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 * REGISTRATION_REQUEST
* SERVICE_REQUEST * SERVICE_REQUEST
* Clear N2 Transfer
* Clear Timer and Message * 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); CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
if (SECURITY_CONTEXT_IS_VALID(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), ogs_plmn_id_hexdump(&ran_ue->saved.nr_cgi.plmn_id),
(long long)ran_ue->saved.nr_cgi.cell_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->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)); memcpy(&amf_ue->nr_cgi, &ran_ue->saved.nr_cgi, sizeof(ogs_nr_cgi_t));
amf_ue->ue_location_timestamp = ogs_time_now(); 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"); 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 & if ((registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_PDU_SESSION_STATUS_PRESENT) == 0) { OGS_NAS_5GS_REGISTRATION_REQUEST_PDU_SESSION_STATUS_PRESENT) == 0) {
amf_ue->nas.present.pdu_session_status = 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; return OGS_OK;
} }
@ -346,8 +338,10 @@ int gmm_handle_service_request(amf_ue_t *amf_ue,
/* /*
* REGISTRATION_REQUEST * REGISTRATION_REQUEST
* SERVICE_REQUEST * SERVICE_REQUEST
* Clear Paging Info
* Clear Timer and Message * Clear Timer and Message
*/ */
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
CLEAR_AMF_UE_ALL_TIMERS(amf_ue); CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
if (SECURITY_CONTEXT_IS_VALID(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), ogs_plmn_id_hexdump(&ran_ue->saved.nr_cgi.plmn_id),
(long long)ran_ue->saved.nr_cgi.cell_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->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)); memcpy(&amf_ue->nr_cgi, &ran_ue->saved.nr_cgi, sizeof(ogs_nr_cgi_t));
amf_ue->ue_location_timestamp = ogs_time_now(); 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); 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 * TS24.501
* 5.6.1.5 Service request procedure not accepted by the network * 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) if (amf_sess_xact_count(amf_ue) == xact_count)
nas_5gs_send_service_accept(amf_ue); 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); ogs_info("[%s] SUCI", amf_ue->suci);
amf_sbi_send_release_all_sessions( amf_sbi_send_release_all_sessions(amf_ue, AMF_SESS_SM_CONTEXT_NO_STATE);
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
if (ogs_list_count(&amf_ue->sess_list) == 0) if (ogs_list_count(&amf_ue->sess_list) == 0)
nas_5gs_send_de_registration_accept(amf_ue); 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, 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); amf_nsmf_pdu_session_build_create_sm_context);
} else { } else {

View File

@ -64,6 +64,8 @@ void gmm_state_de_registered(ogs_fsm_t *s, amf_event_t *e)
switch (e->id) { switch (e->id) {
case OGS_FSM_ENTRY_SIG: 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); CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
@ -159,7 +161,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
} else { } else {
amf_sbi_send_release_all_sessions( amf_sbi_send_release_all_sessions(
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE); amf_ue, AMF_SESS_SM_CONTEXT_NO_STATE);
if (amf_sess_xact_count(amf_ue) == xact_count) { if (amf_sess_xact_count(amf_ue) == xact_count) {
amf_ue_sbi_discover_and_send( amf_ue_sbi_discover_and_send(
OpenAPI_nf_type_AUSF, amf_ue, NULL, 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_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) { if (amf_sess_xact_count(amf_ue) == xact_count) {
amf_ue_sbi_discover_and_send(OpenAPI_nf_type_AUSF, amf_ue, NULL, amf_ue_sbi_discover_and_send(OpenAPI_nf_type_AUSF, amf_ue, NULL,
amf_nausf_auth_build_authenticate); 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: case AMF_TIMER_T3513:
if (amf_ue->t3513.retry_count >= if (amf_ue->t3513.retry_count >=
amf_timer_cfg(AMF_TIMER_T3513)->max_count) { amf_timer_cfg(AMF_TIMER_T3513)->max_count) {
amf_sess_t *sess = NULL;
/* Paging failed */ /* Paging failed */
ogs_warn("[%s] Paging failed. Stop", amf_ue->supi); 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); CLEAR_AMF_UE_TIMER(amf_ue->t3513);
} else { } else {
amf_ue->t3513.retry_count++; amf_ue->t3513.retry_count++;
/* /* If t3513 is timeout, the saved pkbuf is used. */
* If t3513 is timeout, the saved pkbuf is used. ngap_send_paging(amf_ue);
* We don't have to set CNDomain.
* So, we just set CNDomain to 0
*/
#if 0
ngap_send_paging(amf_ue, 0);
#endif
} }
break; 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 == } else if (amf_ue->nas.message_type ==
OGS_NAS_5GS_SERVICE_REQUEST) { OGS_NAS_5GS_SERVICE_REQUEST) {
OGS_FSM_TRAN(s, &gmm_state_registered); 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 { } else {
ogs_fatal("Invalid OGS_NAS_5GS[%d]", amf_ue->nas.message_type); ogs_fatal("Invalid OGS_NAS_5GS[%d]", amf_ue->nas.message_type);
ogs_assert_if_reached(); 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) if (amf_ue->guti_present == 0)
OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_registered); OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_registered);
/* /* If nas_5gs_send_service_accept() used, we need change it. */
* Do not use nas_5gs_send_registration_accept() ogs_assert(amf_ue->nas.message_type ==
* instead of nas_5gs_send_accept() here. OGS_NAS_5GS_REGISTRATION_REQUEST);
* nas_5gs_send_registration_accept(amf_ue);
* 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);
break; break;
DEFAULT 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_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) { if (amf_sess_xact_count(amf_ue) == xact_count) {
amf_ue_sbi_discover_and_send(OpenAPI_nf_type_AUSF, amf_ue, NULL, amf_ue_sbi_discover_and_send(OpenAPI_nf_type_AUSF, amf_ue, NULL,
amf_nausf_auth_build_authenticate); amf_nausf_auth_build_authenticate);
@ -1066,10 +1067,11 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
switch (e->id) { switch (e->id) {
case OGS_FSM_ENTRY_SIG: 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); CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
amf_sbi_send_release_all_sessions( amf_sbi_send_release_all_sessions(amf_ue, AMF_SESS_SM_CONTEXT_NO_STATE);
amf_ue, AMF_RELEASE_SM_CONTEXT_NO_STATE);
if (ogs_list_count(&amf_ue->sess_list) == 0) if (ogs_list_count(&amf_ue->sess_list) == 0)
ngap_send_amf_ue_context_release_command(amf_ue, 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 { } else {
amf_sbi_send_release_all_sessions( 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) { if (amf_sess_xact_count(amf_ue) == xact_count) {
amf_ue_sbi_discover_and_send( amf_ue_sbi_discover_and_send(
OpenAPI_nf_type_AUSF, amf_ue, NULL, OpenAPI_nf_type_AUSF, amf_ue, NULL,

View File

@ -30,11 +30,10 @@ int amf_namf_comm_handle_n1_n2_message_transfer(
int status; int status;
amf_ue_t *amf_ue = NULL; amf_ue_t *amf_ue = NULL;
ran_ue_t *ran_ue = NULL;
amf_sess_t *sess = NULL; amf_sess_t *sess = NULL;
ogs_pkbuf_t *n1smbuf = NULL; ogs_pkbuf_t *n1buf = NULL;
ogs_pkbuf_t *n2smbuf = NULL; ogs_pkbuf_t *n2buf = NULL;
ogs_pkbuf_t *gmmbuf = NULL; ogs_pkbuf_t *gmmbuf = NULL;
ogs_pkbuf_t *ngapbuf = NULL; ogs_pkbuf_t *ngapbuf = NULL;
@ -63,47 +62,6 @@ int amf_namf_comm_handle_n1_n2_message_transfer(
return OGS_ERROR; 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; pdu_session_id = N1N2MessageTransferReqData->pdu_session_id;
if (pdu_session_id == OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED) { if (pdu_session_id == OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED) {
ogs_error("No PDU Session Identity"); ogs_error("No PDU Session Identity");
@ -122,9 +80,6 @@ int amf_namf_comm_handle_n1_n2_message_transfer(
return OGS_ERROR; 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); sess = amf_sess_find_by_psi(amf_ue, pdu_session_id);
if (!sess) { if (!sess) {
ogs_error("[%s] No PDU Session Context [%d]", ogs_error("[%s] No PDU Session Context [%d]",
@ -132,82 +87,278 @@ int amf_namf_comm_handle_n1_n2_message_transfer(
return OGS_ERROR; return OGS_ERROR;
} }
n1smbuf = ogs_sbi_find_part_by_content_id( n1MessageContainer = N1N2MessageTransferReqData->n1_message_container;
recvmsg, n1MessageContent->content_id); if (n1MessageContainer) {
if (!n1smbuf) { n1MessageContent = n1MessageContainer->n1_message_content;
ogs_error("[%s] No N1 SM Content", amf_ue->supi); if (!n1MessageContent || !n1MessageContent->content_id) {
return OGS_ERROR; 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); n2InfoContainer = N1N2MessageTransferReqData->n2_info_container;
if (!n2smbuf) { if (n2InfoContainer) {
ogs_error("[%s] No N2 SM Content", amf_ue->supi); smInfo = n2InfoContainer->sm_info;
return OGS_ERROR; 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) { switch (n2InfoContent->ngap_ie_type) {
case OpenAPI_ngap_ie_type_PDU_RES_SETUP_REQ: case OpenAPI_ngap_ie_type_PDU_RES_SETUP_REQ:
if (sess->pdu_session_establishment_accept) { case OpenAPI_ngap_ie_type_PDU_RES_MOD_REQ:
ogs_pkbuf_free(sess->pdu_session_establishment_accept); case OpenAPI_ngap_ie_type_PDU_RES_REL_CMD:
sess->pdu_session_establishment_accept = NULL; /* 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) { if (gmmbuf) {
ngapbuf = ngap_sess_build_pdu_session_resource_setup_request( ran_ue_t *ran_ue = NULL;
sess, gmmbuf, n2smbuf);
ogs_assert(ngapbuf);
} else {
ngapbuf = ngap_sess_build_initial_context_setup_request(
sess, gmmbuf, n2smbuf);
ogs_assert(ngapbuf);
ran_ue->initial_context_setup_request_sent = true; /***********************************
} * 4.3.2 PDU Session Establishment *
***********************************/
if (SESSION_CONTEXT_IN_SMF(sess)) { ran_ue = ran_ue_cycle(amf_ue->ran_ue);
/* ogs_assert(ran_ue);
* [1-CLIENT] /nsmf-pdusession/v1/sm-contexts
* [2-SERVER] /namf-comm/v1/ue-contexts/{supi}/n1-n2-messages if (sess->pdu_session_establishment_accept) {
* ogs_pkbuf_free(sess->pdu_session_establishment_accept);
* If [2-SERVER] arrives after [1-CLIENT], sess->pdu_session_establishment_accept = NULL;
* 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;
} }
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 { } 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; break;
case OpenAPI_ngap_ie_type_PDU_RES_MOD_REQ: case OpenAPI_ngap_ie_type_PDU_RES_MOD_REQ:
ngapbuf = ngap_build_pdu_session_resource_modify_request( if (!gmmbuf) {
sess, gmmbuf, n2smbuf); ogs_error("[%s] No N1 SM Content", amf_ue->supi);
ogs_assert(ngapbuf); 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) { if (CM_IDLE(amf_ue)) {
ogs_error("nas_5gs_send_to_gnb() failed"); ogs_fatal("[%s] IDLE state is not implemented", amf_ue->supi);
status = OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR; 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; break;
@ -217,21 +368,13 @@ int amf_namf_comm_handle_n1_n2_message_transfer(
ogs_assert_if_reached(); 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); response = ogs_sbi_build_response(&sendmsg, status);
ogs_assert(response); ogs_assert(response);
ogs_sbi_server_send_response(stream, response); ogs_sbi_server_send_response(stream, response);
if (sendmsg.http.location)
ogs_free(sendmsg.http.location);
return OGS_OK; 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); ogs_debug("[%s:%d] SM context remove", amf_ue->supi, sess->psi);
amf_nsmf_pdu_session_handle_release_sm_context( amf_nsmf_pdu_session_handle_release_sm_context(
sess, AMF_RELEASE_SM_CONTEXT_NO_STATE); sess, AMF_SESS_SM_CONTEXT_NO_STATE);
} }
cleanup: 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; ran_ue->initial_context_setup_request_sent = true;
} else { } 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( ngapbuf = ngap_ue_build_pdu_session_resource_setup_request(
amf_ue, gmmbuf); amf_ue, gmmbuf);
ogs_expect_or_return(ngapbuf); 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 && if (ran_ue->ue_context_requested == true &&
ran_ue->initial_context_setup_request_sent == false) { ran_ue->initial_context_setup_request_sent == false) {
ngapbuf = ngap_ue_build_initial_context_setup_request( ngapbuf = ngap_ue_build_initial_context_setup_request(amf_ue, gmmbuf);
amf_ue, gmmbuf);
ogs_expect_or_return(ngapbuf); ogs_expect_or_return(ngapbuf);
rv = nas_5gs_send_to_gnb(amf_ue, 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; ran_ue->initial_context_setup_request_sent = true;
} else { } 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( ngapbuf = ngap_ue_build_pdu_session_resource_setup_request(
amf_ue, gmmbuf); amf_ue, gmmbuf);
ogs_expect_or_return(ngapbuf); ogs_expect_or_return(ngapbuf);
@ -179,22 +178,6 @@ void nas_5gs_send_service_reject(
ogs_expect(rv == OGS_OK); 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) void nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue)
{ {
ran_ue_t *ran_ue = NULL; 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( void nas_5gs_send_service_reject(
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause); 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_de_registration_accept(amf_ue_t *amf_ue);
void nas_5gs_send_identity_request(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)); memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = initiatingMessage->procedureCode =
@ -389,8 +388,7 @@ ogs_pkbuf_t *ngap_ue_build_initial_context_setup_request(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t)); memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = 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( 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; int i, j;
@ -752,12 +750,14 @@ ogs_pkbuf_t *ngap_sess_build_initial_context_setup_request(
GUAMI = &ie->value.choice.GUAMI; GUAMI = &ie->value.choice.GUAMI;
if (n1smbuf && n2smbuf) { if (gmmbuf || n2smbuf) {
NGAP_NAS_PDU_t *nAS_PDU = NULL; NGAP_NAS_PDU_t *nAS_PDU = NULL;
OCTET_STRING_t *transfer = NULL; OCTET_STRING_t *transfer = NULL;
NGAP_S_NSSAI_t *s_NSSAI = NULL; NGAP_S_NSSAI_t *s_NSSAI = NULL;
NGAP_SST_t *sST = NULL; NGAP_SST_t *sST = NULL;
ogs_assert(n2smbuf);
ie = CALLOC(1, sizeof(NGAP_InitialContextSetupRequestIEs_t)); ie = CALLOC(1, sizeof(NGAP_InitialContextSetupRequestIEs_t));
ASN_SEQUENCE_ADD(&InitialContextSetupRequest->protocolIEs, ie); ASN_SEQUENCE_ADD(&InitialContextSetupRequest->protocolIEs, ie);
@ -771,13 +771,15 @@ ogs_pkbuf_t *ngap_sess_build_initial_context_setup_request(
sizeof(struct NGAP_PDUSessionResourceSetupItemCxtReq)); sizeof(struct NGAP_PDUSessionResourceSetupItemCxtReq));
ASN_SEQUENCE_ADD(&PDUSessionList->list, PDUSessionItem); ASN_SEQUENCE_ADD(&PDUSessionList->list, PDUSessionItem);
PDUSessionItem->nAS_PDU = nAS_PDU = CALLOC(1, sizeof(*nAS_PDU)); if (gmmbuf) {
ogs_assert(nAS_PDU); PDUSessionItem->nAS_PDU = nAS_PDU = CALLOC(1, sizeof(*nAS_PDU));
ogs_assert(nAS_PDU);
nAS_PDU->size = n1smbuf->len; nAS_PDU->size = gmmbuf->len;
nAS_PDU->buf = CALLOC(nAS_PDU->size, sizeof(uint8_t)); nAS_PDU->buf = CALLOC(nAS_PDU->size, sizeof(uint8_t));
memcpy(nAS_PDU->buf, n1smbuf->data, nAS_PDU->size); memcpy(nAS_PDU->buf, gmmbuf->data, nAS_PDU->size);
ogs_pkbuf_free(n1smbuf); ogs_pkbuf_free(gmmbuf);
}
PDUSessionItem->pDUSessionID = sess->psi; 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)); memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = initiatingMessage->procedureCode =
@ -1106,8 +1107,7 @@ ogs_pkbuf_t *ngap_build_ue_context_release_command(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t)); memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_UEContextRelease; 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_PDUSessionResourceSetupListSUReq_t *PDUSessionList = NULL;
NGAP_PDUSessionResourceSetupItemSUReq_t *PDUSessionItem = NULL; NGAP_PDUSessionResourceSetupItemSUReq_t *PDUSessionItem = NULL;
ogs_assert(gmmbuf);
ogs_assert(amf_ue); ogs_assert(amf_ue);
ran_ue = ran_ue_cycle(amf_ue->ran_ue); ran_ue = ran_ue_cycle(amf_ue->ran_ue);
ogs_assert(ran_ue); ogs_assert(ran_ue);
@ -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); asn_uint642INTEGER(AMF_UE_NGAP_ID, ran_ue->amf_ue_ngap_id);
*RAN_UE_NGAP_ID = ran_ue->ran_ue_ngap_id; *RAN_UE_NGAP_ID = ran_ue->ran_ue_ngap_id;
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestIEs_t)); if (gmmbuf) {
ASN_SEQUENCE_ADD(&PDUSessionResourceSetupRequest->protocolIEs, ie); ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestIEs_t));
ASN_SEQUENCE_ADD(&PDUSessionResourceSetupRequest->protocolIEs, ie);
ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU;
ie->criticality = NGAP_Criticality_reject; ie->criticality = NGAP_Criticality_reject;
ie->value.present = ie->value.present =
NGAP_PDUSessionResourceSetupRequestIEs__value_PR_NAS_PDU; 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->size = gmmbuf->len;
NAS_PDU->buf = CALLOC(NAS_PDU->size, sizeof(uint8_t)); NAS_PDU->buf = CALLOC(NAS_PDU->size, sizeof(uint8_t));
memcpy(NAS_PDU->buf, gmmbuf->data, NAS_PDU->size); memcpy(NAS_PDU->buf, gmmbuf->data, NAS_PDU->size);
ogs_pkbuf_free(gmmbuf); ogs_pkbuf_free(gmmbuf);
}
ogs_list_for_each(&amf_ue->sess_list, sess) { ogs_list_for_each(&amf_ue->sess_list, sess) {
NGAP_S_NSSAI_t *s_NSSAI = NULL; 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; NGAP_SST_t *sST = NULL;
OCTET_STRING_t *transfer = NULL; OCTET_STRING_t *transfer = NULL;
ogs_assert(gmmbuf);
ogs_assert(n2smbuf); ogs_assert(n2smbuf);
ogs_assert(sess); ogs_assert(sess);
@ -1366,12 +1366,15 @@ ogs_pkbuf_t *ngap_sess_build_pdu_session_resource_setup_request(
PDUSessionItem->pDUSessionID = sess->psi; PDUSessionItem->pDUSessionID = sess->psi;
PDUSessionItem->pDUSessionNAS_PDU = if (gmmbuf) {
pDUSessionNAS_PDU = CALLOC(1, sizeof(NGAP_NAS_PDU_t)); PDUSessionItem->pDUSessionNAS_PDU =
pDUSessionNAS_PDU->size = gmmbuf->len; pDUSessionNAS_PDU = CALLOC(1, sizeof(NGAP_NAS_PDU_t));
pDUSessionNAS_PDU->buf = CALLOC(pDUSessionNAS_PDU->size, sizeof(uint8_t)); pDUSessionNAS_PDU->size = gmmbuf->len;
memcpy(pDUSessionNAS_PDU->buf, gmmbuf->data, pDUSessionNAS_PDU->size); pDUSessionNAS_PDU->buf =
ogs_pkbuf_free(gmmbuf); 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; s_NSSAI = &PDUSessionItem->s_NSSAI;
sST = &s_NSSAI->sST; sST = &s_NSSAI->sST;
@ -1507,7 +1510,6 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command(
NGAP_PDUSessionResourceToReleaseItemRelCmd_t *PDUSessionItem = NULL; NGAP_PDUSessionResourceToReleaseItemRelCmd_t *PDUSessionItem = NULL;
OCTET_STRING_t *transfer = NULL; OCTET_STRING_t *transfer = NULL;
ogs_assert(gmmbuf);
ogs_assert(n2smbuf); ogs_assert(n2smbuf);
ogs_assert(sess); 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; RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID;
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceReleaseCommandIEs_t)); ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld]",
ASN_SEQUENCE_ADD(&PDUSessionResourceReleaseCommand->protocolIEs, ie); ran_ue->ran_ue_ngap_id, (long long)ran_ue->amf_ue_ngap_id);
ie->id = NGAP_ProtocolIE_ID_id_NAS_PDU; asn_uint642INTEGER(AMF_UE_NGAP_ID, ran_ue->amf_ue_ngap_id);
ie->criticality = NGAP_Criticality_ignore; *RAN_UE_NGAP_ID = ran_ue->ran_ue_ngap_id;
ie->value.present =
NGAP_PDUSessionResourceReleaseCommandIEs__value_PR_NAS_PDU;
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)); ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceReleaseCommandIEs_t));
ASN_SEQUENCE_ADD(&PDUSessionResourceReleaseCommand->protocolIEs, ie); 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; 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 = PDUSessionItem =
CALLOC(1, sizeof(struct NGAP_PDUSessionResourceToReleaseItemRelCmd)); CALLOC(1, sizeof(struct NGAP_PDUSessionResourceToReleaseItemRelCmd));
ASN_SEQUENCE_ADD(&PDUSessionList->list, PDUSessionItem); 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); return ogs_ngap_encode(&pdu);
} }
#if 0 ogs_pkbuf_t *ngap_build_paging(amf_ue_t *amf_ue)
ogs_pkbuf_t *ngap_build_paging(
amf_ue_t *amf_ue, NGAP_CNDomain_t cn_domain)
{ {
NGAP_NGAP_PDU_t pdu; NGAP_NGAP_PDU_t pdu;
NGAP_InitiatingMessage_t *initiatingMessage = NULL; NGAP_InitiatingMessage_t *initiatingMessage = NULL;
@ -1605,26 +1607,20 @@ ogs_pkbuf_t *ngap_build_paging(
NGAP_PagingIEs_t *ie = NULL; NGAP_PagingIEs_t *ie = NULL;
NGAP_UEIdentityIndexValue_t *UEIdentityIndexValue = NULL; NGAP_UEPagingIdentity_t *UEPagingIdentity = NULL;
NGAP_UEPagingID_t *UEPagingID = NULL; NGAP_FiveG_S_TMSI_t *fiveG_S_TMSI = NULL;
NGAP_CNDomain_t *CNDomain = NULL; NGAP_AMFSetID_t *aMFSetID = NULL;
NGAP_TAIList_t *TAIList = NULL; NGAP_AMFPointer_t *aMFPointer = NULL;
NGAP_FiveG_TMSI_t *fiveG_TMSI = NULL;
NGAP_TAIItemIEs_t *item = NULL; NGAP_TAIListForPaging_t *TAIList = NULL;
NGAP_TAIItem_t *tai_item = NULL; NGAP_TAIListForPagingItem_t *TAIItem = NULL;
NGAP_TAI_t *tAI = NULL;
uint16_t index_value;
uint64_t ue_imsi_value = 0;
int i = 0;
ogs_assert(amf_ue);
ogs_debug("Paging"); ogs_debug("Paging");
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t)); memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_Paging; initiatingMessage->procedureCode = NGAP_ProcedureCode_id_Paging;
@ -1636,89 +1632,46 @@ ogs_pkbuf_t *ngap_build_paging(
ie = CALLOC(1, sizeof(NGAP_PagingIEs_t)); ie = CALLOC(1, sizeof(NGAP_PagingIEs_t));
ASN_SEQUENCE_ADD(&Paging->protocolIEs, ie); 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->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)); ie = CALLOC(1, sizeof(NGAP_PagingIEs_t));
ASN_SEQUENCE_ADD(&Paging->protocolIEs, ie); 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->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)); TAIItem = CALLOC(1, sizeof(NGAP_TAIListForPagingItem_t));
ASN_SEQUENCE_ADD(&Paging->protocolIEs, ie); ASN_SEQUENCE_ADD(&TAIList->list, TAIItem);
ie->id = NGAP_ProtocolIE_ID_id_CNDomain; tAI = &TAIItem->tAI;
ie->criticality = NGAP_Criticality_ignore; ogs_ngap_5gs_tai_to_ASN(&amf_ue->tai, tAI);
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);
return ogs_ngap_encode(&pdu); return ogs_ngap_encode(&pdu);
} }
#if 0
ogs_pkbuf_t *ngap_build_amf_configuration_transfer( ogs_pkbuf_t *ngap_build_amf_configuration_transfer(
NGAP_SONConfigurationTransfer_t *son_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)); memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = initiatingMessage->procedureCode =
@ -2217,8 +2169,7 @@ ogs_pkbuf_t *ngap_build_handover_request(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t)); memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = initiatingMessage->procedureCode =
@ -2500,8 +2451,7 @@ ogs_pkbuf_t *ngap_build_amf_status_transfer(
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t)); memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_AMFStatusTransfer; 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)); memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_ErrorIndication; 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)); memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage; pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = NGAP_ProcedureCode_id_Reset; 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( ogs_pkbuf_t *ngap_ue_build_initial_context_setup_request(
amf_ue_t *amf_ue, ogs_pkbuf_t *gmmbuf); amf_ue_t *amf_ue, ogs_pkbuf_t *gmmbuf);
ogs_pkbuf_t *ngap_sess_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);
ogs_pkbuf_t *ngap_build_ue_context_modification_request(amf_ue_t *amf_ue); ogs_pkbuf_t *ngap_build_ue_context_modification_request(amf_ue_t *amf_ue);
ogs_pkbuf_t *ngap_build_ue_context_release_command( ogs_pkbuf_t *ngap_build_ue_context_release_command(
ran_ue_t *ran_ue, NGAP_Cause_PR group, long cause); 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( ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command(
amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf); 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);
ogs_pkbuf_t *ngap_build_paging(
amf_ue_t *amf_ue, NGAP_CNDomain_t cn_domain);
#endif
ogs_pkbuf_t *ngap_build_amf_configuration_transfer( ogs_pkbuf_t *ngap_build_amf_configuration_transfer(
NGAP_SONConfigurationTransfer_t *son_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( ogs_ngap_ASN_to_5gs_tai(
&UserLocationInformationNR->tAI, &ran_ue->saved.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->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)); 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)
void ngap_send_paging(amf_ue_t *amf_ue, NGAP_CNDomain_t cn_domain)
{ {
ogs_pkbuf_t *ngapbuf = NULL; ogs_pkbuf_t *ngapbuf = NULL;
amf_gnb_t *gnb = NULL; amf_gnb_t *gnb = NULL;
int i; int i, j;
int rv; int rv;
/* Find enB with matched TAI */
ogs_list_for_each(&amf_self()->gnb_list, gnb) { ogs_list_for_each(&amf_self()->gnb_list, gnb) {
for (i = 0; i < gnb->num_of_supported_ta_list; i++) { 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, if (amf_ue->t3513.pkbuf) {
sizeof(ogs_5gs_tai_t)) == 0) { ngapbuf = amf_ue->t3513.pkbuf;
} else {
ngapbuf = ngap_build_paging(amf_ue);
ogs_expect_or_return(ngapbuf);
}
if (amf_ue->t3413.pkbuf) { amf_ue->t3513.pkbuf = ogs_pkbuf_copy(ngapbuf);
ngapbuf = amf_ue->t3413.pkbuf; ogs_assert(amf_ue->t3513.pkbuf);
} else {
ngapbuf = ngap_build_paging(amf_ue, cn_domain); rv = ngap_send_to_gnb(gnb, ngapbuf, amf_ue->gnb_ostream_id);
ogs_expect_or_return(ngapbuf); 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 */ /* Start T3513 */
ogs_timer_start(amf_ue->t3413.timer, ogs_timer_start(amf_ue->t3513.timer,
amf_timer_cfg(AMF_TIMER_T3413)->duration); 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( void ngap_send_amf_configuration_transfer(
amf_gnb_t *target_gnb, amf_gnb_t *target_gnb,
NGAP_SONConfigurationTransfer_t *SONConfigurationTransfer) 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, amf_ue_t *amf_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay); uint8_t action, uint32_t delay);
#if 0 void ngap_send_paging(amf_ue_t *amf_ue);
void ngap_send_paging(amf_ue_t *amf_ue, NGAP_CNDomain_t cn_domain); void ngap_send_pdu_resource_setup_request(
#endif amf_sess_t *sess, ogs_pkbuf_t *n2smbuf);
void ngap_send_amf_configuration_transfer( void ngap_send_amf_configuration_transfer(
amf_gnb_t *target_gnb, 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.method = (char *)OGS_SBI_HTTP_METHOD_POST;
message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION; message.h.service.name = (char *)OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION;
message.h.api.version = (char *)OGS_SBI_API_V1; message.h.api.version = (char *)OGS_SBI_API_V1;
message.h.resource.component[0] = message.h.resource.component[0] = (char *)OGS_SBI_RESOURCE_NAME_SM_CONTEXTS;
(char *)OGS_SBI_RESOURCE_NAME_SM_CONTEXTS;
message.h.resource.component[1] = sess->sm_context_ref; message.h.resource.component[1] = sess->sm_context_ref;
message.h.resource.component[2] = (char *)OGS_SBI_RESOURCE_NAME_MODIFY; 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; 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( ogs_sbi_request_t *amf_nsmf_pdu_session_build_release_sm_context(
amf_sess_t *sess, void *data); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -193,40 +193,41 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
* To Deliver N2 SM Content to gNB Temporarily, * To Deliver N2 SM Content to gNB Temporarily,
* Store N2 SM Context in Session Context * Store N2 SM Context in Session Context
*/ */
if (sess->transfer.pdu_session_resource_setup_request) { AMF_SESS_STORE_N2_TRANSFER(
/* sess, pdu_session_resource_setup_request,
* It should not be reached this way. ogs_pkbuf_copy(n2smbuf));
* 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);
if (SESSION_SYNC_DONE(amf_ue)) { switch(amf_ue->nas.message_type) {
nas_5gs_send_accept(amf_ue); 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,
* After sending accept message, N2 SM context is freed * N2 tranfer message is freed */
* For checking memory, NULL pointer should be set to n2smbuf. AMF_UE_CLEAR_N2_TRANSFER(
*/ amf_ue, pdu_session_resource_setup_request);
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;
}
} }
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; break;
@ -274,38 +275,15 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
* To Deliver N2 SM Content to gNB Temporarily, * To Deliver N2 SM Content to gNB Temporarily,
* Store N2 SM Context in Session Context * Store N2 SM Context in Session Context
*/ */
if (sess->transfer.path_switch_request_ack) { AMF_SESS_STORE_N2_TRANSFER(
/* sess, path_switch_request_ack,
* It should not be reached this way. ogs_pkbuf_copy(n2smbuf));
* 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);
if (SESSION_SYNC_DONE(amf_ue)) { if (SESSION_SYNC_DONE(amf_ue, state)) {
ngap_send_path_switch_ack(sess); ngap_send_path_switch_ack(sess);
/* /* After sending ack message, N2 SM context is freed */
* After sending ack message, N2 SM context is freed AMF_UE_CLEAR_N2_TRANSFER(amf_ue, path_switch_request_ack);
* 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;
}
}
} }
break; break;
@ -351,7 +329,7 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
* 6. UEContextReleaseComplete * 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_send_amf_ue_context_release_command(amf_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release, NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_NG_REMOVE_AND_UNLINK, 0); 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) { } else if (state == AMF_UPDATE_SM_CONTEXT_ACTIVATING) {
/* Not reached here */ /* Not reached here */
ogs_assert_if_reached();
} else if (state == AMF_UPDATE_SM_CONTEXT_N2_RELEASED) { } 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 */ /* 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); ran_ue_t *ran_ue = ran_ue_cycle(amf_ue->ran_ue);
if (ran_ue) { if (ran_ue) {
ogs_debug(" SUPI[%s]", amf_ue->supi); 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); ogs_debug("[%s:%d] SM context remove", amf_ue->supi, sess->psi);
amf_nsmf_pdu_session_handle_release_sm_context( amf_nsmf_pdu_session_handle_release_sm_context(
sess, AMF_RELEASE_SM_CONTEXT_NO_STATE); sess, AMF_SESS_SM_CONTEXT_NO_STATE);
} }
} }
} else { } else {
@ -510,92 +489,112 @@ int amf_nsmf_pdu_session_handle_release_sm_context(amf_sess_t *sess, int state)
amf_sess_remove(sess); amf_sess_remove(sess);
/* Check last session */ if (state == AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) {
if (ogs_list_count(&amf_ue->sess_list) == 0) { /*
* 1. Registration request
if (state == AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE) { * 2. Release All SM contexts
/* * 3. Registration accept
* 1. Initial context setup failure */
* 2. Release All SM contexts if (SESSION_SYNC_DONE(amf_ue,
* 3. UE Context release command AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) &&
* 4. UE Context release complete SESSION_SYNC_DONE(amf_ue, AMF_UPDATE_SM_CONTEXT_ACTIVATING))
*/
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
*/
nas_5gs_send_registration_accept(amf_ue); nas_5gs_send_registration_accept(amf_ue);
} else if (state == AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) { } else if (state == AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) {
/* /*
* 1. Service request * 1. Service request
* 2. Release All SM contexts * 2. Release All SM contexts
* 3. Service accept * 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); nas_5gs_send_service_accept(amf_ue);
} else { } else {
/* NO_STATE */
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, if (state == AMF_RELEASE_SM_CONTEXT_NG_CONTEXT_REMOVE) {
amf_nausf_auth_build_authenticate);
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_de_registered)) {
/* /*
* 1. PDU session release request * 1. Initial context setup failure
* 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 * 2. Release All SM contexts
* 3. UE Context release command * 3. UE Context release command
* 4. UE Context release complete * 4. UE Context release complete
*/ */
ngap_send_amf_ue_context_release_command(amf_ue, ngap_send_amf_ue_context_release_command(amf_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release, 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, } else if (state == AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) {
gmm_state_initial_context_setup)) {
ogs_fatal("Release SM Context in initial-context-setup"); /* Not reached here */
ogs_assert_if_reached(); ogs_assert_if_reached();
} else if (OGS_FSM_CHECK(
&amf_ue->sm, gmm_state_security_mode)) { } else if (state == AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) {
ogs_fatal("Release SM Context in security-mode");
/* Not reached here */
ogs_assert_if_reached(); ogs_assert_if_reached();
} else { } else {
ogs_fatal("Release SM Context : INVALID STATE"); /* NO_STATE */
ogs_assert_if_reached();
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( int amf_nudm_sdm_handle_provisioned(
amf_ue_t *amf_ue, ogs_sbi_message_t *recvmsg) amf_ue_t *amf_ue, ogs_sbi_message_t *recvmsg)
{ {
int i;
ogs_assert(amf_ue); ogs_assert(amf_ue);
ogs_assert(recvmsg); ogs_assert(recvmsg);
SWITCH(recvmsg->h.resource.component[1]) SWITCH(recvmsg->h.resource.component[1])
CASE(OGS_SBI_RESOURCE_NAME_AM_DATA) CASE(OGS_SBI_RESOURCE_NAME_AM_DATA)
if (recvmsg->AccessAndMobilitySubscriptionData) { if (recvmsg->AccessAndMobilitySubscriptionData) {
OpenAPI_ambr_rm_t *ue_ambr =
recvmsg->AccessAndMobilitySubscriptionData->
subscribed_ue_ambr;
OpenAPI_list_t *gpsiList = OpenAPI_list_t *gpsiList =
recvmsg->AccessAndMobilitySubscriptionData->gpsis; recvmsg->AccessAndMobilitySubscriptionData->gpsis;
OpenAPI_ambr_rm_t *SubscribedUeAmbr = OpenAPI_ambr_rm_t *SubscribedUeAmbr =
@ -42,15 +41,14 @@ int amf_nudm_sdm_handle_provisioned(
recvmsg->AccessAndMobilitySubscriptionData->subscribed_dnn_list; recvmsg->AccessAndMobilitySubscriptionData->subscribed_dnn_list;
OpenAPI_lnode_t *node = NULL; OpenAPI_lnode_t *node = NULL;
if (ue_ambr) { /* Clear MSISDN */
amf_ue->ue_ambr.uplink = for (i = 0; i < amf_ue->num_of_msisdn; i++) {
ogs_sbi_bitrate_from_string(ue_ambr->uplink); ogs_assert(amf_ue->msisdn[i]);
amf_ue->ue_ambr.downlink = ogs_free(amf_ue->msisdn[i]);
ogs_sbi_bitrate_from_string(ue_ambr->downlink);
} }
amf_ue->num_of_msisdn = 0;
if (gpsiList) { if (gpsiList) {
amf_ue->num_of_msisdn = 0;
OpenAPI_list_for_each(gpsiList, node) { OpenAPI_list_for_each(gpsiList, node) {
if (node->data) { if (node->data) {
char *gpsi = NULL; 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) { if (SubscribedUeAmbr) {
amf_ue->ue_ambr.uplink = amf_ue->ue_ambr.uplink =
ogs_sbi_bitrate_from_string(SubscribedUeAmbr->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); 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) { if (SubscribedDnnList) {
OpenAPI_list_for_each(SubscribedDnnList, node) { OpenAPI_list_for_each(SubscribedDnnList, node) {
if (node->data) { 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); 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, amf_ue_t *amf_ue, void *data,
ogs_sbi_request_t *(*build)(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_SESS_SM_CONTEXT_NO_STATE 0
#define AMF_UPDATE_SM_CONTEXT_ACTIVATED 1 #define AMF_UPDATE_SM_CONTEXT_ACTIVATED 1
#define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 2 #define AMF_UPDATE_SM_CONTEXT_DEACTIVATED 2
#define AMF_UPDATE_SM_CONTEXT_ACTIVATING 3 #define AMF_UPDATE_SM_CONTEXT_ACTIVATING 3
#define AMF_UPDATE_SM_CONTEXT_MODIFIED 4 #define AMF_UPDATE_SM_CONTEXT_MODIFIED 4
#define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 5 #define AMF_UPDATE_SM_CONTEXT_N2_RELEASED 5
#define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 6 #define AMF_UPDATE_SM_CONTEXT_N1_RELEASED 6
#define AMF_UPDATE_SM_CONTEXT_NG_RESET 7 #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, void amf_sess_sbi_discover_and_send(OpenAPI_nf_type_e target_nf_type,
amf_sess_t *sess, int state, void *data, amf_sess_t *sess, int state, void *data,
ogs_sbi_request_t *(*build)(amf_sess_t *sess, 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); amf_ue_t *amf_ue, int state, int group, int cause);
void amf_sbi_send_deactivate_all_ue_in_gnb(amf_gnb_t *gnb, int state); void amf_sbi_send_deactivate_all_ue_in_gnb(amf_gnb_t *gnb, int state);
#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_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_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 #ifdef __cplusplus
} }
#endif #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), ogs_plmn_id_hexdump(&enb_ue->saved.e_cgi.plmn_id),
enb_ue->saved.e_cgi.cell_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->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)); 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), ogs_plmn_id_hexdump(&enb_ue->saved.e_cgi.plmn_id),
enb_ue->saved.e_cgi.cell_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->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)); 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), ogs_plmn_id_hexdump(&enb_ue->saved.e_cgi.plmn_id),
enb_ue->saved.e_cgi.cell_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->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)); 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 */ uint16_t vlr_ostream_id; /* SCTP output stream id for VLR */
/* UE Info */ /* UE Info */
uint16_t enb_ostream_id;
ogs_eps_tai_t tai; ogs_eps_tai_t tai;
ogs_e_cgi_t e_cgi; ogs_e_cgi_t e_cgi;
ogs_plmn_id_t last_visited_plmn_id; 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(emmbuf);
ogs_assert(enb_ue); ogs_assert(enb_ue);
ogs_debug("[MME] DownlinkNASTransport"); ogs_debug("DownlinkNASTransport");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = initiatingMessage->procedureCode =
@ -288,12 +287,11 @@ ogs_pkbuf_t *s1ap_build_initial_context_setup_request(
subscription_data = &mme_ue->subscription_data; subscription_data = &mme_ue->subscription_data;
ogs_assert(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)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = 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); enb_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_assert(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)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = initiatingMessage->procedureCode =
@ -782,8 +779,7 @@ ogs_pkbuf_t *s1ap_build_ue_context_release_command(
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_UEContextRelease; 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)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_E_RABSetup; 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); enb_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_assert(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)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_E_RABModify; 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; subscription_data = &mme_ue->subscription_data;
ogs_assert(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)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_E_RABRelease; initiatingMessage->procedureCode = S1AP_ProcedureCode_id_E_RABRelease;
@ -1250,12 +1243,11 @@ ogs_pkbuf_t *s1ap_build_paging(
ogs_assert(mme_ue); ogs_assert(mme_ue);
ogs_debug("[MME] Paging"); ogs_debug("Paging");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_Paging; initiatingMessage->procedureCode = S1AP_ProcedureCode_id_Paging;
@ -1318,8 +1310,7 @@ ogs_pkbuf_t *s1ap_build_paging(
/* Set Paging Identity */ /* Set Paging Identity */
UEPagingID->present = S1AP_UEPagingID_PR_s_TMSI; UEPagingID->present = S1AP_UEPagingID_PR_s_TMSI;
UEPagingID->choice.s_TMSI = UEPagingID->choice.s_TMSI = CALLOC(1, sizeof(S1AP_S_TMSI_t));
CALLOC(1, sizeof(S1AP_S_TMSI_t));
ogs_asn_uint8_to_OCTET_STRING(mme_ue->guti.mme_code, ogs_asn_uint8_to_OCTET_STRING(mme_ue->guti.mme_code,
&UEPagingID->choice.s_TMSI->mMEC); &UEPagingID->choice.s_TMSI->mMEC);
@ -1364,12 +1355,11 @@ ogs_pkbuf_t *s1ap_build_mme_configuration_transfer(
ogs_assert(son_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)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = 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); enb_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_assert(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)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; 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_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
S1AP_Cause_t *Cause = 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)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_unsuccessfulOutcome; 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); ogs_assert(source_ue);
mme_ue = source_ue->mme_ue; mme_ue = source_ue->mme_ue;
ogs_debug("[MME] Handover command"); ogs_debug("Handover command");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; 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(source_ue);
ogs_assert(cause); ogs_assert(cause);
ogs_debug("[MME] Handover preparation failure"); ogs_debug("Handover preparation failure");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_unsuccessfulOutcome; pdu.present = S1AP_S1AP_PDU_PR_unsuccessfulOutcome;
@ -1830,12 +1820,11 @@ ogs_pkbuf_t *s1ap_build_handover_request(
subscription_data = &mme_ue->subscription_data; subscription_data = &mme_ue->subscription_data;
ogs_assert(subscription_data); ogs_assert(subscription_data);
ogs_debug("[MME] Handover request"); ogs_debug("Handover request");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = initiatingMessage->procedureCode =
@ -2040,7 +2029,7 @@ ogs_pkbuf_t *s1ap_build_handover_cancel_ack(enb_ue_t *source_ue)
ogs_assert(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)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome; 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(target_ue);
ogs_assert(enb_statustransfer_transparentContainer); ogs_assert(enb_statustransfer_transparentContainer);
ogs_debug("[MME] MME status transfer"); ogs_debug("MME status transfer");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_MMEStatusTransfer; 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_DataCodingScheme_t *DataCodingScheme = NULL;
S1AP_WarningMessageContents_t *WarningMessageContents = NULL; S1AP_WarningMessageContents_t *WarningMessageContents = NULL;
ogs_debug("[MME] Write-replace warning request"); ogs_debug("Write-replace warning request");
ogs_assert(sbc_pws); ogs_assert(sbc_pws);
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = 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_MessageIdentifier_t *MessageIdentifier = NULL;
S1AP_SerialNumber_t *SerialNumber = NULL; S1AP_SerialNumber_t *SerialNumber = NULL;
ogs_debug("[MME] Kill request"); ogs_debug("Kill request");
ogs_assert(sbc_pws); ogs_assert(sbc_pws);
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t)); memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage = pdu.choice.initiatingMessage = CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
CALLOC(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage; initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_Kill; 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), ogs_plmn_id_hexdump(&enb_ue->saved.e_cgi.plmn_id),
enb_ue->saved.e_cgi.cell_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->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)); 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), ogs_plmn_id_hexdump(&target_ue->saved.e_cgi.plmn_id),
target_ue->saved.e_cgi.cell_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->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)); 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); mme_ue->t3413.pkbuf = ogs_pkbuf_copy(s1apbuf);
ogs_assert(mme_ue->t3413.pkbuf); 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); 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, sgwc_sess_t *sess,
ogs_pfcp_tlv_error_indication_report_t *error_indication_report) 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_bearer_t *bearer = NULL;
sgwc_tunnel_t *tunnel = NULL; sgwc_tunnel_t *tunnel = NULL;

View File

@ -75,6 +75,7 @@ void smf_context_init(void)
self.imsi_hash = ogs_hash_make(); self.imsi_hash = ogs_hash_make();
self.ipv4_hash = ogs_hash_make(); self.ipv4_hash = ogs_hash_make();
self.ipv6_hash = ogs_hash_make(); self.ipv6_hash = ogs_hash_make();
self.n1n2message_hash = ogs_hash_make();
context_initialized = 1; context_initialized = 1;
} }
@ -93,6 +94,8 @@ void smf_context_final(void)
ogs_hash_destroy(self.ipv4_hash); ogs_hash_destroy(self.ipv4_hash);
ogs_assert(self.ipv6_hash); ogs_assert(self.ipv6_hash);
ogs_hash_destroy(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_ue_pool);
ogs_pool_final(&smf_bearer_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) void smf_sess_remove(smf_sess_t *sess)
{ {
int i; int i;
@ -1056,6 +1144,14 @@ void smf_sess_remove(smf_sess_t *sess)
ogs_pfcp_ue_ip_free(sess->ipv6); 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) if (sess->sm_context_ref)
ogs_free(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); 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 *smf_qos_flow_add(smf_sess_t *sess)
{ {
smf_bearer_t *qos_flow = NULL; 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 *imsi_hash; /* hash table (IMSI) */
ogs_hash_t *ipv4_hash; /* hash table (IPv4 Address) */ ogs_hash_t *ipv4_hash; /* hash table (IPv4 Address) */
ogs_hash_t *ipv6_hash; /* hash table (IPv6 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 */ 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 ue_pco;
ogs_tlv_octet_t user_location_information; ogs_tlv_octet_t user_location_information;
ogs_tlv_octet_t ue_timezone; ogs_tlv_octet_t ue_timezone;
bool create_session_response_apn_ambr;
bool create_session_response_bearer_qos;
} gtp; /* Saved from S5-C */ } gtp; /* Saved from S5-C */
struct { 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 */ ogs_pcc_rule_t pcc_rule[OGS_MAX_NUM_OF_PCC_RULE]; /* Saved from Gx */
int num_of_pcc_rule; int num_of_pcc_rule;
/* Paging */
struct { struct {
bool create_session_response_apn_ambr; bool ue_requested_pdu_session_establishment_done;
bool create_session_response_bearer_qos; char *n1n2message_location;
} gtp_5gc; } paging;
/* Release Holding timer of SMF session context */ /* Release Holding timer of SMF session context */
ogs_timer_t *t_release_holding; 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_list_t bearer_list;
ogs_gtp_node_t *gnode; 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_select_upf(smf_sess_t *sess);
void smf_sess_set_ue_ip(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(smf_sess_t *sess);
void smf_sess_remove_all(smf_ue_t *smf_ue); 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_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_ipv4(uint32_t addr);
smf_sess_t *smf_sess_find_by_ipv6(uint32_t *addr6); 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_add(smf_sess_t *sess);
smf_bearer_t *smf_qos_flow_find_by_qfi(smf_sess_t *sess, uint8_t qfi); smf_bearer_t *smf_qos_flow_find_by_qfi(smf_sess_t *sess, uint8_t qfi);

View File

@ -26,6 +26,7 @@
#include "gsm-handler.h" #include "gsm-handler.h"
#include "ngap-handler.h" #include "ngap-handler.h"
#include "pfcp-path.h" #include "pfcp-path.h"
#include "ngap-path.h"
void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e) 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) void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
{ {
int rv; int rv, ngap_state;
char *strerror = NULL; char *strerror = NULL;
smf_ue_t *smf_ue = NULL; smf_ue_t *smf_ue = NULL;
smf_sess_t *sess = 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) CASE(OGS_SBI_SERVICE_NAME_NAMF_COMM)
SWITCH(sbi_message->h.resource.component[0]) SWITCH(sbi_message->h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXTS) 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( smf_namf_comm_handler_n1_n2_message_transfer(
sess, e->sbi.state, sbi_message); sess, e->sbi.state, sbi_message);
break; break;
@ -206,7 +200,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
DEFAULT DEFAULT
ogs_error("[%s:%d] Invalid API name [%s]", ogs_error("[%s:%d] Invalid API name [%s]",
smf_ue->supi, sess->psi, sbi_message->h.service.name); smf_ue->supi, sess->psi, sbi_message->h.service.name);
ogs_assert_if_reached();
END END
break; 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_server_send_error(stream,
OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, strerror, NULL); OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, strerror, NULL);
ogs_free(strerror); ogs_free(strerror);
break;
} }
break; break;
case SMF_EVT_NGAP_MESSAGE: case SMF_EVT_NGAP_MESSAGE:
@ -307,7 +299,33 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
break; break;
case OpenAPI_n2_sm_info_type_PDU_RES_REL_RSP: 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; break;
case OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ: 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: default:
ogs_error("Unknown message[%d]", e->ngap.type); ogs_error("Unknown message[%d]", e->ngap.type);
} }
break; break;
default: default:
ogs_error("Unknown event [%s]", smf_event_get_name(e)); 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 /* APN-AMBR
* if PCRF changes APN-AMBR, this should be included. */ * 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 && if ((gx_message->session_data.pdn.ambr.uplink &&
(sess->pdn.ambr.uplink / 1000) != (sess->pdn.ambr.uplink / 1000) !=
(gx_message->session_data.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.downlink = gx_message->session_data.pdn.ambr.downlink;
sess->pdn.ambr.uplink = gx_message->session_data.pdn.ambr.uplink; 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 /* Bearer QoS
* if PCRF changes Bearer QoS, this should be included. */ * 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 && if ((gx_message->session_data.pdn.qos.qci &&
sess->pdn.qos.qci != 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 && (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 = sess->pdn.qos.arp.pre_emption_vulnerability =
gx_message->session_data.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); 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; return OGS_GTP_CAUSE_SYSTEM_FAILURE;
} }
static int sbi_status_from_pfcp(uint8_t pfcp_cause) static int sbi_status_from_pfcp(uint8_t pfcp_cause)
{ {
switch (pfcp_cause) { switch (pfcp_cause) {
@ -102,8 +103,7 @@ void smf_5gc_n4_handle_session_establishment_response(
{ {
int i; int i;
ogs_pkbuf_t *n1smbuf = NULL; smf_n1_n2_message_transfer_param_t param;
ogs_pkbuf_t *n2smbuf = NULL;
ogs_sbi_stream_t *stream = NULL; ogs_sbi_stream_t *stream = NULL;
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED; 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); ogs_assert(up_f_seid);
sess->upf_n4_seid = be64toh(up_f_seid->seid); sess->upf_n4_seid = be64toh(up_f_seid->seid);
n1smbuf = gsm_build_pdu_session_establishment_accept(sess); memset(&param, 0, sizeof(param));
ogs_assert(n1smbuf); param.state = SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT;
n2smbuf = ngap_build_pdu_session_resource_setup_request_transfer(sess); param.n1smbuf = gsm_build_pdu_session_establishment_accept(sess);
ogs_assert(n2smbuf); 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( smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
sess, SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT,
n1smbuf, n2smbuf);
} }
void smf_5gc_n4_handle_session_modification_response( 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_ACTIVATE) {
if (flags & OGS_PFCP_MODIFY_PATH_SWITCH) { if (flags & OGS_PFCP_MODIFY_PATH_SWITCH) {
ogs_pkbuf_t *n2smbuf = ogs_pkbuf_t *n2smbuf =
ngap_build_path_switch_request_ack_transfer(sess); ngap_build_path_switch_request_ack_transfer(sess);
ogs_assert(n2smbuf); 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); OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ_ACK, n2smbuf);
} else { } else {
/* ACTIVATED Is NOT Included in RESPONSE */ sess->paging.ue_requested_pdu_session_establishment_done = true;
smf_sbi_send_sm_context_updated_data(sess, stream, 0); smf_sbi_send_http_status_no_content(stream);
} }
} else if (flags & OGS_PFCP_MODIFY_DEACTIVATE) { } else if (flags & OGS_PFCP_MODIFY_DEACTIVATE) {
/* Only ACTIVING & DEACTIVATED is Included */ if (flags & OGS_PFCP_MODIFY_ERROR_INDICATION) {
smf_sbi_send_sm_context_updated_data( smf_n1_n2_message_transfer_param_t param;
sess, stream, OpenAPI_up_cnx_state_DEACTIVATED);
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) { } 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); memset(&param, 0, sizeof(param));
n1smbuf = gsm_build_qos_flow_modification_command( param.state = SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION;
param.n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED); qos_flow, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED);
ogs_assert(n1smbuf); ogs_assert(param.n1smbuf);
n2smbuf = ngap_build_qos_flow_resource_modify_request_transfer( param.n2smbuf = ngap_build_qos_flow_resource_modify_request_transfer(
qos_flow); qos_flow);
ogs_assert(n2smbuf); ogs_assert(param.n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer( smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
sess, SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION,
n1smbuf, n2smbuf);
} }
} }
@ -381,9 +397,19 @@ void smf_5gc_n4_handle_session_deletion_response(
ogs_assert(sess); ogs_assert(sess);
if (trigger == OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED) { 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 { } else {
memset(&sendmsg, 0, sizeof(sendmsg)); memset(&sendmsg, 0, sizeof(sendmsg));
@ -643,3 +669,143 @@ void smf_epc_n4_handle_session_deletion_response(
SMF_SESS_CLEAR(sess); 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, smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_deletion_response_t *rsp); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -22,7 +22,7 @@
#include "ngap-build.h" #include "ngap-build.h"
ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer( 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; int i;
smf_ue_t *smf_ue = NULL; 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_message_t message;
ogs_sbi_request_t *request = NULL; 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_n2_message_transfer_req_data_t N1N2MessageTransferReqData;
OpenAPI_n1_message_container_t n1MessageContainer; 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);
ogs_assert(smf_ue->supi); ogs_assert(smf_ue->supi);
ogs_assert(data); ogs_assert(param);
ogs_assert(data->state); ogs_assert(param->state);
ogs_assert(data->n1smbuf); ogs_assert(param->n1smbuf || param->n2smbuf);
ogs_assert(data->n2smbuf);
memset(&message, 0, sizeof(message)); memset(&message, 0, sizeof(message));
message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST; 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)); memset(&N1N2MessageTransferReqData, 0, sizeof(N1N2MessageTransferReqData));
N1N2MessageTransferReqData.pdu_session_id = sess->psi; N1N2MessageTransferReqData.pdu_session_id = sess->psi;
N1N2MessageTransferReqData.n1_message_container = &n1MessageContainer;
N1N2MessageTransferReqData.n2_info_container = &n2InfoContainer;
memset(&n1MessageContainer, 0, sizeof(n1MessageContainer)); if (param->n1smbuf) {
n1MessageContainer.n1_message_class = OpenAPI_n1_message_class_SM; N1N2MessageTransferReqData.n1_message_container = &n1MessageContainer;
n1MessageContainer.n1_message_content = &n1MessageContent;
memset(&n1MessageContent, 0, sizeof(n1MessageContent)); memset(&n1MessageContainer, 0, sizeof(n1MessageContainer));
n1MessageContent.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID; n1MessageContainer.n1_message_class = OpenAPI_n1_message_class_SM;
n1MessageContainer.n1_message_content = &n1MessageContent;
memset(&n2InfoContainer, 0, sizeof(n2InfoContainer)); memset(&n1MessageContent, 0, sizeof(n1MessageContent));
n2InfoContainer.n2_information_class = OpenAPI_n2_information_class_SM; n1MessageContent.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
n2InfoContainer.sm_info = &smInfo;
memset(&smInfo, 0, sizeof(smInfo)); message.part[message.num_of_part].pkbuf = param->n1smbuf;
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].content_id = message.part[message.num_of_part].content_id =
(char *)OGS_SBI_CONTENT_5GNAS_SM_ID; (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
message.part[message.num_of_part].content_type = 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.num_of_part++;
} }
message.part[message.num_of_part].pkbuf = data->n2smbuf; if (param->n2smbuf) {
if (message.part[message.num_of_part].pkbuf) { 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 = message.part[message.num_of_part].content_id =
(char *)OGS_SBI_CONTENT_NGAP_SM_ID; (char *)OGS_SBI_CONTENT_NGAP_SM_ID;
message.part[message.num_of_part].content_type = 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++; 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); request = ogs_sbi_build_request(&message);
ogs_assert(request); ogs_assert(request);
@ -125,6 +148,9 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
if (message.part[i].pkbuf) if (message.part[i].pkbuf)
ogs_pkbuf_free(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; return request;
} }

View File

@ -26,19 +26,24 @@
extern "C" { extern "C" {
#endif #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_N1_N2_MESSAGE_TRANSFER_NO_STATE 0
#define SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT 1 #define SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT 1
#define SMF_NETWORK_REQUESTED_PDU_SESSION_MODIFICATION 2 #define SMF_NETWORK_REQUESTED_PDU_SESSION_MODIFICATION 2
#define SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION 3 #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; int state;
ogs_pkbuf_t *n1smbuf; ogs_pkbuf_t *n1smbuf;
ogs_pkbuf_t *n2smbuf; 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( 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( ogs_sbi_request_t *smf_namf_callback_build_sm_context_status(
smf_sess_t *sess, void *data); smf_sess_t *sess, void *data);

View File

@ -18,23 +18,136 @@
*/ */
#include "sbi-path.h" #include "sbi-path.h"
#include "ngap-path.h"
#include "binding.h" #include "binding.h"
#include "namf-handler.h" #include "namf-handler.h"
bool smf_namf_comm_handler_n1_n2_message_transfer( bool smf_namf_comm_handler_n1_n2_message_transfer(
smf_sess_t *sess, int state, ogs_sbi_message_t *recvmsg) 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); ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
ogs_assert(state); ogs_assert(state);
ogs_assert(recvmsg); ogs_assert(recvmsg);
switch (state) { switch (state) {
case SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT: 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; break;
case SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION: 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; break;
default: default:
@ -44,3 +157,63 @@ bool smf_namf_comm_handler_n1_n2_message_transfer(
return true; 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( bool smf_namf_comm_handler_n1_n2_message_transfer(
smf_sess_t *sess, int state, ogs_sbi_message_t *recvmsg); 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 #ifdef __cplusplus
} }
#endif #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( 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_PDUSessionResourceReleaseCommandTransfer_t message;
NGAP_Cause_t *Cause = NULL; NGAP_Cause_t *Cause = NULL;
ogs_assert(sess);
ogs_assert(state);
sess->ngap_state.pdu_session_resource_release = state;
ogs_debug("PDUSessionResourceReleaseCommandTransfer"); ogs_debug("PDUSessionResourceReleaseCommandTransfer");
memset(&message, 0, memset(&message, 0,
sizeof(NGAP_PDUSessionResourceReleaseCommandTransfer_t)); 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); smf_bearer_t *qos_flow);
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_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);
ogs_pkbuf_t *ngap_build_path_switch_request_ack_transfer(smf_sess_t *sess); 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); sess, stream, OGS_PFCP_MODIFY_ACTIVATE);
} else { } else {
/* ACTIVATED Is NOT Included in RESPONSE */ /* 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; rv = OGS_OK;
@ -343,7 +343,7 @@ int ngap_handle_pdu_session_resource_to_be_switched_dl_transfer(
OGS_PFCP_MODIFY_END_MARKER); OGS_PFCP_MODIFY_END_MARKER);
} else { } else {
/* ACTIVATED Is NOT Included in RESPONSE */ /* 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; rv = OGS_OK;

View File

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

View File

@ -285,7 +285,8 @@ void smf_5gc_pfcp_send_session_modification_request(
ogs_pfcp_xact_t *xact = NULL; ogs_pfcp_xact_t *xact = NULL;
ogs_assert(sess); 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)); memset(&h, 0, sizeof(ogs_pfcp_header_t));
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE; 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); rv = ogs_pfcp_xact_commit(xact);
ogs_expect(rv == OGS_OK); 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( void smf_epc_pfcp_send_session_deletion_request(
smf_sess_t *sess, void *gtp_xact); 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 #ifdef __cplusplus
} }
#endif #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); sess, xact, &message->pfcp_session_deletion_response);
break; 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: default:
ogs_error("Not implemented PFCP message type[%d]", ogs_error("Not implemented PFCP message type[%d]",
message->h.type); message->h.type);

View File

@ -93,7 +93,7 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
/* APN-AMBR /* APN-AMBR
* if PCRF changes APN-AMBR, this should be included. */ * 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)); memset(&ambr, 0, sizeof(ogs_gtp_ambr_t));
ambr.uplink = htobe32(sess->pdn.ambr.uplink / 1000); ambr.uplink = htobe32(sess->pdn.ambr.uplink / 1000);
ambr.downlink = htobe32(sess->pdn.ambr.downlink / 1000); ambr.downlink = htobe32(sess->pdn.ambr.downlink / 1000);
@ -125,7 +125,7 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
/* Bearer QoS /* Bearer QoS
* if PCRF changes Bearer QoS, this should be included. */ * 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)); memset(&bearer_qos, 0, sizeof(bearer_qos));
bearer_qos.qci = sess->pdn.qos.qci; bearer_qos.qci = sess->pdn.qos.qci;
bearer_qos.priority_level = sess->pdn.qos.arp.priority_level; 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( void smf_namf_comm_send_n1_n2_message_transfer(
smf_sess_t *sess, int state, smf_sess_t *sess, smf_n1_n2_message_transfer_param_t *param)
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf)
{ {
ogs_sbi_xact_t *xact = NULL; ogs_sbi_xact_t *xact = NULL;
smf_ue_t *smf_ue = NULL; smf_ue_t *smf_ue = NULL;
smf_n1_n2_message_transfer_data_t data;
ogs_assert(state); ogs_assert(param);
ogs_assert(n1smbuf); ogs_assert(param->state);
ogs_assert(n2smbuf); ogs_assert(param->n1smbuf || param->n2smbuf);
ogs_assert(sess); ogs_assert(sess);
smf_ue = sess->smf_ue; smf_ue = sess->smf_ue;
ogs_assert(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, xact = ogs_sbi_xact_add(OpenAPI_nf_type_AMF, &sess->sbi,
(ogs_sbi_build_f)smf_namf_comm_build_n1_n2_message_transfer, (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); ogs_assert(xact);
xact->state = state; xact->state = param->state;
ogs_sbi_discover_and_send(xact, ogs_sbi_discover_and_send(xact,
(ogs_fsm_handler_t)smf_nf_state_registered, client_cb); (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); ogs_pkbuf_free(n1smbuf);
} }
void smf_sbi_send_sm_context_updated_data(smf_sess_t *sess, void smf_sbi_send_sm_context_updated_data(
ogs_sbi_stream_t *stream, OpenAPI_up_cnx_state_e up_cnx_state) smf_sess_t *sess, ogs_sbi_stream_t *stream,
{ OpenAPI_up_cnx_state_e up_cnx_state,
int status; ogs_pkbuf_t *n1smbuf,
OpenAPI_n2_sm_info_type_e n2type, ogs_pkbuf_t *n2smbuf)
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)
{ {
int i; int i;
@ -285,41 +251,41 @@ void smf_sbi_send_sm_context_updated_data_in_session_deletion(
ogs_assert(sess); ogs_assert(sess);
ogs_assert(stream); ogs_assert(stream);
ogs_assert(up_cnx_state != OpenAPI_up_cnx_state_NULL || n1smbuf || n2smbuf);
memset(&sendmsg, 0, sizeof(sendmsg)); memset(&sendmsg, 0, sizeof(sendmsg));
memset(&SmContextUpdatedData, 0, sizeof(SmContextUpdatedData)); 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; /* n1smbuf */
SmContextUpdatedData.n1_sm_msg = &n1SmMsg; 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 = sendmsg.part[sendmsg.num_of_part].content_id =
(char *)OGS_SBI_CONTENT_5GNAS_SM_ID; (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
sendmsg.part[sendmsg.num_of_part].content_type = sendmsg.part[sendmsg.num_of_part].content_type =
(char *)OGS_SBI_CONTENT_5GNAS_TYPE; (char *)OGS_SBI_CONTENT_5GNAS_TYPE;
sendmsg.part[sendmsg.num_of_part].pkbuf = n1smbuf;
sendmsg.num_of_part++; sendmsg.num_of_part++;
} }
SmContextUpdatedData.n2_sm_info_type = /* n2smbuf */
OpenAPI_n2_sm_info_type_PDU_RES_REL_CMD; if (n2smbuf) {
SmContextUpdatedData.n2_sm_info = &n2SmInfo; 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 = sendmsg.part[sendmsg.num_of_part].content_id =
(char *)OGS_SBI_CONTENT_NGAP_SM_ID; (char *)OGS_SBI_CONTENT_NGAP_SM_ID;
sendmsg.part[sendmsg.num_of_part].content_type = sendmsg.part[sendmsg.num_of_part].content_type =
(char *)OGS_SBI_CONTENT_NGAP_TYPE; (char *)OGS_SBI_CONTENT_NGAP_TYPE;
sendmsg.part[sendmsg.num_of_part].pkbuf = n2smbuf;
sendmsg.num_of_part++; 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); response = ogs_sbi_build_response(&sendmsg, OGS_SBI_HTTP_STATUS_OK);
ogs_assert(response); ogs_assert(response);
ogs_sbi_server_send_response(stream, response); ogs_sbi_server_send_response(stream, response);
for (i = 0; i < sendmsg.num_of_part; i++) 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); ogs_assert(sess);
client = sess->namf.client; client = sess->namf.client;
ogs_assert(client); ogs_assert(client);
client->cb = client_cb;
request = smf_namf_callback_build_sm_context_status(sess, NULL); request = smf_namf_callback_build_sm_context_status(sess, NULL);
ogs_assert(request); ogs_assert(request);
ogs_sbi_client_send_request(client, client_notify_cb, request, NULL); 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)); ogs_sbi_request_t *(*build)(smf_sess_t *sess, void *data));
void smf_namf_comm_send_n1_n2_message_transfer( void smf_namf_comm_send_n1_n2_message_transfer(
smf_sess_t *sess, int state, smf_sess_t *sess, smf_n1_n2_message_transfer_param_t *param);
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf);
#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_response(ogs_sbi_stream_t *stream, int status);
void smf_sbi_send_sm_context_create_error( void smf_sbi_send_sm_context_create_error(
ogs_sbi_stream_t *stream, ogs_sbi_stream_t *stream,
int status, const char *title, const char *detail, int status, const char *title, const char *detail,
ogs_pkbuf_t *n1smbuf); 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); #define smf_sbi_send_sm_context_updated_data_up_cnx_state( \
void smf_sbi_send_sm_context_updated_data_in_session_deletion( __sESS, __sTREAM, __uPCnxState) \
smf_sess_t *sess, ogs_sbi_stream_t *stream); 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( void smf_sbi_send_sm_context_update_error(
ogs_sbi_stream_t *stream, ogs_sbi_stream_t *stream,
int status, const char *title, const char *detail, int status, const char *title, const char *detail,
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf); 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); void smf_sbi_send_sm_context_status_notify(smf_sess_t *sess);

View File

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

View File

@ -37,6 +37,7 @@
#include "event.h" #include "event.h"
#include "gtp-path.h" #include "gtp-path.h"
#include "pfcp-path.h"
#include "rule-match.h" #include "rule-match.h"
#define UPF_GTP_HANDLED 1 #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; ogs_pkbuf_t *recvbuf = NULL;
int n; int n;
upf_sess_t *sess = NULL;
ogs_pfcp_pdr_t *pdr = NULL; ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_user_plane_report_t report; 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) { if (pdr) {
/* Unicast */ /* Unicast */
ogs_pfcp_up_handle_pdr(pdr, recvbuf, &report); 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 { } else {
if (ogs_app()->parameter.multicast) { if (ogs_app()->parameter.multicast) {
upf_gtp_handle_multicast(recvbuf); 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; ssize_t size;
char buf[OGS_ADDRSTRLEN]; char buf[OGS_ADDRSTRLEN];
upf_sess_t *sess = NULL;
ogs_pkbuf_t *pkbuf = NULL; ogs_pkbuf_t *pkbuf = NULL;
ogs_sockaddr_t from; ogs_sockaddr_t from;
ogs_gtp_header_t *gtp_h = NULL; ogs_gtp_header_t *gtp_h = NULL;
#if 0
ogs_pfcp_user_plane_report_t report; ogs_pfcp_user_plane_report_t report;
#endif
uint32_t teid; uint32_t teid;
uint8_t qfi; uint8_t qfi;
@ -188,7 +203,24 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
/* Nothing */ /* Nothing */
} else if (gtp_h->type == OGS_GTPU_MSGTYPE_ERR_IND) { } 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) { } else if (gtp_h->type == OGS_GTPU_MSGTYPE_GPDU) {
int rv; int rv;

View File

@ -431,3 +431,39 @@ void upf_n4_handle_session_deletion_request(
upf_sess_remove(sess); 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, upf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_deletion_request_t *req); 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 #ifdef __cplusplus
} }
#endif #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); rv = ogs_pfcp_xact_commit(xact);
ogs_expect(rv == OGS_OK); 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, void upf_pfcp_send_session_deletion_response(ogs_pfcp_xact_t *xact,
upf_sess_t *sess); upf_sess_t *sess);
void upf_pfcp_send_session_report_request(
upf_sess_t *sess, ogs_pfcp_user_plane_report_t *report);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #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( upf_n4_handle_session_deletion_request(
sess, xact, &message->pfcp_session_deletion_request); sess, xact, &message->pfcp_session_deletion_request);
break; break;
case OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE:
upf_n4_handle_session_report_response(
sess, xact, &message->pfcp_session_report_response);
break;
default: default:
ogs_error("Not implemented PFCP message type[%d]", ogs_error("Not implemented PFCP message type[%d]",
message->h.type); 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); testngap_handle_pdu_session_resource_release_command(test_ue, pdu);
break; break;
case NGAP_ProcedureCode_id_ErrorIndication: case NGAP_ProcedureCode_id_ErrorIndication:
case NGAP_ProcedureCode_id_Paging:
/* Nothing */ /* Nothing */
break; break;
default: default:

View File

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

View File

@ -902,18 +902,22 @@ static void test3_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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); recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf); testngap_recv(test_ue, recvbuf);
/* Send PDU session resource release response */ /* Send PDUSessionResourceReleaseResponse */
sendbuf = testngap_build_pdu_session_resource_release_response(sess); sendbuf = testngap_build_pdu_session_resource_release_response(sess);
ABTS_PTR_NOTNULL(tc, sendbuf); ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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.request_type = 0;
sess->ul_nas_transport_param.dnn = 0; sess->ul_nas_transport_param.dnn = 0;
sess->ul_nas_transport_param.s_nssai = 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); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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); recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf); testngap_recv(test_ue, recvbuf);
/* Send PDU session resource release response */ /* Send PDUSessionResourceReleaseResponse */
sendbuf = sendbuf = testngap_build_pdu_session_resource_release_response(sess);
testngap_build_pdu_session_resource_release_response(sess);
ABTS_PTR_NOTNULL(tc, sendbuf); ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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.request_type = 0;
sess->ul_nas_transport_param.dnn = 0; sess->ul_nas_transport_param.dnn = 0;
sess->ul_nas_transport_param.s_nssai = 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); ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf); testngap_recv(test_ue, recvbuf);
/* TODO : we need to analyze it */
ogs_msleep(100); ogs_msleep(100);
/* Send Identity response */ /* Send Identity response */

View File

@ -316,6 +316,7 @@ static void test1_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* TODO : we need to analyze it */
ogs_msleep(100); ogs_msleep(100);
/* Send De-registration request */ /* Send De-registration request */
@ -358,7 +359,15 @@ static void test1_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, 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); ogs_msleep(100);
#endif
/* INVALID SUCI */ /* INVALID SUCI */
test_ue->mobile_identity_suci.scheme_output[0] = 0x99; 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); recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, 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 */ /* Receive UE context release command */
recvbuf = testgnb_ngap_read(ngap); 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); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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 + * Send InitialUEMessage +
* Service request * Service request
@ -357,10 +353,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */ /* Wait to setup N3 data connection.
recvbuf = testgnb_gtpu_read(gtpu); * Otherwise, network-triggered service request is initiated */
ABTS_PTR_NOTNULL(tc, recvbuf); ogs_msleep(100);
ogs_pkbuf_free(recvbuf);
/* Send GTP-U ICMP Packet */ /* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); 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); ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, 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 */ /* Send UE context release complete */
sendbuf = testngap_build_ue_context_release_complete(test_ue); sendbuf = testngap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf); ABTS_PTR_NOTNULL(tc, sendbuf);
@ -436,10 +427,9 @@ static void test1_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */ /* Wait to setup N3 data connection.
recvbuf = testgnb_gtpu_read(gtpu); * Otherwise, network-triggered service request is initiated */
ABTS_PTR_NOTNULL(tc, recvbuf); ogs_msleep(100);
ogs_pkbuf_free(recvbuf);
/* Send GTP-U ICMP Packet */ /* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); 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); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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 + * Send InitialUEMessage +
* Service request * Service request
@ -2542,10 +2528,9 @@ static void test6_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */ /* Wait to setup N3 data connection.
recvbuf = testgnb_gtpu_read(gtpu); * Otherwise, network-triggered service request is initiated */
ABTS_PTR_NOTNULL(tc, recvbuf); ogs_msleep(100);
ogs_pkbuf_free(recvbuf);
/* Send GTP-U ICMP Packet */ /* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);

View File

@ -21,6 +21,7 @@ test5gc_registration_sources = files('''
auth-test.c auth-test.c
idle-test.c idle-test.c
dereg-test.c dereg-test.c
paging-test.c
identity-test.c identity-test.c
gmm-status-test.c gmm-status-test.c
ue-context-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); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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); recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf); testngap_recv(test_ue, recvbuf);
/* Send PDU session resource release response */ /* Send PDUSessionResourceReleaseResponse */
sendbuf = testngap_build_pdu_session_resource_release_response(sess); sendbuf = testngap_build_pdu_session_resource_release_response(sess);
ABTS_PTR_NOTNULL(tc, sendbuf); ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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.request_type = 0;
sess->ul_nas_transport_param.dnn = 0; sess->ul_nas_transport_param.dnn = 0;
sess->ul_nas_transport_param.s_nssai = 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); ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, 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 */ /* Send UE context release complete */
sendbuf = testngap_build_ue_context_release_complete(test_ue); sendbuf = testngap_build_ue_context_release_complete(test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf); ABTS_PTR_NOTNULL(tc, sendbuf);
@ -1476,10 +1476,9 @@ static void test4_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */ /* Wait to setup N3 data connection.
recvbuf = testgnb_gtpu_read(gtpu); * Otherwise, network-triggered service request is initiated */
ABTS_PTR_NOTNULL(tc, recvbuf); ogs_msleep(100);
ogs_pkbuf_free(recvbuf);
/* Send GTP-U ICMP Packet */ /* Send GTP-U ICMP Packet */
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4); 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_status);
ABTS_INT_EQUAL(tc, 0x0000, test_ue->pdu_session_reactivation_result); 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 */ /* Send Initial context setup response */
sendbuf = testngap_build_initial_context_setup_response(test_ue, true); sendbuf = testngap_build_initial_context_setup_response(test_ue, true);
ABTS_PTR_NOTNULL(tc, sendbuf); ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf); rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv); 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 */ /* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu); recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf); ABTS_PTR_NOTNULL(tc, recvbuf);

File diff suppressed because it is too large Load Diff