TAU implemented
This commit is contained in:
parent
aa40eb24a0
commit
468b3436ec
|
@ -107,3 +107,94 @@ status_t emm_build_attach_reject(
|
|||
return CORE_OK;
|
||||
}
|
||||
|
||||
status_t emm_build_tau_accept(pkbuf_t **emmbuf, mme_ue_t *mme_ue)
|
||||
{
|
||||
nas_message_t message;
|
||||
nas_tracking_area_update_accept_t *tau_accept =
|
||||
&message.emm.tracking_area_update_accept;
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
|
||||
message.emm.h.message_type = NAS_TRACKING_AREA_UPDATE_ACCEPT;
|
||||
|
||||
tau_accept->eps_update_result.result = NAS_EPS_UPDATE_RESULT_TA_UPDATED;
|
||||
|
||||
/* Set T3412 */
|
||||
tau_accept->presencemask |=
|
||||
NAS_TRACKING_AREA_UPDATE_ACCEPT_T3412_VALUE_PRESENT ;
|
||||
|
||||
/* FIXME: Use the value from configuration */
|
||||
tau_accept->t3412_value.unit = NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_DECI_HH;
|
||||
tau_accept->t3412_value.value = 9;
|
||||
|
||||
/* Set TAI */
|
||||
tau_accept->presencemask |=
|
||||
NAS_TRACKING_AREA_UPDATE_ACCEPT_TAI_LIST_PRESENT;
|
||||
|
||||
tau_accept->tai_list.length = 6;
|
||||
tau_accept->tai_list.type = 2;
|
||||
tau_accept->tai_list.num = 0; /* +1 = 1 elements */
|
||||
|
||||
memcpy(&tau_accept->tai_list.type2.tai[0], &mme_ue->tai, sizeof(tai_t));
|
||||
|
||||
/* Set EPS bearer context status */
|
||||
tau_accept->presencemask |=
|
||||
NAS_TRACKING_AREA_UPDATE_ACCEPT_EPS_BEARER_CONTEXT_STATUS_PRESENT;
|
||||
|
||||
tau_accept->eps_bearer_context_status.length = 2;
|
||||
tau_accept->eps_bearer_context_status.ebi5 =
|
||||
(mme_sess_find_by_ebi(mme_ue, 5) ? 1 : 0);
|
||||
tau_accept->eps_bearer_context_status.ebi6 =
|
||||
(mme_sess_find_by_ebi(mme_ue, 6) ? 1 : 0);
|
||||
tau_accept->eps_bearer_context_status.ebi7 =
|
||||
(mme_sess_find_by_ebi(mme_ue, 7) ? 1 : 0);
|
||||
/* FIXME : Need to set other ebi */
|
||||
|
||||
/* Set T3402 */
|
||||
tau_accept->presencemask |=
|
||||
NAS_TRACKING_AREA_UPDATE_ACCEPT_T3402_VALUE_PRESENT;
|
||||
|
||||
/* FIXME: Use the value from configuration */
|
||||
tau_accept->t3402_value.unit = NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_1_MM;
|
||||
tau_accept->t3402_value.value = 12;
|
||||
|
||||
/* Set T3423 */
|
||||
tau_accept->presencemask |=
|
||||
NAS_TRACKING_AREA_UPDATE_ACCEPT_T3423_VALUE_PRESENT;
|
||||
|
||||
/* FIXME: Use the value from configuration */
|
||||
tau_accept->t3423_value.unit = NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_DECI_HH;
|
||||
tau_accept->t3423_value.value = 9;
|
||||
|
||||
/* Set EPS network feature support */
|
||||
tau_accept->presencemask |=
|
||||
NAS_TRACKING_AREA_UPDATE_ACCEPT_EPS_NETWORK_FEATURE_SUPPORT_PRESENT;
|
||||
|
||||
tau_accept->eps_network_feature_support.length = 1;
|
||||
tau_accept->eps_network_feature_support.esr_ps = 1;
|
||||
tau_accept->eps_network_feature_support.epc_lcs = 1;
|
||||
tau_accept->eps_network_feature_support.ims_vops = 1;
|
||||
|
||||
d_assert(nas_security_encode(emmbuf, mme_ue, &message) == CORE_OK &&
|
||||
*emmbuf,,);
|
||||
|
||||
return CORE_OK;
|
||||
}
|
||||
|
||||
status_t emm_build_tau_reject(pkbuf_t **emmbuf, nas_emm_cause_t emm_cause,
|
||||
mme_ue_t *mme_ue)
|
||||
{
|
||||
nas_message_t message;
|
||||
nas_tracking_area_update_reject_t *tau_reject =
|
||||
&message.emm.tracking_area_update_reject;
|
||||
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
|
||||
message.emm.h.message_type = NAS_TRACKING_AREA_UPDATE_REJECT;
|
||||
|
||||
tau_reject->emm_cause = emm_cause;
|
||||
|
||||
d_assert(nas_plain_encode(emmbuf, &message) == CORE_OK && *emmbuf,,);
|
||||
|
||||
return CORE_OK;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ 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(
|
||||
pkbuf_t **emmbuf, nas_emm_cause_t emm_cause, pkbuf_t *esmbuf);
|
||||
CORE_DECLARE(status_t) emm_build_tau_accept(pkbuf_t **emmbuf, mme_ue_t *mme_ue);
|
||||
CORE_DECLARE(status_t) emm_build_tau_reject(pkbuf_t **emmbuf,
|
||||
nas_emm_cause_t emm_cause,mme_ue_t *mme_ue);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -606,6 +606,191 @@ void emm_handle_emm_status(mme_ue_t *mme_ue, nas_emm_status_t *emm_status)
|
|||
emm_status->emm_cause, mme_ue->imsi_bcd);
|
||||
}
|
||||
|
||||
void emm_handle_tau_request(
|
||||
mme_ue_t *mme_ue, nas_tracking_area_update_request_t *tau_request)
|
||||
{
|
||||
nas_eps_mobile_identity_t *eps_mobile_identity =
|
||||
&tau_request->old_guti;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
|
||||
d_assert(mme_ue, return, "Null param");
|
||||
enb_ue = mme_ue->enb_ue;
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
|
||||
/* Store UE specific information */
|
||||
if (tau_request->presencemask &
|
||||
NAS_TRACKING_AREA_UPDATE_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT)
|
||||
{
|
||||
nas_tracking_area_identity_t *last_visited_registered_tai =
|
||||
&tau_request->last_visited_registered_tai;
|
||||
|
||||
memcpy(&mme_ue->visited_plmn_id,
|
||||
&last_visited_registered_tai->plmn_id,
|
||||
PLMN_ID_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME : what will do if we don't know last visited plmn_id */
|
||||
memcpy(&mme_ue->visited_plmn_id,
|
||||
&mme_self()->served_tai[0].plmn_id, PLMN_ID_LEN);
|
||||
}
|
||||
|
||||
if (tau_request->presencemask &
|
||||
NAS_TRACKING_AREA_UPDATE_REQUEST_UE_NETWORK_CAPABILITY_PRESENT)
|
||||
{
|
||||
memcpy(&mme_ue->ue_network_capability,
|
||||
&tau_request->ue_network_capability,
|
||||
sizeof(tau_request->ue_network_capability));
|
||||
}
|
||||
|
||||
if (tau_request->presencemask &
|
||||
NAS_TRACKING_AREA_UPDATE_REQUEST_MS_NETWORK_CAPABILITY_PRESENT)
|
||||
{
|
||||
memcpy(&mme_ue->ms_network_capability,
|
||||
&tau_request->ms_network_capability,
|
||||
sizeof(tau_request->ms_network_capability));
|
||||
}
|
||||
|
||||
/* Copy TAI and ECGI from enb_ue */
|
||||
memcpy(&mme_ue->tai, &enb_ue->tai, sizeof(tai_t));
|
||||
memcpy(&mme_ue->e_cgi, &enb_ue->e_cgi, sizeof(e_cgi_t));
|
||||
|
||||
/* TODO:
|
||||
* 1) Consider if MME is changed or not.
|
||||
* 2) Consider if SGW is changed or not.
|
||||
*/
|
||||
switch(eps_mobile_identity->imsi.type)
|
||||
{
|
||||
case NAS_EPS_MOBILE_IDENTITY_GUTI:
|
||||
{
|
||||
nas_eps_mobile_identity_guti_t *nas_guti = NULL;
|
||||
nas_guti = &eps_mobile_identity->guti;
|
||||
guti_t guti;
|
||||
|
||||
guti.plmn_id = nas_guti->plmn_id;
|
||||
guti.mme_gid = nas_guti->mme_gid;
|
||||
guti.mme_code = nas_guti->mme_code;
|
||||
guti.m_tmsi = nas_guti->m_tmsi;
|
||||
|
||||
d_trace(3, "[NAS] TAU request : GUTI[G:%d,C:%d,M_TMSI:0x%x]-"
|
||||
"IMSI:[%s] --> EMM\n",
|
||||
guti.mme_gid,
|
||||
guti.mme_code,
|
||||
guti.m_tmsi,
|
||||
MME_UE_HAVE_IMSI(mme_ue)
|
||||
? mme_ue->imsi_bcd : "Unknown");
|
||||
|
||||
if (!MME_UE_HAVE_IMSI(mme_ue))
|
||||
{
|
||||
/* Unknown GUTI */
|
||||
|
||||
/* FIXME : Need to check if GUTI is allocated to old MME.
|
||||
* if so , transmit context request to get the context of ue.
|
||||
*/
|
||||
|
||||
/* Send TAU reject */
|
||||
emm_handle_tau_reject(mme_ue,
|
||||
EMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
|
||||
}
|
||||
else if (!SECURITY_CONTEXT_IS_VALID(mme_ue))
|
||||
{
|
||||
/* Need Authencation */
|
||||
d_warn("Need Authenticatoin");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Send TAU accept */
|
||||
emm_handle_tau_accept(mme_ue);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_warn("Not implemented(type:%d)",
|
||||
eps_mobile_identity->imsi.type);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//event_emm_to_esm(mme_ue, &attach_request->esm_message_container);
|
||||
}
|
||||
|
||||
void emm_handle_tau_accept(mme_ue_t *mme_ue)
|
||||
{
|
||||
status_t rv;
|
||||
mme_enb_t *enb = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
pkbuf_t *emmbuf = NULL, *s1apbuf = NULL;
|
||||
S1ap_Cause_t cause;
|
||||
|
||||
d_assert(mme_ue, return, "Null param");
|
||||
enb_ue = mme_ue->enb_ue;
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
enb = enb_ue->enb;
|
||||
d_assert(enb, return, "Null param");
|
||||
|
||||
/* Build TAU accept */
|
||||
if (emm_build_tau_accept(&emmbuf, mme_ue) != CORE_OK)
|
||||
{
|
||||
d_error("emm_build_tau_accept error");
|
||||
pkbuf_free(emmbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send Dl NAS to UE */
|
||||
d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,);
|
||||
|
||||
|
||||
/* FIXME : delay required before sending UE context release to make sure
|
||||
* that UE receive DL NAS ? */
|
||||
cause.present = S1ap_Cause_PR_nas;
|
||||
cause.choice.nas = S1ap_CauseNas_normal_release;
|
||||
|
||||
rv = s1ap_build_ue_context_release_commmand(&s1apbuf, enb_ue, &cause);
|
||||
d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error");
|
||||
|
||||
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, "s1ap send error");
|
||||
}
|
||||
|
||||
void emm_handle_tau_reject(mme_ue_t *mme_ue, nas_emm_cause_t emm_cause)
|
||||
{
|
||||
status_t rv;
|
||||
mme_enb_t *enb = NULL;
|
||||
enb_ue_t *enb_ue = NULL;
|
||||
pkbuf_t *emmbuf = NULL, *s1apbuf = NULL;
|
||||
S1ap_Cause_t cause;
|
||||
|
||||
d_assert(mme_ue, return, "Null param");
|
||||
enb_ue = mme_ue->enb_ue;
|
||||
d_assert(enb_ue, return, "Null param");
|
||||
enb = enb_ue->enb;
|
||||
d_assert(enb, return, "Null param");
|
||||
|
||||
/* Build TAU reject */
|
||||
if (emm_build_tau_reject(&emmbuf, emm_cause, mme_ue) != CORE_OK)
|
||||
{
|
||||
d_error("emm_build_tau_accept error");
|
||||
pkbuf_free(emmbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send Dl NAS to UE */
|
||||
d_assert(nas_send_to_downlink_nas_transport(mme_ue, emmbuf) == CORE_OK,,);
|
||||
|
||||
|
||||
/* FIXME : delay required before sending UE context release to make sure
|
||||
* that UE receive DL NAS ? */
|
||||
cause.present = S1ap_Cause_PR_nas;
|
||||
cause.choice.nas = S1ap_CauseNas_normal_release;
|
||||
|
||||
rv = s1ap_build_ue_context_release_commmand(&s1apbuf, enb_ue, &cause);
|
||||
d_assert(rv == CORE_OK && s1apbuf, return, "s1ap build error");
|
||||
|
||||
d_assert(s1ap_send_to_enb(enb, s1apbuf) == CORE_OK,, "s1ap send error");
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* S11 Layer in EMM Handler
|
||||
*/
|
||||
|
|
|
@ -34,6 +34,11 @@ CORE_DECLARE(void) emm_handle_service_request(
|
|||
|
||||
CORE_DECLARE(void) emm_handle_emm_status(
|
||||
mme_ue_t *mme_ue, nas_emm_status_t *emm_status);
|
||||
CORE_DECLARE(void) emm_handle_tau_request(
|
||||
mme_ue_t *mme_ue, nas_tracking_area_update_request_t *tau_request);
|
||||
CORE_DECLARE(void) emm_handle_tau_accept(mme_ue_t *mme_ue);
|
||||
CORE_DECLARE(void) emm_handle_tau_reject(mme_ue_t *mme_ue,
|
||||
nas_esm_cause_t emm_cause);
|
||||
|
||||
/** S11 Layer in EMM handler */
|
||||
CORE_DECLARE(void) emm_handle_s11_delete_session_request(mme_ue_t *mme_ue);
|
||||
|
|
|
@ -186,6 +186,8 @@ void emm_state_operational(fsm_t *s, event_t *e)
|
|||
case NAS_TRACKING_AREA_UPDATE_REQUEST:
|
||||
{
|
||||
mme_ue_paged(mme_ue);
|
||||
emm_handle_tau_request(
|
||||
mme_ue, &message->emm.tracking_area_update_request);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -1280,7 +1280,49 @@ mme_ue_t* mme_ue_find_by_message(nas_message_t *message)
|
|||
}
|
||||
case NAS_TRACKING_AREA_UPDATE_REQUEST:
|
||||
{
|
||||
/* TODO */
|
||||
nas_tracking_area_update_request_t *tau_request =
|
||||
&message->emm.tracking_area_update_request;
|
||||
|
||||
nas_eps_mobile_identity_t *eps_mobile_identity =
|
||||
&tau_request->old_guti;
|
||||
|
||||
switch(eps_mobile_identity->imsi.type)
|
||||
{
|
||||
case NAS_EPS_MOBILE_IDENTITY_GUTI:
|
||||
{
|
||||
nas_eps_mobile_identity_guti_t *nas_guti = NULL;
|
||||
nas_guti = &eps_mobile_identity->guti;
|
||||
guti_t guti;
|
||||
|
||||
guti.plmn_id = nas_guti->plmn_id;
|
||||
guti.mme_gid = nas_guti->mme_gid;
|
||||
guti.mme_code = nas_guti->mme_code;
|
||||
guti.m_tmsi = nas_guti->m_tmsi;
|
||||
|
||||
mme_ue = mme_ue_find_by_guti(&guti);
|
||||
if (mme_ue)
|
||||
{
|
||||
d_trace(3, "Known UE by GUTI[G:%d,C:%d,M_TMSI:0x%x]\n",
|
||||
guti.mme_gid,
|
||||
guti.mme_code,
|
||||
guti.m_tmsi);
|
||||
}
|
||||
else
|
||||
{
|
||||
d_warn("Unknown UE by GUTI[G:%d,C:%d,M_TMSI:0x%x]",
|
||||
guti.mme_gid,
|
||||
guti.mme_code,
|
||||
guti.m_tmsi);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
d_error("Uknown message imsi type =%d\n",
|
||||
eps_mobile_identity->imsi.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -4,7 +4,7 @@ ifconfig eth1:hss 10.1.35.214/24 up
|
|||
ifconfig eth1:mme 10.1.35.215/24 up
|
||||
ifconfig eth1:sgw_s5 10.1.35.216/24 up
|
||||
ifconfig eth1:sgw_s11 10.1.35.217/24 up
|
||||
ifconfig eth1:pcrf 10.1.35.218/24 up
|
||||
ifconfig eth1:pcrf 10.1.35.213/24 up
|
||||
ifconfig eth1:pgw 10.1.35.219/24 up
|
||||
ifconfig pgwtun 45.45.0.1/16 up
|
||||
|
||||
|
|
Loading…
Reference in New Issue