[#220] T3460 done

This commit is contained in:
Sukchan Lee 2019-07-20 21:28:36 +09:00
parent 805869da4f
commit 90290d236e
9 changed files with 154 additions and 53 deletions

View File

@ -254,9 +254,6 @@ int emm_build_security_mode_command(
ogs_assert(mme_ue);
ogs_debug("[EMM] Security mode command");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_NEW_SECURITY_CONTEXT;

View File

@ -70,18 +70,18 @@ int emm_handle_attach_request(
/*
* ATTACH_REQUEST
* Clear EBI generator
* Clear Paging Timer and Message
* Clear Timer and Message
*
* TAU_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*
* SERVICE_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*
* EXTENDED_SERVICE_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*/
CLEAR_MME_UE_TIMER(mme_ue->t3413);
CLEAR_MME_UE_ALL_TIMERS(mme_ue);
CLEAR_EPS_BEARER_ID(mme_ue);
CLEAR_SERVICE_INDICATOR(mme_ue);
@ -373,18 +373,19 @@ int emm_handle_service_request(
/*
* ATTACH_REQUEST
* Clear EBI generator
* Clear Paging Timer and Message
* Clear Timer and Message
*
* TAU_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*
* SERVICE_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*
* EXTENDED_SERVICE_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*/
CLEAR_MME_UE_TIMER(mme_ue->t3413);
CLEAR_MME_UE_ALL_TIMERS(mme_ue);
if (SECURITY_CONTEXT_IS_VALID(mme_ue)) {
mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32, mme_ue->kenb);
mme_kdf_nh(mme_ue->kasme, mme_ue->kenb, mme_ue->nh);
@ -430,18 +431,18 @@ int emm_handle_tau_request(
/*
* ATTACH_REQUEST
* Clear EBI generator
* Clear Paging Timer and Message
* Clear Timer and Message
*
* TAU_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*
* SERVICE_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*
* EXTENDED_SERVICE_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*/
CLEAR_MME_UE_TIMER(mme_ue->t3413);
CLEAR_MME_UE_ALL_TIMERS(mme_ue);
CLEAR_SERVICE_INDICATOR(mme_ue);
if (BEARER_CONTEXT_IS_ACTIVE(mme_ue))
@ -561,18 +562,18 @@ int emm_handle_extended_service_request(
/*
* ATTACH_REQUEST
* Clear EBI generator
* Clear Paging Timer and Message
* Clear Timer and Message
*
* TAU_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*
* SERVICE_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*
* EXTENDED_SERVICE_REQUEST
* Clear Paging Timer and Message
* Clear Timer and Message
*/
CLEAR_MME_UE_TIMER(mme_ue->t3413);
CLEAR_MME_UE_ALL_TIMERS(mme_ue);
ogs_debug(" OLD TAI[PLMN_ID:%06x,TAC:%d]",
plmn_id_hexdump(&mme_ue->tai.plmn_id), mme_ue->tai.tac);

View File

@ -273,14 +273,15 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
/* Paging failed */
ogs_warn("[EMM] Paging to IMSI[%s] failed. Stop paging",
mme_ue->imsi_bcd);
if (mme_ue->t3413.pkbuf) {
ogs_pkbuf_free(mme_ue->t3413.pkbuf);
mme_ue->t3413.pkbuf = NULL;
}
CLEAR_MME_UE_TIMER(mme_ue->t3413);
} else {
mme_ue->t3413.retry_count++;
/* If t3413 is timeout, last_paging_msg is used.
* We don't have to set CNDomain. So, we just set CNDomain to 0 */
/*
* If t3413 is timeout, the saved pkbuf is used.
* We don't have to set CNDomain.
* So, we just set CNDomain to 0
*/
s1ap_send_paging(mme_ue, 0);
}
break;
@ -496,6 +497,8 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
ogs_debug("[EMM] Authentication response");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
CLEAR_MME_UE_TIMER(mme_ue->t3460);
if (memcmp(authentication_response_parameter->res,
mme_ue->xres,
authentication_response_parameter->length) != 0) {
@ -510,6 +513,7 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
} else {
OGS_FSM_TRAN(&mme_ue->sm, &emm_state_security_mode);
}
break;
}
case NAS_AUTHENTICATION_FAILURE:
@ -525,6 +529,8 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
ogs_debug(" IMSI[%s] EMM_CAUSE[%d]", mme_ue->imsi_bcd,
authentication_failure->emm_cause);
CLEAR_MME_UE_TIMER(mme_ue->t3460);
switch (authentication_failure->emm_cause) {
case EMM_CAUSE_MAC_FAILURE:
ogs_warn("Authentication failure(MAC failure)");
@ -548,6 +554,7 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
rv = nas_send_authentication_reject(mme_ue);
ogs_assert(rv == OGS_OK);
OGS_FSM_TRAN(&mme_ue->sm, &emm_state_exception);
break;
}
case NAS_ATTACH_REQUEST:
@ -590,6 +597,29 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
break;
}
break;
case MME_EVT_EMM_TIMER:
switch (e->timer_id) {
case MME_TIMER_T3460:
if (mme_ue->t3460.retry_count >=
mme_timer_cfg(MME_TIMER_T3460)->max_count) {
ogs_warn("[EMM] Retransmission of IMSI[%s] failed. "
"Stop retransmission",
mme_ue->imsi_bcd);
CLEAR_MME_UE_TIMER(mme_ue->t3460);
nas_send_authentication_reject(mme_ue);
OGS_FSM_TRAN(&mme_ue->sm, &emm_state_exception);
} else {
mme_ue->t3460.retry_count++;
nas_send_authentication_request(mme_ue, NULL);
}
break;
default:
ogs_error("Unknown timer[%s:%d]",
mme_timer_get_name(e->timer_id), e->timer_id);
break;
}
return;
default:
ogs_error("Unknown event[%s]", mme_event_get_name(e));
break;
@ -600,7 +630,6 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
{
int rv;
mme_ue_t *mme_ue = NULL;
ogs_pkbuf_t *emmbuf = NULL;
nas_message_t *message = NULL;
ogs_assert(s);
@ -613,12 +642,8 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
rv = emm_build_security_mode_command(&emmbuf, mme_ue);
ogs_assert(rv == OGS_OK && emmbuf);
rv = nas_send_to_downlink_nas_transport(mme_ue, emmbuf);
ogs_assert(rv == OGS_OK && emmbuf);
CLEAR_MME_UE_TIMER(mme_ue->t3460);
nas_send_security_mode_command(mme_ue);
break;
case OGS_FSM_EXIT_SIG:
break;
@ -641,6 +666,8 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
ogs_debug("[EMM] Security mode complete");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
CLEAR_MME_UE_TIMER(mme_ue->t3460);
/* Update Kenb */
if (SECURITY_CONTEXT_IS_VALID(mme_ue)) {
mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32,
@ -665,6 +692,7 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
ogs_warn("[EMM] Security mode reject : IMSI[%s] Cause[%d]",
mme_ue->imsi_bcd,
message->emm.security_mode_reject.emm_cause);
CLEAR_MME_UE_TIMER(mme_ue->t3460);
OGS_FSM_TRAN(s, &emm_state_exception);
break;
case NAS_ATTACH_REQUEST:
@ -714,6 +742,30 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
break;
}
break;
case MME_EVT_EMM_TIMER:
switch (e->timer_id) {
case MME_TIMER_T3460:
if (mme_ue->t3460.retry_count >=
mme_timer_cfg(MME_TIMER_T3460)->max_count) {
ogs_warn("[EMM] Retransmission of IMSI[%s] failed. "
"Stop retransmission",
mme_ue->imsi_bcd);
CLEAR_MME_UE_TIMER(mme_ue->t3460);
/* No response message for security-mode */
OGS_FSM_TRAN(&mme_ue->sm, &emm_state_exception);
} else {
mme_ue->t3460.retry_count++;
nas_send_security_mode_command(mme_ue);
}
break;
default:
ogs_error("Unknown timer[%s:%d]",
mme_timer_get_name(e->timer_id), e->timer_id);
break;
}
return;
default:
ogs_error("Unknown event[%s]", mme_event_get_name(e));
break;
@ -810,11 +862,17 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
void emm_state_exception(ogs_fsm_t *s, mme_event_t *e)
{
mme_ue_t *mme_ue = NULL;
ogs_assert(e);
mme_sm_debug(e);
mme_ue = e->mme_ue;
ogs_assert(mme_ue);
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
CLEAR_MME_UE_ALL_TIMERS(mme_ue);
break;
case OGS_FSM_EXIT_SIG:
break;

View File

@ -2081,11 +2081,7 @@ void mme_ue_remove(mme_ue_t *mme_ue)
S1AP_CLEAR_DATA(&mme_ue->container);
/* Delete All Timers */
CLEAR_MME_UE_TIMER(mme_ue->t3413);
CLEAR_MME_UE_TIMER(mme_ue->t3422);
CLEAR_MME_UE_TIMER(mme_ue->t3450);
CLEAR_MME_UE_TIMER(mme_ue->t3460);
CLEAR_MME_UE_TIMER(mme_ue->t3470);
CLEAR_MME_UE_ALL_TIMERS(mme_ue);
ogs_timer_delete(mme_ue->t3413.timer);
ogs_timer_delete(mme_ue->t3422.timer);
ogs_timer_delete(mme_ue->t3450.timer);

View File

@ -393,7 +393,14 @@ struct mme_ue_s {
/* Save PDN Connectivity Request */
nas_esm_message_container_t pdn_connectivity_request;
/* Paging */
#define CLEAR_MME_UE_ALL_TIMERS(__mME) \
do { \
CLEAR_MME_UE_TIMER((__mME)->t3413); \
CLEAR_MME_UE_TIMER((__mME)->t3422); \
CLEAR_MME_UE_TIMER((__mME)->t3450); \
CLEAR_MME_UE_TIMER((__mME)->t3460); \
CLEAR_MME_UE_TIMER((__mME)->t3470); \
} while(0);
#define CLEAR_MME_UE_TIMER(__mME_UE_TIMER) \
do { \
ogs_timer_stop((__mME_UE_TIMER).timer); \

View File

@ -39,6 +39,8 @@ void mme_s6a_handle_aia(mme_ue_t *mme_ue, s6a_aia_message_t *aia_message)
memcpy(mme_ue->kasme, e_utran_vector->kasme, OGS_SHA256_DIGEST_SIZE);
memcpy(mme_ue->rand, e_utran_vector->rand, RAND_LEN);
CLEAR_MME_UE_TIMER(mme_ue->t3460);
rv = nas_send_authentication_request(mme_ue, e_utran_vector);
ogs_assert(rv == OGS_OK);
}

View File

@ -23,15 +23,15 @@
static mme_timer_cfg_t g_mme_timer_cfg[MAX_NUM_OF_MME_TIMER] = {
[MME_TIMER_T3413] =
{ .max_count = 4, .duration = ogs_time_from_sec(2) },
{ .max_count = 2, .duration = ogs_time_from_sec(2) },
[MME_TIMER_T3422] =
{ .max_count = 2, .duration = ogs_time_from_sec(6) },
{ .max_count = 4, .duration = ogs_time_from_sec(3) },
[MME_TIMER_T3450] =
{ .max_count = 2, .duration = ogs_time_from_sec(6) },
{ .max_count = 4, .duration = ogs_time_from_sec(3) },
[MME_TIMER_T3460] =
{ .max_count = 2, .duration = ogs_time_from_sec(6) },
{ .max_count = 4, .duration = ogs_time_from_sec(3) },
[MME_TIMER_T3470] =
{ .max_count = 2, .duration = ogs_time_from_sec(6) },
{ .max_count = 4, .duration = ogs_time_from_sec(3) },
[MME_TIMER_SGS_CLI_CONN_TO_SRV] =
{ .duration = ogs_time_from_sec(3) },
};
@ -95,15 +95,15 @@ void mme_timer_t3422_expire(void *data)
}
void mme_timer_t3450_expire(void *data)
{
mme_ue_timer_event(MME_TIMER_T3413, data);
mme_ue_timer_event(MME_TIMER_T3450, data);
}
void mme_timer_t3460_expire(void *data)
{
mme_ue_timer_event(MME_TIMER_T3413, data);
mme_ue_timer_event(MME_TIMER_T3460, data);
}
void mme_timer_t3470_expire(void *data)
{
mme_ue_timer_event(MME_TIMER_T3413, data);
mme_ue_timer_event(MME_TIMER_T3470, data);
}
static void mme_ue_timer_event(

View File

@ -23,6 +23,7 @@
#include "emm-build.h"
#include "nas-path.h"
#include "mme-event.h"
#include "mme-timer.h"
#include "mme-sm.h"
int nas_send_to_enb(mme_ue_t *mme_ue, ogs_pkbuf_t *pkbuf)
@ -161,13 +162,50 @@ int nas_send_authentication_request(
ogs_pkbuf_t *emmbuf = NULL;
ogs_assert(mme_ue);
ogs_assert(e_utran_vector);
ogs_debug("[EMM] Authentication request");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
rv = emm_build_authentication_request(&emmbuf, e_utran_vector);
ogs_assert(rv == OGS_OK && emmbuf);
if (mme_ue->t3460.pkbuf) {
emmbuf = mme_ue->t3460.pkbuf;
} else {
ogs_assert(e_utran_vector);
rv = emm_build_authentication_request(&emmbuf, e_utran_vector);
ogs_assert(rv == OGS_OK && emmbuf);
}
mme_ue->t3460.pkbuf = ogs_pkbuf_copy(emmbuf);
ogs_timer_start(mme_ue->t3460.timer,
mme_timer_cfg(MME_TIMER_T3460)->duration);
rv = nas_send_to_downlink_nas_transport(mme_ue, emmbuf);
ogs_assert(rv == OGS_OK);
return rv;
}
int nas_send_security_mode_command(mme_ue_t *mme_ue)
{
int rv;
ogs_pkbuf_t *emmbuf = NULL;
ogs_assert(mme_ue);
ogs_debug("[EMM] Security mode command");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
if (mme_ue->t3460.pkbuf) {
emmbuf = mme_ue->t3460.pkbuf;
} else {
rv = emm_build_security_mode_command(&emmbuf, mme_ue);
ogs_assert(rv == OGS_OK && emmbuf);
}
mme_ue->t3460.pkbuf = ogs_pkbuf_copy(emmbuf);
ogs_timer_start(mme_ue->t3460.timer,
mme_timer_cfg(MME_TIMER_T3460)->duration);
rv = nas_send_to_downlink_nas_transport(mme_ue, emmbuf);
ogs_assert(rv == OGS_OK);

View File

@ -41,6 +41,8 @@ int nas_send_authentication_request(
mme_ue_t *mme_ue, e_utran_vector_t *e_utran_vector);
int nas_send_authentication_reject(mme_ue_t *mme_ue);
int nas_send_security_mode_command(mme_ue_t *mme_ue);
int nas_send_detach_accept(mme_ue_t *mme_ue);
int nas_send_pdn_connectivity_reject(