From 229d04c284a8cb460b8d4cc1a25b6c7b55bc0fc6 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Thu, 7 Sep 2017 00:37:16 +0900 Subject: [PATCH] Multiple PDN ..done! --- lib/base/types.c | 47 +++++-- src/mme/emm_sm.c | 41 +++++- src/mme/esm_build.c | 19 ++- src/mme/esm_handler.c | 49 +++---- src/mme/esm_handler.h | 2 - src/mme/esm_sm.c | 146 +++++++++++++++++--- src/mme/mme_s11_handler.c | 57 ++------ src/mme/mme_s11_handler.h | 3 +- src/mme/mme_sm.c | 75 ++++++++-- src/mme/mme_sm.h | 3 + src/mme/s1ap_handler.c | 114 ++++++++++++---- src/pcrf/pcrf_fd_path.c | 2 +- test/testpacket.c | 98 ++++++++++++- test/testpacket.h | 6 +- test/volte_test.c | 279 +++++++++++++++++++++++++++++++++++++- 15 files changed, 776 insertions(+), 165 deletions(-) diff --git a/lib/base/types.c b/lib/base/types.c index 1ca439431..ee0f89e8b 100644 --- a/lib/base/types.c +++ b/lib/base/types.c @@ -41,26 +41,47 @@ void *plmn_id_build(plmn_id_t *plmn_id, return plmn_id; } -c_int16_t apn_build(c_int8_t *dst, c_int8_t *src, c_int16_t len) +c_int16_t apn_build(c_int8_t *dst, c_int8_t *src, c_int16_t length) { - char *dot = NULL; + int i = 0, j = 0; - core_cpystrn(dst+1, src, c_min(len, MAX_APN_LEN)+1); + for (i = 0, j = 0; i < length; i++, j++) + { + if (src[i] == '.') + { + dst[i-j] = j; + j = -1; + } + else + { + dst[i+1] = src[i]; + } + } + dst[i-j] = j; - dot = strchr(src, '.'); - if (dot) - dst[0] = src - dot; - else - dst[0] = len; - - return len+1; + return length+1; } -c_int16_t apn_parse(c_int8_t *dst, c_int8_t *src, c_int16_t len) +c_int16_t apn_parse(c_int8_t *dst, c_int8_t *src, c_int16_t length) { - core_cpystrn(dst, src+1, c_min(len-1, MAX_APN_LEN)+1); + int i = 0, j = 0; + c_uint8_t len = 0; - return len-1; + do + { + len = src[i++]; + memcpy(&dst[j], &src[i], len); + + i += len; + j += len; + + if (i < length) + dst[j++] = '.'; + else + dst[j] = 0; + } while(i < length); + + return j; } /* 8.13 Protocol Configuration Options (PCO) diff --git a/src/mme/emm_sm.c b/src/mme/emm_sm.c index c0d9845cf..bf04ad49b 100644 --- a/src/mme/emm_sm.c +++ b/src/mme/emm_sm.c @@ -16,7 +16,7 @@ #include "mme_s11_handler.h" #include "nas_path.h" -void emm_state_attach_request(fsm_t *s, event_t *e, +static void emm_state_attach_request(fsm_t *s, event_t *e, mme_ue_t *mme_ue, nas_message_t *message); void emm_state_initial(fsm_t *s, event_t *e) @@ -484,7 +484,43 @@ void emm_state_attached(fsm_t *s, event_t *e) } } -void emm_state_attach_request(fsm_t *s, event_t *e, +void emm_state_exception(fsm_t *s, event_t *e) +{ + mme_ue_t *mme_ue = NULL; + mme_sess_t *sess = NULL; + mme_bearer_t *bearer = NULL; + + d_assert(s, return, "Null param"); + d_assert(e, return, "Null param"); + + mme_sm_trace(3, e); + + bearer = mme_bearer_find(event_get_param1(e)); + d_assert(bearer, return, "Null param"); + sess = bearer->sess; + d_assert(sess, return, "Null param"); + mme_ue = sess->mme_ue; + d_assert(mme_ue, return, "Null param"); + + switch (event_get(e)) + { + case FSM_ENTRY_SIG: + { + break; + } + case FSM_EXIT_SIG: + { + break; + } + default: + { + d_error("Unknown event %s", mme_event_get_name(e)); + break; + } + } +} + +static void emm_state_attach_request(fsm_t *s, event_t *e, mme_ue_t *mme_ue, nas_message_t *message) { d_assert(s, return, "Null param"); @@ -528,4 +564,3 @@ void emm_state_attach_request(fsm_t *s, event_t *e, } } } - diff --git a/src/mme/esm_build.c b/src/mme/esm_build.c index 426164037..98aa03d51 100644 --- a/src/mme/esm_build.c +++ b/src/mme/esm_build.c @@ -84,9 +84,16 @@ status_t esm_build_activate_default_bearer_context( d_assert(bearer, return CORE_ERROR, "Null param"); memset(&message, 0, sizeof(message)); + if (FSM_CHECK(&mme_ue->sm, emm_state_attached)) + { + message.h.security_header_type = + NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED; + message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; + } message.esm.h.eps_bearer_identity = bearer->ebi; message.esm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_ESM; - message.esm.h.procedure_transaction_identity = bearer->pti; + if (!FSM_CHECK(&mme_ue->sm, emm_state_attached)) + message.esm.h.procedure_transaction_identity = bearer->pti; message.esm.h.message_type = NAS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST; @@ -119,7 +126,15 @@ status_t esm_build_activate_default_bearer_context( TLV_CLEAR_DATA(&sess->pgw_pco); } - d_assert(nas_plain_encode(pkbuf, &message) == CORE_OK && *pkbuf,,); + if (FSM_CHECK(&mme_ue->sm, emm_state_attached)) + { + d_assert(nas_security_encode(pkbuf, mme_ue, &message) == CORE_OK && + *pkbuf,,); + } + else + { + d_assert(nas_plain_encode(pkbuf, &message) == CORE_OK && *pkbuf,,); + } return CORE_OK; } diff --git a/src/mme/esm_handler.c b/src/mme/esm_handler.c index 24e8040cd..240141724 100644 --- a/src/mme/esm_handler.c +++ b/src/mme/esm_handler.c @@ -15,7 +15,20 @@ void esm_handle_pdn_connectivity_request(mme_sess_t *sess, nas_pdn_connectivity_request_t *pdn_connectivity_request) { + mme_ue_t *mme_ue = NULL; + d_assert(sess, return, "Null param"); + mme_ue = sess->mme_ue; + d_assert(mme_ue, return, "Null param"); + + if (pdn_connectivity_request->presencemask & + NAS_PDN_CONNECTIVITY_REQUEST_ACCESS_POINT_NAME_PRESENT) + { + sess->pdn = mme_pdn_find_by_apn(mme_ue, + pdn_connectivity_request->access_point_name.apn); + d_assert(sess->pdn, return, "No PDN Context[APN:%s])", + pdn_connectivity_request->access_point_name.apn); + } if (pdn_connectivity_request->presencemask & NAS_PDN_CONNECTIVITY_REQUEST_PROTOCOL_CONFIGURATION_OPTIONS_PRESENT) @@ -54,32 +67,6 @@ void esm_handle_information_response(mme_sess_t *sess, } } -void esm_handle_activate_dedicated_bearer_request(mme_bearer_t *bearer) -{ - status_t rv; - mme_ue_t *mme_ue = NULL; - enb_ue_t *enb_ue = NULL; - pkbuf_t *esmbuf = NULL, *s1apbuf = NULL; - - d_assert(bearer, return, "Null param"); - mme_ue = bearer->mme_ue; - d_assert(mme_ue, return, "Null param"); - enb_ue = mme_ue->enb_ue; - d_assert(enb_ue, return, "Null param"); - - rv = esm_build_activate_dedicated_bearer_context(&esmbuf, bearer); - d_assert(rv == CORE_OK && esmbuf, return, "esm build error"); - - d_trace(3, "[NAS] Activate dedicated bearer context request : " - "EMM <-- ESM\n"); - - rv = s1ap_build_e_rab_setup_request(&s1apbuf, bearer, esmbuf); - d_assert(rv == CORE_OK && s1apbuf, - pkbuf_free(esmbuf); return, "s1ap build error"); - - d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,); -} - void esm_handle_activate_default_bearer_accept(mme_bearer_t *bearer) { status_t rv; @@ -110,12 +97,9 @@ void esm_handle_activate_default_bearer_accept(mme_bearer_t *bearer) rv = gtp_xact_commit(xact); d_assert(rv == CORE_OK, return, "xact_commit error"); - } - dedicated_bearer = mme_bearer_next(bearer); - while(dedicated_bearer) - { - if (!MME_HAVE_ENB_S1U_PATH(dedicated_bearer)) + dedicated_bearer = mme_bearer_next(bearer); + while(dedicated_bearer) { enb_ue_t *enb_ue = NULL; pkbuf_t *esmbuf = NULL, *s1apbuf = NULL; @@ -136,8 +120,9 @@ void esm_handle_activate_default_bearer_accept(mme_bearer_t *bearer) pkbuf_free(esmbuf); return, "s1ap build error"); d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,); + + dedicated_bearer = mme_bearer_next(dedicated_bearer); } - dedicated_bearer = mme_bearer_next(dedicated_bearer); } } diff --git a/src/mme/esm_handler.h b/src/mme/esm_handler.h index cff7816e0..a52ab78fa 100644 --- a/src/mme/esm_handler.h +++ b/src/mme/esm_handler.h @@ -13,8 +13,6 @@ CORE_DECLARE(void) esm_handle_pdn_connectivity_request(mme_sess_t *sess, nas_pdn_connectivity_request_t *pdn_connectivity_request); CORE_DECLARE(void) esm_handle_information_response(mme_sess_t *sess, nas_esm_information_response_t *bearer_information_response); -CORE_DECLARE(void) esm_handle_activate_dedicated_bearer_request( - mme_bearer_t *bearer); CORE_DECLARE(void) esm_handle_activate_default_bearer_accept( mme_bearer_t *bearer); CORE_DECLARE(void) esm_handle_activate_dedicated_bearer_accept( diff --git a/src/mme/esm_sm.c b/src/mme/esm_sm.c index 2de1472fe..7921e4dbc 100644 --- a/src/mme/esm_sm.c +++ b/src/mme/esm_sm.c @@ -73,17 +73,6 @@ void esm_state_inactive(fsm_t *s, event_t *e) mme_ue, sess, bearer, message); break; } - case NAS_ESM_INFORMATION_RESPONSE: - { - d_trace(3, "[NAS] ESM information response : " - "UE[%s] --> ESM[%d]\n", - mme_ue->imsi_bcd, bearer->pti); - esm_handle_information_response( - sess, &message->esm.esm_information_response); - - mme_s11_handle_create_session_request(sess); - break; - } case NAS_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT: { d_trace(3, "[NAS] Activate default EPS bearer " @@ -121,6 +110,79 @@ void esm_state_inactive(fsm_t *s, event_t *e) } } +void esm_state_information(fsm_t *s, event_t *e) +{ + mme_ue_t *mme_ue = NULL; + mme_sess_t *sess = NULL; + mme_bearer_t *bearer = NULL; + + d_assert(s, return, "Null param"); + d_assert(e, return, "Null param"); + + mme_sm_trace(3, e); + + bearer = mme_bearer_find(event_get_param1(e)); + d_assert(bearer, return, "Null param"); + sess = bearer->sess; + d_assert(sess, return, "Null param"); + mme_ue = sess->mme_ue; + d_assert(mme_ue, return, "Null param"); + + switch (event_get(e)) + { + case FSM_ENTRY_SIG: + { + status_t rv; + pkbuf_t *esmbuf = NULL; + + rv = esm_build_information_request(&esmbuf, bearer); + d_assert(rv == CORE_OK && esmbuf, return, + "esm_build failed"); + d_assert(nas_send_to_downlink_nas_transport( + mme_ue, esmbuf) == CORE_OK,,); + break; + } + case FSM_EXIT_SIG: + { + break; + } + case MME_EVT_ESM_MESSAGE: + { + nas_message_t *message = (nas_message_t *)event_get_param3(e); + d_assert(message, break, "Null param"); + + switch(message->esm.h.message_type) + { + case NAS_ESM_INFORMATION_RESPONSE: + { + d_trace(3, "[NAS] ESM information response : " + "UE[%s] --> ESM[%d]\n", + mme_ue->imsi_bcd, bearer->pti); + esm_handle_information_response( + sess, &message->esm.esm_information_response); + + mme_s11_handle_create_session_request(sess); + FSM_TRAN(s, esm_state_inactive); + break; + } + default: + { + d_warn("Not implemented(type:%d)", + message->esm.h.message_type); + break; + } + } + break; + } + + default: + { + d_error("Unknown event %s", mme_event_get_name(e)); + break; + } + } +} + void esm_state_active(fsm_t *s, event_t *e) { mme_ue_t *mme_ue = NULL; @@ -181,6 +243,46 @@ void esm_state_active(fsm_t *s, event_t *e) } } +void esm_state_session_exception(fsm_t *s, event_t *e) +{ + switch (event_get(e)) + { + case FSM_ENTRY_SIG: + { + break; + } + case FSM_EXIT_SIG: + { + break; + } + default: + { + d_error("Unknown event %s", mme_event_get_name(e)); + break; + } + } +} + +void esm_state_bearer_exception(fsm_t *s, event_t *e) +{ + switch (event_get(e)) + { + case FSM_ENTRY_SIG: + { + break; + } + case FSM_EXIT_SIG: + { + break; + } + default: + { + d_error("Unknown event %s", mme_event_get_name(e)); + break; + } + } +} + static void esm_state_pdn_connectivity_request( fsm_t *s, event_t *e, mme_ue_t *mme_ue, mme_sess_t *sess, mme_bearer_t *bearer, nas_message_t *message) @@ -205,25 +307,25 @@ static void esm_state_pdn_connectivity_request( if (MME_UE_HAVE_APN(mme_ue)) { - if (MME_HAVE_SGW_S11_PATH(mme_ue)) + if (FSM_CHECK(&mme_ue->sm, emm_state_attached)) { - emm_handle_attach_accept(mme_ue); + mme_s11_handle_create_session_request(sess); } else { - mme_s11_handle_create_session_request(sess); + if (MME_HAVE_SGW_S11_PATH(mme_ue)) + { + emm_handle_attach_accept(mme_ue); + } + else + { + mme_s11_handle_create_session_request(sess); + } } } else { - status_t rv; - pkbuf_t *esmbuf = NULL; - - rv = esm_build_information_request(&esmbuf, bearer); - d_assert(rv == CORE_OK && esmbuf, return, - "esm_build failed"); - d_assert(nas_send_to_downlink_nas_transport( - mme_ue, esmbuf) == CORE_OK,,); + FSM_TRAN(s, esm_state_information); } } diff --git a/src/mme/mme_s11_handler.c b/src/mme/mme_s11_handler.c index c1edc2977..2a0ddc33d 100644 --- a/src/mme/mme_s11_handler.c +++ b/src/mme/mme_s11_handler.c @@ -44,24 +44,24 @@ void mme_s11_handle_create_session_request(mme_sess_t *sess) d_assert(rv == CORE_OK, return, "xact_commit error"); } -void mme_s11_handle_create_session_response( - gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_create_session_response_t *rsp) +void mme_s11_handle_create_session_response(gtp_xact_t *xact, + mme_bearer_t *bearer, gtp_create_session_response_t *rsp) { status_t rv; gtp_f_teid_t *sgw_s11_teid = NULL; gtp_f_teid_t *sgw_s1u_teid = NULL; + mme_ue_t *mme_ue = NULL; mme_sess_t *sess = NULL; - mme_bearer_t *bearer = NULL; pdn_t *pdn = NULL; d_assert(xact, return, "Null param"); - d_assert(mme_ue, return, "Null param"); + d_assert(bearer, return, "Null param"); d_assert(rsp, return, "Null param"); if (rsp->sender_f_teid_for_control_plane.presence == 0) { - d_error("No GTP TEID"); + d_error("No S11 TEID"); return; } if (rsp->pdn_address_allocation.presence == 0) @@ -69,25 +69,14 @@ void mme_s11_handle_create_session_response( d_error("No PDN Address Allocation"); return; } - if (rsp->bearer_contexts_created.presence == 0) - { - d_error("No Bearer"); - return; - } - if (rsp->bearer_contexts_created.eps_bearer_id.presence == 0) - { - d_error("No EPS Bearer ID"); - return; - } if (rsp->bearer_contexts_created.s1_u_enodeb_f_teid.presence == 0) { - d_error("No GTP TEID"); + d_error("No S1U TEID"); return; } - bearer = mme_bearer_find_by_ue_ebi(mme_ue, - rsp->bearer_contexts_created.eps_bearer_id.u8); - d_assert(bearer, return, "Null param"); + mme_ue = bearer->mme_ue; + d_assert(mme_ue, return, "Null param"); sess = bearer->sess; d_assert(sess, return, "Null param"); pdn = sess->pdn; @@ -206,7 +195,6 @@ void mme_s11_handle_delete_session_response( void mme_s11_handle_create_bearer_request( gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_create_bearer_request_t *req) { - status_t rv; mme_bearer_t *bearer = NULL; mme_sess_t *sess = NULL; @@ -278,34 +266,11 @@ void mme_s11_handle_create_bearer_request( bearer->qos.gbr.downlink = bearer_qos.dl_gbr; bearer->qos.gbr.uplink = bearer_qos.ul_gbr; - /* Bearer TFT */ + /* Save Bearer TFT */ TLV_STORE_DATA(&bearer->tft, &req->bearer_contexts.tft); - if (FSM_CHECK(&mme_ue->sm, emm_state_attached)) - { - enb_ue_t *enb_ue = NULL; - pkbuf_t *esmbuf = NULL, *s1apbuf = NULL; - - enb_ue = mme_ue->enb_ue; - d_assert(enb_ue, return, "Null param"); - - rv = esm_build_activate_dedicated_bearer_context(&esmbuf, bearer); - d_assert(rv == CORE_OK && esmbuf, return, "esm build error"); - - d_trace(3, "[NAS] Activate dedicated bearer context request : " - "EMM <-- ESM\n"); - - rv = s1ap_build_e_rab_setup_request(&s1apbuf, bearer, esmbuf); - d_assert(rv == CORE_OK && s1apbuf, - pkbuf_free(esmbuf); return, "s1ap build error"); - - d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,); - } - else - { - /* Save Transaction. will be handled after EMM-attached */ - bearer->xact = xact; - } + /* Save Transaction. will be handled after EMM-attached */ + bearer->xact = xact; } void mme_s11_handle_release_access_bearers_response( diff --git a/src/mme/mme_s11_handler.h b/src/mme/mme_s11_handler.h index 7789e401f..2533f6f8f 100644 --- a/src/mme/mme_s11_handler.h +++ b/src/mme/mme_s11_handler.h @@ -11,7 +11,8 @@ extern "C" { CORE_DECLARE(void) mme_s11_handle_create_session_request(mme_sess_t *sess); CORE_DECLARE(void) mme_s11_handle_create_session_response( - gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_create_session_response_t *rsp); + gtp_xact_t *xact, mme_bearer_t *bearer, + gtp_create_session_response_t *rsp); CORE_DECLARE(void) mme_s11_handle_modify_bearer_response( gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_modify_bearer_response_t *rsp); CORE_DECLARE(void) mme_s11_handle_delete_all_sessions_in_ue(mme_ue_t *mme_ue); diff --git a/src/mme/mme_sm.c b/src/mme/mme_sm.c index a8e8c190b..5561455b6 100644 --- a/src/mme/mme_sm.c +++ b/src/mme/mme_sm.c @@ -6,14 +6,16 @@ #include "mme_event.h" +#include "s1ap_build.h" #include "s1ap_handler.h" #include "s1ap_path.h" #include "mme_fd_path.h" -#include "nas_security.h" -#include "emm_handler.h" #include "mme_gtp_path.h" #include "mme_s11_handler.h" +#include "nas_security.h" +#include "nas_path.h" #include "emm_handler.h" +#include "esm_build.h" #include "esm_handler.h" #include "fd_lib.h" #include "mme_s6a_handler.h" @@ -205,6 +207,10 @@ void mme_state_operational(fsm_t *s, event_t *e) event_set_param4(e, (c_uintptr_t)&message); fsm_dispatch(&mme_ue->sm, (fsm_event_t*)e); + if (FSM_CHECK(&mme_ue->sm, emm_state_exception)) + { + mme_ue_remove(mme_ue); + } pkbuf_free(pkbuf); @@ -237,6 +243,16 @@ void mme_state_operational(fsm_t *s, event_t *e) event_set_param3(e, (c_uintptr_t)&message); fsm_dispatch(&bearer->sm, (fsm_event_t*)e); + if (FSM_CHECK(&bearer->sm, esm_state_session_exception)) + { + mme_sess_t *sess = bearer->sess; + d_assert(sess, break, "Null param"); + mme_sess_remove(sess); + } + else if (FSM_CHECK(&bearer->sm, esm_state_bearer_exception)) + { + mme_bearer_remove(bearer); + } pkbuf_free(pkbuf); @@ -264,8 +280,7 @@ void mme_state_operational(fsm_t *s, event_t *e) EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); - fsm_final(&mme_ue->sm, e); - fsm_init(&mme_ue->sm, e); + mme_ue_remove(mme_ue); break; } @@ -281,8 +296,7 @@ void mme_state_operational(fsm_t *s, event_t *e) EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); - fsm_final(&mme_ue->sm, e); - fsm_init(&mme_ue->sm, e); + mme_ue_remove(mme_ue); break; } @@ -337,8 +351,29 @@ void mme_state_operational(fsm_t *s, event_t *e) { case GTP_CREATE_SESSION_RESPONSE_TYPE: { - mme_s11_handle_create_session_response( - xact, mme_ue, &message.create_session_response); + mme_bearer_t *bearer = NULL; + + gtp_create_session_response_t *rsp + = &message.create_session_response; + d_assert(rsp, return, "Null param"); + + if (rsp->bearer_contexts_created.presence == 0) + { + d_error("No Bearer"); + return; + } + if (rsp->bearer_contexts_created. + eps_bearer_id.presence == 0) + { + d_error("No EPS Bearer ID"); + return; + } + + bearer = mme_bearer_find_by_ue_ebi(mme_ue, + rsp->bearer_contexts_created.eps_bearer_id.u8); + d_assert(bearer, return, "Null param"); + + mme_s11_handle_create_session_response(xact, bearer, rsp); if (FSM_CHECK(&mme_ue->sm, emm_state_default_esm)) { @@ -346,7 +381,29 @@ void mme_state_operational(fsm_t *s, event_t *e) } else if (FSM_CHECK(&mme_ue->sm, emm_state_attached)) { - d_assert(0, , "Coming Soon!"); + mme_sess_t *sess = NULL; + enb_ue_t *enb_ue = NULL; + pkbuf_t *esmbuf = NULL, *s1apbuf = NULL; + + sess = bearer->sess; + d_assert(sess, return, "Null param"); + enb_ue = mme_ue->enb_ue; + d_assert(enb_ue, return, "Null param"); + + rv = esm_build_activate_default_bearer_context( + &esmbuf, sess); + d_assert(rv == CORE_OK && esmbuf, return, + "esm build error"); + + d_trace(3, "[NAS] Activate default bearer " + "context request : EMM <-- ESM\n"); + + rv = s1ap_build_e_rab_setup_request( + &s1apbuf, bearer, esmbuf); + d_assert(rv == CORE_OK && s1apbuf, + pkbuf_free(esmbuf); return, "s1ap build error"); + + d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,); } else d_assert(0, break, "Invalid EMM state"); diff --git a/src/mme/mme_sm.h b/src/mme/mme_sm.h index 82ff1729d..e8a3fe443 100644 --- a/src/mme/mme_sm.h +++ b/src/mme/mme_sm.h @@ -32,7 +32,10 @@ void emm_state_exception(fsm_t *s, event_t *e); void esm_state_initial(fsm_t *s, event_t *e); void esm_state_final(fsm_t *s, event_t *e); void esm_state_inactive(fsm_t *s, event_t *e); +void esm_state_information(fsm_t *s, event_t *e); void esm_state_active(fsm_t *s, event_t *e); +void esm_state_session_exception(fsm_t *s, event_t *e); +void esm_state_bearer_exception(fsm_t *s, event_t *e); #define mme_sm_print(__pe) \ d_print("%s(): %s\n", __func__, mme_event_get_name(__pe)) diff --git a/src/mme/s1ap_handler.c b/src/mme/s1ap_handler.c index 962adea9d..de7ccd348 100644 --- a/src/mme/s1ap_handler.c +++ b/src/mme/s1ap_handler.c @@ -9,6 +9,8 @@ #include "s1ap_path.h" #include "nas_message.h" #include "nas_security.h" +#include "nas_path.h" +#include "esm_build.h" #include "mme_s11_build.h" #include "mme_gtp_path.h" @@ -381,6 +383,63 @@ void s1ap_handle_ue_capability_info_indication( enb->enb_id); } +void s1ap_handle_activate_default_bearer_accept(mme_bearer_t *bearer) +{ + status_t rv; + gtp_header_t h; + gtp_xact_t *xact = NULL; + mme_ue_t *mme_ue = NULL; + mme_sess_t *sess = NULL; + mme_bearer_t *dedicated_bearer = NULL; + pkbuf_t *pkbuf = NULL; + + d_assert(bearer, return, "Null param"); + sess = bearer->sess; + d_assert(sess, return, "Null param"); + mme_ue = sess->mme_ue; + d_assert(mme_ue, return, "Null param"); + + memset(&h, 0, sizeof(gtp_header_t)); + h.type = GTP_MODIFY_BEARER_REQUEST_TYPE; + h.teid = mme_ue->sgw_s11_teid; + + rv = mme_s11_build_modify_bearer_request(&pkbuf, h.type, bearer); + d_assert(rv == CORE_OK, return, "S11 build error"); + + xact = gtp_xact_local_create(sess->sgw, &h, pkbuf); + d_assert(xact, return, "Null param"); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return, "xact_commit error"); + + dedicated_bearer = mme_bearer_next(bearer); + while(dedicated_bearer) + { + enb_ue_t *enb_ue = NULL; + pkbuf_t *esmbuf = NULL, *s1apbuf = NULL; + + enb_ue = mme_ue->enb_ue; + d_assert(enb_ue, return, "Null param"); + + rv = esm_build_activate_dedicated_bearer_context( + &esmbuf, dedicated_bearer); + d_assert(rv == CORE_OK && esmbuf, return, "esm build error"); + + d_trace(3, "[NAS] Activate dedicated bearer context request : " + "EMM <-- ESM\n"); + + rv = s1ap_build_e_rab_setup_request( + &s1apbuf, dedicated_bearer, esmbuf); + d_assert(rv == CORE_OK && s1apbuf, + pkbuf_free(esmbuf); return, "s1ap build error"); + + d_assert(nas_send_to_enb(enb_ue, s1apbuf) == CORE_OK,,); + + dedicated_bearer = mme_bearer_next(dedicated_bearer); + } +} + + void s1ap_handle_initial_context_setup_response( mme_enb_t *enb, s1ap_message_t *message) { @@ -405,11 +464,7 @@ void s1ap_handle_initial_context_setup_response( for (i = 0; i < ies->e_RABSetupListCtxtSURes. s1ap_E_RABSetupItemCtxtSURes.count; i++) { - status_t rv; - gtp_header_t h; - gtp_xact_t *xact = NULL; mme_sess_t *sess = NULL; - pkbuf_t *pkbuf = NULL; mme_bearer_t *bearer = NULL; mme_ue_t *mme_ue = enb_ue->mme_ue; @@ -431,18 +486,7 @@ void s1ap_handle_initial_context_setup_response( if (FSM_CHECK(&bearer->sm, esm_state_active)) { - memset(&h, 0, sizeof(gtp_header_t)); - h.type = GTP_MODIFY_BEARER_REQUEST_TYPE; - h.teid = mme_ue->sgw_s11_teid; - - rv = mme_s11_build_modify_bearer_request(&pkbuf, h.type, bearer); - d_assert(rv == CORE_OK, return, "S11 build error"); - - xact = gtp_xact_local_create(sess->sgw, &h, pkbuf); - d_assert(xact, return, "Null param"); - - rv = gtp_xact_commit(xact); - d_assert(rv == CORE_OK, return, "xact_commit error"); + s1ap_handle_activate_default_bearer_accept(bearer); } } } @@ -479,7 +523,7 @@ void s1ap_handle_e_rab_setup_response( gtp_xact_t *xact = NULL; pkbuf_t *pkbuf = NULL; - mme_bearer_t *bearer = NULL; + mme_bearer_t *bearer = NULL, *linked_bearer = NULL; mme_ue_t *mme_ue = enb_ue->mme_ue; S1ap_E_RABSetupItemBearerSURes_t *e_rab = NULL; @@ -489,8 +533,6 @@ void s1ap_handle_e_rab_setup_response( bearer = mme_bearer_find_by_ue_ebi(mme_ue, e_rab->e_RAB_ID); d_assert(bearer, return, "Null param"); - xact = bearer->xact; - d_assert(xact, return, "Null param"); memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf, sizeof(bearer->enb_s1u_teid)); @@ -500,18 +542,34 @@ void s1ap_handle_e_rab_setup_response( if (FSM_CHECK(&bearer->sm, esm_state_active)) { - memset(&h, 0, sizeof(gtp_header_t)); - h.type = GTP_CREATE_BEARER_RESPONSE_TYPE; - h.teid = mme_ue->sgw_s11_teid; + linked_bearer = mme_linked_bearer(bearer); + d_assert(linked_bearer, return, "Null param"); + + if (linked_bearer->ebi == bearer->ebi) + { + /* Default Bearer */ + s1ap_handle_activate_default_bearer_accept(bearer); + } + else + { + /* Dedicated Bearer */ + xact = bearer->xact; + d_assert(xact, return, "Null param"); - rv = mme_s11_build_create_bearer_response(&pkbuf, h.type, bearer); - d_assert(rv == CORE_OK, return, "S11 build error"); + memset(&h, 0, sizeof(gtp_header_t)); + h.type = GTP_CREATE_BEARER_RESPONSE_TYPE; + h.teid = mme_ue->sgw_s11_teid; - rv = gtp_xact_update_tx(xact, &h, pkbuf); - d_assert(xact, return, "Null param"); + rv = mme_s11_build_create_bearer_response( + &pkbuf, h.type, bearer); + d_assert(rv == CORE_OK, return, "S11 build error"); - rv = gtp_xact_commit(xact); - d_assert(rv == CORE_OK, return, "xact_commit error"); + rv = gtp_xact_update_tx(xact, &h, pkbuf); + d_assert(xact, return, "Null param"); + + rv = gtp_xact_commit(xact); + d_assert(rv == CORE_OK, return, "xact_commit error"); + } } } } diff --git a/src/pcrf/pcrf_fd_path.c b/src/pcrf/pcrf_fd_path.c index aebc53742..a3a34ae12 100644 --- a/src/pcrf/pcrf_fd_path.c +++ b/src/pcrf/pcrf_fd_path.c @@ -94,7 +94,7 @@ static int pcrf_gx_ccr_cb( struct msg **msg, struct avp *avp, CHECK_FCT( fd_msg_search_avp(qry, gx_called_station_id, &avp) ); CHECK_FCT( fd_msg_avp_hdr(avp, &hdr) ); core_cpystrn(apn, (char*)hdr->avp_value->os.data, - c_min(hdr->avp_value->os.len, MAX_IMSI_BCD_LEN)+1); + c_min(hdr->avp_value->os.len, MAX_APN_LEN)+1); rv = pcrf_db_pdn_data(imsi_bcd, apn, &cca_message); if (rv != CORE_OK) diff --git a/test/testpacket.c b/test/testpacket.c index 46a303784..bcf832fe0 100644 --- a/test/testpacket.c +++ b/test/testpacket.c @@ -755,7 +755,8 @@ status_t tests1ap_build_e_rab_setup_response(pkbuf_t **pkbuf, int i) char *payload[TESTS1AP_MAX_MESSAGE] = { "2005002600000300 004005c00200003c 0008400300010000 1c400f000027400a" "0c1f0a012da50100 b410", - "", + "2005002600000300 004005c00200003c 0008400300010000 1c400f000027400a" + "0e1f0a012da50100 b410", "", "", @@ -769,6 +770,50 @@ status_t tests1ap_build_e_rab_setup_response(pkbuf_t **pkbuf, int i) }; c_uint16_t len[TESTS1AP_MAX_MESSAGE] = { 42, + 42, + 0, + + 0, + 0, + 0, + + 0, + 0, + 0, + }; + char hexbuf[MAX_SDU_LEN]; + + *pkbuf = pkbuf_alloc(0, MAX_SDU_LEN); + if (!(*pkbuf)) return CORE_ERROR; + + (*pkbuf)->len = len[i]; + memcpy((*pkbuf)->payload, CORE_HEX(payload[i], strlen(payload[i]), hexbuf), + (*pkbuf)->len); + + return CORE_OK; +} + +status_t tests1ap_build_activate_default_bearer_accept( + pkbuf_t **pkbuf, int i) +{ + char *payload[TESTS1AP_MAX_MESSAGE] = { + "000d40370000" + "0500000005c08000 0107000800030001 00001a000a0927e7 f5bb400b6200c200" + "6440080055f50100 19d0100043400600 55f5011022", + "", + "", + + "", + "", + "", + + "", + "", + "", + + }; + c_uint16_t len[TESTS1AP_MAX_MESSAGE] = { + 59, 0, 0, @@ -799,7 +844,9 @@ status_t tests1ap_build_activate_dedicated_bearer_accept( "000d403700000500" "000005c00200003c 0008000300010000 1a000a0927c035da 96036200c6006440" "080000f1109d67aa 50004340060000f1 102b67", - "", + "000d403700000500" + "000005c00200003c 0008000300010000 1a000a0927078a5f 34037200c6006440" + "080000f1109d67aa 50004340060000f1 102b67", "", "", @@ -813,7 +860,7 @@ status_t tests1ap_build_activate_dedicated_bearer_accept( }; c_uint16_t len[TESTS1AP_MAX_MESSAGE] = { 59, - 0, + 59, 0, 0, @@ -836,3 +883,48 @@ status_t tests1ap_build_activate_dedicated_bearer_accept( return CORE_OK; } +status_t tests1ap_build_pdn_connectivity_request( + pkbuf_t **pkbuf, int i) +{ + char *payload[TESTS1AP_MAX_MESSAGE] = { + "000d40680000" + "0500000005c08000 0107000800030001 00001a003b3a277c 81dab50a0205d011" + "281208696e746572 6e6574036e673204 6d6e6574271a8080 2110010000108106" + "0000000083060000 0000000d00000a00 006440080055f501 0019d01000434006" + "0055f5011022", + "", + "", + + "", + "", + "", + + "", + "", + "", + + }; + c_uint16_t len[TESTS1AP_MAX_MESSAGE] = { + 108, + 0, + 0, + + 0, + 0, + 0, + + 59, + 0, + 0, + }; + char hexbuf[MAX_SDU_LEN]; + + *pkbuf = pkbuf_alloc(0, MAX_SDU_LEN); + if (!(*pkbuf)) return CORE_ERROR; + + (*pkbuf)->len = len[i]; + memcpy((*pkbuf)->payload, CORE_HEX(payload[i], strlen(payload[i]), hexbuf), + (*pkbuf)->len); + + return CORE_OK; +} diff --git a/test/testpacket.h b/test/testpacket.h index 215481979..d781f3b40 100644 --- a/test/testpacket.h +++ b/test/testpacket.h @@ -35,9 +35,13 @@ CORE_DECLARE(status_t) tests1ap_build_ue_context_release_complete( pkbuf_t **pkbuf, int i); CORE_DECLARE(status_t) tests1ap_build_service_request( pkbuf_t **pkbuf, int i); +CORE_DECLARE(status_t) tests1ap_build_e_rab_setup_response( + pkbuf_t **pkbuf, int i); +CORE_DECLARE(status_t) tests1ap_build_activate_default_bearer_accept( + pkbuf_t **pkbuf, int i); CORE_DECLARE(status_t) tests1ap_build_activate_dedicated_bearer_accept( pkbuf_t **pkbuf, int i); -CORE_DECLARE(status_t) tests1ap_build_e_rab_setup_response( +CORE_DECLARE(status_t) tests1ap_build_pdn_connectivity_request( pkbuf_t **pkbuf, int i); #ifdef __cplusplus diff --git a/test/volte_test.c b/test/volte_test.c index 7fb0739ea..cbb26cecb 100644 --- a/test/volte_test.c +++ b/test/volte_test.c @@ -218,13 +218,14 @@ static void volte_test1(abts_case *tc, void *data) ABTS_INT_NEQUAL(tc, 0, rc); pkbuf_free(recvbuf); - /* Receive E-RAB Setup */ + /* Receive E-RAB Setup Request + + * Activate dedicated EPS bearer context request */ recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); rc = tests1ap_enb_read(sock, recvbuf); ABTS_INT_NEQUAL(tc, 0, rc); pkbuf_free(recvbuf); - /* Send E-RAB Setup */ + /* Send E-RAB Setup Response */ rv = tests1ap_build_e_rab_setup_response(&sendbuf, msgindex); ABTS_INT_EQUAL(tc, CORE_OK, rv); rv = tests1ap_enb_send(sock, sendbuf); @@ -254,11 +255,285 @@ static void volte_test1(abts_case *tc, void *data) core_sleep(time_from_msec(300)); } +static void volte_test2(abts_case *tc, void *data) +{ + status_t rv; + net_sock_t *sock; + pkbuf_t *sendbuf; + pkbuf_t *recvbuf; + s1ap_message_t message; + int rc; + int i; + int msgindex = 0; + + mongoc_collection_t *collection = NULL; + bson_t *doc = NULL; + c_int64_t count = 0; + bson_error_t error; + const char *json = + "{" + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2b\" }," + "\"imsi\" : \"001010123456819\"," + "\"pdn\" : [" + "{ \"apn\" : \"internet\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd32\" }," + "\"qos\" : {" + "\"qci\" : 9," + "\"arp\" : {" + "\"priority_level\" : 8," + "\"pre_emption_vulnerability\" : 1," + "\"pre_emption_capability\" : 1 } }," + "\"type\" : 0 }," + "{ \"apn\" : \"internet.ng2.mnet\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2c\" }," + "\"pcc_rule\" : [" + "{ \"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2d\" }," + "\"qos\" : {" + "\"qci\" : 1," + "\"gbr\" : {" + "\"downlink\" : { \"$numberLong\" : \"64\" }," + "\"uplink\" : { \"$numberLong\" : \"44\" } }," + "\"mbr\" : {" + "\"downlink\" : { \"$numberLong\" : \"64\" }," + "\"uplink\" : { \"$numberLong\" : \"44\" } }," + "\"arp\" : {" + "\"priority_level\" : 3," + "\"pre_emption_vulnerability\" : 0," + "\"pre_emption_capability\" : 0 } }," + "\"flow\" : [" + "{ \"direction\" : 2," + "\"description\" : \"permit out udp from any 1-65535 to 10.200.136.98/32 23454\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd31\" } }," + "{ \"direction\" : 1," + "\"description\" : \"permit out udp from any 50020 to 10.200.136.98/32 1-65535\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd30\" } }," + "{ \"direction\" : 2," + "\"description\" : \"permit out udp from any 1-65535 to 10.200.136.98/32 23455\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2f\" } }," + "{ \"direction\" : 1," + "\"description\" : \"permit out udp from any 50021 to 10.200.136.98/32 1-65535\"," + "\"_id\" : { \"$oid\" : \"599eb929c850caabcbfdcd2e\" } } ]" + "} ]," + "\"ambr\" : {" + "\"downlink\" : { \"$numberLong\" : \"35840\" }," + "\"uplink\" : { \"$numberLong\" : \"15360\" } }," + "\"qos\" : {" + "\"qci\" : 6," + "\"arp\" : {" + "\"priority_level\" : 6," + "\"pre_emption_vulnerability\" : 1," + "\"pre_emption_capability\" : 1 } }," + "\"type\" : 0 }" + "]," + "\"ambr\" : {" + "\"downlink\" : { \"$numberLong\" : \"1024000\" }," + "\"uplink\" : { \"$numberLong\" : \"1024000\" } }," + "\"subscribed_rau_tau_timer\" : 12," + "\"network_access_mode\" : 2," + "\"subscriber_status\" : 0," + "\"access_restriction_data\" : 32," + "\"security\" : {" + "\"k\" : \"465B5CE8 B199B49F AA5F0A2E E238A6BC\"," + "\"op\" : \"5F1D289C 5D354D0A 140C2548 F5F3E3BA\"," + "\"amf\" : \"8000\"," + "\"sqn\" : { \"$numberLong\" : \"64\" }, " + "\"rand\" : \"20080C38 18183B52 2614162C 07601D0D\" }, " + "\"__v\" : 0" + "}"; + + /* eNB connects to MME */ + sock = tests1ap_enb_connect(); + ABTS_PTR_NOTNULL(tc, sock); + + /* Send S1-Setup Reqeust */ + rv = tests1ap_build_setup_req(&sendbuf, 0x54f64); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + /* Receive S1-Setup Response */ + recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); + rc = tests1ap_enb_read(sock, recvbuf); + ABTS_INT_NEQUAL(tc, 0, rc); + rv = s1ap_decode_pdu(&message, recvbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + s1ap_free_pdu(&message); + pkbuf_free(recvbuf); + + collection = mongoc_client_get_collection( + context_self()->db_client, + context_self()->db_name, "subscribers"); + ABTS_PTR_NOTNULL(tc, collection); + + 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("001010123456819")); + 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); + + /*********************************************************************** + * Attach Request : Known IMSI, Integrity Protected, No Security Context + * Send Initial-UE Message + Attach Request + PDN Connectivity */ + rv = tests1ap_build_initial_ue_msg(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + /* Receive Authentication Request */ + recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); + rc = tests1ap_enb_read(sock, recvbuf); + ABTS_INT_NEQUAL(tc, 0, rc); + pkbuf_free(recvbuf); + + /* Send Authentication Response */ + rv = tests1ap_build_authentication_response(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + /* Receive Security mode Command */ + recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); + rc = tests1ap_enb_read(sock, recvbuf); + ABTS_INT_NEQUAL(tc, 0, rc); + pkbuf_free(recvbuf); + + /* Send Security mode Complete */ + rv = tests1ap_build_security_mode_complete(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + /* Receive ESM Information Request */ + recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); + rc = tests1ap_enb_read(sock, recvbuf); + ABTS_INT_NEQUAL(tc, 0, rc); + pkbuf_free(recvbuf); + + /* Send ESM Information Response */ + rv = tests1ap_build_esm_information_response(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + /* Receive Initial Context Setup Request + + * Attach Accept + + * Activate Default Bearer Context Request */ + recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); + rc = tests1ap_enb_read(sock, recvbuf); + ABTS_INT_NEQUAL(tc, 0, rc); + pkbuf_free(recvbuf); + + /* Send UE Capability Info Indication */ + rv = tests1ap_build_ue_capability_info_indication(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + core_sleep(time_from_msec(300)); + + /* Send Initial Context Setup Response */ + rv = tests1ap_build_initial_context_setup_response(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + /* Send Attach Complete + Activate default EPS bearer cotext accept */ + rv = tests1ap_build_attach_complete(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + /* Receive EMM information */ + recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); + rc = tests1ap_enb_read(sock, recvbuf); + ABTS_INT_NEQUAL(tc, 0, rc); + pkbuf_free(recvbuf); + + core_sleep(time_from_msec(300)); + + /* Send PDN Connectivity Request */ + rv = tests1ap_build_pdn_connectivity_request(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + core_sleep(time_from_msec(300)); + + /* Receive E-RAB Setup Request + + * Activate default EPS bearer context request */ + recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); + rc = tests1ap_enb_read(sock, recvbuf); + ABTS_INT_NEQUAL(tc, 0, rc); + pkbuf_free(recvbuf); + + /* Send E-RAB Setup Response */ + rv = tests1ap_build_e_rab_setup_response(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + core_sleep(time_from_msec(300)); + + /* Send Activate default EPS bearer context accept */ + rv = tests1ap_build_activate_default_bearer_accept(&sendbuf, msgindex); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + /* Receive E-RAB Setup Request + + * Activate dedicated EPS bearer context request */ + recvbuf = pkbuf_alloc(0, MAX_SDU_LEN); + rc = tests1ap_enb_read(sock, recvbuf); + ABTS_INT_NEQUAL(tc, 0, rc); + pkbuf_free(recvbuf); + + /* Send Activate dedicated EPS bearer context accept */ + rv = tests1ap_build_activate_dedicated_bearer_accept(&sendbuf, msgindex+1); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + core_sleep(time_from_msec(300)); + + /* Send E-RAB Setup Response */ + rv = tests1ap_build_e_rab_setup_response(&sendbuf, msgindex+1); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + rv = tests1ap_enb_send(sock, sendbuf); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + core_sleep(time_from_msec(300)); + + /********** Remove Subscriber in Database */ + doc = BCON_NEW("imsi", BCON_UTF8("001010123456819")); + 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 */ + rv = tests1ap_enb_close(sock); + ABTS_INT_EQUAL(tc, CORE_OK, rv); + + core_sleep(time_from_msec(300)); +} + abts_suite *test_volte(abts_suite *suite) { suite = ADD_SUITE(suite) abts_run_test(suite, volte_test1, NULL); + abts_run_test(suite, volte_test2, NULL); return suite; }