2019-06-21 15:28:21 +00:00
|
|
|
/*
|
|
|
|
* 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 "sgsap-types.h"
|
2019-07-12 14:18:17 +00:00
|
|
|
#include "sgsap-build.h"
|
2019-07-07 01:16:21 +00:00
|
|
|
#include "sgsap-path.h"
|
2019-10-27 08:41:14 +00:00
|
|
|
#include "sgsap-handler.h"
|
2019-06-21 15:28:21 +00:00
|
|
|
|
2019-07-14 02:00:11 +00:00
|
|
|
#include "mme-sm.h"
|
2019-06-21 15:28:21 +00:00
|
|
|
#include "mme-context.h"
|
|
|
|
#include "mme-path.h"
|
|
|
|
#include "nas-path.h"
|
2019-07-08 09:15:19 +00:00
|
|
|
#include "s1ap-path.h"
|
2019-06-21 15:28:21 +00:00
|
|
|
|
2019-07-05 09:13:32 +00:00
|
|
|
void sgsap_handle_location_update_accept(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
|
2019-06-21 15:28:21 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r;
|
2019-06-21 15:28:21 +00:00
|
|
|
ogs_tlv_t *root = NULL, *iter = NULL;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
2019-07-13 05:51:35 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_nas_mobile_identity_imsi_t *nas_mobile_identity_imsi = NULL;
|
2019-06-21 15:28:21 +00:00
|
|
|
int nas_mobile_identity_imsi_len = 0;
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_nas_lai_t *lai = NULL;
|
|
|
|
ogs_nas_mobile_identity_tmsi_t *nas_mobile_identity_tmsi = NULL;
|
2019-06-21 15:28:21 +00:00
|
|
|
|
|
|
|
ogs_assert(vlr);
|
|
|
|
ogs_assert(pkbuf);
|
|
|
|
|
2019-06-22 03:11:07 +00:00
|
|
|
ogs_debug("[SGSAP] LOCATION-UPDATE-ACCEPT");
|
|
|
|
|
2019-06-21 15:28:21 +00:00
|
|
|
ogs_pkbuf_pull(pkbuf, 1);
|
|
|
|
|
|
|
|
root = ogs_tlv_parse_block(pkbuf->len, pkbuf->data, OGS_TLV_MODE_T1_L1);
|
2022-06-23 12:37:47 +00:00
|
|
|
if (!root) {
|
2023-01-23 15:01:36 +00:00
|
|
|
ogs_error("ogs_tlv_parse_block() failed");
|
2019-11-29 06:31:22 +00:00
|
|
|
goto error;
|
2022-06-23 12:37:47 +00:00
|
|
|
}
|
2019-06-21 15:28:21 +00:00
|
|
|
|
|
|
|
iter = root;
|
|
|
|
while (iter) {
|
|
|
|
switch (iter->type) {
|
|
|
|
case SGSAP_IE_IMSI_TYPE:
|
|
|
|
nas_mobile_identity_imsi = iter->value;
|
|
|
|
nas_mobile_identity_imsi_len = iter->length;
|
|
|
|
break;
|
|
|
|
case SGSAP_IE_LAI_TYPE:
|
|
|
|
lai = iter->value;
|
|
|
|
break;
|
|
|
|
case SGSAP_IE_MOBILE_IDENTITY_TYPE:
|
|
|
|
nas_mobile_identity_tmsi = iter->value;
|
|
|
|
break;
|
2019-07-05 06:55:07 +00:00
|
|
|
default:
|
|
|
|
ogs_warn("Invalid Type [%d]", iter->type);
|
|
|
|
break;
|
2019-06-21 15:28:21 +00:00
|
|
|
}
|
|
|
|
iter = iter->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_tlv_free_all(root);
|
|
|
|
|
2022-06-23 12:37:47 +00:00
|
|
|
if (!nas_mobile_identity_imsi || !lai) {
|
|
|
|
ogs_error("!nas_mobile_identity_imsi || !lai");
|
2019-11-29 06:31:22 +00:00
|
|
|
goto error;
|
2022-06-23 12:37:47 +00:00
|
|
|
}
|
|
|
|
if (nas_mobile_identity_imsi_len != SGSAP_IE_IMSI_LEN) {
|
|
|
|
ogs_error("nas_mobile_identity_imsi_len != SGSAP_IE_IMSI_LEN");
|
2019-11-29 06:31:22 +00:00
|
|
|
goto error;
|
2022-06-23 12:37:47 +00:00
|
|
|
}
|
2019-06-21 15:28:21 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
if (nas_mobile_identity_imsi->type == OGS_NAS_MOBILE_IDENTITY_IMSI) {
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_nas_eps_imsi_to_bcd(nas_mobile_identity_imsi,
|
2019-06-21 15:28:21 +00:00
|
|
|
nas_mobile_identity_imsi_len, imsi_bcd);
|
|
|
|
mme_ue = mme_ue_find_by_imsi_bcd(imsi_bcd);
|
2022-06-23 12:37:47 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("nas_mobile_identity_imsi->type == "
|
|
|
|
"OGS_NAS_MOBILE_IDENTITY_IMSI");
|
2019-11-29 06:31:22 +00:00
|
|
|
goto error;
|
2022-06-23 12:37:47 +00:00
|
|
|
}
|
2019-06-21 15:28:21 +00:00
|
|
|
|
2022-06-23 12:37:47 +00:00
|
|
|
if (!mme_ue) {
|
|
|
|
ogs_error("!mme_ue");
|
2019-11-29 06:31:22 +00:00
|
|
|
goto error;
|
2022-06-23 12:37:47 +00:00
|
|
|
}
|
2019-06-21 15:28:21 +00:00
|
|
|
|
2019-07-05 06:55:07 +00:00
|
|
|
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
|
2019-07-08 09:15:19 +00:00
|
|
|
if (lai) {
|
|
|
|
ogs_debug(" LAI[PLMN_ID:%06x,LAC:%d]",
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_plmn_id_hexdump(&lai->nas_plmn_id), lai->lac);
|
2019-07-08 09:15:19 +00:00
|
|
|
}
|
2019-06-21 15:28:21 +00:00
|
|
|
|
2019-07-05 06:55:07 +00:00
|
|
|
if (nas_mobile_identity_tmsi) {
|
2019-09-13 12:07:47 +00:00
|
|
|
if (nas_mobile_identity_tmsi->type == OGS_NAS_MOBILE_IDENTITY_TMSI) {
|
2020-10-01 17:27:58 +00:00
|
|
|
mme_ue->p_tmsi = be32toh(nas_mobile_identity_tmsi->tmsi);
|
2019-07-05 06:55:07 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("Not supported Identity type[%d]",
|
|
|
|
nas_mobile_identity_tmsi->type);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
ogs_debug(" P-TMSI[0x%08x]", mme_ue->p_tmsi);
|
|
|
|
}
|
2019-06-22 03:11:07 +00:00
|
|
|
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_attach_accept(mme_ue);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2019-06-21 15:28:21 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
error:
|
2024-03-16 13:59:36 +00:00
|
|
|
r = nas_eps_send_attach_reject(mme_ue->enb_ue, mme_ue,
|
2022-12-27 12:06:44 +00:00
|
|
|
OGS_NAS_EMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED,
|
2023-01-23 01:37:22 +00:00
|
|
|
OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2019-11-15 14:56:55 +00:00
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
2019-06-21 15:28:21 +00:00
|
|
|
}
|
2019-07-05 06:55:07 +00:00
|
|
|
|
2019-07-05 09:13:32 +00:00
|
|
|
void sgsap_handle_location_update_reject(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
|
2019-07-05 06:55:07 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r;
|
2019-07-05 06:55:07 +00:00
|
|
|
ogs_tlv_t *root = NULL, *iter = NULL;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
2019-07-13 05:51:35 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_nas_mobile_identity_imsi_t *nas_mobile_identity_imsi = NULL;
|
2019-07-05 06:55:07 +00:00
|
|
|
int nas_mobile_identity_imsi_len = 0;
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_nas_emm_cause_t emm_cause = 0;
|
|
|
|
ogs_nas_lai_t *lai = NULL;
|
2019-07-05 06:55:07 +00:00
|
|
|
|
|
|
|
ogs_assert(vlr);
|
|
|
|
ogs_assert(pkbuf);
|
|
|
|
|
|
|
|
ogs_warn("[SGSAP] LOCATION-UPDATE-REJECT");
|
|
|
|
|
|
|
|
ogs_pkbuf_pull(pkbuf, 1);
|
|
|
|
|
|
|
|
root = ogs_tlv_parse_block(pkbuf->len, pkbuf->data, OGS_TLV_MODE_T1_L1);
|
2022-06-23 12:37:47 +00:00
|
|
|
if (!root) {
|
2023-01-23 15:01:36 +00:00
|
|
|
ogs_error("ogs_tlv_parse_block() failed");
|
2019-11-29 06:31:22 +00:00
|
|
|
goto error;
|
2022-06-23 12:37:47 +00:00
|
|
|
}
|
2019-07-05 06:55:07 +00:00
|
|
|
|
|
|
|
iter = root;
|
|
|
|
while (iter) {
|
|
|
|
switch (iter->type) {
|
|
|
|
case SGSAP_IE_IMSI_TYPE:
|
|
|
|
nas_mobile_identity_imsi = iter->value;
|
|
|
|
nas_mobile_identity_imsi_len = iter->length;
|
|
|
|
break;
|
|
|
|
case SGSAP_IE_LAI_TYPE:
|
2019-07-08 09:15:19 +00:00
|
|
|
lai = iter->value;
|
2019-07-05 06:55:07 +00:00
|
|
|
break;
|
|
|
|
case SGSAP_IE_REJECT_CAUSE_TYPE:
|
|
|
|
emm_cause = *((uint8_t*)(iter->value));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_warn("Invalid Type [%d]", iter->type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
iter = iter->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_tlv_free_all(root);
|
|
|
|
|
2022-06-23 12:37:47 +00:00
|
|
|
if (!nas_mobile_identity_imsi || !emm_cause) {
|
|
|
|
ogs_error("!nas_mobile_identity_imsi || !emm_cause");
|
2019-11-29 06:31:22 +00:00
|
|
|
goto error;
|
2022-06-23 12:37:47 +00:00
|
|
|
}
|
|
|
|
if (nas_mobile_identity_imsi_len != SGSAP_IE_IMSI_LEN) {
|
|
|
|
ogs_error("nas_mobile_identity_imsi_len != SGSAP_IE_IMSI_LEN");
|
2019-11-29 06:31:22 +00:00
|
|
|
goto error;
|
2022-06-23 12:37:47 +00:00
|
|
|
}
|
2019-07-05 06:55:07 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
if (nas_mobile_identity_imsi->type == OGS_NAS_MOBILE_IDENTITY_IMSI) {
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_nas_eps_imsi_to_bcd(nas_mobile_identity_imsi,
|
2019-07-05 06:55:07 +00:00
|
|
|
nas_mobile_identity_imsi_len, imsi_bcd);
|
|
|
|
mme_ue = mme_ue_find_by_imsi_bcd(imsi_bcd);
|
2022-06-23 12:37:47 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("nas_mobile_identity_imsi->type == "
|
|
|
|
"OGS_NAS_MOBILE_IDENTITY_IMSI");
|
2019-11-29 06:31:22 +00:00
|
|
|
goto error;
|
2022-06-23 12:37:47 +00:00
|
|
|
}
|
2019-07-05 06:55:07 +00:00
|
|
|
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!mme_ue) {
|
|
|
|
ogs_error("No UE(mme-ue) context");
|
|
|
|
return;
|
|
|
|
}
|
2019-07-05 06:55:07 +00:00
|
|
|
|
|
|
|
ogs_debug(" IMSI[%s] CAUSE[%d]", mme_ue->imsi_bcd, emm_cause);
|
2019-07-08 09:15:19 +00:00
|
|
|
if (lai) {
|
|
|
|
ogs_debug(" LAI[PLMN_ID:%06x,LAC:%d]",
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_plmn_id_hexdump(&lai->nas_plmn_id), lai->lac);
|
2019-07-08 09:15:19 +00:00
|
|
|
}
|
2019-07-05 06:55:07 +00:00
|
|
|
|
2024-03-24 11:30:04 +00:00
|
|
|
r = nas_eps_send_attach_accept(mme_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2019-11-29 06:31:22 +00:00
|
|
|
|
|
|
|
return;
|
2022-08-19 09:58:55 +00:00
|
|
|
|
2019-11-29 06:31:22 +00:00
|
|
|
error:
|
|
|
|
ogs_error("Error processing SGsAP LU REJECT");
|
|
|
|
return;
|
2019-07-05 06:55:07 +00:00
|
|
|
}
|
2019-07-05 09:13:32 +00:00
|
|
|
|
|
|
|
void sgsap_handle_detach_ack(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
|
|
|
|
{
|
|
|
|
ogs_tlv_t *root = NULL, *iter = NULL;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
2019-07-13 05:51:35 +00:00
|
|
|
|
2019-07-05 09:13:32 +00:00
|
|
|
uint8_t type = 0;
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_nas_mobile_identity_imsi_t *nas_mobile_identity_imsi = NULL;
|
2019-07-05 09:13:32 +00:00
|
|
|
int nas_mobile_identity_imsi_len = 0;
|
|
|
|
|
|
|
|
ogs_assert(vlr);
|
|
|
|
ogs_assert(pkbuf);
|
|
|
|
|
|
|
|
type = *(unsigned char *)(pkbuf->data);
|
|
|
|
if (type == SGSAP_EPS_DETACH_ACK)
|
|
|
|
ogs_debug("[SGSAP] EPS-DETACH-ACK");
|
|
|
|
else if (type == SGSAP_IMSI_DETACH_ACK)
|
|
|
|
ogs_debug("[SGSAP] IMSI-DETACH-ACK");
|
2023-01-23 15:01:36 +00:00
|
|
|
else {
|
|
|
|
ogs_error("Unknown type [%d]", type);
|
|
|
|
return;
|
|
|
|
}
|
2019-07-05 09:13:32 +00:00
|
|
|
|
|
|
|
ogs_pkbuf_pull(pkbuf, 1);
|
|
|
|
|
|
|
|
root = ogs_tlv_parse_block(pkbuf->len, pkbuf->data, OGS_TLV_MODE_T1_L1);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!root) {
|
|
|
|
ogs_error("ogs_tlv_parse_block() failed");
|
|
|
|
return;
|
|
|
|
}
|
2019-07-05 09:13:32 +00:00
|
|
|
|
|
|
|
iter = root;
|
|
|
|
while (iter) {
|
|
|
|
switch (iter->type) {
|
|
|
|
case SGSAP_IE_IMSI_TYPE:
|
|
|
|
nas_mobile_identity_imsi = iter->value;
|
|
|
|
nas_mobile_identity_imsi_len = iter->length;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_warn("Invalid Type [%d]", iter->type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
iter = iter->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_tlv_free_all(root);
|
|
|
|
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!nas_mobile_identity_imsi) {
|
|
|
|
ogs_error("No IMSI");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (nas_mobile_identity_imsi_len != SGSAP_IE_IMSI_LEN) {
|
|
|
|
ogs_error("Invalid IMSI len [%d]", nas_mobile_identity_imsi_len);
|
|
|
|
return;
|
|
|
|
}
|
2019-07-05 09:13:32 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
if (nas_mobile_identity_imsi->type == OGS_NAS_MOBILE_IDENTITY_IMSI) {
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_nas_eps_imsi_to_bcd(nas_mobile_identity_imsi,
|
2019-07-05 09:13:32 +00:00
|
|
|
nas_mobile_identity_imsi_len, imsi_bcd);
|
|
|
|
mme_ue = mme_ue_find_by_imsi_bcd(imsi_bcd);
|
2023-01-23 15:01:36 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("Unknown type [%d]", nas_mobile_identity_imsi->type);
|
|
|
|
return;
|
|
|
|
}
|
2019-07-05 09:13:32 +00:00
|
|
|
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!mme_ue) {
|
|
|
|
ogs_error("No UE(mme-ue) context");
|
|
|
|
return;
|
|
|
|
}
|
2019-07-05 09:13:32 +00:00
|
|
|
|
|
|
|
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
|
2019-07-08 09:15:19 +00:00
|
|
|
|
2022-07-30 05:44:34 +00:00
|
|
|
mme_send_delete_session_or_detach(mme_ue);
|
2019-07-05 09:13:32 +00:00
|
|
|
}
|
2019-07-07 01:16:21 +00:00
|
|
|
|
2019-07-08 09:15:19 +00:00
|
|
|
void sgsap_handle_paging_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
|
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r;
|
2019-07-08 09:15:19 +00:00
|
|
|
ogs_tlv_t *root = NULL, *iter = NULL;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
2019-07-13 05:51:35 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_nas_mobile_identity_imsi_t *nas_mobile_identity_imsi = NULL;
|
2019-07-08 09:15:19 +00:00
|
|
|
int nas_mobile_identity_imsi_len = 0;
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_nas_lai_t *lai = NULL;
|
2019-07-08 09:15:19 +00:00
|
|
|
char vlr_name[SGSAP_IE_VLR_NAME_LEN] = { 0, };
|
|
|
|
uint8_t service_indicator = 0;
|
|
|
|
|
|
|
|
ogs_assert(vlr);
|
|
|
|
ogs_assert(pkbuf);
|
|
|
|
|
|
|
|
ogs_debug("[SGSAP] PAGING-REQUEST");
|
|
|
|
|
|
|
|
ogs_pkbuf_pull(pkbuf, 1);
|
|
|
|
|
|
|
|
root = ogs_tlv_parse_block(pkbuf->len, pkbuf->data, OGS_TLV_MODE_T1_L1);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!root) {
|
|
|
|
ogs_error("ogs_tlv_parse_block() failed");
|
|
|
|
return;
|
|
|
|
}
|
2019-07-08 09:15:19 +00:00
|
|
|
|
|
|
|
iter = root;
|
|
|
|
while (iter) {
|
|
|
|
switch (iter->type) {
|
|
|
|
case SGSAP_IE_IMSI_TYPE:
|
|
|
|
nas_mobile_identity_imsi = iter->value;
|
|
|
|
nas_mobile_identity_imsi_len = iter->length;
|
|
|
|
break;
|
|
|
|
case SGSAP_IE_VLR_NAME_TYPE:
|
2021-10-01 13:41:03 +00:00
|
|
|
ogs_assert(0 < ogs_fqdn_parse(
|
|
|
|
vlr_name, iter->value,
|
2022-01-22 00:34:38 +00:00
|
|
|
ogs_min(iter->length, SGSAP_IE_VLR_NAME_LEN)));
|
2019-07-08 09:15:19 +00:00
|
|
|
break;
|
|
|
|
case SGSAP_IE_LAI_TYPE:
|
|
|
|
lai = iter->value;
|
|
|
|
break;
|
|
|
|
case SGSAP_IE_SERVICE_INDICATOR_TYPE:
|
|
|
|
service_indicator = *((uint8_t*)(iter->value));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_warn("Invalid Type [%d]", iter->type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
iter = iter->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_tlv_free_all(root);
|
|
|
|
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!nas_mobile_identity_imsi) {
|
|
|
|
ogs_error("No IMSI");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (nas_mobile_identity_imsi_len != SGSAP_IE_IMSI_LEN) {
|
|
|
|
ogs_error("Invalid IMSI len [%d]", nas_mobile_identity_imsi_len);
|
|
|
|
return;
|
|
|
|
}
|
2019-07-08 09:15:19 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
if (nas_mobile_identity_imsi->type == OGS_NAS_MOBILE_IDENTITY_IMSI) {
|
2019-07-08 09:15:19 +00:00
|
|
|
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_nas_eps_imsi_to_bcd(nas_mobile_identity_imsi,
|
2019-07-08 09:15:19 +00:00
|
|
|
nas_mobile_identity_imsi_len, imsi_bcd);
|
|
|
|
mme_ue = mme_ue_find_by_imsi_bcd(imsi_bcd);
|
2023-01-23 15:01:36 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("Unknown type [%d]", nas_mobile_identity_imsi->type);
|
|
|
|
return;
|
|
|
|
}
|
2019-07-08 09:15:19 +00:00
|
|
|
|
2019-07-12 09:33:42 +00:00
|
|
|
if (mme_ue) {
|
|
|
|
ogs_assert(service_indicator);
|
|
|
|
mme_ue->service_indicator = service_indicator;
|
2019-07-08 09:15:19 +00:00
|
|
|
|
2019-07-12 09:33:42 +00:00
|
|
|
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
|
|
|
|
ogs_debug(" VLR_NAME[%s]", vlr_name);
|
|
|
|
ogs_debug(" SERVICE_INDICATOR[%d]", mme_ue->service_indicator);
|
2019-07-08 09:15:19 +00:00
|
|
|
|
2019-07-12 09:33:42 +00:00
|
|
|
if (lai) {
|
|
|
|
ogs_debug(" LAI[PLMN_ID:%06x,LAC:%d]",
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_plmn_id_hexdump(&lai->nas_plmn_id), lai->lac);
|
2019-07-12 09:33:42 +00:00
|
|
|
}
|
2019-07-08 09:15:19 +00:00
|
|
|
|
2019-07-13 13:52:50 +00:00
|
|
|
if (ECM_IDLE(mme_ue)) {
|
2019-07-14 02:00:11 +00:00
|
|
|
if (CS_CALL_SERVICE_INDICATOR(mme_ue)) {
|
[AMF/MME] Remove code that doesn't work (#2013)
Based on the standard document below, when the UE is in the IDLE state,
we checked the implicit timer and tried to send a message to the UE,
but it doesn't work properly.
So, first of all, I deleted the related code.
- TS 24.301 Ch 5.3.7
If ISR is not activated, the network behaviour upon expiry of
the mobile reachable timer is network dependent, but typically
the network stops sending paging messages to the UE on the
first expiry, and may take other appropriate actions
- TS 24.501 Ch 5.3.7
The network behaviour upon expiry of the mobile reachable timer is network dependent,
but typically the network stops sending paging messages to the UE on the first expiry,
and may take other appropriate actions.
2023-07-23 05:54:06 +00:00
|
|
|
/* UE will respond Extended Service Request in PS CNDomain*/
|
|
|
|
MME_STORE_PAGING_INFO(mme_ue,
|
|
|
|
MME_PAGING_TYPE_CS_CALL_SERVICE, NULL);
|
|
|
|
r = s1ap_send_paging(mme_ue, S1AP_CNDomain_cs);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2019-07-14 02:00:11 +00:00
|
|
|
} else if (SMS_SERVICE_INDICATOR(mme_ue)) {
|
[AMF/MME] Remove code that doesn't work (#2013)
Based on the standard document below, when the UE is in the IDLE state,
we checked the implicit timer and tried to send a message to the UE,
but it doesn't work properly.
So, first of all, I deleted the related code.
- TS 24.301 Ch 5.3.7
If ISR is not activated, the network behaviour upon expiry of
the mobile reachable timer is network dependent, but typically
the network stops sending paging messages to the UE on the
first expiry, and may take other appropriate actions
- TS 24.501 Ch 5.3.7
The network behaviour upon expiry of the mobile reachable timer is network dependent,
but typically the network stops sending paging messages to the UE on the first expiry,
and may take other appropriate actions.
2023-07-23 05:54:06 +00:00
|
|
|
/* UE will respond Service Request in PS CNDomain*/
|
|
|
|
MME_STORE_PAGING_INFO(mme_ue,
|
|
|
|
MME_PAGING_TYPE_SMS_SERVICE, NULL);
|
|
|
|
r = s1ap_send_paging(mme_ue, S1AP_CNDomain_ps);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2019-07-13 13:52:50 +00:00
|
|
|
} else
|
|
|
|
goto paging_reject;
|
|
|
|
|
|
|
|
} else {
|
2023-02-20 11:49:48 +00:00
|
|
|
MME_CLEAR_PAGING_INFO(mme_ue);
|
2019-11-29 02:39:32 +00:00
|
|
|
if (CS_CALL_SERVICE_INDICATOR(mme_ue)) {
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_cs_service_notification(mme_ue);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2019-11-29 02:39:32 +00:00
|
|
|
} else if (SMS_SERVICE_INDICATOR(mme_ue)) {
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgsap_send_service_request(
|
|
|
|
mme_ue, SGSAP_EMM_CONNECTED_MODE));
|
2019-11-29 02:39:32 +00:00
|
|
|
} else
|
|
|
|
goto paging_reject;
|
2019-07-13 13:52:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
paging_reject:
|
|
|
|
ogs_debug("[SGSAP] PAGING-REJECT");
|
|
|
|
ogs_debug(" IMSI[%s]", imsi_bcd);
|
|
|
|
|
|
|
|
sgsap_send_to_vlr_with_sid(
|
2022-08-19 09:58:55 +00:00
|
|
|
vlr,
|
2019-07-13 13:52:50 +00:00
|
|
|
sgsap_build_paging_reject(
|
|
|
|
nas_mobile_identity_imsi, nas_mobile_identity_imsi_len,
|
|
|
|
SGSAP_SGS_CAUSE_IMSI_UNKNOWN),
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sgsap_handle_downlink_unitdata(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
|
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r;
|
2019-07-13 13:52:50 +00:00
|
|
|
ogs_tlv_t *root = NULL, *iter = NULL;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
2019-07-13 13:52:50 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_nas_mobile_identity_imsi_t *nas_mobile_identity_imsi = NULL;
|
2019-07-13 13:52:50 +00:00
|
|
|
int nas_mobile_identity_imsi_len = 0;
|
|
|
|
uint8_t *nas_message_container_buffer = NULL;
|
|
|
|
uint8_t nas_message_container_length = 0;
|
|
|
|
|
|
|
|
ogs_assert(vlr);
|
|
|
|
ogs_assert(pkbuf);
|
|
|
|
|
|
|
|
ogs_debug("[SGSAP] DOWNLINK-UNITDATA");
|
|
|
|
|
|
|
|
ogs_pkbuf_pull(pkbuf, 1);
|
|
|
|
|
|
|
|
root = ogs_tlv_parse_block(pkbuf->len, pkbuf->data, OGS_TLV_MODE_T1_L1);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!root) {
|
|
|
|
ogs_error("ogs_tlv_parse_block() failed");
|
|
|
|
return;
|
|
|
|
}
|
2019-07-13 13:52:50 +00:00
|
|
|
|
|
|
|
iter = root;
|
|
|
|
while (iter) {
|
|
|
|
switch (iter->type) {
|
|
|
|
case SGSAP_IE_IMSI_TYPE:
|
|
|
|
nas_mobile_identity_imsi = iter->value;
|
|
|
|
nas_mobile_identity_imsi_len = iter->length;
|
|
|
|
break;
|
|
|
|
case SGSAP_IE_NAS_MESSAGE_CONTAINER_TYPE:
|
|
|
|
nas_message_container_buffer = iter->value;
|
|
|
|
nas_message_container_length = iter->length;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_warn("Invalid Type [%d]", iter->type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
iter = iter->next;
|
2019-07-08 09:15:19 +00:00
|
|
|
}
|
2019-07-13 13:52:50 +00:00
|
|
|
|
|
|
|
ogs_tlv_free_all(root);
|
|
|
|
|
|
|
|
ogs_assert(nas_mobile_identity_imsi);
|
|
|
|
ogs_assert(nas_mobile_identity_imsi_len == SGSAP_IE_IMSI_LEN);
|
|
|
|
ogs_assert(nas_message_container_buffer);
|
|
|
|
ogs_assert(nas_message_container_length);
|
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
if (nas_mobile_identity_imsi->type == OGS_NAS_MOBILE_IDENTITY_IMSI) {
|
2019-07-13 13:52:50 +00:00
|
|
|
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_nas_eps_imsi_to_bcd(nas_mobile_identity_imsi,
|
2019-07-13 13:52:50 +00:00
|
|
|
nas_mobile_identity_imsi_len, imsi_bcd);
|
|
|
|
mme_ue = mme_ue_find_by_imsi_bcd(imsi_bcd);
|
2022-08-19 09:58:55 +00:00
|
|
|
} else
|
2019-07-13 13:52:50 +00:00
|
|
|
ogs_assert_if_reached();
|
|
|
|
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!mme_ue) {
|
|
|
|
ogs_error("No UE(mme-ue) context");
|
|
|
|
return;
|
|
|
|
}
|
2019-07-13 13:52:50 +00:00
|
|
|
|
|
|
|
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
|
|
|
|
ogs_log_hexdump(OGS_LOG_DEBUG,
|
|
|
|
nas_message_container_buffer,
|
|
|
|
nas_message_container_length);
|
|
|
|
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_downlink_nas_transport(mme_ue,
|
|
|
|
nas_message_container_buffer, nas_message_container_length);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2019-07-08 09:15:19 +00:00
|
|
|
}
|
|
|
|
|
2019-07-07 01:16:21 +00:00
|
|
|
void sgsap_handle_reset_indication(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
|
|
|
|
{
|
|
|
|
ogs_debug("[SGSAP] RESET-INDICATION");
|
|
|
|
|
|
|
|
ogs_assert(vlr);
|
|
|
|
ogs_assert(pkbuf);
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK == sgsap_send_reset_ack(vlr));
|
2019-07-07 01:16:21 +00:00
|
|
|
}
|
2019-07-13 05:51:35 +00:00
|
|
|
|
|
|
|
void sgsap_handle_release_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
|
|
|
|
{
|
|
|
|
ogs_tlv_t *root = NULL, *iter = NULL;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
2019-07-13 05:51:35 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_nas_mobile_identity_imsi_t *nas_mobile_identity_imsi = NULL;
|
2019-07-13 05:51:35 +00:00
|
|
|
int nas_mobile_identity_imsi_len = 0;
|
|
|
|
|
|
|
|
ogs_assert(vlr);
|
|
|
|
ogs_assert(pkbuf);
|
|
|
|
|
|
|
|
ogs_debug("[SGSAP] RELEASE-REQUEST");
|
|
|
|
|
|
|
|
ogs_pkbuf_pull(pkbuf, 1);
|
|
|
|
|
|
|
|
root = ogs_tlv_parse_block(pkbuf->len, pkbuf->data, OGS_TLV_MODE_T1_L1);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!root) {
|
|
|
|
ogs_error("ogs_tlv_parse_block() failed");
|
|
|
|
return;
|
|
|
|
}
|
2019-07-13 05:51:35 +00:00
|
|
|
|
|
|
|
iter = root;
|
|
|
|
while (iter) {
|
|
|
|
switch (iter->type) {
|
|
|
|
case SGSAP_IE_IMSI_TYPE:
|
|
|
|
nas_mobile_identity_imsi = iter->value;
|
|
|
|
nas_mobile_identity_imsi_len = iter->length;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_warn("Invalid Type [%d]", iter->type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
iter = iter->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_tlv_free_all(root);
|
|
|
|
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!nas_mobile_identity_imsi) {
|
|
|
|
ogs_error("No IMSI");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (nas_mobile_identity_imsi_len != SGSAP_IE_IMSI_LEN) {
|
|
|
|
ogs_error("Invalid IMSI len [%d]", nas_mobile_identity_imsi_len);
|
|
|
|
return;
|
|
|
|
}
|
2019-07-13 05:51:35 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
if (nas_mobile_identity_imsi->type == OGS_NAS_MOBILE_IDENTITY_IMSI) {
|
2019-07-13 05:51:35 +00:00
|
|
|
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_nas_eps_imsi_to_bcd(nas_mobile_identity_imsi,
|
2019-07-13 05:51:35 +00:00
|
|
|
nas_mobile_identity_imsi_len, imsi_bcd);
|
|
|
|
mme_ue = mme_ue_find_by_imsi_bcd(imsi_bcd);
|
2023-01-23 15:01:36 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("Unknown type [%d]", nas_mobile_identity_imsi->type);
|
|
|
|
return;
|
|
|
|
}
|
2019-07-13 05:51:35 +00:00
|
|
|
|
|
|
|
if (mme_ue)
|
|
|
|
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
|
|
|
|
else
|
|
|
|
ogs_warn("Unknown IMSI[%s]", imsi_bcd);
|
|
|
|
|
|
|
|
}
|
2019-07-21 13:52:28 +00:00
|
|
|
|
|
|
|
void sgsap_handle_mm_information_request(mme_vlr_t *vlr, ogs_pkbuf_t *pkbuf)
|
|
|
|
{
|
|
|
|
ogs_tlv_t *root = NULL, *iter = NULL;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
char imsi_bcd[OGS_MAX_IMSI_BCD_LEN+1];
|
2019-07-21 13:52:28 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_nas_mobile_identity_imsi_t *nas_mobile_identity_imsi = NULL;
|
2019-07-21 13:52:28 +00:00
|
|
|
int nas_mobile_identity_imsi_len = 0;
|
|
|
|
|
|
|
|
ogs_assert(vlr);
|
|
|
|
ogs_assert(pkbuf);
|
|
|
|
|
|
|
|
ogs_debug("[SGSAP] MM-INFORMATION-REQUEST(DISCARD by OPTION2)");
|
|
|
|
|
|
|
|
ogs_pkbuf_pull(pkbuf, 1);
|
|
|
|
|
|
|
|
root = ogs_tlv_parse_block(pkbuf->len, pkbuf->data, OGS_TLV_MODE_T1_L1);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!root) {
|
|
|
|
ogs_error("ogs_tlv_parse_block() failed");
|
|
|
|
return;
|
|
|
|
}
|
2019-07-21 13:52:28 +00:00
|
|
|
|
|
|
|
iter = root;
|
|
|
|
while (iter) {
|
|
|
|
switch (iter->type) {
|
|
|
|
case SGSAP_IE_IMSI_TYPE:
|
|
|
|
nas_mobile_identity_imsi = iter->value;
|
|
|
|
nas_mobile_identity_imsi_len = iter->length;
|
|
|
|
break;
|
|
|
|
case SGSAP_IE_MM_INFORMATION_TYPE:
|
|
|
|
/* TODO */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_warn("Invalid Type [%d]", iter->type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
iter = iter->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_tlv_free_all(root);
|
|
|
|
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!nas_mobile_identity_imsi) {
|
|
|
|
ogs_error("No IMSI");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (nas_mobile_identity_imsi_len != SGSAP_IE_IMSI_LEN) {
|
|
|
|
ogs_error("Invalid IMSI len [%d]", nas_mobile_identity_imsi_len);
|
|
|
|
return;
|
|
|
|
}
|
2019-07-21 13:52:28 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
if (nas_mobile_identity_imsi->type == OGS_NAS_MOBILE_IDENTITY_IMSI) {
|
2019-07-21 13:52:28 +00:00
|
|
|
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_nas_eps_imsi_to_bcd(nas_mobile_identity_imsi,
|
2019-07-21 13:52:28 +00:00
|
|
|
nas_mobile_identity_imsi_len, imsi_bcd);
|
|
|
|
mme_ue = mme_ue_find_by_imsi_bcd(imsi_bcd);
|
2023-01-23 15:01:36 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("Unknown type [%d]", nas_mobile_identity_imsi->type);
|
|
|
|
return;
|
|
|
|
}
|
2019-07-21 13:52:28 +00:00
|
|
|
|
|
|
|
if (mme_ue)
|
|
|
|
ogs_debug(" IMSI[%s]", mme_ue->imsi_bcd);
|
|
|
|
else
|
|
|
|
ogs_warn("Unknown IMSI[%s]", imsi_bcd);
|
|
|
|
}
|