Multiple PDN ..done!

This commit is contained in:
Sukchan Lee 2017-09-07 00:37:16 +09:00
parent 5b2728babd
commit 229d04c284
15 changed files with 776 additions and 165 deletions

View File

@ -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)

View File

@ -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,
}
}
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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(

View File

@ -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);
}
}

View File

@ -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(

View File

@ -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);

View File

@ -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");

View File

@ -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))

View File

@ -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");
}
}
}
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}