improve EMM SM

This commit is contained in:
Sukchan Lee 2017-09-04 13:04:35 +09:00
parent 87b0897602
commit af4cf2a4e1
11 changed files with 292 additions and 184 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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