TAU implemented

This commit is contained in:
James Park 2017-08-23 16:53:44 -07:00
parent aa40eb24a0
commit 468b3436ec
7 changed files with 330 additions and 2 deletions

View File

@ -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;
}

View File

@ -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
}

View File

@ -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
*/

View File

@ -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);

View File

@ -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:

View File

@ -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:

View File

@ -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