[AMF/MME] Add retransmission for accept message

Registration accept with GUTI
Attach accept
Tracking area update request with GUTI
This commit is contained in:
Sukchan Lee 2021-04-23 15:16:18 +09:00
parent 2766a1ce2c
commit dcfc9ef803
11 changed files with 243 additions and 279 deletions

View File

@ -53,8 +53,6 @@ ogs_pkbuf_t *gmm_build_registration_accept(amf_ue_t *amf_ue)
ogs_assert(amf_ue);
ogs_debug("[%s] Registration accept", amf_ue->supi);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
@ -196,8 +194,6 @@ ogs_pkbuf_t *gmm_build_service_accept(amf_ue_t *amf_ue)
pdu_session_reactivation_result;
ogs_assert(pdu_session_reactivation_result);
ogs_debug("[%s] Service accept", amf_ue->supi);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
@ -241,8 +237,6 @@ ogs_pkbuf_t *gmm_build_service_reject(
pdu_session_status = &service_reject->pdu_session_status;
ogs_debug("Service reject");
memset(&message, 0, sizeof(message));
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
@ -274,8 +268,6 @@ ogs_pkbuf_t *gmm_build_de_registration_accept(amf_ue_t *amf_ue)
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
ogs_debug("[%s] De-registration accept", amf_ue->supi);
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_DEREGISTRATION_ACCEPT;
@ -633,184 +625,6 @@ ogs_pkbuf_t *gmm_build_dl_nas_transport(amf_sess_t *sess,
return gmmbuf;
}
#if 0
ogs_pkbuf_t *gmm_build_tau_accept(amf_ue_t *amf_ue)
{
ogs_nas_5gs_message_t message;
ogs_nas_5gs_tracking_area_update_accept_t *tau_accept =
&message.gmm.tracking_area_update_accept;
int served_tai_index = 0;
amf_sess_t *sess = NULL;
ogs_assert(amf_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_TRACKING_AREA_UPDATE_ACCEPT;
tau_accept->eps_update_result.result = amf_ue->nas_5gs.update.value;
/* Set T3512 */
tau_accept->presencemask |=
OGS_NAS_5GS_TRACKING_AREA_UPDATE_ACCEPT_T3512_VALUE_PRESENT ;
tau_accept->t3512_value.unit = OGS_NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_DECI_HH;
tau_accept->t3512_value.value = 9;
/* Set TAI */
tau_accept->presencemask |=
OGS_NAS_5GS_TRACKING_AREA_UPDATE_ACCEPT_TAI_LIST_PRESENT;
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&amf_ue->nr_tai.plmn_id),
amf_ue->nr_tai.tac);
ogs_debug(" E_CGI[PLMN_ID:%06x,CELL_ID:%d]",
ogs_plmn_id_hexdump(&amf_ue->e_cgi.plmn_id),
amf_ue->e_cgi.cell_id);
served_tai_index = amf_find_served_tai(&amf_ue->nr_tai);
ogs_debug(" SERVED_TAI_INDEX[%d]", served_tai_index);
ogs_assert(served_tai_index >= 0 &&
served_tai_index < OGS_MAX_NUM_OF_SERVED_TAI);
ogs_nas_tai_list_build(&tau_accept->tai_list,
&amf_self()->served_tai[served_tai_index].list0,
&amf_self()->served_tai[served_tai_index].list2);
/* Set EPS bearer context status */
tau_accept->presencemask |=
OGS_NAS_5GS_TRACKING_AREA_UPDATE_ACCEPT_EPS_BEARER_CONTEXT_STATUS_PRESENT;
tau_accept->eps_bearer_context_status.length = 2;
sess = amf_sess_first(amf_ue);
while (sess) {
amf_bearer_t *bearer = amf_bearer_first(sess);
while (bearer) {
switch (bearer->ebi) {
case 5: tau_accept->eps_bearer_context_status.ebi5 = 1; break;
case 6: tau_accept->eps_bearer_context_status.ebi6 = 1; break;
case 7: tau_accept->eps_bearer_context_status.ebi7 = 1; break;
case 8: tau_accept->eps_bearer_context_status.ebi8 = 1; break;
case 9: tau_accept->eps_bearer_context_status.ebi9 = 1; break;
case 10: tau_accept->eps_bearer_context_status.ebi10 = 1; break;
case 11: tau_accept->eps_bearer_context_status.ebi11 = 1; break;
case 12: tau_accept->eps_bearer_context_status.ebi12 = 1; break;
case 13: tau_accept->eps_bearer_context_status.ebi13 = 1; break;
case 14: tau_accept->eps_bearer_context_status.ebi14 = 1; break;
case 15: tau_accept->eps_bearer_context_status.ebi15 = 1; break;
default: break;
}
bearer = amf_bearer_next(bearer);
}
sess = amf_sess_next(sess);
}
#if 0 /* Need not to include T3502 */
/* Set T3502 */
tau_accept->presencemask |=
OGS_NAS_5GS_TRACKING_AREA_UPDATE_ACCEPT_T3502_VALUE_PRESENT;
tau_accept->t3502_value.unit = OGS_NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_1_MM;
tau_accept->t3502_value.value = 12;
#endif
/* Set T3523 */
tau_accept->presencemask |=
OGS_NAS_5GS_TRACKING_AREA_UPDATE_ACCEPT_T3523_VALUE_PRESENT;
tau_accept->t3523_value.unit = OGS_NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_DECI_HH;
tau_accept->t3523_value.value = 9;
/* Set EPS network feature support */
tau_accept->presencemask |=
OGS_NAS_5GS_TRACKING_AREA_UPDATE_ACCEPT_EPS_NETWORK_FEATURE_SUPPORT_PRESENT;
tau_accept->eps_network_feature_support.length = 1;
tau_accept->eps_network_feature_support.ims_vops = 1;
return nas_5gs_security_encode(amf_ue, &message);
}
ogs_pkbuf_t *gmm_build_tau_reject(
ogs_nas_5gmm_cause_t gmm_cause, amf_ue_t *amf_ue)
{
ogs_nas_5gs_message_t message;
ogs_nas_5gs_tracking_area_update_reject_t *tau_reject =
&message.gmm.tracking_area_update_reject;
ogs_assert(amf_ue);
ogs_debug("Tracking area update reject");
ogs_debug(" IMSI[%s] Cause[%d]",
MME_UE_HAVE_IMSI(amf_ue) ? amf_ue->imsi_bcd : "Unknown", gmm_cause);
memset(&message, 0, sizeof(message));
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_TRACKING_AREA_UPDATE_REJECT;
tau_reject->gmm_cause = gmm_cause;
return ogs_nas_5gs_plain_encode(&message);
}
ogs_pkbuf_t *gmm_build_cs_service_notification(amf_ue_t *amf_ue)
{
ogs_nas_5gs_message_t message;
ogs_nas_5gs_cs_service_notification_t *cs_service_notification =
&message.gmm.cs_service_notification;
ogs_nas_paging_identity_t *paging_identity =
&cs_service_notification->paging_identity;
ogs_assert(amf_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_CS_SERVICE_NOTIFICATION;
/* FIXME : Does it right to use TMSI */
paging_identity->identity = OGS_NAS_PAGING_IDENTITY_TMSI;
ogs_debug(" Paging Identity[%d]", paging_identity->identity);
/* FIXME : What optional filed should be included in this message? */
return nas_5gs_security_encode(amf_ue, &message);
}
ogs_pkbuf_t *gmm_build_downlink_nas_transport(
amf_ue_t *amf_ue, uint8_t *buffer, uint8_t length)
{
ogs_nas_5gs_message_t message;
ogs_nas_5gs_downlink_nas_transport_t *downlink_nas_transport =
&message.gmm.downlink_nas_transport;
ogs_nas_5gs_message_container_t *nas_message_container =
&downlink_nas_transport->nas_message_container;
ogs_assert(amf_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_DOWNLINK_NAS_TRANSPORT;
nas_message_container->length = length;
memcpy(nas_message_container->buffer, buffer, length);
return nas_5gs_security_encode(amf_ue, &message);
}
#endif
ogs_pkbuf_t *gmm_build_status(amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t cause)
{

View File

@ -191,6 +191,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
break;
}
CLEAR_AMF_UE_TIMER(amf_ue->t3550);
nas_5gs_send_registration_accept(amf_ue);
}
@ -907,36 +908,13 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
break;
}
/*
* The usage of guti_present is changed
* This following code should be removed.
*/
#if 0
/*
* Issues #553
*
* o Tester
* 1. UE registered to 5GS and can connect to internet.
* 2. Turn off the UE and turn on the UE immediately
* 3. UE send PDU session request message
* without sending registration complete
*
* o Analysis Result
* 1. UE sends registration request with unknown GUTI
* 2. AMF send registration accept without GUTI
* 3. UE skips the registration complete
*
* So, if GUTI is not present,
* we need to move REGISTERED state.
*/
if (amf_ue->guti_present == 0)
OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_registered);
#endif
/* If nas_5gs_send_service_accept() used, we need change it. */
ogs_assert(amf_ue->nas.message_type ==
OGS_NAS_5GS_REGISTRATION_REQUEST);
CLEAR_AMF_UE_TIMER(amf_ue->t3550);
nas_5gs_send_registration_accept(amf_ue);
if (!amf_ue->next.m_tmsi)
OGS_FSM_TRAN(s, &gmm_state_registered);
break;
DEFAULT
@ -960,6 +938,8 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
case OGS_NAS_5GS_REGISTRATION_COMPLETE:
ogs_info("[%s] Registration complete", amf_ue->supi);
CLEAR_AMF_UE_TIMER(amf_ue->t3550);
/* Confirm GUTI */
if (amf_ue->next.m_tmsi) {
amf_ue_confirm_guti(amf_ue);
@ -1045,8 +1025,19 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
break;
case AMF_EVT_5GMM_TIMER:
switch (e->timer_id) {
case AMF_TIMER_T3550:
if (amf_ue->t3550.retry_count >=
amf_timer_cfg(AMF_TIMER_T3550)->max_count) {
ogs_warn("[%s] Retransmission failed. Stop retransmission",
amf_ue->suci);
OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_exception);
} else {
amf_ue->t3550.retry_count++;
nas_5gs_send_registration_accept(amf_ue);
}
break;
default:
ogs_error("Unknown timer[%s:%d]",
ogs_error("[%s] Unknown timer[%s:%d]", amf_ue->suci,
amf_timer_get_name(e->timer_id), e->timer_id);
break;
}
@ -1122,6 +1113,8 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
if (!AMF_UE_HAVE_SUCI(amf_ue)) {
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
nas_5gs_send_identity_request(amf_ue);
OGS_FSM_TRAN(s, &gmm_state_de_registered);
break;
}
@ -1173,6 +1166,7 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
break;
}
CLEAR_AMF_UE_TIMER(amf_ue->t3550);
nas_5gs_send_registration_accept(amf_ue);
}

View File

@ -77,8 +77,25 @@ void nas_5gs_send_registration_accept(amf_ue_t *amf_ue)
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
ogs_assert(ran_ue);
gmmbuf = gmm_build_registration_accept(amf_ue);
ogs_expect_or_return(gmmbuf);
ogs_debug("[%s] Registration accept", amf_ue->supi);
if (amf_ue->next.m_tmsi) {
if (amf_ue->t3550.pkbuf) {
gmmbuf = amf_ue->t3550.pkbuf;
ogs_expect_or_return(gmmbuf);
} else {
gmmbuf = gmm_build_registration_accept(amf_ue);
ogs_expect_or_return(gmmbuf);
}
amf_ue->t3550.pkbuf = ogs_pkbuf_copy(gmmbuf);
ogs_assert(amf_ue->t3550.pkbuf);
ogs_timer_start(amf_ue->t3550.timer,
amf_timer_cfg(AMF_TIMER_T3550)->duration);
} else {
gmmbuf = gmm_build_registration_accept(amf_ue);
ogs_expect_or_return(gmmbuf);
}
/*
* Previously, AMF would sends PDUSessionResourceSetupRequest
@ -158,6 +175,8 @@ void nas_5gs_send_service_accept(amf_ue_t *amf_ue)
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
ogs_assert(ran_ue);
ogs_debug("[%s] Service accept", amf_ue->supi);
gmmbuf = gmm_build_service_accept(amf_ue);
ogs_expect_or_return(gmmbuf);
@ -213,6 +232,8 @@ void nas_5gs_send_service_reject(
ogs_assert(amf_ue);
ogs_debug("[%s] Service reject", amf_ue->supi);
gmmbuf = gmm_build_service_reject(amf_ue, gmm_cause);
ogs_expect_or_return(gmmbuf);
@ -229,6 +250,8 @@ void nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue)
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
ogs_assert(ran_ue);
ogs_debug("[%s] De-registration accept", amf_ue->supi);
if (amf_ue->nas.de_registration.switch_off == 0) {
int rv;

View File

@ -2418,6 +2418,11 @@ void ngap_handle_handover_required(
/* Source UE - Target UE associated */
source_ue_associate_target_ue(source_ue, target_ue);
/* Context Transfer */
target_ue->ue_context_requested = source_ue->ue_context_requested;
target_ue->initial_context_setup_request_sent =
source_ue->initial_context_setup_request_sent;
ogs_debug(" Target : RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld] ",
target_ue->ran_ue_ngap_id, (long long)target_ue->amf_ue_ngap_id);

View File

@ -194,9 +194,11 @@ int amf_nsmf_pdusession_handle_update_sm_context(
ogs_pkbuf_copy(n2smbuf));
if (SESSION_SYNC_DONE(amf_ue,
AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) &&
AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) &&
SESSION_SYNC_DONE(amf_ue,
AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST)) {
CLEAR_AMF_UE_TIMER(amf_ue->t3550);
nas_5gs_send_registration_accept(amf_ue);
AMF_UE_CLEAR_N2_TRANSFER(
@ -631,6 +633,8 @@ int amf_nsmf_pdusession_handle_release_sm_context(amf_sess_t *sess, int state)
amf_ue, AMF_RELEASE_SM_CONTEXT_REGISTRATION_ACCEPT) &&
SESSION_SYNC_DONE(
amf_ue, AMF_UPDATE_SM_CONTEXT_REGISTRATION_REQUEST))
CLEAR_AMF_UE_TIMER(amf_ue->t3550);
nas_5gs_send_registration_accept(amf_ue);
} else if (state == AMF_RELEASE_SM_CONTEXT_SERVICE_ACCEPT) {

View File

@ -27,14 +27,11 @@ static amf_timer_cfg_t g_amf_timer_cfg[MAX_NUM_OF_AMF_TIMER] = {
[AMF_TIMER_T3513] =
{ .max_count = 2, .duration = ogs_time_from_sec(2) },
/* DETACH REQUEST sent */
/* DEREGISTRATION REQUEST sent */
[AMF_TIMER_T3522] =
{ .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 */
/* REGISTRATION ACCEPT sent */
[AMF_TIMER_T3550] =
{ .max_count = 4, .duration = ogs_time_from_sec(6) },

View File

@ -45,8 +45,6 @@ ogs_pkbuf_t *emm_build_attach_accept(
ogs_assert(mme_ue);
ogs_assert(esmbuf);
ogs_debug("Attach accept");
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
@ -364,9 +362,6 @@ ogs_pkbuf_t *emm_build_detach_accept(mme_ue_t *mme_ue)
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
ogs_debug("Detach accept");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_DETACH_ACCEPT;
@ -512,9 +507,7 @@ ogs_pkbuf_t *emm_build_tau_reject(
ogs_assert(mme_ue);
ogs_debug("Tracking area update reject");
ogs_debug(" IMSI[%s] Cause[%d]",
MME_UE_HAVE_IMSI(mme_ue) ? mme_ue->imsi_bcd : "Unknown", emm_cause);
ogs_debug(" Cause[%d]", emm_cause);
memset(&message, 0, sizeof(message));
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
@ -533,9 +526,6 @@ ogs_pkbuf_t *emm_build_service_reject(
ogs_assert(mme_ue);
ogs_debug("Service reject");
ogs_debug(" Cause[%d]", emm_cause);
memset(&message, 0, sizeof(message));
message.emm.h.protocol_discriminator = OGS_NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = OGS_NAS_EPS_SERVICE_REJECT;

View File

@ -120,7 +120,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
if (message->emm.h.security_header_type
== OGS_NAS_SECURITY_HEADER_FOR_SERVICE_REQUEST_MESSAGE) {
ogs_info("Service request");
ogs_info("[%s] Service request", mme_ue->imsi_bcd);
rv = emm_handle_service_request(
mme_ue, &message->emm.service_request);
if (rv != OGS_OK) {
@ -239,7 +239,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
break;
case OGS_NAS_EPS_TRACKING_AREA_UPDATE_REQUEST:
ogs_info("Tracking area update request");
ogs_info("[%s] Tracking area update request", mme_ue->imsi_bcd);
rv = emm_handle_tau_request(mme_ue,
&message->emm.tracking_area_update_request, e->pkbuf);
if (rv != OGS_OK) {
@ -278,6 +278,71 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
break;
}
/*
* <EMM-IDLE State>
* 1. InitialUEMessage + Tracking area update request
* Active flag : No bearer establishment requested (0)
* EPS update type : TA updating (0) or Periodic updating (3)
* 2. DownlinkNASTransport + Tracking area update accept
* EPS update result value : TA updated (0)
* 3. UEContextReleaseCommand
* Cause : nas(2) + normal-release(0)
* 4. UEContextReleaseComplete
*
* <EMM-IDLE State>
* 1. InitialUEMessage + Tracking area update request
* Active flag : bearer establishment requested (1)
* EPS update type : Combined TA/LA updating with IMSI attach (2)
* 2. InitialContextSetupRequest + Tracking area update accept
* EPS update result : Combined TA/LA updated (1)
* New GUTI
* 3. InitialContextSetupResponse
* 4. UplinkNASTransport + Tracking area update complete
*
* <De-registered State>
* 1. S1SetupRequest/S1SetupResponse
* 2. InitialUEMessage + Tracking area update request
* Active flag : bearer establishment requested (1)
* EPS update type : Periodic updating (3)
* 3. InitialContextSetupRequest + Tracking area update accept
* EPS update result : TA updated (0)
* No GUTI
* 4. InitialContextSetupResponse
*
* <Handover>
* 1. HandoverNotify (Target)
* 2. UplinkNASTransport + Tracking area update request (Target)
* Active flag : bearer establishment requested (1)
* EPS update type : TA updating (0)
* 3. UEContextReleaseCommand (Source)
* Cause : radioNetwork(0) + successful-handover(2)
* 4. UEcontextReleaseComplete (Source)
* 5. DownlinkNASTransport + Tracking area update accept (Target)
* EPS update result : TA updated (0)
*
* <Handover + EMM-Idle State>
* 1. HandoverNotify (Target)
*
* 2. UEContextReleaseCommand (Source)
* Cause : radioNetwork(0) + successful-handover(2)
* 3. UEcontextReleaseComplete (Source)
* 4. UEContextReleaseRequest (Target)
* Cause : transport(1) + transport-resource-unavailable(0)
* 5. UEContextReleaseCommand (Target)
* Cause : nas(2) + normal-release(0)
* 6. UEcontextReleaseComplete (Target)
*
* 7. InitialUEMessage + Tracking area update request (Target)
* Active flag : bearer establishment requested (1)
* EPS update type : TA updating (0)
* 8. InitialContextSetupRequest + Tracking area update accept
* EPS update result : TA updated (0)
* New GUTI
* 9. InitialContextSetupResponse (Target)
* EPS update result : TA updated (0)
* 10. UplinkNASTransport + Tracking area update complete (Target)
*/
if (e->s1ap_code == S1AP_ProcedureCode_id_initialUEMessage) {
ogs_debug(" Iniital UE Message");
if (mme_ue->nas_eps.update.active_flag) {
@ -286,8 +351,6 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
} else {
nas_eps_send_tau_accept(mme_ue,
S1AP_ProcedureCode_id_downlinkNASTransport);
mme_send_release_access_bearer_or_ue_context_release(
enb_ue);
}
} else if (e->s1ap_code ==
S1AP_ProcedureCode_id_uplinkNASTransport) {
@ -297,24 +360,21 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
} else {
ogs_fatal("Invalid Procedure Code[%d]", (int)e->s1ap_code);
}
OGS_FSM_TRAN(s, &emm_state_registered);
break;
if (!mme_ue->nas_eps.update.active_flag)
mme_send_release_access_bearer_or_ue_context_release(enb_ue);
case OGS_NAS_EPS_TRACKING_AREA_UPDATE_COMPLETE:
ogs_info("Tracking area update complete");
ogs_info(" IMSI[%s]", mme_ue->imsi_bcd);
/* Confirm GUTI */
if (mme_ue->next.m_tmsi) {
mme_ue_confirm_guti(mme_ue);
ogs_fatal("MME does not create new GUTI");
ogs_assert_if_reached();
OGS_FSM_TRAN(s, &emm_state_initial_context_setup);
} else {
ogs_error("[%s] No GUTI allocated", mme_ue->imsi_bcd);
OGS_FSM_TRAN(s, &emm_state_registered);
}
break;
case OGS_NAS_EPS_EXTENDED_SERVICE_REQUEST:
ogs_info("Extended service request");
ogs_info("[%s] Extended service request", mme_ue->imsi_bcd);
rv = emm_handle_extended_service_request(
mme_ue, &message->emm.extended_service_request);
if (rv != OGS_OK) {
@ -429,7 +489,7 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
break;
case OGS_NAS_EPS_DETACH_REQUEST:
ogs_info("Detach request");
ogs_info("[%s] Detach request", mme_ue->imsi_bcd);
rv = emm_handle_detach_request(
mme_ue, &message->emm.detach_request_from_ue);
if (rv != OGS_OK) {
@ -473,6 +533,11 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
mme_ue->imsi_bcd);
break;
case OGS_NAS_EPS_TRACKING_AREA_UPDATE_COMPLETE:
ogs_error("[%s] Tracking area update complete in INVALID-STATE",
mme_ue->imsi_bcd);
break;
default:
ogs_warn("Unknown message[%d]", message->emm.h.message_type);
}
@ -515,7 +580,6 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
mme_timer_cfg(MME_TIMER_T3470)->max_count) {
ogs_warn("Retransmission of Identity-Request failed. "
"Stop retransmission");
CLEAR_MME_UE_TIMER(mme_ue->t3470);
OGS_FSM_TRAN(&mme_ue->sm, &emm_state_exception);
} else {
mme_ue->t3470.retry_count++;
@ -672,8 +736,7 @@ void emm_state_authentication(ogs_fsm_t *s, mme_event_t *e)
if (mme_ue->t3460.retry_count >=
mme_timer_cfg(MME_TIMER_T3460)->max_count) {
ogs_warn("Retransmission of IMSI[%s] failed. "
"Stop retransmission",
mme_ue->imsi_bcd);
"Stop retransmission", mme_ue->imsi_bcd);
OGS_FSM_TRAN(&mme_ue->sm, &emm_state_exception);
nas_eps_send_authentication_reject(mme_ue);
@ -769,14 +832,13 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
mme_ue_new_guti(mme_ue);
mme_s6a_send_ulr(mme_ue);
if (mme_ue->nas_eps.type == MME_EPS_TYPE_ATTACH_REQUEST) {
if (mme_ue->next.m_tmsi) {
OGS_FSM_TRAN(s, &emm_state_initial_context_setup);
} else if (mme_ue->nas_eps.type ==
MME_EPS_TYPE_SERVICE_REQUEST ||
mme_ue->nas_eps.type == MME_EPS_TYPE_TAU_REQUEST) {
OGS_FSM_TRAN(s, &emm_state_registered);
} else {
ogs_fatal("Invalid OGS_NAS_EPS[%d]", mme_ue->nas_eps.type);
ogs_fatal("MME always creates new GUTI");
ogs_assert_if_reached();
OGS_FSM_TRAN(s, &emm_state_registered);
}
break;
case OGS_NAS_EPS_SECURITY_MODE_REJECT:
@ -835,8 +897,7 @@ void emm_state_security_mode(ogs_fsm_t *s, mme_event_t *e)
if (mme_ue->t3460.retry_count >=
mme_timer_cfg(MME_TIMER_T3460)->max_count) {
ogs_warn("Retransmission of IMSI[%s] failed. "
"Stop retransmission",
mme_ue->imsi_bcd);
"Stop retransmission", mme_ue->imsi_bcd);
OGS_FSM_TRAN(&mme_ue->sm, &emm_state_exception);
nas_eps_send_attach_reject(mme_ue,
@ -894,7 +955,9 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
switch (message->emm.h.message_type) {
case OGS_NAS_EPS_ATTACH_COMPLETE:
ogs_info("Attach complete");
ogs_info("[%s] Attach complete", mme_ue->imsi_bcd);
CLEAR_MME_UE_TIMER(mme_ue->t3450);
h.type = e->nas_type;
if (h.integrity_protected == 0) {
@ -934,6 +997,39 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
OGS_FSM_TRAN(s, &emm_state_registered);
break;
case OGS_NAS_EPS_TRACKING_AREA_UPDATE_COMPLETE:
ogs_debug("[%s] Tracking area update complete", mme_ue->imsi_bcd);
CLEAR_MME_UE_TIMER(mme_ue->t3450);
h.type = e->nas_type;
if (h.integrity_protected == 0) {
ogs_error("[%s] No Integrity Protected", mme_ue->imsi_bcd);
nas_eps_send_attach_reject(mme_ue,
EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED,
ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
OGS_FSM_TRAN(s, &emm_state_exception);
break;
}
if (!SECURITY_CONTEXT_IS_VALID(mme_ue)) {
ogs_warn("[%s] No Security Context", mme_ue->imsi_bcd);
nas_eps_send_attach_reject(mme_ue,
EMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED,
ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
OGS_FSM_TRAN(s, &emm_state_exception);
break;
}
/* Confirm GUTI */
if (mme_ue->next.m_tmsi)
mme_ue_confirm_guti(mme_ue);
OGS_FSM_TRAN(s, &emm_state_registered);
break;
case OGS_NAS_EPS_ATTACH_REQUEST:
ogs_warn("[%s] Attach request", mme_ue->imsi_bcd);
rv = emm_handle_attach_request(
@ -972,13 +1068,36 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
mme_ue->imsi_bcd);
break;
default:
ogs_warn("Unknown message[%d]",
message->emm.h.message_type);
ogs_warn("Unknown message[%d]", message->emm.h.message_type);
break;
}
break;
case MME_EVT_EMM_TIMER:
switch (e->timer_id) {
case MME_TIMER_T3450:
if (mme_ue->t3450.retry_count >=
mme_timer_cfg(MME_TIMER_T3450)->max_count) {
ogs_warn("Retransmission of IMSI[%s] failed. "
"Stop retransmission", mme_ue->imsi_bcd);
OGS_FSM_TRAN(&mme_ue->sm, &emm_state_exception);
} else {
ogs_pkbuf_t *emmbuf = NULL;
mme_ue->t3450.retry_count++;
emmbuf = mme_ue->t3450.pkbuf;
ogs_expect_or_return(emmbuf);
mme_ue->t3450.pkbuf = ogs_pkbuf_copy(emmbuf);
ogs_assert(mme_ue->t3450.pkbuf);
ogs_timer_start(mme_ue->t3450.timer,
mme_timer_cfg(MME_TIMER_T3450)->duration);
rv = nas_eps_send_to_downlink_nas_transport(mme_ue, emmbuf);
ogs_expect(rv == OGS_OK);
}
break;
default:
ogs_error("Unknown timer[%s:%d]",
mme_timer_get_name(e->timer_id), e->timer_id);
@ -1037,6 +1156,8 @@ void emm_state_exception(ogs_fsm_t *s, mme_event_t *e)
if (!MME_UE_HAVE_IMSI(mme_ue)) {
CLEAR_MME_UE_TIMER(mme_ue->t3470);
nas_eps_send_identity_request(mme_ue);
OGS_FSM_TRAN(s, &emm_state_de_registered);
break;
}

View File

@ -482,10 +482,10 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
nas_eps_send_tau_accept(mme_ue,
S1AP_ProcedureCode_id_InitialContextSetup);
} else if (mme_ue->nas_eps.type == MME_EPS_TYPE_SERVICE_REQUEST) {
s1ap_send_initial_context_setup_request(mme_ue);
ogs_error("[%s] Service request", mme_ue->imsi_bcd);
} else if (mme_ue->nas_eps.type ==
MME_EPS_TYPE_DETACH_REQUEST_FROM_UE) {
ogs_error("Detach request");
ogs_error("[%s] Detach request", mme_ue->imsi_bcd);
} else {
ogs_fatal("Invalid Type[%d]", mme_ue->nas_eps.type);
ogs_assert_if_reached();

View File

@ -109,12 +109,20 @@ void nas_eps_send_attach_accept(mme_ue_t *mme_ue)
ogs_assert(bearer);
ogs_assert(mme_bearer_next(bearer) == NULL);
ogs_debug("[%s] Attach accept", mme_ue->imsi_bcd);
esmbuf = esm_build_activate_default_bearer_context_request(sess);
ogs_expect_or_return(esmbuf);
emmbuf = emm_build_attach_accept(mme_ue, esmbuf);
ogs_expect_or_return(emmbuf);
CLEAR_MME_UE_TIMER(mme_ue->t3450);
mme_ue->t3450.pkbuf = ogs_pkbuf_copy(emmbuf);
ogs_assert(mme_ue->t3450.pkbuf);
ogs_timer_start(mme_ue->t3450.timer,
mme_timer_cfg(MME_TIMER_T3450)->duration);
s1apbuf = s1ap_build_initial_context_setup_request(mme_ue, emmbuf);
ogs_expect_or_return(s1apbuf);
@ -131,8 +139,8 @@ void nas_eps_send_attach_reject(mme_ue_t *mme_ue,
ogs_assert(mme_ue);
ogs_debug("Attach reject");
ogs_debug(" IMSI[%s] Cause[%d]", mme_ue->imsi_bcd, emm_cause);
ogs_debug("[%s] Attach reject", mme_ue->imsi_bcd);
ogs_debug(" Cause[%d]", emm_cause);
sess = mme_sess_first(mme_ue);
if (sess) {
@ -179,8 +187,7 @@ void nas_eps_send_authentication_request(mme_ue_t *mme_ue)
ogs_assert(mme_ue);
ogs_debug("Authentication request");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
ogs_debug("[%s] Authentication request", mme_ue->imsi_bcd);
if (mme_ue->t3460.pkbuf) {
emmbuf = mme_ue->t3460.pkbuf;
@ -206,8 +213,7 @@ void nas_eps_send_security_mode_command(mme_ue_t *mme_ue)
ogs_assert(mme_ue);
ogs_debug("Security mode command");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
ogs_debug("[%s] Security mode command", mme_ue->imsi_bcd);
if (mme_ue->t3460.pkbuf) {
emmbuf = mme_ue->t3460.pkbuf;
@ -233,8 +239,7 @@ void nas_eps_send_authentication_reject(mme_ue_t *mme_ue)
ogs_assert(mme_ue);
ogs_debug("Authentication reject");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
ogs_debug("[%s] Authentication reject", mme_ue->imsi_bcd);
emmbuf = emm_build_authentication_reject();
ogs_expect_or_return(emmbuf);
@ -252,6 +257,8 @@ void nas_eps_send_detach_accept(mme_ue_t *mme_ue)
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
ogs_assert(enb_ue);
ogs_debug("[%s] Detach accept", mme_ue->imsi_bcd);
/* reply with detach accept */
if (mme_ue->nas_eps.detach.switch_off == 0) {
int rv;
@ -471,12 +478,19 @@ void nas_eps_send_tau_accept(
ogs_assert(mme_ue);
ogs_debug("Tracking area update accept");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
ogs_debug("[%s] Tracking area update accept", mme_ue->imsi_bcd);
emmbuf = emm_build_tau_accept(mme_ue);
ogs_expect_or_return(emmbuf);
if (mme_ue->next.m_tmsi) {
CLEAR_MME_UE_TIMER(mme_ue->t3450);
mme_ue->t3450.pkbuf = ogs_pkbuf_copy(emmbuf);
ogs_assert(mme_ue->t3450.pkbuf);
ogs_timer_start(mme_ue->t3450.timer,
mme_timer_cfg(MME_TIMER_T3450)->duration);
}
if (procedureCode == S1AP_ProcedureCode_id_InitialContextSetup) {
ogs_pkbuf_t *s1apbuf = NULL;
s1apbuf = s1ap_build_initial_context_setup_request(mme_ue, emmbuf);
@ -498,6 +512,8 @@ void nas_eps_send_tau_reject(mme_ue_t *mme_ue, ogs_nas_emm_cause_t emm_cause)
ogs_assert(mme_ue);
ogs_debug("[%s] Tracking area update reject", mme_ue->imsi_bcd);
/* Build TAU reject */
emmbuf = emm_build_tau_reject(emm_cause, mme_ue);
ogs_expect_or_return(emmbuf);
@ -514,6 +530,8 @@ void nas_eps_send_service_reject(mme_ue_t *mme_ue,
ogs_assert(mme_ue);
ogs_debug("[%s] Service reject", mme_ue->imsi_bcd);
/* Build Service Reject */
emmbuf = emm_build_service_reject(emm_cause, mme_ue);
ogs_expect_or_return(emmbuf);
@ -529,8 +547,7 @@ void nas_eps_send_cs_service_notification(mme_ue_t *mme_ue)
ogs_assert(mme_ue);
ogs_debug("CS Service Notification");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
ogs_debug("[%s] CS Service Notification", mme_ue->imsi_bcd);
emmbuf = emm_build_cs_service_notification(mme_ue);
ogs_expect_or_return(emmbuf);
@ -549,8 +566,7 @@ void nas_eps_send_downlink_nas_transport(
ogs_assert(buffer);
ogs_assert(length);
ogs_debug("Downlink NAS transport");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
ogs_debug("[%s] Downlink NAS transport", mme_ue->imsi_bcd);
emmbuf = emm_build_downlink_nas_transport(mme_ue, buffer, length);
ogs_expect_or_return(emmbuf);

View File

@ -374,7 +374,7 @@ static void test1_func(abts_case *tc, void *data)
test_ue->tau_request_param.mobile_station_classmark_2 = 1;
test_ue->tau_request_param.ue_usage_setting = 1;
emmbuf = testemm_build_tau_request(
test_ue, false, OGS_NAS_EPS_UPDATE_TYPE_COMBINED_TA_LA_UPDATING);
test_ue, true, OGS_NAS_EPS_UPDATE_TYPE_COMBINED_TA_LA_UPDATING);
ABTS_PTR_NOTNULL(tc, emmbuf);
sendbuf = test_s1ap_build_uplink_nas_transport(test_ue, emmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);