design EMM state machine initially.

This commit is contained in:
Sukchan Lee 2017-09-04 00:06:39 +09:00
parent 93ebb9cd43
commit 87b0897602
23 changed files with 622 additions and 365 deletions

View File

@ -3,7 +3,6 @@
#include "core_msgq.h"
#include "core_timer.h"
#include "core_fsm.h"
#ifdef __cplusplus
extern "C" {
@ -50,7 +49,7 @@ extern "C" {
(__duration), (__ptr_e), (__param))
typedef struct {
fsm_event_t event;
c_uintptr_t event;
c_uintptr_t param1;
c_uintptr_t param2;
c_uintptr_t param3;
@ -61,10 +60,6 @@ typedef struct {
c_uintptr_t param8;
} event_t;
extern char *FSM_NAME_INIT_SIG;
extern char *FSM_NAME_ENTRY_SIG;
extern char *FSM_NAME_EXIT_SIG;
extern char *EVT_NAME_UNKNOWN;
/**

View File

@ -7,14 +7,21 @@
extern "C" {
#endif /* __cplusplus */
extern char *FSM_NAME_INIT_SIG;
extern char *FSM_NAME_ENTRY_SIG;
extern char *FSM_NAME_EXIT_SIG;
typedef enum _fsm_signal_t {
FSM_ENTRY_SIG,
FSM_EXIT_SIG,
FSM_USER_SIG
} fsm_signal_t;
typedef c_uint32_t fsm_event_t;
typedef c_uint32_t fsm_state_t;
typedef struct {
c_uintptr_t event;
} fsm_event_t;
typedef c_uintptr_t fsm_state_t;
typedef void (*fsm_handler_t)(void *s, void *e);
typedef struct _fsm_t {
@ -41,6 +48,9 @@ CORE_DECLARE(void) fsm_final(fsm_t *s, fsm_event_t *e);
#define FSM_STATE(__s) \
(((fsm_t *)__s)->state)
#define FSM_CHECK(__s, __f) \
(FSM_STATE(__s) == (fsm_handler_t)__f)
#ifdef __cplusplus
}
#endif

View File

@ -10,10 +10,6 @@
#define EVT_Q_DEPTH 16
char *FSM_NAME_INIT_SIG = "INIT";
char *FSM_NAME_ENTRY_SIG = "ENTRY";
char *FSM_NAME_EXIT_SIG = "EXIT";
char *EVT_NAME_UNKNOWN = "UNKNOWN";
msgq_id event_create(void)

View File

@ -1,9 +1,15 @@
#include "core_fsm.h"
static fsm_event_t fsm_event[] = {
static fsm_event_t entry_event = {
FSM_ENTRY_SIG,
FSM_EXIT_SIG
};
static fsm_event_t exit_event = {
FSM_EXIT_SIG,
};
char *FSM_NAME_INIT_SIG = "INIT";
char *FSM_NAME_ENTRY_SIG = "ENTRY";
char *FSM_NAME_EXIT_SIG = "EXIT";
void fsm_init(fsm_t *s, fsm_event_t *e)
{
@ -12,7 +18,15 @@ void fsm_init(fsm_t *s, fsm_event_t *e)
(*s->initial)(s, e);
if (s->initial != s->state)
{
(*s->state)(s, &fsm_event[FSM_ENTRY_SIG]);
if (e)
{
e->event = FSM_ENTRY_SIG;
(*s->state)(s, e);
}
else
{
(*s->state)(s, &entry_event);
}
}
}
}
@ -25,8 +39,24 @@ void fsm_dispatch(fsm_t *s, fsm_event_t *e)
(*tmp)(s, e);
if (s->state != (fsm_state_t)0)
{
(*tmp)(s, &fsm_event[FSM_EXIT_SIG]);
(*s->state)(s, &fsm_event[FSM_ENTRY_SIG]);
if (e)
{
e->event = FSM_EXIT_SIG;
(*tmp)(s, e);
}
else
{
(*tmp)(s, &exit_event);
}
if (e)
{
e->event = FSM_ENTRY_SIG;
(*s->state)(s, e);
}
else
{
(*tmp)(s, &entry_event);
}
}
else
{
@ -38,12 +68,20 @@ void fsm_final(fsm_t *s, fsm_event_t *e)
{
if (s->final != s->state)
{
(*s->state)(s, &fsm_event[FSM_EXIT_SIG]);
if (e)
{
e->event = FSM_EXIT_SIG;
(*s->state)(s, e);
}
else
{
(*s->state)(s, &exit_event);
}
}
if (s->final != (fsm_state_t)0)
{
(*s->final)(s, 0);
(*s->final)(s, e);
}
s->state = s->initial;

View File

@ -18,7 +18,7 @@ AM_CPPFLAGS = \
AM_CFLAGS = \
-Wall -Werror @OSCPPFLAGS@ \
-Wno-unused-function
-Wno-unused-function -Wno-unused-variable
TESTS = testcore

View File

@ -8,7 +8,7 @@ enum bomb_signal_t {
};
typedef struct _tick_event_t {
fsm_event_t event;
c_uintptr_t event;
} tick_event_t;
typedef struct _bomb_t {
@ -176,17 +176,17 @@ enum alarm_signal_t {
};
typedef struct _alarm_t {
fsm_t fsm;
fsm_t fsm;
c_uint32_t time;
} alarm_t;
typedef struct _set_event_t {
fsm_event_t event;
c_uintptr_t event;
c_uint8_t digit;
} set_event_t;
typedef struct _time_event_t {
fsm_event_t event;
c_uintptr_t event;
c_uint8_t current_time;
} time_event_t;

View File

@ -152,7 +152,7 @@ void emm_handle_attach_request(
d_warn("Not implemented(type:%d)",
eps_mobile_identity->imsi.type);
return;
break;
}
}
@ -472,7 +472,8 @@ void emm_handle_detach_request(
break;
}
SET_DETACH_TYPE(mme_ue, detach_request->detach_type);
/* Save detach type */
mme_ue->detach_type = detach_request->detach_type;
}
void emm_handle_detach_accept(mme_ue_t *mme_ue)
@ -509,8 +510,6 @@ void emm_handle_detach_accept(mme_ue_t *mme_ue)
d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,);
}
CLEAR_DETACH_TYPE(mme_ue);
cause.present = S1ap_Cause_PR_nas;
cause.choice.nas = S1ap_CauseNas_detach;

View File

@ -21,7 +21,7 @@ void emm_state_initial(fsm_t *s, event_t *e)
mme_sm_trace(3, e);
FSM_TRAN(s, &emm_state_operational);
FSM_TRAN(s, &emm_state_detached);
}
void emm_state_final(fsm_t *s, event_t *e)
@ -31,13 +31,18 @@ void emm_state_final(fsm_t *s, event_t *e)
mme_sm_trace(3, e);
}
void emm_state_operational(fsm_t *s, event_t *e)
void emm_state_detached(fsm_t *s, event_t *e)
{
mme_ue_t *mme_ue = NULL;
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
mme_sm_trace(3, e);
mme_ue = mme_ue_find(event_get_param1(e));
d_assert(mme_ue, return, "Null param");
switch (event_get(e))
{
case FSM_ENTRY_SIG:
@ -50,15 +55,305 @@ void emm_state_operational(fsm_t *s, event_t *e)
}
case MME_EVT_EMM_MESSAGE:
{
index_t index = event_get_param1(e);
mme_ue_t *mme_ue = NULL;
nas_message_t *message = NULL;
nas_message_t *message = (nas_message_t *)event_get_param4(e);
d_assert(message, break, "Null param");
d_assert(index, return, "Null param");
mme_ue = mme_ue_find(index);
switch(message->emm.h.message_type)
{
case NAS_ATTACH_REQUEST:
{
/* Update Kenb */
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32,
mme_ue->kenb);
CLEAR_EPS_BEARER_ID(mme_ue);
mme_ue_paged(mme_ue);
emm_handle_attach_request(
mme_ue, &message->emm.attach_request);
if (!MME_UE_HAVE_IMSI(mme_ue))
{
/* Unknown GUTI */
FSM_TRAN(s, &emm_state_identity);
break;
}
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
{
event_emm_to_esm(
mme_ue, &mme_ue->last_pdn_connectivity_request);
FSM_TRAN(s, &emm_state_default_esm);
}
else
{
if (MME_UE_HAVE_SESSION(mme_ue))
{
mme_s11_handle_delete_all_sessions_in_ue(mme_ue);
}
else
{
mme_s6a_send_air(mme_ue);
}
FSM_TRAN(s, &emm_state_auth);
}
break;
}
}
break;
}
default:
{
d_error("Unknown event %s", mme_event_get_name(e));
break;
}
}
}
void emm_state_identity(fsm_t *s, event_t *e)
{
mme_ue_t *mme_ue = NULL;
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
mme_sm_trace(3, e);
mme_ue = mme_ue_find(event_get_param1(e));
d_assert(mme_ue, return, "Null param");
switch (event_get(e))
{
case FSM_ENTRY_SIG:
{
mme_ue_t *mme_ue = mme_ue_find(event_get_param1(e));
d_assert(mme_ue, return, "Null param");
message = (nas_message_t *)event_get_param4(e);
emm_handle_identity_request(mme_ue);
break;
}
case FSM_EXIT_SIG:
{
break;
}
case MME_EVT_EMM_MESSAGE:
{
nas_message_t *message = (nas_message_t *)event_get_param4(e);
d_assert(message, break, "Null param");
switch(message->emm.h.message_type)
{
case NAS_IDENTITY_RESPONSE:
{
emm_handle_identity_response(mme_ue,
&message->emm.identity_response);
d_assert(MME_UE_HAVE_IMSI(mme_ue), break,
"No IMSI in IDENTITY_RESPONSE");
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
{
event_emm_to_esm(mme_ue,
&mme_ue->last_pdn_connectivity_request);
FSM_TRAN(s, &emm_state_default_esm);
}
else
{
if (MME_UE_HAVE_SESSION(mme_ue))
{
mme_s11_handle_delete_all_sessions_in_ue(mme_ue);
}
else
{
mme_s6a_send_air(mme_ue);
}
FSM_TRAN(s, &emm_state_auth);
}
break;
}
case NAS_EMM_STATUS:
{
emm_handle_emm_status(mme_ue, &message->emm.emm_status);
FSM_TRAN(s, &emm_state_detached);
break;
}
default:
{
d_warn("Unknown message(type:%d)",
message->emm.h.message_type);
break;
}
}
break;
}
default:
{
d_error("Unknown event %s", mme_event_get_name(e));
break;
}
}
}
void emm_state_auth(fsm_t *s, event_t *e)
{
mme_ue_t *mme_ue = NULL;
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
mme_sm_trace(3, e);
mme_ue = mme_ue_find(event_get_param1(e));
d_assert(mme_ue, return, "Null param");
switch (event_get(e))
{
case FSM_ENTRY_SIG:
{
break;
}
case FSM_EXIT_SIG:
{
break;
}
case MME_EVT_EMM_MESSAGE:
{
nas_message_t *message = (nas_message_t *)event_get_param4(e);
d_assert(message, break, "Null param");
switch(message->emm.h.message_type)
{
case NAS_AUTHENTICATION_RESPONSE:
{
emm_handle_authentication_response(
mme_ue, &message->emm.authentication_response);
break;
}
case NAS_SECURITY_MODE_COMPLETE:
{
d_trace(3, "[NAS] Security mode complete : "
"UE[%s] --> EMM\n", mme_ue->imsi_bcd);
/* Update Kenb */
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32,
mme_ue->kenb);
mme_s6a_send_ulr(mme_ue);
FSM_TRAN(s, &emm_state_default_esm);
break;
}
case NAS_EMM_STATUS:
{
emm_handle_emm_status(mme_ue, &message->emm.emm_status);
FSM_TRAN(s, &emm_state_detached);
break;
}
default:
{
d_warn("Unknown message(type:%d)",
message->emm.h.message_type);
break;
}
}
break;
}
default:
{
d_error("Unknown event %s", mme_event_get_name(e));
break;
}
}
}
void emm_state_default_esm(fsm_t *s, event_t *e)
{
mme_ue_t *mme_ue = NULL;
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
mme_sm_trace(3, e);
mme_ue = mme_ue_find(event_get_param1(e));
d_assert(mme_ue, return, "Null param");
switch (event_get(e))
{
case FSM_ENTRY_SIG:
{
break;
}
case FSM_EXIT_SIG:
{
break;
}
case MME_EVT_EMM_MESSAGE:
{
nas_message_t *message = (nas_message_t *)event_get_param4(e);
d_assert(message, break, "Null param");
switch(message->emm.h.message_type)
{
case NAS_ATTACH_COMPLETE:
{
d_trace(3, "[NAS] Attach complete : UE[%s] --> EMM\n",
mme_ue->imsi_bcd);
emm_handle_attach_complete(
mme_ue, &message->emm.attach_complete);
FSM_TRAN(s, &emm_state_attached);
break;
}
case NAS_EMM_STATUS:
{
emm_handle_emm_status(mme_ue, &message->emm.emm_status);
FSM_TRAN(s, &emm_state_detached);
break;
}
default:
{
d_warn("Unknown message(type:%d)",
message->emm.h.message_type);
break;
}
}
break;
}
default:
{
d_error("Unknown event %s", mme_event_get_name(e));
break;
}
}
}
void emm_state_attached(fsm_t *s, event_t *e)
{
mme_ue_t *mme_ue = NULL;
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
mme_sm_trace(3, e);
mme_ue = mme_ue_find(event_get_param1(e));
d_assert(mme_ue, return, "Null param");
switch (event_get(e))
{
case FSM_ENTRY_SIG:
{
break;
}
case FSM_EXIT_SIG:
{
break;
}
case MME_EVT_EMM_MESSAGE:
{
nas_message_t *message = (nas_message_t *)event_get_param4(e);
d_assert(message, break, "Null param");
if (message->emm.h.security_header_type
@ -86,15 +381,15 @@ void emm_state_operational(fsm_t *s, event_t *e)
mme_ue->kenb);
CLEAR_EPS_BEARER_ID(mme_ue);
mme_ue_paged(mme_ue);
emm_handle_attach_request(
mme_ue, &message->emm.attach_request);
if (!MME_UE_HAVE_IMSI(mme_ue))
{
/* Unknown GUTI */
emm_handle_identity_request(mme_ue);
FSM_TRAN(s, &emm_state_identity);
break;
}
@ -102,80 +397,27 @@ void emm_state_operational(fsm_t *s, event_t *e)
{
event_emm_to_esm(
mme_ue, &mme_ue->last_pdn_connectivity_request);
FSM_TRAN(s, &emm_state_default_esm);
}
else
{
if (MME_UE_HAVE_SESSION(mme_ue))
{
mme_s11_handle_delete_all_sessions_request_in_ue(
mme_ue);
mme_s11_handle_delete_all_sessions_in_ue(mme_ue);
}
else
{
mme_s6a_send_air(mme_ue);
}
FSM_TRAN(s, &emm_state_auth);
}
break;
}
case NAS_IDENTITY_RESPONSE:
{
emm_handle_identity_response(mme_ue,
&message->emm.identity_response);
d_assert(MME_UE_HAVE_IMSI(mme_ue), break,
"No IMSI in IDENTITY_RESPONSE");
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
{
event_emm_to_esm(mme_ue,
&mme_ue->last_pdn_connectivity_request);
}
else
{
if (MME_UE_HAVE_SESSION(mme_ue))
{
mme_s11_handle_delete_all_sessions_request_in_ue(
mme_ue);
}
else
{
mme_s6a_send_air(mme_ue);
}
}
break;
}
case NAS_AUTHENTICATION_RESPONSE:
{
emm_handle_authentication_response(
mme_ue, &message->emm.authentication_response);
break;
}
case NAS_SECURITY_MODE_COMPLETE:
{
d_trace(3, "[NAS] Security mode complete : "
"UE[%s] --> EMM\n", mme_ue->imsi_bcd);
/* Update Kenb */
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32,
mme_ue->kenb);
mme_s6a_send_ulr(mme_ue);
break;
}
case NAS_ATTACH_COMPLETE:
{
d_trace(3, "[NAS] Attach complete : UE[%s] --> EMM\n",
mme_ue->imsi_bcd);
emm_handle_attach_complete(
mme_ue, &message->emm.attach_complete);
break;
}
case NAS_EMM_STATUS:
{
emm_handle_emm_status(mme_ue, &message->emm.emm_status);
FSM_TRAN(s, &emm_state_detached);
break;
}
case NAS_DETACH_REQUEST:
@ -185,13 +427,14 @@ void emm_state_operational(fsm_t *s, event_t *e)
if (MME_UE_HAVE_SESSION(mme_ue))
{
mme_s11_handle_delete_all_sessions_request_in_ue(
mme_ue);
mme_s11_handle_delete_all_sessions_in_ue(mme_ue);
}
else
{
emm_handle_detach_accept(mme_ue);
}
FSM_TRAN(s, &emm_state_detached);
break;
}
case NAS_TRACKING_AREA_UPDATE_REQUEST:
@ -203,7 +446,7 @@ void emm_state_operational(fsm_t *s, event_t *e)
}
default:
{
d_warn("Not implemented(type:%d)",
d_warn("Unknown message(type:%d)",
message->emm.h.message_type);
break;
}
@ -212,13 +455,6 @@ void emm_state_operational(fsm_t *s, event_t *e)
}
case MME_EVT_EMM_T3413:
{
index_t index = event_get_param1(e);
mme_ue_t *mme_ue = NULL;
d_assert(index, return, "Null param");
mme_ue = mme_ue_find(index);
d_assert(mme_ue, return, "Null param");
if (mme_ue->max_paging_retry >= MAX_NUM_OF_PAGING)
{
/* Paging failed */
@ -246,28 +482,3 @@ void emm_state_operational(fsm_t *s, event_t *e)
}
}
}
void emm_state_exception(fsm_t *s, event_t *e)
{
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
mme_sm_trace(3, 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;
}
}
}

View File

@ -29,11 +29,19 @@ void esm_state_final(fsm_t *s, event_t *e)
void esm_state_operational(fsm_t *s, event_t *e)
{
mme_sess_t *sess = NULL;
mme_ue_t *mme_ue = NULL;
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
mme_sm_trace(3, e);
sess = mme_sess_find(event_get_param1(e));
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:
@ -46,17 +54,7 @@ void esm_state_operational(fsm_t *s, event_t *e)
}
case MME_EVT_ESM_MESSAGE:
{
index_t index = event_get_param1(e);
mme_sess_t *sess = NULL;
mme_ue_t *mme_ue = NULL;
nas_message_t *message = NULL;
d_assert(index, return, "Null param");
sess = mme_sess_find(index);
d_assert(sess, return, "Null param");
mme_ue = sess->mme_ue;
d_assert(mme_ue, return, "Null param");
message = (nas_message_t *)event_get_param3(e);
nas_message_t *message = (nas_message_t *)event_get_param3(e);
d_assert(message, break, "Null param");
switch(message->esm.h.message_type)

View File

@ -910,6 +910,7 @@ mme_sgw_t* mme_sgw_next(mme_sgw_t *sgw)
mme_enb_t* mme_enb_add(net_sock_t *s1ap_sock)
{
mme_enb_t *enb = NULL;
event_t e;
index_alloc(&mme_enb_pool, &enb);
d_assert(enb, return NULL, "Null param");
@ -922,17 +923,21 @@ mme_enb_t* mme_enb_add(net_sock_t *s1ap_sock)
list_init(&enb->enb_ue_list);
list_append(&self.enb_list, enb);
event_set_param1(&e, (c_uintptr_t)enb->index);
fsm_create(&enb->sm, s1ap_state_initial, s1ap_state_final);
fsm_init(&enb->sm, 0);
fsm_init(&enb->sm, (fsm_event_t *)&e);
return enb;
}
status_t mme_enb_remove(mme_enb_t *enb)
{
event_t e;
d_assert(enb, return CORE_ERROR, "Null param");
fsm_final(&enb->sm, 0);
event_set_param1(&e, (c_uintptr_t)enb->index);
fsm_final(&enb->sm, (fsm_event_t *)&e);
fsm_clear(&enb->sm);
enb_ue_remove_in_enb(enb);
@ -1117,6 +1122,7 @@ enb_ue_t* enb_ue_next_in_enb(enb_ue_t *enb_ue)
mme_ue_t* mme_ue_add(enb_ue_t *enb_ue)
{
mme_ue_t *mme_ue = NULL;
event_t e;
d_assert(enb_ue, return NULL, "Null param");
@ -1135,17 +1141,21 @@ mme_ue_t* mme_ue_add(enb_ue_t *enb_ue)
mme_ue->enb_ue = enb_ue;
enb_ue->mme_ue = mme_ue;
event_set_param1(&e, (c_uintptr_t)mme_ue->index);
fsm_create(&mme_ue->sm, emm_state_initial, emm_state_final);
fsm_init(&mme_ue->sm, 0);
fsm_init(&mme_ue->sm, (fsm_event_t *)&e);
return mme_ue;
}
status_t mme_ue_remove(mme_ue_t *mme_ue)
{
event_t e;
d_assert(mme_ue, return CORE_ERROR, "Null param");
fsm_final(&mme_ue->sm, 0);
event_set_param1(&e, (c_uintptr_t)mme_ue->index);
fsm_final(&mme_ue->sm, (fsm_event_t *)&e);
fsm_clear(&mme_ue->sm);
/* Clear hash table */
@ -1462,6 +1472,7 @@ mme_sess_t *mme_sess_add(mme_ue_t *mme_ue, c_uint8_t pti)
{
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;
event_t e;
d_assert(mme_ue, return NULL, "Null param");
d_assert(pti != NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
@ -1483,18 +1494,22 @@ mme_sess_t *mme_sess_add(mme_ue_t *mme_ue, c_uint8_t pti)
d_assert(bearer, mme_sess_remove(sess); return NULL,
"Can't add default bearer context");
event_set_param1(&e, (c_uintptr_t)sess->index);
fsm_create(&sess->sm, esm_state_initial, esm_state_final);
fsm_init(&sess->sm, 0);
fsm_init(&sess->sm, (fsm_event_t *)&e);
return sess;
}
status_t mme_sess_remove(mme_sess_t *sess)
{
event_t e;
d_assert(sess, return CORE_ERROR, "Null param");
d_assert(sess->mme_ue, return CORE_ERROR, "Null param");
fsm_final(&sess->sm, 0);
event_set_param1(&e, (c_uintptr_t)sess->index);
fsm_final(&sess->sm, (fsm_event_t *)&e);
fsm_clear(&sess->sm);
mme_bearer_remove_all(sess);

View File

@ -144,8 +144,8 @@ struct _mme_ue_t {
fsm_t sm; /* A state machine */
/* UE identity */
#define MME_UE_HAVE_IMSI(mme) \
((mme) && ((mme)->imsi_len))
#define MME_UE_HAVE_IMSI(__mME) \
((__mME) && ((__mME)->imsi_len))
c_uint8_t imsi[MAX_IMSI_LEN];
int imsi_len;
c_int8_t imsi_bcd[MAX_IMSI_BCD_LEN+1];
@ -164,14 +164,14 @@ struct _mme_ue_t {
e_cgi_t e_cgi;
plmn_id_t visited_plmn_id;
#define SECURITY_CONTEXT_IS_VALID(mme) \
((mme) && \
((mme)->security_context_available == 1) && ((mme)->mac_failed == 0))
#define CLEAR_SECURITY_CONTEXT(mme) \
#define SECURITY_CONTEXT_IS_VALID(__mME) \
((__mME) && \
((__mME)->security_context_available == 1) && ((__mME)->mac_failed == 0))
#define CLEAR_SECURITY_CONTEXT(__mME) \
do { \
d_assert((mme), break, "Null param"); \
(mme)->security_context_available = 0; \
(mme)->mac_failed = 0; \
d_assert((__mME), break, "Null param"); \
(__mME)->security_context_available = 0; \
(__mME)->mac_failed = 0; \
} while(0)
int security_context_available;
int mac_failed;
@ -215,10 +215,10 @@ struct _mme_ue_t {
#define MIN_EPS_BEARER_ID 5
#define MAX_EPS_BEARER_ID 15
#define CLEAR_EPS_BEARER_ID(mme) \
#define CLEAR_EPS_BEARER_ID(__mME) \
do { \
d_assert((mme), break, "Null param"); \
(mme)->ebi = MIN_EPS_BEARER_ID - 1; \
d_assert((__mME), break, "Null param"); \
(__mME)->ebi = MIN_EPS_BEARER_ID - 1; \
} while(0)
c_uint8_t ebi; /* EPS Bearer ID generator */
list_t sess_list;
@ -238,24 +238,10 @@ struct _mme_ue_t {
/* UE Radio Capability */
void *radio_capa;
#define MME_UE_DETACH_INITIATED(mme) \
((mme_ue) && (mme_ue)->detach_type.detach_type)
#define SET_DETACH_TYPE(mme, type) \
do { \
d_assert((mme), break, "Null param"); \
(mme)->detach_type = (type); \
} while(0)
#define CLEAR_DETACH_TYPE(mme) \
do { \
d_assert((mme), break, "Null param"); \
memset(&((mme)->detach_type), 0, sizeof(nas_detach_type_t)); \
} while(0)
/* Detach Request */
nas_detach_type_t detach_type;
};
#define MME_UE_IN_ATTACH_STATE(mme) \
((mme) && mme_sess_first(mme) && \
(mme_sess_next(mme_sess_first(mme)) == NULL))
typedef struct _mme_sess_t {
lnode_t node; /* A node of list_t */
index_t index; /* An index of this node */
@ -267,22 +253,22 @@ typedef struct _mme_sess_t {
list_t bearer_list;
/* Related Context */
#define MME_S11_PATH_IN_SESSION(session) \
#define MME_S11_PATH_IN_SESSION(__sESS) \
do { \
d_assert((session), return, "Null param"); \
(session)->sgw = mme_sgw_next((session)->sgw); \
if (!(session)->sgw) (session)->sgw = mme_sgw_first(); \
d_assert((session)->sgw, return, "Null param"); \
d_assert((__sESS), return, "Null param"); \
(__sESS)->sgw = mme_sgw_next((__sESS)->sgw); \
if (!(__sESS)->sgw) (__sESS)->sgw = mme_sgw_first(); \
d_assert((__sESS)->sgw, return, "Null param"); \
} while(0)
mme_sgw_t *sgw;
mme_ue_t *mme_ue;
#define MME_UE_HAVE_APN(mme) \
((mme) && (mme_sess_first(mme)) && \
((mme_sess_first(mme))->pdn))
#define MME_SESSION_GET_PGW_IPV4_ADDR(sess) \
(((sess) && ((sess)->pdn) && (((sess)->pdn)->pgw.ipv4_addr)) ? \
(((sess)->pdn)->pgw.ipv4_addr) : (mme_self()->s5c_addr))
#define MME_UE_HAVE_APN(__mME) \
((__mME) && (mme_sess_first(__mME)) && \
((mme_sess_first(__mME))->pdn))
#define MME_SESSION_GET_PGW_IPV4_ADDR(__sESS) \
(((__sESS) && ((__sESS)->pdn) && (((__sESS)->pdn)->pgw.ipv4_addr)) ? \
(((__sESS)->pdn)->pgw.ipv4_addr) : (mme_self()->s5c_addr))
pdn_t *pdn;
/* Protocol Configuration Options */
@ -298,19 +284,14 @@ typedef struct _mme_bearer_t {
c_uint8_t ebi; /* EPS Bearer ID */
#define MME_UE_HAVE_SESSION(mme) \
((mme) && (mme_sess_first(mme)) && \
(mme_default_bearer_in_sess(mme_sess_first(mme))) && \
((mme_default_bearer_in_sess(mme_sess_first(mme)))->sgw_s1u_teid) && \
((mme_default_bearer_in_sess(mme_sess_first(mme)))->sgw_s1u_addr))
#define MME_SESSION_IS_VALID(__sESS) \
((__sESS) && (mme_bearer_first(__sESS)) && \
((mme_default_bearer_in_sess(__sESS)->sgw_s1u_teid) && \
(mme_default_bearer_in_sess(__sESS)->sgw_s1u_addr)))
#define MME_UE_HAVE_DEFAULT_BEARER(mme) \
((mme) && (mme_sess_first(mme)) && \
(mme_default_bearer_in_sess(mme_sess_first(mme))) && \
((mme_default_bearer_in_sess(mme_sess_first(mme)))->enb_s1u_teid) && \
((mme_default_bearer_in_sess(mme_sess_first(mme)))->enb_s1u_addr) && \
((mme_default_bearer_in_sess(mme_sess_first(mme)))->sgw_s1u_teid) && \
((mme_default_bearer_in_sess(mme_sess_first(mme)))->sgw_s1u_addr))
#define MME_UE_HAVE_SESSION(__mME) \
((__mME) && (mme_sess_first(__mME)) && \
MME_SESSION_IS_VALID(mme_sess_first(__mME)))
c_uint32_t enb_s1u_teid;
c_uint32_t enb_s1u_addr;
c_uint32_t sgw_s1u_teid;

View File

@ -2,6 +2,7 @@
#define __MME_EVENT_H__
#include "core_event.h"
#include "core_fsm.h"
#include "core_pkbuf.h"
#ifdef __cplusplus

View File

@ -118,35 +118,44 @@ void mme_s11_handle_create_session_response(
d_assert(rv == CORE_OK, return, "xact_commit error");
}
void mme_s11_handle_delete_all_sessions_request_in_ue(mme_ue_t *mme_ue)
void mme_s11_handle_delete_all_sessions_in_ue(mme_ue_t *mme_ue)
{
status_t rv;
pkbuf_t *s11buf = NULL;
mme_sess_t *sess = NULL;
mme_sess_t *sess = NULL, *next_sess = NULL;
d_assert(mme_ue, return, "Null param");
sess = mme_sess_first(mme_ue);
while (sess != NULL)
{
gtp_header_t h;
gtp_xact_t *xact = NULL;
next_sess = mme_sess_next(sess);
memset(&h, 0, sizeof(gtp_header_t));
h.type = GTP_DELETE_SESSION_REQUEST_TYPE;
h.teid = mme_ue->sgw_s11_teid;
if (MME_SESSION_IS_VALID(sess))
{
gtp_header_t h;
gtp_xact_t *xact = NULL;
rv = mme_s11_build_delete_session_request(&s11buf, h.type, sess);
d_assert(rv == CORE_OK, return, "S11 build error");
memset(&h, 0, sizeof(gtp_header_t));
h.type = GTP_DELETE_SESSION_REQUEST_TYPE;
h.teid = mme_ue->sgw_s11_teid;
xact = gtp_xact_local_create(sess->sgw, &h, s11buf);
d_assert(xact, return, "Null param");
rv = mme_s11_build_delete_session_request(&s11buf, h.type, sess);
d_assert(rv == CORE_OK, return, "S11 build error");
GTP_XACT_STORE_SESSION(xact, sess);
xact = gtp_xact_local_create(sess->sgw, &h, s11buf);
d_assert(xact, return, "Null param");
rv = gtp_xact_commit(xact);
d_assert(rv == CORE_OK, return, "xact_commit error");
GTP_XACT_STORE_SESSION(xact, sess);
sess = mme_sess_next(sess);
rv = gtp_xact_commit(xact);
d_assert(rv == CORE_OK, return, "xact_commit error");
}
else
{
mme_sess_remove(sess);
}
sess = next_sess;
}
}

View File

@ -12,8 +12,7 @@ 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);
CORE_DECLARE(void) mme_s11_handle_delete_all_sessions_request_in_ue(
mme_ue_t *mme_ue);
CORE_DECLARE(void) mme_s11_handle_delete_all_sessions_in_ue(mme_ue_t *mme_ue);
CORE_DECLARE(void) mme_s11_handle_delete_session_response(
gtp_xact_t *xact, mme_ue_t *mme_ue, gtp_delete_session_response_t *rsp);

View File

@ -34,8 +34,6 @@ void mme_state_final(fsm_t *s, event_t *e)
d_assert(s, return, "Null param");
}
int test = 0;
void mme_state_operational(fsm_t *s, event_t *e)
{
status_t rv;
@ -113,11 +111,7 @@ void mme_state_operational(fsm_t *s, event_t *e)
}
case MME_EVT_S1AP_LO_CONNREFUSED:
{
index_t index = event_get_param1(e);
mme_enb_t *enb = NULL;
d_assert(index, break, "Null param");
enb = mme_enb_find(index);
mme_enb_t *enb = mme_enb_find(event_get_param1(e));
if (enb)
{
d_trace(1, "eNB-S1[%x] connection refused!!!\n",
@ -134,12 +128,11 @@ void mme_state_operational(fsm_t *s, event_t *e)
case MME_EVT_S1AP_MESSAGE:
{
s1ap_message_t message;
index_t index = event_get_param1(e);
mme_enb_t *enb = NULL;
pkbuf_t *pkbuf = NULL;
d_assert(index, break, "Null param");
d_assert(enb = mme_enb_find(index), break, "No eNB context");
enb = mme_enb_find(event_get_param1(e));
d_assert(enb, break, "No eNB context");
d_assert(FSM_STATE(&enb->sm), break, "No S1AP State Machine");
pkbuf = (pkbuf_t *)event_get_param2(e);
@ -157,14 +150,13 @@ void mme_state_operational(fsm_t *s, event_t *e)
case MME_EVT_EMM_MESSAGE:
{
nas_message_t message;
index_t index = event_get_param1(e);
pkbuf_t *pkbuf = (pkbuf_t *)event_get_param3(e);
pkbuf_t *pkbuf = NULL;
enb_ue_t *enb_ue = NULL;
mme_ue_t *mme_ue = NULL;
enb_ue = enb_ue_find(index);
enb_ue = enb_ue_find(event_get_param1(e));
d_assert(enb_ue, break, "No ENB UE context");
pkbuf = (pkbuf_t *)event_get_param3(e);
d_assert(pkbuf, break, "Null param");
d_assert(nas_emm_decode(&message, pkbuf) == CORE_OK,
pkbuf_free(pkbuf); break, "Can't decode NAS_EMM");
@ -220,11 +212,7 @@ void mme_state_operational(fsm_t *s, event_t *e)
}
case MME_EVT_EMM_T3413:
{
index_t index = event_get_param1(e);
mme_ue_t *mme_ue = NULL;
d_assert(index, break, "Null param");
mme_ue = mme_ue_find(index);
mme_ue_t *mme_ue = mme_ue_find(event_get_param1(e));
d_assert(mme_ue, break, "No UE context");
d_assert(FSM_STATE(&mme_ue->sm), break, "No EMM State Machine");
@ -235,13 +223,11 @@ void mme_state_operational(fsm_t *s, event_t *e)
case MME_EVT_ESM_MESSAGE:
{
nas_message_t message;
index_t index = event_get_param1(e);
mme_sess_t *sess = NULL;
mme_ue_t *mme_ue = NULL;
pkbuf_t *pkbuf = NULL;
d_assert(index, break, "Null param");
sess = mme_sess_find(index);
sess = mme_sess_find(event_get_param1(e));
d_assert(sess, break, "No Session context");
d_assert(mme_ue = sess->mme_ue, break, "No UE context");
d_assert(FSM_STATE(&sess->sm), break, "No ESM State Machine");
@ -259,6 +245,72 @@ void mme_state_operational(fsm_t *s, event_t *e)
break;
}
case MME_EVT_S6A_MESSAGE:
{
mme_ue_t *mme_ue = mme_ue_find(event_get_param1(e));
pkbuf_t *s6abuf = (pkbuf_t *)event_get_param2(e);
s6a_message_t *s6a_message = NULL;
d_assert(mme_ue, return, "Null param");
d_assert(s6abuf, return, "Null param");
s6a_message = s6abuf->payload;
d_assert(s6a_message, return, "Null param");
switch(s6a_message->cmd_code)
{
case S6A_CMD_CODE_AUTHENTICATION_INFORMATION:
{
if (s6a_message->result_code != ER_DIAMETER_SUCCESS)
{
emm_handle_attach_reject(mme_ue,
S1ap_CauseNas_authentication_failure,
EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
FSM_TRAN(&mme_ue->sm, emm_state_detached);
break;
}
mme_s6a_handle_aia(mme_ue, &s6a_message->aia_message);
break;
}
case S6A_CMD_CODE_UPDATE_LOCATION:
{
if (s6a_message->result_code != ER_DIAMETER_SUCCESS)
{
emm_handle_attach_reject(mme_ue,
S1ap_CauseNas_unspecified,
EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
FSM_TRAN(&mme_ue->sm, emm_state_detached);
break;
}
mme_s6a_handle_ula(mme_ue, &s6a_message->ula_message);
if (FSM_CHECK(&mme_ue->sm, emm_state_default_esm))
{
event_emm_to_esm(mme_ue,
&mme_ue->last_pdn_connectivity_request);
}
else if (FSM_CHECK(&mme_ue->sm, emm_state_attached))
{
d_error("Not implemented for Tracking Area Update");
}
else
d_assert(0,, "Invaild EMM state");
break;
}
default:
{
d_error("Invalid type(%d)", event_get_param2(e));
break;
}
}
pkbuf_free(s6abuf);
break;
}
case MME_EVT_S11_MESSAGE:
{
status_t rv;
@ -288,14 +340,18 @@ void mme_state_operational(fsm_t *s, event_t *e)
{
mme_s11_handle_create_session_response(
xact, mme_ue, &message.create_session_response);
if (MME_UE_IN_ATTACH_STATE(mme_ue))
if (FSM_CHECK(&mme_ue->sm, emm_state_default_esm))
{
emm_handle_attach_accept(mme_ue);
}
else
else if (FSM_CHECK(&mme_ue->sm, emm_state_attached))
{
d_error("Not implemented of multiple PDN");
d_assert(0, , "Coming Soon!");
}
else
d_assert(0, break, "Invalid EMM state");
break;
}
case GTP_MODIFY_BEARER_RESPONSE_TYPE:
@ -307,41 +363,26 @@ void mme_state_operational(fsm_t *s, event_t *e)
mme_s11_handle_delete_session_response(
xact, mme_ue, &message.delete_session_response);
if (MME_UE_DETACH_INITIATED(mme_ue))
{
/* Detach Request is Initiated */
if (mme_sess_first(mme_ue) == NULL)
{
/* All session is deleted */
emm_handle_detach_accept(mme_ue);
}
else
{
d_trace(3, "wait to delete all sessions"
"in detach state\n");
}
}
else
if (FSM_CHECK(&mme_ue->sm, emm_state_auth))
{
if (mme_sess_first(mme_ue) == NULL)
{
/* If no session, it menas UE try to attach */
mme_s6a_send_air(mme_ue);
}
else
}
else if (FSM_CHECK(&mme_ue->sm, emm_state_detached))
{
if (mme_sess_first(mme_ue) == NULL)
{
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
{
/* PDN Disconnect Request */
d_error("Not implemented of multiple PDN");
}
else
{
d_trace(3, "wait to delete all sessions"
"in no security context\n");
}
emm_handle_detach_accept(mme_ue);
}
}
else if (FSM_CHECK(&mme_ue->sm, emm_state_attached))
{
d_assert(0, , "Coming Soon!");
}
else
d_assert(0, break, "Invalid EMM state");
break;
}
@ -377,74 +418,6 @@ void mme_state_operational(fsm_t *s, event_t *e)
gtp_xact_timeout(event_get_param1(e), event_get(e));
break;
}
case MME_EVT_S6A_MESSAGE:
{
index_t index = event_get_param1(e);
mme_ue_t *mme_ue = NULL;
pkbuf_t *s6abuf = (pkbuf_t *)event_get_param2(e);
s6a_message_t *s6a_message = NULL;
d_assert(index, return, "Null param");
mme_ue = mme_ue_find(index);
d_assert(mme_ue, return, "Null param");
d_assert(s6abuf, return, "Null param");
s6a_message = s6abuf->payload;
d_assert(s6a_message, return, "Null param");
switch(s6a_message->cmd_code)
{
case S6A_CMD_CODE_AUTHENTICATION_INFORMATION:
{
if (s6a_message->result_code != ER_DIAMETER_SUCCESS)
{
emm_handle_attach_reject(mme_ue,
S1ap_CauseNas_authentication_failure,
EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
break;
}
mme_s6a_handle_aia(mme_ue, &s6a_message->aia_message);
break;
}
case S6A_CMD_CODE_UPDATE_LOCATION:
{
if (s6a_message->result_code != ER_DIAMETER_SUCCESS)
{
emm_handle_attach_reject(mme_ue,
S1ap_CauseNas_unspecified,
EMM_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED,
ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
break;
}
mme_s6a_handle_ula(mme_ue, &s6a_message->ula_message);
if (MME_UE_HAVE_DEFAULT_BEARER(mme_ue))
{
/* if there is default bearer, UE attached completely */
d_error("Not implemented for Tracking Area Update");
}
else
{
event_emm_to_esm(mme_ue,
&mme_ue->last_pdn_connectivity_request);
}
break;
}
default:
{
d_error("Invalid type(%d)", event_get_param2(e));
break;
}
}
pkbuf_free(s6abuf);
break;
}
default:
{
d_error("No handler for event %s", mme_event_get_name(e));

View File

@ -21,7 +21,11 @@ void s1ap_state_exception(fsm_t *s, event_t *e);
void emm_state_initial(fsm_t *s, event_t *e);
void emm_state_final(fsm_t *s, event_t *e);
void emm_state_operational(fsm_t *s, event_t *e);
void emm_state_detached(fsm_t *s, event_t *e);
void emm_state_identity(fsm_t *s, event_t *e);
void emm_state_auth(fsm_t *s, event_t *e);
void emm_state_default_esm(fsm_t *s, event_t *e);
void emm_state_attached(fsm_t *s, event_t *e);
void emm_state_exception(fsm_t *s, event_t *e);
void esm_state_initial(fsm_t *s, event_t *e);

View File

@ -28,11 +28,16 @@ void s1ap_state_final(fsm_t *s, event_t *e)
void s1ap_state_operational(fsm_t *s, event_t *e)
{
mme_enb_t *enb = NULL;
d_assert(s, return, "Null param");
d_assert(e, return, "Null param");
mme_sm_trace(3, e);
enb = mme_enb_find(event_get_param1(e));
d_assert(enb, return, "Null param");
switch (event_get(e))
{
case FSM_ENTRY_SIG:
@ -45,15 +50,7 @@ void s1ap_state_operational(fsm_t *s, event_t *e)
}
case MME_EVT_S1AP_MESSAGE:
{
index_t index = event_get_param1(e);
mme_enb_t *enb = NULL;
s1ap_message_t *message = NULL;
d_assert(index, return, "Null param");
enb = mme_enb_find(index);
d_assert(enb, return, "Null param");
message = (s1ap_message_t *)event_get_param3(e);
s1ap_message_t *message = (s1ap_message_t *)event_get_param3(e);
d_assert(message, break, "Null param");
switch(message->direction)

View File

@ -91,11 +91,11 @@ typedef struct _pgw_sess_t {
list_t bearer_list;
/* Related Context */
#define PGW_S5C_PATH_IN_SESSION(session, xaction) \
#define PGW_S5C_PATH_IN_SESSION(__sESS, __xACT) \
do { \
d_assert((session), return, "Null param"); \
d_assert((xaction), return, "Null param"); \
(session)->sgw = (xaction)->gnode; \
d_assert((__sESS), return, "Null param"); \
d_assert((__xACT), return, "Null param"); \
(__sESS)->sgw = (__xACT)->gnode; \
} while(0)
pgw_sgw_t *sgw;
} pgw_sess_t;

View File

@ -2,6 +2,7 @@
#define __PGW_EVENT_H__
#include "core_event.h"
#include "core_fsm.h"
#ifdef __cplusplus
extern "C" {

View File

@ -83,18 +83,18 @@ typedef struct _sgw_sess_t {
list_t bearer_list;
/* Related Context */
#define SGW_S11_PATH_IN_SESSION(session, xaction) \
#define SGW_S11_PATH_IN_SESSION(__sESS, __xACT) \
do { \
d_assert((session), return, "Null param"); \
d_assert((xaction), return, "Null param"); \
(session)->mme = (xaction)->gnode; \
d_assert((__sESS), return, "Null param"); \
d_assert((__xACT), return, "Null param"); \
(__sESS)->mme = (__xACT)->gnode; \
} while(0)
sgw_mme_t *mme;
#define SGW_S5C_PATH_IN_SESSION(session, gnode) \
#define SGW_S5C_PATH_IN_SESSION(__sESS, __gNODE) \
do { \
d_assert((session), return, "Null param"); \
d_assert((gnode), return, "Null param"); \
(session)->pgw = gnode; \
d_assert((__sESS), return, "Null param"); \
d_assert((__gNODE), return, "Null param"); \
(__sESS)->pgw = __gNODE; \
} while(0)
sgw_mme_t *pgw;
sgw_ue_t *sgw_ue;
@ -132,14 +132,14 @@ typedef struct _sgw_bearer_t {
#define SGW_DL_NOTI_SENT 0x0001
#define CHECK_DL_NOTI_SENT(bearer) ((bearer)->state & SGW_DL_NOTI_SENT)
#define SET_DL_NOTI_SENT(bearer) \
#define CHECK_DL_NOTI_SENT(__bEARER) ((__bEARER)->state & SGW_DL_NOTI_SENT)
#define SET_DL_NOTI_SENT(__bEARER) \
do { \
(bearer)->state |= SGW_DL_NOTI_SENT;\
(__bEARER)->state |= SGW_DL_NOTI_SENT;\
} while (0)
#define RESET_DL_NOTI_SENT(bearer) \
#define RESET_DL_NOTI_SENT(__bEARER) \
do { \
(bearer)->state &= ~SGW_DL_NOTI_SENT;\
(__bEARER)->state &= ~SGW_DL_NOTI_SENT;\
} while (0)
CORE_DECLARE(status_t) sgw_context_init(void);

View File

@ -2,6 +2,7 @@
#define __SGW_EVENT_H__
#include "core_event.h"
#include "core_fsm.h"
#ifdef __cplusplus
extern "C" {

View File

@ -301,6 +301,18 @@ static void attach_test1(abts_case *tc, void *data)
rc = tests1ap_enb_read(sock, recvbuf);
pkbuf_free(recvbuf);
/* Send Attach Complete +
* Activate Default EPS Bearer Context Accept */
rv = tests1ap_build_attach_complete(&sendbuf, msgindex+1);
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);
pkbuf_free(recvbuf);
/* Send Detach Request */
rv = tests1ap_build_detach_request(&sendbuf, msgindex);
ABTS_INT_EQUAL(tc, CORE_OK, rv);
@ -570,6 +582,18 @@ static void attach_test2(abts_case *tc, void *data)
rc = tests1ap_enb_read(sock, recvbuf);
pkbuf_free(recvbuf);
/* Send Attach Complete +
* Activate Default EPS Bearer Context Accept */
rv = tests1ap_build_attach_complete(&sendbuf, msgindex+1);
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);
pkbuf_free(recvbuf);
/*****************************************************************
* Attach Request : IMSI, Integrity Protected, MAC Failed
* Send Initial-UE Message + Attach Request + PDN Connectivity */

View File

@ -490,11 +490,16 @@ status_t tests1ap_build_attach_complete(pkbuf_t **pkbuf, int i)
"403a000005000000 05c00100009d0008 00020001001a000e 0d27c183eb950207"
"4300035200c20064 40080000f1101079 baf0004340060000 f1105ba0",
"",
"000d"
"403a000005000000 05c00100009e0008 00020002001a000e 0d27e8a2a3f10207"
"4300035200c20064 40080000f1101079 baf0004340060000 f1105ba0",
"",
"",
"",
"000d"
"403a000005000000 05c0010000020008 00020011001a000e 0d27225d92bb0207"
"4300035200c20064 40080000f1101079 baf0004340060000 f1105ba0",
"",
"000d"
@ -506,11 +511,11 @@ status_t tests1ap_build_attach_complete(pkbuf_t **pkbuf, int i)
};
c_uint16_t len[TESTS1AP_MAX_MESSAGE] = {
62,
0,
62,
0,
0,
0,
62,
0,
62,