diff --git a/src/mme/Makefile.am b/src/mme/Makefile.am index 6ec9093ab..1cb7e2990 100644 --- a/src/mme/Makefile.am +++ b/src/mme/Makefile.am @@ -6,17 +6,17 @@ libmme_la_SOURCES = \ kdf.h kasumi.h snow_3g.h zuc.h \ event.h context.h \ s1ap_build.h s1ap_handler.h s1ap_conv.h s1ap_path.h \ - nas_conv.h nas_security.h emm_handler.h \ + nas_conv.h nas_security.h emm_handler.h esm_handler.h \ s11_path.h s11_build.h \ sm.h s6a_sm.h nodist_libmme_la_SOURCES = \ kdf.c kasumi.c snow_3g.c zuc.c \ init.c event.c context.c \ - s1ap_build.c s1ap_handler.c s1ap_conv.c s1ap_path.c \ - nas_conv.c nas_security.c emm_handler.c \ - s11_path.c s11_build.c \ - mme_sm.c enb_s1ap_sm.c ue_emm_sm.c s6a_sm.c + s1ap_sm.c s1ap_build.c s1ap_handler.c s1ap_conv.c s1ap_path.c \ + nas_conv.c nas_security.c emm_sm.c emm_handler.c esm_sm.c esm_handler.c \ + s11_path.c s11_build.c s11_sm.c \ + mme_sm.c s6a_sm.c libmme_la_DEPENDENCIES = \ $(top_srcdir)/lib/core/src/libcore.la \ diff --git a/src/mme/context.c b/src/mme/context.c index e6c44b201..7d6703701 100644 --- a/src/mme/context.c +++ b/src/mme/context.c @@ -288,6 +288,17 @@ status_t mme_ctx_ue_remove(ue_ctx_t *ue) mme_ctx_rab_remove_all(ue); + if (FSM_STATE(&ue->emm_sm)) + { + fsm_final((fsm_t*)&ue->emm_sm, 0); + fsm_clear((fsm_t*)&ue->emm_sm); + } + if (FSM_STATE(&ue->esm_sm)) + { + fsm_final((fsm_t*)&ue->esm_sm, 0); + fsm_clear((fsm_t*)&ue->esm_sm); + } + list_remove(&ue->enb->ue_list, ue); pool_free_node(&ue_pool, ue); diff --git a/src/mme/context.h b/src/mme/context.h index 2f7396cdc..ff7ae5dea 100644 --- a/src/mme/context.h +++ b/src/mme/context.h @@ -81,7 +81,7 @@ typedef struct _enb_ctx_t { c_uint32_t enb_id; /** eNB_ID received from eNB */ - enb_s1ap_sm_t s1ap_sm; + s1ap_sm_t s1ap_sm; net_sock_t *s1ap_sock; ue_list_t ue_list; @@ -92,7 +92,8 @@ typedef struct _ue_ctx_t { lnode_t node; /**< A node of list_t */ /* State Machine */ - ue_emm_sm_t emm_sm; + emm_sm_t emm_sm; + esm_sm_t esm_sm; /* UE identity */ c_uint32_t enb_ue_s1ap_id; /** eNB-UE-S1AP-ID received from eNB */ diff --git a/src/mme/ue_emm_sm.c b/src/mme/emm_sm.c similarity index 90% rename from src/mme/ue_emm_sm.c rename to src/mme/emm_sm.c index a5fae6f55..8c54c2c38 100644 --- a/src/mme/ue_emm_sm.c +++ b/src/mme/emm_sm.c @@ -1,4 +1,4 @@ -#define TRACE_MODULE _ue_emm_sm +#define TRACE_MODULE _emm_sm #include "core_debug.h" @@ -8,23 +8,23 @@ #include "nas_security.h" #include "emm_handler.h" -void ue_emm_state_initial(ue_emm_sm_t *s, event_t *e) +void emm_state_initial(emm_sm_t *s, event_t *e) { d_assert(s, return, "Null param"); mme_sm_trace(1, e); - FSM_TRAN(s, &ue_emm_state_operational); + FSM_TRAN(s, &emm_state_operational); } -void ue_emm_state_final(ue_emm_sm_t *s, event_t *e) +void emm_state_final(emm_sm_t *s, event_t *e) { d_assert(s, return, "Null param"); mme_sm_trace(1, e); } -void ue_emm_state_operational(ue_emm_sm_t *s, event_t *e) +void emm_state_operational(emm_sm_t *s, event_t *e) { d_assert(s, return, "Null param"); d_assert(e, return, "Null param"); @@ -108,7 +108,7 @@ void ue_emm_state_operational(ue_emm_sm_t *s, event_t *e) } } -void ue_emm_state_exception(ue_emm_sm_t *s, event_t *e) +void emm_state_exception(emm_sm_t *s, event_t *e) { d_assert(s, return, "Null param"); d_assert(e, return, "Null param"); diff --git a/src/mme/esm_handler.c b/src/mme/esm_handler.c new file mode 100644 index 000000000..a7f9af761 --- /dev/null +++ b/src/mme/esm_handler.c @@ -0,0 +1,12 @@ +#define TRACE_MODULE _esm_handler + +#include "core_debug.h" + +#include "nas_message.h" + +#include "event.h" + +#include "kdf.h" +#include "nas_security.h" +#include "nas_conv.h" +#include "s6a_sm.h" diff --git a/src/mme/esm_handler.h b/src/mme/esm_handler.h new file mode 100644 index 000000000..7435723d7 --- /dev/null +++ b/src/mme/esm_handler.h @@ -0,0 +1,16 @@ +#ifndef __ESM_HANDLER_H__ +#define __ESM_HANDLER_H__ + +#include "nas_message.h" + +#include "context.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __ESM_HANDLER_H__ */ diff --git a/src/mme/esm_sm.c b/src/mme/esm_sm.c new file mode 100644 index 000000000..34e84bf7e --- /dev/null +++ b/src/mme/esm_sm.c @@ -0,0 +1,109 @@ +#define TRACE_MODULE _esm_sm + +#include "core_debug.h" + +#include "nas_message.h" + +#include "event.h" +#include "nas_security.h" +#include "emm_handler.h" + +void esm_state_initial(esm_sm_t *s, event_t *e) +{ + d_assert(s, return, "Null param"); + + mme_sm_trace(1, e); + + FSM_TRAN(s, &esm_state_operational); +} + +void esm_state_final(esm_sm_t *s, event_t *e) +{ + d_assert(s, return, "Null param"); + + mme_sm_trace(1, e); +} + +void esm_state_operational(esm_sm_t *s, event_t *e) +{ + d_assert(s, return, "Null param"); + d_assert(e, return, "Null param"); + + ue_ctx_t *ue = s->ctx; + d_assert(ue, return, "Null param"); + + mme_sm_trace(1, e); + + switch (event_get(e)) + { + case FSM_ENTRY_SIG: + { + break; + } + case FSM_EXIT_SIG: + { + break; + } + case EVT_MSG_UE_EMM: + { + nas_message_t message; + status_t rv; + pkbuf_t *recvbuf = (pkbuf_t *)event_get_param2(e); + d_assert(recvbuf, break, "Null param"); + + rv = nas_security_decode(&message, ue, recvbuf); + if (rv != CORE_OK) + { + d_error("Can't parse NAS_PDU"); + break; + } + + switch(message.h.message_type) + { + case NAS_PDN_CONNECTIVITY_REQUEST: + { + break; + } + default: + { + d_warn("Not implemented(type:%d)", message.h.message_type); + break; + } + } + + pkbuf_free(recvbuf); + break; + } + + default: + { + d_error("Unknown event %s", mme_event_get_name(e)); + break; + } + } +} + +void esm_state_exception(esm_sm_t *s, event_t *e) +{ + d_assert(s, return, "Null param"); + d_assert(e, return, "Null param"); + + mme_sm_trace(1, 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; + } + } +} diff --git a/src/mme/event.c b/src/mme/event.c index f3b496c61..4d27f3ae4 100644 --- a/src/mme/event.c +++ b/src/mme/event.c @@ -13,6 +13,7 @@ static char EVT_NAME_LO_ENB_S1AP_CONNREFUSED[] = "LO_ENB_S1AP_CONNREFUSED"; static char EVT_NAME_MSG_ENB_S1AP[] = "MSG_ENB_S1AP"; static char EVT_NAME_MSG_UE_EMM[] = "MSG_UE_EMM"; +static char EVT_NAME_MSG_UE_ESM[] = "MSG_UE_ESM"; static char EVT_NAME_MSG_MME_S11[] = "MSG_MME_S11"; char* mme_event_get_name(event_t *e) @@ -39,6 +40,8 @@ char* mme_event_get_name(event_t *e) return EVT_NAME_MSG_ENB_S1AP; case EVT_MSG_UE_EMM: return EVT_NAME_MSG_UE_EMM; + case EVT_MSG_UE_ESM: + return EVT_NAME_MSG_UE_ESM; case EVT_MSG_MME_S11: return EVT_NAME_MSG_MME_S11; diff --git a/src/mme/event.h b/src/mme/event.h index 0e5cd8a5c..a224b4a05 100644 --- a/src/mme/event.h +++ b/src/mme/event.h @@ -22,6 +22,7 @@ typedef enum { EVT_MSG_ENB_S1AP, EVT_MSG_UE_EMM, + EVT_MSG_UE_ESM, EVT_MSG_MME_S11, MME_EVT_TOP, diff --git a/src/mme/mme_sm.c b/src/mme/mme_sm.c index 953769c6d..9333d42ac 100644 --- a/src/mme/mme_sm.c +++ b/src/mme/mme_sm.c @@ -89,7 +89,7 @@ void mme_state_operational(mme_sm_t *s, event_t *e) enb->s1ap_sock = sock; fsm_create((fsm_t*)&enb->s1ap_sm, - enb_s1ap_state_initial, enb_s1ap_state_final); + s1ap_state_initial, s1ap_state_final); enb->s1ap_sm.ctx = enb; fsm_init((fsm_t*)&enb->s1ap_sm, 0); } @@ -132,6 +132,16 @@ void mme_state_operational(mme_sm_t *s, event_t *e) break; } + case EVT_MSG_UE_ESM: + { + ue_ctx_t *ue = (ue_ctx_t *)event_get_param1(e); + d_assert(ue, break, "Null param"); + + d_assert(FSM_STATE(&ue->esm_sm), break, "Null param"); + fsm_dispatch((fsm_t*)&ue->esm_sm, (fsm_event_t*)e); + + break; + } case EVT_MSG_MME_S11: { net_sock_t *sock = (net_sock_t *)event_get_param1(e); diff --git a/src/mme/s1ap_handler.c b/src/mme/s1ap_handler.c index 09d8d6bbc..eb63ebe0f 100644 --- a/src/mme/s1ap_handler.c +++ b/src/mme/s1ap_handler.c @@ -90,11 +90,15 @@ void s1ap_handle_initial_ue_message(enb_ctx_t *enb, s1ap_message_t *message) enb->enb_id); fsm_create((fsm_t*)&ue->emm_sm, - ue_emm_state_initial, ue_emm_state_final); + emm_state_initial, emm_state_final); ue->emm_sm.ctx = ue; - fsm_init((fsm_t*)&ue->emm_sm, 0); + fsm_create((fsm_t*)&ue->esm_sm, + esm_state_initial, esm_state_final); + ue->esm_sm.ctx = ue; + fsm_init((fsm_t*)&ue->esm_sm, 0); + mme_event_s1ap_to_nas(ue, &ies->nas_pdu); } diff --git a/src/mme/enb_s1ap_sm.c b/src/mme/s1ap_sm.c similarity index 91% rename from src/mme/enb_s1ap_sm.c rename to src/mme/s1ap_sm.c index c74514f9c..1d0fb0336 100644 --- a/src/mme/enb_s1ap_sm.c +++ b/src/mme/s1ap_sm.c @@ -1,4 +1,4 @@ -#define TRACE_MODULE _enb_s1_sm +#define TRACE_MODULE _s1ap_sm #include "core_debug.h" @@ -7,23 +7,23 @@ #include "s1ap_build.h" #include "s1ap_handler.h" -void enb_s1ap_state_initial(enb_s1ap_sm_t *s, event_t *e) +void s1ap_state_initial(s1ap_sm_t *s, event_t *e) { d_assert(s, return, "Null param"); mme_sm_trace(1, e); - FSM_TRAN(s, &enb_s1ap_state_operational); + FSM_TRAN(s, &s1ap_state_operational); } -void enb_s1ap_state_final(enb_s1ap_sm_t *s, event_t *e) +void s1ap_state_final(s1ap_sm_t *s, event_t *e) { d_assert(s, return, "Null param"); mme_sm_trace(1, e); } -void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e) +void s1ap_state_operational(s1ap_sm_t *s, event_t *e) { d_assert(s, return, "Null param"); d_assert(e, return, "Null param"); @@ -123,7 +123,7 @@ void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e) } } -void enb_s1ap_state_exception(enb_s1ap_sm_t *s, event_t *e) +void s1ap_state_exception(s1ap_sm_t *s, event_t *e) { d_assert(s, return, "Null param"); d_assert(e, return, "Null param"); diff --git a/src/mme/sm.h b/src/mme/sm.h index a7c1505d1..1a80071e2 100644 --- a/src/mme/sm.h +++ b/src/mme/sm.h @@ -19,25 +19,45 @@ void mme_state_final(mme_sm_t *s, event_t *e); void mme_state_operational(mme_sm_t *s, event_t *e); void mme_state_exception(mme_sm_t *s, event_t *e); -typedef struct _enb_s1ap_sm_t { +typedef struct _s1ap_sm_t { fsm_t fsm; void *ctx; -} enb_s1ap_sm_t; +} s1ap_sm_t; -void enb_s1ap_state_initial(enb_s1ap_sm_t *s, event_t *e); -void enb_s1ap_state_final(enb_s1ap_sm_t *s, event_t *e); -void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e); -void enb_s1ap_state_exception(enb_s1ap_sm_t *s, event_t *e); +void s1ap_state_initial(s1ap_sm_t *s, event_t *e); +void s1ap_state_final(s1ap_sm_t *s, event_t *e); +void s1ap_state_operational(s1ap_sm_t *s, event_t *e); +void s1ap_state_exception(s1ap_sm_t *s, event_t *e); -typedef struct _ue_emm_sm_t { +typedef struct _emm_sm_t { fsm_t fsm; void *ctx; -} ue_emm_sm_t; +} emm_sm_t; -void ue_emm_state_initial(ue_emm_sm_t *s, event_t *e); -void ue_emm_state_final(ue_emm_sm_t *s, event_t *e); -void ue_emm_state_operational(ue_emm_sm_t *s, event_t *e); -void ue_emm_state_exception(ue_emm_sm_t *s, event_t *e); +void emm_state_initial(emm_sm_t *s, event_t *e); +void emm_state_final(emm_sm_t *s, event_t *e); +void emm_state_operational(emm_sm_t *s, event_t *e); +void emm_state_exception(emm_sm_t *s, event_t *e); + +typedef struct _esm_sm_t { + fsm_t fsm; + void *ctx; +} esm_sm_t; + +void esm_state_initial(esm_sm_t *s, event_t *e); +void esm_state_final(esm_sm_t *s, event_t *e); +void esm_state_operational(esm_sm_t *s, event_t *e); +void esm_state_exception(esm_sm_t *s, event_t *e); + +typedef struct _s11_sm_t { + fsm_t fsm; + void *ctx; +} s11_sm_t; + +void s11_state_initial(s11_sm_t *s, event_t *e); +void s11_state_final(s11_sm_t *s, event_t *e); +void s11_state_operational(s11_sm_t *s, event_t *e); +void s11_state_exception(s11_sm_t *s, event_t *e); #define mme_sm_print(__pe) \ d_print("%s(): %s\n", __func__, mme_event_get_name(__pe))