From af4cf2a4e1f5aff5cb416dcf337d6469f3efda10 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Mon, 4 Sep 2017 13:04:35 +0900 Subject: [PATCH] improve EMM SM --- lib/core/include/core_event.h | 3 +- lib/core/include/core_fsm.h | 10 ++- lib/core/src/fsm.c | 54 +++++++++------ lib/core/test/testfsm.c | 124 ++++++++++++++++------------------ src/mme/emm_build.c | 99 +++++++++++++++++++++++++++ src/mme/emm_build.h | 4 ++ src/mme/emm_handler.c | 75 -------------------- src/mme/emm_sm.c | 84 +++++++++++++++++++++-- src/mme/mme_context.c | 12 ++-- src/mme/mme_sm.c | 8 ++- src/mme/mme_sm.h | 3 +- 11 files changed, 292 insertions(+), 184 deletions(-) diff --git a/lib/core/include/core_event.h b/lib/core/include/core_event.h index 0db4694cc..5d5a34b82 100644 --- a/lib/core/include/core_event.h +++ b/lib/core/include/core_event.h @@ -3,6 +3,7 @@ #include "core_msgq.h" #include "core_timer.h" +#include "core_fsm.h" #ifdef __cplusplus extern "C" { @@ -49,7 +50,7 @@ extern "C" { (__duration), (__ptr_e), (__param)) typedef struct { - c_uintptr_t event; + fsm_event_t event; c_uintptr_t param1; c_uintptr_t param2; c_uintptr_t param3; diff --git a/lib/core/include/core_fsm.h b/lib/core/include/core_fsm.h index c3e364fd3..63b62643b 100644 --- a/lib/core/include/core_fsm.h +++ b/lib/core/include/core_fsm.h @@ -17,9 +17,7 @@ typedef enum _fsm_signal_t { FSM_USER_SIG } fsm_signal_t; -typedef struct { - c_uintptr_t event; -} fsm_event_t; +typedef c_uintptr_t fsm_event_t; typedef c_uintptr_t fsm_state_t; typedef void (*fsm_handler_t)(void *s, void *e); @@ -38,9 +36,9 @@ typedef struct _fsm_t { ((__s)->initial = (__s)->state = (__s)->final = NULL) -CORE_DECLARE(void) fsm_init(fsm_t *s, fsm_event_t *e); -CORE_DECLARE(void) fsm_dispatch(fsm_t *s, fsm_event_t *e); -CORE_DECLARE(void) fsm_final(fsm_t *s, fsm_event_t *e); +CORE_DECLARE(void) fsm_init(void *s, void *e); +CORE_DECLARE(void) fsm_dispatch(void *s, void *e); +CORE_DECLARE(void) fsm_final(void *s, void *e); #define FSM_TRAN(__s, __target) \ ((fsm_t *)__s)->state = (fsm_handler_t)(__target) diff --git a/lib/core/src/fsm.c b/lib/core/src/fsm.c index e0ff02d77..037c9574b 100644 --- a/lib/core/src/fsm.c +++ b/lib/core/src/fsm.c @@ -1,9 +1,13 @@ #include "core_fsm.h" -static fsm_event_t entry_event = { +typedef struct _event_t { + fsm_event_t event; +} event_t; + +static event_t entry_event = { FSM_ENTRY_SIG, }; -static fsm_event_t exit_event = { +static event_t exit_event = { FSM_EXIT_SIG, }; @@ -11,33 +15,38 @@ 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) +void fsm_init(void *s, void *_e) { - if (s->initial != (fsm_state_t)0) + fsm_t *fsm = s; + event_t *e = _e; + + if (fsm->initial != (fsm_state_t)0) { - (*s->initial)(s, e); - if (s->initial != s->state) + (*fsm->initial)(s, e); + if (fsm->initial != fsm->state) { if (e) { e->event = FSM_ENTRY_SIG; - (*s->state)(s, e); + (*fsm->state)(s, e); } else { - (*s->state)(s, &entry_event); + (*fsm->state)(s, &entry_event); } } } } -void fsm_dispatch(fsm_t *s, fsm_event_t *e) +void fsm_dispatch(void *s, void *_e) { - fsm_handler_t tmp = s->state; - s->state = (fsm_handler_t)0; + fsm_t *fsm = s; + event_t *e = _e; + fsm_handler_t tmp = fsm->state; + fsm->state = (fsm_handler_t)0; (*tmp)(s, e); - if (s->state != (fsm_state_t)0) + if (fsm->state != (fsm_state_t)0) { if (e) { @@ -51,7 +60,7 @@ void fsm_dispatch(fsm_t *s, fsm_event_t *e) if (e) { e->event = FSM_ENTRY_SIG; - (*s->state)(s, e); + (*fsm->state)(s, e); } else { @@ -60,29 +69,32 @@ void fsm_dispatch(fsm_t *s, fsm_event_t *e) } else { - s->state = tmp; + fsm->state = tmp; } } -void fsm_final(fsm_t *s, fsm_event_t *e) +void fsm_final(void *s, void *_e) { - if (s->final != s->state) + fsm_t *fsm = s; + event_t *e = _e; + + if (fsm->final != fsm->state) { if (e) { e->event = FSM_EXIT_SIG; - (*s->state)(s, e); + (*fsm->state)(s, e); } else { - (*s->state)(s, &exit_event); + (*fsm->state)(s, &exit_event); } } - if (s->final != (fsm_state_t)0) + if (fsm->final != (fsm_state_t)0) { - (*s->final)(s, e); + (*fsm->final)(s, e); } - s->state = s->initial; + fsm->state = fsm->initial; } diff --git a/lib/core/test/testfsm.c b/lib/core/test/testfsm.c index a38769c40..2959174ed 100644 --- a/lib/core/test/testfsm.c +++ b/lib/core/test/testfsm.c @@ -8,7 +8,7 @@ enum bomb_signal_t { }; typedef struct _tick_event_t { - c_uintptr_t event; + fsm_event_t event; } tick_event_t; typedef struct _bomb_t { @@ -18,26 +18,25 @@ typedef struct _bomb_t { c_uint8_t defuse; } bomb_t; -void bomb_initial(bomb_t *s, fsm_event_t *e); -void bomb_setting(bomb_t *s, fsm_event_t *e); -void bomb_timing(bomb_t *s, fsm_event_t *e); +void bomb_initial(bomb_t *s, tick_event_t *e); +void bomb_setting(bomb_t *s, tick_event_t *e); +void bomb_timing(bomb_t *s, tick_event_t *e); void bomb_create(bomb_t *s, uint8_t defuse) { - fsm_create(&s->fsm, (fsm_handler_t)&bomb_initial, (fsm_handler_t)0); + fsm_create(&s->fsm, &bomb_initial, 0); s->defuse = defuse; } -void bomb_initial(bomb_t *s, fsm_event_t *e) +void bomb_initial(bomb_t *s, tick_event_t *e) { s->timeout = 10; FSM_TRAN(s, &bomb_setting); } -void bomb_setting(bomb_t *s, fsm_event_t *e) +void bomb_setting(bomb_t *s, tick_event_t *e) { - tick_event_t *te = (tick_event_t*)e; - switch (te->event) + switch (e->event) { case UP_SIG: { @@ -62,10 +61,9 @@ void bomb_setting(bomb_t *s, fsm_event_t *e) } } -void bomb_timing(bomb_t *s, fsm_event_t *e) +void bomb_timing(bomb_t *s, tick_event_t *e) { - tick_event_t *te = (tick_event_t*)e; - switch (te->event) + switch (e->event) { case FSM_ENTRY_SIG: { @@ -101,66 +99,66 @@ static void fsm_test1(abts_case *tc, void *data) bomb_create(&bomb, 14); - fsm_init((fsm_t *)&bomb, (fsm_event_t*)0); - ABTS_PTR_EQUAL(tc, &bomb_setting, ((fsm_t*)&bomb)->state); + fsm_init(&bomb, 0); + ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 10, bomb.timeout); tick_event.event = UP_SIG; - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_setting, ((fsm_t*)&bomb)->state); + fsm_dispatch(&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 11, bomb.timeout); - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_setting, ((fsm_t*)&bomb)->state); + fsm_dispatch(&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 12, bomb.timeout); - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_setting, ((fsm_t*)&bomb)->state); + fsm_dispatch(&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 12, bomb.timeout); tick_event.event = DOWN_SIG; - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_setting, ((fsm_t*)&bomb)->state); + fsm_dispatch(&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 11, bomb.timeout); - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_setting, ((fsm_t*)&bomb)->state); + fsm_dispatch(&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 10, bomb.timeout); - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_setting, ((fsm_t*)&bomb)->state); + fsm_dispatch(&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 9, bomb.timeout); - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_setting, ((fsm_t*)&bomb)->state); + fsm_dispatch(&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 8, bomb.timeout); - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_setting, ((fsm_t*)&bomb)->state); + fsm_dispatch(&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 8, bomb.timeout); tick_event.event = ARM_SIG; - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_timing, ((fsm_t*)&bomb)->state); + fsm_dispatch((fsm_t *)&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_timing, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 0, bomb.code); tick_event.event = UP_SIG; - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_timing, ((fsm_t*)&bomb)->state); + fsm_dispatch((fsm_t *)&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_timing, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 1, bomb.code); tick_event.event = UP_SIG; - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_timing, ((fsm_t*)&bomb)->state); + fsm_dispatch((fsm_t *)&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_timing, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 3, bomb.code); tick_event.event = UP_SIG; - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_timing, ((fsm_t*)&bomb)->state); + fsm_dispatch((fsm_t *)&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_timing, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 7, bomb.code); tick_event.event = DOWN_SIG; - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_timing, ((fsm_t*)&bomb)->state); + fsm_dispatch((fsm_t *)&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_timing, FSM_STATE(&bomb)); ABTS_INT_EQUAL(tc, 14, bomb.code); tick_event.event = ARM_SIG; - fsm_dispatch((fsm_t *)&bomb, (fsm_event_t*)&tick_event); - ABTS_PTR_EQUAL(tc, &bomb_setting, ((fsm_t*)&bomb)->state); + fsm_dispatch((fsm_t *)&bomb, &tick_event); + ABTS_PTR_EQUAL(tc, &bomb_setting, FSM_STATE(&bomb)); } enum alarm_signal_t { @@ -181,29 +179,28 @@ typedef struct _alarm_t { } alarm_t; typedef struct _set_event_t { - c_uintptr_t event; + fsm_event_t event; c_uint8_t digit; } set_event_t; typedef struct _time_event_t { - c_uintptr_t event; + fsm_event_t event; c_uint8_t current_time; } time_event_t; -void alarm_initial(alarm_t *s, fsm_event_t *e); -void alarm_off(alarm_t *s, fsm_event_t *e); -void alarm_on(alarm_t *s, fsm_event_t *e); +void alarm_initial(alarm_t *s, set_event_t *e); +void alarm_off(alarm_t *s, set_event_t *e); +void alarm_on(alarm_t *s, time_event_t *e); -void alarm_initial(alarm_t *s, fsm_event_t *e) +void alarm_initial(alarm_t *s, set_event_t *e) { s->time = 12*60; FSM_TRAN(s, &alarm_off); } -void alarm_off(alarm_t *s, fsm_event_t *e) +void alarm_off(alarm_t *s, set_event_t *e) { - set_event_t *ae = (set_event_t*)e; - switch (ae->event) + switch (e->event) { case FSM_ENTRY_SIG: { @@ -223,7 +220,7 @@ void alarm_off(alarm_t *s, fsm_event_t *e) case ALARM_SET_SIG: { c_uint32_t alarm = (10 * s->time - + ae->digit) % 10000; + + e->digit) % 10000; if ((alarm / 100 < 24) && (alarm % 100 < 60)) { s->time = alarm; @@ -237,10 +234,9 @@ void alarm_off(alarm_t *s, fsm_event_t *e) } } -void alarm_on(alarm_t *s, fsm_event_t *e) +void alarm_on(alarm_t *s, time_event_t *e) { - time_event_t *ae = (time_event_t*)e; - switch (ae->event) + switch (e->event) { case FSM_ENTRY_SIG: { @@ -264,26 +260,26 @@ static void fsm_test2(abts_case *tc, void *data) set_event_t set_event; time_event_t time_event; - fsm_create((fsm_t *)&alarm, (fsm_handler_t)&alarm_initial, (fsm_handler_t)0); + fsm_create(&alarm.fsm, &alarm_initial, 0); - fsm_init((fsm_t *)&alarm, (fsm_event_t*)0); - ABTS_PTR_EQUAL(tc, &alarm_off, ((fsm_t*)&alarm)->state); + fsm_init(&alarm, 0); + ABTS_PTR_EQUAL(tc, &alarm_off, FSM_STATE(&alarm)); ABTS_INT_EQUAL(tc, 1200, alarm.time); set_event.event = ALARM_ON_SIG; - fsm_dispatch((fsm_t *)&alarm, (fsm_event_t*)&set_event); - ABTS_PTR_EQUAL(tc, &alarm_on, ((fsm_t*)&alarm)->state); + fsm_dispatch(&alarm, &set_event); + ABTS_PTR_EQUAL(tc, &alarm_on, FSM_STATE(&alarm)); ABTS_INT_EQUAL(tc, 720, alarm.time); time_event.event = ALARM_OFF_SIG; - fsm_dispatch((fsm_t *)&alarm, (fsm_event_t*)&time_event); - ABTS_PTR_EQUAL(tc, &alarm_off, ((fsm_t*)&alarm)->state); + fsm_dispatch(&alarm, &time_event); + ABTS_PTR_EQUAL(tc, &alarm_off, FSM_STATE(&alarm)); ABTS_INT_EQUAL(tc, 1200, alarm.time); set_event.event = ALARM_SET_SIG; set_event.digit = 0; - fsm_dispatch((fsm_t *)&alarm, (fsm_event_t*)&set_event); - ABTS_PTR_EQUAL(tc, &alarm_off, ((fsm_t*)&alarm)->state); + fsm_dispatch(&alarm, &set_event); + ABTS_PTR_EQUAL(tc, &alarm_off, FSM_STATE(&alarm)); ABTS_INT_EQUAL(tc, 2000, alarm.time); } diff --git a/src/mme/emm_build.c b/src/mme/emm_build.c index eb967700b..ea2e83d66 100644 --- a/src/mme/emm_build.c +++ b/src/mme/emm_build.c @@ -5,8 +5,107 @@ #include "nas_message.h" #include "nas_security.h" +#include "mme_kdf.h" #include "emm_build.h" +status_t emm_build_identity_request( + pkbuf_t **emmbuf, mme_ue_t *mme_ue) +{ + nas_message_t message; + nas_identity_request_t *identity_request = + &message.emm.identity_request; + + d_assert(mme_ue, return CORE_ERROR, "Null param"); + + memset(&message, 0, sizeof(message)); + message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; + message.emm.h.message_type = NAS_IDENTITY_REQUEST; + + /* Request IMSI */ + identity_request->identity_type.type = NAS_IDENTITY_TYPE_2_IMSI; + + d_assert(nas_plain_encode(emmbuf, &message) == CORE_OK && *emmbuf,,); + + return CORE_OK; +} +status_t emm_build_security_mode_command( + pkbuf_t **emmbuf, mme_ue_t *mme_ue) +{ + status_t rv; + int i; + + nas_message_t message; + nas_security_mode_command_t *security_mode_command = + &message.emm.security_mode_command; + nas_security_algorithms_t *selected_nas_security_algorithms = + &security_mode_command->selected_nas_security_algorithms; + nas_key_set_identifier_t *nas_key_set_identifier = + &security_mode_command->nas_key_set_identifier; + nas_ue_security_capability_t *replayed_ue_security_capabilities = + &security_mode_command->replayed_ue_security_capabilities; + + d_assert(mme_ue, return CORE_ERROR, "Null param"); + + memset(&message, 0, sizeof(message)); + message.h.security_header_type = + NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_NEW_SECURITY_CONTEXT; + message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; + + message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; + message.emm.h.message_type = NAS_SECURITY_MODE_COMMAND; + + for (i = 0; i < mme_self()->num_of_integrity_order; i++) + { + if (mme_ue->ue_network_capability.eia & + (0x80 >> mme_self()->integrity_order[i])) + { + mme_ue->selected_int_algorithm = mme_self()->integrity_order[i]; + break; + } + } + for (i = 0; i < mme_self()->num_of_ciphering_order; i++) + { + if (mme_ue->ue_network_capability.eea & + (0x80 >> mme_self()->ciphering_order[i])) + { + mme_ue->selected_enc_algorithm = mme_self()->ciphering_order[i]; + break; + } + } + + selected_nas_security_algorithms->type_of_integrity_protection_algorithm = + mme_ue->selected_int_algorithm; + selected_nas_security_algorithms->type_of_ciphering_algorithm = + mme_ue->selected_enc_algorithm; + + nas_key_set_identifier->tsc = 0; + nas_key_set_identifier->nas_key_set_identifier = 0; + + replayed_ue_security_capabilities->length = + sizeof(replayed_ue_security_capabilities->eea) + + sizeof(replayed_ue_security_capabilities->eia) + + sizeof(replayed_ue_security_capabilities->uea) + + sizeof(replayed_ue_security_capabilities->uia) + + sizeof(replayed_ue_security_capabilities->gea); + replayed_ue_security_capabilities->eea = mme_ue->ue_network_capability.eea; + replayed_ue_security_capabilities->eia = mme_ue->ue_network_capability.eia; + replayed_ue_security_capabilities->uea = mme_ue->ue_network_capability.uea; + replayed_ue_security_capabilities->uia = mme_ue->ue_network_capability.uia; + replayed_ue_security_capabilities->gea = + (mme_ue->ms_network_capability.gea1 << 6) | + mme_ue->ms_network_capability.extended_gea; + + mme_kdf_nas(MME_KDF_NAS_INT_ALG, mme_ue->selected_int_algorithm, + mme_ue->kasme, mme_ue->knas_int); + mme_kdf_nas(MME_KDF_NAS_ENC_ALG, mme_ue->selected_enc_algorithm, + mme_ue->kasme, mme_ue->knas_enc); + + rv = nas_security_encode(emmbuf, mme_ue, &message); + d_assert(rv == CORE_OK && *emmbuf, return CORE_ERROR, "emm build error"); + + return CORE_OK; +} + status_t emm_build_attach_accept( pkbuf_t **emmbuf, mme_ue_t *mme_ue, pkbuf_t *esmbuf) { diff --git a/src/mme/emm_build.h b/src/mme/emm_build.h index 290a57cd4..7ba1fb476 100644 --- a/src/mme/emm_build.h +++ b/src/mme/emm_build.h @@ -7,6 +7,10 @@ extern "C" { #endif /* __cplusplus */ +CORE_DECLARE(status_t) emm_build_identity_request( + pkbuf_t **emmbuf, mme_ue_t *mme_ue); +CORE_DECLARE(status_t) emm_build_security_mode_command( + pkbuf_t **emmbuf, mme_ue_t *mme_ue); CORE_DECLARE(status_t) emm_build_attach_accept( pkbuf_t **emmbuf, mme_ue_t *mme_ue, pkbuf_t *esmbuf); CORE_DECLARE(status_t) emm_build_attach_reject( diff --git a/src/mme/emm_handler.c b/src/mme/emm_handler.c index a8a6c59d4..84b7faf3e 100644 --- a/src/mme/emm_handler.c +++ b/src/mme/emm_handler.c @@ -348,23 +348,9 @@ void emm_handle_identity_response( void emm_handle_authentication_response(mme_ue_t *mme_ue, nas_authentication_response_t *authentication_response) { - status_t rv; - pkbuf_t *emmbuf = NULL; - int i; - nas_authentication_response_parameter_t *authentication_response_parameter = &authentication_response->authentication_response_parameter; - nas_message_t message; - nas_security_mode_command_t *security_mode_command = - &message.emm.security_mode_command; - nas_security_algorithms_t *selected_nas_security_algorithms = - &security_mode_command->selected_nas_security_algorithms; - nas_key_set_identifier_t *nas_key_set_identifier = - &security_mode_command->nas_key_set_identifier; - nas_ue_security_capability_t *replayed_ue_security_capabilities = - &security_mode_command->replayed_ue_security_capabilities; - d_assert(mme_ue, return, "Null param"); if (authentication_response_parameter->length != mme_ue->xres_len || @@ -377,67 +363,6 @@ void emm_handle_authentication_response(mme_ue_t *mme_ue, d_trace(3, "[NAS] Authentication response : UE[%s] --> EMM\n", mme_ue->imsi_bcd); - - memset(&message, 0, sizeof(message)); - message.h.security_header_type = - NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_NEW_SECURITY_CONTEXT; - message.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; - - message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM; - message.emm.h.message_type = NAS_SECURITY_MODE_COMMAND; - - for (i = 0; i < mme_self()->num_of_integrity_order; i++) - { - if (mme_ue->ue_network_capability.eia & - (0x80 >> mme_self()->integrity_order[i])) - { - mme_ue->selected_int_algorithm = mme_self()->integrity_order[i]; - break; - } - } - for (i = 0; i < mme_self()->num_of_ciphering_order; i++) - { - if (mme_ue->ue_network_capability.eea & - (0x80 >> mme_self()->ciphering_order[i])) - { - mme_ue->selected_enc_algorithm = mme_self()->ciphering_order[i]; - break; - } - } - - selected_nas_security_algorithms->type_of_integrity_protection_algorithm = - mme_ue->selected_int_algorithm; - selected_nas_security_algorithms->type_of_ciphering_algorithm = - mme_ue->selected_enc_algorithm; - - nas_key_set_identifier->tsc = 0; - nas_key_set_identifier->nas_key_set_identifier = 0; - - replayed_ue_security_capabilities->length = - sizeof(replayed_ue_security_capabilities->eea) + - sizeof(replayed_ue_security_capabilities->eia) + - sizeof(replayed_ue_security_capabilities->uea) + - sizeof(replayed_ue_security_capabilities->uia) + - sizeof(replayed_ue_security_capabilities->gea); - replayed_ue_security_capabilities->eea = mme_ue->ue_network_capability.eea; - replayed_ue_security_capabilities->eia = mme_ue->ue_network_capability.eia; - replayed_ue_security_capabilities->uea = mme_ue->ue_network_capability.uea; - replayed_ue_security_capabilities->uia = mme_ue->ue_network_capability.uia; - replayed_ue_security_capabilities->gea = - (mme_ue->ms_network_capability.gea1 << 6) | - mme_ue->ms_network_capability.extended_gea; - - mme_kdf_nas(MME_KDF_NAS_INT_ALG, mme_ue->selected_int_algorithm, - mme_ue->kasme, mme_ue->knas_int); - mme_kdf_nas(MME_KDF_NAS_ENC_ALG, mme_ue->selected_enc_algorithm, - mme_ue->kasme, mme_ue->knas_enc); - - d_trace(3, "[NAS] Security mode command : UE[%s] <-- EMM\n", - mme_ue->imsi_bcd); - - rv = nas_security_encode(&emmbuf, mme_ue, &message); - d_assert(rv == CORE_OK && emmbuf, return, "emm build error"); - d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,); } void emm_handle_detach_request( diff --git a/src/mme/emm_sm.c b/src/mme/emm_sm.c index d78b9672d..1c17133bc 100644 --- a/src/mme/emm_sm.c +++ b/src/mme/emm_sm.c @@ -14,6 +14,7 @@ #include "emm_build.h" #include "esm_handler.h" #include "mme_s11_handler.h" +#include "nas_path.h" void emm_state_initial(fsm_t *s, event_t *e) { @@ -96,7 +97,7 @@ void emm_state_detached(fsm_t *s, event_t *e) { mme_s6a_send_air(mme_ue); } - FSM_TRAN(s, &emm_state_auth); + FSM_TRAN(s, &emm_state_authentication); } break; @@ -128,10 +129,15 @@ void emm_state_identity(fsm_t *s, event_t *e) { case FSM_ENTRY_SIG: { - mme_ue_t *mme_ue = mme_ue_find(event_get_param1(e)); - d_assert(mme_ue, return, "Null param"); + status_t rv; + pkbuf_t *emmbuf = NULL; + + rv = emm_build_identity_request(&emmbuf, mme_ue); + d_assert(rv == CORE_OK && emmbuf, break, "emm build error"); + + rv = nas_send_to_downlink_nas_transport(mme_ue, emmbuf); + d_assert(rv == CORE_OK && emmbuf, break, "emm send error"); - emm_handle_identity_request(mme_ue); break; } case FSM_EXIT_SIG: @@ -169,7 +175,7 @@ void emm_state_identity(fsm_t *s, event_t *e) { mme_s6a_send_air(mme_ue); } - FSM_TRAN(s, &emm_state_auth); + FSM_TRAN(s, &emm_state_authentication); } break; } @@ -196,7 +202,7 @@ void emm_state_identity(fsm_t *s, event_t *e) } } -void emm_state_auth(fsm_t *s, event_t *e) +void emm_state_authentication(fsm_t *s, event_t *e) { mme_ue_t *mme_ue = NULL; @@ -229,8 +235,72 @@ void emm_state_auth(fsm_t *s, event_t *e) { emm_handle_authentication_response( mme_ue, &message->emm.authentication_response); + FSM_TRAN(s, &emm_state_security_mode); 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_security_mode(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: + { + status_t rv; + pkbuf_t *emmbuf = NULL; + + rv = emm_build_security_mode_command(&emmbuf, mme_ue); + d_assert(rv == CORE_OK && emmbuf, break, "emm build error"); + + rv = nas_send_to_downlink_nas_transport(mme_ue, emmbuf); + d_assert(rv == CORE_OK && emmbuf, break, "emm send error"); + + d_trace(3, "[NAS] Security mode command : UE[%s] <-- EMM\n", + mme_ue->imsi_bcd); + 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_SECURITY_MODE_COMPLETE: { d_trace(3, "[NAS] Security mode complete : " @@ -409,7 +479,7 @@ void emm_state_attached(fsm_t *s, event_t *e) { mme_s6a_send_air(mme_ue); } - FSM_TRAN(s, &emm_state_auth); + FSM_TRAN(s, &emm_state_authentication); } break; diff --git a/src/mme/mme_context.c b/src/mme/mme_context.c index 3e6ee2817..980e59621 100644 --- a/src/mme/mme_context.c +++ b/src/mme/mme_context.c @@ -925,7 +925,7 @@ mme_enb_t* mme_enb_add(net_sock_t *s1ap_sock) event_set_param1(&e, (c_uintptr_t)enb->index); fsm_create(&enb->sm, s1ap_state_initial, s1ap_state_final); - fsm_init(&enb->sm, (fsm_event_t *)&e); + fsm_init(&enb->sm, &e); return enb; } @@ -937,7 +937,7 @@ status_t mme_enb_remove(mme_enb_t *enb) d_assert(enb, return CORE_ERROR, "Null param"); event_set_param1(&e, (c_uintptr_t)enb->index); - fsm_final(&enb->sm, (fsm_event_t *)&e); + fsm_final(&enb->sm, &e); fsm_clear(&enb->sm); enb_ue_remove_in_enb(enb); @@ -1143,7 +1143,7 @@ mme_ue_t* mme_ue_add(enb_ue_t *enb_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, (fsm_event_t *)&e); + fsm_init(&mme_ue->sm, &e); return mme_ue; } @@ -1155,7 +1155,7 @@ status_t mme_ue_remove(mme_ue_t *mme_ue) d_assert(mme_ue, return CORE_ERROR, "Null param"); event_set_param1(&e, (c_uintptr_t)mme_ue->index); - fsm_final(&mme_ue->sm, (fsm_event_t *)&e); + fsm_final(&mme_ue->sm, &e); fsm_clear(&mme_ue->sm); /* Clear hash table */ @@ -1496,7 +1496,7 @@ mme_sess_t *mme_sess_add(mme_ue_t *mme_ue, c_uint8_t pti) event_set_param1(&e, (c_uintptr_t)sess->index); fsm_create(&sess->sm, esm_state_initial, esm_state_final); - fsm_init(&sess->sm, (fsm_event_t *)&e); + fsm_init(&sess->sm, &e); return sess; } @@ -1509,7 +1509,7 @@ status_t mme_sess_remove(mme_sess_t *sess) d_assert(sess->mme_ue, return CORE_ERROR, "Null param"); event_set_param1(&e, (c_uintptr_t)sess->index); - fsm_final(&sess->sm, (fsm_event_t *)&e); + fsm_final(&sess->sm, &e); fsm_clear(&sess->sm); mme_bearer_remove_all(sess); diff --git a/src/mme/mme_sm.c b/src/mme/mme_sm.c index 3052d73d5..a2779dbb1 100644 --- a/src/mme/mme_sm.c +++ b/src/mme/mme_sm.c @@ -267,7 +267,8 @@ 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_TRAN(&mme_ue->sm, emm_state_detached); + fsm_final(&mme_ue->sm, e); + fsm_init(&mme_ue->sm, e); break; } @@ -283,7 +284,8 @@ 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_TRAN(&mme_ue->sm, emm_state_detached); + fsm_final(&mme_ue->sm, e); + fsm_init(&mme_ue->sm, e); break; } @@ -363,7 +365,7 @@ void mme_state_operational(fsm_t *s, event_t *e) mme_s11_handle_delete_session_response( xact, mme_ue, &message.delete_session_response); - if (FSM_CHECK(&mme_ue->sm, emm_state_auth)) + if (FSM_CHECK(&mme_ue->sm, emm_state_authentication)) { if (mme_sess_first(mme_ue) == NULL) { diff --git a/src/mme/mme_sm.h b/src/mme/mme_sm.h index 1b065e7a7..f77a7091a 100644 --- a/src/mme/mme_sm.h +++ b/src/mme/mme_sm.h @@ -23,7 +23,8 @@ void emm_state_initial(fsm_t *s, event_t *e); void emm_state_final(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_authentication(fsm_t *s, event_t *e); +void emm_state_security_mode(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);