diff --git a/src/mme/Makefile.am b/src/mme/Makefile.am index 0692463985..80c7210fed 100644 --- a/src/mme/Makefile.am +++ b/src/mme/Makefile.am @@ -12,7 +12,7 @@ nodist_libmme_la_SOURCES = \ init.c event.c context.c \ s1ap_build.c s1ap_conv.c s1ap_path.c \ s6a_init.c s6a_auth_info.c \ - mme_sm.c enb_s1ap_sm.c + mme_sm.c enb_s1ap_sm.c ue_emm_sm.c libmme_la_DEPENDENCIES = \ $(top_srcdir)/lib/core/src/libcore.la \ diff --git a/src/mme/context.h b/src/mme/context.h index ff11243ec1..46c0820584 100644 --- a/src/mme/context.h +++ b/src/mme/context.h @@ -65,6 +65,8 @@ typedef struct _ue_ctx_t { c_uint32_t enb_ue_s1ap_id; /** eNB-UE-S1AP-ID received from eNB */ c_uint32_t mme_ue_s1ap_id; /** MME-UE-S1AP-ID received from MME */ + ue_emm_sm_t emm_sm; + rab_list_t rab_list; enb_ctx_t *enb; diff --git a/src/mme/enb_s1ap_sm.c b/src/mme/enb_s1ap_sm.c index edd2347928..ebb19f41fd 100644 --- a/src/mme/enb_s1ap_sm.c +++ b/src/mme/enb_s1ap_sm.c @@ -12,8 +12,6 @@ static status_t enb_s1ap_handle_s1setuprequest( enb_ctx_t *enb, s1ap_message *message); -static status_t enb_s1ap_handle_initialuemessage( - enb_ctx_t *enb, s1ap_message *message); void enb_s1ap_state_initial(enb_s1ap_sm_t *s, event_t *e) { @@ -77,7 +75,55 @@ void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e) } case S1ap_ProcedureCode_id_initialUEMessage : { - enb_s1ap_handle_initialuemessage(enb, &message); + ue_ctx_t *ue = NULL; + S1ap_InitialUEMessage_IEs_t *ies = NULL; + S1ap_NAS_PDU_t *nasPdu = NULL; + event_t e; + pkbuf_t *sendbuf = NULL; + + ies = &message.s1ap_InitialUEMessage_IEs; + d_assert(ies, break, "Null param"); + + nasPdu = &ies->nas_pdu; + d_assert(nasPdu, break, "Null param"); + + sendbuf = pkbuf_alloc(0, nasPdu->size); + d_assert(sendbuf, break, "Null param"); + memcpy(sendbuf->payload, nasPdu->buf, nasPdu->size); + + ue = mme_ctx_ue_find_by_enb_ue_s1ap_id( + enb, ies->eNB_UE_S1AP_ID); + if (!ue) + { + ue = mme_ctx_ue_add(enb); + d_assert(ue, break, "Null param"); + + ue->enb_ue_s1ap_id = ies->eNB_UE_S1AP_ID; + } + else + { + d_warn("Duplicated: eNB[0x%x] sends " + "Initial-UE Message[eNB-UE-S1AP-ID(%d)]", + enb->enb_id, ue->enb_ue_s1ap_id); + } + + d_info("eNB[0x%x] sends " + "Initial-UE Message[eNB-UE-S1AP-ID(%d)]", + enb->enb_id, ue->enb_ue_s1ap_id); + + fsm_create((fsm_t*)&ue->emm_sm, + ue_emm_state_initial, ue_emm_state_final); + ue->emm_sm.ctx = ue; + ue->emm_sm.queue_id = s->queue_id; + ue->emm_sm.tm_service = s->tm_service; + + fsm_init((fsm_t*)&ue->emm_sm, 0); + + event_set(&e, EVT_MSG_UE_EMM); + event_set_param1(&e, (c_uintptr_t)ue); + event_set_param2(&e, (c_uintptr_t)sendbuf); + + event_send(s->queue_id, &e); break; } default: @@ -87,6 +133,7 @@ void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e) break; } } + break; } case S1AP_PDU_PR_successfulOutcome : @@ -112,6 +159,7 @@ void enb_s1ap_state_operational(enb_s1ap_sm_t *s, event_t *e) } s1ap_free_pdu(&message); + pkbuf_free(recvbuf); break; } @@ -193,34 +241,3 @@ status_t enb_s1ap_handle_s1setuprequest(enb_ctx_t *enb, s1ap_message *message) return CORE_OK; } - -status_t enb_s1ap_handle_initialuemessage( - enb_ctx_t *enb, s1ap_message *message) -{ - S1ap_InitialUEMessage_IEs_t *ies = NULL; - ue_ctx_t *ue = NULL; - - d_assert(enb, return CORE_ERROR, "Null param"); - d_assert(message, return CORE_ERROR, "Null param"); - - ies = &message->s1ap_InitialUEMessage_IEs; - d_assert(ies, return CORE_ERROR, "Null param"); - - ue = mme_ctx_ue_add(enb); - d_assert(ue, return CORE_ERROR, "Null param"); - - ue->enb_ue_s1ap_id = ies->eNB_UE_S1AP_ID; - - d_info("eNB[0x%x] sends Initial-UE Message[eNB-UE-S1AP-ID(%d)]", - enb->enb_id, ue->enb_ue_s1ap_id); -#if 0 - fsm_create((fsm_t*)&enb->s1ap_sm, - enb_s1ap_state_initial, enb_s1ap_state_final); - enb->s1ap_sm.ctx = enb; - enb->s1ap_sm.queue_id = s->queue_id; - enb->s1ap_sm.tm_service = s->tm_service; - fsm_init((fsm_t*)&enb->s1ap_sm, 0); -#endif - - return CORE_OK; -} diff --git a/src/mme/event.c b/src/mme/event.c index f885adeb79..fe49ae7207 100644 --- a/src/mme/event.c +++ b/src/mme/event.c @@ -127,6 +127,7 @@ static char EVT_NAME_LO_ENB_S1AP_ACCEPT[] = "LO_ENB_S1AP_ACCEPT"; 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_UNKNOWN[] = "UNKNOWN"; @@ -146,8 +147,11 @@ char* event_get_name(event_t *e) return EVT_NAME_LO_ENB_S1AP_ACCEPT; case EVT_LO_ENB_S1AP_CONNREFUSED: return EVT_NAME_LO_ENB_S1AP_CONNREFUSED; + case EVT_MSG_ENB_S1AP: return EVT_NAME_MSG_ENB_S1AP; + case EVT_MSG_UE_EMM: + return EVT_NAME_MSG_UE_EMM; default: break; diff --git a/src/mme/event.h b/src/mme/event.h index d927e88c4e..2c5c494e1b 100644 --- a/src/mme/event.h +++ b/src/mme/event.h @@ -19,7 +19,7 @@ typedef enum { EVT_LO_ENB_S1AP_CONNREFUSED, EVT_MSG_ENB_S1AP, - EVT_MSG_UE_NAS, + EVT_MSG_UE_EMM, EVT_TOP, diff --git a/src/mme/mme_sm.c b/src/mme/mme_sm.c index 13a5df4d1f..f037dda1d9 100644 --- a/src/mme/mme_sm.c +++ b/src/mme/mme_sm.c @@ -94,9 +94,7 @@ void mme_state_operational(mme_sm_t *s, event_t *e) case EVT_MSG_ENB_S1AP: { net_sock_t *sock = (net_sock_t *)event_get_param1(e); - pkbuf_t *recvbuf = (pkbuf_t *)event_get_param2(e); d_assert(sock, break, "Null param"); - d_assert(recvbuf, break, "Null param"); enb_ctx_t *enb = mme_ctx_enb_find_by_sock(sock); if (enb) @@ -110,7 +108,16 @@ void mme_state_operational(mme_sm_t *s, event_t *e) INET_NTOP(&sock->remote.sin_addr.s_addr, buf)); } - pkbuf_free(recvbuf); + break; + } + case EVT_MSG_UE_EMM: + { + ue_ctx_t *ue = (ue_ctx_t *)event_get_param1(e); + d_assert(ue, break, "Null param"); + + d_assert(FSM_STATE(&ue->emm_sm), break, "Null param"); + fsm_dispatch((fsm_t*)&ue->emm_sm, (fsm_event_t*)e); + break; } case EVT_LO_ENB_S1AP_CONNREFUSED: diff --git a/src/mme/ue_emm_sm.c b/src/mme/ue_emm_sm.c index c41e1dab7c..a99383d854 100644 --- a/src/mme/ue_emm_sm.c +++ b/src/mme/ue_emm_sm.c @@ -42,8 +42,15 @@ void ue_emm_state_operational(ue_emm_sm_t *s, event_t *e) { break; } - case EVT_ENB_S1AP_INF: + case EVT_MSG_UE_EMM: { + pkbuf_t *recvbuf = (pkbuf_t *)event_get_param2(e); + d_assert(recvbuf, break, "Null param"); + + d_print_hex(recvbuf->payload, recvbuf->len); + d_info("Received EVT_MSG_UE_EMM"); + + pkbuf_free(recvbuf); break; }