forked from acouzens/open5gs
[#220] fix RACE-CONDITION for MESSAGE and TIMER
This commit is contained in:
parent
649b6ec5e9
commit
d9238e3036
|
@ -93,8 +93,30 @@ static void mme_main(void *data)
|
|||
ogs_pollset_poll(mme_self()->pollset,
|
||||
ogs_timer_mgr_next(mme_self()->timer_mgr));
|
||||
|
||||
/* Process the MESSAGE FIRST.
|
||||
*
|
||||
* For example, if UE Context Release Complete is received,
|
||||
* the MME_TIMER_UE_CONTEXT_RELEASE is first stopped */
|
||||
for ( ;; ) {
|
||||
mme_event_t *e = NULL;
|
||||
|
||||
rv = ogs_queue_trypop(mme_self()->queue, (void**)&e);
|
||||
ogs_assert(rv != OGS_ERROR);
|
||||
|
||||
if (rv == OGS_DONE)
|
||||
goto done;
|
||||
|
||||
if (rv == OGS_RETRY)
|
||||
break;
|
||||
|
||||
ogs_assert(e);
|
||||
ogs_fsm_dispatch(&mme_sm, e);
|
||||
mme_event_free(e);
|
||||
}
|
||||
|
||||
ogs_timer_mgr_expire(mme_self()->timer_mgr);
|
||||
|
||||
/* AND THEN, process the TIMER. */
|
||||
for ( ;; ) {
|
||||
mme_event_t *e = NULL;
|
||||
|
||||
|
|
|
@ -219,24 +219,7 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
|
|||
ogs_assert(enb);
|
||||
ogs_assert(OGS_FSM_STATE(&enb->sm));
|
||||
|
||||
/*
|
||||
* MME main loop is as below,
|
||||
* 1. Wait Poll. If S1AP message is received, Awake Poll
|
||||
* 2. Check Timer Expiration. If Timer is expired, push Queue
|
||||
* 3. In this situation,
|
||||
* 3-1. S1AP message is processed
|
||||
* 3-1. And then, Timer handler is processed.
|
||||
*
|
||||
* If UE Context Release Complete is received,
|
||||
* 1. enb_ue context is removed.
|
||||
* 2. And then, timer handler retransmits UE context release command.
|
||||
*
|
||||
* The race-condition is raised,
|
||||
* So, we should check whether the enb_ue context is removed or not.
|
||||
*/
|
||||
if (enb_ue_find_by_mme_ue_s1ap_id(enb_ue->mme_ue_s1ap_id)) {
|
||||
ogs_fsm_dispatch(&enb->sm, e);
|
||||
}
|
||||
ogs_fsm_dispatch(&enb->sm, e);
|
||||
break;
|
||||
|
||||
case MME_EVT_EMM_MESSAGE:
|
||||
|
|
|
@ -24,18 +24,35 @@
|
|||
static mme_timer_cfg_t g_mme_timer_cfg[MAX_NUM_OF_MME_TIMER] = {
|
||||
[MME_TIMER_UE_CONTEXT_RELEASE] =
|
||||
{ .max_count = 2, .duration = ogs_time_from_sec(1) },
|
||||
|
||||
/* Paging procedure for EPS services initiated */
|
||||
[MME_TIMER_T3413] =
|
||||
{ .max_count = 2, .duration = ogs_time_from_sec(2) },
|
||||
|
||||
/* DETACH REQUEST sent */
|
||||
[MME_TIMER_T3422] =
|
||||
{ .max_count = 4, .duration = ogs_time_from_sec(3) },
|
||||
|
||||
/* ATTACH ACCEPT sent
|
||||
* TRACKING AREA UPDATE ACCEPT sent with GUTI
|
||||
* TRACKING AREA UPDATE ACCEPT sent with TMSI
|
||||
* GUTI REALLOCATION COMMAND sent */
|
||||
[MME_TIMER_T3450] =
|
||||
{ .max_count = 4, .duration = ogs_time_from_sec(3) },
|
||||
|
||||
/* AUTHENTICATION REQUEST sent
|
||||
* SECURITY MODE COMMAND sent */
|
||||
[MME_TIMER_T3460] =
|
||||
{ .max_count = 4, .duration = ogs_time_from_sec(3) },
|
||||
|
||||
/* IDENTITY REQUEST sent */
|
||||
[MME_TIMER_T3470] =
|
||||
{ .max_count = 4, .duration = ogs_time_from_sec(3) },
|
||||
|
||||
/* ESM INFORMATION REQUEST sent */
|
||||
[MME_TIMER_T3489] =
|
||||
{ .max_count = 2, .duration = ogs_time_from_sec(4) },
|
||||
|
||||
[MME_TIMER_SGS_CLI_CONN_TO_SRV] =
|
||||
{ .duration = ogs_time_from_sec(3) },
|
||||
};
|
||||
|
|
|
@ -34,26 +34,11 @@ typedef enum {
|
|||
|
||||
MME_TIMER_UE_CONTEXT_RELEASE,
|
||||
|
||||
/* Paging procedure for EPS services initiated */
|
||||
MME_TIMER_T3413,
|
||||
|
||||
/* DETACH REQUEST sent */
|
||||
MME_TIMER_T3422,
|
||||
|
||||
/* ATTACH ACCEPT sent
|
||||
* TRACKING AREA UPDATE ACCEPT sent with GUTI
|
||||
* TRACKING AREA UPDATE ACCEPT sent with TMSI
|
||||
* GUTI REALLOCATION COMMAND sent */
|
||||
MME_TIMER_T3450,
|
||||
|
||||
/* AUTHENTICATION REQUEST sent
|
||||
* SECURITY MODE COMMAND sent */
|
||||
MME_TIMER_T3460,
|
||||
|
||||
/* IDENTITY REQUEST sent */
|
||||
MME_TIMER_T3470,
|
||||
|
||||
/* ESM INFORMATION REQUEST sent */
|
||||
MME_TIMER_T3489,
|
||||
|
||||
MME_TIMER_SGS_CLI_CONN_TO_SRV,
|
||||
|
|
|
@ -96,13 +96,10 @@ int s1ap_send_to_enb(mme_enb_t *enb, ogs_pkbuf_t *pkbuf, uint16_t stream_no)
|
|||
int s1ap_send_to_enb_ue(enb_ue_t *enb_ue, ogs_pkbuf_t *pkbuf)
|
||||
{
|
||||
mme_enb_t *enb = NULL;
|
||||
mme_ue_t *mme_ue = NULL;
|
||||
|
||||
ogs_assert(enb_ue);
|
||||
enb = enb_ue->enb;
|
||||
ogs_assert(enb);
|
||||
mme_ue = enb_ue->mme_ue;
|
||||
ogs_assert(mme_ue);
|
||||
|
||||
return s1ap_send_to_enb(enb, pkbuf, enb_ue->enb_ostream_id);
|
||||
}
|
||||
|
|
|
@ -90,8 +90,30 @@ static void pgw_main(void *data)
|
|||
ogs_pollset_poll(pgw_self()->pollset,
|
||||
ogs_timer_mgr_next(pgw_self()->timer_mgr));
|
||||
|
||||
/* Process the MESSAGE FIRST.
|
||||
*
|
||||
* For example, if UE Context Release Complete is received,
|
||||
* the MME_TIMER_UE_CONTEXT_RELEASE is first stopped */
|
||||
for ( ;; ) {
|
||||
pgw_event_t *e = NULL;
|
||||
|
||||
rv = ogs_queue_trypop(pgw_self()->queue, (void**)&e);
|
||||
ogs_assert(rv != OGS_ERROR);
|
||||
|
||||
if (rv == OGS_DONE)
|
||||
goto done;
|
||||
|
||||
if (rv == OGS_RETRY)
|
||||
break;
|
||||
|
||||
ogs_assert(e);
|
||||
ogs_fsm_dispatch(&pgw_sm, e);
|
||||
pgw_event_free(e);
|
||||
}
|
||||
|
||||
ogs_timer_mgr_expire(pgw_self()->timer_mgr);
|
||||
|
||||
/* AND THEN, process the TIMER. */
|
||||
for ( ;; ) {
|
||||
pgw_event_t *e = NULL;
|
||||
|
||||
|
|
|
@ -80,8 +80,30 @@ static void sgw_main(void *data)
|
|||
ogs_pollset_poll(sgw_self()->pollset,
|
||||
ogs_timer_mgr_next(sgw_self()->timer_mgr));
|
||||
|
||||
/* Process the MESSAGE FIRST.
|
||||
*
|
||||
* For example, if UE Context Release Complete is received,
|
||||
* the MME_TIMER_UE_CONTEXT_RELEASE is first stopped */
|
||||
for ( ;; ) {
|
||||
sgw_event_t *e = NULL;
|
||||
|
||||
rv = ogs_queue_trypop(sgw_self()->queue, (void**)&e);
|
||||
ogs_assert(rv != OGS_ERROR);
|
||||
|
||||
if (rv == OGS_DONE)
|
||||
goto done;
|
||||
|
||||
if (rv == OGS_RETRY)
|
||||
break;
|
||||
|
||||
ogs_assert(e);
|
||||
ogs_fsm_dispatch(&sgw_sm, e);
|
||||
sgw_event_free(e);
|
||||
}
|
||||
|
||||
ogs_timer_mgr_expire(sgw_self()->timer_mgr);
|
||||
|
||||
/* AND THEN, process the TIMER. */
|
||||
for ( ;; ) {
|
||||
sgw_event_t *e = NULL;
|
||||
|
||||
|
|
Loading…
Reference in New Issue