[#220] T3489 done

This commit is contained in:
Sukchan Lee 2019-07-20 23:06:54 +09:00
parent 6a1f628e44
commit 5ce04bcc6f
9 changed files with 136 additions and 29 deletions

View File

@ -71,6 +71,7 @@ void emm_state_de_registered(ogs_fsm_t *s, mme_event_t *e)
switch (e->id) { switch (e->id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
CLEAR_SERVICE_INDICATOR(mme_ue);
CLEAR_MME_UE_ALL_TIMERS(mme_ue); CLEAR_MME_UE_ALL_TIMERS(mme_ue);
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
@ -921,6 +922,7 @@ void emm_state_exception(ogs_fsm_t *s, mme_event_t *e)
switch (e->id) { switch (e->id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
CLEAR_SERVICE_INDICATOR(mme_ue);
CLEAR_MME_UE_ALL_TIMERS(mme_ue); CLEAR_MME_UE_ALL_TIMERS(mme_ue);
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:

View File

@ -85,8 +85,8 @@ int esm_handle_pdn_connectivity_request(mme_bearer_t *bearer,
} }
if (security_protected_required) { if (security_protected_required) {
rv = nas_send_esm_information_request(bearer); CLEAR_BEARER_TIMER(bearer->t3489);
ogs_assert(rv == OGS_OK); nas_send_esm_information_request(bearer);
return OGS_OK; return OGS_OK;
} }

View File

@ -19,6 +19,7 @@
#include "nas/nas-message.h" #include "nas/nas-message.h"
#include "mme-event.h" #include "mme-event.h"
#include "mme-timer.h"
#include "mme-sm.h" #include "mme-sm.h"
#include "mme-fd-path.h" #include "mme-fd-path.h"
#include "emm-handler.h" #include "emm-handler.h"
@ -69,6 +70,7 @@ void esm_state_inactive(ogs_fsm_t *s, mme_event_t *e)
switch (e->id) { switch (e->id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
CLEAR_BEARER_ALL_TIMERS(bearer);
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;
@ -92,6 +94,8 @@ void esm_state_inactive(ogs_fsm_t *s, mme_event_t *e)
ogs_debug("[ESM] ESM information response"); ogs_debug("[ESM] ESM information response");
ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]", ogs_debug(" IMSI[%s] PTI[%d] EBI[%d]",
mme_ue->imsi_bcd, sess->pti, bearer->ebi); mme_ue->imsi_bcd, sess->pti, bearer->ebi);
CLEAR_BEARER_TIMER(bearer->t3489);
rv = esm_handle_information_response( rv = esm_handle_information_response(
sess, &message->esm.esm_information_response); sess, &message->esm.esm_information_response);
if (rv != OGS_OK) { if (rv != OGS_OK) {
@ -136,6 +140,30 @@ void esm_state_inactive(ogs_fsm_t *s, mme_event_t *e)
break; break;
} }
break; break;
case MME_EVT_ESM_TIMER:
switch (e->timer_id) {
case MME_TIMER_T3489:
if (bearer->t3489.retry_count >=
mme_timer_cfg(MME_TIMER_T3489)->max_count) {
ogs_warn("[EMM] Retransmission of IMSI[%s] failed. "
"Stop retransmission",
mme_ue->imsi_bcd);
CLEAR_BEARER_TIMER(bearer->t3489);
OGS_FSM_TRAN(&bearer->sm, &esm_state_exception);
nas_send_pdn_connectivity_reject(sess,
ESM_CAUSE_ESM_INFORMATION_NOT_RECEIVED);
} else {
bearer->t3489.retry_count++;
nas_send_esm_information_request(bearer);
}
break;
default:
ogs_error("Unknown timer[%s:%d]",
mme_timer_get_name(e->timer_id), e->timer_id);
break;
}
break;
default: default:
ogs_error("Unknown event %s", mme_event_get_name(e)); ogs_error("Unknown event %s", mme_event_get_name(e));
break; break;
@ -310,11 +338,15 @@ void esm_state_bearer_deactivated(ogs_fsm_t *s, mme_event_t *e)
void esm_state_exception(ogs_fsm_t *s, mme_event_t *e) void esm_state_exception(ogs_fsm_t *s, mme_event_t *e)
{ {
mme_bearer_t *bearer = NULL;
ogs_assert(e); ogs_assert(e);
mme_sm_debug(e); mme_sm_debug(e);
bearer = e->bearer;
switch (e->id) { switch (e->id) {
case OGS_FSM_ENTRY_SIG: case OGS_FSM_ENTRY_SIG:
CLEAR_BEARER_ALL_TIMERS(bearer);
break; break;
case OGS_FSM_EXIT_SIG: case OGS_FSM_EXIT_SIG:
break; break;

View File

@ -2525,6 +2525,9 @@ mme_bearer_t *mme_bearer_add(mme_sess_t *sess)
bearer->sess = sess; bearer->sess = sess;
ogs_list_add(&sess->bearer_list, bearer); ogs_list_add(&sess->bearer_list, bearer);
bearer->t3489.timer = ogs_timer_add(
self.timer_mgr, mme_timer_t3489_expire, bearer);
e.bearer = bearer; e.bearer = bearer;
ogs_fsm_create(&bearer->sm, esm_state_initial, esm_state_final); ogs_fsm_create(&bearer->sm, esm_state_initial, esm_state_final);
@ -2544,6 +2547,8 @@ void mme_bearer_remove(mme_bearer_t *bearer)
ogs_fsm_fini(&bearer->sm, &e); ogs_fsm_fini(&bearer->sm, &e);
ogs_fsm_delete(&bearer->sm); ogs_fsm_delete(&bearer->sm);
ogs_timer_delete(bearer->t3489.timer);
ogs_list_remove(&bearer->sess->bearer_list, bearer); ogs_list_remove(&bearer->sess->bearer_list, bearer);
TLV_CLEAR_DATA(&bearer->tft); TLV_CLEAR_DATA(&bearer->tft);

View File

@ -589,6 +589,26 @@ typedef struct mme_bearer_s {
qos_t qos; qos_t qos;
tlv_octet_t tft; /* Saved TFT */ tlv_octet_t tft; /* Saved TFT */
#define CLEAR_BEARER_ALL_TIMERS(__bEARER) \
do { \
CLEAR_BEARER_TIMER((__bEARER)->t3489); \
} while(0);
#define CLEAR_BEARER_TIMER(__bEARER_TIMER) \
do { \
ogs_timer_stop((__bEARER_TIMER).timer); \
if ((__bEARER_TIMER).pkbuf) \
{ \
ogs_pkbuf_free((__bEARER_TIMER).pkbuf); \
(__bEARER_TIMER).pkbuf = NULL; \
} \
(__bEARER_TIMER).retry_count = 0; \
} while(0);
struct {
ogs_pkbuf_t *pkbuf;
ogs_timer_t *timer;
uint32_t retry_count;;
} t3489;
/* Related Context */ /* Related Context */
mme_ue_t *mme_ue; mme_ue_t *mme_ue;
mme_sess_t *sess; mme_sess_t *sess;

View File

@ -276,11 +276,7 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
ogs_fsm_dispatch(&mme_ue->sm, e); ogs_fsm_dispatch(&mme_ue->sm, e);
if (OGS_FSM_CHECK(&mme_ue->sm, emm_state_exception)) { if (OGS_FSM_CHECK(&mme_ue->sm, emm_state_exception)) {
CLEAR_SERVICE_INDICATOR(mme_ue); mme_send_delete_session_or_ue_context_release(mme_ue, enb_ue);
rv = mme_send_delete_session_or_ue_context_release(
mme_ue, enb_ue);
ogs_assert(rv == OGS_OK);
} }
ogs_pkbuf_free(pkbuf); ogs_pkbuf_free(pkbuf);
@ -332,14 +328,21 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
* [Enhancement] - Probably Invalid APN * [Enhancement] - Probably Invalid APN
* At this point, we'll forcely release UE context * At this point, we'll forcely release UE context
*/ */
rv = mme_send_delete_session_or_ue_context_release( mme_send_delete_session_or_ue_context_release(
mme_ue, mme_ue->enb_ue); mme_ue, mme_ue->enb_ue);
ogs_assert(rv == OGS_OK);
} }
ogs_pkbuf_free(pkbuf); ogs_pkbuf_free(pkbuf);
break; break;
case MME_EVT_ESM_TIMER:
bearer = e->bearer;
ogs_assert(bearer);
ogs_assert(OGS_FSM_STATE(&bearer->sm));
ogs_fsm_dispatch(&bearer->sm, e);
break;
case MME_EVT_S6A_MESSAGE: case MME_EVT_S6A_MESSAGE:
mme_ue = e->mme_ue; mme_ue = e->mme_ue;
ogs_assert(mme_ue); ogs_assert(mme_ue);

View File

@ -32,12 +32,16 @@ static mme_timer_cfg_t g_mme_timer_cfg[MAX_NUM_OF_MME_TIMER] = {
{ .max_count = 4, .duration = ogs_time_from_sec(3) }, { .max_count = 4, .duration = ogs_time_from_sec(3) },
[MME_TIMER_T3470] = [MME_TIMER_T3470] =
{ .max_count = 4, .duration = ogs_time_from_sec(3) }, { .max_count = 4, .duration = ogs_time_from_sec(3) },
[MME_TIMER_T3489] =
{ .max_count = 2, .duration = ogs_time_from_sec(4) },
[MME_TIMER_SGS_CLI_CONN_TO_SRV] = [MME_TIMER_SGS_CLI_CONN_TO_SRV] =
{ .duration = ogs_time_from_sec(3) }, { .duration = ogs_time_from_sec(3) },
}; };
static void mme_ue_timer_event( static void emm_timer_event_send(
mme_timer_e timer_id, mme_ue_t *mme_ue); mme_timer_e timer_id, mme_ue_t *mme_ue);
static void esm_timer_event_send(
mme_timer_e timer_id, mme_bearer_t *bearer);
mme_timer_cfg_t *mme_timer_cfg(mme_timer_e id) mme_timer_cfg_t *mme_timer_cfg(mme_timer_e id)
{ {
@ -60,6 +64,8 @@ const char *mme_timer_get_name(mme_timer_e id)
return "MME_TIMER_T3460"; return "MME_TIMER_T3460";
case MME_TIMER_T3470: case MME_TIMER_T3470:
return "MME_TIMER_T3470"; return "MME_TIMER_T3470";
case MME_TIMER_T3489:
return "MME_TIMER_T3489";
case MME_TIMER_SGS_CLI_CONN_TO_SRV: case MME_TIMER_SGS_CLI_CONN_TO_SRV:
return "MME_TIMER_SGS_CLI_CONN_TO_SRV"; return "MME_TIMER_SGS_CLI_CONN_TO_SRV";
default: default:
@ -87,26 +93,30 @@ void mme_timer_s1_delayed_send(void *data)
void mme_timer_t3413_expire(void *data) void mme_timer_t3413_expire(void *data)
{ {
mme_ue_timer_event(MME_TIMER_T3413, data); emm_timer_event_send(MME_TIMER_T3413, data);
} }
void mme_timer_t3422_expire(void *data) void mme_timer_t3422_expire(void *data)
{ {
mme_ue_timer_event(MME_TIMER_T3422, data); emm_timer_event_send(MME_TIMER_T3422, data);
} }
void mme_timer_t3450_expire(void *data) void mme_timer_t3450_expire(void *data)
{ {
mme_ue_timer_event(MME_TIMER_T3450, data); emm_timer_event_send(MME_TIMER_T3450, data);
} }
void mme_timer_t3460_expire(void *data) void mme_timer_t3460_expire(void *data)
{ {
mme_ue_timer_event(MME_TIMER_T3460, data); emm_timer_event_send(MME_TIMER_T3460, data);
} }
void mme_timer_t3470_expire(void *data) void mme_timer_t3470_expire(void *data)
{ {
mme_ue_timer_event(MME_TIMER_T3470, data); emm_timer_event_send(MME_TIMER_T3470, data);
}
void mme_timer_t3489_expire(void *data)
{
esm_timer_event_send(MME_TIMER_T3489, data);
} }
static void mme_ue_timer_event( static void emm_timer_event_send(
mme_timer_e timer_id, mme_ue_t *mme_ue) mme_timer_e timer_id, mme_ue_t *mme_ue)
{ {
int rv; int rv;
@ -124,6 +134,28 @@ static void mme_ue_timer_event(
} }
} }
static void esm_timer_event_send(
mme_timer_e timer_id, mme_bearer_t *bearer)
{
int rv;
mme_event_t *e = NULL;
mme_ue_t *mme_ue = NULL;
ogs_assert(bearer);
mme_ue = bearer->mme_ue;
ogs_assert(bearer);
e = mme_event_new(MME_EVT_ESM_TIMER);
e->timer_id = timer_id;
e->mme_ue = mme_ue;
e->bearer = bearer;
rv = ogs_queue_push(mme_self()->queue, e);
if (rv != OGS_OK) {
ogs_warn("ogs_queue_push() failed:%d", (int)rv);
mme_event_free(e);
}
}
void mme_timer_sgs_cli_conn_to_srv(void *data) void mme_timer_sgs_cli_conn_to_srv(void *data)
{ {
int rv; int rv;

View File

@ -32,23 +32,27 @@ typedef enum {
MME_TIMER_S1_DELAYED_SEND, MME_TIMER_S1_DELAYED_SEND,
MME_TIMER_T3413, /* Paging procedure for EPS services initiated */ /* Paging procedure for EPS services initiated */
MME_TIMER_T3422, /* DETACH REQUEST sent */ MME_TIMER_T3413,
/* /* DETACH REQUEST sent */
* ATTACH ACCEPT sent MME_TIMER_T3422,
/* ATTACH ACCEPT sent
* TRACKING AREA UPDATE ACCEPT sent with GUTI * TRACKING AREA UPDATE ACCEPT sent with GUTI
* TRACKING AREA UPDATE ACCEPT sent with TMSI * TRACKING AREA UPDATE ACCEPT sent with TMSI
* GUTI REALLOCATION COMMAND sent * GUTI REALLOCATION COMMAND sent */
*/
MME_TIMER_T3450, MME_TIMER_T3450,
/*
* AUTHENTICATION REQUEST sent /* AUTHENTICATION REQUEST sent
* SECURITY MODE COMMAND sent * SECURITY MODE COMMAND sent */
*/
MME_TIMER_T3460, MME_TIMER_T3460,
MME_TIMER_T3470, /* IDENTITY REQUEST sent */ /* IDENTITY REQUEST sent */
MME_TIMER_T3470,
/* ESM INFORMATION REQUEST sent */
MME_TIMER_T3489,
MME_TIMER_SGS_CLI_CONN_TO_SRV, MME_TIMER_SGS_CLI_CONN_TO_SRV,
@ -72,6 +76,7 @@ void mme_timer_t3422_expire(void *data);
void mme_timer_t3450_expire(void *data); void mme_timer_t3450_expire(void *data);
void mme_timer_t3460_expire(void *data); void mme_timer_t3460_expire(void *data);
void mme_timer_t3470_expire(void *data); void mme_timer_t3470_expire(void *data);
void mme_timer_t3489_expire(void *data);
void mme_timer_sgs_cli_conn_to_srv(void *data); void mme_timer_sgs_cli_conn_to_srv(void *data);

View File

@ -318,8 +318,16 @@ int nas_send_esm_information_request(mme_bearer_t *bearer)
mme_ue = bearer->mme_ue; mme_ue = bearer->mme_ue;
ogs_assert(mme_ue); ogs_assert(mme_ue);
rv = esm_build_information_request(&esmbuf, bearer); if (bearer->t3489.pkbuf) {
ogs_assert(rv == OGS_OK && esmbuf); esmbuf = bearer->t3489.pkbuf;
} else {
rv = esm_build_information_request(&esmbuf, bearer);
ogs_assert(rv == OGS_OK && esmbuf);
}
bearer->t3489.pkbuf = ogs_pkbuf_copy(esmbuf);
ogs_timer_start(bearer->t3489.timer,
mme_timer_cfg(MME_TIMER_T3489)->duration);
rv = nas_send_to_downlink_nas_transport(mme_ue, esmbuf); rv = nas_send_to_downlink_nas_transport(mme_ue, esmbuf);
ogs_assert(rv == OGS_OK); ogs_assert(rv == OGS_OK);