From 3c3bac681265cb5ce1f3fea77b1f1939553a1c4e Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Thu, 3 Sep 2020 19:59:00 -0400 Subject: [PATCH] 4G/EPC: Maintaining Old NAS signalling [#546] --- src/amf/amf-sm.c | 14 ++ src/amf/ngap-handler.c | 4 +- src/amf/ngap-path.c | 30 +-- src/mme/mme-context.c | 5 + src/mme/mme-context.h | 3 + src/mme/mme-sm.c | 49 +++- src/mme/mme-timer.c | 26 +++ src/mme/mme-timer.h | 2 + src/mme/s1ap-handler.c | 38 +++- src/mme/s1ap-handler.h | 1 + src/mme/s1ap-path.c | 31 +-- src/mme/s1ap-sm.c | 15 -- tests/attach/abts-main.c | 4 +- tests/attach/auth-test.c | 33 +++ tests/attach/guti-test.c | 30 +++ tests/attach/idle-test.c | 402 +++++++++++++++++++++++++++++++++ tests/attach/ue-context-test.c | 51 +++++ tests/volte/bearer-test.c | 20 ++ tests/volte/rx-test.c | 36 +++ 19 files changed, 712 insertions(+), 82 deletions(-) diff --git a/src/amf/amf-sm.c b/src/amf/amf-sm.c index b6add90e5..618621cd3 100644 --- a/src/amf/amf-sm.c +++ b/src/amf/amf-sm.c @@ -691,6 +691,20 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e) } } + /* + * TS23.502 + * 4.2.3.2 UE Triggered Service Request + * + * 4. [Conditional] + * AMF to SMF: Nsmf_PDUSession_UpdateSMContext Request + * + * The AMF may receive a Service Request to establish another + * NAS signalling connection via a NG-RAN while it has maintained + * an old NAS signalling connection for UE still via NG-RAN. + * In this case, AMF shall trigger the AN release procedure toward + * the old NG-RAN to release the old NAS signalling connection + * as defined in clause 4.2.6 with following logic: */ + /* If NAS(amf_ue_t) has already been associated with * older NG(ran_ue_t) context */ if (CM_CONNECTED(amf_ue)) { diff --git a/src/amf/ngap-handler.c b/src/amf/ngap-handler.c index 4dcc460d5..b1d557f04 100644 --- a/src/amf/ngap-handler.c +++ b/src/amf/ngap-handler.c @@ -1267,7 +1267,7 @@ void ngap_handle_ue_context_release_complete( switch (ran_ue->ue_ctx_rel_action) { case NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE: - ogs_debug(" No Action"); + ogs_debug(" Action: NG context remove"); ran_ue_remove(ran_ue); break; case NGAP_UE_CTX_REL_NG_REMOVE_AND_UNLINK: @@ -1276,7 +1276,7 @@ void ngap_handle_ue_context_release_complete( amf_ue_deassociate(amf_ue); break; case NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE: - ogs_debug(" Action: UE context remove()"); + ogs_debug(" Action: UE context remove"); ran_ue_remove(ran_ue); amf_ue_remove(amf_ue); break; diff --git a/src/amf/ngap-path.c b/src/amf/ngap-path.c index 6b5a2cdd9..225b63dd9 100644 --- a/src/amf/ngap-path.c +++ b/src/amf/ngap-path.c @@ -312,31 +312,17 @@ void ngap_send_ran_ue_context_release_command( 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); - if (delay) { - ogs_assert(action != NGAP_UE_CTX_REL_INVALID_ACTION); - ran_ue->ue_ctx_rel_action = action; + ogs_assert(action != NGAP_UE_CTX_REL_INVALID_ACTION); + ran_ue->ue_ctx_rel_action = action; - ogs_debug(" Group[%d] Cause[%d] Action[%d] Delay[%d]", - group, (int)cause, action, delay); + ogs_debug(" Group[%d] Cause[%d] Action[%d] Delay[%d]", + group, (int)cause, action, delay); - ngapbuf = ngap_build_ue_context_release_command(ran_ue, group, cause); - ogs_expect_or_return(ngapbuf); + ngapbuf = ngap_build_ue_context_release_command(ran_ue, group, cause); + ogs_expect_or_return(ngapbuf); - rv = ngap_delayed_send_to_ran_ue(ran_ue, ngapbuf, delay); - ogs_expect(rv == OGS_OK); - } else { - ogs_assert(action != NGAP_UE_CTX_REL_INVALID_ACTION); - ran_ue->ue_ctx_rel_action = action; - - ogs_debug(" Group[%d] Cause[%d] Action[%d] Delay[%d]", - group, (int)cause, action, delay); - - ngapbuf = ngap_build_ue_context_release_command(ran_ue, group, cause); - ogs_expect_or_return(ngapbuf); - - rv = ngap_delayed_send_to_ran_ue(ran_ue, ngapbuf, 0); - ogs_expect(rv == OGS_OK); - } + rv = ngap_delayed_send_to_ran_ue(ran_ue, ngapbuf, delay); + ogs_expect(rv == OGS_OK); } void ngap_send_amf_ue_context_release_command( diff --git a/src/mme/mme-context.c b/src/mme/mme-context.c index 0bfca1080..3760c1b4c 100644 --- a/src/mme/mme-context.c +++ b/src/mme/mme-context.c @@ -2050,6 +2050,9 @@ enb_ue_t *enb_ue_add(mme_enb_t *enb, uint32_t enb_ue_s1ap_id) enb_ue->enb_ostream_id = OGS_NEXT_ID(enb->ostream_id, 1, enb->max_num_of_ostreams-1); + enb_ue->t_s1_holding = ogs_timer_add( + ogs_app()->timer_mgr, mme_timer_s1_holding_timer_expire, enb_ue); + enb_ue->enb = enb; ogs_list_add(&enb->enb_ue_list, enb_ue); @@ -2069,6 +2072,8 @@ void enb_ue_remove(enb_ue_t *enb_ue) ogs_list_remove(&enb_ue->enb->enb_ue_list, enb_ue); + ogs_timer_delete(enb_ue->t_s1_holding); + stats_remove_ue(); ogs_pool_free(&enb_ue_pool, enb_ue); diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h index 58d98a653..2a6e3dd95 100644 --- a/src/mme/mme-context.h +++ b/src/mme/mme-context.h @@ -254,6 +254,9 @@ struct enb_ue_s { ogs_e_cgi_t e_cgi; } saved; + /* S1 Holding timer for removing this context */ + ogs_timer_t *t_s1_holding; + /* Store by UE Context Release Command * Retrieve by UE Context Release Complete */ #define S1AP_UE_CTX_REL_INVALID_ACTION 0 diff --git a/src/mme/mme-sm.c b/src/mme/mme-sm.c index a2f08ba5d..9629b91f9 100644 --- a/src/mme/mme-sm.c +++ b/src/mme/mme-sm.c @@ -19,6 +19,7 @@ #include "mme-context.h" #include "mme-sm.h" +#include "mme-timer.h" #include "s1ap-handler.h" #include "s1ap-path.h" @@ -254,11 +255,29 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e) case MME_EVT_S1AP_TIMER: enb_ue = e->enb_ue; ogs_assert(enb_ue); - enb = e->enb; - ogs_assert(enb); - ogs_assert(OGS_FSM_STATE(&enb->sm)); - ogs_fsm_dispatch(&enb->sm, e); + switch (e->timer_id) { + case MME_TIMER_S1_DELAYED_SEND: + enb = e->enb; + ogs_assert(enb); + pkbuf = e->pkbuf; + ogs_assert(pkbuf); + + ogs_expect(OGS_OK == s1ap_send_to_enb_ue(enb_ue, pkbuf)); + ogs_timer_delete(e->timer); + break; + case MME_TIMER_S1_HOLDING: + ogs_warn("Implicit S1 release"); + ogs_warn(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", + enb_ue->enb_ue_s1ap_id, + enb_ue->mme_ue_s1ap_id); + s1ap_handle_ue_context_release_action(enb_ue); + break; + default: + ogs_error("Unknown timer[%s:%d]", + mme_timer_get_name(e->timer_id), e->timer_id); + break; + } break; case MME_EVT_EMM_MESSAGE: @@ -304,12 +323,22 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e) /* If NAS(mme_ue_t) has already been associated with * older S1(enb_ue_t) context */ if (ECM_CONNECTED(mme_ue)) { - /* Implcit S1 release */ - ogs_debug("Implicit S1 release"); - ogs_debug(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", - mme_ue->enb_ue->enb_ue_s1ap_id, - mme_ue->enb_ue->mme_ue_s1ap_id); - enb_ue_remove(mme_ue->enb_ue); + /* Previous S1(enb_ue_t) context the holding timer(30secs) + * is started. + * Newly associated S1(enb_ue_t) context holding timer + * is stopped. */ + ogs_debug("Start S1 Holding Timer\n"); + ogs_debug(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n", + mme_ue->enb_ue->enb_ue_s1ap_id, + mme_ue->enb_ue->mme_ue_s1ap_id); + + /* De-associate S1 with NAS/EMM */ + enb_ue_deassociate(mme_ue->enb_ue); + + s1ap_send_ue_context_release_command(mme_ue->enb_ue, + S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release, + S1AP_UE_CTX_REL_S1_CONTEXT_REMOVE, 0); + } mme_ue_associate_enb_ue(mme_ue, enb_ue); } diff --git a/src/mme/mme-timer.c b/src/mme/mme-timer.c index 6a779e89e..7cfcfe08c 100644 --- a/src/mme/mme-timer.c +++ b/src/mme/mme-timer.c @@ -52,6 +52,9 @@ static mme_timer_cfg_t g_mme_timer_cfg[MAX_NUM_OF_MME_TIMER] = { [MME_TIMER_SGS_CLI_CONN_TO_SRV] = { .duration = ogs_time_from_sec(3) }, + + [MME_TIMER_S1_HOLDING] = + { .duration = ogs_time_from_sec(30) }, }; static void emm_timer_event_send( @@ -84,6 +87,8 @@ const char *mme_timer_get_name(mme_timer_e id) return "MME_TIMER_T3489"; case MME_TIMER_SGS_CLI_CONN_TO_SRV: return "MME_TIMER_SGS_CLI_CONN_TO_SRV"; + case MME_TIMER_S1_HOLDING: + return "MME_TIMER_S1_HOLDING"; default: break; } @@ -190,3 +195,24 @@ void mme_timer_sgs_cli_conn_to_srv(void *data) mme_event_free(e); } } + +void mme_timer_s1_holding_timer_expire(void *data) +{ + int rv; + mme_event_t *e = NULL; + enb_ue_t *enb_ue = NULL; + + ogs_assert(data); + enb_ue = data; + + e = mme_event_new(MME_EVT_S1AP_TIMER); + + e->timer_id = MME_TIMER_S1_HOLDING; + e->enb_ue = enb_ue; + + rv = ogs_queue_push(ogs_app()->queue, e); + if (rv != OGS_OK) { + ogs_warn("ogs_queue_push() failed:%d", (int)rv); + mme_event_free(e); + } +} diff --git a/src/mme/mme-timer.h b/src/mme/mme-timer.h index 4a8815d3b..ef2e7984f 100644 --- a/src/mme/mme-timer.h +++ b/src/mme/mme-timer.h @@ -31,6 +31,7 @@ typedef enum { MME_TIMER_BASE = 0, MME_TIMER_S1_DELAYED_SEND, + MME_TIMER_S1_HOLDING, MME_TIMER_T3413, MME_TIMER_T3422, @@ -64,6 +65,7 @@ void mme_timer_t3470_expire(void *data); void mme_timer_t3489_expire(void *data); void mme_timer_sgs_cli_conn_to_srv(void *data); +void mme_timer_s1_holding_timer_expire(void *data); #ifdef __cplusplus } diff --git a/src/mme/s1ap-handler.c b/src/mme/s1ap-handler.c index 64787f44b..b655c8c4c 100644 --- a/src/mme/s1ap-handler.c +++ b/src/mme/s1ap-handler.c @@ -18,6 +18,7 @@ */ #include "mme-event.h" +#include "mme-timer.h" #include "s1ap-path.h" #include "nas-path.h" @@ -287,12 +288,21 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, ogs_s1ap_message_t *message) /* If NAS(mme_ue_t) has already been associated with * older S1(enb_ue_t) context */ if (ECM_CONNECTED(mme_ue)) { - /* Implcit S1 release */ - ogs_debug("Implicit S1 release"); - ogs_debug(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", - mme_ue->enb_ue->enb_ue_s1ap_id, - mme_ue->enb_ue->mme_ue_s1ap_id); - enb_ue_remove(mme_ue->enb_ue); + /* Previous S1(enb_ue_t) context the holding timer(30secs) + * is started. + * Newly associated S1(enb_ue_t) context holding timer + * is stopped. */ + ogs_debug("Start S1 Holding Timer\n"); + ogs_debug(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]\n", + mme_ue->enb_ue->enb_ue_s1ap_id, + mme_ue->enb_ue->mme_ue_s1ap_id); + + /* De-associate S1 with NAS/EMM */ + enb_ue_deassociate(mme_ue->enb_ue); + + s1ap_send_ue_context_release_command(mme_ue->enb_ue, + S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release, + S1AP_UE_CTX_REL_S1_CONTEXT_REMOVE, 0); } mme_ue_associate_enb_ue(mme_ue, enb_ue); } @@ -918,7 +928,6 @@ void s1ap_handle_ue_context_release_request( void s1ap_handle_ue_context_release_complete( mme_enb_t *enb, ogs_s1ap_message_t *message) { - int rv; char buf[OGS_ADDRSTRLEN]; int i; @@ -928,7 +937,6 @@ void s1ap_handle_ue_context_release_complete( S1AP_UEContextReleaseComplete_IEs_t *ie = NULL; S1AP_MME_UE_S1AP_ID_t *MME_UE_S1AP_ID = NULL; - mme_ue_t *mme_ue = NULL; enb_ue_t *enb_ue = NULL; ogs_assert(enb); @@ -969,6 +977,16 @@ void s1ap_handle_ue_context_release_complete( return; } + s1ap_handle_ue_context_release_action(enb_ue); +} + +void s1ap_handle_ue_context_release_action(enb_ue_t *enb_ue) +{ + int rv; + mme_ue_t *mme_ue = NULL; + + ogs_assert(enb_ue); + mme_ue = enb_ue->mme_ue; ogs_debug(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", @@ -976,7 +994,7 @@ void s1ap_handle_ue_context_release_complete( switch (enb_ue->ue_ctx_rel_action) { case S1AP_UE_CTX_REL_S1_CONTEXT_REMOVE: - ogs_debug(" No Action"); + ogs_debug(" Action: S1 context remove"); enb_ue_remove(enb_ue); break; case S1AP_UE_CTX_REL_S1_REMOVE_AND_UNLINK: @@ -985,7 +1003,7 @@ void s1ap_handle_ue_context_release_complete( mme_ue_deassociate(mme_ue); break; case S1AP_UE_CTX_REL_UE_CONTEXT_REMOVE: - ogs_debug(" Action: UE context remove()"); + ogs_debug(" Action: UE context remove"); enb_ue_remove(enb_ue); mme_ue_remove(mme_ue); break; diff --git a/src/mme/s1ap-handler.h b/src/mme/s1ap-handler.h index a301ca21f..120482770 100644 --- a/src/mme/s1ap-handler.h +++ b/src/mme/s1ap-handler.h @@ -48,6 +48,7 @@ void s1ap_handle_ue_context_release_request( mme_enb_t *enb, ogs_s1ap_message_t *message); void s1ap_handle_ue_context_release_complete( mme_enb_t *enb, ogs_s1ap_message_t *message); +void s1ap_handle_ue_context_release_action(enb_ue_t *enb_ue); void s1ap_handle_e_rab_setup_response( mme_enb_t *enb, ogs_s1ap_message_t *message); diff --git a/src/mme/s1ap-path.c b/src/mme/s1ap-path.c index baf3dfe0e..6d79d1086 100644 --- a/src/mme/s1ap-path.c +++ b/src/mme/s1ap-path.c @@ -311,31 +311,20 @@ void s1ap_send_ue_context_release_command( ogs_debug(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id); - if (delay) { - ogs_assert(action != S1AP_UE_CTX_REL_INVALID_ACTION); - enb_ue->ue_ctx_rel_action = action; + ogs_assert(action != S1AP_UE_CTX_REL_INVALID_ACTION); + enb_ue->ue_ctx_rel_action = action; - ogs_debug(" Group[%d] Cause[%d] Action[%d] Delay[%d]", - group, (int)cause, action, delay); + ogs_debug(" Group[%d] Cause[%d] Action[%d] Delay[%d]", + group, (int)cause, action, delay); - s1apbuf = s1ap_build_ue_context_release_command(enb_ue, group, cause); - ogs_expect_or_return(s1apbuf); + s1apbuf = s1ap_build_ue_context_release_command(enb_ue, group, cause); + ogs_expect_or_return(s1apbuf); - rv = s1ap_delayed_send_to_enb_ue(enb_ue, s1apbuf, delay); - ogs_expect(rv == OGS_OK); - } else { - ogs_assert(action != S1AP_UE_CTX_REL_INVALID_ACTION); - enb_ue->ue_ctx_rel_action = action; + rv = s1ap_delayed_send_to_enb_ue(enb_ue, s1apbuf, delay); + ogs_expect(rv == OGS_OK); - ogs_debug(" Group[%d] Cause[%d] Action[%d] Delay[%d]", - group, (int)cause, action, delay); - - s1apbuf = s1ap_build_ue_context_release_command(enb_ue, group, cause); - ogs_expect_or_return(s1apbuf); - - rv = s1ap_delayed_send_to_enb_ue(enb_ue, s1apbuf, 0); - ogs_expect(rv == OGS_OK); - } + ogs_timer_start(enb_ue->t_s1_holding, + mme_timer_cfg(MME_TIMER_S1_HOLDING)->duration); } void s1ap_send_paging(mme_ue_t *mme_ue, S1AP_CNDomain_t cn_domain) diff --git a/src/mme/s1ap-sm.c b/src/mme/s1ap-sm.c index 8a13a52fa..7efb5164a 100644 --- a/src/mme/s1ap-sm.c +++ b/src/mme/s1ap-sm.c @@ -184,21 +184,6 @@ void s1ap_state_operational(ogs_fsm_t *s, mme_event_t *e) break; } - break; - case MME_EVT_S1AP_TIMER: - switch (e->timer_id) { - case MME_TIMER_S1_DELAYED_SEND: - ogs_assert(e->enb_ue); - ogs_assert(e->pkbuf); - - ogs_expect(OGS_OK == s1ap_send_to_enb_ue(e->enb_ue, e->pkbuf)); - ogs_timer_delete(e->timer); - break; - default: - ogs_error("Unknown timer[%s:%d]", - mme_timer_get_name(e->timer_id), e->timer_id); - break; - } break; default: ogs_error("Unknown event %s", mme_event_get_name(e)); diff --git a/tests/attach/abts-main.c b/tests/attach/abts-main.c index baece1606..e71c307c4 100644 --- a/tests/attach/abts-main.c +++ b/tests/attach/abts-main.c @@ -24,8 +24,8 @@ abts_suite *test_guti(abts_suite *suite); abts_suite *test_auth(abts_suite *suite); abts_suite *test_idle(abts_suite *suite); abts_suite *test_emm_status(abts_suite *suite); -abts_suite *test_reset(abts_suite *suite); abts_suite *test_ue_context(abts_suite *suite); +abts_suite *test_reset(abts_suite *suite); const struct testlist { abts_suite *(*func)(abts_suite *suite); @@ -35,8 +35,8 @@ const struct testlist { {test_auth}, {test_idle}, {test_emm_status}, - {test_reset}, {test_ue_context}, + {test_reset}, {NULL}, }; diff --git a/tests/attach/auth-test.c b/tests/attach/auth-test.c index 646371d91..e072cae35 100644 --- a/tests/attach/auth-test.c +++ b/tests/attach/auth-test.c @@ -35,6 +35,9 @@ static void test1_func(abts_case *tc, void *data) test_sess_t *sess = NULL; test_bearer_t *bearer = NULL; + uint32_t enb_ue_s1ap_id; + uint64_t mme_ue_s1ap_id; + const char *_k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; uint8_t k[OGS_KEY_LEN]; const char *_opc_string = "e8ed289deba952e4283b54e88e6183ca"; @@ -289,6 +292,21 @@ static void test1_func(abts_case *tc, void *data) rv = testenb_s1ap_send(s1ap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD 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); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + /* Receive ESM Information Request */ recvbuf = testenb_s1ap_read(s1ap); ABTS_PTR_NOTNULL(tc, recvbuf); @@ -345,6 +363,21 @@ static void test1_func(abts_case *tc, void *data) rv = testenb_s1ap_send(s1ap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD 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); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + /* Receive Authentication request */ recvbuf = testenb_s1ap_read(s1ap); ABTS_PTR_NOTNULL(tc, recvbuf); diff --git a/tests/attach/guti-test.c b/tests/attach/guti-test.c index a724d7fb9..3352be632 100644 --- a/tests/attach/guti-test.c +++ b/tests/attach/guti-test.c @@ -334,6 +334,21 @@ static void test1_func(abts_case *tc, void *data) rv = testenb_s1ap_send(s1ap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD 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); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + /* Receive ESM Information Request */ recvbuf = testenb_s1ap_read(s1ap); ABTS_PTR_NOTNULL(tc, recvbuf); @@ -399,6 +414,21 @@ static void test1_func(abts_case *tc, void *data) rv = testenb_s1ap_send(s1ap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD 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); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + /* Receive UE Context Release Command */ recvbuf = testenb_s1ap_read(s1ap); ABTS_PTR_NOTNULL(tc, recvbuf); diff --git a/tests/attach/idle-test.c b/tests/attach/idle-test.c index 86abbed93..35c7d75b4 100644 --- a/tests/attach/idle-test.c +++ b/tests/attach/idle-test.c @@ -35,6 +35,9 @@ static void test1_func(abts_case *tc, void *data) test_sess_t *sess = NULL; test_bearer_t *bearer = NULL; + uint32_t enb_ue_s1ap_id; + uint64_t mme_ue_s1ap_id; + const char *_k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; uint8_t k[OGS_KEY_LEN]; const char *_opc_string = "e8ed289deba952e4283b54e88e6183ca"; @@ -330,6 +333,21 @@ static void test1_func(abts_case *tc, void *data) rv = testenb_s1ap_send(s1ap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD 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); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + /* Receive TAU Accept */ recvbuf = testenb_s1ap_read(s1ap); ABTS_PTR_NOTNULL(tc, recvbuf); @@ -361,6 +379,21 @@ static void test1_func(abts_case *tc, void *data) rv = testenb_s1ap_send(s1ap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD 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); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + /* Receive TAU Accept */ recvbuf = testenb_s1ap_read(s1ap); ABTS_PTR_NOTNULL(tc, recvbuf); @@ -397,11 +430,380 @@ 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 *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; + + uint32_t enb_ue_s1ap_id; + uint64_t mme_ue_s1ap_id; + + const char *_k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; + uint8_t k[OGS_KEY_LEN]; + const char *_opc_string = "e8ed289deba952e4283b54e88e6183ca"; + 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\" : \"310014158b8861d7605378c6\" }, " + "\"imsi\" : \"901707364000060\", " + "\"pdn\" : [" + "{" + "\"apn\" : \"internet\", " + "\"_id\" : { \"$oid\" : \"310014158b8861d7605378c7\" }, " + "\"ambr\" : {" + "\"uplink\" : { \"$numberLong\" : \"1000000\" }, " + "\"downlink\" : { \"$numberLong\" : \"1000000\" } " + "}," + "\"qos\" : { " + "\"qci\" : 9, " + "\"arp\" : { " + "\"priority_level\" : 15," + "\"pre_emption_vulnerability\" : 1, " + "\"pre_emption_capability\" : 1" + "} " + "}, " + "\"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\" : \"465B5CE8 B199B49F AA5F0A2E E238A6BC\", " + "\"opc\" : \"E8ED289D EBA952E4 283B54E8 8E6183CA\", " + "\"amf\" : \"8000\", " + "\"sqn\" : { \"$numberLong\" : \"64\" } " + "}, " + "\"__v\" : 0 " + "}"; + + /* 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_NAS_5GS_NULL_SCHEME; + mobile_identity_suci.home_network_pki_value = 0; + mobile_identity_suci.scheme_output[0] = 0x37; + mobile_identity_suci.scheme_output[1] = 0x46; + mobile_identity_suci.scheme_output[2] = 0; + mobile_identity_suci.scheme_output[3] = 0; + mobile_identity_suci.scheme_output[4] = 0x06; + + test_ue = test_ue_add_by_suci(&mobile_identity_suci, 13); + ogs_assert(test_ue); + + test_ue->e_cgi.cell_id = 0x54f6401; + test_ue->nas.ksi = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE; + test_ue->nas.value = OGS_NAS_ATTACH_TYPE_EPS_ATTACH; + + OGS_HEX(_k_string, strlen(_k_string), test_ue->k); + OGS_HEX(_opc_string, strlen(_opc_string), test_ue->opc); + + sess = test_sess_add_by_apn(test_ue, "internet"); + 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, 0x54f64); + 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 */ + 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); + + collection = mongoc_client_get_collection( + ogs_mongoc()->client, ogs_mongoc()->name, "subscribers"); + ABTS_PTR_NOTNULL(tc, collection); + + /* 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; + esmbuf = testesm_build_pdn_connectivity_request(sess); + ABTS_PTR_NOTNULL(tc, esmbuf); + + memset(&test_ue->attach_request_param, + 0, sizeof(test_ue->attach_request_param)); + test_ue->attach_request_param.ms_network_feature_support = 1; + emmbuf = testemm_build_attach_request(test_ue, esmbuf); + 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 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 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 UE Capability Info Indication */ + sendbuf = tests1ap_build_ue_radio_capability_info_indication(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* 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); + + /* Send TAU Request */ + memset(&test_ue->tau_request_param, 0, sizeof(test_ue->tau_request_param)); + test_ue->tau_request_param.ciphered = 1; + test_ue->tau_request_param.ue_network_capability = 1; + test_ue->tau_request_param.last_visited_registered_tai = 1; + test_ue->tau_request_param.drx_parameter = 1; + test_ue->tau_request_param.eps_bearer_context_status = 1; + test_ue->tau_request_param.ms_network_capability = 1; + test_ue->tau_request_param.tmsi_status = 1; + test_ue->tau_request_param.mobile_station_classmark_2 = 1; + test_ue->tau_request_param.mobile_station_classmark_3 = 1; + test_ue->tau_request_param.supported_codecs = 1; + test_ue->tau_request_param.ue_usage_setting = 1; + test_ue->tau_request_param.old_guti_type = 1; + test_ue->tau_request_param.ms_network_feature_support = 1; + emmbuf = testemm_build_tau_request(test_ue, false); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Signalling, true); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD 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); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + + /* Receive TAU Accept */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* 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); + + /* Send Service Request */ + emmbuf = testemm_build_service_request(test_ue); + ABTS_PTR_NOTNULL(tc, emmbuf); + sendbuf = test_s1ap_build_initial_ue_message( + test_ue, emmbuf, S1AP_RRC_Establishment_Cause_mo_Data, true); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* Receive Initial Context Setup Request */ + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send UE Capability Info Indication */ + sendbuf = tests1ap_build_ue_radio_capability_info_indication(test_ue); + ABTS_PTR_NOTNULL(tc, sendbuf); + rv = testenb_s1ap_send(s1ap, sendbuf); + ABTS_INT_EQUAL(tc, OGS_OK, rv); + + /* 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 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(300); + + /********** 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); + + /* eNB disonncect from MME */ + testenb_s1ap_close(s1ap); + + /* eNB disonncect from SGW */ + test_gtpu_close(gtpu); + + test_ue_remove(test_ue); +} + abts_suite *test_idle(abts_suite *suite) { suite = ADD_SUITE(suite) abts_run_test(suite, test1_func, NULL); + abts_run_test(suite, test2_func, NULL); return suite; } diff --git a/tests/attach/ue-context-test.c b/tests/attach/ue-context-test.c index 05c335306..8be7fc9b0 100644 --- a/tests/attach/ue-context-test.c +++ b/tests/attach/ue-context-test.c @@ -287,6 +287,9 @@ static void test2_func(abts_case *tc, void *data) test_sess_t *sess = NULL; test_bearer_t *bearer = NULL; + uint32_t enb_ue_s1ap_id; + uint64_t mme_ue_s1ap_id; + const char *_k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; uint8_t k[OGS_KEY_LEN]; const char *_opc_string = "e8ed289deba952e4283b54e88e6183ca"; @@ -530,6 +533,21 @@ static void test2_func(abts_case *tc, void *data) rv = testenb_s1ap_send(s1ap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD 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); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + /* Receive Authentication Request */ recvbuf = testenb_s1ap_read(s1ap); ABTS_PTR_NOTNULL(tc, recvbuf); @@ -649,6 +667,9 @@ static void test3_func(abts_case *tc, void *data) test_sess_t *sess = NULL; test_bearer_t *bearer = NULL; + uint32_t enb_ue_s1ap_id; + uint64_t mme_ue_s1ap_id; + const char *_k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; uint8_t k[OGS_KEY_LEN]; const char *_opc_string = "e8ed289deba952e4283b54e88e6183ca"; @@ -892,6 +913,21 @@ static void test3_func(abts_case *tc, void *data) rv = testenb_s1ap_send(s1ap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD 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); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + /* Receive Authentication Request */ recvbuf = testenb_s1ap_read(s1ap); ABTS_PTR_NOTNULL(tc, recvbuf); @@ -1017,6 +1053,21 @@ static void test3_func(abts_case *tc, void *data) rv = testenb_s1ap_send(s1ap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD 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); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + /* Receive Service Reject */ recvbuf = testenb_s1ap_read(s1ap); ABTS_PTR_NOTNULL(tc, recvbuf); diff --git a/tests/volte/bearer-test.c b/tests/volte/bearer-test.c index d29a73c69..fcaa7d524 100644 --- a/tests/volte/bearer-test.c +++ b/tests/volte/bearer-test.c @@ -339,6 +339,26 @@ static void test1_func(abts_case *tc, void *data) ABTS_PTR_NOTNULL(tc, recvbuf); ogs_pkbuf_free(recvbuf); + /* 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(300); + /********** Remove Subscriber in Database */ doc = BCON_NEW("imsi", BCON_UTF8(test_ue->imsi)); ABTS_PTR_NOTNULL(tc, doc); diff --git a/tests/volte/rx-test.c b/tests/volte/rx-test.c index c457ef37a..e74ba0c2a 100644 --- a/tests/volte/rx-test.c +++ b/tests/volte/rx-test.c @@ -38,6 +38,9 @@ static void test1_func(abts_case *tc, void *data) test_sess_t *sess = NULL; test_bearer_t *bearer = NULL; + uint32_t enb_ue_s1ap_id; + uint64_t mme_ue_s1ap_id; + const char *_k_string = "465b5ce8b199b49faa5f0a2ee238a6bc"; uint8_t k[OGS_KEY_LEN]; const char *_opc_string = "e8ed289deba952e4283b54e88e6183ca"; @@ -578,6 +581,21 @@ static void test1_func(abts_case *tc, void *data) rv = testenb_s1ap_send(s1ap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); + /* Receive OLD UE Context Release Command */ + enb_ue_s1ap_id = test_ue->enb_ue_s1ap_id; + + recvbuf = testenb_s1ap_read(s1ap); + ABTS_PTR_NOTNULL(tc, recvbuf); + tests1ap_recv(test_ue, recvbuf); + + /* Send OLD 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); + + test_ue->enb_ue_s1ap_id = enb_ue_s1ap_id; + /* Receive UE Context Release Command */ recvbuf = testenb_s1ap_read(s1ap); ABTS_PTR_NOTNULL(tc, recvbuf); @@ -1029,6 +1047,24 @@ static void test2_func(abts_case *tc, void *data) rv = testenb_s1ap_send(s1ap, sendbuf); ABTS_INT_EQUAL(tc, OGS_OK, rv); + /* 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(300); /********** Remove Subscriber in Database */