[CSFB] Add MO in Active-mode

This commit is contained in:
Sukchan Lee 2019-07-10 22:04:52 +09:00
parent 9dbca85c1f
commit d9b7e966e1
13 changed files with 780 additions and 105 deletions

View File

@ -347,6 +347,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
} }
if (procedureCode == S1AP_ProcedureCode_id_initialUEMessage) { if (procedureCode == S1AP_ProcedureCode_id_initialUEMessage) {
ogs_debug(" Initial UE Message");
if (mme_ue->nas_eps.service.service_type == if (mme_ue->nas_eps.service.service_type ==
NAS_SERVICE_TYPE_CS_FALLBACK_FROM_UE || NAS_SERVICE_TYPE_CS_FALLBACK_FROM_UE ||
mme_ue->nas_eps.service.service_type == mme_ue->nas_eps.service.service_type ==
@ -368,12 +369,34 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
OGS_FSM_TRAN(s, &emm_state_exception); OGS_FSM_TRAN(s, &emm_state_exception);
return; return;
} }
ogs_debug(" Iniital UE Message");
rv = s1ap_send_initial_context_setup_request(mme_ue); rv = s1ap_send_initial_context_setup_request(mme_ue);
ogs_assert(rv == OGS_OK); ogs_assert(rv == OGS_OK);
} else if (procedureCode == S1AP_ProcedureCode_id_uplinkNASTransport) { } else if (procedureCode == S1AP_ProcedureCode_id_uplinkNASTransport) {
ogs_error(" Uplink NAS Transport : Not Implemented"); ogs_debug(" Uplink NAS Transport");
ogs_assert_if_reached(); if (mme_ue->nas_eps.service.service_type ==
NAS_SERVICE_TYPE_CS_FALLBACK_FROM_UE ||
mme_ue->nas_eps.service.service_type ==
NAS_SERVICE_TYPE_CS_FALLBACK_EMERGENCY_CALL_FROM_UE) {
ogs_debug(" MO-CSFB-INDICATION[%d]",
mme_ue->nas_eps.service.service_type);
sgsap_send_mo_csfb_indication(mme_ue);
} else if (mme_ue->nas_eps.service.service_type ==
NAS_SERVICE_TYPE_CS_FALLBACK_TO_UE) {
ogs_debug(" SERVICE_REQUEST[%d]",
mme_ue->nas_eps.service.service_type);
sgsap_send_service_request(mme_ue, SGSAP_EMM_CONNECTED_MODE);
} else {
ogs_warn(" Unknown CSFB Service Type[%d]",
mme_ue->nas_eps.service.service_type);
rv = nas_send_service_reject(mme_ue,
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
ogs_assert(rv == OGS_OK);
OGS_FSM_TRAN(s, &emm_state_exception);
return;
}
rv = s1ap_send_ue_context_modification_request(mme_ue);
ogs_assert(rv == OGS_OK);
} else { } else {
ogs_fatal("Invalid Procedure Code[%d]", (int)procedureCode); ogs_fatal("Invalid Procedure Code[%d]", (int)procedureCode);
ogs_assert_if_reached(); ogs_assert_if_reached();

View File

@ -559,6 +559,236 @@ int s1ap_build_initial_context_setup_request(
return OGS_OK; return OGS_OK;
} }
int s1ap_build_ue_context_modification_request(
ogs_pkbuf_t **s1apbuf, mme_ue_t *mme_ue)
{
int rv;
S1AP_S1AP_PDU_t pdu;
S1AP_InitiatingMessage_t *initiatingMessage = NULL;
S1AP_UEContextModificationRequest_t *UEContextModificationRequest = NULL;
S1AP_UEContextModificationRequestIEs_t *ie = NULL;
S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL;
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
S1AP_UESecurityCapabilities_t *UESecurityCapabilities = NULL;
S1AP_SecurityKey_t *SecurityKey = NULL;
S1AP_CSFallbackIndicator_t *CSFallbackIndicator = NULL;
S1AP_LAI_t *LAI = NULL;
enb_ue_t *enb_ue = NULL;
ogs_assert(mme_ue);
enb_ue = mme_ue->enb_ue;
ogs_assert(enb_ue);
ogs_debug("[MME] UE context modification request");
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
ogs_calloc(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode =
S1AP_ProcedureCode_id_UEContextModification;
initiatingMessage->criticality = S1AP_Criticality_reject;
initiatingMessage->value.present =
S1AP_InitiatingMessage__value_PR_UEContextModificationRequest;
UEContextModificationRequest =
&initiatingMessage->value.choice.UEContextModificationRequest;
ie = ogs_calloc(1, sizeof(S1AP_UEContextModificationRequestIEs_t));
ASN_SEQUENCE_ADD(&UEContextModificationRequest->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID;
ie->criticality = S1AP_Criticality_reject;
ie->value.present =
S1AP_UEContextModificationRequestIEs__value_PR_MME_UE_S1AP_ID,
MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID;
ie = ogs_calloc(1, sizeof(S1AP_UEContextModificationRequestIEs_t));
ASN_SEQUENCE_ADD(&UEContextModificationRequest->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID;
ie->criticality = S1AP_Criticality_reject;
ie->value.present =
S1AP_UEContextModificationRequestIEs__value_PR_ENB_UE_S1AP_ID,
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
ie = ogs_calloc(1, sizeof(S1AP_UEContextModificationRequestIEs_t));
ASN_SEQUENCE_ADD(&UEContextModificationRequest->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_UESecurityCapabilities;
ie->criticality = S1AP_Criticality_reject;
ie->value.present =
S1AP_UEContextModificationRequestIEs__value_PR_UESecurityCapabilities,
UESecurityCapabilities = &ie->value.choice.UESecurityCapabilities;
ie = ogs_calloc(1, sizeof(S1AP_UEContextModificationRequestIEs_t));
ASN_SEQUENCE_ADD(&UEContextModificationRequest->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_SecurityKey;
ie->criticality = S1AP_Criticality_reject;
ie->value.present =
S1AP_UEContextModificationRequestIEs__value_PR_SecurityKey,
SecurityKey = &ie->value.choice.SecurityKey;
ogs_debug(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]",
enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id);
*MME_UE_S1AP_ID = enb_ue->mme_ue_s1ap_id;
*ENB_UE_S1AP_ID = enb_ue->enb_ue_s1ap_id;
UESecurityCapabilities->encryptionAlgorithms.size = 2;
UESecurityCapabilities->encryptionAlgorithms.buf =
ogs_calloc(UESecurityCapabilities->encryptionAlgorithms.size,
sizeof(uint8_t));
UESecurityCapabilities->encryptionAlgorithms.bits_unused = 0;
UESecurityCapabilities->encryptionAlgorithms.buf[0] =
(mme_ue->ue_network_capability.eea << 1);
UESecurityCapabilities->integrityProtectionAlgorithms.size = 2;
UESecurityCapabilities->integrityProtectionAlgorithms.buf =
ogs_calloc(UESecurityCapabilities->
integrityProtectionAlgorithms.size, sizeof(uint8_t));
UESecurityCapabilities->integrityProtectionAlgorithms.bits_unused = 0;
UESecurityCapabilities->integrityProtectionAlgorithms.buf[0] =
(mme_ue->ue_network_capability.eia << 1);
SecurityKey->size = OGS_SHA256_DIGEST_SIZE;
SecurityKey->buf =
ogs_calloc(SecurityKey->size, sizeof(uint8_t));
SecurityKey->bits_unused = 0;
memcpy(SecurityKey->buf, mme_ue->kenb, SecurityKey->size);
ie = ogs_calloc(1, sizeof(S1AP_UEContextModificationRequestIEs_t));
ASN_SEQUENCE_ADD(&UEContextModificationRequest->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_CSFallbackIndicator;
ie->criticality = S1AP_Criticality_reject;
ie->value.present =
S1AP_UEContextModificationRequestIEs__value_PR_CSFallbackIndicator;
CSFallbackIndicator = &ie->value.choice.CSFallbackIndicator;
ogs_assert(CSFallbackIndicator);
*CSFallbackIndicator = S1AP_CSFallbackIndicator_cs_fallback_required;
ie = ogs_calloc(1, sizeof(S1AP_UEContextModificationRequestIEs_t));
ASN_SEQUENCE_ADD(&UEContextModificationRequest->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_RegisteredLAI;
ie->criticality = S1AP_Criticality_ignore;
ie->value.present =
S1AP_UEContextModificationRequestIEs__value_PR_LAI;
LAI = &ie->value.choice.LAI;
ogs_assert(LAI);
s1ap_buffer_to_OCTET_STRING(&mme_ue->tai.plmn_id, sizeof(plmn_id_t),
&LAI->pLMNidentity);
ogs_assert(mme_ue->vlr);
ogs_assert(mme_ue->p_tmsi);
s1ap_uint16_to_OCTET_STRING(mme_ue->vlr->lai.lac, &LAI->lAC);
rv = s1ap_encode_pdu(s1apbuf, &pdu);
s1ap_free_pdu(&pdu);
if (rv != OGS_OK) {
ogs_error("s1ap_encode_pdu() failed");
return OGS_ERROR;
}
return OGS_OK;
}
int s1ap_build_ue_context_release_command(
ogs_pkbuf_t **s1apbuf, enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause)
{
int rv;
S1AP_S1AP_PDU_t pdu;
S1AP_InitiatingMessage_t *initiatingMessage = NULL;
S1AP_UEContextReleaseCommand_t *UEContextReleaseCommand = NULL;
S1AP_UEContextReleaseCommand_IEs_t *ie = NULL;
S1AP_UE_S1AP_IDs_t *UE_S1AP_IDs = NULL;
S1AP_Cause_t *Cause = NULL;
ogs_assert(enb_ue);
if (enb_ue->mme_ue_s1ap_id == 0) {
ogs_error("invalid mme ue s1ap id");
return OGS_ERROR;
}
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
ogs_calloc(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_UEContextRelease;
initiatingMessage->criticality = S1AP_Criticality_reject;
initiatingMessage->value.present =
S1AP_InitiatingMessage__value_PR_UEContextReleaseCommand;
UEContextReleaseCommand =
&initiatingMessage->value.choice.UEContextReleaseCommand;
ie = ogs_calloc(1, sizeof(S1AP_UEContextReleaseCommand_IEs_t));
ASN_SEQUENCE_ADD(&UEContextReleaseCommand->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_UE_S1AP_IDs;
ie->criticality = S1AP_Criticality_reject;
ie->value.present = S1AP_UEContextReleaseCommand_IEs__value_PR_UE_S1AP_IDs;
UE_S1AP_IDs = &ie->value.choice.UE_S1AP_IDs;
ie = ogs_calloc(1, sizeof(S1AP_UEContextReleaseCommand_IEs_t));
ASN_SEQUENCE_ADD(&UEContextReleaseCommand->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_Cause;
ie->criticality = S1AP_Criticality_ignore;
ie->value.present = S1AP_UEContextReleaseCommand_IEs__value_PR_Cause;
Cause = &ie->value.choice.Cause;
if (enb_ue->enb_ue_s1ap_id == INVALID_UE_S1AP_ID) {
UE_S1AP_IDs->present = S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID;
UE_S1AP_IDs->choice.mME_UE_S1AP_ID = enb_ue->mme_ue_s1ap_id;
} else {
UE_S1AP_IDs->present = S1AP_UE_S1AP_IDs_PR_uE_S1AP_ID_pair;
UE_S1AP_IDs->choice.uE_S1AP_ID_pair =
ogs_calloc(1, sizeof(S1AP_UE_S1AP_ID_pair_t));
UE_S1AP_IDs->choice.uE_S1AP_ID_pair->mME_UE_S1AP_ID =
enb_ue->mme_ue_s1ap_id;
UE_S1AP_IDs->choice.uE_S1AP_ID_pair->eNB_UE_S1AP_ID =
enb_ue->enb_ue_s1ap_id;
}
Cause->present = group;
Cause->choice.radioNetwork = cause;
rv = s1ap_encode_pdu(s1apbuf, &pdu);
s1ap_free_pdu(&pdu);
if (rv != OGS_OK) {
ogs_error("s1ap_encode_pdu() failed");
return OGS_ERROR;
}
return OGS_OK;
}
int s1ap_build_e_rab_setup_request( int s1ap_build_e_rab_setup_request(
ogs_pkbuf_t **s1apbuf, mme_bearer_t *bearer, ogs_pkbuf_t *esmbuf) ogs_pkbuf_t **s1apbuf, mme_bearer_t *bearer, ogs_pkbuf_t *esmbuf)
{ {
@ -986,85 +1216,6 @@ int s1ap_build_e_rab_release_command(ogs_pkbuf_t **s1apbuf,
return OGS_OK; return OGS_OK;
} }
int s1ap_build_ue_context_release_command(
ogs_pkbuf_t **s1apbuf, enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause)
{
int rv;
S1AP_S1AP_PDU_t pdu;
S1AP_InitiatingMessage_t *initiatingMessage = NULL;
S1AP_UEContextReleaseCommand_t *UEContextReleaseCommand = NULL;
S1AP_UEContextReleaseCommand_IEs_t *ie = NULL;
S1AP_UE_S1AP_IDs_t *UE_S1AP_IDs = NULL;
S1AP_Cause_t *Cause = NULL;
ogs_assert(enb_ue);
if (enb_ue->mme_ue_s1ap_id == 0) {
ogs_error("invalid mme ue s1ap id");
return OGS_ERROR;
}
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage =
ogs_calloc(1, sizeof(S1AP_InitiatingMessage_t));
initiatingMessage = pdu.choice.initiatingMessage;
initiatingMessage->procedureCode = S1AP_ProcedureCode_id_UEContextRelease;
initiatingMessage->criticality = S1AP_Criticality_reject;
initiatingMessage->value.present =
S1AP_InitiatingMessage__value_PR_UEContextReleaseCommand;
UEContextReleaseCommand =
&initiatingMessage->value.choice.UEContextReleaseCommand;
ie = ogs_calloc(1, sizeof(S1AP_UEContextReleaseCommand_IEs_t));
ASN_SEQUENCE_ADD(&UEContextReleaseCommand->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_UE_S1AP_IDs;
ie->criticality = S1AP_Criticality_reject;
ie->value.present = S1AP_UEContextReleaseCommand_IEs__value_PR_UE_S1AP_IDs;
UE_S1AP_IDs = &ie->value.choice.UE_S1AP_IDs;
ie = ogs_calloc(1, sizeof(S1AP_UEContextReleaseCommand_IEs_t));
ASN_SEQUENCE_ADD(&UEContextReleaseCommand->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_Cause;
ie->criticality = S1AP_Criticality_ignore;
ie->value.present = S1AP_UEContextReleaseCommand_IEs__value_PR_Cause;
Cause = &ie->value.choice.Cause;
if (enb_ue->enb_ue_s1ap_id == INVALID_UE_S1AP_ID) {
UE_S1AP_IDs->present = S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID;
UE_S1AP_IDs->choice.mME_UE_S1AP_ID = enb_ue->mme_ue_s1ap_id;
} else {
UE_S1AP_IDs->present = S1AP_UE_S1AP_IDs_PR_uE_S1AP_ID_pair;
UE_S1AP_IDs->choice.uE_S1AP_ID_pair =
ogs_calloc(1, sizeof(S1AP_UE_S1AP_ID_pair_t));
UE_S1AP_IDs->choice.uE_S1AP_ID_pair->mME_UE_S1AP_ID =
enb_ue->mme_ue_s1ap_id;
UE_S1AP_IDs->choice.uE_S1AP_ID_pair->eNB_UE_S1AP_ID =
enb_ue->enb_ue_s1ap_id;
}
Cause->present = group;
Cause->choice.radioNetwork = cause;
rv = s1ap_encode_pdu(s1apbuf, &pdu);
s1ap_free_pdu(&pdu);
if (rv != OGS_OK) {
ogs_error("s1ap_encode_pdu() failed");
return OGS_ERROR;
}
return OGS_OK;
}
int s1ap_build_paging(ogs_pkbuf_t **s1apbuf, int s1ap_build_paging(ogs_pkbuf_t **s1apbuf,
mme_ue_t *mme_ue, S1AP_CNDomain_t cn_domain) mme_ue_t *mme_ue, S1AP_CNDomain_t cn_domain)
{ {

View File

@ -32,18 +32,24 @@ extern "C" {
int s1ap_build_setup_rsp(ogs_pkbuf_t **pkbuf); int s1ap_build_setup_rsp(ogs_pkbuf_t **pkbuf);
int s1ap_build_setup_failure( int s1ap_build_setup_failure(
ogs_pkbuf_t **pkbuf, S1AP_Cause_PR group, long cause, long time_to_wait); ogs_pkbuf_t **pkbuf, S1AP_Cause_PR group, long cause, long time_to_wait);
int s1ap_build_downlink_nas_transport( int s1ap_build_downlink_nas_transport(
ogs_pkbuf_t **s1apbuf, enb_ue_t *enb_ue, ogs_pkbuf_t *emmbuf); ogs_pkbuf_t **s1apbuf, enb_ue_t *enb_ue, ogs_pkbuf_t *emmbuf);
int s1ap_build_initial_context_setup_request( int s1ap_build_initial_context_setup_request(
ogs_pkbuf_t **s1apbuf, mme_ue_t *mme_ue, ogs_pkbuf_t *emmbuf); ogs_pkbuf_t **s1apbuf, mme_ue_t *mme_ue, ogs_pkbuf_t *emmbuf);
int s1ap_build_ue_context_modification_request(
ogs_pkbuf_t **s1apbuf, mme_ue_t *mme_ue);
int s1ap_build_ue_context_release_command(
ogs_pkbuf_t **s1apbuf, enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause);
int s1ap_build_e_rab_setup_request( int s1ap_build_e_rab_setup_request(
ogs_pkbuf_t **s1apbuf, mme_bearer_t *bearer, ogs_pkbuf_t *esmbuf); ogs_pkbuf_t **s1apbuf, mme_bearer_t *bearer, ogs_pkbuf_t *esmbuf);
int s1ap_build_e_rab_modify_request( int s1ap_build_e_rab_modify_request(
ogs_pkbuf_t **s1apbuf, mme_bearer_t *bearer, ogs_pkbuf_t *esmbuf); ogs_pkbuf_t **s1apbuf, mme_bearer_t *bearer, ogs_pkbuf_t *esmbuf);
int s1ap_build_e_rab_release_command(ogs_pkbuf_t **s1apbuf, int s1ap_build_e_rab_release_command(ogs_pkbuf_t **s1apbuf,
mme_bearer_t *bearer, ogs_pkbuf_t *esmbuf, S1AP_Cause_PR group, long cause); mme_bearer_t *bearer, ogs_pkbuf_t *esmbuf, S1AP_Cause_PR group, long cause);
int s1ap_build_ue_context_release_command(
ogs_pkbuf_t **s1apbuf, enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause);
int s1ap_build_paging(ogs_pkbuf_t **s1apbuf, int s1ap_build_paging(ogs_pkbuf_t **s1apbuf,
mme_ue_t *mme_ue, S1AP_CNDomain_t cn_domain); mme_ue_t *mme_ue, S1AP_CNDomain_t cn_domain);

View File

@ -567,8 +567,8 @@ void s1ap_handle_initial_context_setup_failure(
enb_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, *ENB_UE_S1AP_ID); enb_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, *ENB_UE_S1AP_ID);
if (enb_ue == NULL) { if (enb_ue == NULL) {
ogs_warn("Initial context setup failure : cannot find eNB-UE-S1AP-ID[%d]", ogs_warn("Initial context setup failure : "
(int)*ENB_UE_S1AP_ID); "cannot find eNB-UE-S1AP-ID[%d]", (int)*ENB_UE_S1AP_ID);
return; return;
} }
mme_ue = enb_ue->mme_ue; mme_ue = enb_ue->mme_ue;
@ -600,6 +600,119 @@ void s1ap_handle_initial_context_setup_failure(
} }
} }
void s1ap_handle_ue_context_modification_response(
mme_enb_t *enb, s1ap_message_t *message)
{
char buf[OGS_ADDRSTRLEN];
int i;
S1AP_SuccessfulOutcome_t *successfulOutcome = NULL;
S1AP_UEContextModificationResponse_t *UEContextModificationResponse = NULL;
S1AP_UEContextModificationResponseIEs_t *ie = NULL;
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
mme_ue_t *mme_ue = NULL;
enb_ue_t *enb_ue = NULL;
ogs_assert(enb);
ogs_assert(enb->sock);
ogs_assert(message);
successfulOutcome = message->choice.successfulOutcome;
ogs_assert(successfulOutcome);
UEContextModificationResponse =
&successfulOutcome->value.choice.UEContextModificationResponse;
ogs_assert(UEContextModificationResponse);
ogs_debug("[MME] UE context modification response");
for (i = 0; i < UEContextModificationResponse->protocolIEs.list.count; i++) {
ie = UEContextModificationResponse->protocolIEs.list.array[i];
switch (ie->id) {
case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID:
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
break;
default:
break;
}
}
ogs_debug(" IP[%s] ENB_ID[%d]",
OGS_ADDR(enb->addr, buf), enb->enb_id);
ogs_assert(ENB_UE_S1AP_ID);
enb_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, *ENB_UE_S1AP_ID);
ogs_assert(enb_ue);
mme_ue = enb_ue->mme_ue;
ogs_assert(mme_ue);
ogs_debug(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]",
enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id);
}
void s1ap_handle_ue_context_modification_failure(
mme_enb_t *enb, s1ap_message_t *message)
{
char buf[OGS_ADDRSTRLEN];
int i;
S1AP_UnsuccessfulOutcome_t *unsuccessfulOutcome = NULL;
S1AP_UEContextModificationFailure_t *UEContextModificationFailure = NULL;
S1AP_UEContextModificationFailureIEs_t *ie = NULL;
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
S1AP_Cause_t *Cause = NULL;
enb_ue_t *enb_ue = NULL;
ogs_assert(enb);
ogs_assert(enb->sock);
ogs_assert(message);
unsuccessfulOutcome = message->choice.unsuccessfulOutcome;
ogs_assert(unsuccessfulOutcome);
UEContextModificationFailure =
&unsuccessfulOutcome->value.choice.UEContextModificationFailure;
ogs_assert(UEContextModificationFailure);
ogs_warn("[MME] UE context modification failure");
for (i = 0; i < UEContextModificationFailure->protocolIEs.list.count; i++) {
ie = UEContextModificationFailure->protocolIEs.list.array[i];
switch (ie->id) {
case S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID:
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
break;
case S1AP_ProtocolIE_ID_id_Cause:
Cause = &ie->value.choice.Cause;
break;
default:
break;
}
}
ogs_debug(" IP[%s] ENB_ID[%d]",
OGS_ADDR(enb->addr, buf), enb->enb_id);
ogs_assert(ENB_UE_S1AP_ID);
ogs_assert(Cause);
enb_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, *ENB_UE_S1AP_ID);
if (enb_ue == NULL) {
ogs_warn("Initial context setup failure : "
"cannot find eNB-UE-S1AP-ID[%d]", (int)*ENB_UE_S1AP_ID);
return;
}
ogs_debug(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]",
enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id);
ogs_debug(" Cause[Group:%d Cause:%d]",
Cause->present, (int)Cause->choice.radioNetwork);
}
void s1ap_handle_e_rab_setup_response( void s1ap_handle_e_rab_setup_response(
mme_enb_t *enb, s1ap_message_t *message) mme_enb_t *enb, s1ap_message_t *message)
{ {

View File

@ -40,7 +40,10 @@ void s1ap_handle_initial_context_setup_response(
mme_enb_t *enb, s1ap_message_t *message); mme_enb_t *enb, s1ap_message_t *message);
void s1ap_handle_initial_context_setup_failure( void s1ap_handle_initial_context_setup_failure(
mme_enb_t *enb, s1ap_message_t *message); mme_enb_t *enb, s1ap_message_t *message);
void s1ap_handle_e_rab_setup_response(
void s1ap_handle_ue_context_modification_response(
mme_enb_t *enb, s1ap_message_t *message);
void s1ap_handle_ue_context_modification_failure(
mme_enb_t *enb, s1ap_message_t *message); mme_enb_t *enb, s1ap_message_t *message);
void s1ap_handle_ue_context_release_request( void s1ap_handle_ue_context_release_request(
@ -48,6 +51,9 @@ void s1ap_handle_ue_context_release_request(
void s1ap_handle_ue_context_release_complete( void s1ap_handle_ue_context_release_complete(
mme_enb_t *enb, s1ap_message_t *message); mme_enb_t *enb, s1ap_message_t *message);
void s1ap_handle_e_rab_setup_response(
mme_enb_t *enb, s1ap_message_t *message);
void s1ap_handle_path_switch_request( void s1ap_handle_path_switch_request(
mme_enb_t *enb, s1ap_message_t *message); mme_enb_t *enb, s1ap_message_t *message);

View File

@ -257,6 +257,22 @@ int s1ap_send_initial_context_setup_request(mme_ue_t *mme_ue)
return OGS_OK; return OGS_OK;
} }
int s1ap_send_ue_context_modification_request(mme_ue_t *mme_ue)
{
int rv;
ogs_pkbuf_t *s1apbuf = NULL;
ogs_assert(mme_ue);
rv = s1ap_build_ue_context_modification_request(&s1apbuf, mme_ue);
ogs_assert(rv == OGS_OK && s1apbuf);
rv = nas_send_to_enb(mme_ue, s1apbuf);
ogs_assert(rv == OGS_OK);
return OGS_OK;
}
int s1ap_send_ue_context_release_command( int s1ap_send_ue_context_release_command(
enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause, enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause,
uint8_t action, uint32_t delay) uint8_t action, uint32_t delay)

View File

@ -50,8 +50,8 @@ int s1ap_send_to_nas(enb_ue_t *enb_ue,
S1AP_ProcedureCode_t procedureCode, S1AP_NAS_PDU_t *nasPdu); S1AP_ProcedureCode_t procedureCode, S1AP_NAS_PDU_t *nasPdu);
int s1ap_send_to_esm(mme_ue_t *mme_ue, ogs_pkbuf_t *esmbuf); int s1ap_send_to_esm(mme_ue_t *mme_ue, ogs_pkbuf_t *esmbuf);
int s1ap_send_initial_context_setup_request( int s1ap_send_initial_context_setup_request(mme_ue_t *mme_ue);
mme_ue_t *mme_ue); int s1ap_send_ue_context_modification_request(mme_ue_t *mme_ue);
int s1ap_send_ue_context_release_command( int s1ap_send_ue_context_release_command(
enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause, enb_ue_t *enb_ue, S1AP_Cause_PR group, long cause,
uint8_t action, uint32_t delay); uint8_t action, uint32_t delay);

View File

@ -125,20 +125,23 @@ void s1ap_state_operational(ogs_fsm_t *s, mme_event_t *e)
ogs_assert(successfulOutcome); ogs_assert(successfulOutcome);
switch (successfulOutcome->procedureCode) { switch (successfulOutcome->procedureCode) {
case S1AP_ProcedureCode_id_InitialContextSetup : case S1AP_ProcedureCode_id_InitialContextSetup:
s1ap_handle_initial_context_setup_response(enb, pdu); s1ap_handle_initial_context_setup_response(enb, pdu);
break; break;
case S1AP_ProcedureCode_id_E_RABSetup : case S1AP_ProcedureCode_id_UEContextModification:
s1ap_handle_e_rab_setup_response(enb, pdu); s1ap_handle_ue_context_modification_response(enb, pdu);
break; break;
case S1AP_ProcedureCode_id_E_RABModify : case S1AP_ProcedureCode_id_UEContextRelease:
break;
case S1AP_ProcedureCode_id_E_RABRelease :
break;
case S1AP_ProcedureCode_id_UEContextRelease :
s1ap_handle_ue_context_release_complete( s1ap_handle_ue_context_release_complete(
enb, pdu); enb, pdu);
break; break;
case S1AP_ProcedureCode_id_E_RABSetup:
s1ap_handle_e_rab_setup_response(enb, pdu);
break;
case S1AP_ProcedureCode_id_E_RABModify:
break;
case S1AP_ProcedureCode_id_E_RABRelease:
break;
case S1AP_ProcedureCode_id_HandoverResourceAllocation: case S1AP_ProcedureCode_id_HandoverResourceAllocation:
s1ap_handle_handover_request_ack(enb, pdu); s1ap_handle_handover_request_ack(enb, pdu);
break; break;
@ -162,6 +165,9 @@ void s1ap_state_operational(ogs_fsm_t *s, mme_event_t *e)
case S1AP_ProcedureCode_id_InitialContextSetup : case S1AP_ProcedureCode_id_InitialContextSetup :
s1ap_handle_initial_context_setup_failure(enb, pdu); s1ap_handle_initial_context_setup_failure(enb, pdu);
break; break;
case S1AP_ProcedureCode_id_UEContextModification:
s1ap_handle_ue_context_modification_failure(enb, pdu);
break;
case S1AP_ProcedureCode_id_HandoverResourceAllocation : case S1AP_ProcedureCode_id_HandoverResourceAllocation :
s1ap_handle_handover_failure(enb, pdu); s1ap_handle_handover_failure(enb, pdu);
break; break;

View File

@ -44,6 +44,7 @@ testcsfb_SOURCES = \
common/test-app.h \ common/test-app.h \
csfb/abts-main.c csfb/test-app.c \ csfb/abts-main.c csfb/test-app.c \
csfb/mo-idle-test.c csfb/mt-idle-test.c \ csfb/mo-idle-test.c csfb/mt-idle-test.c \
csfb/mo-active-test.c \
$(NULL) $(NULL)
testcsfb_LDADD = $(top_srcdir)/src/libepc.la testcsfb_LDADD = $(top_srcdir)/src/libepc.la

View File

@ -1145,6 +1145,70 @@ int tests1ap_build_initial_context_setup_response(
return OGS_OK; return OGS_OK;
} }
int tests1ap_build_ue_context_modification_response(
ogs_pkbuf_t **pkbuf,
uint32_t mme_ue_s1ap_id, uint32_t enb_ue_s1ap_id)
{
int rv;
S1AP_S1AP_PDU_t pdu;
S1AP_SuccessfulOutcome_t *successfulOutcome = NULL;
S1AP_UEContextModificationResponse_t *UEContextModificationResponse = NULL;
ogs_sockaddr_t *addr = NULL;
S1AP_UEContextModificationResponseIEs_t *ie = NULL;
S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL;
S1AP_ENB_UE_S1AP_ID_t *ENB_UE_S1AP_ID = NULL;
memset(&pdu, 0, sizeof (S1AP_S1AP_PDU_t));
pdu.present = S1AP_S1AP_PDU_PR_successfulOutcome;
pdu.choice.successfulOutcome =
ogs_calloc(1, sizeof(S1AP_SuccessfulOutcome_t));
successfulOutcome = pdu.choice.successfulOutcome;
successfulOutcome->procedureCode =
S1AP_ProcedureCode_id_UEContextModification;
successfulOutcome->criticality = S1AP_Criticality_reject;
successfulOutcome->value.present =
S1AP_SuccessfulOutcome__value_PR_UEContextModificationResponse;
UEContextModificationResponse =
&successfulOutcome->value.choice.UEContextModificationResponse;
ie = ogs_calloc(1, sizeof(S1AP_UEContextModificationResponseIEs_t));
ASN_SEQUENCE_ADD(&UEContextModificationResponse->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID;
ie->criticality = S1AP_Criticality_ignore;
ie->value.present =
S1AP_UEContextModificationResponseIEs__value_PR_MME_UE_S1AP_ID;
MME_UE_S1AP_ID = &ie->value.choice.MME_UE_S1AP_ID;
ie = ogs_calloc(1, sizeof(S1AP_UEContextModificationResponseIEs_t));
ASN_SEQUENCE_ADD(&UEContextModificationResponse->protocolIEs, ie);
ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID;
ie->criticality = S1AP_Criticality_ignore;
ie->value.present =
S1AP_UEContextModificationResponseIEs__value_PR_ENB_UE_S1AP_ID;
ENB_UE_S1AP_ID = &ie->value.choice.ENB_UE_S1AP_ID;
*MME_UE_S1AP_ID = mme_ue_s1ap_id;
*ENB_UE_S1AP_ID = enb_ue_s1ap_id;
rv = s1ap_encode_pdu(pkbuf, &pdu);
s1ap_free_pdu(&pdu);
if (rv != OGS_OK) {
ogs_error("s1ap_encode_pdu() failed");
return OGS_ERROR;
}
return OGS_OK;
}
int tests1ap_build_initial_context_setup_failure(ogs_pkbuf_t **pkbuf, int i) int tests1ap_build_initial_context_setup_failure(ogs_pkbuf_t **pkbuf, int i)
{ {
char *payload[TESTS1AP_MAX_MESSAGE] = { char *payload[TESTS1AP_MAX_MESSAGE] = {
@ -1761,7 +1825,9 @@ int tests1ap_build_extended_service_request(ogs_pkbuf_t **pkbuf, int i,
"000c" "000c"
"4038000005000800 020002001a00100f 17b51a57a504074c 000504e900a25200" "4038000005000800 020002001a00100f 17b51a57a504074c 000504e900a25200"
"4300060009f10700 07006440080009f1 0707080140008640 0130", "4300060009f10700 07006440080009f1 0707080140008640 0130",
"",
"000d403900000500 0000020001000800 020001001a00100f 17b51a57a504074c"
"000504e900a25200 6440080009f10700 19b0100043400600 09f1070007",
"", "",
/* 21 */ /* 21 */
@ -1794,7 +1860,7 @@ int tests1ap_build_extended_service_request(ogs_pkbuf_t **pkbuf, int i,
0, 0,
60, 60,
0, 61,
0, 0,
/* 21 */ /* 21 */
@ -1807,13 +1873,22 @@ int tests1ap_build_extended_service_request(ogs_pkbuf_t **pkbuf, int i,
*pkbuf = ogs_pkbuf_alloc(NULL, MAX_SDU_LEN); *pkbuf = ogs_pkbuf_alloc(NULL, MAX_SDU_LEN);
ogs_pkbuf_put_data(*pkbuf, ogs_pkbuf_put_data(*pkbuf,
OGS_HEX(payload[i], strlen(payload[i]), hexbuf), len[i]); OGS_HEX(payload[i], strlen(payload[i]), hexbuf), len[i]);
memcpy((*pkbuf)->data + 26, &service_type, sizeof service_type); if (i == 18) {
m_tmsi = htonl(m_tmsi); memcpy((*pkbuf)->data + 26, &service_type, sizeof service_type);
memcpy((*pkbuf)->data + 29, &m_tmsi, sizeof m_tmsi); m_tmsi = htonl(m_tmsi);
memcpy((*pkbuf)->data + 29, &m_tmsi, sizeof m_tmsi);
snow_3g_f9(knas_int, seq, (0 << 27), 0, snow_3g_f9(knas_int, seq, (0 << 27), 0,
(*pkbuf)->data + 23, (10 << 3), (*pkbuf)->data + 23, (10 << 3),
(*pkbuf)->data + 19); (*pkbuf)->data + 19);
} else if (i == 19) {
memcpy((*pkbuf)->data + 32, &service_type, sizeof service_type);
m_tmsi = htonl(m_tmsi);
memcpy((*pkbuf)->data + 35, &m_tmsi, sizeof m_tmsi);
snow_3g_f9(knas_int, seq, (0 << 27), 0,
(*pkbuf)->data + 29, (10 << 3),
(*pkbuf)->data + 25);
}
return OGS_OK; return OGS_OK;
} }

View File

@ -67,6 +67,9 @@ int tests1ap_build_initial_context_setup_response(
ogs_pkbuf_t **pkbuf, ogs_pkbuf_t **pkbuf,
uint32_t mme_ue_s1ap_id, uint32_t enb_ue_s1ap_id, uint32_t mme_ue_s1ap_id, uint32_t enb_ue_s1ap_id,
uint8_t ebi, uint32_t teid, const char *ipstr); uint8_t ebi, uint32_t teid, const char *ipstr);
int tests1ap_build_ue_context_modification_response(
ogs_pkbuf_t **pkbuf,
uint32_t mme_ue_s1ap_id, uint32_t enb_ue_s1ap_id);
int tests1ap_build_initial_context_setup_failure( int tests1ap_build_initial_context_setup_failure(
ogs_pkbuf_t **pkbuf, int i); ogs_pkbuf_t **pkbuf, int i);
int tests1ap_build_attach_complete(ogs_pkbuf_t **pkbuf, int i); int tests1ap_build_attach_complete(ogs_pkbuf_t **pkbuf, int i);

View File

@ -31,12 +31,14 @@
abts_suite *test_mo_idle(abts_suite *suite); abts_suite *test_mo_idle(abts_suite *suite);
abts_suite *test_mt_idle(abts_suite *suite); abts_suite *test_mt_idle(abts_suite *suite);
abts_suite *test_mo_active(abts_suite *suite);
const struct testlist { const struct testlist {
abts_suite *(*func)(abts_suite *suite); abts_suite *(*func)(abts_suite *suite);
} alltests[] = { } alltests[] = {
{test_mo_idle}, {test_mo_idle},
{test_mt_idle}, {test_mt_idle},
{test_mo_active},
{NULL}, {NULL},
}; };

273
tests/csfb/mo-active-test.c Normal file
View File

@ -0,0 +1,273 @@
#include <mongoc.h>
#include "core/abts.h"
#include "app/context.h"
#include "mme/mme-context.h"
#include "mme/s1ap-build.h"
#include "asn1c/s1ap-message.h"
#include "test-packet.h"
extern ogs_socknode_t *sgsap;
static void test1_func(abts_case *tc, void *data)
{
int rv;
ogs_socknode_t *s1ap;
ogs_pkbuf_t *sendbuf;
ogs_pkbuf_t *recvbuf;
s1ap_message_t message;
int i;
int msgindex = 18;
enb_ue_t *enb_ue = NULL;
mme_ue_t *mme_ue = NULL;
uint32_t m_tmsi = 0;
mongoc_collection_t *collection = NULL;
bson_t *doc = NULL;
int64_t count = 0;
bson_error_t error;
const char *json =
"{"
"\"_id\" : { \"$oid\" : \"310014158b8861d7605378c6\" }, "
"\"imsi\" : \"262420000118139\", "
"\"pdn\" : ["
"{"
"\"apn\" : \"internet\", "
"\"_id\" : { \"$oid\" : \"310014158b8861d7605378c7\" }, "
"\"ambr\" : {"
"\"uplink\" : { \"$numberLong\" : \"1000000\" }, "
"\"downlink\" : { \"$numberLong\" : \"1000000\" } "
"},"
"\"qos\" : { "
"\"qci\" : 9, "
"\"arp\" : { "
"\"priority_level\" : 8,"
"\"pre_emption_vulnerability\" : 0, "
"\"pre_emption_capability\" : 0"
"} "
"}, "
"\"type\" : 2"
"}"
"],"
"\"ambr\" : { "
"\"uplink\" : { \"$numberLong\" : \"1000000\" }, "
"\"downlink\" : { \"$numberLong\" : \"1000000\" } "
"},"
"\"subscribed_rau_tau_timer\" : 12,"
"\"network_access_mode\" : 2, "
"\"subscriber_status\" : 0, "
"\"access_restriction_data\" : 32, "
"\"security\" : { "
"\"k\" : \"70D49A71DD1A2B806A25ABE0EF749F1E\", "
"\"opc\" : \"6F1BF53D624B3A43AF6592854E2444C7\", "
"\"amf\" : \"8000\", "
"\"sqn\" : { \"$numberLong\" : \"2374\" }, "
"\"rand\" : \"aa266700bc2887354e9f87368d5d0ae7\" "
"}, "
"\"__v\" : 0 "
"}";
/* eNB connects to MME */
s1ap = testenb_s1ap_client("127.0.0.1");
ABTS_PTR_NOTNULL(tc, s1ap);
/* Send S1-Setup Reqeust */
rv = tests1ap_build_setup_req(
&sendbuf, S1AP_ENB_ID_PR_macroENB_ID, 0x0019b0, 7, 901, 70, 2);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive S1-Setup Response */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
rv = s1ap_decode_pdu(&message, recvbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
s1ap_free_pdu(&message);
ogs_pkbuf_free(recvbuf);
collection = mongoc_client_get_collection(
context_self()->db.client,
context_self()->db.name, "subscribers");
ABTS_PTR_NOTNULL(tc, collection);
/********** Insert Subscriber in Database */
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("262420000118139"));
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 Attach Request */
mme_self()->mme_ue_s1ap_id = 0;
rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Identity-Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send Identity Response */
rv = tests1ap_build_identity_response(&sendbuf, msgindex);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Authentication Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send Authentication Response */
rv = tests1ap_build_authentication_response(&sendbuf, msgindex);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Security mode Command */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send Security mode Complete */
rv = tests1ap_build_security_mode_complete(&sendbuf, msgindex);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive ESM Information Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send ESM Information Response */
rv = tests1ap_build_esm_information_response(&sendbuf, msgindex);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive SGsAP-Location-Update-Request */
recvbuf = testvlr_sgsap_read(sgsap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send SGsAP-Location-Update-Accept */
rv = testsgsap_location_update_accept(&sendbuf, 0);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testvlr_sgsap_send(sgsap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Initial Context Setup Request +
* Attach Accept +
* Activate Default Bearer Context Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send Initial Context Setup Response */
rv = tests1ap_build_initial_context_setup_response(&sendbuf,
1, 1, 5, 0x00460003, "127.0.0.5");
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Attach Complete + Activate default EPS bearer cotext accept */
rv = tests1ap_build_attach_complete(&sendbuf, msgindex);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive EMM information */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Receive SGsAP TMSI-REALLOCATION-COMPLETE */
recvbuf = testvlr_sgsap_read(sgsap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Retreive M-TMSI */
enb_ue = enb_ue_find_by_mme_ue_s1ap_id(1);
ogs_assert(enb_ue);
mme_ue = enb_ue->mme_ue;
ogs_assert(mme_ue);
m_tmsi = mme_ue->guti.m_tmsi;
/* Send Extended Service Request */
rv = tests1ap_build_extended_service_request(&sendbuf, msgindex+1,
0, m_tmsi, 4, mme_ue->knas_int);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive SGsAP MO-CSFB-INDICATION */
recvbuf = testvlr_sgsap_read(sgsap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Receive UE Context Modification Request */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send UE Context Modification Response */
rv = tests1ap_build_ue_context_modification_response(&sendbuf, 1, 1);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send UE Context Release Request */
rv = tests1ap_build_ue_context_release_request(&sendbuf, msgindex);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive UE Context Release Command */
recvbuf = testenb_s1ap_read(s1ap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send UE Context Release Complete */
rv = tests1ap_build_ue_context_release_complete(&sendbuf, msgindex);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testenb_s1ap_send(s1ap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_msleep(300);
/********** Remove Subscriber in Database */
doc = BCON_NEW("imsi", BCON_UTF8("262420000118139"));
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);
/* eNB disonncect from MME */
testenb_s1ap_close(s1ap);
}
abts_suite *test_mo_active(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, test1_func, NULL);
return suite;
}