From da5d424ed92405f3adb2a1fd73c65414b5803ee7 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Mon, 1 Apr 2024 22:07:19 +0900 Subject: [PATCH] [MME] Incorrect behavior of SGsAP+Dedicated-Bearer (#3072) First of all, it crashes when creating a Dedicated Bearer on the default Session that is created for the first time. This behavior should be possible, so the related ASSERT is removed. Next, the InitialContextRequest is modified during the Attach Request to include the first Bearer. Finally, there was an issue where trying to create a Dedicated Bearer with SGsAP enabled resulted in an InitialContextSetupRequest message with a PTI of zero. This is because MME initializes the PTI to 0 upon receiving the Create Bearer Request while processing SGsAP. All of these issues has been fixed. --- src/mme/esm-build.c | 20 ++- src/mme/mme-context.c | 6 +- src/mme/mme-s11-handler.c | 15 ++- src/mme/nas-path.c | 9 +- src/mme/s1ap-build.c | 238 +++++++++++++++++++------------- tests/attach/auth-test.c | 4 + tests/attach/guti-test.c | 9 ++ tests/common/context.c | 12 ++ tests/common/context.h | 1 + tests/common/esm-build.c | 37 ++++- tests/common/esm-handler.c | 93 +++++++++++++ tests/common/esm-handler.h | 10 ++ tests/common/nas-path.c | 5 + tests/csfb/mo-idle-test.c | 268 +++++++++++++++++++++++++++++++++++++ 14 files changed, 621 insertions(+), 106 deletions(-) diff --git a/src/mme/esm-build.c b/src/mme/esm-build.c index 5ab89be36..7813c1a6d 100644 --- a/src/mme/esm-build.c +++ b/src/mme/esm-build.c @@ -124,7 +124,6 @@ ogs_pkbuf_t *esm_build_activate_default_bearer_context_request( ogs_assert(session->name); bearer = mme_default_bearer_in_sess(sess); ogs_assert(bearer); - ogs_assert(mme_bearer_next(bearer) == NULL); ogs_debug("Activate default bearer context request"); ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]", @@ -254,6 +253,7 @@ ogs_pkbuf_t *esm_build_activate_dedicated_bearer_context_request( mme_bearer_t *bearer) { mme_ue_t *mme_ue = NULL; + mme_sess_t *sess = NULL; mme_bearer_t *linked_bearer = NULL; ogs_nas_eps_message_t message; @@ -269,6 +269,8 @@ ogs_pkbuf_t *esm_build_activate_dedicated_bearer_context_request( &activate_dedicated_eps_bearer_context_request->tft; ogs_assert(bearer); + sess = bearer->sess; + ogs_assert(sess); mme_ue = bearer->mme_ue; ogs_assert(mme_ue); linked_bearer = mme_linked_bearer(bearer); @@ -284,7 +286,21 @@ ogs_pkbuf_t *esm_build_activate_dedicated_bearer_context_request( message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM; message.esm.h.eps_bearer_identity = bearer->ebi; message.esm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_ESM; - message.esm.h.procedure_transaction_identity = 0; + + /* + * Issue #3072 + * + * PTI 0 is set here to prevent a InitialContextSetupRequest message + * with a PTI of 0 from being created when the Create Bearer Request occurs + * and InitialContextSetupRequest occurs. + * + * If you implement the creation of a dedicated bearer + * in the ESM procedure reqeusted by the UE, + * you will need to refactor the part that sets the PTI. + */ + message.esm.h.procedure_transaction_identity = + sess->pti = OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED; + message.esm.h.message_type = OGS_NAS_EPS_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST; diff --git a/src/mme/mme-context.c b/src/mme/mme-context.c index 0308c27dd..b08b9b506 100644 --- a/src/mme/mme-context.c +++ b/src/mme/mme-context.c @@ -4287,7 +4287,8 @@ mme_bearer_t *mme_bearer_find_or_add_by_message( } if (pti == OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED) { - ogs_error("Both PTI[%d] and EBI[%d] are 0", pti, ebi); + ogs_error("ESM message type: %d, Both PTI[%d] and EBI[%d] are 0", + message->esm.h.message_type, pti, ebi); r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue, OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED, OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); @@ -4373,6 +4374,9 @@ mme_bearer_t *mme_bearer_find_or_add_by_message( sess = mme_sess_find_by_apn(mme_ue, pdn_connectivity_request->access_point_name.apn); if (sess && create_action != OGS_GTP_CREATE_IN_ATTACH_REQUEST) { + + sess->pti = pti; + r = nas_eps_send_pdn_connectivity_reject( sess, OGS_NAS_ESM_CAUSE_MULTIPLE_PDN_CONNECTIONS_FOR_A_GIVEN_APN_NOT_ALLOWED, diff --git a/src/mme/mme-s11-handler.c b/src/mme/mme-s11-handler.c index 339bde7ef..795305a4a 100644 --- a/src/mme/mme-s11-handler.c +++ b/src/mme/mme-s11-handler.c @@ -793,7 +793,7 @@ void mme_s11_handle_create_bearer_request( ogs_assert(xact); ogs_assert(req); - ogs_debug("Create Bearer Response"); + ogs_debug("Create Bearer Request"); /*********************** * Check MME-UE Context @@ -877,12 +877,25 @@ void mme_s11_handle_create_bearer_request( ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]", mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid); + /* + * DEPRECATED : Issues #3072 + * + * PTI 0 is set here to prevent a InitialContextSetupRequest message + * with a PTI of 0 from being created when the Create Bearer Request occurs + * and InitialContextSetupRequest occurs. + * + * If you implement the creation of a dedicated bearer + * in the ESM procedure reqeusted by the UE, + * you will need to refactor the part that sets the PTI. + */ +#if 0 /* Set PTI */ sess->pti = OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED; if (req->procedure_transaction_id.presence) { sess->pti = req->procedure_transaction_id.u8; ogs_debug(" PTI[%d]", sess->pti); } +#endif /* Data Plane(UL) : SGW-S1U */ sgw_s1u_teid = req->bearer_contexts.s1_u_enodeb_f_teid.data; diff --git a/src/mme/nas-path.c b/src/mme/nas-path.c index bf8cd8095..ed01be095 100644 --- a/src/mme/nas-path.c +++ b/src/mme/nas-path.c @@ -106,7 +106,6 @@ int nas_eps_send_attach_accept(mme_ue_t *mme_ue) { int rv; mme_sess_t *sess = NULL; - mme_bearer_t *bearer = NULL; ogs_pkbuf_t *s1apbuf = NULL; ogs_pkbuf_t *esmbuf = NULL, *emmbuf = NULL; @@ -122,10 +121,10 @@ int nas_eps_send_attach_accept(mme_ue_t *mme_ue) sess = mme_sess_first(mme_ue); ogs_assert(sess); - ogs_assert(mme_sess_next(sess) == NULL); - bearer = mme_default_bearer_in_sess(sess); - ogs_assert(bearer); - ogs_assert(mme_bearer_next(bearer) == NULL); + if (mme_sess_next(sess)) { + ogs_error("There should only be one SESSION"); + return OGS_ERROR; + } ogs_debug("[%s] Attach accept", mme_ue->imsi_bcd); diff --git a/src/mme/s1ap-build.c b/src/mme/s1ap-build.c index 245d70a08..4f21ab8dd 100644 --- a/src/mme/s1ap-build.c +++ b/src/mme/s1ap-build.c @@ -343,11 +343,72 @@ ogs_pkbuf_t *s1ap_build_downlink_nas_transport( return ogs_s1ap_encode(&pdu); } +static void fill_e_rab_to_be_setup( + S1AP_E_RABToBeSetupItemCtxtSUReq_t *e_rab, mme_bearer_t *bearer) +{ + int rv; + S1AP_GBR_QosInformation_t *gbrQosInformation = NULL; + + ogs_assert(e_rab); + ogs_assert(bearer); + + e_rab->e_RAB_ID = bearer->ebi; + e_rab->e_RABlevelQoSParameters.qCI = bearer->qos.index; + + ogs_debug(" EBI[%d] QCI[%d] SGW-S1U-TEID[%d]", + bearer->ebi, bearer->qos.index, bearer->sgw_s1u_teid); + ogs_debug(" ARP[%d:%d:%d]", + bearer->qos.arp.priority_level, + bearer->qos.arp.pre_emption_capability, + bearer->qos.arp.pre_emption_vulnerability); + + e_rab->e_RABlevelQoSParameters.allocationRetentionPriority. + priorityLevel = bearer->qos.arp.priority_level; + e_rab->e_RABlevelQoSParameters.allocationRetentionPriority. + pre_emptionCapability = + !(bearer->qos.arp.pre_emption_capability); + e_rab->e_RABlevelQoSParameters.allocationRetentionPriority. + pre_emptionVulnerability = + !(bearer->qos.arp.pre_emption_vulnerability); + + if (bearer->qos.mbr.downlink || bearer->qos.mbr.uplink || + bearer->qos.gbr.downlink || bearer->qos.gbr.uplink) { + ogs_assert(bearer->qos.mbr.downlink); + ogs_assert(bearer->qos.mbr.uplink); + ogs_assert(bearer->qos.gbr.downlink); + ogs_assert(bearer->qos.gbr.uplink); + + ogs_debug(" MBR[DL:%lld,UL:%lld]", + (long long)bearer->qos.mbr.downlink, + (long long)bearer->qos.mbr.uplink); + ogs_debug(" GBR[DL:%lld,UL:%lld]", + (long long)bearer->qos.gbr.downlink, + (long long)bearer->qos.gbr.uplink); + + gbrQosInformation = + CALLOC(1, sizeof(struct S1AP_GBR_QosInformation)); + asn_uint642INTEGER(&gbrQosInformation->e_RAB_MaximumBitrateDL, + bearer->qos.mbr.downlink); + asn_uint642INTEGER(&gbrQosInformation->e_RAB_MaximumBitrateUL, + bearer->qos.mbr.uplink); + asn_uint642INTEGER(&gbrQosInformation-> + e_RAB_GuaranteedBitrateDL, bearer->qos.gbr.downlink); + asn_uint642INTEGER(&gbrQosInformation-> + e_RAB_GuaranteedBitrateUL, bearer->qos.gbr.uplink); + e_rab->e_RABlevelQoSParameters.gbrQosInformation = + gbrQosInformation; + } + + rv = ogs_asn_ip_to_BIT_STRING( + &bearer->sgw_s1u_ip, &e_rab->transportLayerAddress); + ogs_assert(rv == OGS_OK); + ogs_asn_uint32_to_OCTET_STRING( + bearer->sgw_s1u_teid, &e_rab->gTP_TEID); +} + ogs_pkbuf_t *s1ap_build_initial_context_setup_request( mme_ue_t *mme_ue, ogs_pkbuf_t *emmbuf) { - int rv; - S1AP_S1AP_PDU_t pdu; S1AP_InitiatingMessage_t *initiatingMessage = NULL; S1AP_InitialContextSetupRequest_t *InitialContextSetupRequest = NULL; @@ -443,50 +504,26 @@ ogs_pkbuf_t *s1ap_build_initial_context_setup_request( &UEAggregateMaximumBitrate->uEaggregateMaximumBitRateDL, mme_ue->ambr.downlink); - ogs_list_for_each(&mme_ue->sess_list, sess) { - ogs_list_for_each(&sess->bearer_list, bearer) { + S1AP_E_RABToBeSetupItemCtxtSUReqIEs_t *item = NULL; + S1AP_E_RABToBeSetupItemCtxtSUReq_t *e_rab = NULL; + S1AP_NAS_PDU_t *nasPdu = NULL; - S1AP_E_RABToBeSetupItemCtxtSUReqIEs_t *item = NULL; - S1AP_E_RABToBeSetupItemCtxtSUReq_t *e_rab = NULL; - S1AP_GBR_QosInformation_t *gbrQosInformation = NULL; - S1AP_NAS_PDU_t *nasPdu = NULL; - - if (mme_ue->nas_eps.type == MME_EPS_TYPE_ATTACH_REQUEST) { - /* - * For Attach Request, - * Delete Session Request/Response removes ALL session/bearers. - * - * Since all bearers are INACTIVE, - * we should not check the bearer activation. - */ - } else if (OGS_FSM_CHECK(&bearer->sm, esm_state_inactive)) { - /* - * For Service Request/TAU Request/Extended Service Request, - * Only the active EPS bearer can be included. - * - * If MME received Create Bearer Request and - * if MME does not receive Activate EPS Bearer Context Accept, - * We should not include the INACTIVE bearer. - * - * For example, - * 1. SGW->MME : Create Bearer Request - * 2. MME->UE : S1 Paging - * 3. UE->MME : Service Request - * 4. MME->UE : Initial Context Setup Request - * (We should not include INACTIVE BEARER) - * 5. UE->MME : Initial Context Setup Response - * 6. MME->UE : Activate dedicated EPS Bearer Context Request - * 7. UE->MME : Activate dedicated EPS Bearer Context Accept - * 8. MME->SGW : Create Bearer Response - */ - ogs_warn("No active EPS bearer [%d]", bearer->ebi); - ogs_warn(" IMSI[%s] NAS-EPS Type[%d] " - "ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", - mme_ue->imsi_bcd, mme_ue->nas_eps.type, - enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id); - continue; - } + if (mme_ue->nas_eps.type == MME_EPS_TYPE_ATTACH_REQUEST) { + /* + * For Attach Request, + * Delete Session Request/Response removes ALL session/bearers. + * + * Since all bearers are INACTIVE, + * we should not check the bearer activation. + */ + sess = ogs_list_first(&mme_ue->sess_list); + /* + * Issue #3072 : Only first Bearer should be included. + */ + if (sess) + bearer = ogs_list_first(&sess->bearer_list); + if (sess && bearer) { item = CALLOC(1, sizeof(S1AP_E_RABToBeSetupItemCtxtSUReqIEs_t)); ASN_SEQUENCE_ADD(&E_RABToBeSetupListCtxtSUReq->list, item); @@ -496,58 +533,7 @@ ogs_pkbuf_t *s1ap_build_initial_context_setup_request( e_rab = &item->value.choice.E_RABToBeSetupItemCtxtSUReq; - e_rab->e_RAB_ID = bearer->ebi; - e_rab->e_RABlevelQoSParameters.qCI = bearer->qos.index; - - ogs_debug(" EBI[%d] QCI[%d] SGW-S1U-TEID[%d]", - bearer->ebi, bearer->qos.index, bearer->sgw_s1u_teid); - ogs_debug(" ARP[%d:%d:%d]", - bearer->qos.arp.priority_level, - bearer->qos.arp.pre_emption_capability, - bearer->qos.arp.pre_emption_vulnerability); - - e_rab->e_RABlevelQoSParameters.allocationRetentionPriority. - priorityLevel = bearer->qos.arp.priority_level; - e_rab->e_RABlevelQoSParameters.allocationRetentionPriority. - pre_emptionCapability = - !(bearer->qos.arp.pre_emption_capability); - e_rab->e_RABlevelQoSParameters.allocationRetentionPriority. - pre_emptionVulnerability = - !(bearer->qos.arp.pre_emption_vulnerability); - - if (bearer->qos.mbr.downlink || bearer->qos.mbr.uplink || - bearer->qos.gbr.downlink || bearer->qos.gbr.uplink) { - ogs_assert(bearer->qos.mbr.downlink); - ogs_assert(bearer->qos.mbr.uplink); - ogs_assert(bearer->qos.gbr.downlink); - ogs_assert(bearer->qos.gbr.uplink); - - ogs_debug(" MBR[DL:%lld,UL:%lld]", - (long long)bearer->qos.mbr.downlink, - (long long)bearer->qos.mbr.uplink); - ogs_debug(" GBR[DL:%lld,UL:%lld]", - (long long)bearer->qos.gbr.downlink, - (long long)bearer->qos.gbr.uplink); - - gbrQosInformation = - CALLOC(1, sizeof(struct S1AP_GBR_QosInformation)); - asn_uint642INTEGER(&gbrQosInformation->e_RAB_MaximumBitrateDL, - bearer->qos.mbr.downlink); - asn_uint642INTEGER(&gbrQosInformation->e_RAB_MaximumBitrateUL, - bearer->qos.mbr.uplink); - asn_uint642INTEGER(&gbrQosInformation-> - e_RAB_GuaranteedBitrateDL, bearer->qos.gbr.downlink); - asn_uint642INTEGER(&gbrQosInformation-> - e_RAB_GuaranteedBitrateUL, bearer->qos.gbr.uplink); - e_rab->e_RABlevelQoSParameters.gbrQosInformation = - gbrQosInformation; - } - - rv = ogs_asn_ip_to_BIT_STRING( - &bearer->sgw_s1u_ip, &e_rab->transportLayerAddress); - ogs_assert(rv == OGS_OK); - ogs_asn_uint32_to_OCTET_STRING( - bearer->sgw_s1u_teid, &e_rab->gTP_TEID); + fill_e_rab_to_be_setup(e_rab, bearer); if (emmbuf && emmbuf->len) { ogs_debug(" NASPdu[%p:%d]", emmbuf, emmbuf->len); @@ -566,6 +552,66 @@ ogs_pkbuf_t *s1ap_build_initial_context_setup_request( emmbuf = NULL; } } + } else { + /* + * For Service Request/TAU Request/Extended Service Request, + * Only the active EPS bearer can be included. + * + * If MME received Create Bearer Request and + * if MME does not receive Activate EPS Bearer Context Accept, + * We should not include the INACTIVE bearer. + * + * For example, + * 1. SGW->MME : Create Bearer Request + * 2. MME->UE : S1 Paging + * 3. UE->MME : Service Request + * 4. MME->UE : Initial Context Setup Request + * (We should not include INACTIVE BEARER) + * 5. UE->MME : Initial Context Setup Response + * 6. MME->UE : Activate dedicated EPS Bearer Context Request + * 7. UE->MME : Activate dedicated EPS Bearer Context Accept + * 8. MME->SGW : Create Bearer Response + */ + ogs_list_for_each(&mme_ue->sess_list, sess) { + ogs_list_for_each(&sess->bearer_list, bearer) { + if (OGS_FSM_CHECK(&bearer->sm, esm_state_inactive)) { + ogs_warn("No active EPS bearer [%d]", bearer->ebi); + ogs_warn(" IMSI[%s] NAS-EPS Type[%d] " + "ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", + mme_ue->imsi_bcd, mme_ue->nas_eps.type, + enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id); + continue; + } + + item = CALLOC(1, sizeof(S1AP_E_RABToBeSetupItemCtxtSUReqIEs_t)); + ASN_SEQUENCE_ADD(&E_RABToBeSetupListCtxtSUReq->list, item); + + item->id = S1AP_ProtocolIE_ID_id_E_RABToBeSetupItemCtxtSUReq; + item->criticality = S1AP_Criticality_reject; + item->value.present = S1AP_E_RABToBeSetupItemCtxtSUReqIEs__value_PR_E_RABToBeSetupItemCtxtSUReq; + + e_rab = &item->value.choice.E_RABToBeSetupItemCtxtSUReq; + + fill_e_rab_to_be_setup(e_rab, bearer); + + if (emmbuf && emmbuf->len) { + ogs_debug(" NASPdu[%p:%d]", emmbuf, emmbuf->len); + + nasPdu = (S1AP_NAS_PDU_t *)CALLOC(1, sizeof(S1AP_NAS_PDU_t)); + nasPdu->size = emmbuf->len; + nasPdu->buf = CALLOC(nasPdu->size, sizeof(uint8_t)); + memcpy(nasPdu->buf, emmbuf->data, nasPdu->size); + e_rab->nAS_PDU = nasPdu; + ogs_pkbuf_free(emmbuf); + + ogs_log_hexdump(OGS_LOG_DEBUG, nasPdu->buf, nasPdu->size); + + /* Since Tracking area update accept is used only once, + * set emmbuf to NULL as shown below */ + emmbuf = NULL; + } + } + } } if (emmbuf && emmbuf->len) { diff --git a/tests/attach/auth-test.c b/tests/attach/auth-test.c index 9ba162d5d..abbc9ca31 100644 --- a/tests/attach/auth-test.c +++ b/tests/attach/auth-test.c @@ -196,6 +196,8 @@ static void test1_func(abts_case *tc, void *data) tests1ap_recv(test_ue, recvbuf); /* Send Attach Request */ + sess->pti = 1; + sess->pdn_connectivity_param.eit = 1; sess->pdn_connectivity_param.pco = 1; sess->pdn_connectivity_param.request_type = @@ -269,6 +271,8 @@ static void test1_func(abts_case *tc, void *data) tests1ap_recv(test_ue, recvbuf); /* Send Attach Request - No Integrity */ + sess->pti = 1; + sess->pdn_connectivity_param.eit = 1; sess->pdn_connectivity_param.pco = 1; sess->pdn_connectivity_param.request_type = diff --git a/tests/attach/guti-test.c b/tests/attach/guti-test.c index b8662b1b6..00cd87561 100644 --- a/tests/attach/guti-test.c +++ b/tests/attach/guti-test.c @@ -225,6 +225,8 @@ static void test1_func(abts_case *tc, void *data) #endif /* Send Attach Request */ + sess->pti = 1; + memset(&sess->pdn_connectivity_param, 0, sizeof(sess->pdn_connectivity_param)); sess->pdn_connectivity_param.eit = 1; @@ -364,6 +366,7 @@ static void test1_func(abts_case *tc, void *data) /* Send Attach Request - INVALID GUTI */ test_ue->nas_eps_guti.m_tmsi = 0x1234; + sess->pti = 1; memset(&sess->pdn_connectivity_param, 0, sizeof(sess->pdn_connectivity_param)); @@ -618,6 +621,8 @@ static void test2_func(abts_case *tc, void *data) tests1ap_recv(test_ue, recvbuf); /* Send Attach Request - No Integrity */ + sess->pti = 1; + sess->pdn_connectivity_param.eit = 1; sess->pdn_connectivity_param.pco = 1; sess->pdn_connectivity_param.request_type = @@ -751,6 +756,8 @@ static void test2_func(abts_case *tc, void *data) tests1ap_recv(test_ue, recvbuf); /* Send Attach Request */ + sess->pti = 1; + memset(&sess->pdn_connectivity_param, 0, sizeof(sess->pdn_connectivity_param)); sess->pdn_connectivity_param.eit = 1; @@ -1507,6 +1514,8 @@ static void test4_func(abts_case *tc, void *data) tests1ap_recv(test_ue, recvbuf); /* Send Attach Request */ + sess->pti = 1; + memset(&sess->pdn_connectivity_param, 0, sizeof(sess->pdn_connectivity_param)); sess->pdn_connectivity_param.eit = 1; diff --git a/tests/common/context.c b/tests/common/context.c index 8d797dfd4..afe083899 100644 --- a/tests/common/context.c +++ b/tests/common/context.c @@ -1295,6 +1295,18 @@ test_sess_t *test_sess_find_by_apn( return NULL; } +test_sess_t *test_sess_find_by_pti(test_ue_t *test_ue, uint8_t pti) +{ + test_sess_t *sess = NULL; + + ogs_assert(test_ue); + + ogs_list_for_each(&test_ue->sess_list, sess) + if (sess->pti == pti) return sess; + + return NULL; +} + test_sess_t *test_sess_find_by_psi(test_ue_t *test_ue, uint8_t psi) { test_sess_t *sess = NULL; diff --git a/tests/common/context.h b/tests/common/context.h index 07d7e6822..8befe4e12 100644 --- a/tests/common/context.h +++ b/tests/common/context.h @@ -513,6 +513,7 @@ void test_sess_remove_all(test_ue_t *test_ue); test_sess_t *test_sess_find_by_apn( test_ue_t *test_ue, char *apn, uint8_t rat_type); +test_sess_t *test_sess_find_by_pti(test_ue_t *test_ue, uint8_t pti); test_sess_t *test_sess_find_by_psi(test_ue_t *test_ue, uint8_t psi); test_bearer_t *test_bearer_add(test_sess_t *sess, uint8_t ebi); diff --git a/tests/common/esm-build.c b/tests/common/esm-build.c index 93e6034ba..e8ec4f760 100644 --- a/tests/common/esm-build.c +++ b/tests/common/esm-build.c @@ -63,7 +63,13 @@ ogs_pkbuf_t *testesm_build_pdn_connectivity_request( } message.esm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_ESM; + + if (!sess->pti) { + ogs_error("PTI should be not NULL in PDU Connectivity Request"); + return NULL; + } message.esm.h.procedure_transaction_identity = sess->pti; + message.esm.h.message_type = OGS_NAS_EPS_PDN_CONNECTIVITY_REQUEST; request_type->type = OGS_NAS_EPS_PDN_TYPE_IPV4V6; @@ -136,7 +142,13 @@ ogs_pkbuf_t *testesm_build_pdn_disconnect_request(test_sess_t *sess) message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM; message.esm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_ESM; + + if (!sess->pti) { + ogs_error("PTI should be not NULL in PDU Disonnectivity Request"); + return NULL; + } message.esm.h.procedure_transaction_identity = sess->pti; + message.esm.h.message_type = OGS_NAS_EPS_PDN_DISCONNECT_REQUEST; linked_eps_bearer_identity->eps_bearer_identity = bearer->ebi; @@ -194,7 +206,13 @@ ogs_pkbuf_t *testesm_build_esm_information_response(test_sess_t *sess) message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM; message.esm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_ESM; + + if (!sess->pti) { + ogs_error("PTI should be not 0 in ESM Information Response"); + return NULL; + } message.esm.h.procedure_transaction_identity = sess->pti; + message.esm.h.message_type = OGS_NAS_EPS_ESM_INFORMATION_RESPONSE; esm_information_response->presencemask |= OGS_NAS_EPS_ESM_INFORMATION_RESPONSE_ACCESS_POINT_NAME_PRESENT; @@ -254,6 +272,7 @@ ogs_pkbuf_t *testesm_build_activate_default_eps_bearer_context_accept( message.esm.h.eps_bearer_identity = bearer->ebi; message.esm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_ESM; + message.esm.h.procedure_transaction_identity = sess->pti = 0; message.esm.h.message_type = OGS_NAS_EPS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT; @@ -289,6 +308,7 @@ ogs_pkbuf_t *testesm_build_activate_dedicated_eps_bearer_context_accept( message.esm.h.eps_bearer_identity = bearer->ebi; message.esm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_ESM; + message.esm.h.procedure_transaction_identity = sess->pti = 0; message.esm.h.message_type = OGS_NAS_EPS_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT; @@ -321,6 +341,7 @@ ogs_pkbuf_t *testesm_build_activate_dedicated_eps_bearer_context_reject( message.esm.h.eps_bearer_identity = bearer->ebi; message.esm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_ESM; + message.esm.h.procedure_transaction_identity = sess->pti = 0; message.esm.h.message_type = OGS_NAS_EPS_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REJECT; @@ -352,7 +373,7 @@ ogs_pkbuf_t *testesm_build_modify_eps_bearer_context_accept( message.esm.h.eps_bearer_identity = bearer->ebi; message.esm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_ESM; - message.esm.h.procedure_transaction_identity = sess->pti; + message.esm.h.procedure_transaction_identity = sess->pti = 0; message.esm.h.message_type = OGS_NAS_EPS_MODIFY_EPS_BEARER_CONTEXT_ACCEPT; return test_nas_eps_security_encode(test_ue, &message); @@ -381,6 +402,7 @@ ogs_pkbuf_t *testesm_build_deactivate_eps_bearer_context_accept( message.esm.h.eps_bearer_identity = bearer->ebi; message.esm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_ESM; + message.esm.h.procedure_transaction_identity = sess->pti = 0; message.esm.h.message_type = OGS_NAS_EPS_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT; @@ -422,7 +444,13 @@ ogs_pkbuf_t *testesm_build_bearer_resource_allocation_request( message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM; message.esm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_ESM; + + if (!sess->pti) { + ogs_error("PTI should be not 0 in Bearer Resource Allocation Request"); + return NULL; + } message.esm.h.procedure_transaction_identity = sess->pti; + message.esm.h.message_type = OGS_NAS_EPS_BEARER_RESOURCE_ALLOCATION_REQUEST; linked_eps_bearer_identity->eps_bearer_identity = bearer->ebi; @@ -473,7 +501,14 @@ ogs_pkbuf_t *testesm_build_bearer_resource_modification_request( message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM; message.esm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_ESM; + + if (!sess->pti) { + ogs_error("PTI should be not 0 " + "in Bearer Resource Modification Request"); + return NULL; + } message.esm.h.procedure_transaction_identity = sess->pti; + message.esm.h.message_type = OGS_NAS_EPS_BEARER_RESOURCE_MODIFICATION_REQUEST; diff --git a/tests/common/esm-handler.c b/tests/common/esm-handler.c index 921f3e71c..ed5af22e0 100644 --- a/tests/common/esm-handler.c +++ b/tests/common/esm-handler.c @@ -19,6 +19,38 @@ #include "test-common.h" +void testesm_handle_esm_information_request( + test_ue_t *test_ue, ogs_nas_eps_message_t *message) +{ + test_sess_t *sess = NULL; + + ogs_assert(test_ue); + ogs_assert(message); + + ogs_assert(message->esm.h.procedure_transaction_identity != + OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED); + + sess = test_sess_find_by_pti( + test_ue, message->esm.h.procedure_transaction_identity); + ogs_assert(sess); +} + +void testesm_handle_pdn_connectivity_reject( + test_ue_t *test_ue, ogs_nas_eps_message_t *message) +{ + test_sess_t *sess = NULL; + + ogs_assert(test_ue); + ogs_assert(message); + + ogs_assert(message->esm.h.procedure_transaction_identity != + OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED); + + sess = test_sess_find_by_pti( + test_ue, message->esm.h.procedure_transaction_identity); + ogs_assert(sess); +} + void testesm_handle_activate_default_eps_bearer_context_request( test_ue_t *test_ue, ogs_nas_eps_message_t *message) { @@ -43,6 +75,9 @@ void testesm_handle_activate_default_eps_bearer_context_request( sess = test_sess_find_by_apn( test_ue, access_point_name->apn, OGS_GTP2_RAT_TYPE_EUTRAN); ogs_assert(sess); + + ogs_assert(sess->pti == message->esm.h.procedure_transaction_identity); + bearer = test_bearer_find_by_sess_ebi( sess, message->esm.h.eps_bearer_identity); if (!bearer) @@ -96,6 +131,8 @@ void testesm_handle_activate_dedicated_eps_bearer_context_request( sess = bearer->sess; ogs_assert(sess); + ogs_assert(sess->pti == message->esm.h.procedure_transaction_identity); + bearer = test_bearer_find_by_sess_ebi( sess, message->esm.h.eps_bearer_identity); if (!bearer) @@ -103,6 +140,26 @@ void testesm_handle_activate_dedicated_eps_bearer_context_request( ogs_assert(bearer); } +void testesm_handle_modify_eps_bearer_context_request( + test_ue_t *test_ue, ogs_nas_eps_message_t *message) +{ + test_sess_t *sess = NULL; + test_bearer_t *bearer = NULL; + uint8_t ebi; + + ogs_assert(message); + + ebi = message->esm.h.eps_bearer_identity; + ogs_assert(ebi); + + bearer = test_bearer_find_by_ue_ebi(test_ue, ebi); + ogs_assert(bearer); + sess = bearer->sess; + ogs_assert(sess); + + ogs_assert(sess->pti == message->esm.h.procedure_transaction_identity); +} + void testesm_handle_deactivate_eps_bearer_context_request( test_ue_t *test_ue, ogs_nas_eps_message_t *message) { @@ -117,4 +174,40 @@ void testesm_handle_deactivate_eps_bearer_context_request( bearer = test_bearer_find_by_ue_ebi(test_ue, ebi); ogs_assert(bearer); + sess = bearer->sess; + ogs_assert(sess); + + ogs_assert(sess->pti == message->esm.h.procedure_transaction_identity); +} + +void testesm_handle_bearer_resource_allocation( + test_ue_t *test_ue, ogs_nas_eps_message_t *message) +{ + test_sess_t *sess = NULL; + + ogs_assert(test_ue); + ogs_assert(message); + + ogs_assert(message->esm.h.procedure_transaction_identity != + OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED); + + sess = test_sess_find_by_pti( + test_ue, message->esm.h.procedure_transaction_identity); + ogs_assert(sess); +} + +void testesm_handle_bearer_resource_modification( + test_ue_t *test_ue, ogs_nas_eps_message_t *message) +{ + test_sess_t *sess = NULL; + + ogs_assert(test_ue); + ogs_assert(message); + + ogs_assert(message->esm.h.procedure_transaction_identity != + OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED); + + sess = test_sess_find_by_pti( + test_ue, message->esm.h.procedure_transaction_identity); + ogs_assert(sess); } diff --git a/tests/common/esm-handler.h b/tests/common/esm-handler.h index 884a854e9..cf3feaab9 100644 --- a/tests/common/esm-handler.h +++ b/tests/common/esm-handler.h @@ -24,12 +24,22 @@ extern "C" { #endif +void testesm_handle_esm_information_request( + test_ue_t *test_ue, ogs_nas_eps_message_t *message); +void testesm_handle_pdn_connectivity_reject( + test_ue_t *test_ue, ogs_nas_eps_message_t *message); void testesm_handle_activate_default_eps_bearer_context_request( test_ue_t *test_ue, ogs_nas_eps_message_t *message); void testesm_handle_activate_dedicated_eps_bearer_context_request( test_ue_t *test_ue, ogs_nas_eps_message_t *message); +void testesm_handle_modify_eps_bearer_context_request( + test_ue_t *test_ue, ogs_nas_eps_message_t *message); void testesm_handle_deactivate_eps_bearer_context_request( test_ue_t *test_ue, ogs_nas_eps_message_t *message); +void testesm_handle_bearer_resource_allocation( + test_ue_t *test_ue, ogs_nas_eps_message_t *message); +void testesm_handle_bearer_resource_modification( + test_ue_t *test_ue, ogs_nas_eps_message_t *message); #ifdef __cplusplus } diff --git a/tests/common/nas-path.c b/tests/common/nas-path.c index f46bb5091..372cf0b1e 100644 --- a/tests/common/nas-path.c +++ b/tests/common/nas-path.c @@ -196,8 +196,10 @@ void testesm_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf) test_ue->esm_message_type = message.esm.h.message_type; switch (message.esm.h.message_type) { case OGS_NAS_EPS_ESM_INFORMATION_REQUEST: + testesm_handle_esm_information_request(test_ue, &message); break; case OGS_NAS_EPS_PDN_CONNECTIVITY_REJECT: + testesm_handle_pdn_connectivity_reject(test_ue, &message); break; case OGS_NAS_EPS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST: testesm_handle_activate_default_eps_bearer_context_request( @@ -208,13 +210,16 @@ void testesm_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf) test_ue, &message); break; case OGS_NAS_EPS_MODIFY_EPS_BEARER_CONTEXT_REQUEST: + testesm_handle_modify_eps_bearer_context_request(test_ue, &message); break; case OGS_NAS_EPS_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST: testesm_handle_deactivate_eps_bearer_context_request(test_ue, &message); break; case OGS_NAS_EPS_BEARER_RESOURCE_ALLOCATION_REJECT: + testesm_handle_bearer_resource_allocation(test_ue, &message); break; case OGS_NAS_EPS_BEARER_RESOURCE_MODIFICATION_REJECT: + testesm_handle_bearer_resource_modification(test_ue, &message); break; default: ogs_error("Unknown message[%d]", message.esm.h.message_type); diff --git a/tests/csfb/mo-idle-test.c b/tests/csfb/mo-idle-test.c index 762447f4c..dadc7d9eb 100644 --- a/tests/csfb/mo-idle-test.c +++ b/tests/csfb/mo-idle-test.c @@ -305,6 +305,273 @@ static void test1_func(abts_case *tc, void *data) test_ue_remove(test_ue); } +static void test_issues3072_func(abts_case *tc, void *data) +{ + int rv; + ogs_socknode_t *s1ap; + ogs_socknode_t *gtpu; + ogs_pkbuf_t *emmbuf; + ogs_pkbuf_t *esmbuf; + ogs_pkbuf_t *sendbuf; + ogs_pkbuf_t *recvbuf; + ogs_s1ap_message_t message; + + ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci; + test_ue_t *test_ue = NULL; + test_sess_t *sess = NULL; + test_bearer_t *bearer = NULL; + + bson_t *doc = NULL; + + /* Setup Test UE & Session Context */ + 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; + 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_PROTECTION_SCHEME_NULL; + mobile_identity_suci.home_network_pki_value = 0; + + test_ue = test_ue_add_by_suci(&mobile_identity_suci, "3746000006"); + ogs_assert(test_ue); + + test_ue->e_cgi.cell_id = 0x19b010; + test_ue->nas.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE; + test_ue->nas.value = OGS_NAS_ATTACH_TYPE_COMBINED_EPS_IMSI_ATTACH; + + test_ue->k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; + test_ue->opc_string = "e8ed289deba952e4283b54e88e6183ca"; + + sess = test_sess_add_by_apn(test_ue, "internet", OGS_GTP2_RAT_TYPE_EUTRAN); + ogs_assert(sess); + + /* eNB connects to MME */ + s1ap = tests1ap_client(AF_INET); + ABTS_PTR_NOTNULL(tc, s1ap); + + /* eNB connects to SGW */ + gtpu = test_gtpu_server(1, AF_INET); + ABTS_PTR_NOTNULL(tc, gtpu); + + /* Send S1-Setup Reqeust */ + sendbuf = test_s1ap_build_s1_setup_request( + S1AP_ENB_ID_PR_macroENB_ID, 0x19b0); + ABTS_PTR_NOTNULL(tc, sendbuf); + 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); + tests1ap_recv(NULL, recvbuf); + + /********** Insert Subscriber in Database */ + doc = test_db_new_qos_flow(test_ue); + ABTS_PTR_NOTNULL(tc, doc); + ABTS_INT_EQUAL(tc, OGS_OK, test_db_insert_ue(test_ue, doc)); + + /* Send Attach Request */ + memset(&sess->pdn_connectivity_param, + 0, sizeof(sess->pdn_connectivity_param)); + sess->pdn_connectivity_param.eit = 1; + sess->pdn_connectivity_param.pco = 1; + sess->pdn_connectivity_param.request_type = + OGS_NAS_EPS_REQUEST_TYPE_INITIAL; + esmbuf = testesm_build_pdn_connectivity_request(sess, false); + ABTS_PTR_NOTNULL(tc, esmbuf); + + memset(&test_ue->attach_request_param, + 0, sizeof(test_ue->attach_request_param)); + test_ue->attach_request_param.guti = 1; + test_ue->attach_request_param.last_visited_registered_tai = 1; + test_ue->attach_request_param.drx_parameter = 1; + test_ue->attach_request_param.ms_network_capability = 1; + test_ue->attach_request_param.tmsi_status = 1; + test_ue->attach_request_param.mobile_station_classmark_2 = 1; + test_ue->attach_request_param.mobile_station_classmark_3 = 1; + test_ue->attach_request_param.supported_codecs = 1; + test_ue->attach_request_param.ue_usage_setting = 1; + test_ue->attach_request_param.old_guti_type = 1; + test_ue->attach_request_param.ms_network_feature_support = 1; + emmbuf = testemm_build_attach_request(test_ue, esmbuf, true, false); + ABTS_PTR_NOTNULL(tc, emmbuf); + + memset(&test_ue->initial_ue_param, 0, sizeof(test_ue->initial_ue_param)); + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, false); + 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); + tests1ap_recv(test_ue, recvbuf); + + /* Send Identity response */ + emmbuf = testemm_build_identity_response(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Authentication Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Authentication response */ + emmbuf = testemm_build_authentication_response(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Security mode Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send Security mode complete */ + test_ue->mobile_identity_imeisv_presence = true; + emmbuf = testemm_build_security_mode_complete(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive ESM Information Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send ESM Information Response */ + esmbuf = testesm_build_esm_information_response(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + 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); + + /* + * To raise the RACE CONDITION + * for the Create Bearer Request and InitialContextSetupRequest + */ + ogs_msleep(100); + + /* Send SGsAP-Location-Update-Accept */ + sendbuf = test_sgsap_location_update_accept(0); + ABTS_PTR_NOTNULL(tc, sendbuf); + 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); + tests1ap_recv(test_ue, recvbuf); + + /* Send Initial Context Setup Response */ + sendbuf = test_s1ap_build_initial_context_setup_response(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Attach Complete + Activate default EPS bearer cotext accept */ + test_ue->nr_cgi.cell_id = 0x1234502; + bearer = test_bearer_find_by_ue_ebi(test_ue, 5); + ogs_assert(bearer); + esmbuf = testesm_build_activate_default_eps_bearer_context_accept( + bearer, false); + ABTS_PTR_NOTNULL(tc, esmbuf); + emmbuf = testemm_build_attach_complete(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive EMM information */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Receive SGsAP TMSI-REALLOCATION-COMPLETE */ + recvbuf = testvlr_sgsap_read(sgsap); + ABTS_PTR_NOTNULL(tc, recvbuf); + ogs_pkbuf_free(recvbuf); + + /* Receive E-RABSetupRequest + + * Activate dedicated EPS bearer context request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + ABTS_INT_EQUAL(tc, + S1AP_ProcedureCode_id_E_RABSetup, + test_ue->s1ap_procedure_code); + + /* Send E-RABSetupResponse */ + bearer = test_bearer_find_by_ue_ebi(test_ue, 6); + ogs_assert(bearer); + sendbuf = test_s1ap_build_e_rab_setup_response(bearer); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Send Activate dedicated EPS bearer context accept */ + esmbuf = testesm_build_activate_dedicated_eps_bearer_context_accept(bearer); + ABTS_PTR_NOTNULL(tc, esmbuf); + sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, esmbuf); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(100); + + /* Send UE Context Release Request */ + sendbuf = test_s1ap_build_ue_context_release_request(test_ue, + S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_user_inactivity); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive UE Context Release Command */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Context Release Complete */ + sendbuf = test_s1ap_build_ue_context_release_complete(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + ogs_msleep(100); + + /********** Remove Subscriber in Database */ + ABTS_INT_EQUAL(tc, OGS_OK, test_db_remove_ue(test_ue)); + + /* eNB disonncect from MME */ + testenb_s1ap_close(s1ap); + + /* eNB disonncect from SGW */ + test_gtpu_close(gtpu); + + test_ue_remove(test_ue); +} + static void test2_func(abts_case *tc, void *data) { int rv; @@ -1043,6 +1310,7 @@ abts_suite *test_mo_idle(abts_suite *suite) suite = ADD_SUITE(suite) abts_run_test(suite, test1_func, NULL); + abts_run_test(suite, test_issues3072_func, NULL); abts_run_test(suite, test2_func, NULL); abts_run_test(suite, test3_func, NULL); abts_run_test(suite, test4_func, NULL);