forked from acouzens/open5gs
Add PDU Session Release [#488]
This commit is contained in:
parent
8afc4b7887
commit
d9743286c5
|
@ -61,6 +61,13 @@ typedef struct ogs_pfcp_xact_s {
|
|||
uint8_t holding_rcount;
|
||||
|
||||
void *assoc_xact; /**< Associated GTP transaction */
|
||||
#define OGS_PFCP_5GC_DELETE_TRIGGER_UE_REQUESTED 1
|
||||
#define OGS_PFCP_5GC_DELETE_TRIGGER_PCF_INITIATED 2
|
||||
#define OGS_PFCP_5GC_DELETE_TRIGGER_RAN_INITIATED 3
|
||||
#define OGS_PFCP_5GC_DELETE_TRIGGER_SMF_INITIATED 4
|
||||
#define OGS_PFCP_5GC_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT 5
|
||||
#define OGS_PFCP_5GC_DELETE_TRIGGER_AMF_UPDATE_SM_CONTEXT 6
|
||||
int trigger;
|
||||
} ogs_pfcp_xact_t;
|
||||
|
||||
int ogs_pfcp_xact_init(ogs_timer_mgr_t *timer_mgr, int size);
|
||||
|
|
|
@ -133,6 +133,9 @@ void ogs_sbi_message_free(ogs_sbi_message_t *message)
|
|||
if (message->N1N2MessageTransferRspData)
|
||||
OpenAPI_n1_n2_message_transfer_rsp_data_free(
|
||||
message->N1N2MessageTransferRspData);
|
||||
if (message->SmContextStatusNotification)
|
||||
OpenAPI_sm_context_status_notification_free(
|
||||
message->SmContextStatusNotification);
|
||||
|
||||
for (i = 0; i < message->num_of_part; i++) {
|
||||
if (message->part[i].pkbuf)
|
||||
|
@ -709,6 +712,10 @@ static char *build_json(ogs_sbi_message_t *message)
|
|||
item = OpenAPI_n1_n2_message_transfer_rsp_data_convertToJSON(
|
||||
message->N1N2MessageTransferRspData);
|
||||
ogs_assert(item);
|
||||
} else if (message->SmContextStatusNotification) {
|
||||
item = OpenAPI_sm_context_status_notification_convertToJSON(
|
||||
message->SmContextStatusNotification);
|
||||
ogs_assert(item);
|
||||
}
|
||||
|
||||
if (item) {
|
||||
|
@ -1234,6 +1241,23 @@ static int parse_json(ogs_sbi_message_t *message,
|
|||
message->h.resource.component[0]);
|
||||
END
|
||||
break;
|
||||
CASE(OGS_SBI_SERVICE_NAME_NAMF_CALLBACK)
|
||||
SWITCH(message->h.resource.component[1])
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SM_CONTEXT_STATUS)
|
||||
message->SmContextStatusNotification =
|
||||
OpenAPI_sm_context_status_notification_parseFromJSON(item);
|
||||
if (!message->SmContextStatusNotification) {
|
||||
rv = OGS_ERROR;
|
||||
ogs_error("JSON parse error");
|
||||
}
|
||||
break;
|
||||
|
||||
DEFAULT
|
||||
rv = OGS_ERROR;
|
||||
ogs_error("Unknown resource name [%s]",
|
||||
message->h.resource.component[1]);
|
||||
END
|
||||
break;
|
||||
|
||||
DEFAULT
|
||||
rv = OGS_ERROR;
|
||||
|
|
|
@ -252,6 +252,7 @@ typedef struct ogs_sbi_message_s {
|
|||
SessionManagementSubscriptionData;
|
||||
OpenAPI_n1_n2_message_transfer_req_data_t *N1N2MessageTransferReqData;
|
||||
OpenAPI_n1_n2_message_transfer_rsp_data_t *N1N2MessageTransferRspData;
|
||||
OpenAPI_sm_context_status_notification_t *SmContextStatusNotification;
|
||||
|
||||
ogs_sbi_links_t *links;
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "model/session_management_subscription_data.h"
|
||||
#include "model/n1_n2_message_transfer_req_data.h"
|
||||
#include "model/n1_n2_message_transfer_rsp_data.h"
|
||||
#include "model/sm_context_status_notification.h"
|
||||
|
||||
#include "custom/links.h"
|
||||
|
||||
|
|
|
@ -229,6 +229,23 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
|
|||
END
|
||||
break;
|
||||
|
||||
CASE(OGS_SBI_SERVICE_NAME_NAMF_CALLBACK)
|
||||
SWITCH(sbi_message.h.resource.component[1])
|
||||
CASE(OGS_SBI_RESOURCE_NAME_SM_CONTEXT_STATUS)
|
||||
amf_namf_callback_handle_sm_context_status(
|
||||
session, &sbi_message);
|
||||
break;
|
||||
|
||||
DEFAULT
|
||||
ogs_error("Invalid resource name [%s]",
|
||||
sbi_message.h.resource.component[1]);
|
||||
ogs_sbi_server_send_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST, &sbi_message,
|
||||
"Invalid resource name",
|
||||
sbi_message.h.resource.component[1]);
|
||||
END
|
||||
break;
|
||||
|
||||
DEFAULT
|
||||
ogs_error("Invalid API name [%s]", sbi_message.h.service.name);
|
||||
ogs_sbi_server_send_error(session,
|
||||
|
|
|
@ -403,7 +403,6 @@ typedef struct amf_sess_s {
|
|||
/* SMF session context is activated or not */
|
||||
OpenAPI_up_cnx_state_e smfUpCnxState;
|
||||
|
||||
OpenAPI_n2_sm_info_type_e n2SmInfoType;
|
||||
ogs_pkbuf_t *n2smbuf;
|
||||
|
||||
/* last payload for sending back to the UE */
|
||||
|
|
|
@ -773,14 +773,16 @@ int gmm_handle_security_mode_complete(amf_ue_t *amf_ue,
|
|||
int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
|
||||
ogs_nas_5gs_ul_nas_transport_t *ul_nas_transport)
|
||||
{
|
||||
amf_sess_t *sess = NULL;
|
||||
amf_nsmf_pdu_session_update_sm_context_param_t param;
|
||||
|
||||
ogs_nas_payload_container_type_t *payload_container_type = NULL;
|
||||
ogs_nas_payload_container_t *payload_container = NULL;
|
||||
ogs_nas_pdu_session_identity_2_t *pdu_session_id = NULL;
|
||||
ogs_nas_s_nssai_t *nas_s_nssai = NULL;
|
||||
ogs_s_nssai_t *selected_s_nssai = NULL;
|
||||
ogs_nas_dnn_t *dnn = NULL;
|
||||
|
||||
amf_sess_t *sess = NULL;
|
||||
ogs_nas_5gsm_header_t *gsm_header = NULL;
|
||||
|
||||
ogs_assert(amf_ue);
|
||||
ogs_assert(ul_nas_transport);
|
||||
|
@ -792,16 +794,22 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
|
|||
|
||||
if (!payload_container_type->value) {
|
||||
ogs_error("[%s] No Payload container type", amf_ue->supi);
|
||||
nas_5gs_send_gmm_status(
|
||||
amf_ue, OGS_5GMM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
if (!payload_container->length) {
|
||||
ogs_error("[%s] No Payload container length", amf_ue->supi);
|
||||
nas_5gs_send_gmm_status(
|
||||
amf_ue, OGS_5GMM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
if (!payload_container->buffer) {
|
||||
ogs_error("[%s] No Payload container buffer", amf_ue->supi);
|
||||
nas_5gs_send_gmm_status(
|
||||
amf_ue, OGS_5GMM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
|
@ -814,9 +822,14 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
|
|||
dnn = &ul_nas_transport->dnn;
|
||||
ogs_assert(dnn);
|
||||
|
||||
gsm_header = (ogs_nas_5gsm_header_t *)payload_container->buffer;
|
||||
ogs_assert(gsm_header);
|
||||
|
||||
if ((ul_nas_transport->presencemask &
|
||||
OGS_NAS_5GS_UL_NAS_TRANSPORT_PDU_SESSION_ID_PRESENT) == 0) {
|
||||
ogs_error("[%s] No PDU session ID", amf_ue->supi);
|
||||
nas_5gs_send_gmm_status(
|
||||
amf_ue, OGS_5GMM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
|
@ -824,6 +837,8 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
|
|||
if (*pdu_session_id == OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED) {
|
||||
ogs_error("[%s] PDU session identity is unassigned",
|
||||
amf_ue->supi);
|
||||
nas_5gs_send_gmm_status(
|
||||
amf_ue, OGS_5GMM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
|
@ -872,18 +887,42 @@ int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
|
|||
if (ul_nas_transport->presencemask &
|
||||
OGS_NAS_5GS_UL_NAS_TRANSPORT_DNN_PRESENT) {
|
||||
if (sess->dnn)
|
||||
ogs_free(dnn);
|
||||
ogs_free(sess->dnn);
|
||||
sess->dnn = ogs_strdup(dnn->value);
|
||||
}
|
||||
|
||||
amf_sess_sbi_discover_and_send(
|
||||
OpenAPI_nf_type_SMF, sess, NULL,
|
||||
amf_nsmf_pdu_session_build_create_sm_context);
|
||||
if (gsm_header->message_type ==
|
||||
OGS_NAS_5GS_PDU_SESSION_ESTABLISHMENT_REQUEST) {
|
||||
|
||||
amf_sess_sbi_discover_and_send(
|
||||
OpenAPI_nf_type_SMF, sess, NULL,
|
||||
amf_nsmf_pdu_session_build_create_sm_context);
|
||||
|
||||
} else {
|
||||
|
||||
if (!SESSION_CONTEXT_IN_SMF(sess)) {
|
||||
ogs_error("[%s] Session Context is not in SMF [%d]",
|
||||
amf_ue->supi, sess->psi);
|
||||
nas_5gs_send_back_5gsm_message(sess,
|
||||
OGS_5GSM_CAUSE_PDU_SESSION_DOES_NOT_EXIST);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.n1smbuf = sess->payload_container;
|
||||
|
||||
amf_sess_sbi_discover_and_send(
|
||||
OpenAPI_nf_type_SMF, sess, ¶m,
|
||||
amf_nsmf_pdu_session_build_update_sm_context);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_error("[%s] Unknown Payload container type [%d]",
|
||||
amf_ue->supi, payload_container_type->value);
|
||||
nas_5gs_send_gmm_status(amf_ue,
|
||||
OGS_5GMM_CAUSE_MESSAGE_TYPE_NON_EXISTENT_OR_NOT_IMPLEMENTED);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
|
|
|
@ -299,12 +299,8 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
|
|||
break;
|
||||
|
||||
case OGS_NAS_5GS_UL_NAS_TRANSPORT:
|
||||
rv = gmm_handle_ul_nas_transport(
|
||||
gmm_handle_ul_nas_transport(
|
||||
amf_ue, &nas_message->gmm.ul_nas_transport);
|
||||
if (rv != OGS_OK) {
|
||||
nas_5gs_send_gmm_status(
|
||||
amf_ue, OGS_5GMM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -158,3 +158,84 @@ int amf_namf_comm_handle_n1_n2_message_transfer(
|
|||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
int amf_namf_callback_handle_sm_context_status(
|
||||
ogs_sbi_session_t *session, ogs_sbi_message_t *recvmsg)
|
||||
{
|
||||
int status = OGS_SBI_HTTP_STATUS_NO_CONTENT;
|
||||
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
amf_sess_t *sess = NULL;
|
||||
|
||||
uint8_t pdu_session_identity;
|
||||
|
||||
ogs_sbi_message_t sendmsg;
|
||||
ogs_sbi_response_t *response = NULL;
|
||||
|
||||
OpenAPI_sm_context_status_notification_t *SmContextStatusNotification;
|
||||
OpenAPI_status_info_t *StatusInfo;
|
||||
|
||||
ogs_assert(session);
|
||||
ogs_assert(recvmsg);
|
||||
|
||||
if (!recvmsg->h.resource.component[0]) {
|
||||
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
|
||||
ogs_error("No SUPI");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
amf_ue = amf_ue_find_by_supi(recvmsg->h.resource.component[0]);
|
||||
if (!amf_ue) {
|
||||
status = OGS_SBI_HTTP_STATUS_NOT_FOUND;
|
||||
ogs_error("Cannot find SUPI [%s]", recvmsg->h.resource.component[0]);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!recvmsg->h.resource.component[2]) {
|
||||
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
|
||||
ogs_error("[%s] No PDU Session Identity", amf_ue->supi);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
pdu_session_identity = atoi(recvmsg->h.resource.component[2]);
|
||||
if (pdu_session_identity == OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED) {
|
||||
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
|
||||
ogs_error("[%s] PDU Session Identity is unassigned", amf_ue->supi);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sess = amf_sess_find_by_psi(amf_ue, pdu_session_identity);
|
||||
if (!sess) {
|
||||
status = OGS_SBI_HTTP_STATUS_NOT_FOUND;
|
||||
ogs_error("[%s] Cannot find session [%d]", amf_ue->supi, sess->psi);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
SmContextStatusNotification = recvmsg->SmContextStatusNotification;
|
||||
if (!SmContextStatusNotification) {
|
||||
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
|
||||
ogs_error("No SmContextStatusNotification");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
StatusInfo = SmContextStatusNotification->status_info;
|
||||
if (!StatusInfo) {
|
||||
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
|
||||
ogs_error("No StatusInfo");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (StatusInfo->resource_status == OpenAPI_resource_status_RELEASED) {
|
||||
ogs_info("[%s:%d] Session Released", amf_ue->supi, sess->psi);
|
||||
amf_sess_remove(sess);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
memset(&sendmsg, 0, sizeof(sendmsg));
|
||||
|
||||
response = ogs_sbi_build_response(&sendmsg, status);
|
||||
ogs_assert(response);
|
||||
ogs_sbi_server_send_response(session, response);
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ extern "C" {
|
|||
|
||||
int amf_namf_comm_handle_n1_n2_message_transfer(
|
||||
ogs_sbi_session_t *session, ogs_sbi_message_t *recvmsg);
|
||||
int amf_namf_callback_handle_sm_context_status(
|
||||
ogs_sbi_session_t *session, ogs_sbi_message_t *recvmsg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -328,6 +328,34 @@ void nas_send_pdu_session_establishment_accept(amf_sess_t *sess,
|
|||
ogs_expect(rv == OGS_OK);
|
||||
}
|
||||
|
||||
void nas_send_pdu_session_release_command(amf_sess_t *sess,
|
||||
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf)
|
||||
{
|
||||
int rv;
|
||||
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
|
||||
ogs_pkbuf_t *gmmbuf = NULL;
|
||||
ogs_pkbuf_t *ngapbuf = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
amf_ue = sess->amf_ue;
|
||||
ogs_assert(amf_ue);
|
||||
ogs_assert(n1smbuf);
|
||||
ogs_assert(n2smbuf);
|
||||
|
||||
gmmbuf = gmm_build_dl_nas_transport(sess,
|
||||
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0);
|
||||
ogs_expect_or_return(gmmbuf);
|
||||
|
||||
ngapbuf = ngap_build_pdu_session_resource_release_command(
|
||||
sess, gmmbuf, n2smbuf);
|
||||
ogs_expect_or_return(ngapbuf);
|
||||
|
||||
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
}
|
||||
|
||||
void nas_5gs_send_gmm_status(amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t cause)
|
||||
{
|
||||
int rv;
|
||||
|
|
|
@ -56,6 +56,8 @@ void nas_5gs_send_configuration_update_command(
|
|||
|
||||
void nas_send_pdu_session_establishment_accept(amf_sess_t *sess,
|
||||
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf);
|
||||
void nas_send_pdu_session_release_command(amf_sess_t *sess,
|
||||
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf);
|
||||
|
||||
void nas_5gs_send_gmm_status(amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t cause);
|
||||
|
||||
|
|
|
@ -909,6 +909,113 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request(
|
|||
return nga_ngap_encode(&pdu);
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command(
|
||||
amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf)
|
||||
{
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
ran_ue_t *ran_ue = NULL;
|
||||
|
||||
NGAP_NGAP_PDU_t pdu;
|
||||
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
|
||||
NGAP_PDUSessionResourceReleaseCommand_t *PDUSessionResourceReleaseCommand;
|
||||
|
||||
NGAP_PDUSessionResourceReleaseCommandIEs_t *ie = NULL;
|
||||
NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL;
|
||||
NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL;
|
||||
NGAP_NAS_PDU_t *NAS_PDU = NULL;
|
||||
|
||||
NGAP_PDUSessionResourceToReleaseListRelCmd_t *PDUSessionList = NULL;
|
||||
NGAP_PDUSessionResourceToReleaseItemRelCmd_t *PDUSessionItem = NULL;
|
||||
OCTET_STRING_t *transfer = NULL;
|
||||
|
||||
ogs_assert(gmmbuf);
|
||||
ogs_assert(n2smbuf);
|
||||
ogs_assert(sess);
|
||||
|
||||
amf_ue = sess->amf_ue;
|
||||
ogs_assert(amf_ue);
|
||||
ran_ue = amf_ue->ran_ue;
|
||||
ogs_assert(ran_ue);
|
||||
|
||||
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_initiatingMessage;
|
||||
pdu.choice.initiatingMessage = CALLOC(1, sizeof(NGAP_InitiatingMessage_t));
|
||||
|
||||
initiatingMessage = pdu.choice.initiatingMessage;
|
||||
initiatingMessage->procedureCode =
|
||||
NGAP_ProcedureCode_id_PDUSessionResourceRelease;
|
||||
initiatingMessage->criticality = NGAP_Criticality_reject;
|
||||
initiatingMessage->value.present =
|
||||
NGAP_InitiatingMessage__value_PR_PDUSessionResourceReleaseCommand;
|
||||
|
||||
PDUSessionResourceReleaseCommand =
|
||||
&initiatingMessage->value.choice.PDUSessionResourceReleaseCommand;
|
||||
|
||||
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceReleaseCommandIEs_t));
|
||||
ASN_SEQUENCE_ADD(&PDUSessionResourceReleaseCommand->protocolIEs, ie);
|
||||
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present =
|
||||
NGAP_PDUSessionResourceReleaseCommandIEs__value_PR_AMF_UE_NGAP_ID;
|
||||
|
||||
AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID;
|
||||
|
||||
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceReleaseCommandIEs_t));
|
||||
ASN_SEQUENCE_ADD(&PDUSessionResourceReleaseCommand->protocolIEs, ie);
|
||||
|
||||
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present =
|
||||
NGAP_PDUSessionResourceReleaseCommandIEs__value_PR_RAN_UE_NGAP_ID;
|
||||
|
||||
RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID;
|
||||
|
||||
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;
|
||||
|
||||
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceReleaseCommandIEs_t));
|
||||
ASN_SEQUENCE_ADD(&PDUSessionResourceReleaseCommand->protocolIEs, ie);
|
||||
|
||||
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceToReleaseListRelCmd;
|
||||
ie->criticality = NGAP_Criticality_reject;
|
||||
ie->value.present = NGAP_PDUSessionResourceReleaseCommandIEs__value_PR_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 =
|
||||
CALLOC(1, sizeof(struct NGAP_PDUSessionResourceToReleaseItemRelCmd));
|
||||
ASN_SEQUENCE_ADD(&PDUSessionList->list, PDUSessionItem);
|
||||
|
||||
PDUSessionItem->pDUSessionID = sess->psi;
|
||||
|
||||
transfer = &PDUSessionItem->pDUSessionResourceReleaseCommandTransfer;
|
||||
transfer->size = n2smbuf->len;
|
||||
transfer->buf = CALLOC(transfer->size, sizeof(uint8_t));
|
||||
memcpy(transfer->buf, n2smbuf->data, transfer->size);
|
||||
ogs_pkbuf_free(n2smbuf);
|
||||
|
||||
return nga_ngap_encode(&pdu);
|
||||
}
|
||||
|
||||
#if 0
|
||||
ogs_pkbuf_t *ngap_build_paging(
|
||||
amf_ue_t *amf_ue, NGAP_CNDomain_t cn_domain)
|
||||
|
|
|
@ -41,10 +41,8 @@ ogs_pkbuf_t *ngap_build_ue_context_release_command(
|
|||
|
||||
ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request(
|
||||
amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf);
|
||||
ogs_pkbuf_t *ngap_build_e_rab_modify_request(
|
||||
amf_bearer_t *bearer, ogs_pkbuf_t *gsmbuf);
|
||||
ogs_pkbuf_t *ngap_build_e_rab_release_command(
|
||||
amf_bearer_t *bearer, ogs_pkbuf_t *gsmbuf, NGAP_Cause_PR group, long cause);
|
||||
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command(
|
||||
amf_sess_t *sess, ogs_pkbuf_t *gmmbuf, ogs_pkbuf_t *n2smbuf);
|
||||
|
||||
#if 0
|
||||
ogs_pkbuf_t *ngap_build_paging(
|
||||
|
|
|
@ -771,6 +771,7 @@ void ngap_handle_initial_context_setup_response(
|
|||
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.n2smbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
|
||||
param.n2SmInfoType = OpenAPI_n2_sm_info_type_PDU_RES_SETUP_RSP;
|
||||
ogs_pkbuf_put_data(param.n2smbuf, transfer->buf, transfer->size);
|
||||
|
||||
amf_sess_sbi_discover_and_send(
|
||||
|
@ -1412,6 +1413,164 @@ void ngap_handle_pdu_session_resource_setup_response(
|
|||
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.n2smbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
|
||||
param.n2SmInfoType = OpenAPI_n2_sm_info_type_PDU_RES_SETUP_RSP;
|
||||
ogs_pkbuf_put_data(param.n2smbuf, transfer->buf, transfer->size);
|
||||
|
||||
amf_sess_sbi_discover_and_send(
|
||||
OpenAPI_nf_type_SMF, sess, ¶m,
|
||||
amf_nsmf_pdu_session_build_update_sm_context);
|
||||
|
||||
ogs_pkbuf_free(param.n2smbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void ngap_handle_pdu_session_resource_release_response(
|
||||
amf_gnb_t *gnb, ogs_ngap_message_t *message)
|
||||
{
|
||||
char buf[OGS_ADDRSTRLEN];
|
||||
int i;
|
||||
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
ran_ue_t *ran_ue = NULL;
|
||||
uint64_t amf_ue_ngap_id;
|
||||
amf_nsmf_pdu_session_update_sm_context_param_t param;
|
||||
|
||||
NGAP_SuccessfulOutcome_t *successfulOutcome = NULL;
|
||||
NGAP_PDUSessionResourceReleaseResponse_t *PDUSessionResourceReleaseResponse;
|
||||
|
||||
NGAP_PDUSessionResourceReleaseResponseIEs_t *ie = NULL;
|
||||
NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL;
|
||||
NGAP_PDUSessionResourceReleasedListRelRes_t *PDUSessionList = NULL;
|
||||
NGAP_PDUSessionResourceReleasedItemRelRes_t *PDUSessionItem = NULL;
|
||||
OCTET_STRING_t *transfer = NULL;
|
||||
|
||||
ogs_assert(gnb);
|
||||
ogs_assert(gnb->sock);
|
||||
|
||||
ogs_assert(message);
|
||||
successfulOutcome = message->choice.successfulOutcome;
|
||||
ogs_assert(successfulOutcome);
|
||||
PDUSessionResourceReleaseResponse =
|
||||
&successfulOutcome->value.choice.PDUSessionResourceReleaseResponse;
|
||||
ogs_assert(PDUSessionResourceReleaseResponse);
|
||||
|
||||
ogs_debug("PDU session resource release response");
|
||||
|
||||
for (i = 0; i < PDUSessionResourceReleaseResponse->protocolIEs.list.count;
|
||||
i++) {
|
||||
ie = PDUSessionResourceReleaseResponse->protocolIEs.list.array[i];
|
||||
switch (ie->id) {
|
||||
case NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID:
|
||||
AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID;
|
||||
break;
|
||||
case NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes:
|
||||
PDUSessionList =
|
||||
&ie->value.choice.PDUSessionResourceReleasedListRelRes;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ogs_debug(" IP[%s] RAN_ID[%d]", OGS_ADDR(gnb->addr, buf), gnb->gnb_id);
|
||||
|
||||
if (!AMF_UE_NGAP_ID) {
|
||||
ogs_error("No AMF_UE_NGAP_ID");
|
||||
ngap_send_error_indication(gnb, NULL, NULL,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (asn_INTEGER2ulong(AMF_UE_NGAP_ID,
|
||||
(unsigned long *)&amf_ue_ngap_id) != 0) {
|
||||
ogs_error("Invalid AMF_UE_NGAP_ID");
|
||||
ngap_send_error_indication(gnb, NULL, NULL,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error);
|
||||
return;
|
||||
}
|
||||
|
||||
ran_ue = ran_ue_find_by_amf_ue_ngap_id(amf_ue_ngap_id);
|
||||
if (!ran_ue) {
|
||||
ogs_error("No RAN UE Context : AMF_UE_NGAP_ID[%lld]",
|
||||
(long long)amf_ue_ngap_id);
|
||||
ngap_send_error_indication(
|
||||
gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id,
|
||||
NGAP_Cause_PR_radioNetwork,
|
||||
NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld]",
|
||||
ran_ue->ran_ue_ngap_id, (long long)ran_ue->amf_ue_ngap_id);
|
||||
|
||||
amf_ue = ran_ue->amf_ue;
|
||||
if (!amf_ue) {
|
||||
ogs_error("Cannot find AMF-UE Context [%lld]",
|
||||
(long long)amf_ue_ngap_id);
|
||||
ngap_send_error_indication(
|
||||
gnb, &ran_ue->ran_ue_ngap_id, &ran_ue->amf_ue_ngap_id,
|
||||
NGAP_Cause_PR_radioNetwork,
|
||||
NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!PDUSessionList) {
|
||||
ogs_error("No PDUSessionResourceReleasedListRelRes");
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < PDUSessionList->list.count; i++) {
|
||||
amf_sess_t *sess = NULL;
|
||||
PDUSessionItem = (NGAP_PDUSessionResourceReleasedItemRelRes_t *)
|
||||
PDUSessionList->list.array[i];
|
||||
|
||||
if (!PDUSessionItem) {
|
||||
ogs_error("No PDUSessionResourceReleasedItemRelRes");
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error);
|
||||
return;
|
||||
}
|
||||
|
||||
transfer = &PDUSessionItem->pDUSessionResourceReleaseResponseTransfer;
|
||||
if (!transfer) {
|
||||
ogs_error("No PDUSessionResourceReleaseResponseTransfer");
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PDUSessionItem->pDUSessionID ==
|
||||
OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED) {
|
||||
ogs_error("PDU Session Identity is unassigned");
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error);
|
||||
return;
|
||||
}
|
||||
|
||||
sess = amf_sess_find_by_psi(amf_ue, PDUSessionItem->pDUSessionID);
|
||||
if (!sess) {
|
||||
ogs_error("Cannot find PDU Session ID [%d]",
|
||||
(int)PDUSessionItem->pDUSessionID);
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_radioNetwork,
|
||||
NGAP_CauseRadioNetwork_unknown_PDU_session_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SESSION_CONTEXT_IN_SMF(sess)) {
|
||||
ogs_error("Session Context is not in SMF [%d]",
|
||||
(int)PDUSessionItem->pDUSessionID);
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_radioNetwork,
|
||||
NGAP_CauseRadioNetwork_unknown_PDU_session_ID);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.n2smbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
|
||||
param.n2SmInfoType = OpenAPI_n2_sm_info_type_PDU_RES_REL_RSP;
|
||||
ogs_pkbuf_put_data(param.n2smbuf, transfer->buf, transfer->size);
|
||||
|
||||
amf_sess_sbi_discover_and_send(
|
||||
|
|
|
@ -41,6 +41,8 @@ void ngap_handle_initial_context_setup_failure(
|
|||
|
||||
void ngap_handle_pdu_session_resource_setup_response(
|
||||
amf_gnb_t *gnb, ogs_ngap_message_t *message);
|
||||
void ngap_handle_pdu_session_resource_release_response(
|
||||
amf_gnb_t *gnb, ogs_ngap_message_t *message);
|
||||
|
||||
void ngap_handle_ue_context_modification_response(
|
||||
amf_gnb_t *gnb, ogs_ngap_message_t *message);
|
||||
|
|
|
@ -130,6 +130,9 @@ void ngap_state_operational(ogs_fsm_t *s, amf_event_t *e)
|
|||
case NGAP_ProcedureCode_id_PDUSessionResourceSetup:
|
||||
ngap_handle_pdu_session_resource_setup_response(gnb, pdu);
|
||||
break;
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceRelease:
|
||||
ngap_handle_pdu_session_resource_release_response(gnb, pdu);
|
||||
break;
|
||||
#if 0
|
||||
case NGAP_ProcedureCode_id_UEContextModification:
|
||||
ngap_handle_ue_context_modification_response(gnb, pdu);
|
||||
|
|
|
@ -34,7 +34,7 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context(
|
|||
OpenAPI_sm_context_create_data_t SmContextCreateData;
|
||||
OpenAPI_plmn_id_nid_t plmn_id_nid;
|
||||
OpenAPI_snssai_t s_nssai;
|
||||
OpenAPI_ref_to_binary_data_t n1_sm_msg;
|
||||
OpenAPI_ref_to_binary_data_t n1SmMsg;
|
||||
OpenAPI_guami_t guami;
|
||||
|
||||
ogs_assert(sess);
|
||||
|
@ -94,8 +94,8 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_create_sm_context(
|
|||
SmContextCreateData.sm_context_status_uri =
|
||||
ogs_sbi_server_uri(server, &header);
|
||||
|
||||
n1_sm_msg.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
|
||||
SmContextCreateData.n1_sm_msg = &n1_sm_msg;
|
||||
n1SmMsg.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
|
||||
SmContextCreateData.n1_sm_msg = &n1SmMsg;
|
||||
|
||||
message.SmContextCreateData = &SmContextCreateData;
|
||||
|
||||
|
@ -134,6 +134,7 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_update_sm_context(
|
|||
ogs_sbi_request_t *request = NULL;
|
||||
|
||||
OpenAPI_sm_context_update_data_t SmContextUpdateData;
|
||||
OpenAPI_ref_to_binary_data_t n1SmMsg;
|
||||
OpenAPI_ref_to_binary_data_t n2SmInfo;
|
||||
OpenAPI_ng_ap_cause_t ngApCause;
|
||||
|
||||
|
@ -150,29 +151,43 @@ ogs_sbi_request_t *amf_nsmf_pdu_session_build_update_sm_context(
|
|||
message.h.resource.component[1] = sess->sm_context_ref;
|
||||
message.h.resource.component[2] = (char *)OGS_SBI_RESOURCE_NAME_MODIFY;
|
||||
|
||||
memset(&SmContextUpdateData, 0, sizeof(SmContextUpdateData));
|
||||
|
||||
message.num_of_part = 0;
|
||||
|
||||
if (param->n1smbuf) {
|
||||
n1SmMsg.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
|
||||
SmContextUpdateData.n1_sm_msg = &n1SmMsg;
|
||||
|
||||
message.part[message.num_of_part].pkbuf = param->n1smbuf;
|
||||
message.part[message.num_of_part].content_id =
|
||||
(char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
|
||||
message.part[message.num_of_part].content_type =
|
||||
(char *)OGS_SBI_CONTENT_5GNAS_TYPE;
|
||||
message.num_of_part++;
|
||||
|
||||
message.SmContextUpdateData = &SmContextUpdateData;
|
||||
}
|
||||
|
||||
if (param->n2smbuf) {
|
||||
memset(&SmContextUpdateData, 0, sizeof(SmContextUpdateData));
|
||||
SmContextUpdateData.n2_sm_info_type =
|
||||
OpenAPI_n2_sm_info_type_PDU_RES_SETUP_RSP;
|
||||
ogs_assert(param->n2SmInfoType);
|
||||
SmContextUpdateData.n2_sm_info_type = param->n2SmInfoType;
|
||||
SmContextUpdateData.n2_sm_info = &n2SmInfo;
|
||||
|
||||
memset(&n2SmInfo, 0, sizeof(n2SmInfo));
|
||||
n2SmInfo.content_id = (char *)OGS_SBI_CONTENT_NGAP_SM_ID;
|
||||
|
||||
message.part[message.num_of_part].pkbuf = param->n2smbuf;
|
||||
if (message.part[message.num_of_part].pkbuf) {
|
||||
message.part[message.num_of_part].content_id =
|
||||
(char *)OGS_SBI_CONTENT_NGAP_SM_ID;
|
||||
message.part[message.num_of_part].content_type =
|
||||
(char *)OGS_SBI_CONTENT_NGAP_TYPE;
|
||||
message.num_of_part++;
|
||||
}
|
||||
message.part[message.num_of_part].content_id =
|
||||
(char *)OGS_SBI_CONTENT_NGAP_SM_ID;
|
||||
message.part[message.num_of_part].content_type =
|
||||
(char *)OGS_SBI_CONTENT_NGAP_TYPE;
|
||||
message.num_of_part++;
|
||||
|
||||
message.SmContextUpdateData = &SmContextUpdateData;
|
||||
}
|
||||
|
||||
if (param->upCnxState) {
|
||||
memset(&SmContextUpdateData, 0, sizeof(SmContextUpdateData));
|
||||
SmContextUpdateData.up_cnx_state = param->upCnxState;
|
||||
|
||||
if (param->ngApCause.group) {
|
||||
|
|
|
@ -27,7 +27,9 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef struct amf_nsmf_pdu_session_update_sm_context_param_s {
|
||||
ogs_pkbuf_t *n1smbuf;
|
||||
ogs_pkbuf_t *n2smbuf;
|
||||
OpenAPI_n2_sm_info_type_e n2SmInfoType;
|
||||
OpenAPI_up_cnx_state_e upCnxState;
|
||||
struct {
|
||||
int group;
|
||||
|
|
|
@ -90,30 +90,28 @@ int amf_nsmf_pdu_session_handle_create_sm_context(
|
|||
nas_5gs_send_back_5gsm_message_from_sbi(sess, recvmsg->res_status);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
n1SmMsg = SmContextCreateError->n1_sm_msg;
|
||||
if (!n1SmMsg || !n1SmMsg->content_id) {
|
||||
ogs_error("[%d:%d] No N1 SM Message", sess->psi, sess->pti);
|
||||
nas_5gs_send_back_5gsm_message_from_sbi(sess, recvmsg->res_status);
|
||||
return OGS_ERROR;
|
||||
if (n1SmMsg && n1SmMsg->content_id) {
|
||||
n1smbuf = ogs_sbi_find_part_by_content_id(
|
||||
recvmsg, n1SmMsg->content_id);
|
||||
if (n1smbuf) {
|
||||
/*
|
||||
* 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);
|
||||
nas_5gs_send_gsm_reject_from_sbi(sess,
|
||||
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION,
|
||||
n1smbuf, recvmsg->res_status);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
n1smbuf = ogs_sbi_find_part_by_content_id(recvmsg, n1SmMsg->content_id);
|
||||
if (!n1smbuf) {
|
||||
ogs_error("[%d:%d] No N1 SM Content [%s]",
|
||||
sess->psi, sess->pti, n1SmMsg->content_id);
|
||||
nas_5gs_send_back_5gsm_message_from_sbi(sess, recvmsg->res_status);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
nas_5gs_send_back_5gsm_message_from_sbi(sess, recvmsg->res_status);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
nas_5gs_send_gsm_reject_from_sbi(sess,
|
||||
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION,
|
||||
n1smbuf, recvmsg->res_status);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
|
@ -130,134 +128,167 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
|
|||
|
||||
if (recvmsg->res_status == OGS_SBI_HTTP_STATUS_NO_CONTENT ||
|
||||
recvmsg->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||||
if (recvmsg->res_status == OGS_SBI_HTTP_STATUS_OK) {
|
||||
/* Nothing */
|
||||
}
|
||||
|
||||
OpenAPI_sm_context_updated_data_t *SmContextUpdatedData = NULL;
|
||||
OpenAPI_ref_to_binary_data_t *n1SmMsg = NULL;
|
||||
OpenAPI_ref_to_binary_data_t *n2SmInfo = NULL;
|
||||
ogs_pkbuf_t *n1smbuf = NULL;
|
||||
ogs_pkbuf_t *n2smbuf = NULL;
|
||||
|
||||
/* UPDATE_UpCnxState - SYNC */
|
||||
sess->smfUpCnxState = sess->ueUpCnxState;
|
||||
|
||||
if (sess->ueUpCnxState == OpenAPI_up_cnx_state_ACTIVATED) {
|
||||
/*
|
||||
* 1. PDUSessionResourceSetupResponse
|
||||
* 2. /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify
|
||||
* 3. PFCP Session Modifcation Request (OuterHeaderCreation)
|
||||
* 4. PFCP Session Modifcation Response
|
||||
*/
|
||||
|
||||
/*
|
||||
* 1. InitialContextSetupResponse
|
||||
* 2. /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify
|
||||
* 3. PFCP Session Modifcation Request (Apply: FORWARD)
|
||||
* 4. PFCP Session Modifcation Response
|
||||
*/
|
||||
|
||||
/* Nothing */
|
||||
|
||||
} else if (sess->ueUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED) {
|
||||
/*
|
||||
* 1. UEContextReleaseRequest
|
||||
* 2. /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify
|
||||
* 3. PFCP Session Modifcation Request (Apply:Buff & NOCP)
|
||||
* 4. PFCP Session Modifcation Response
|
||||
* 5. UEContextReleaseCommand
|
||||
* 6. UEContextReleaseComplete
|
||||
*/
|
||||
|
||||
if (SESSION_SYNC_DONE(amf_ue)) {
|
||||
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 (sess->ueUpCnxState == OpenAPI_up_cnx_state_ACTIVATING) {
|
||||
|
||||
OpenAPI_sm_context_updated_data_t *SmContextUpdatedData = NULL;
|
||||
OpenAPI_ref_to_binary_data_t *n2SmInfo = NULL;
|
||||
ogs_pkbuf_t *n2smbuf = NULL;
|
||||
|
||||
/*
|
||||
* 1. ServiceRequest
|
||||
* 2. /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify
|
||||
*/
|
||||
if (recvmsg->SmContextUpdatedData &&
|
||||
recvmsg->SmContextUpdatedData->n2_sm_info) {
|
||||
|
||||
SmContextUpdatedData = recvmsg->SmContextUpdatedData;
|
||||
if (!SmContextUpdatedData) {
|
||||
ogs_error("No SmContextUpdatedData");
|
||||
nas_5gs_send_gmm_reject(amf_ue,
|
||||
OGS_5GMM_CAUSE_5GS_SERVICES_NOT_ALLOWED);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
ogs_assert(SmContextUpdatedData);
|
||||
n2SmInfo = SmContextUpdatedData->n2_sm_info;
|
||||
if (!n2SmInfo || !n2SmInfo->content_id) {
|
||||
ogs_error("No SmInfo");
|
||||
nas_5gs_send_gmm_reject(amf_ue,
|
||||
OGS_5GMM_CAUSE_5GS_SERVICES_NOT_ALLOWED);
|
||||
return OGS_ERROR;
|
||||
ogs_assert(n2SmInfo);
|
||||
|
||||
if (n2SmInfo->content_id) {
|
||||
n2smbuf = ogs_sbi_find_part_by_content_id(
|
||||
recvmsg, n2SmInfo->content_id);
|
||||
}
|
||||
|
||||
sess->n2SmInfoType = SmContextUpdatedData->n2_sm_info_type;
|
||||
if (!sess->n2SmInfoType) {
|
||||
ogs_error("No SmInfoType");
|
||||
nas_5gs_send_gmm_reject(amf_ue,
|
||||
OGS_5GMM_CAUSE_5GS_SERVICES_NOT_ALLOWED);
|
||||
return OGS_ERROR;
|
||||
n1SmMsg = SmContextUpdatedData->n1_sm_msg;
|
||||
if (n1SmMsg && n1SmMsg->content_id) {
|
||||
n1smbuf = ogs_sbi_find_part_by_content_id(
|
||||
recvmsg, n1SmMsg->content_id);
|
||||
}
|
||||
|
||||
n2smbuf = ogs_sbi_find_part_by_content_id(
|
||||
recvmsg, n2SmInfo->content_id);
|
||||
if (!n2smbuf) {
|
||||
ogs_error("[%s] No N2 SM Content", amf_ue->supi);
|
||||
nas_5gs_send_gmm_reject(amf_ue,
|
||||
OGS_5GMM_CAUSE_5GS_SERVICES_NOT_ALLOWED);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
switch (SmContextUpdatedData->n2_sm_info_type) {
|
||||
case OpenAPI_n2_sm_info_type_PDU_RES_SETUP_REQ:
|
||||
if (!n2smbuf) {
|
||||
ogs_error("[%s:%d] No N2 SM Content",
|
||||
amf_ue->supi, sess->psi);
|
||||
nas_5gs_send_gmm_reject(amf_ue,
|
||||
OGS_5GMM_CAUSE_5GS_SERVICES_NOT_ALLOWED);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* To Deliver N2 SM Content to gNB Temporarily,
|
||||
* Store N2 SM Context in Session Context
|
||||
*/
|
||||
if (sess->n2smbuf) {
|
||||
/*
|
||||
* It should not be reached this way.
|
||||
* If the problem occurred, free the old n2smbuf
|
||||
* To Deliver N2 SM Content to gNB Temporarily,
|
||||
* Store N2 SM Context in Session Context
|
||||
*/
|
||||
ogs_error("N2 SM Content is duplicated");
|
||||
ogs_pkbuf_free(sess->n2smbuf);
|
||||
}
|
||||
/*
|
||||
* 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->n2smbuf = ogs_pkbuf_copy(n2smbuf);
|
||||
ogs_assert(sess->n2smbuf);
|
||||
if (sess->n2smbuf) {
|
||||
/*
|
||||
* It should not be reached this way.
|
||||
* If the problem occurred, free the old n2smbuf
|
||||
*/
|
||||
ogs_error("[%s:%d] N2 SM Content is duplicated",
|
||||
amf_ue->supi, sess->psi);
|
||||
ogs_pkbuf_free(sess->n2smbuf);
|
||||
}
|
||||
/*
|
||||
* 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->n2smbuf = ogs_pkbuf_copy(n2smbuf);
|
||||
ogs_assert(sess->n2smbuf);
|
||||
|
||||
if (SESSION_SYNC_DONE(amf_ue)) {
|
||||
nas_5gs_send_accept(amf_ue);
|
||||
if (SESSION_SYNC_DONE(amf_ue)) {
|
||||
nas_5gs_send_accept(amf_ue);
|
||||
|
||||
/*
|
||||
* After sending accept message, N2 SM context is freed
|
||||
* For checking memory, NULL pointer should be set to n2smbuf.
|
||||
*/
|
||||
ogs_list_for_each(&amf_ue->sess_list, sess) {
|
||||
if (sess->n2smbuf) {
|
||||
ogs_pkbuf_free(sess->n2smbuf);
|
||||
sess->n2smbuf = NULL;
|
||||
ogs_list_for_each(&amf_ue->sess_list, sess) {
|
||||
if (sess->n2smbuf) {
|
||||
ogs_pkbuf_free(sess->n2smbuf);
|
||||
sess->n2smbuf = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OpenAPI_n2_sm_info_type_PDU_RES_REL_CMD:
|
||||
if (!n1smbuf) {
|
||||
ogs_error("[%s:%d] No N1 SM Content [%s]",
|
||||
amf_ue->supi, sess->psi, n1SmMsg->content_id);
|
||||
nas_5gs_send_back_5gsm_message(sess,
|
||||
OGS_5GSM_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_pkbuf_copy(n2smbuf);
|
||||
ogs_assert(n2smbuf);
|
||||
|
||||
nas_send_pdu_session_release_command(sess, n1smbuf, n2smbuf);
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_error("Not implemented [%d]",
|
||||
SmContextUpdatedData->n2_sm_info_type);
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error);
|
||||
}
|
||||
|
||||
} else {
|
||||
ogs_error("Invalid UpCnxState [UE:%d,SMF:%d]",
|
||||
sess->ueUpCnxState, sess->smfUpCnxState);
|
||||
}
|
||||
|
||||
if (sess->ueUpCnxState == OpenAPI_up_cnx_state_ACTIVATED) {
|
||||
/*
|
||||
* 1. PDUSessionResourceSetupResponse
|
||||
* 2. /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify
|
||||
* 3. PFCP Session Modifcation Request (OuterHeaderCreation)
|
||||
* 4. PFCP Session Modifcation Response
|
||||
*/
|
||||
|
||||
/*
|
||||
* 1. InitialContextSetupResponse
|
||||
* 2. /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify
|
||||
* 3. PFCP Session Modifcation Request (Apply: FORWARD)
|
||||
* 4. PFCP Session Modifcation Response
|
||||
*/
|
||||
|
||||
/*
|
||||
* 1. PDUSessionResourceReleaseResponse
|
||||
* 2. /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify
|
||||
*/
|
||||
|
||||
/* Nothing */
|
||||
|
||||
} else if (sess->ueUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED) {
|
||||
/*
|
||||
* 1. UEContextReleaseRequest
|
||||
* 2. /nsmf-pdusession/v1/sm-contexts/{smContextRef}/modify
|
||||
* 3. PFCP Session Modifcation Request (Apply:Buff & NOCP)
|
||||
* 4. PFCP Session Modifcation Response
|
||||
* 5. UEContextReleaseCommand
|
||||
* 6. UEContextReleaseComplete
|
||||
*/
|
||||
|
||||
if (SESSION_SYNC_DONE(amf_ue)) {
|
||||
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 (sess->ueUpCnxState == OpenAPI_up_cnx_state_ACTIVATING) {
|
||||
|
||||
/* Not reached here */
|
||||
|
||||
} else {
|
||||
ogs_error("Invalid UpCnxState [UE:%d,SMF:%d]",
|
||||
sess->ueUpCnxState, sess->smfUpCnxState);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
amf_ue_t *amf_ue = NULL;
|
||||
|
||||
OpenAPI_sm_context_update_error_t *SmContextUpdateError = NULL;
|
||||
OpenAPI_ref_to_binary_data_t *n1SmMsg = NULL;
|
||||
ogs_pkbuf_t *n1smbuf = NULL;
|
||||
|
||||
#if 0 /* Is it needed? */
|
||||
OpenAPI_ref_to_binary_data_t *n2SmInfo = NULL;
|
||||
ogs_pkbuf_t *n2smbuf = NULL;
|
||||
|
@ -279,6 +310,25 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
|
|||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
n1SmMsg = SmContextUpdateError->n1_sm_msg;
|
||||
if (n1SmMsg && n1SmMsg->content_id) {
|
||||
n1smbuf = ogs_sbi_find_part_by_content_id(
|
||||
recvmsg, n1SmMsg->content_id);
|
||||
if (n1smbuf) {
|
||||
/*
|
||||
* 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);
|
||||
nas_5gs_send_gsm_reject_from_sbi(sess,
|
||||
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION,
|
||||
n1smbuf, recvmsg->res_status);
|
||||
return OGS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* Is it needed? */
|
||||
n2SmInfo = SmContextUpdateError->n2_sm_info;
|
||||
if (!n2SmInfo || !n2SmInfo->content_id) {
|
||||
|
@ -301,6 +351,8 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
|
|||
|
||||
ngap_send_error_indication2(amf_ue,
|
||||
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error);
|
||||
|
||||
return OGS_ERROR;
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
|
|
|
@ -190,16 +190,13 @@ void amf_sbi_send_deactivate_session(
|
|||
/* UPDATE_UpCnxState - DEACTIVATED */
|
||||
sess->ueUpCnxState = OpenAPI_up_cnx_state_DEACTIVATED;
|
||||
|
||||
if (sess->smfUpCnxState != OpenAPI_up_cnx_state_DEACTIVATED) {
|
||||
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.upCnxState = sess->ueUpCnxState;
|
||||
param.ngApCause.group = group;
|
||||
param.ngApCause.value = cause;
|
||||
amf_sess_sbi_discover_and_send(
|
||||
OpenAPI_nf_type_SMF, sess, ¶m,
|
||||
amf_nsmf_pdu_session_build_update_sm_context);
|
||||
}
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.upCnxState = sess->ueUpCnxState;
|
||||
param.ngApCause.group = group;
|
||||
param.ngApCause.value = cause;
|
||||
amf_sess_sbi_discover_and_send(
|
||||
OpenAPI_nf_type_SMF, sess, ¶m,
|
||||
amf_nsmf_pdu_session_build_update_sm_context);
|
||||
}
|
||||
|
||||
void amf_sbi_send_deactivate_all_sessions(
|
||||
|
|
|
@ -238,6 +238,34 @@ ogs_pkbuf_t *emm_build_security_mode_command(mme_ue_t *mme_ue)
|
|||
*replayed_ue_additional_security_capability =
|
||||
&security_mode_command->replayed_ue_additional_security_capability;
|
||||
|
||||
#if 0
|
||||
char *_reg = (char *)
|
||||
"0741720bf632f540 800101dde9c6cf07 f0f0c04001001000 230201d031271d80"
|
||||
"8021100101001081 0600000000830600 000000000300000a 00000d005232f540"
|
||||
"00015c20001332f5 40000111034f1880 5d0105e010028dc0 6f04f000f000";
|
||||
uint8_t tmp[OGS_MAX_SDU_LEN];
|
||||
uint8_t s[OGS_MAX_SDU_LEN];
|
||||
uint16_t len;
|
||||
uint8_t key[32];
|
||||
uint8_t output[OGS_SHA256_DIGEST_SIZE];
|
||||
|
||||
OGS_HEX(_reg, strlen(_reg), tmp);
|
||||
|
||||
len = htobe16(94);
|
||||
memcpy(&s[94], &len, sizeof(len));
|
||||
memset(key, 0, 32);
|
||||
|
||||
ogs_log_hexdump(OGS_LOG_FATAL, s, 96);
|
||||
ogs_log_hexdump(OGS_LOG_FATAL, key, 32);
|
||||
|
||||
ogs_hmac_sha256(key, 32, s, 94, output, OGS_SHA256_DIGEST_SIZE);
|
||||
ogs_log_hexdump(OGS_LOG_FATAL, output, 32);
|
||||
memcpy(s, key, 32);
|
||||
memcpy(s+32, tmp, 94);
|
||||
ogs_sha256(s, 32+94, output);
|
||||
ogs_log_hexdump(OGS_LOG_FATAL, output, 32);
|
||||
#endif
|
||||
|
||||
ogs_assert(mme_ue);
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
|
|
|
@ -266,6 +266,7 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
|
|||
ogs_assert(enb_ue);
|
||||
pkbuf = e->pkbuf;
|
||||
ogs_assert(pkbuf);
|
||||
|
||||
if (ogs_nas_emm_decode(&nas_message, pkbuf) != OGS_OK) {
|
||||
ogs_error("ogs_nas_emm_decode() failed");
|
||||
ogs_pkbuf_free(pkbuf);
|
||||
|
|
|
@ -49,12 +49,9 @@ static int client_notify_cb(ogs_sbi_response_t *response, void *data)
|
|||
{
|
||||
int rv;
|
||||
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
ogs_sbi_message_t message;
|
||||
|
||||
ogs_assert(response);
|
||||
client = data;
|
||||
ogs_assert(client);
|
||||
|
||||
rv = ogs_sbi_parse_response(&message, response);
|
||||
if (rv != OGS_OK) {
|
||||
|
@ -99,7 +96,7 @@ void nrf_nnrf_nfm_send_nf_status_notify(ogs_sbi_subscription_t *subscription,
|
|||
request = nrf_nnrf_nfm_build_nf_status_notify(
|
||||
client, subscription, event, nf_instance);
|
||||
ogs_assert(request);
|
||||
ogs_sbi_client_send_request(client, request, client);
|
||||
ogs_sbi_client_send_request(client, request, NULL);
|
||||
ogs_sbi_request_free(request);
|
||||
}
|
||||
|
||||
|
|
|
@ -1329,6 +1329,11 @@ void smf_sess_remove(smf_sess_t *sess)
|
|||
if (sess->sm_context_ref)
|
||||
ogs_free(sess->sm_context_ref);
|
||||
|
||||
if (sess->sm_context_status_uri)
|
||||
ogs_free(sess->sm_context_status_uri);
|
||||
if (sess->namf.client)
|
||||
ogs_sbi_client_remove(sess->namf.client);
|
||||
|
||||
if (sess->dnn)
|
||||
ogs_free(sess->dnn);
|
||||
|
||||
|
|
|
@ -166,6 +166,11 @@ typedef struct smf_sess_s {
|
|||
uint8_t psi; /* PDU session identity */
|
||||
uint8_t pti; /* Procedure transaction identity */
|
||||
|
||||
char *sm_context_status_uri; /* SmContextStatusNotification */
|
||||
struct {
|
||||
ogs_sbi_client_t *client;
|
||||
} namf;
|
||||
|
||||
/* PLMN ID & NID */
|
||||
ogs_plmn_id_t plmn_id;
|
||||
char *nid;
|
||||
|
|
|
@ -215,3 +215,41 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_reject(
|
|||
|
||||
return ogs_nas_5gs_plain_encode(&message);
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *gsm_build_pdu_session_release_command(
|
||||
smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause)
|
||||
{
|
||||
ogs_nas_5gs_message_t message;
|
||||
ogs_nas_5gs_pdu_session_release_command_t *pdu_session_release_command =
|
||||
&message.gsm.pdu_session_release_command;
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.gsm.h.extended_protocol_discriminator =
|
||||
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GSM;
|
||||
message.gsm.h.pdu_session_identity = sess->psi;
|
||||
message.gsm.h.procedure_transaction_identity = sess->pti;
|
||||
message.gsm.h.message_type = OGS_NAS_5GS_PDU_SESSION_RELEASE_COMMAND;
|
||||
|
||||
pdu_session_release_command->gsm_cause = gsm_cause;
|
||||
|
||||
return ogs_nas_5gs_plain_encode(&message);
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *gsm_build_pdu_session_release_reject(
|
||||
smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause)
|
||||
{
|
||||
ogs_nas_5gs_message_t message;
|
||||
ogs_nas_5gs_pdu_session_release_reject_t *
|
||||
pdu_session_release_reject = &message.gsm.pdu_session_release_reject;
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.gsm.h.extended_protocol_discriminator =
|
||||
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GSM;
|
||||
message.gsm.h.pdu_session_identity = sess->psi;
|
||||
message.gsm.h.procedure_transaction_identity = sess->pti;
|
||||
message.gsm.h.message_type = OGS_NAS_5GS_PDU_SESSION_RELEASE_REJECT;
|
||||
|
||||
pdu_session_release_reject->gsm_cause = gsm_cause;
|
||||
|
||||
return ogs_nas_5gs_plain_encode(&message);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,11 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess);
|
|||
ogs_pkbuf_t *gsm_build_pdu_session_establishment_reject(
|
||||
smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause);
|
||||
|
||||
ogs_pkbuf_t *gsm_build_pdu_session_release_command(
|
||||
smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause);
|
||||
ogs_pkbuf_t *gsm_build_pdu_session_release_reject(
|
||||
smf_sess_t *sess, ogs_nas_5gsm_cause_t gsm_cause);
|
||||
|
||||
ogs_pkbuf_t *gsm_build_status(smf_sess_t *sess, ogs_nas_5gsm_cause_t cause);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "gsm-handler.h"
|
||||
#include "sbi-path.h"
|
||||
#include "pfcp-path.h"
|
||||
|
||||
#undef OGS_LOG_DOMAIN
|
||||
#define OGS_LOG_DOMAIN __gsm_log_domain
|
||||
|
@ -64,7 +65,6 @@ int gsm_handle_pdu_session_establishment_request(smf_sess_t *sess,
|
|||
extended_protocol_configuration_options);
|
||||
}
|
||||
|
||||
|
||||
smf_sbi_discover_and_send(OpenAPI_nf_type_UDM, sess,
|
||||
(char *)OGS_SBI_RESOURCE_NAME_SM_DATA, smf_nudm_sdm_build_get);
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ void smf_gsm_state_final(ogs_fsm_t *s, smf_event_t *e)
|
|||
void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
||||
{
|
||||
int rv;
|
||||
char *strerror = NULL;
|
||||
smf_ue_t *smf_ue = NULL;
|
||||
smf_sess_t *sess = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
@ -169,6 +170,8 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
ogs_assert(nas_message);
|
||||
sess = e->sess;
|
||||
ogs_assert(sess);
|
||||
session = sess->sbi.session;
|
||||
ogs_assert(session);
|
||||
smf_ue = sess->smf_ue;
|
||||
ogs_assert(smf_ue);
|
||||
|
||||
|
@ -180,11 +183,29 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
ogs_error("[%s:%d] Cannot handle NAS message",
|
||||
smf_ue->supi, sess->psi);
|
||||
OGS_FSM_TRAN(s, smf_gsm_state_exception);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case OGS_NAS_5GS_PDU_SESSION_RELEASE_REQUEST:
|
||||
smf_5gc_pfcp_send_session_deletion_request(
|
||||
sess, OGS_PFCP_5GC_DELETE_TRIGGER_UE_REQUESTED);
|
||||
break;
|
||||
|
||||
case OGS_NAS_5GS_PDU_SESSION_RELEASE_COMPLETE:
|
||||
smf_sbi_send_response(sess, OGS_SBI_HTTP_STATUS_NO_CONTENT);
|
||||
smf_sbi_send_sm_context_status_notify(sess);
|
||||
|
||||
OGS_FSM_TRAN(s, smf_gsm_state_released);
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_error("Unknown message[%d]", nas_message->gsm.h.message_type);
|
||||
strerror = ogs_msprintf("Unknown message [%d]",
|
||||
nas_message->gsm.h.message_type);
|
||||
ogs_assert(strerror);
|
||||
ogs_error("%s", strerror);
|
||||
ogs_sbi_server_send_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST, NULL, strerror, NULL);
|
||||
ogs_free(strerror);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -210,6 +231,10 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
}
|
||||
break;
|
||||
|
||||
case OpenAPI_n2_sm_info_type_PDU_RES_REL_RSP:
|
||||
smf_sbi_send_response(sess, OGS_SBI_HTTP_STATUS_NO_CONTENT);
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_error("Unknown message[%d]", e->ngap.type);
|
||||
}
|
||||
|
@ -222,6 +247,31 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
}
|
||||
}
|
||||
|
||||
void smf_gsm_state_released(ogs_fsm_t *s, smf_event_t *e)
|
||||
{
|
||||
smf_sess_t *sess = NULL;
|
||||
ogs_assert(s);
|
||||
ogs_assert(e);
|
||||
|
||||
smf_sm_debug(e);
|
||||
|
||||
sess = e->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
switch (e->id) {
|
||||
case OGS_FSM_ENTRY_SIG:
|
||||
break;
|
||||
|
||||
case OGS_FSM_EXIT_SIG:
|
||||
break;
|
||||
|
||||
default:
|
||||
ogs_error("[%s] Unknown event %s",
|
||||
sess->imsi_bcd, smf_event_get_name(e));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void smf_gsm_state_exception(ogs_fsm_t *s, smf_event_t *e)
|
||||
{
|
||||
smf_sess_t *sess = NULL;
|
||||
|
@ -241,7 +291,8 @@ void smf_gsm_state_exception(ogs_fsm_t *s, smf_event_t *e)
|
|||
break;
|
||||
|
||||
default:
|
||||
ogs_error("[%s] Unknown event %s", sess->imsi_bcd, smf_event_get_name(e));
|
||||
ogs_error("[%s] Unknown event %s",
|
||||
sess->imsi_bcd, smf_event_get_name(e));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ libsmf_sources = files('''
|
|||
nnrf-handler.h
|
||||
nudm-build.h
|
||||
nudm-handler.h
|
||||
nsmf-handler.h
|
||||
namf-build.h
|
||||
sbi-path.h
|
||||
gsm-build.h
|
||||
|
|
|
@ -206,7 +206,8 @@ void smf_5gc_n4_handle_session_modification_response(
|
|||
"PFCP Cause[%d] : No Accepted", rsp->cause.u8);
|
||||
ogs_error("%s", strerror);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST, strerror, NULL, NULL);
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST, strerror,
|
||||
NULL, NULL, NULL);
|
||||
ogs_free(strerror);
|
||||
return;
|
||||
}
|
||||
|
@ -214,7 +215,7 @@ void smf_5gc_n4_handle_session_modification_response(
|
|||
ogs_error("No Cause");
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"[PFCP] No Cause", NULL, NULL);
|
||||
"[PFCP] No Cause", NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -228,6 +229,8 @@ void smf_5gc_n4_handle_session_deletion_response(
|
|||
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
|
||||
ogs_pfcp_session_deletion_response_t *rsp)
|
||||
{
|
||||
int trigger;
|
||||
|
||||
ogs_sbi_session_t *session = NULL;
|
||||
|
||||
ogs_sbi_message_t sendmsg;
|
||||
|
@ -238,6 +241,9 @@ void smf_5gc_n4_handle_session_deletion_response(
|
|||
ogs_assert(session);
|
||||
ogs_assert(rsp);
|
||||
|
||||
trigger = xact->trigger;
|
||||
ogs_assert(trigger);
|
||||
|
||||
ogs_pfcp_xact_commit(xact);
|
||||
|
||||
if (rsp->cause.presence) {
|
||||
|
@ -258,14 +264,20 @@ void smf_5gc_n4_handle_session_deletion_response(
|
|||
return;
|
||||
}
|
||||
|
||||
memset(&sendmsg, 0, sizeof(sendmsg));
|
||||
if (trigger == OGS_PFCP_5GC_DELETE_TRIGGER_UE_REQUESTED) {
|
||||
|
||||
response = ogs_sbi_build_response(
|
||||
&sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
|
||||
ogs_assert(response);
|
||||
ogs_sbi_server_send_response(session, response);
|
||||
smf_sbi_send_sm_context_updated_data_in_session_deletion(sess);
|
||||
|
||||
SMF_SESS_CLEAR(sess);
|
||||
} else {
|
||||
memset(&sendmsg, 0, sizeof(sendmsg));
|
||||
|
||||
response = ogs_sbi_build_response(
|
||||
&sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
|
||||
ogs_assert(response);
|
||||
ogs_sbi_server_send_response(session, response);
|
||||
|
||||
SMF_SESS_CLEAR(sess);
|
||||
}
|
||||
}
|
||||
|
||||
void smf_epc_n4_handle_session_establishment_response(
|
||||
|
|
|
@ -113,3 +113,34 @@ ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
|
|||
|
||||
return request;
|
||||
}
|
||||
|
||||
ogs_sbi_request_t *smf_namf_callback_build_sm_context_status(
|
||||
smf_sess_t *sess, void *data)
|
||||
{
|
||||
ogs_sbi_message_t message;
|
||||
ogs_sbi_request_t *request = NULL;
|
||||
|
||||
OpenAPI_sm_context_status_notification_t SmContextStatusNotification;
|
||||
OpenAPI_status_info_t StatusInfo;
|
||||
|
||||
ogs_assert(sess);
|
||||
ogs_assert(sess->sm_context_status_uri);
|
||||
|
||||
memset(&StatusInfo, 0, sizeof(StatusInfo));
|
||||
StatusInfo.resource_status = OpenAPI_resource_status_RELEASED;
|
||||
|
||||
memset(&SmContextStatusNotification, 0,
|
||||
sizeof(SmContextStatusNotification));
|
||||
SmContextStatusNotification.status_info = &StatusInfo;
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.h.method = (char *)OGS_SBI_HTTP_METHOD_POST;
|
||||
message.h.uri = sess->sm_context_status_uri;
|
||||
|
||||
message.SmContextStatusNotification = &SmContextStatusNotification;
|
||||
|
||||
request = ogs_sbi_build_request(&message);
|
||||
ogs_assert(request);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@ extern "C" {
|
|||
|
||||
ogs_sbi_request_t *smf_namf_comm_build_n1_n2_message_transfer(
|
||||
smf_sess_t *sess, void *data);
|
||||
ogs_sbi_request_t *smf_namf_callback_build_sm_context_status(
|
||||
smf_sess_t *sess, void *data);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -157,3 +157,23 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer(
|
|||
return ogs_asn_encode(
|
||||
&asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer, &message);
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer(
|
||||
NGAP_Cause_PR group, long cause)
|
||||
{
|
||||
NGAP_PDUSessionResourceReleaseCommandTransfer_t message;
|
||||
NGAP_Cause_t *Cause = NULL;
|
||||
|
||||
ogs_debug("PDUSessionResourceReleaseCommandTransfer");
|
||||
memset(&message, 0,
|
||||
sizeof(NGAP_PDUSessionResourceReleaseCommandTransfer_t));
|
||||
|
||||
ogs_debug(" Group[%d] Cause[%d]", group, (int)cause);
|
||||
|
||||
Cause = &message.cause;
|
||||
Cause->present = group;
|
||||
Cause->choice.radioNetwork = cause;
|
||||
|
||||
return ogs_asn_encode(
|
||||
&asn_DEF_NGAP_PDUSessionResourceReleaseCommandTransfer, &message);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ extern "C" {
|
|||
|
||||
ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer(
|
||||
smf_sess_t *sess);
|
||||
ogs_pkbuf_t *ngap_build_pdu_session_resource_release_command_transfer(
|
||||
NGAP_Cause_PR group, long cause);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ int ngap_handle_pdu_session_resource_setup_response_transfer(
|
|||
smf_ue->supi, sess->psi);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No N2 SM Info Type", smf_ue->supi, NULL);
|
||||
"No N2 SM Info Type", smf_ue->supi, NULL, NULL);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ int ngap_handle_pdu_session_resource_setup_response_transfer(
|
|||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"Unknown NGAP_UPTransportLayerInformation.present",
|
||||
smf_ue->supi, NULL);
|
||||
smf_ue->supi, NULL, NULL);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ int ngap_handle_pdu_session_resource_setup_response_transfer(
|
|||
ogs_error("[%s:%d] No GTPTunnel", smf_ue->supi, sess->psi);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No GTPTunnel", smf_ue->supi, NULL);
|
||||
"No GTPTunnel", smf_ue->supi, NULL, NULL);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,13 +29,16 @@ bool smf_nsmf_handle_create_sm_context(
|
|||
smf_ue_t *smf_ue = NULL;
|
||||
ogs_sbi_session_t *session = NULL;
|
||||
|
||||
ogs_pkbuf_t *n1smbuf = NULL;
|
||||
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
ogs_sockaddr_t *addr = NULL;
|
||||
|
||||
OpenAPI_sm_context_create_data_t *SmContextCreateData = NULL;
|
||||
OpenAPI_snssai_t *sNssai = NULL;
|
||||
OpenAPI_plmn_id_nid_t *servingNetwork = NULL;
|
||||
OpenAPI_ref_to_binary_data_t *n1SmMsg = NULL;
|
||||
|
||||
ogs_pkbuf_t *n1smbuf = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
session = sess->sbi.session;
|
||||
ogs_assert(session);
|
||||
|
@ -102,6 +105,30 @@ bool smf_nsmf_handle_create_sm_context(
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!SmContextCreateData->sm_context_status_uri) {
|
||||
ogs_error("[%s:%d] No SmContextStatusNotification",
|
||||
smf_ue->supi, sess->psi);
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_create_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No SmContextStatusNotification", smf_ue->supi, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
addr = ogs_sbi_getaddr_from_uri(SmContextCreateData->sm_context_status_uri);
|
||||
if (!addr) {
|
||||
ogs_error("[%s:%d] Invalid URI [%s]",
|
||||
smf_ue->supi, sess->psi,
|
||||
SmContextCreateData->sm_context_status_uri);
|
||||
n1smbuf = gsm_build_pdu_session_establishment_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_create_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST, "Invalid URI",
|
||||
SmContextCreateData->sm_context_status_uri, n1smbuf);
|
||||
return false;
|
||||
}
|
||||
|
||||
ogs_plmn_id_build(&sess->plmn_id,
|
||||
atoi(servingNetwork->mcc), atoi(servingNetwork->mnc),
|
||||
strlen(servingNetwork->mnc));
|
||||
|
@ -110,6 +137,20 @@ bool smf_nsmf_handle_create_sm_context(
|
|||
sess->s_nssai.sst = sNssai->sst;
|
||||
sess->s_nssai.sd = ogs_s_nssai_sd_from_string(sNssai->sd);
|
||||
|
||||
if (sess->sm_context_status_uri)
|
||||
ogs_free(sess->sm_context_status_uri);
|
||||
sess->sm_context_status_uri =
|
||||
ogs_strdup(SmContextCreateData->sm_context_status_uri);
|
||||
|
||||
client = ogs_sbi_client_find(addr);
|
||||
if (!client) {
|
||||
client = ogs_sbi_client_add(addr);
|
||||
ogs_assert(client);
|
||||
}
|
||||
OGS_SETUP_SBI_CLIENT(&sess->namf, client);
|
||||
|
||||
ogs_freeaddrinfo(addr);
|
||||
|
||||
if (SmContextCreateData->dnn) {
|
||||
if (sess->dnn) ogs_free(sess->dnn);
|
||||
sess->dnn = ogs_strdup(SmContextCreateData->dnn);
|
||||
|
@ -140,8 +181,10 @@ bool smf_nsmf_handle_update_sm_context(
|
|||
|
||||
OpenAPI_sm_context_update_data_t *SmContextUpdateData = NULL;
|
||||
OpenAPI_sm_context_updated_data_t SmContextUpdatedData;
|
||||
OpenAPI_ref_to_binary_data_t *n1SmMsg = NULL;
|
||||
OpenAPI_ref_to_binary_data_t *n2SmMsg = NULL;
|
||||
|
||||
ogs_pkbuf_t *n1smbuf = NULL;
|
||||
ogs_pkbuf_t *n2smbuf = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
|
@ -158,11 +201,46 @@ bool smf_nsmf_handle_update_sm_context(
|
|||
smf_ue->supi, sess->psi);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No SmContextUpdateData", smf_ue->supi, NULL);
|
||||
"No SmContextUpdateData", smf_ue->supi, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SmContextUpdateData->n1_sm_msg) {
|
||||
n1SmMsg = SmContextUpdateData->n1_sm_msg;
|
||||
if (!n1SmMsg || !n1SmMsg->content_id) {
|
||||
ogs_error("[%s:%d] No n1SmMsg", smf_ue->supi, sess->psi);
|
||||
n1smbuf = gsm_build_pdu_session_release_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No n1SmMsg", smf_ue->supi, n1smbuf, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
n1smbuf = ogs_sbi_find_part_by_content_id(message, n1SmMsg->content_id);
|
||||
if (!n1smbuf) {
|
||||
ogs_error("[%s:%d] No N1 SM Content [%s]",
|
||||
smf_ue->supi, sess->psi, n1SmMsg->content_id);
|
||||
n1smbuf = gsm_build_pdu_session_release_reject(sess,
|
||||
OGS_5GSM_CAUSE_INVALID_MANDATORY_INFORMATION);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No N1 SM Content", smf_ue->supi, n1smbuf, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
n1smbuf = ogs_pkbuf_copy(n1smbuf);
|
||||
ogs_assert(n1smbuf);
|
||||
nas_5gs_send_to_gsm(sess, n1smbuf);
|
||||
|
||||
return true;
|
||||
|
||||
if (SmContextUpdateData->n2_sm_info) {
|
||||
} else if (SmContextUpdateData->n2_sm_info) {
|
||||
|
||||
/*********************************************************
|
||||
* Handle ACTIVATED
|
||||
|
@ -172,7 +250,7 @@ bool smf_nsmf_handle_update_sm_context(
|
|||
ogs_error("[%s:%d] No n2SmInfoType", smf_ue->supi, sess->psi);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No n2SmInfoType", smf_ue->supi, NULL);
|
||||
"No n2SmInfoType", smf_ue->supi, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -182,7 +260,7 @@ bool smf_nsmf_handle_update_sm_context(
|
|||
smf_ue->supi, sess->psi);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No n2SmInfo.content_id", smf_ue->supi, NULL);
|
||||
"No n2SmInfo.content_id", smf_ue->supi, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -191,7 +269,7 @@ bool smf_nsmf_handle_update_sm_context(
|
|||
ogs_error("[%s:%d] No N2 SM Content", smf_ue->supi, sess->psi);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No N2 SM Content", smf_ue->supi, NULL);
|
||||
"No N2 SM Content", smf_ue->supi, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -212,7 +290,7 @@ bool smf_nsmf_handle_update_sm_context(
|
|||
ogs_error("[%s:%d] No upCnxState", smf_ue->supi, sess->psi);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No upCnxState", smf_ue->supi, NULL);
|
||||
"No upCnxState", smf_ue->supi, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -254,7 +332,8 @@ bool smf_nsmf_handle_update_sm_context(
|
|||
sess->ueUpCnxState, sess->smfUpCnxState);
|
||||
ogs_error("%s", strerror);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST, strerror, NULL, NULL);
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST, strerror,
|
||||
NULL, NULL, NULL);
|
||||
ogs_free(strerror);
|
||||
return false;
|
||||
}
|
||||
|
@ -352,7 +431,8 @@ bool smf_nsmf_handle_update_sm_context(
|
|||
sess->ueUpCnxState, sess->smfUpCnxState);
|
||||
ogs_error("%s", strerror);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST, strerror, NULL, NULL);
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST, strerror,
|
||||
NULL, NULL, NULL);
|
||||
ogs_free(strerror);
|
||||
return false;
|
||||
}
|
||||
|
@ -366,7 +446,8 @@ bool smf_nsmf_handle_release_sm_context(
|
|||
{
|
||||
ogs_assert(sess);
|
||||
|
||||
smf_5gc_pfcp_send_session_deletion_request(sess);
|
||||
smf_5gc_pfcp_send_session_deletion_request(
|
||||
sess, OGS_PFCP_5GC_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -300,9 +300,30 @@ void smf_5gc_pfcp_send_session_modification_request(smf_sess_t *sess)
|
|||
ogs_expect(rv == OGS_OK);
|
||||
}
|
||||
|
||||
void smf_5gc_pfcp_send_session_deletion_request(smf_sess_t *sess)
|
||||
void smf_5gc_pfcp_send_session_deletion_request(smf_sess_t *sess, int trigger)
|
||||
{
|
||||
smf_epc_pfcp_send_session_deletion_request(sess, NULL);
|
||||
int rv;
|
||||
ogs_pkbuf_t *n4buf = NULL;
|
||||
ogs_pfcp_header_t h;
|
||||
ogs_pfcp_xact_t *xact = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
ogs_assert(trigger);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_pfcp_header_t));
|
||||
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
|
||||
h.seid = sess->upf_n4_seid;
|
||||
|
||||
n4buf = smf_n4_build_session_deletion_request(h.type, sess);
|
||||
ogs_expect_or_return(n4buf);
|
||||
|
||||
xact = ogs_pfcp_xact_local_create(
|
||||
sess->pfcp_node, &h, n4buf, timeout, sess);
|
||||
ogs_expect_or_return(xact);
|
||||
xact->trigger = trigger;
|
||||
|
||||
rv = ogs_pfcp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
}
|
||||
|
||||
void smf_epc_pfcp_send_session_establishment_request(
|
||||
|
|
|
@ -36,7 +36,7 @@ void smf_pfcp_send_heartbeat_request(ogs_pfcp_node_t *node);
|
|||
|
||||
void smf_5gc_pfcp_send_session_establishment_request(smf_sess_t *sess);
|
||||
void smf_5gc_pfcp_send_session_modification_request(smf_sess_t *sess);
|
||||
void smf_5gc_pfcp_send_session_deletion_request(smf_sess_t *sess);
|
||||
void smf_5gc_pfcp_send_session_deletion_request(smf_sess_t *sess, int trigger);
|
||||
|
||||
void smf_epc_pfcp_send_session_establishment_request(
|
||||
smf_sess_t *sess, void *gtp_xact);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "context.h"
|
||||
#include "ngap-path.h"
|
||||
#include "sbi-path.h"
|
||||
|
||||
static int server_cb(ogs_sbi_server_t *server,
|
||||
|
@ -148,6 +149,24 @@ void smf_sbi_discover_and_send(
|
|||
}
|
||||
}
|
||||
|
||||
void smf_sbi_send_response(smf_sess_t *sess, int status)
|
||||
{
|
||||
ogs_sbi_session_t *session = NULL;
|
||||
|
||||
ogs_sbi_message_t sendmsg;
|
||||
ogs_sbi_response_t *response = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
session = sess->sbi.session;
|
||||
ogs_assert(session);
|
||||
|
||||
memset(&sendmsg, 0, sizeof(sendmsg));
|
||||
|
||||
response = ogs_sbi_build_response(&sendmsg, status);
|
||||
ogs_assert(response);
|
||||
ogs_sbi_server_send_response(session, response);
|
||||
}
|
||||
|
||||
void smf_sbi_send_sm_context_create_error(
|
||||
ogs_sbi_session_t *session,
|
||||
int status, const char *title, const char *detail,
|
||||
|
@ -158,7 +177,7 @@ void smf_sbi_send_sm_context_create_error(
|
|||
|
||||
OpenAPI_sm_context_create_error_t SmContextCreateError;
|
||||
OpenAPI_problem_details_t problem;
|
||||
OpenAPI_ref_to_binary_data_t n1_sm_msg;
|
||||
OpenAPI_ref_to_binary_data_t n1SmMsg;
|
||||
|
||||
ogs_assert(session);
|
||||
|
||||
|
@ -174,8 +193,8 @@ void smf_sbi_send_sm_context_create_error(
|
|||
SmContextCreateError.error = &problem;
|
||||
|
||||
if (n1smbuf) {
|
||||
SmContextCreateError.n1_sm_msg = &n1_sm_msg;
|
||||
n1_sm_msg.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
|
||||
SmContextCreateError.n1_sm_msg = &n1SmMsg;
|
||||
n1SmMsg.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
|
||||
sendmsg.part[0].content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
|
||||
sendmsg.part[0].content_type = (char *)OGS_SBI_CONTENT_5GNAS_TYPE;
|
||||
sendmsg.part[0].pkbuf = n1smbuf;
|
||||
|
@ -223,17 +242,82 @@ void smf_sbi_send_sm_context_updated_data(smf_sess_t *sess)
|
|||
ogs_sbi_server_send_response(session, response);
|
||||
}
|
||||
|
||||
void smf_sbi_send_sm_context_updated_data_in_session_deletion(smf_sess_t *sess)
|
||||
{
|
||||
int i;
|
||||
ogs_sbi_session_t *session = NULL;
|
||||
|
||||
ogs_sbi_message_t sendmsg;
|
||||
ogs_sbi_response_t *response = NULL;
|
||||
|
||||
OpenAPI_sm_context_updated_data_t SmContextUpdatedData;
|
||||
OpenAPI_ref_to_binary_data_t n1SmMsg;
|
||||
OpenAPI_ref_to_binary_data_t n2SmInfo;
|
||||
|
||||
ogs_assert(sess);
|
||||
session = sess->sbi.session;
|
||||
ogs_assert(session);
|
||||
|
||||
memset(&sendmsg, 0, sizeof(sendmsg));
|
||||
|
||||
memset(&SmContextUpdatedData, 0, sizeof(SmContextUpdatedData));
|
||||
|
||||
sendmsg.num_of_part = 0;
|
||||
|
||||
n1SmMsg.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
|
||||
SmContextUpdatedData.n1_sm_msg = &n1SmMsg;
|
||||
|
||||
sendmsg.part[sendmsg.num_of_part].pkbuf =
|
||||
gsm_build_pdu_session_release_command(
|
||||
sess, OGS_5GSM_CAUSE_REGULAR_DEACTIVATION);
|
||||
if (sendmsg.part[sendmsg.num_of_part].pkbuf) {
|
||||
sendmsg.part[sendmsg.num_of_part].content_id =
|
||||
(char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
|
||||
sendmsg.part[sendmsg.num_of_part].content_type =
|
||||
(char *)OGS_SBI_CONTENT_5GNAS_TYPE;
|
||||
sendmsg.num_of_part++;
|
||||
}
|
||||
|
||||
SmContextUpdatedData.n2_sm_info_type =
|
||||
OpenAPI_n2_sm_info_type_PDU_RES_REL_CMD;
|
||||
SmContextUpdatedData.n2_sm_info = &n2SmInfo;
|
||||
|
||||
memset(&n2SmInfo, 0, sizeof(n2SmInfo));
|
||||
n2SmInfo.content_id = (char *)OGS_SBI_CONTENT_NGAP_SM_ID;
|
||||
|
||||
sendmsg.part[sendmsg.num_of_part].pkbuf =
|
||||
ngap_build_pdu_session_resource_release_command_transfer(
|
||||
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
|
||||
if (sendmsg.part[sendmsg.num_of_part].pkbuf) {
|
||||
sendmsg.part[sendmsg.num_of_part].content_id =
|
||||
(char *)OGS_SBI_CONTENT_NGAP_SM_ID;
|
||||
sendmsg.part[sendmsg.num_of_part].content_type =
|
||||
(char *)OGS_SBI_CONTENT_NGAP_TYPE;
|
||||
sendmsg.num_of_part++;
|
||||
}
|
||||
|
||||
sendmsg.SmContextUpdatedData = &SmContextUpdatedData;
|
||||
|
||||
response = ogs_sbi_build_response(&sendmsg, OGS_SBI_HTTP_STATUS_OK);
|
||||
ogs_assert(response);
|
||||
ogs_sbi_server_send_response(session, response);
|
||||
|
||||
for (i = 0; i < sendmsg.num_of_part; i++)
|
||||
ogs_pkbuf_free(sendmsg.part[i].pkbuf);
|
||||
}
|
||||
|
||||
void smf_sbi_send_sm_context_update_error(
|
||||
ogs_sbi_session_t *session,
|
||||
int status, const char *title, const char *detail,
|
||||
ogs_pkbuf_t *n2smbuf)
|
||||
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf)
|
||||
{
|
||||
ogs_sbi_message_t sendmsg;
|
||||
ogs_sbi_response_t *response = NULL;
|
||||
|
||||
OpenAPI_sm_context_update_error_t SmContextUpdateError;
|
||||
OpenAPI_problem_details_t problem;
|
||||
OpenAPI_ref_to_binary_data_t n2_sm_info;
|
||||
OpenAPI_ref_to_binary_data_t n1SmMsg;
|
||||
OpenAPI_ref_to_binary_data_t n2SmInfo;
|
||||
|
||||
ogs_assert(session);
|
||||
|
||||
|
@ -248,13 +332,26 @@ void smf_sbi_send_sm_context_update_error(
|
|||
memset(&SmContextUpdateError, 0, sizeof(SmContextUpdateError));
|
||||
SmContextUpdateError.error = &problem;
|
||||
|
||||
if (n1smbuf) {
|
||||
SmContextUpdateError.n1_sm_msg = &n1SmMsg;
|
||||
n1SmMsg.content_id = (char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
|
||||
sendmsg.part[sendmsg.num_of_part].content_id =
|
||||
(char *)OGS_SBI_CONTENT_5GNAS_SM_ID;
|
||||
sendmsg.part[sendmsg.num_of_part].content_type =
|
||||
(char *)OGS_SBI_CONTENT_5GNAS_TYPE;
|
||||
sendmsg.part[sendmsg.num_of_part].pkbuf = n1smbuf;
|
||||
sendmsg.num_of_part++;
|
||||
}
|
||||
|
||||
if (n2smbuf) {
|
||||
SmContextUpdateError.n2_sm_info = &n2_sm_info;
|
||||
n2_sm_info.content_id = (char *)OGS_SBI_CONTENT_NGAP_SM_ID;
|
||||
sendmsg.part[0].content_id = (char *)OGS_SBI_CONTENT_NGAP_SM_ID;
|
||||
sendmsg.part[0].content_type = (char *)OGS_SBI_CONTENT_NGAP_TYPE;
|
||||
sendmsg.part[0].pkbuf = n2smbuf;
|
||||
sendmsg.num_of_part = 1;
|
||||
SmContextUpdateError.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, problem.status);
|
||||
|
@ -262,6 +359,52 @@ void smf_sbi_send_sm_context_update_error(
|
|||
|
||||
ogs_sbi_server_send_response(session, response);
|
||||
|
||||
if (n1smbuf)
|
||||
ogs_pkbuf_free(n1smbuf);
|
||||
|
||||
if (n2smbuf)
|
||||
ogs_pkbuf_free(n2smbuf);
|
||||
}
|
||||
|
||||
#if 0
|
||||
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("SmContextStatusNotification failed [%d]",
|
||||
message.res_status);
|
||||
|
||||
ogs_sbi_message_free(&message);
|
||||
ogs_sbi_response_free(response);
|
||||
return OGS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
void smf_sbi_send_sm_context_status_notify(smf_sess_t *sess)
|
||||
{
|
||||
ogs_sbi_request_t *request = NULL;
|
||||
ogs_sbi_client_t *client = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
client = sess->namf.client;
|
||||
ogs_assert(client);
|
||||
client->cb = client_cb;
|
||||
|
||||
request = smf_namf_callback_build_sm_context_status(sess, NULL);
|
||||
ogs_assert(request);
|
||||
ogs_sbi_client_send_request(client, request, NULL);
|
||||
ogs_sbi_request_free(request);
|
||||
}
|
||||
|
|
|
@ -38,15 +38,20 @@ void smf_sbi_discover_and_send(
|
|||
OpenAPI_nf_type_e nf_type, smf_sess_t *sess, void *data,
|
||||
ogs_sbi_request_t *(*build)(smf_sess_t *sess, void *data));
|
||||
|
||||
void smf_sbi_send_response(smf_sess_t *sess, int status);
|
||||
|
||||
void smf_sbi_send_sm_context_create_error(
|
||||
ogs_sbi_session_t *session,
|
||||
int status, const char *title, const char *detail,
|
||||
ogs_pkbuf_t *n1smbuf);
|
||||
void smf_sbi_send_sm_context_updated_data(smf_sess_t *sess);
|
||||
void smf_sbi_send_sm_context_updated_data_in_session_deletion(smf_sess_t *sess);
|
||||
void smf_sbi_send_sm_context_update_error(
|
||||
ogs_sbi_session_t *session,
|
||||
int status, const char *title, const char *detail,
|
||||
ogs_pkbuf_t *n2smbuf);
|
||||
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf);
|
||||
|
||||
void smf_sbi_send_sm_context_status_notify(smf_sess_t *sess);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -332,7 +332,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||
"No smContextRef",
|
||||
sbi_message.h.resource.component[2], NULL);
|
||||
sbi_message.h.resource.component[2],
|
||||
NULL, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -340,10 +341,12 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
sbi_message.h.resource.component[1]);
|
||||
|
||||
if (!sess) {
|
||||
ogs_error("Not found [%s]", sbi_message.h.method);
|
||||
ogs_error("Not found [%s]",
|
||||
sbi_message.h.resource.component[1]);
|
||||
smf_sbi_send_sm_context_update_error(session,
|
||||
OGS_SBI_HTTP_STATUS_NOT_FOUND,
|
||||
"Not found", sbi_message.h.method, NULL);
|
||||
OGS_SBI_HTTP_STATUS_NOT_FOUND, "Not found",
|
||||
sbi_message.h.resource.component[1],
|
||||
NULL, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -537,8 +540,6 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
break;
|
||||
|
||||
DEFAULT
|
||||
ogs_error("Invalid API name [%s]", sbi_message.h.service.name);
|
||||
ogs_assert_if_reached();
|
||||
END
|
||||
|
||||
ogs_sbi_message_free(&sbi_message);
|
||||
|
@ -612,7 +613,10 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
|
|||
|
||||
e->nas.message = &nas_message;
|
||||
ogs_fsm_dispatch(&sess->sm, e);
|
||||
if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
|
||||
if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_released)) {
|
||||
SMF_SESS_CLEAR(sess);
|
||||
|
||||
} else if (OGS_FSM_CHECK(&sess->sm, smf_gsm_state_exception)) {
|
||||
ogs_error("State machine exception");
|
||||
SMF_SESS_CLEAR(sess);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ void smf_nf_state_exception(ogs_fsm_t *s, smf_event_t *e);
|
|||
void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e);
|
||||
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_released(ogs_fsm_t *s, smf_event_t *e);
|
||||
void smf_gsm_state_exception(ogs_fsm_t *s, smf_event_t *e);
|
||||
|
||||
void smf_pfcp_state_initial(ogs_fsm_t *s, smf_event_t *e);
|
||||
|
|
|
@ -88,3 +88,51 @@ ogs_pkbuf_t *testgsm_build_pdu_session_establishment_request(
|
|||
|
||||
return ogs_nas_5gs_plain_encode(&message);
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *testgsm_build_pdu_session_release_request(test_sess_t *test_sess)
|
||||
{
|
||||
ogs_nas_5gs_message_t message;
|
||||
ogs_nas_5gs_pdu_session_release_request_t *pdu_session_release_request =
|
||||
&message.gsm.pdu_session_release_request;
|
||||
|
||||
test_ue_t *test_ue = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_assert(test_sess);
|
||||
test_ue = test_sess;
|
||||
ogs_assert(test_ue);
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
|
||||
message.gsm.h.extended_protocol_discriminator =
|
||||
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GSM;
|
||||
message.gsm.h.pdu_session_identity = test_sess->psi;
|
||||
message.gsm.h.procedure_transaction_identity = test_sess->pti;
|
||||
message.gsm.h.message_type = OGS_NAS_5GS_PDU_SESSION_RELEASE_REQUEST;
|
||||
|
||||
return ogs_nas_5gs_plain_encode(&message);
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *testgsm_build_pdu_session_release_complete(test_sess_t *test_sess)
|
||||
{
|
||||
ogs_nas_5gs_message_t message;
|
||||
ogs_nas_5gs_pdu_session_release_complete_t *pdu_session_release_complete =
|
||||
&message.gsm.pdu_session_release_complete;
|
||||
|
||||
test_ue_t *test_ue = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
ogs_assert(test_sess);
|
||||
test_ue = test_sess;
|
||||
ogs_assert(test_ue);
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
|
||||
message.gsm.h.extended_protocol_discriminator =
|
||||
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GSM;
|
||||
message.gsm.h.pdu_session_identity = test_sess->psi;
|
||||
message.gsm.h.procedure_transaction_identity = test_sess->pti;
|
||||
message.gsm.h.message_type = OGS_NAS_5GS_PDU_SESSION_RELEASE_COMPLETE;
|
||||
|
||||
return ogs_nas_5gs_plain_encode(&message);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ extern "C" {
|
|||
|
||||
ogs_pkbuf_t *testgsm_build_pdu_session_establishment_request(
|
||||
test_sess_t *test_sess);
|
||||
ogs_pkbuf_t *testgsm_build_pdu_session_release_request(test_sess_t *test_sess);
|
||||
ogs_pkbuf_t *testgsm_build_pdu_session_release_complete(test_sess_t *test_sess);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -84,6 +84,8 @@ void testgsm_recv(test_sess_t *sess, ogs_pkbuf_t *pkbuf)
|
|||
testgsm_handle_pdu_session_establishment_accept(sess,
|
||||
&message.gsm.pdu_session_establishment_accept);
|
||||
break;
|
||||
case OGS_NAS_5GS_PDU_SESSION_RELEASE_COMMAND:
|
||||
break;
|
||||
default:
|
||||
ogs_error("Unknown message[%d]", message.gsm.h.message_type);
|
||||
break;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "test-ngap.h"
|
||||
|
||||
static ogs_pkbuf_t *testngap_build_pdu_session_resource_response_trasfer(
|
||||
static ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response_trasfer(
|
||||
test_sess_t *sess);
|
||||
|
||||
ogs_pkbuf_t *testngap_build_ng_setup_request(uint32_t gnb_id, uint8_t bitsize)
|
||||
|
@ -462,7 +462,8 @@ ogs_pkbuf_t *testngap_build_initial_context_setup_response(
|
|||
|
||||
PDUSessionItem->pDUSessionID = sess->psi;
|
||||
|
||||
n2smbuf = testngap_build_pdu_session_resource_response_trasfer(sess);
|
||||
n2smbuf = testngap_build_pdu_session_resource_setup_response_trasfer(
|
||||
sess);
|
||||
ogs_assert(n2smbuf);
|
||||
transfer = &PDUSessionItem->pDUSessionResourceSetupResponseTransfer;
|
||||
|
||||
|
@ -847,7 +848,7 @@ ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response(
|
|||
|
||||
PDUSessionItem->pDUSessionID = sess->psi;
|
||||
|
||||
n2smbuf = testngap_build_pdu_session_resource_response_trasfer(sess);
|
||||
n2smbuf = testngap_build_pdu_session_resource_setup_response_trasfer(sess);
|
||||
ogs_assert(n2smbuf);
|
||||
transfer = &PDUSessionItem->pDUSessionResourceSetupResponseTransfer;
|
||||
|
||||
|
@ -859,7 +860,89 @@ ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response(
|
|||
return nga_ngap_encode(&pdu);
|
||||
}
|
||||
|
||||
static ogs_pkbuf_t *testngap_build_pdu_session_resource_response_trasfer(
|
||||
ogs_pkbuf_t *testngap_build_pdu_session_resource_release_response(
|
||||
test_sess_t *sess)
|
||||
{
|
||||
int rv;
|
||||
test_ue_t *test_ue;
|
||||
ogs_pkbuf_t *ngapbuf = NULL;
|
||||
|
||||
NGAP_NGAP_PDU_t pdu;
|
||||
NGAP_SuccessfulOutcome_t *successfulOutcome = NULL;
|
||||
NGAP_PDUSessionResourceReleaseResponse_t *PDUSessionResourceReleaseResponse;
|
||||
|
||||
NGAP_PDUSessionResourceReleaseResponseIEs_t *ie = NULL;
|
||||
NGAP_AMF_UE_NGAP_ID_t *AMF_UE_NGAP_ID = NULL;
|
||||
NGAP_RAN_UE_NGAP_ID_t *RAN_UE_NGAP_ID = NULL;
|
||||
NGAP_PDUSessionResourceReleasedListRelRes_t *PDUSessionList = NULL;
|
||||
NGAP_PDUSessionResourceReleasedItemRelRes_t *PDUSessionItem = NULL;
|
||||
OCTET_STRING_t *transfer = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
test_ue = sess->test_ue;
|
||||
ogs_assert(test_ue);
|
||||
|
||||
memset(&pdu, 0, sizeof (NGAP_NGAP_PDU_t));
|
||||
pdu.present = NGAP_NGAP_PDU_PR_successfulOutcome;
|
||||
pdu.choice.successfulOutcome = CALLOC(1, sizeof(NGAP_SuccessfulOutcome_t));
|
||||
|
||||
successfulOutcome = pdu.choice.successfulOutcome;
|
||||
successfulOutcome->procedureCode =
|
||||
NGAP_ProcedureCode_id_PDUSessionResourceRelease;
|
||||
successfulOutcome->criticality = NGAP_Criticality_reject;
|
||||
successfulOutcome->value.present =
|
||||
NGAP_SuccessfulOutcome__value_PR_PDUSessionResourceReleaseResponse;
|
||||
|
||||
PDUSessionResourceReleaseResponse =
|
||||
&successfulOutcome->value.choice.PDUSessionResourceReleaseResponse;
|
||||
|
||||
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t));
|
||||
ASN_SEQUENCE_ADD(&PDUSessionResourceReleaseResponse->protocolIEs, ie);
|
||||
|
||||
ie->id = NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present =
|
||||
NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_AMF_UE_NGAP_ID;
|
||||
|
||||
AMF_UE_NGAP_ID = &ie->value.choice.AMF_UE_NGAP_ID;
|
||||
|
||||
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t));
|
||||
ASN_SEQUENCE_ADD(&PDUSessionResourceReleaseResponse->protocolIEs, ie);
|
||||
|
||||
ie->id = NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present =
|
||||
NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_RAN_UE_NGAP_ID;
|
||||
|
||||
RAN_UE_NGAP_ID = &ie->value.choice.RAN_UE_NGAP_ID;
|
||||
|
||||
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceReleaseResponseIEs_t));
|
||||
ASN_SEQUENCE_ADD(&PDUSessionResourceReleaseResponse->protocolIEs, ie);
|
||||
|
||||
ie->id = NGAP_ProtocolIE_ID_id_PDUSessionResourceReleasedListRelRes;
|
||||
ie->criticality = NGAP_Criticality_ignore;
|
||||
ie->value.present = NGAP_PDUSessionResourceReleaseResponseIEs__value_PR_PDUSessionResourceReleasedListRelRes;
|
||||
|
||||
PDUSessionList = &ie->value.choice.PDUSessionResourceReleasedListRelRes;
|
||||
|
||||
asn_uint642INTEGER(AMF_UE_NGAP_ID, test_ue->amf_ue_ngap_id);
|
||||
*RAN_UE_NGAP_ID = test_ue->ran_ue_ngap_id;
|
||||
|
||||
PDUSessionItem =
|
||||
CALLOC(1, sizeof(struct NGAP_PDUSessionResourceReleasedItemRelRes));
|
||||
ASN_SEQUENCE_ADD(&PDUSessionList->list, PDUSessionItem);
|
||||
|
||||
PDUSessionItem->pDUSessionID = sess->psi;
|
||||
|
||||
transfer = &PDUSessionItem->pDUSessionResourceReleaseResponseTransfer;
|
||||
|
||||
transfer->size = 1;
|
||||
transfer->buf = CALLOC(transfer->size, sizeof(uint8_t));
|
||||
|
||||
return nga_ngap_encode(&pdu);
|
||||
}
|
||||
|
||||
static ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response_trasfer(
|
||||
test_sess_t *sess)
|
||||
{
|
||||
ogs_ip_t gnb_n3_ip;
|
||||
|
|
|
@ -44,6 +44,8 @@ ogs_pkbuf_t *testngap_build_ue_context_release_complete(test_ue_t *test_ue);
|
|||
|
||||
ogs_pkbuf_t *testngap_build_pdu_session_resource_setup_response(
|
||||
test_sess_t *sess);
|
||||
ogs_pkbuf_t *testngap_build_pdu_session_resource_release_response(
|
||||
test_sess_t *sess);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -248,3 +248,44 @@ void testngap_handle_pdu_session_resource_setup_request(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testngap_handle_pdu_session_resource_release_command(
|
||||
test_ue_t *test_ue, ogs_ngap_message_t *message)
|
||||
{
|
||||
test_sess_t *sess = NULL;
|
||||
int rv, i, j, k;
|
||||
char buf[OGS_ADDRSTRLEN];
|
||||
|
||||
NGAP_NGAP_PDU_t pdu;
|
||||
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
|
||||
NGAP_PDUSessionResourceReleaseCommand_t *PDUSessionResourceReleaseCommand;
|
||||
|
||||
NGAP_PDUSessionResourceReleaseCommandIEs_t *ie = NULL;
|
||||
NGAP_NAS_PDU_t *NAS_PDU = NULL;
|
||||
|
||||
ogs_assert(test_ue);
|
||||
sess = test_ue->sess;
|
||||
ogs_assert(sess);
|
||||
ogs_assert(message);
|
||||
|
||||
initiatingMessage = message->choice.initiatingMessage;
|
||||
ogs_assert(initiatingMessage);
|
||||
PDUSessionResourceReleaseCommand =
|
||||
&initiatingMessage->value.choice.PDUSessionResourceReleaseCommand;
|
||||
ogs_assert(PDUSessionResourceReleaseCommand);
|
||||
|
||||
for (i = 0; i < PDUSessionResourceReleaseCommand->protocolIEs.list.count;
|
||||
i++) {
|
||||
ie = PDUSessionResourceReleaseCommand->protocolIEs.list.array[i];
|
||||
switch (ie->id) {
|
||||
case NGAP_ProtocolIE_ID_id_NAS_PDU:
|
||||
NAS_PDU = &ie->value.choice.NAS_PDU;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (NAS_PDU)
|
||||
testngap_send_to_nas(test_ue, NAS_PDU);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ void testngap_handle_initial_context_setup_request(
|
|||
test_ue_t *test_ue, ogs_ngap_message_t *message);
|
||||
void testngap_handle_pdu_session_resource_setup_request(
|
||||
test_ue_t *test_ue, ogs_ngap_message_t *message);
|
||||
void testngap_handle_pdu_session_resource_release_command(
|
||||
test_ue_t *test_ue, ogs_ngap_message_t *message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -53,6 +53,9 @@ void testngap_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
|
|||
case NGAP_ProcedureCode_id_PDUSessionResourceSetup:
|
||||
testngap_handle_pdu_session_resource_setup_request(test_ue, pdu);
|
||||
break;
|
||||
case NGAP_ProcedureCode_id_PDUSessionResourceRelease:
|
||||
testngap_handle_pdu_session_resource_release_command(test_ue, pdu);
|
||||
break;
|
||||
case NGAP_ProcedureCode_id_UEContextRelease:
|
||||
/* Nothing */
|
||||
break;
|
||||
|
|
|
@ -523,11 +523,362 @@ static void test1_func(abts_case *tc, void *data)
|
|||
test_ue_remove(&test_ue);
|
||||
}
|
||||
|
||||
static void test2_func(abts_case *tc, void *data)
|
||||
{
|
||||
int rv;
|
||||
ogs_socknode_t *ngap;
|
||||
ogs_socknode_t *gtpu;
|
||||
ogs_pkbuf_t *gmmbuf;
|
||||
ogs_pkbuf_t *gsmbuf;
|
||||
ogs_pkbuf_t *nasbuf;
|
||||
ogs_pkbuf_t *sendbuf;
|
||||
ogs_pkbuf_t *recvbuf;
|
||||
ogs_ngap_message_t message;
|
||||
int i;
|
||||
int msgindex = 0;
|
||||
|
||||
ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci;
|
||||
test_ue_t test_ue;
|
||||
test_sess_t test_sess;
|
||||
|
||||
uint8_t tmp[OGS_MAX_SDU_LEN];
|
||||
|
||||
const char *_k_string = "70d49a71dd1a2b806a25abe0ef749f1e";
|
||||
uint8_t k[OGS_KEY_LEN];
|
||||
const char *_opc_string = "6f1bf53d624b3a43af6592854e2444c7";
|
||||
uint8_t opc[OGS_KEY_LEN];
|
||||
|
||||
mongoc_collection_t *collection = NULL;
|
||||
bson_t *doc = NULL;
|
||||
int64_t count = 0;
|
||||
bson_error_t error;
|
||||
const char *json =
|
||||
"{"
|
||||
"\"_id\" : { \"$oid\" : \"597223158b8861d7605378c6\" }, "
|
||||
"\"imsi\" : \"901700000021309\","
|
||||
"\"ambr\" : { "
|
||||
"\"uplink\" : { \"$numberLong\" : \"1024000\" }, "
|
||||
"\"downlink\" : { \"$numberLong\" : \"1024000\" } "
|
||||
"},"
|
||||
"\"pdn\" : ["
|
||||
"{"
|
||||
"\"apn\" : \"internet\", "
|
||||
"\"_id\" : { \"$oid\" : \"597223158b8861d7605378c7\" }, "
|
||||
"\"ambr\" : {"
|
||||
"\"uplink\" : { \"$numberLong\" : \"1024000\" }, "
|
||||
"\"downlink\" : { \"$numberLong\" : \"1024000\" } "
|
||||
"},"
|
||||
"\"qos\" : { "
|
||||
"\"qci\" : 9, "
|
||||
"\"arp\" : { "
|
||||
"\"priority_level\" : 8,"
|
||||
"\"pre_emption_vulnerability\" : 1, "
|
||||
"\"pre_emption_capability\" : 1"
|
||||
"} "
|
||||
"}, "
|
||||
"\"type\" : 2"
|
||||
"}"
|
||||
"],"
|
||||
"\"security\" : { "
|
||||
"\"k\" : \"70d49a71dd1a2b806a25abe0ef749f1e\", "
|
||||
"\"opc\" : \"6f1bf53d624b3a43af6592854e2444c7\", "
|
||||
"\"amf\" : \"8000\", "
|
||||
"\"sqn\" : { \"$numberLong\" : \"25235952177090\" } "
|
||||
"}, "
|
||||
"\"subscribed_rau_tau_timer\" : 12,"
|
||||
"\"network_access_mode\" : 2, "
|
||||
"\"subscriber_status\" : 0, "
|
||||
"\"access_restriction_data\" : 32, "
|
||||
"\"__v\" : 0 "
|
||||
"}";
|
||||
|
||||
/* Setup Test UE & Session Context */
|
||||
memset(&test_ue, 0, sizeof(test_ue));
|
||||
memset(&test_sess, 0, sizeof(test_sess));
|
||||
test_sess.test_ue = &test_ue;
|
||||
test_ue.sess = &test_sess;
|
||||
|
||||
test_ue.nas.registration.type = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE;
|
||||
test_ue.nas.registration.follow_on_request = 1;
|
||||
test_ue.nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL;
|
||||
|
||||
memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci));
|
||||
|
||||
mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI;
|
||||
mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI;
|
||||
ogs_nas_from_plmn_id(&mobile_identity_suci.nas_plmn_id,
|
||||
&test_self()->tai.plmn_id);
|
||||
mobile_identity_suci.routing_indicator1 = 0;
|
||||
mobile_identity_suci.routing_indicator2 = 0xf;
|
||||
mobile_identity_suci.routing_indicator3 = 0xf;
|
||||
mobile_identity_suci.routing_indicator4 = 0xf;
|
||||
mobile_identity_suci.protection_scheme_id = OGS_NAS_5GS_NULL_SCHEME;
|
||||
mobile_identity_suci.home_network_pki_value = 0;
|
||||
mobile_identity_suci.scheme_output[0] = 0;
|
||||
mobile_identity_suci.scheme_output[1] = 0;
|
||||
mobile_identity_suci.scheme_output[2] = 0x20;
|
||||
mobile_identity_suci.scheme_output[3] = 0x31;
|
||||
mobile_identity_suci.scheme_output[4] = 0x90;
|
||||
|
||||
test_ue_set_mobile_identity_suci(&test_ue, &mobile_identity_suci, 13);
|
||||
|
||||
memset(&test_ue.mobile_identity_imeisv, 0,
|
||||
sizeof(ogs_nas_mobile_identity_imeisv_t));
|
||||
test_ue.mobile_identity_imeisv.type = OGS_NAS_5GS_MOBILE_IDENTITY_IMEISV;
|
||||
test_ue.mobile_identity_imeisv.odd_even = OGS_NAS_MOBILE_IDENTITY_EVEN;
|
||||
test_ue.mobile_identity_imeisv.digit1 = 8;
|
||||
test_ue.mobile_identity_imeisv.digit2 = 6;
|
||||
test_ue.mobile_identity_imeisv.digit3 = 6;
|
||||
test_ue.mobile_identity_imeisv.digit4 = 5;
|
||||
test_ue.mobile_identity_imeisv.digit5 = 0;
|
||||
test_ue.mobile_identity_imeisv.digit6 = 7;
|
||||
test_ue.mobile_identity_imeisv.digit7 = 0;
|
||||
test_ue.mobile_identity_imeisv.digit8 = 4;
|
||||
test_ue.mobile_identity_imeisv.digit9 = 0;
|
||||
test_ue.mobile_identity_imeisv.digit10 = 0;
|
||||
test_ue.mobile_identity_imeisv.digit11 = 4;
|
||||
test_ue.mobile_identity_imeisv.digit12 = 0;
|
||||
test_ue.mobile_identity_imeisv.digit13 = 5;
|
||||
test_ue.mobile_identity_imeisv.digit14 = 3;
|
||||
test_ue.mobile_identity_imeisv.digit15 = 0;
|
||||
test_ue.mobile_identity_imeisv.digit16 = 1;
|
||||
test_ue.mobile_identity_imeisv.digit17 = 0xf;
|
||||
|
||||
test_ue.nas.access_type = OGS_ACCESS_TYPE_3GPP;
|
||||
test_ue.abba_len = 2;
|
||||
|
||||
OGS_HEX(_k_string, strlen(_k_string), test_ue.k);
|
||||
OGS_HEX(_opc_string, strlen(_opc_string), test_ue.opc);
|
||||
|
||||
test_sess.psi = 5;
|
||||
test_sess.pti = 1;
|
||||
test_sess.pdu_session_type = OGS_PDU_SESSION_TYPE_IPV4V6;
|
||||
test_sess.dnn = (char *)"internet";
|
||||
|
||||
memset(&test_sess.gnb_n3_ip, 0, sizeof(test_sess.gnb_n3_ip));
|
||||
test_sess.gnb_n3_ip.ipv4 = true;
|
||||
test_sess.gnb_n3_ip.addr = inet_addr("127.0.0.5");
|
||||
test_sess.gnb_n3_teid = 0;
|
||||
|
||||
/* gNB connects to AMF */
|
||||
ngap = testgnb_ngap_client("127.0.0.2");
|
||||
ABTS_PTR_NOTNULL(tc, ngap);
|
||||
|
||||
/* gNB connects to UPF */
|
||||
gtpu = testgnb_gtpu_server("127.0.0.5");
|
||||
ABTS_PTR_NOTNULL(tc, gtpu);
|
||||
|
||||
/* Send NG-Setup Reqeust */
|
||||
sendbuf = testngap_build_ng_setup_request(0x4000, 22);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive NG-Setup Response */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(&test_ue, recvbuf);
|
||||
|
||||
/********** Insert Subscriber in Database */
|
||||
collection = mongoc_client_get_collection(
|
||||
ogs_mongoc()->client, ogs_mongoc()->name, "subscribers");
|
||||
ABTS_PTR_NOTNULL(tc, collection);
|
||||
doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi));
|
||||
ABTS_PTR_NOTNULL(tc, doc);
|
||||
|
||||
count = mongoc_collection_count (
|
||||
collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
|
||||
if (count) {
|
||||
ABTS_TRUE(tc, mongoc_collection_remove(collection,
|
||||
MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error))
|
||||
}
|
||||
bson_destroy(doc);
|
||||
|
||||
doc = bson_new_from_json((const uint8_t *)json, -1, &error);;
|
||||
ABTS_PTR_NOTNULL(tc, doc);
|
||||
ABTS_TRUE(tc, mongoc_collection_insert(collection,
|
||||
MONGOC_INSERT_NONE, doc, NULL, &error));
|
||||
bson_destroy(doc);
|
||||
|
||||
doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi));
|
||||
ABTS_PTR_NOTNULL(tc, doc);
|
||||
do {
|
||||
count = mongoc_collection_count (
|
||||
collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
|
||||
} while (count == 0);
|
||||
bson_destroy(doc);
|
||||
|
||||
/* Send Registration request */
|
||||
test_ue.registration_request_type.guti = 1;
|
||||
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
|
||||
test_ue.registration_request_type.requested_nssai = 1;
|
||||
test_ue.registration_request_type.last_visited_registered_tai = 1;
|
||||
test_ue.registration_request_type.ue_usage_setting = 1;
|
||||
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
|
||||
ABTS_PTR_NOTNULL(tc, nasbuf);
|
||||
|
||||
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, false);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Identity request */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(&test_ue, recvbuf);
|
||||
|
||||
/* Send Identity response */
|
||||
gmmbuf = testgmm_build_identity_response(&test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Authentication request */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(&test_ue, recvbuf);
|
||||
|
||||
/* Send Authentication response */
|
||||
gmmbuf = testgmm_build_authentication_response(&test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Security mode command */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(&test_ue, recvbuf);
|
||||
|
||||
/* Send Security mode complete */
|
||||
gmmbuf = testgmm_build_security_mode_complete(&test_ue, nasbuf);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Initial context setup request */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(&test_ue, recvbuf);
|
||||
|
||||
/* Send UE radio capability info indication */
|
||||
sendbuf = testngap_build_ue_radio_capability_info_indication(&test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Send Initial context setup response */
|
||||
sendbuf = testngap_build_initial_context_setup_response(&test_ue, NULL);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Send Registration complete */
|
||||
gmmbuf = testgmm_build_registration_complete(&test_ue);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive Configuration update command */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(&test_ue, recvbuf);
|
||||
|
||||
/* Send PDU session establishment request */
|
||||
gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess);
|
||||
ABTS_PTR_NOTNULL(tc, gsmbuf);
|
||||
gmmbuf = testgmm_build_ul_nas_transport(&test_sess,
|
||||
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive PDU session establishment accept */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(&test_ue, recvbuf);
|
||||
|
||||
/* Send PDU session resource setup response */
|
||||
sendbuf = testngap_build_pdu_session_resource_setup_response(&test_sess);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
ogs_msleep(100);
|
||||
|
||||
/* Send PDU Session release request */
|
||||
gsmbuf = testgsm_build_pdu_session_release_request(&test_sess);
|
||||
ABTS_PTR_NOTNULL(tc, gsmbuf);
|
||||
gmmbuf = testgmm_build_ul_nas_transport(&test_sess,
|
||||
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
/* Receive PDU session release command */
|
||||
recvbuf = testgnb_ngap_read(ngap);
|
||||
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||
testngap_recv(&test_ue, recvbuf);
|
||||
|
||||
/* Send PDU session resource release response */
|
||||
sendbuf = testngap_build_pdu_session_resource_release_response(&test_sess);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
ogs_msleep(100);
|
||||
|
||||
/* Send PDU session resource release complete */
|
||||
gsmbuf = testgsm_build_pdu_session_release_complete(&test_sess);
|
||||
ABTS_PTR_NOTNULL(tc, gsmbuf);
|
||||
gmmbuf = testgmm_build_ul_nas_transport(&test_sess,
|
||||
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, gmmbuf);
|
||||
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
|
||||
ABTS_PTR_NOTNULL(tc, sendbuf);
|
||||
rv = testgnb_ngap_send(ngap, sendbuf);
|
||||
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||
|
||||
ogs_msleep(100);
|
||||
|
||||
/********** Remove Subscriber in Database */
|
||||
doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi));
|
||||
ABTS_PTR_NOTNULL(tc, doc);
|
||||
ABTS_TRUE(tc, mongoc_collection_remove(collection,
|
||||
MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error))
|
||||
bson_destroy(doc);
|
||||
|
||||
mongoc_collection_destroy(collection);
|
||||
|
||||
/* gNB disonncect from UPF */
|
||||
testgnb_gtpu_close(gtpu);
|
||||
|
||||
/* gNB disonncect from AMF */
|
||||
testgnb_ngap_close(ngap);
|
||||
|
||||
/* Clear Test UE Context */
|
||||
test_ue_remove(&test_ue);
|
||||
}
|
||||
|
||||
abts_suite *test_guti(abts_suite *suite)
|
||||
{
|
||||
suite = ADD_SUITE(suite)
|
||||
|
||||
abts_run_test(suite, test1_func, NULL);
|
||||
abts_run_test(suite, test2_func, NULL);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue