[SGsAP] Add TMSI-REALLOCATION-COMPLETE

This commit is contained in:
Sukchan Lee 2019-06-22 12:11:07 +09:00
parent 693afa922f
commit 712b9c8334
11 changed files with 271 additions and 201 deletions

View File

@ -23,11 +23,11 @@
#define PLMN_ID_DIGIT2(x) (((x) / 10) % 10)
#define PLMN_ID_DIGIT3(x) ((x) % 10)
uint32_t plmn_id_hexdump(plmn_id_t *plmn_id)
uint32_t plmn_id_hexdump(void *plmn_id)
{
uint32_t hex;
ogs_assert(plmn_id);
memcpy(&hex, plmn_id, sizeof *plmn_id);
memcpy(&hex, plmn_id, sizeof(plmn_id_t));
hex = ntohl(hex) >> 8;
return hex;
}

View File

@ -81,7 +81,7 @@ ED2(uint8_t mnc3:4;,
uint8_t mnc2:4;)
} __attribute__ ((packed)) plmn_id_t;
uint32_t plmn_id_hexdump(plmn_id_t *plmn_id);
uint32_t plmn_id_hexdump(void *plmn_id);
uint16_t plmn_id_mcc(plmn_id_t *plmn_id);
uint16_t plmn_id_mnc(plmn_id_t *plmn_id);

View File

@ -1,3 +1,22 @@
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "nas/nas-message.h"
#include "nas-security.h"
@ -64,8 +83,7 @@ int emm_build_attach_accept(
mme_ue->guti_present ? "[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)
{
if (mme_ue->guti_present) {
attach_accept->presencemask |= NAS_ATTACH_ACCEPT_GUTI_PRESENT;
nas_guti->length = sizeof(nas_eps_mobile_identity_guti_t);
nas_guti->guti.odd_even = NAS_EPS_MOBILE_IDENTITY_EVEN;
@ -98,23 +116,8 @@ int emm_build_attach_accept(
NAS_ATTACH_ACCEPT_LOCATION_AREA_IDENTIFICATION_PRESENT;
lai->nas_plmn_id = mme_ue->vlr->lai.nas_plmn_id;
lai->lac = mme_ue->vlr->lai.lac;
if (lai->nas_plmn_id.mnc3 == 0xf)
ogs_debug(" LAI[MCC:%d%d%d,MNC:%d%d,LAC:%d]",
lai->nas_plmn_id.mcc1,
lai->nas_plmn_id.mcc2,
lai->nas_plmn_id.mcc3,
lai->nas_plmn_id.mnc1,
lai->nas_plmn_id.mnc2,
lai->lac);
else
ogs_debug(" LAI[MCC:%d%d%d,MNC:%d%d%d,LAC:%d]",
lai->nas_plmn_id.mcc1,
lai->nas_plmn_id.mcc2,
lai->nas_plmn_id.mcc3,
lai->nas_plmn_id.mnc1,
lai->nas_plmn_id.mnc2,
lai->nas_plmn_id.mnc3,
lai->lac);
ogs_debug(" LAI[PLMN_ID:%06x,LAC:%d]",
plmn_id_hexdump(&lai->nas_plmn_id), lai->lac);
}
if (mme_ue->p_tmsi) {
@ -147,8 +150,7 @@ int emm_build_attach_reject(
attach_reject->emm_cause = emm_cause;
if (esmbuf)
{
if (esmbuf) {
attach_reject->presencemask |=
NAS_ATTACH_REJECT_ESM_MESSAGE_CONTAINER_PRESENT;
attach_reject->esm_message_container.buffer = esmbuf->data;
@ -158,8 +160,7 @@ int emm_build_attach_reject(
rv = nas_plain_encode(emmbuf, &message);
ogs_assert(rv == OGS_OK && *emmbuf);
if (esmbuf)
{
if (esmbuf) {
ogs_pkbuf_free(esmbuf);
}
@ -263,20 +264,16 @@ int emm_build_security_mode_command(
message.emm.h.protocol_discriminator = NAS_PROTOCOL_DISCRIMINATOR_EMM;
message.emm.h.message_type = NAS_SECURITY_MODE_COMMAND;
for (i = 0; i < mme_self()->num_of_integrity_order; i++)
{
for (i = 0; i < mme_self()->num_of_integrity_order; i++) {
if (mme_ue->ue_network_capability.eia &
(0x80 >> mme_self()->integrity_order[i]))
{
(0x80 >> mme_self()->integrity_order[i])) {
mme_ue->selected_int_algorithm = mme_self()->integrity_order[i];
break;
}
}
for (i = 0; i < mme_self()->num_of_ciphering_order; i++)
{
for (i = 0; i < mme_self()->num_of_ciphering_order; i++) {
if (mme_ue->ue_network_capability.eea &
(0x80 >> mme_self()->ciphering_order[i]))
{
(0x80 >> mme_self()->ciphering_order[i])) {
mme_ue->selected_enc_algorithm = mme_self()->ciphering_order[i];
break;
}
@ -325,8 +322,7 @@ int emm_build_security_mode_command(
replayed_ue_security_capabilities->gea);
ogs_debug(" Selected[Integrity:0x%x Encrypt:0x%x]",
mme_ue->selected_int_algorithm, mme_ue->selected_enc_algorithm);
if (mme_ue->selected_int_algorithm == NAS_SECURITY_ALGORITHMS_EIA0)
{
if (mme_ue->selected_int_algorithm == NAS_SECURITY_ALGORITHMS_EIA0) {
ogs_fatal("Encrypt[0x%x] can be skipped with EEA0, "
"but Integrity[0x%x] cannot be bypassed with EIA0",
mme_ue->selected_enc_algorithm, mme_ue->selected_int_algorithm);
@ -420,25 +416,22 @@ int emm_build_tau_accept(ogs_pkbuf_t **emmbuf, mme_ue_t *mme_ue)
NAS_TRACKING_AREA_UPDATE_ACCEPT_EPS_BEARER_CONTEXT_STATUS_PRESENT;
tau_accept->eps_bearer_context_status.length = 2;
sess = mme_sess_first(mme_ue);
while(sess)
{
while (sess) {
mme_bearer_t *bearer = mme_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;
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 = mme_bearer_next(bearer);

View File

@ -1,11 +1,30 @@
#ifndef __EMM_BUILD_H__
#define __EMM_BUILD_H__
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef EMM_BUILD_H
#define EMM_BUILD_H
#include "mme-context.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif
int emm_build_attach_accept(
ogs_pkbuf_t **emmbuf, mme_ue_t *mme_ue, ogs_pkbuf_t *esmbuf);
@ -33,6 +52,6 @@ int emm_build_service_reject(ogs_pkbuf_t **emmbuf,
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
#endif /* __EMM_BUILD_H__ */
#endif /* EMM_BUILD_H */

View File

@ -1,5 +1,23 @@
#include "nas/nas-message.h"
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "nas/nas-message.h"
#include "mme-event.h"
#include "mme-kdf.h"
@ -10,6 +28,7 @@
#include "nas-path.h"
#include "mme-fd-path.h"
#include "mme-gtp-path.h"
#include "sgsap-path.h"
#include "emm-handler.h"
@ -58,8 +77,7 @@ int emm_handle_attach_request(
*/
CLEAR_EPS_BEARER_ID(mme_ue);
CLEAR_PAGING_INFO(mme_ue);
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
{
if (SECURITY_CONTEXT_IS_VALID(mme_ue)) {
mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32, mme_ue->kenb);
mme_kdf_nh(mme_ue->kasme, mme_ue->kenb, mme_ue->nh);
mme_ue->nhcc = 1;
@ -81,8 +99,7 @@ int emm_handle_attach_request(
/* Check TAI */
served_tai_index = mme_find_served_tai(&mme_ue->tai);
if (served_tai_index < 0)
{
if (served_tai_index < 0) {
/* Send Attach Reject */
ogs_warn("Cannot find Served TAI[PLMN_ID:%06x,TAC:%d]",
plmn_id_hexdump(&mme_ue->tai.plmn_id), mme_ue->tai.tac);
@ -95,8 +112,7 @@ int emm_handle_attach_request(
/* Store UE specific information */
if (attach_request->presencemask &
NAS_ATTACH_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT)
{
NAS_ATTACH_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT) {
nas_tracking_area_identity_t *last_visited_registered_tai =
&attach_request->last_visited_registered_tai;
@ -104,9 +120,7 @@ int emm_handle_attach_request(
&last_visited_registered_tai->nas_plmn_id);
ogs_debug(" Visited_PLMN_ID:%06x",
plmn_id_hexdump(&mme_ue->visited_plmn_id));
}
else
{
} else {
memcpy(&mme_ue->visited_plmn_id, &mme_ue->tai.plmn_id, PLMN_ID_LEN);
}
@ -115,54 +129,50 @@ int emm_handle_attach_request(
sizeof(attach_request->ue_network_capability));
if (attach_request->presencemask &
NAS_ATTACH_REQUEST_MS_NETWORK_CAPABILITY_PRESENT)
{
NAS_ATTACH_REQUEST_MS_NETWORK_CAPABILITY_PRESENT) {
memcpy(&mme_ue->ms_network_capability,
&attach_request->ms_network_capability,
sizeof(attach_request->ms_network_capability));
}
switch(eps_mobile_identity->imsi.type)
switch (eps_mobile_identity->imsi.type) {
case NAS_EPS_MOBILE_IDENTITY_IMSI:
{
case NAS_EPS_MOBILE_IDENTITY_IMSI:
{
char imsi_bcd[MAX_IMSI_BCD_LEN+1];
char imsi_bcd[MAX_IMSI_BCD_LEN+1];
memcpy(&mme_ue->nas_mobile_identity_imsi,
&eps_mobile_identity->imsi, sizeof(nas_mobile_identity_imsi_t));
nas_imsi_to_bcd(
&eps_mobile_identity->imsi, eps_mobile_identity->length,
imsi_bcd);
mme_ue_set_imsi(mme_ue, imsi_bcd);
memcpy(&mme_ue->nas_mobile_identity_imsi,
&eps_mobile_identity->imsi, sizeof(nas_mobile_identity_imsi_t));
nas_imsi_to_bcd(
&eps_mobile_identity->imsi, eps_mobile_identity->length,
imsi_bcd);
mme_ue_set_imsi(mme_ue, imsi_bcd);
ogs_debug(" IMSI[%s]", imsi_bcd);
ogs_debug(" IMSI[%s]", imsi_bcd);
break;
}
case NAS_EPS_MOBILE_IDENTITY_GUTI:
{
nas_eps_mobile_identity_guti_t *nas_eps_mobile_identity_guti =
&eps_mobile_identity->guti;
nas_guti_t nas_guti;
break;
}
case NAS_EPS_MOBILE_IDENTITY_GUTI:
{
nas_eps_mobile_identity_guti_t *nas_eps_mobile_identity_guti =
&eps_mobile_identity->guti;
nas_guti_t nas_guti;
nas_guti.nas_plmn_id = nas_eps_mobile_identity_guti->nas_plmn_id;
nas_guti.mme_gid = nas_eps_mobile_identity_guti->mme_gid;
nas_guti.mme_code = nas_eps_mobile_identity_guti->mme_code;
nas_guti.m_tmsi = nas_eps_mobile_identity_guti->m_tmsi;
nas_guti.nas_plmn_id = nas_eps_mobile_identity_guti->nas_plmn_id;
nas_guti.mme_gid = nas_eps_mobile_identity_guti->mme_gid;
nas_guti.mme_code = nas_eps_mobile_identity_guti->mme_code;
nas_guti.m_tmsi = nas_eps_mobile_identity_guti->m_tmsi;
ogs_debug(" GUTI[G:%d,C:%d,M_TMSI:0x%x] IMSI[%s]",
nas_guti.mme_gid,
nas_guti.mme_code,
nas_guti.m_tmsi,
MME_UE_HAVE_IMSI(mme_ue)
? mme_ue->imsi_bcd : "Unknown");
break;
}
default:
{
ogs_warn("Not implemented[%d]", eps_mobile_identity->imsi.type);
break;
}
ogs_debug(" GUTI[G:%d,C:%d,M_TMSI:0x%x] IMSI[%s]",
nas_guti.mme_gid,
nas_guti.mme_code,
nas_guti.m_tmsi,
MME_UE_HAVE_IMSI(mme_ue)
? mme_ue->imsi_bcd : "Unknown");
break;
}
default:
ogs_warn("Not implemented[%d]", eps_mobile_identity->imsi.type);
break;
}
NAS_STORE_DATA(&mme_ue->pdn_connectivity_request, esm_message_container);
@ -224,13 +234,10 @@ int emm_handle_attach_complete(
NAS_TIME_TO_BCD(gmt.tm_hour);
universal_time_and_local_time_zone->min = NAS_TIME_TO_BCD(gmt.tm_min);
universal_time_and_local_time_zone->sec = NAS_TIME_TO_BCD(gmt.tm_sec);
if (local.tm_gmtoff >= 0)
{
if (local.tm_gmtoff >= 0) {
universal_time_and_local_time_zone->timezone =
NAS_TIME_TO_BCD(local.tm_gmtoff / 900);
}
else
{
} else {
universal_time_and_local_time_zone->timezone =
NAS_TIME_TO_BCD((-local.tm_gmtoff) / 900);
universal_time_and_local_time_zone->timezone |= 0x08;
@ -242,16 +249,14 @@ int emm_handle_attach_complete(
NAS_EMM_INFORMATION_NETWORK_DAYLIGHT_SAVING_TIME_PRESENT;
network_daylight_saving_time->length = 1;
if(mme_self()->full_name.length)
{
if (mme_self()->full_name.length) {
emm_information->presencemask |=
NAS_EMM_INFORMATION_FULL_NAME_FOR_NETWORK_PRESENT;
memcpy(&emm_information->full_name_for_network,
&mme_self()->full_name, sizeof(nas_network_name_t));
}
if(mme_self()->short_name.length)
{
if (mme_self()->short_name.length) {
emm_information->presencemask |=
NAS_EMM_INFORMATION_SHORT_NAME_FOR_NETWORK_PRESENT;
memcpy(&emm_information->short_name_for_network,
@ -265,6 +270,9 @@ int emm_handle_attach_complete(
ogs_debug("[EMM] EMM information");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
if (mme_ue->vlr)
sgsap_send_tmsi_reallocation_complete(mme_ue);
return OGS_OK;
}
@ -282,8 +290,7 @@ int emm_handle_identity_response(
mobile_identity = &identity_response->mobile_identity;
if (mobile_identity->imsi.type == NAS_IDENTITY_TYPE_2_IMSI)
{
if (mobile_identity->imsi.type == NAS_IDENTITY_TYPE_2_IMSI) {
char imsi_bcd[MAX_IMSI_BCD_LEN+1];
memcpy(&mme_ue->nas_mobile_identity_imsi,
@ -293,9 +300,7 @@ int emm_handle_identity_response(
mme_ue_set_imsi(mme_ue, imsi_bcd);
ogs_assert(mme_ue->imsi_len);
}
else
{
} else {
ogs_warn("Not supported Identity type[%d]", mobile_identity->imsi.type);
}
@ -319,26 +324,25 @@ int emm_handle_detach_request(
ogs_debug(" NAS_EPS TYPE[%d] KSI[%d] DETACH[0x%x]",
mme_ue->nas_eps.type, mme_ue->nas_eps.ksi, mme_ue->nas_eps.data);
switch (detach_request->detach_type.detach_type)
{
/* 0 0 1 : EPS detach */
case NAS_DETACH_TYPE_FROM_UE_EPS_DETACH:
ogs_debug(" EPS Detach");
break;
/* 0 1 0 : IMSI detach */
case NAS_DETACH_TYPE_FROM_UE_IMSI_DETACH:
ogs_debug(" IMSI Detach");
break;
case 6: /* 1 1 0 : reserved */
case 7: /* 1 1 1 : reserved */
ogs_warn("Unknown Detach type[%d]",
detach_request->detach_type.detach_type);
break;
/* 0 1 1 : combined EPS/IMSI detach */
case NAS_DETACH_TYPE_FROM_UE_COMBINED_EPS_IMSI_DETACH:
ogs_debug(" Combined EPS/IMSI Detach");
default: /* all other values */
break;
switch (detach_request->detach_type.detach_type) {
/* 0 0 1 : EPS detach */
case NAS_DETACH_TYPE_FROM_UE_EPS_DETACH:
ogs_debug(" EPS Detach");
break;
/* 0 1 0 : IMSI detach */
case NAS_DETACH_TYPE_FROM_UE_IMSI_DETACH:
ogs_debug(" IMSI Detach");
break;
case 6: /* 1 1 0 : reserved */
case 7: /* 1 1 1 : reserved */
ogs_warn("Unknown Detach type[%d]",
detach_request->detach_type.detach_type);
break;
/* 0 1 1 : combined EPS/IMSI detach */
case NAS_DETACH_TYPE_FROM_UE_COMBINED_EPS_IMSI_DETACH:
ogs_debug(" Combined EPS/IMSI Detach");
default: /* all other values */
break;
}
if (detach_request->detach_type.switch_off)
ogs_debug(" Switch-Off");
@ -374,8 +378,7 @@ int emm_handle_service_request(
* Update KeNB
*/
CLEAR_PAGING_INFO(mme_ue);
if (SECURITY_CONTEXT_IS_VALID(mme_ue))
{
if (SECURITY_CONTEXT_IS_VALID(mme_ue)) {
mme_kdf_enb(mme_ue->kasme, mme_ue->ul_count.i32, mme_ue->kenb);
mme_kdf_nh(mme_ue->kasme, mme_ue->kenb, mme_ue->nh);
mme_ue->nhcc = 1;
@ -455,8 +458,7 @@ int emm_handle_tau_request(
/* Check TAI */
served_tai_index = mme_find_served_tai(&mme_ue->tai);
if (served_tai_index < 0)
{
if (served_tai_index < 0) {
/* Send TAU reject */
ogs_warn("Cannot find Served TAI[PLMN_ID:%06x,TAC:%d]",
plmn_id_hexdump(&mme_ue->tai.plmn_id), mme_ue->tai.tac);
@ -467,8 +469,7 @@ int emm_handle_tau_request(
/* Store UE specific information */
if (tau_request->presencemask &
NAS_TRACKING_AREA_UPDATE_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT)
{
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;
@ -476,23 +477,19 @@ int emm_handle_tau_request(
&last_visited_registered_tai->nas_plmn_id);
ogs_debug(" Visited_PLMN_ID:%06x",
plmn_id_hexdump(&mme_ue->visited_plmn_id));
}
else
{
} else {
memcpy(&mme_ue->visited_plmn_id, &mme_ue->tai.plmn_id, PLMN_ID_LEN);
}
if (tau_request->presencemask &
NAS_TRACKING_AREA_UPDATE_REQUEST_UE_NETWORK_CAPABILITY_PRESENT)
{
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)
{
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));
@ -502,34 +499,31 @@ int emm_handle_tau_request(
* 1) Consider if MME is changed or not.
* 2) Consider if SGW is changed or not.
*/
switch(eps_mobile_identity->imsi.type)
switch (eps_mobile_identity->imsi.type) {
case NAS_EPS_MOBILE_IDENTITY_GUTI:
{
case NAS_EPS_MOBILE_IDENTITY_GUTI:
{
nas_eps_mobile_identity_guti_t *nas_eps_mobile_identity_guti =
&eps_mobile_identity->guti;
nas_guti_t nas_guti;
nas_eps_mobile_identity_guti_t *nas_eps_mobile_identity_guti =
&eps_mobile_identity->guti;
nas_guti_t nas_guti;
nas_guti.nas_plmn_id = nas_eps_mobile_identity_guti->nas_plmn_id;
nas_guti.mme_gid = nas_eps_mobile_identity_guti->mme_gid;
nas_guti.mme_code = nas_eps_mobile_identity_guti->mme_code;
nas_guti.m_tmsi = nas_eps_mobile_identity_guti->m_tmsi;
nas_guti.nas_plmn_id = nas_eps_mobile_identity_guti->nas_plmn_id;
nas_guti.mme_gid = nas_eps_mobile_identity_guti->mme_gid;
nas_guti.mme_code = nas_eps_mobile_identity_guti->mme_code;
nas_guti.m_tmsi = nas_eps_mobile_identity_guti->m_tmsi;
ogs_debug(" GUTI[G:%d,C:%d,M_TMSI:0x%x] IMSI:[%s]",
nas_guti.mme_gid,
nas_guti.mme_code,
nas_guti.m_tmsi,
MME_UE_HAVE_IMSI(mme_ue)
? mme_ue->imsi_bcd : "Unknown");
break;
}
default:
{
ogs_warn("Not implemented[%d]",
eps_mobile_identity->imsi.type);
return OGS_OK;
}
ogs_debug(" GUTI[G:%d,C:%d,M_TMSI:0x%x] IMSI:[%s]",
nas_guti.mme_gid,
nas_guti.mme_code,
nas_guti.m_tmsi,
MME_UE_HAVE_IMSI(mme_ue)
? mme_ue->imsi_bcd : "Unknown");
break;
}
default:
ogs_warn("Not implemented[%d]",
eps_mobile_identity->imsi.type);
return OGS_OK;
}
return OGS_OK;

View File

@ -1,5 +1,24 @@
#ifndef __EMM_HANDLER_H__
#define __EMM_HANDLER_H__
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef EMM_HANDLER_H
#define EMM_HANDLER_H
#include "nas/nas-message.h"
@ -7,7 +26,7 @@
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif
int emm_handle_attach_request(
mme_ue_t *mme_ue, nas_attach_request_t *attach_request);
@ -28,6 +47,6 @@ int emm_handle_tau_request(
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
#endif /* __EMM_HANDLER_H__ */
#endif /* EMM_HANDLER_H */

View File

@ -67,12 +67,34 @@ ogs_pkbuf_t *sgsap_build_location_update_request(mme_ue_t *mme_ue)
}
ogs_pkbuf_t *sgsap_build_tmsi_reallocation_complete(mme_ue_t *mme_ue)
{
return NULL;
mme_vlr_t *vlr = NULL;
ogs_tlv_t *root = NULL;
ogs_pkbuf_t *pkbuf = NULL;
ogs_assert(mme_ue);
vlr = mme_ue->vlr;
ogs_assert(vlr);
root = ogs_tlv_add(NULL, SGSAP_IE_IMSI_TYPE, SGSAP_IE_IMSI_LEN, 0,
&mme_ue->nas_mobile_identity_imsi);
pkbuf = ogs_pkbuf_alloc(NULL, MAX_SDU_LEN);
ogs_pkbuf_put_u8(pkbuf, SGSAP_TMSI_REALLOCATION_COMPLETE);
ogs_pkbuf_put(pkbuf, MAX_SDU_LEN-1);
ogs_pkbuf_trim(pkbuf, 1+ogs_tlv_render(root,
pkbuf->data+1, MAX_SDU_LEN-1, OGS_TLV_MODE_T1_L1));
ogs_tlv_free_all(root);
return pkbuf;
}
ogs_pkbuf_t *sgsap_build_service_request(mme_ue_t *mme_ue)
{
return NULL;
}
ogs_pkbuf_t *sgsap_build_mo_csfb_indication(mme_ue_t *mme_ue)
{
return NULL;

View File

@ -38,6 +38,8 @@ void sgsap_handler_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
ogs_assert(vlr);
ogs_assert(pkbuf);
ogs_debug("[SGSAP] LOCATION-UPDATE-ACCEPT");
ogs_pkbuf_pull(pkbuf, 1);
root = ogs_tlv_parse_block(pkbuf->len, pkbuf->data, OGS_TLV_MODE_T1_L1);
@ -87,6 +89,9 @@ void sgsap_handler_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
goto error;
}
ogs_debug(" IMSI[%s] P-TMSI[0x%08x]",
mme_ue->imsi_bcd, mme_ue->p_tmsi);
nas_send_attach_accept(mme_ue);
return;

View File

@ -87,23 +87,11 @@ int sgsap_send_to_vlr_with_sid(
sock = node->sock;
ogs_assert(sock);
ogs_debug(" IP[%s] TAI[MCC:%d%d%d,MNC:%d%d%d,TAC:%d]",
OGS_ADDR(node->addr, buf),
vlr->tai.nas_plmn_id.mcc1,
vlr->tai.nas_plmn_id.mcc2,
vlr->tai.nas_plmn_id.mcc3,
vlr->tai.nas_plmn_id.mnc1,
vlr->tai.nas_plmn_id.mnc2,
vlr->tai.nas_plmn_id.mnc3,
vlr->tai.tac);
ogs_debug(" LAI[MCC:%d%d%d,MNC:%d%d%d,TAC:%d]",
vlr->lai.nas_plmn_id.mcc1,
vlr->lai.nas_plmn_id.mcc2,
vlr->lai.nas_plmn_id.mcc3,
vlr->lai.nas_plmn_id.mnc1,
vlr->lai.nas_plmn_id.mnc2,
vlr->lai.nas_plmn_id.mnc3,
vlr->lai.lac);
ogs_debug(" VLR-IP[%s]", OGS_ADDR(node->addr, buf));
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
plmn_id_hexdump(&vlr->tai.nas_plmn_id), vlr->tai.tac);
ogs_debug(" LAI[PLMN_ID:%06x,LAC:%d]",
plmn_id_hexdump(&vlr->lai.nas_plmn_id), vlr->lai.lac);
rv = sgsap_send(sock, pkbuf, node->addr, stream_no);
if (rv != OGS_OK) {
@ -131,6 +119,8 @@ int sgsap_send_location_update_request(mme_ue_t *mme_ue)
ogs_pkbuf_t *pkbuf = NULL;
ogs_assert(mme_ue);
ogs_debug("[SGSAP] LOCATION-UPDATE-REQUEST");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
pkbuf = sgsap_build_location_update_request(mme_ue);
rv = sgsap_send_to_vlr(mme_ue, pkbuf);
@ -138,3 +128,19 @@ int sgsap_send_location_update_request(mme_ue_t *mme_ue)
return OGS_OK;
}
int sgsap_send_tmsi_reallocation_complete(mme_ue_t *mme_ue)
{
int rv;
ogs_pkbuf_t *pkbuf = NULL;
ogs_assert(mme_ue);
ogs_debug("[SGSAP] TMSI-REALLOCATION-COMPLETE");
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
pkbuf = sgsap_build_tmsi_reallocation_complete(mme_ue);
rv = sgsap_send_to_vlr(mme_ue, pkbuf);
ogs_assert(rv == OGS_OK);
return OGS_OK;
}

View File

@ -40,6 +40,7 @@ int sgsap_send_to_vlr_with_sid(
int sgsap_send_to_vlr(mme_ue_t *mme_ue, ogs_pkbuf_t *pkbuf);
int sgsap_send_location_update_request(mme_ue_t *mme_ue);
int sgsap_send_tmsi_reallocation_complete(mme_ue_t *mme_ue);
#ifdef __cplusplus
}

View File

@ -53,6 +53,8 @@ static void test1_func(abts_case *tc, void *data)
char *_emm_information =
"000b403800000300 0000020001000800 020001001a002524 2751034124030761"
"430f10004e006500 7800740045005000 4347916051216124 63490100";
char *_sgsap_tmsi_reallocation_complete =
"0c01082926240000 111893";
mongoc_collection_t *collection = NULL;
bson_t *doc = NULL;
@ -253,6 +255,15 @@ static void test1_func(abts_case *tc, void *data)
ABTS_TRUE(tc, memcmp(recvbuf->data+57, tmp+57, 3) == 0);
ogs_pkbuf_free(recvbuf);
/* Receive SGsAP TMSI-REALLOCATION-COMPLETE */
recvbuf = testvlr_sgsap_read(sgsap);
ABTS_PTR_NOTNULL(tc, recvbuf);
ABTS_TRUE(tc, memcmp(recvbuf->data,
OGS_HEX(_sgsap_tmsi_reallocation_complete,
strlen(_sgsap_tmsi_reallocation_complete), tmp),
recvbuf->len) == 0);
ogs_pkbuf_free(recvbuf);
#if 0 /* Sometimes, it's not working. */
/* Send GTP-U ICMP Packet */
rv = testgtpu_build_ping(&sendbuf, "45.45.0.2", "45.45.0.1");