[AMF] 5G-GUTI generation changed (#910)

The AMF shall assign a new 5G-GUTI for a particular UE:
a) during  a successful initial registration procedure;
b) during a successful registration procedure
   for mobility registration update; and
c) after a successful service request procedure invoked as a response
   to a paging request from the network and before the release
   of the N1 NAS signalling connection as specified in subclause 5.4.4.1.

The AMF should assign a new 5G-GUTI for a particular UE
during a successful registration procedure
for periodic registration update. The AMF may assign a new 5G-GUTI
at any time for a particular UE by performing
the generic UE configuration update procedure.
This commit is contained in:
Sukchan Lee 2021-04-13 17:34:25 +09:00
parent 3275584236
commit cc03c91bdd
25 changed files with 337 additions and 126 deletions

View File

@ -1041,27 +1041,47 @@ ran_ue_t *ran_ue_cycle(ran_ue_t *ran_ue)
void amf_ue_new_guti(amf_ue_t *amf_ue)
{
if (amf_ue->m_tmsi) {
if (amf_ue->next.m_tmsi) {
ogs_warn("GUTI has already been allocated");
return;
}
memset(&amf_ue->next.guti, 0, sizeof(ogs_nas_5gs_guti_t));
ogs_assert(amf_ue->guami);
ogs_nas_from_plmn_id(
&amf_ue->next.guti.nas_plmn_id, &amf_ue->guami->plmn_id);
memcpy(&amf_ue->next.guti.amf_id,
&amf_ue->guami->amf_id, sizeof(ogs_amf_id_t));
amf_ue->next.m_tmsi = amf_m_tmsi_alloc();
ogs_assert(amf_ue->next.m_tmsi);
amf_ue->next.guti.m_tmsi = *(amf_ue->next.m_tmsi);
}
void amf_ue_confirm_guti(amf_ue_t *amf_ue)
{
ogs_assert(amf_ue->next.m_tmsi);
if (amf_ue->current.m_tmsi) {
/* AMF has a VALID GUTI
* As such, we need to remove previous GUTI in hash table */
ogs_hash_set(self.guti_ue_hash,
&amf_ue->guti, sizeof(ogs_nas_5gs_guti_t), NULL);
ogs_assert(amf_m_tmsi_free(amf_ue->m_tmsi) == OGS_OK);
&amf_ue->current.guti, sizeof(ogs_nas_5gs_guti_t), NULL);
ogs_assert(amf_m_tmsi_free(amf_ue->current.m_tmsi) == OGS_OK);
}
memset(&amf_ue->guti, 0, sizeof(ogs_nas_5gs_guti_t));
/* Copying from Current to Next Guti */
amf_ue->current.m_tmsi = amf_ue->next.m_tmsi;
memcpy(&amf_ue->current.guti,
&amf_ue->next.guti, sizeof(ogs_nas_5gs_guti_t));
ogs_assert(amf_ue->guami);
ogs_nas_from_plmn_id(&amf_ue->guti.nas_plmn_id, &amf_ue->guami->plmn_id);
memcpy(&amf_ue->guti.amf_id, &amf_ue->guami->amf_id, sizeof(ogs_amf_id_t));
amf_ue->m_tmsi = amf_m_tmsi_alloc();
ogs_assert(amf_ue->m_tmsi);
amf_ue->guti.m_tmsi = *(amf_ue->m_tmsi);
/* Hashing Current GUTI */
ogs_hash_set(self.guti_ue_hash,
&amf_ue->guti, sizeof(ogs_nas_5gs_guti_t), amf_ue);
&amf_ue->current.guti, sizeof(ogs_nas_5gs_guti_t), amf_ue);
amf_ue->guti_present = true;
/* Clear Next GUTI */
amf_ue->next.m_tmsi = NULL;
}
amf_ue_t *amf_ue_add(ran_ue_t *ran_ue)
@ -1131,14 +1151,22 @@ void amf_ue_remove(amf_ue_t *amf_ue)
amf_ue_fsm_fini(amf_ue);
/* Clear Paging Info */
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
/* Clear N2 Transfer */
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, pdu_session_resource_setup_request);
/* Remove all session context */
amf_sess_remove_all(amf_ue);
/* Clear hash table */
if (amf_ue->m_tmsi) {
if (amf_ue->current.m_tmsi) {
ogs_hash_set(self.guti_ue_hash,
&amf_ue->guti, sizeof(ogs_nas_5gs_guti_t), NULL);
ogs_assert(amf_m_tmsi_free(amf_ue->m_tmsi) == OGS_OK);
&amf_ue->current.guti, sizeof(ogs_nas_5gs_guti_t), NULL);
ogs_assert(amf_m_tmsi_free(amf_ue->current.m_tmsi) == OGS_OK);
}
if (amf_ue->next.m_tmsi) {
ogs_assert(amf_m_tmsi_free(amf_ue->next.m_tmsi) == OGS_OK);
}
if (amf_ue->suci) {
ogs_hash_set(self.suci_hash, amf_ue->suci, strlen(amf_ue->suci), NULL);
@ -1172,12 +1200,6 @@ void amf_ue_remove(amf_ue_t *amf_ue)
/* Clear Transparent Container */
OGS_ASN_CLEAR_DATA(&amf_ue->handover.container);
/* Clear Paging Info */
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
/* Clear N2 Transfer */
AMF_UE_CLEAR_N2_TRANSFER(amf_ue, pdu_session_resource_setup_request);
/* Delete All Timers */
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
ogs_timer_delete(amf_ue->t3513.timer);

View File

@ -261,9 +261,10 @@ struct amf_ue_s {
int num_of_msisdn;
char *msisdn[OGS_MAX_NUM_OF_MSISDN];
amf_m_tmsi_t *m_tmsi;
ogs_nas_5gs_guti_t guti;
bool guti_present;
struct {
amf_m_tmsi_t *m_tmsi;
ogs_nas_5gs_guti_t guti;
} current, next;
/* UE Info */
ogs_guami_t *guami;
@ -600,6 +601,7 @@ ran_ue_t *ran_ue_find_by_amf_ue_ngap_id(uint64_t amf_ue_ngap_id);
ran_ue_t *ran_ue_cycle(ran_ue_t *ran_ue);
void amf_ue_new_guti(amf_ue_t *amf_ue);
void amf_ue_confirm_guti(amf_ue_t *amf_ue);
amf_ue_t *amf_ue_add(ran_ue_t *ran_ue);
void amf_ue_remove(amf_ue_t *amf_ue);

View File

@ -70,14 +70,16 @@ ogs_pkbuf_t *gmm_build_registration_accept(amf_ue_t *amf_ue)
registration_result->value = amf_ue->nas.access_type;
/* Set GUTI */
ogs_debug("[%s] %s 5G-S_GUTI[AMF_ID:0x%x,M_TMSI:0x%x]", amf_ue->supi,
amf_ue->guti_present == true ? "[V]" : "[N]",
ogs_amf_id_hexdump(&amf_ue->guti.amf_id), amf_ue->guti.m_tmsi);
if (amf_ue->guti_present == true) {
registration_accept->presencemask |= OGS_NAS_5GS_REGISTRATION_ACCEPT_5G_GUTI_PRESENT;
if (amf_ue->next.m_tmsi) {
registration_accept->presencemask |=
OGS_NAS_5GS_REGISTRATION_ACCEPT_5G_GUTI_PRESENT;
ogs_debug("[%s] 5G-S_GUTI[AMF_ID:0x%x,M_TMSI:0x%x]", amf_ue->supi,
ogs_amf_id_hexdump(&amf_ue->next.guti.amf_id),
amf_ue->next.guti.m_tmsi);
ogs_nas_5gs_nas_guti_to_mobility_identity_guti(
&amf_ue->guti, &mobile_identity_guti);
&amf_ue->next.guti, &mobile_identity_guti);
mobile_identity->length = sizeof(mobile_identity_guti);
mobile_identity->buffer = &mobile_identity_guti;
@ -455,6 +457,9 @@ ogs_pkbuf_t *gmm_build_configuration_update_command(
ogs_nas_configuration_update_indication_t
*configuration_update_indication =
&configuration_update_command->configuration_update_indication;
ogs_nas_5gs_mobile_identity_t *mobile_identity =
&configuration_update_command->guti;
ogs_nas_5gs_mobile_identity_guti_t mobile_identity_guti;
struct timeval tv;
struct tm gmt, local;
@ -543,6 +548,22 @@ ogs_pkbuf_t *gmm_build_configuration_update_command(
network_daylight_saving_time->length = 1;
}
if (param->guti) {
configuration_update_command->presencemask |=
OGS_NAS_5GS_CONFIGURATION_UPDATE_COMMAND_5G_GUTI_PRESENT;
ogs_assert(amf_ue->next.m_tmsi);
ogs_info("[%s] 5G-S_GUTI[AMF_ID:0x%x,M_TMSI:0x%x]", amf_ue->supi,
ogs_amf_id_hexdump(&amf_ue->next.guti.amf_id),
amf_ue->next.guti.m_tmsi);
ogs_nas_5gs_nas_guti_to_mobility_identity_guti(
&amf_ue->next.guti, &mobile_identity_guti);
mobile_identity->length = sizeof(mobile_identity_guti);
mobile_identity->buffer = &mobile_identity_guti;
}
return nas_5gs_security_encode(amf_ue, &message);
}

View File

@ -45,6 +45,7 @@ typedef struct gmm_configuration_update_command_param_s {
int registration_requested;
int acknowledgement_requested;
int nitz;
int guti;
} gmm_configuration_update_command_param_t;
ogs_pkbuf_t *gmm_build_configuration_update_command(

View File

@ -117,6 +117,9 @@ int gmm_handle_registration_request(amf_ue_t *amf_ue,
amf_ue->nhcc = 1;
}
/* Create New GUTI */
amf_ue_new_guti(amf_ue);
ogs_debug(" OLD TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&amf_ue->nr_tai.plmn_id), amf_ue->nr_tai.tac.v);
ogs_debug(" OLD NR_CGI[PLMN_ID:%06x,CELL_ID:0x%llx]",
@ -343,10 +346,8 @@ int gmm_handle_service_request(amf_ue_t *amf_ue,
/*
* REGISTRATION_REQUEST
* SERVICE_REQUEST
* Clear Paging Info
* Clear Timer and Message
*/
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
if (SECURITY_CONTEXT_IS_VALID(amf_ue)) {
@ -389,7 +390,8 @@ int gmm_handle_service_request(amf_ue_t *amf_ue,
ogs_info("[%s] 5G-S_GUTI[AMF_ID:0x%x,M_TMSI:0x%x]",
AMF_UE_HAVE_SUCI(amf_ue) ? amf_ue->suci : "Unknown ID",
ogs_amf_id_hexdump(&amf_ue->guti.amf_id), amf_ue->guti.m_tmsi);
ogs_amf_id_hexdump(&amf_ue->current.guti.amf_id),
amf_ue->current.guti.m_tmsi);
return OGS_OK;
}

View File

@ -194,7 +194,10 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
nas_5gs_send_registration_accept(amf_ue);
}
OGS_FSM_TRAN(s, &gmm_state_registered);
if (amf_ue->next.m_tmsi)
OGS_FSM_TRAN(s, &gmm_state_initial_context_setup);
else
OGS_FSM_TRAN(s, &gmm_state_registered);
} else {
@ -292,6 +295,13 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
case OGS_NAS_5GS_CONFIGURATION_UPDATE_COMPLETE:
ogs_debug("[%s] Configuration update complete", amf_ue->supi);
/* Confirm GUTI */
if (amf_ue->next.m_tmsi) {
amf_ue_confirm_guti(amf_ue);
} else {
ogs_error("[%s] No GUTI allocated", amf_ue->supi);
}
CLEAR_AMF_UE_TIMER(amf_ue->t3555);
break;
@ -690,9 +700,6 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
ogs_kdf_nh_gnb(amf_ue->kamf, amf_ue->kgnb, amf_ue->nh);
amf_ue->nhcc = 1;
/* Create New GUTI */
amf_ue_new_guti(amf_ue);
amf_ue_sbi_discover_and_send(OpenAPI_nf_type_UDM, amf_ue, NULL,
amf_nudm_uecm_build_registration);
@ -953,8 +960,12 @@ 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 GUTI present */
amf_ue->guti_present = false;
/* Confirm GUTI */
if (amf_ue->next.m_tmsi) {
amf_ue_confirm_guti(amf_ue);
} else {
ogs_error("[%s] No GUTI allocated", amf_ue->supi);
}
/*
* TS24.501
@ -1165,7 +1176,10 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
nas_5gs_send_registration_accept(amf_ue);
}
OGS_FSM_TRAN(s, &gmm_state_registered);
if (amf_ue->next.m_tmsi)
OGS_FSM_TRAN(s, &gmm_state_initial_context_setup);
else
OGS_FSM_TRAN(s, &gmm_state_registered);
} else {

View File

@ -1514,10 +1514,10 @@ ogs_pkbuf_t *ngap_build_paging(amf_ue_t *amf_ue)
fiveG_TMSI = &fiveG_S_TMSI->fiveG_TMSI;
ogs_ngap_uint16_to_AMFSetID(
ogs_amf_set_id(&amf_ue->guti.amf_id), aMFSetID);
ogs_amf_set_id(&amf_ue->current.guti.amf_id), aMFSetID);
ogs_ngap_uint8_to_AMFPointer(
ogs_amf_pointer(&amf_ue->guti.amf_id), aMFPointer);
ogs_asn_uint32_to_OCTET_STRING(amf_ue->guti.m_tmsi, fiveG_TMSI);
ogs_amf_pointer(&amf_ue->current.guti.amf_id), aMFPointer);
ogs_asn_uint32_to_OCTET_STRING(amf_ue->current.guti.m_tmsi, fiveG_TMSI);
ie = CALLOC(1, sizeof(NGAP_PagingIEs_t));
ASN_SEQUENCE_ADD(&Paging->protocolIEs, ie);

View File

@ -20,6 +20,7 @@
#include "ngap-handler.h"
#include "ngap-path.h"
#include "sbi-path.h"
#include "nas-path.h"
static bool served_tai_is_found(amf_gnb_t *gnb)
{
@ -420,8 +421,8 @@ void ngap_handle_initial_ue_message(amf_gnb_t *gnb, ogs_ngap_message_t *message)
} else {
ogs_info("[%s] 5G-S_TMSI[AMF_ID:0x%x,M_TMSI:0x%x]",
AMF_UE_HAVE_SUCI(amf_ue) ? amf_ue->suci : "Unknown ID",
ogs_amf_id_hexdump(&amf_ue->guti.amf_id),
amf_ue->guti.m_tmsi);
ogs_amf_id_hexdump(&amf_ue->current.guti.amf_id),
amf_ue->current.guti.m_tmsi);
/* If NAS(amf_ue_t) has already been associated with
* older NG(ran_ue_t) context */
if (CM_CONNECTED(amf_ue)) {
@ -727,9 +728,12 @@ void ngap_handle_initial_context_setup_response(
amf_ue_t *amf_ue = NULL;
ran_ue_t *ran_ue = NULL;
amf_sess_t *sess = NULL;
uint64_t amf_ue_ngap_id;
amf_nsmf_pdusession_update_sm_context_param_t param;
bool paging_ongoing = false;
NGAP_SuccessfulOutcome_t *successfulOutcome = NULL;
NGAP_InitialContextSetupResponse_t *InitialContextSetupResponse = NULL;
@ -802,9 +806,6 @@ void ngap_handle_initial_context_setup_response(
ogs_debug(" RAN_UE_NGAP_ID[%d] AMF_UE_NGAP_ID[%lld]",
ran_ue->ran_ue_ngap_id, (long long)ran_ue->amf_ue_ngap_id);
if (!PDUSessionList) /* No PDUSessionList */
return;
amf_ue = ran_ue->amf_ue;
if (!amf_ue) {
ogs_error("Cannot find AMF-UE Context [%lld]",
@ -816,8 +817,7 @@ void ngap_handle_initial_context_setup_response(
return;
}
for (i = 0; i < PDUSessionList->list.count; i++) {
amf_sess_t *sess = NULL;
for (i = 0; PDUSessionList && i < PDUSessionList->list.count; i++) {
PDUSessionItem = (NGAP_PDUSessionResourceSetupItemCxtRes_t *)
PDUSessionList->list.array[i];
@ -875,6 +875,27 @@ void ngap_handle_initial_context_setup_response(
ogs_pkbuf_free(param.n2smbuf);
}
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (sess->paging.ongoing == true) {
paging_ongoing = true;
break;
}
}
if (paging_ongoing == true) {
gmm_configuration_update_command_param_t param;
/* Create New GUTI */
amf_ue_new_guti(amf_ue);
memset(&param, 0, sizeof(param));
param.acknowledgement_requested = 1;
param.guti = 1;
nas_5gs_send_configuration_update_command(amf_ue, &param);
}
AMF_UE_CLEAR_PAGING_INFO(amf_ue);
}
void ngap_handle_initial_context_setup_failure(

View File

@ -77,19 +77,20 @@ ogs_pkbuf_t *emm_build_attach_accept(
attach_accept->esm_message_container.buffer = esmbuf->data;
attach_accept->esm_message_container.length = esmbuf->len;
ogs_debug(" %s GUTI[G:%d,C:%d,M_TMSI:0x%x] IMSI:[%s]",
mme_ue->guti_present == true ? "[V]" : "[N]",
mme_ue->guti.mme_gid, mme_ue->guti.mme_code,
mme_ue->guti.m_tmsi, mme_ue->imsi_bcd);
if (mme_ue->guti_present == true) {
if (mme_ue->next.m_tmsi) {
attach_accept->presencemask |= OGS_NAS_EPS_ATTACH_ACCEPT_GUTI_PRESENT;
ogs_debug("[%s] GUTI[G:%d,C:%d,M_TMSI:0x%x]",
mme_ue->imsi_bcd,
mme_ue->next.guti.mme_gid, mme_ue->next.guti.mme_code,
mme_ue->next.guti.m_tmsi);
nas_guti->length = sizeof(ogs_nas_eps_mobile_identity_guti_t);
nas_guti->guti.odd_even = OGS_NAS_MOBILE_IDENTITY_EVEN;
nas_guti->guti.type = OGS_NAS_EPS_MOBILE_IDENTITY_GUTI;
nas_guti->guti.nas_plmn_id = mme_ue->guti.nas_plmn_id;
nas_guti->guti.mme_gid = mme_ue->guti.mme_gid;
nas_guti->guti.mme_code = mme_ue->guti.mme_code;
nas_guti->guti.m_tmsi = mme_ue->guti.m_tmsi;
nas_guti->guti.nas_plmn_id = mme_ue->next.guti.nas_plmn_id;
nas_guti->guti.mme_gid = mme_ue->next.guti.mme_gid;
nas_guti->guti.mme_code = mme_ue->next.guti.mme_code;
nas_guti->guti.m_tmsi = mme_ue->next.guti.m_tmsi;
}
#if 0 /* Need not to include T3402 */
@ -409,20 +410,21 @@ ogs_pkbuf_t *emm_build_tau_accept(mme_ue_t *mme_ue)
tau_accept->t3412_value.unit = OGS_NAS_GRPS_TIMER_UNIT_MULTIPLES_OF_DECI_HH;
tau_accept->t3412_value.value = 9;
ogs_debug(" %s GUTI[G:%d,C:%d,M_TMSI:0x%x] IMSI:[%s]",
mme_ue->guti_present == true ? "[V]" : "[N]",
mme_ue->guti.mme_gid, mme_ue->guti.mme_code,
mme_ue->guti.m_tmsi, mme_ue->imsi_bcd);
if (mme_ue->guti_present == true) {
if (mme_ue->next.m_tmsi) {
tau_accept->presencemask |=
OGS_NAS_EPS_TRACKING_AREA_UPDATE_ACCEPT_GUTI_PRESENT;
ogs_debug("[%s] GUTI[G:%d,C:%d,M_TMSI:0x%x]",
mme_ue->imsi_bcd,
mme_ue->next.guti.mme_gid, mme_ue->next.guti.mme_code,
mme_ue->next.guti.m_tmsi);
nas_guti->length = sizeof(ogs_nas_eps_mobile_identity_guti_t);
nas_guti->guti.odd_even = OGS_NAS_MOBILE_IDENTITY_EVEN;
nas_guti->guti.type = OGS_NAS_EPS_MOBILE_IDENTITY_GUTI;
nas_guti->guti.nas_plmn_id = mme_ue->guti.nas_plmn_id;
nas_guti->guti.mme_gid = mme_ue->guti.mme_gid;
nas_guti->guti.mme_code = mme_ue->guti.mme_code;
nas_guti->guti.m_tmsi = mme_ue->guti.m_tmsi;
nas_guti->guti.nas_plmn_id = mme_ue->next.guti.nas_plmn_id;
nas_guti->guti.mme_gid = mme_ue->next.guti.mme_gid;
nas_guti->guti.mme_code = mme_ue->next.guti.mme_code;
nas_guti->guti.m_tmsi = mme_ue->next.guti.m_tmsi;
}
/* Set TAI */

View File

@ -422,9 +422,9 @@ int emm_handle_service_request(
}
ogs_info(" GUTI[G:%d,C:%d,M_TMSI:0x%x] IMSI[%s]",
mme_ue->guti.mme_gid,
mme_ue->guti.mme_code,
mme_ue->guti.m_tmsi,
mme_ue->current.guti.mme_gid,
mme_ue->current.guti.mme_code,
mme_ue->current.guti.m_tmsi,
MME_UE_HAVE_IMSI(mme_ue) ? mme_ue->imsi_bcd : "Unknown");
return OGS_OK;

View File

@ -305,8 +305,12 @@ static void common_register_state(ogs_fsm_t *s, mme_event_t *e)
ogs_info("Tracking area update complete");
ogs_info(" IMSI[%s]", mme_ue->imsi_bcd);
/* Clear GUTI present */
mme_ue->guti_present = false;
/* Confirm GUTI */
if (mme_ue->next.m_tmsi) {
mme_ue_confirm_guti(mme_ue);
} else {
ogs_error("[%s] No GUTI allocated", mme_ue->imsi_bcd);
}
break;
case OGS_NAS_EPS_EXTENDED_SERVICE_REQUEST:
@ -921,8 +925,9 @@ void emm_state_initial_context_setup(ogs_fsm_t *s, mme_event_t *e)
break;
}
/* Clear GUTI present */
mme_ue->guti_present = false;
/* Confirm GUTI */
if (mme_ue->next.m_tmsi)
mme_ue_confirm_guti(mme_ue);
if (MME_P_TMSI_IS_AVAILABLE(mme_ue))
sgsap_send_tmsi_reallocation_complete(mme_ue);

View File

@ -1999,28 +1999,47 @@ void mme_ue_new_guti(mme_ue_t *mme_ue)
ogs_assert(served_gummei->num_of_mme_gid > 0);
ogs_assert(served_gummei->num_of_mme_code > 0);
if (mme_ue->m_tmsi) {
if (mme_ue->next.m_tmsi) {
ogs_warn("GUTI has already been allocated");
return;
}
memset(&mme_ue->next.guti, 0, sizeof(ogs_nas_eps_guti_t));
/* Use the first configured plmn_id and mme group id */
ogs_nas_from_plmn_id(
&mme_ue->next.guti.nas_plmn_id, &served_gummei->plmn_id[0]);
mme_ue->next.guti.mme_gid = served_gummei->mme_gid[0];
mme_ue->next.guti.mme_code = served_gummei->mme_code[0];
mme_ue->next.m_tmsi = mme_m_tmsi_alloc();
ogs_assert(mme_ue->next.m_tmsi);
mme_ue->next.guti.m_tmsi = *(mme_ue->next.m_tmsi);
}
void mme_ue_confirm_guti(mme_ue_t *mme_ue)
{
ogs_assert(mme_ue->next.m_tmsi);
if (mme_ue->current.m_tmsi) {
/* MME has a VALID GUTI
* As such, we need to remove previous GUTI in hash table */
ogs_hash_set(self.guti_ue_hash,
&mme_ue->guti, sizeof(ogs_nas_eps_guti_t), NULL);
ogs_assert(mme_m_tmsi_free(mme_ue->m_tmsi) == OGS_OK);
&mme_ue->current.guti, sizeof(ogs_nas_eps_guti_t), NULL);
ogs_assert(mme_m_tmsi_free(mme_ue->current.m_tmsi) == OGS_OK);
}
memset(&mme_ue->guti, 0, sizeof(ogs_nas_eps_guti_t));
/* Copying from Current to Next Guti */
mme_ue->current.m_tmsi = mme_ue->next.m_tmsi;
memcpy(&mme_ue->current.guti,
&mme_ue->next.guti, sizeof(ogs_nas_eps_guti_t));
/* Use the first configured plmn_id and mme group id */
ogs_nas_from_plmn_id(&mme_ue->guti.nas_plmn_id, &served_gummei->plmn_id[0]);
mme_ue->guti.mme_gid = served_gummei->mme_gid[0];
mme_ue->guti.mme_code = served_gummei->mme_code[0];
mme_ue->m_tmsi = mme_m_tmsi_alloc();
ogs_assert(mme_ue->m_tmsi);
mme_ue->guti.m_tmsi = *(mme_ue->m_tmsi);
/* Hashing Current GUTI */
ogs_hash_set(self.guti_ue_hash,
&mme_ue->guti, sizeof(ogs_nas_eps_guti_t), mme_ue);
&mme_ue->current.guti, sizeof(ogs_nas_eps_guti_t), mme_ue);
mme_ue->guti_present = true;
/* Clear Next GUTI */
mme_ue->next.m_tmsi = NULL;
}
static bool compare_ue_info(mme_sgw_t *node, enb_ue_t *enb_ue)
@ -2134,11 +2153,13 @@ void mme_ue_remove(mme_ue_t *mme_ue)
mme_ue_fsm_fini(mme_ue);
/* Clear hash table */
if (mme_ue->m_tmsi) {
if (mme_ue->current.m_tmsi) {
ogs_hash_set(self.guti_ue_hash,
&mme_ue->guti, sizeof(ogs_nas_eps_guti_t), NULL);
ogs_assert(mme_m_tmsi_free(mme_ue->m_tmsi) == OGS_OK);
&mme_ue->current.guti, sizeof(ogs_nas_eps_guti_t), NULL);
ogs_assert(mme_m_tmsi_free(mme_ue->current.m_tmsi) == OGS_OK);
}
if (mme_ue->next.m_tmsi) {
ogs_assert(mme_m_tmsi_free(mme_ue->next.m_tmsi) == OGS_OK);
}
if (mme_ue->imsi_len != 0)
ogs_hash_set(self.imsi_ue_hash, mme_ue->imsi, mme_ue->imsi_len, NULL);

View File

@ -312,10 +312,12 @@ struct mme_ue_s {
int a_msisdn_len;
char a_msisdn_bcd[OGS_MAX_MSISDN_BCD_LEN+1];
mme_m_tmsi_t *m_tmsi;
mme_p_tmsi_t p_tmsi;
ogs_nas_eps_guti_t guti;
bool guti_present;
struct {
mme_m_tmsi_t *m_tmsi;
ogs_nas_eps_guti_t guti;
} current, next;
uint32_t mme_s11_teid; /* MME-S11-TEID is derived from INDEX */
uint32_t sgw_s11_teid; /* SGW-S11-TEID is received from SGW */
@ -687,6 +689,7 @@ enb_ue_t *enb_ue_find_by_mme_ue_s1ap_id(uint32_t mme_ue_s1ap_id);
enb_ue_t *enb_ue_cycle(enb_ue_t *enb_ue);
void mme_ue_new_guti(mme_ue_t *mme_ue);
void mme_ue_confirm_guti(mme_ue_t *mme_ue);
mme_ue_t *mme_ue_add(enb_ue_t *enb_ue);
void mme_ue_remove(mme_ue_t *mme_ue);

View File

@ -1416,14 +1416,14 @@ ogs_pkbuf_t *s1ap_build_paging(
/* Set Paging Identity */
UEPagingID->present = S1AP_UEPagingID_PR_s_TMSI;
UEPagingID->choice.s_TMSI = CALLOC(1, sizeof(S1AP_S_TMSI_t));
ogs_asn_uint8_to_OCTET_STRING(mme_ue->guti.mme_code,
ogs_asn_uint8_to_OCTET_STRING(mme_ue->current.guti.mme_code,
&UEPagingID->choice.s_TMSI->mMEC);
ogs_asn_uint32_to_OCTET_STRING(mme_ue->guti.m_tmsi,
ogs_asn_uint32_to_OCTET_STRING(mme_ue->current.guti.m_tmsi,
&UEPagingID->choice.s_TMSI->m_TMSI);
ogs_debug(" MME_CODE[%d] M_TMSI[0x%x]",
mme_ue->guti.mme_code, mme_ue->guti.m_tmsi);
mme_ue->current.guti.mme_code, mme_ue->current.guti.m_tmsi);
ogs_debug(" CN_DOMAIN[%s]",
cn_domain == S1AP_CNDomain_cs ? "CS" :
cn_domain == S1AP_CNDomain_ps ? "PS" : "Unknown");

View File

@ -284,9 +284,9 @@ void s1ap_handle_initial_ue_message(mme_enb_t *enb, ogs_s1ap_message_t *message)
nas_guti.mme_gid, nas_guti.mme_code, nas_guti.m_tmsi);
} else {
ogs_info(" S_TMSI[G:%d,C:%d,M_TMSI:0x%x] IMSI:[%s]",
mme_ue->guti.mme_gid,
mme_ue->guti.mme_code,
mme_ue->guti.m_tmsi,
mme_ue->current.guti.mme_gid,
mme_ue->current.guti.mme_code,
mme_ue->current.guti.m_tmsi,
MME_UE_HAVE_IMSI(mme_ue)
? mme_ue->imsi_bcd : "Unknown");

View File

@ -1361,8 +1361,6 @@ static void test4_func(abts_case *tc, void *data)
memset(&test_ue->attach_request_param,
0, sizeof(test_ue->attach_request_param));
test_ue->attach_request_param.integrity_protected = 1;
test_ue->attach_request_param.guti = 1;
test_ue->attach_request_param.last_visited_registered_tai = 1;
test_ue->attach_request_param.old_guti_type = 1;
emmbuf = testemm_build_attach_request(test_ue, esmbuf);

View File

@ -350,8 +350,6 @@ static void test2_func(abts_case *tc, void *data)
memset(&test_ue->attach_request_param,
0, sizeof(test_ue->attach_request_param));
test_ue->attach_request_param.integrity_protected = 1;
test_ue->attach_request_param.guti = 1;
test_ue->attach_request_param.last_visited_registered_tai = 1;
test_ue->attach_request_param.old_guti_type = 1;
emmbuf = testemm_build_attach_request(test_ue, esmbuf);
@ -634,8 +632,6 @@ static void test3_func(abts_case *tc, void *data)
memset(&test_ue->attach_request_param,
0, sizeof(test_ue->attach_request_param));
test_ue->attach_request_param.integrity_protected = 1;
test_ue->attach_request_param.guti = 1;
test_ue->attach_request_param.last_visited_registered_tai = 1;
test_ue->attach_request_param.old_guti_type = 1;
emmbuf = testemm_build_attach_request(test_ue, esmbuf);

View File

@ -181,6 +181,28 @@ void testgmm_handle_security_mode_command(test_ue_t *test_ue,
test_ue->security_context_available = 1;
}
void testgmm_handle_configuration_update_command(test_ue_t *test_ue,
ogs_nas_5gs_configuration_update_command_t
*configuration_update_command)
{
ogs_assert(test_ue);
ogs_assert(configuration_update_command);
if (configuration_update_command->presencemask &
OGS_NAS_5GS_CONFIGURATION_UPDATE_COMMAND_5G_GUTI_PRESENT) {
ogs_nas_5gs_mobile_identity_t *mobile_identity = NULL;
ogs_nas_5gs_mobile_identity_guti_t *mobile_identity_guti = NULL;
mobile_identity = &configuration_update_command->guti;
mobile_identity_guti = mobile_identity->buffer;
memcpy(&test_ue->nas_5gs_guti.nas_plmn_id,
&mobile_identity_guti->nas_plmn_id, OGS_PLMN_ID_LEN);
memcpy(&test_ue->nas_5gs_guti.amf_id,
&mobile_identity_guti->amf_id, sizeof(ogs_amf_id_t));
test_ue->nas_5gs_guti.m_tmsi = be32toh(mobile_identity_guti->m_tmsi);
}
}
void testgmm_handle_dl_nas_transport(test_ue_t *test_ue,
ogs_nas_5gs_dl_nas_transport_t *dl_nas_transport)
{

View File

@ -36,6 +36,9 @@ void testgmm_handle_authentication_request(test_ue_t *test_ue,
ogs_nas_5gs_authentication_request_t *authentication_request);
void testgmm_handle_security_mode_command(test_ue_t *test_ue,
ogs_nas_5gs_security_mode_command_t *security_mode_command);
void testgmm_handle_configuration_update_command(test_ue_t *test_ue,
ogs_nas_5gs_configuration_update_command_t
*configuration_update_command);
void testgmm_handle_dl_nas_transport(test_ue_t *test_ue,
ogs_nas_5gs_dl_nas_transport_t *dl_nas_transport);

View File

@ -56,6 +56,8 @@ void testgmm_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
case OGS_NAS_5GS_SECURITY_MODE_COMMAND:
break;
case OGS_NAS_5GS_CONFIGURATION_UPDATE_COMMAND:
testgmm_handle_configuration_update_command(
test_ue, &message.gmm.configuration_update_command);
break;
case OGS_NAS_5GS_DL_NAS_TRANSPORT:
testgmm_handle_dl_nas_transport(test_ue, &message.gmm.dl_nas_transport);

View File

@ -168,16 +168,6 @@ static void test1_func(abts_case *tc, void *data)
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
#if 0
/* Send Configuration update complete */
gmmbuf = testgmm_build_configuration_update_complete(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
#endif
/* Send PDU session establishment request */
sess = test_sess_add_by_dnn_and_psi(test_ue, "internet", 5);
ogs_assert(sess);
@ -803,6 +793,19 @@ static void test3_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Registration complete */
gmmbuf = testgmm_build_registration_complete(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Configuration update command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send PDU session establishment request */
sess->ul_nas_transport_param.request_type =
OGS_NAS_5GS_REQUEST_TYPE_INITIAL;

View File

@ -328,8 +328,7 @@ static void test1_func(abts_case *tc, void *data)
test_ue->nas.registration.value =
OGS_NAS_5GS_REGISTRATION_TYPE_PERIODIC_UPDATING;
/* Send Registration request - INVALID_GUTI */
test_ue->nas_5gs_guti.m_tmsi = 0x1234;
/* Send Registration request without Registration complete */
gmmbuf = testgmm_build_registration_request(test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
@ -784,12 +783,25 @@ static void test2_func(abts_case *tc, void *data)
test_ue->ngap_procedure_code);
ABTS_INT_EQUAL(tc, 0x0000, test_ue->pdu_session_reactivation_result);
/* Send Registration complete */
gmmbuf = testgmm_build_registration_complete(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send InitialContextSetupResponse */
sendbuf = testngap_build_initial_context_setup_response(test_ue, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Configuration update command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send GTP-U ICMP Packet */
qos_flow = test_qos_flow_find_by_qfi(sess, 1);
ogs_assert(qos_flow);
@ -844,6 +856,19 @@ static void test2_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Registration complete */
gmmbuf = testgmm_build_registration_complete(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Configuration update command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send PDU session establishment request */
sess->ul_nas_transport_param.request_type =
OGS_NAS_5GS_REQUEST_TYPE_INITIAL;

View File

@ -280,9 +280,6 @@ static void test1_func(abts_case *tc, void *data)
test_ue->nas.registration.value =
OGS_NAS_5GS_REGISTRATION_TYPE_PERIODIC_UPDATING;
/* INVALID GUTI */
test_ue->nas_5gs_guti.m_tmsi = 0x1234;
/* Send Registration request */
gmmbuf = testgmm_build_registration_request(test_ue, NULL);

View File

@ -301,6 +301,19 @@ static void cm_idle_paging_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Configuration update command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send Configuration update complete */
gmmbuf = testgmm_build_configuration_update_complete(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
@ -506,6 +519,19 @@ static void cm_idle_paging_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Configuration update command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send Configuration update complete */
gmmbuf = testgmm_build_configuration_update_complete(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
@ -837,6 +863,19 @@ static void cm_idle_error_indication_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Configuration update command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send Configuration update complete */
gmmbuf = testgmm_build_configuration_update_complete(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Wait to setup N3 data connection.
* Otherwise, network-triggered service request is initiated */
ogs_msleep(100);

View File

@ -302,7 +302,6 @@ static void test2_func(abts_case *tc, void *data)
test_ue->ngap_procedure_code);
/* Send Registration request */
test_ue->registration_request_param.guti = 1;
gmmbuf = testgmm_build_registration_request(test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
@ -730,6 +729,19 @@ static void test3_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Registration complete */
gmmbuf = testgmm_build_registration_complete(test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Configuration update command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(test_ue, recvbuf);
/* Send GTP-U ICMP Packet */
qos_flow = test_qos_flow_find_by_qfi(sess, 1);
ogs_assert(qos_flow);