2019-06-19 09:04:57 +00:00
|
|
|
/*
|
2023-04-21 15:04:11 +00:00
|
|
|
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
2019-06-19 09:04:57 +00:00
|
|
|
*
|
|
|
|
* 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/>.
|
|
|
|
*/
|
|
|
|
|
2019-06-11 13:10:47 +00:00
|
|
|
#include "mme-event.h"
|
|
|
|
#include "mme-sm.h"
|
|
|
|
#include "mme-context.h"
|
2022-05-12 13:52:36 +00:00
|
|
|
#include "mme-timer.h"
|
2017-08-09 15:41:09 +00:00
|
|
|
|
2019-06-01 09:52:38 +00:00
|
|
|
#include "s1ap-path.h"
|
2019-06-11 13:10:47 +00:00
|
|
|
#include "mme-gtp-path.h"
|
|
|
|
#include "nas-path.h"
|
|
|
|
#include "mme-fd-path.h"
|
2019-06-20 09:20:32 +00:00
|
|
|
#include "sgsap-path.h"
|
2019-11-15 14:56:55 +00:00
|
|
|
#include "mme-path.h"
|
2017-08-10 08:02:07 +00:00
|
|
|
|
2019-06-11 13:10:47 +00:00
|
|
|
#include "mme-s11-build.h"
|
|
|
|
#include "mme-s11-handler.h"
|
2017-09-10 14:03:24 +00:00
|
|
|
|
2021-01-11 04:36:12 +00:00
|
|
|
static uint8_t esm_cause_from_gtp(uint8_t gtp_cause)
|
|
|
|
{
|
|
|
|
switch (gtp_cause) {
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND:
|
2022-07-19 03:42:02 +00:00
|
|
|
return OGS_NAS_ESM_CAUSE_INVALID_EPS_BEARER_IDENTITY;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_SERVICE_NOT_SUPPORTED:
|
2022-07-19 03:42:02 +00:00
|
|
|
return OGS_NAS_ESM_CAUSE_SERVICE_OPTION_NOT_SUPPORTED;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_SEMANTIC_ERROR_IN_THE_TFT_OPERATION:
|
2022-07-19 03:42:02 +00:00
|
|
|
return OGS_NAS_ESM_CAUSE_SEMANTIC_ERROR_IN_THE_TFT_OPERATION;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_SYNTACTIC_ERROR_IN_THE_TFT_OPERATION:
|
2022-07-19 03:42:02 +00:00
|
|
|
return OGS_NAS_ESM_CAUSE_SYNTACTICAL_ERROR_IN_THE_TFT_OPERATION;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_SYNTACTIC_ERRORS_IN_PACKET_FILTER:
|
2022-07-19 03:42:02 +00:00
|
|
|
return OGS_NAS_ESM_CAUSE_SYNTACTICAL_ERROR_IN_PACKET_FILTERS;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_SEMANTIC_ERRORS_IN_PACKET_FILTER:
|
2022-07-19 03:42:02 +00:00
|
|
|
return OGS_NAS_ESM_CAUSE_SEMANTIC_ERRORS_IN_PACKET_FILTERS;
|
2021-01-11 04:36:12 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2022-04-12 22:07:39 +00:00
|
|
|
* OGS_GTP2_CAUSE_SYSTEM_FAILURE
|
|
|
|
* OGS_GTP2_CAUSE_MANDATORY_IE_MISSING
|
2021-01-11 04:36:12 +00:00
|
|
|
* ...
|
|
|
|
*/
|
2022-07-19 03:42:02 +00:00
|
|
|
return OGS_NAS_ESM_CAUSE_NETWORK_FAILURE;
|
2021-01-11 04:36:12 +00:00
|
|
|
}
|
|
|
|
|
2020-03-25 21:43:02 +00:00
|
|
|
void mme_s11_handle_echo_request(
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp_xact_t *xact, ogs_gtp2_echo_request_t *req)
|
2020-03-25 21:43:02 +00:00
|
|
|
{
|
|
|
|
ogs_assert(xact);
|
|
|
|
ogs_assert(req);
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug("Receiving Echo Request");
|
2020-03-25 21:43:02 +00:00
|
|
|
/* FIXME : Before implementing recovery counter correctly,
|
|
|
|
* I'll re-use the recovery value in request message */
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_send_echo_response(xact, req->recovery.u8, 0);
|
2020-03-25 21:43:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void mme_s11_handle_echo_response(
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp_xact_t *xact, ogs_gtp2_echo_response_t *rsp)
|
2020-03-25 21:43:02 +00:00
|
|
|
{
|
|
|
|
/* Not Implemented */
|
|
|
|
}
|
|
|
|
|
2017-09-10 14:03:24 +00:00
|
|
|
void mme_s11_handle_create_session_response(
|
2022-06-30 00:11:31 +00:00
|
|
|
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_session_response_t *rsp)
|
2017-04-12 12:44:18 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int i, r, rv;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
|
|
|
uint8_t session_cause = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
|
|
|
uint8_t bearer_cause = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_f_teid_t *sgw_s11_teid = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_gtp2_f_teid_t *pgw_s5c_teid = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_f_teid_t *sgw_s1u_teid = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_gtp2_f_teid_t *pgw_s5u_teid = NULL;
|
2017-04-12 12:44:18 +00:00
|
|
|
|
2017-09-10 14:03:24 +00:00
|
|
|
mme_bearer_t *bearer = NULL;
|
2017-09-01 12:35:45 +00:00
|
|
|
mme_sess_t *sess = NULL;
|
2022-06-30 00:11:31 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue_t *source_ue = NULL, *target_ue = NULL;
|
2021-03-08 12:25:09 +00:00
|
|
|
ogs_session_t *session = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_bearer_qos_t bearer_qos;
|
|
|
|
ogs_gtp2_ambr_t *ambr = NULL;
|
2020-06-04 19:12:32 +00:00
|
|
|
uint16_t decoded = 0;
|
2022-04-14 08:34:55 +00:00
|
|
|
int create_action = 0;
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(rsp);
|
2017-04-12 12:44:18 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug("Create Session Response");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(xact);
|
|
|
|
create_action = xact->create_action;
|
|
|
|
sess = xact->data;
|
|
|
|
ogs_assert(sess);
|
2024-02-27 12:16:50 +00:00
|
|
|
|
|
|
|
MME_UE_CHECK(OGS_LOG_DEBUG, sess->mme_ue);
|
2023-02-20 11:49:48 +00:00
|
|
|
mme_ue = mme_ue_cycle(sess->mme_ue);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_commit() failed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mme_ue) {
|
|
|
|
ogs_error("MME-UE Context has already been removed");
|
|
|
|
return;
|
|
|
|
}
|
2022-05-12 13:52:36 +00:00
|
|
|
source_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(source_ue);
|
|
|
|
|
|
|
|
if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
|
|
|
target_ue = sgw_ue_cycle(source_ue->target_ue);
|
|
|
|
ogs_assert(target_ue);
|
|
|
|
} else {
|
|
|
|
target_ue = source_ue;
|
|
|
|
ogs_assert(target_ue);
|
|
|
|
}
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
/************************
|
|
|
|
* Getting Cause Value
|
|
|
|
************************/
|
|
|
|
if (rsp->cause.presence && rsp->cause.data) {
|
|
|
|
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
|
|
|
ogs_assert(cause);
|
|
|
|
session_cause = cause->value;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
2022-05-12 13:52:36 +00:00
|
|
|
* Check MME-UE Context
|
2022-04-29 12:28:16 +00:00
|
|
|
************************/
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-06-30 00:11:31 +00:00
|
|
|
if (!mme_ue_from_teid) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] No Context in TEID [Cause:%d]",
|
|
|
|
mme_ue->imsi_bcd, session_cause);
|
2022-06-30 00:11:31 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] Attach reject [Cause:%d]",
|
|
|
|
mme_ue->imsi_bcd, session_cause);
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_attach_reject(mme_ue,
|
|
|
|
OGS_NAS_EMM_CAUSE_NETWORK_FAILURE,
|
|
|
|
OGS_NAS_ESM_CAUSE_NETWORK_FAILURE);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2022-04-29 12:28:16 +00:00
|
|
|
}
|
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
|
|
return;
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
if (rsp->sender_f_teid_for_control_plane.presence == 0) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] No S11 TEID [Cause:%d]",
|
|
|
|
mme_ue->imsi_bcd, session_cause);
|
2022-04-29 12:28:16 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
|
|
|
}
|
2019-11-15 14:56:55 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
2020-12-17 03:44:32 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
/* No need S5C TEID in PathSwitchRequest */
|
|
|
|
|
|
|
|
} else {
|
2020-12-17 03:44:32 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
if (rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.presence == 0) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] No S5C TEID [Cause:%d]",
|
|
|
|
mme_ue->imsi_bcd, session_cause);
|
2022-05-12 13:52:36 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
2020-12-17 03:44:32 +00:00
|
|
|
}
|
2022-05-12 13:52:36 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
|
|
|
|
|
|
|
/* No need S5C TEID in PathSwitchRequest */
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
} else {
|
2022-05-12 13:52:36 +00:00
|
|
|
|
|
|
|
if (rsp->pdn_address_allocation.presence) {
|
|
|
|
ogs_paa_t paa;
|
|
|
|
|
|
|
|
memcpy(&paa, rsp->pdn_address_allocation.data,
|
|
|
|
rsp->pdn_address_allocation.len);
|
|
|
|
|
|
|
|
if (!OGS_PDU_SESSION_TYPE_IS_VALID(paa.session_type)) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] Unknown PDN Type [Session:%u, Cause:%d]",
|
|
|
|
mme_ue->imsi_bcd, paa.session_type, session_cause);
|
2022-05-12 13:52:36 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_INCORRECT;
|
|
|
|
}
|
|
|
|
} else {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] No PDN Address Allocation [Cause:%d]",
|
|
|
|
mme_ue->imsi_bcd, session_cause);
|
2022-05-12 13:52:36 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
|
|
|
}
|
2020-12-17 03:44:32 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (rsp->cause.presence == 0) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] No Cause [VALUE:%d]", mme_ue->imsi_bcd, session_cause);
|
2022-04-29 12:28:16 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
2022-03-22 13:47:45 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] Attach reject [Cause:%d]",
|
|
|
|
mme_ue->imsi_bcd, session_cause);
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_attach_reject(mme_ue,
|
2022-12-02 00:10:49 +00:00
|
|
|
OGS_NAS_EMM_CAUSE_NETWORK_FAILURE,
|
2023-01-23 01:37:22 +00:00
|
|
|
OGS_NAS_ESM_CAUSE_NETWORK_FAILURE);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2024-01-16 10:13:47 +00:00
|
|
|
} else if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE) {
|
|
|
|
ogs_error("[%s] TAU reject [Cause:%d]",
|
|
|
|
mme_ue->imsi_bcd, session_cause);
|
|
|
|
r = nas_eps_send_tau_reject(mme_ue, OGS_NAS_EMM_CAUSE_NETWORK_FAILURE);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2022-04-29 12:28:16 +00:00
|
|
|
}
|
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
|
|
return;
|
2022-03-22 13:47:45 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Cause Value
|
|
|
|
********************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_gtp2_cause_t *cause = NULL;
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
if (rsp->bearer_contexts_created[i].cause.presence == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cause = rsp->bearer_contexts_created[i].cause.data;
|
2022-12-02 00:10:49 +00:00
|
|
|
if (cause == NULL) {
|
|
|
|
ogs_error("No Cause Data");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
bearer_cause = cause->value;
|
|
|
|
if (bearer_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_error("[%s] GTP Bearer Cause [VALUE:%d]",
|
|
|
|
mme_ue->imsi_bcd, bearer_cause);
|
2022-05-12 13:52:36 +00:00
|
|
|
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
|
|
|
|
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_attach_reject(mme_ue,
|
2022-12-02 00:10:49 +00:00
|
|
|
OGS_NAS_EMM_CAUSE_NETWORK_FAILURE,
|
2023-01-23 01:37:22 +00:00
|
|
|
OGS_NAS_ESM_CAUSE_NETWORK_FAILURE);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2022-05-12 13:52:36 +00:00
|
|
|
}
|
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
|
|
return;
|
2022-04-29 12:28:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
if (session_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED &&
|
|
|
|
session_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED_PARTIALLY &&
|
|
|
|
session_cause !=
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_NETWORK_PREFERENCE &&
|
2022-12-02 00:10:49 +00:00
|
|
|
session_cause !=
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_SINGLE_ADDRESS_BEARER_ONLY) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] GTP Cause [VALUE:%d]", mme_ue->imsi_bcd, session_cause);
|
2022-04-29 12:28:16 +00:00
|
|
|
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
|
|
|
|
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_attach_reject(mme_ue,
|
|
|
|
OGS_NAS_EMM_CAUSE_NETWORK_FAILURE,
|
|
|
|
OGS_NAS_ESM_CAUSE_NETWORK_FAILURE);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2020-04-18 01:36:26 +00:00
|
|
|
}
|
2022-04-29 12:28:16 +00:00
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
2017-09-10 14:03:24 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-04-12 12:44:18 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(sess);
|
2021-03-08 12:25:09 +00:00
|
|
|
session = sess->session;
|
|
|
|
ogs_assert(session);
|
2017-09-02 01:14:40 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_assert(mme_ue);
|
|
|
|
ogs_assert(source_ue);
|
|
|
|
ogs_assert(target_ue);
|
|
|
|
|
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
|
|
|
mme_ue->mme_s11_teid, target_ue->sgw_s11_teid);
|
|
|
|
|
|
|
|
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
|
|
|
if (rsp->bearer_contexts_created[i].presence == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (rsp->bearer_contexts_created[i].eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No EPS Bearer ID");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.presence == 0) {
|
|
|
|
ogs_error("No SGW-S1U TEID");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.presence == 0) {
|
|
|
|
ogs_error("No PGW-S5U TEID");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EPS Bearer ID */
|
|
|
|
bearer = mme_bearer_find_by_ue_ebi(mme_ue,
|
|
|
|
rsp->bearer_contexts_created[i].eps_bearer_id.u8);
|
|
|
|
if (!bearer) {
|
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Data Plane(UL) : SGW-S1U */
|
|
|
|
sgw_s1u_teid = rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.data;
|
|
|
|
bearer->sgw_s1u_teid = be32toh(sgw_s1u_teid->teid);
|
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_gtp2_f_teid_to_ip(sgw_s1u_teid, &bearer->sgw_s1u_ip));
|
|
|
|
|
|
|
|
/* Data Plane(UL) : PGW-S5U */
|
|
|
|
pgw_s5u_teid = rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.data;
|
|
|
|
bearer->pgw_s5u_teid = be32toh(pgw_s5u_teid->teid);
|
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &bearer->pgw_s5u_ip));
|
|
|
|
|
|
|
|
ogs_debug(" ENB_S1U_TEID[%d] SGW_S1U_TEID[%d] PGW_S5U_TEID[%d]",
|
|
|
|
bearer->enb_s1u_teid, bearer->sgw_s1u_teid, bearer->pgw_s5u_teid);
|
2024-01-16 10:13:47 +00:00
|
|
|
|
|
|
|
if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE &&
|
|
|
|
!OGS_FSM_CHECK(&bearer->sm, esm_state_active))
|
|
|
|
OGS_FSM_TRAN(&bearer->sm, esm_state_active);
|
2022-05-12 13:52:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Bearer Level QoS */
|
|
|
|
if (rsp->bearer_contexts_created[0].bearer_level_qos.presence) {
|
|
|
|
decoded = ogs_gtp2_parse_bearer_qos(&bearer_qos,
|
|
|
|
&rsp->bearer_contexts_created[0].bearer_level_qos);
|
|
|
|
ogs_assert(decoded ==
|
|
|
|
rsp->bearer_contexts_created[0].bearer_level_qos.len);
|
|
|
|
session->qos.index = bearer_qos.qci;
|
|
|
|
session->qos.arp.priority_level = bearer_qos.priority_level;
|
|
|
|
session->qos.arp.pre_emption_capability =
|
|
|
|
bearer_qos.pre_emption_capability;
|
|
|
|
session->qos.arp.pre_emption_vulnerability =
|
|
|
|
bearer_qos.pre_emption_vulnerability;
|
|
|
|
}
|
|
|
|
|
2017-09-04 13:00:51 +00:00
|
|
|
/* Control Plane(UL) : SGW-S11 */
|
2017-04-12 12:44:18 +00:00
|
|
|
sgw_s11_teid = rsp->sender_f_teid_for_control_plane.data;
|
2022-05-12 13:52:36 +00:00
|
|
|
target_ue->sgw_s11_teid = be32toh(sgw_s11_teid->teid);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
/* Control Plane(UL) : PGW-S5C */
|
2022-05-12 13:52:36 +00:00
|
|
|
if (rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.presence) {
|
|
|
|
pgw_s5c_teid = rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.data;
|
|
|
|
sess->pgw_s5c_teid = be32toh(pgw_s5c_teid->teid);
|
2023-12-13 15:42:32 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_gtp2_f_teid_to_ip(pgw_s5c_teid, &sess->pgw_s5c_ip));
|
2022-05-12 13:52:36 +00:00
|
|
|
}
|
2017-04-12 12:44:18 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
/* PDN Addresss Allocation */
|
|
|
|
if (rsp->pdn_address_allocation.presence) {
|
|
|
|
memcpy(&session->paa, rsp->pdn_address_allocation.data,
|
|
|
|
rsp->pdn_address_allocation.len);
|
2023-12-18 14:58:41 +00:00
|
|
|
session->session_type = session->paa.session_type;
|
|
|
|
ogs_assert(OGS_OK ==
|
2024-01-05 19:16:29 +00:00
|
|
|
ogs_paa_to_ip(&session->paa, &session->ue_ip));
|
2022-05-12 13:52:36 +00:00
|
|
|
}
|
2017-04-13 03:21:47 +00:00
|
|
|
|
2023-04-21 15:04:11 +00:00
|
|
|
/* ePCO */
|
|
|
|
if (rsp->extended_protocol_configuration_options.presence) {
|
|
|
|
OGS_TLV_STORE_DATA(&sess->pgw_epco,
|
|
|
|
&rsp->extended_protocol_configuration_options);
|
|
|
|
|
2017-09-04 13:00:51 +00:00
|
|
|
/* PCO */
|
2023-04-21 15:04:11 +00:00
|
|
|
} else if (rsp->protocol_configuration_options.presence) {
|
2019-09-13 12:07:47 +00:00
|
|
|
OGS_TLV_STORE_DATA(&sess->pgw_pco,
|
|
|
|
&rsp->protocol_configuration_options);
|
2017-04-13 03:21:47 +00:00
|
|
|
}
|
|
|
|
|
2020-06-04 19:12:32 +00:00
|
|
|
/* Bearer QoS */
|
2022-05-12 13:52:36 +00:00
|
|
|
if (rsp->bearer_contexts_created[0].bearer_level_qos.presence) {
|
2022-04-12 22:07:39 +00:00
|
|
|
decoded = ogs_gtp2_parse_bearer_qos(&bearer_qos,
|
2022-05-12 13:52:36 +00:00
|
|
|
&rsp->bearer_contexts_created[0].bearer_level_qos);
|
|
|
|
ogs_assert(rsp->bearer_contexts_created[0].bearer_level_qos.len ==
|
2020-06-04 19:12:32 +00:00
|
|
|
decoded);
|
2021-03-08 12:25:09 +00:00
|
|
|
session->qos.index = bearer_qos.qci;
|
|
|
|
session->qos.arp.priority_level = bearer_qos.priority_level;
|
|
|
|
session->qos.arp.pre_emption_capability =
|
2020-06-04 19:12:32 +00:00
|
|
|
bearer_qos.pre_emption_capability;
|
2021-03-08 12:25:09 +00:00
|
|
|
session->qos.arp.pre_emption_vulnerability =
|
2020-06-04 19:12:32 +00:00
|
|
|
bearer_qos.pre_emption_vulnerability;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* AMBR */
|
|
|
|
if (rsp->aggregate_maximum_bit_rate.presence) {
|
|
|
|
ambr = rsp->aggregate_maximum_bit_rate.data;
|
2021-03-08 12:25:09 +00:00
|
|
|
session->ambr.downlink = be32toh(ambr->downlink) * 1000;
|
|
|
|
session->ambr.uplink = be32toh(ambr->uplink) * 1000;
|
2020-06-04 19:12:32 +00:00
|
|
|
}
|
|
|
|
|
2022-04-14 08:34:55 +00:00
|
|
|
if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) {
|
2019-07-21 11:25:29 +00:00
|
|
|
mme_csmap_t *csmap = mme_csmap_find_by_tai(&mme_ue->tai);
|
|
|
|
mme_ue->csmap = csmap;
|
2019-06-22 02:16:22 +00:00
|
|
|
|
2019-07-21 11:25:29 +00:00
|
|
|
if (csmap) {
|
2021-03-08 12:25:09 +00:00
|
|
|
ogs_assert(OGS_PDU_SESSION_TYPE_IS_VALID(
|
|
|
|
session->paa.session_type));
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgsap_send_location_update_request(mme_ue));
|
2019-07-20 13:30:53 +00:00
|
|
|
} else {
|
2021-03-08 12:25:09 +00:00
|
|
|
ogs_assert(OGS_PDU_SESSION_TYPE_IS_VALID(
|
|
|
|
session->paa.session_type));
|
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-07-20 13:30:53 +00:00
|
|
|
}
|
2019-06-22 02:16:22 +00:00
|
|
|
|
2024-01-16 10:13:47 +00:00
|
|
|
} else if (create_action == OGS_GTP_CREATE_IN_TRACKING_AREA_UPDATE) {
|
|
|
|
/* 3GPP TS 23.401 D.3.6 step 13, 14: */
|
|
|
|
mme_s6a_send_ulr(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
} else if (create_action == OGS_GTP_CREATE_IN_UPLINK_NAS_TRANSPORT) {
|
2021-03-08 12:25:09 +00:00
|
|
|
ogs_assert(OGS_PDU_SESSION_TYPE_IS_VALID(session->paa.session_type));
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_activate_default_bearer_context_request(
|
|
|
|
bearer, create_action);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2022-04-29 12:28:16 +00:00
|
|
|
} else if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
2022-05-12 13:52:36 +00:00
|
|
|
|
|
|
|
GTP_COUNTER_CHECK(mme_ue, GTP_COUNTER_CREATE_SESSION_BY_PATH_SWITCH,
|
|
|
|
ogs_timer_start(source_ue->t_s11_holding,
|
|
|
|
mme_timer_cfg(MME_TIMER_S11_HOLDING)->duration);
|
|
|
|
|
|
|
|
sgw_ue_associate_mme_ue(target_ue, mme_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
r = s1ap_send_path_switch_ack(mme_ue, true);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2022-05-12 13:52:36 +00:00
|
|
|
);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
} else {
|
|
|
|
ogs_fatal("Invalid Create Session Action[%d]", create_action);
|
|
|
|
ogs_assert_if_reached();
|
2020-09-10 18:04:26 +00:00
|
|
|
}
|
2017-04-12 12:44:18 +00:00
|
|
|
}
|
2017-04-13 16:26:50 +00:00
|
|
|
|
2017-09-04 13:00:51 +00:00
|
|
|
void mme_s11_handle_modify_bearer_response(
|
2022-06-30 00:11:31 +00:00
|
|
|
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_modify_bearer_response_t *rsp)
|
2017-09-04 13:00:51 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r, rv;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
|
|
|
uint8_t session_cause = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2022-04-29 12:28:16 +00:00
|
|
|
int modify_action = 0;
|
2017-09-04 13:00:51 +00:00
|
|
|
|
2022-06-30 00:11:31 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2021-10-16 05:11:43 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(rsp);
|
2017-09-04 13:00:51 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug("Modify Bearer Response");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(xact);
|
2022-05-12 13:52:36 +00:00
|
|
|
modify_action = xact->modify_action;
|
2024-02-27 12:16:50 +00:00
|
|
|
|
|
|
|
MME_UE_CHECK(OGS_LOG_DEBUG, xact->data);
|
2023-02-20 11:49:48 +00:00
|
|
|
mme_ue = mme_ue_cycle(xact->data);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_commit() failed");
|
|
|
|
return;
|
|
|
|
}
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2023-02-20 11:49:48 +00:00
|
|
|
if (!mme_ue) {
|
|
|
|
ogs_error("MME-UE Context has already been removed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
/************************
|
|
|
|
* Getting Cause Value
|
|
|
|
************************/
|
|
|
|
if (rsp->cause.presence && rsp->cause.data) {
|
|
|
|
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
|
|
|
ogs_assert(cause);
|
|
|
|
session_cause = cause->value;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
2022-05-12 13:52:36 +00:00
|
|
|
* Check MME-UE Context
|
2022-04-29 12:28:16 +00:00
|
|
|
************************/
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-06-30 00:11:31 +00:00
|
|
|
if (!mme_ue_from_teid) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] No Context in TEID [Cause:%d]",
|
|
|
|
mme_ue->imsi_bcd, session_cause);
|
2022-06-30 00:11:31 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
|
|
return;
|
|
|
|
}
|
2022-02-19 00:47:44 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (rsp->cause.presence == 0) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] No Cause [%d]", mme_ue->imsi_bcd, session_cause);
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2019-11-11 14:09:35 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2022-04-29 12:28:16 +00:00
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
2019-11-15 14:56:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Cause Value
|
|
|
|
********************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
if (session_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_error("[%s] GTP Cause [VALUE:%d]", mme_ue->imsi_bcd, session_cause);
|
2022-04-29 12:28:16 +00:00
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
|
|
return;
|
|
|
|
}
|
2021-03-17 05:26:57 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
|
|
|
ogs_assert(mme_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
2022-05-12 13:52:36 +00:00
|
|
|
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
switch (modify_action) {
|
|
|
|
case OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST:
|
2023-01-23 01:37:22 +00:00
|
|
|
r = s1ap_send_path_switch_ack(mme_ue, false);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2022-04-29 12:28:16 +00:00
|
|
|
break;
|
|
|
|
case OGS_GTP_MODIFY_IN_E_RAB_MODIFICATION:
|
2023-01-23 01:37:22 +00:00
|
|
|
r = s1ap_send_e_rab_modification_confirm(mme_ue);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2022-04-29 12:28:16 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2017-09-04 13:00:51 +00:00
|
|
|
}
|
|
|
|
|
2017-09-10 14:03:24 +00:00
|
|
|
void mme_s11_handle_delete_session_response(
|
2022-06-30 00:11:31 +00:00
|
|
|
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_delete_session_response_t *rsp)
|
2017-09-10 14:03:24 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r, rv;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2020-10-22 21:53:13 +00:00
|
|
|
int action = 0;
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue_t *source_ue = NULL, *target_ue = NULL;
|
2017-09-10 14:03:24 +00:00
|
|
|
mme_sess_t *sess = NULL;
|
2022-06-30 00:11:31 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
2017-09-10 14:03:24 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(rsp);
|
2017-09-10 14:03:24 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug("Delete Session Response");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(xact);
|
|
|
|
action = xact->delete_action;
|
|
|
|
ogs_assert(action);
|
2019-11-15 14:56:55 +00:00
|
|
|
sess = xact->data;
|
2019-11-11 14:09:35 +00:00
|
|
|
ogs_assert(sess);
|
2024-02-27 12:16:50 +00:00
|
|
|
|
|
|
|
ogs_debug("delete_session_response - xact:%p, sess:%p", xact, sess);
|
|
|
|
MME_UE_CHECK(OGS_LOG_DEBUG, sess->mme_ue);
|
2023-02-20 11:49:48 +00:00
|
|
|
mme_ue = mme_ue_cycle(sess->mme_ue);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_commit() failed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mme_ue) {
|
|
|
|
ogs_error("MME-UE Context has already been removed");
|
|
|
|
return;
|
|
|
|
}
|
2022-05-12 13:52:36 +00:00
|
|
|
target_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(target_ue);
|
|
|
|
|
|
|
|
if (action == OGS_GTP_DELETE_IN_PATH_SWITCH_REQUEST) {
|
|
|
|
source_ue = sgw_ue_cycle(target_ue->source_ue);
|
2023-12-11 16:18:11 +00:00
|
|
|
if (!source_ue) /* InterRAT to 2G/3G (SGSN) case: */
|
|
|
|
source_ue = target_ue;
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_assert(source_ue);
|
|
|
|
} else {
|
|
|
|
source_ue = target_ue;
|
|
|
|
ogs_assert(source_ue);
|
|
|
|
}
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2022-06-30 00:11:31 +00:00
|
|
|
/************************
|
|
|
|
* Check MME-UE Context
|
|
|
|
************************/
|
|
|
|
if (!mme_ue_from_teid) {
|
2023-02-20 11:49:48 +00:00
|
|
|
/*
|
|
|
|
* In mme_ue_set_imsi(),
|
|
|
|
* OLD MME-UE Context could be switched to NEW MME-UE Context
|
|
|
|
*
|
|
|
|
* OLD/NEW MME-UE Contexts have different MME-S11-TEID.
|
|
|
|
* Since MME has NEW MME-S11-TEID and SGW-C has OLD MME-S11-TEID.
|
|
|
|
*
|
|
|
|
* At this time, if the MME receives OLD MME-S11-TEID from SGW-C
|
|
|
|
* in the Delete Session Response, MME cannot find MME-UE Context.
|
|
|
|
*
|
|
|
|
* Since there is such a case,
|
|
|
|
* Delete Session Response treats this as a WARNING.
|
|
|
|
*/
|
|
|
|
ogs_warn("No Context in TEID");
|
2022-06-30 00:11:31 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Cause Value
|
|
|
|
********************/
|
2019-11-15 14:56:55 +00:00
|
|
|
if (rsp->cause.presence) {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
2019-11-15 14:56:55 +00:00
|
|
|
ogs_assert(cause);
|
2019-11-07 14:07:29 +00:00
|
|
|
|
2019-11-15 14:56:55 +00:00
|
|
|
cause_value = cause->value;
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED)
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("GTP Cause [VALUE:%d] - Ignored", cause_value);
|
2019-11-07 14:07:29 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
|
|
|
ogs_assert(sess);
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_assert(mme_ue);
|
|
|
|
ogs_assert(target_ue);
|
|
|
|
ogs_assert(source_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
|
|
|
mme_ue->mme_s11_teid, source_ue->sgw_s11_teid);
|
2017-09-10 14:03:24 +00:00
|
|
|
|
2022-08-19 07:52:39 +00:00
|
|
|
if (action == OGS_GTP_DELETE_NO_ACTION) {
|
|
|
|
/* No Action to be taken after sessions are deleted during
|
|
|
|
* MME Initiated detach. S1 will be cleared after receipt
|
|
|
|
* of the detach accept from UE */
|
|
|
|
} else if (action == OGS_GTP_DELETE_SEND_AUTHENTICATION_REQUEST) {
|
2019-06-19 09:04:57 +00:00
|
|
|
if (mme_sess_count(mme_ue) == 1) /* Last Session */ {
|
2017-12-17 15:01:07 +00:00
|
|
|
mme_s6a_send_air(mme_ue, NULL);
|
2018-01-30 12:57:19 +00:00
|
|
|
}
|
2020-10-22 21:53:13 +00:00
|
|
|
|
|
|
|
} else if (action == OGS_GTP_DELETE_SEND_DETACH_ACCEPT) {
|
2019-06-19 09:04:57 +00:00
|
|
|
if (mme_sess_count(mme_ue) == 1) /* Last Session */ {
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_detach_accept(mme_ue);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2018-01-30 12:57:19 +00:00
|
|
|
}
|
2020-10-22 21:53:13 +00:00
|
|
|
|
|
|
|
} else if (action ==
|
|
|
|
OGS_GTP_DELETE_SEND_DEACTIVATE_BEARER_CONTEXT_REQUEST) {
|
2017-09-10 14:03:24 +00:00
|
|
|
mme_bearer_t *bearer = mme_default_bearer_in_sess(sess);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!bearer) {
|
|
|
|
ogs_error("No Bearer");
|
|
|
|
return;
|
|
|
|
}
|
2017-09-10 14:03:24 +00:00
|
|
|
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_deactivate_bearer_context_request(bearer);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2019-06-25 01:55:00 +00:00
|
|
|
|
2023-02-20 11:49:48 +00:00
|
|
|
/* mme_sess_remove() should not be called here. */
|
2020-10-22 21:53:13 +00:00
|
|
|
return;
|
|
|
|
|
2022-10-05 05:50:52 +00:00
|
|
|
} else if (action == OGS_GTP_DELETE_SEND_RELEASE_WITH_UE_CONTEXT_REMOVE) {
|
2019-06-19 09:04:57 +00:00
|
|
|
if (mme_sess_count(mme_ue) == 1) /* Last Session */ {
|
2022-10-06 01:10:31 +00:00
|
|
|
if (ECM_IDLE(mme_ue)) {
|
2024-02-03 07:18:26 +00:00
|
|
|
MME_UE_CHECK(OGS_LOG_ERROR, mme_ue);
|
|
|
|
mme_ue_remove(mme_ue);
|
2022-10-06 01:10:31 +00:00
|
|
|
} else {
|
|
|
|
ogs_assert(mme_ue->enb_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
r = s1ap_send_ue_context_release_command(mme_ue->enb_ue,
|
2019-06-14 15:11:30 +00:00
|
|
|
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
|
2023-01-23 01:37:22 +00:00
|
|
|
S1AP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2022-10-06 01:10:31 +00:00
|
|
|
}
|
2018-01-30 12:57:19 +00:00
|
|
|
}
|
2020-10-22 21:53:13 +00:00
|
|
|
|
2022-10-05 05:50:52 +00:00
|
|
|
} else if (action ==
|
|
|
|
OGS_GTP_DELETE_SEND_RELEASE_WITH_S1_REMOVE_AND_UNLINK) {
|
2022-08-19 07:52:39 +00:00
|
|
|
if (mme_sess_count(mme_ue) == 1) /* Last Session */ {
|
|
|
|
enb_ue_t *enb_ue = NULL;
|
|
|
|
|
|
|
|
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
|
|
|
|
if (enb_ue) {
|
2023-01-23 01:37:22 +00:00
|
|
|
r = s1ap_send_ue_context_release_command(enb_ue,
|
2022-08-19 07:52:39 +00:00
|
|
|
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
|
2023-01-23 01:37:22 +00:00
|
|
|
S1AP_UE_CTX_REL_S1_REMOVE_AND_UNLINK, 0);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2022-08-19 07:52:39 +00:00
|
|
|
} else
|
|
|
|
ogs_error("ENB-S1 Context has already been removed");
|
|
|
|
}
|
|
|
|
|
2020-10-22 21:53:13 +00:00
|
|
|
} else if (action == OGS_GTP_DELETE_HANDLE_PDN_CONNECTIVITY_REQUEST) {
|
|
|
|
if (mme_sess_count(mme_ue) == 1) /* Last Session */ {
|
|
|
|
rv = nas_eps_send_emm_to_esm(mme_ue,
|
|
|
|
&mme_ue->pdn_connectivity_request);
|
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("nas_eps_send_emm_to_esm() failed");
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_attach_reject(mme_ue,
|
2022-07-19 03:42:02 +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);
|
2020-10-22 21:53:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
} else if (action == OGS_GTP_DELETE_IN_PATH_SWITCH_REQUEST) {
|
|
|
|
|
|
|
|
/* Don't have to remove Session in X2 Handover with SGW relocation */
|
|
|
|
ogs_assert(source_ue);
|
|
|
|
|
|
|
|
GTP_COUNTER_CHECK(mme_ue, GTP_COUNTER_DELETE_SESSION_BY_PATH_SWITCH,
|
|
|
|
|
|
|
|
sgw_ue_source_deassociate_target(source_ue);
|
|
|
|
sgw_ue_remove(source_ue);
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
2020-10-22 21:53:13 +00:00
|
|
|
} else {
|
|
|
|
ogs_fatal("Invalid action = %d", action);
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert_if_reached();
|
2020-10-22 21:53:13 +00:00
|
|
|
}
|
2017-09-10 14:03:24 +00:00
|
|
|
|
2023-05-05 09:06:25 +00:00
|
|
|
MME_SESS_CLEAR(sess);
|
2017-09-10 14:03:24 +00:00
|
|
|
}
|
2018-01-16 11:49:39 +00:00
|
|
|
|
2017-09-04 13:00:51 +00:00
|
|
|
void mme_s11_handle_create_bearer_request(
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_bearer_request_t *req)
|
2017-08-27 07:30:10 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2018-01-14 13:49:29 +00:00
|
|
|
mme_bearer_t *bearer = NULL, *default_bearer = NULL;
|
2017-09-04 13:00:51 +00:00
|
|
|
mme_sess_t *sess = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2017-09-04 13:00:51 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_f_teid_t *sgw_s1u_teid = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_gtp2_f_teid_t *pgw_s5u_teid = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_bearer_qos_t bearer_qos;
|
2017-08-31 05:03:00 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(xact);
|
|
|
|
ogs_assert(req);
|
2017-09-01 12:35:45 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug("Create Bearer Response");
|
2017-08-31 05:03:00 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/***********************
|
2022-05-12 13:52:36 +00:00
|
|
|
* Check MME-UE Context
|
2022-04-29 12:28:16 +00:00
|
|
|
***********************/
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2019-11-15 14:56:55 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
if (!mme_ue) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("No Context in TEID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
} else {
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
if (req->linked_eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No Linked EBI");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
sess = mme_sess_find_by_ebi(mme_ue, req->linked_eps_bearer_id.u8);
|
|
|
|
if (!sess) {
|
|
|
|
ogs_error("No Context for Linked EPS Bearer ID[%d]",
|
|
|
|
req->linked_eps_bearer_id.u8);
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
|
|
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
|
|
|
return;
|
2019-11-15 14:56:55 +00:00
|
|
|
}
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
|
|
|
2019-06-19 09:04:57 +00:00
|
|
|
if (req->bearer_contexts.presence == 0) {
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_error("No Bearer");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2017-09-04 13:00:51 +00:00
|
|
|
}
|
2019-06-19 09:04:57 +00:00
|
|
|
if (req->bearer_contexts.eps_bearer_id.presence == 0) {
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_error("No EPS Bearer ID");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2017-09-04 13:00:51 +00:00
|
|
|
}
|
2019-06-19 09:04:57 +00:00
|
|
|
if (req->bearer_contexts.s1_u_enodeb_f_teid.presence == 0) {
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_error("No SGW-S1U TEID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
|
|
|
}
|
|
|
|
if (req->bearer_contexts.s4_u_sgsn_f_teid.presence == 0) {
|
|
|
|
ogs_error("No PGW-S5U TEID");
|
2022-04-29 12:28:16 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
2017-09-04 13:00:51 +00:00
|
|
|
}
|
2019-06-19 09:04:57 +00:00
|
|
|
if (req->bearer_contexts.bearer_level_qos.presence == 0) {
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_error("No QoS");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2017-09-04 13:00:51 +00:00
|
|
|
}
|
2019-06-19 09:04:57 +00:00
|
|
|
if (req->bearer_contexts.tft.presence == 0) {
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_error("No TFT");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2019-11-15 14:56:55 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
2017-09-06 06:38:24 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-09-04 13:00:51 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
|
|
|
ogs_assert(mme_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
|
|
|
ogs_assert(sess);
|
|
|
|
bearer = mme_bearer_add(sess);
|
|
|
|
ogs_assert(bearer);
|
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
2022-05-12 13:52:36 +00:00
|
|
|
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
2018-01-22 15:00:57 +00:00
|
|
|
|
2020-01-22 12:33:25 +00:00
|
|
|
/* Set PTI */
|
|
|
|
sess->pti = OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED;
|
|
|
|
if (req->procedure_transaction_id.presence) {
|
|
|
|
sess->pti = req->procedure_transaction_id.u8;
|
|
|
|
ogs_debug(" PTI[%d]", sess->pti);
|
|
|
|
}
|
|
|
|
|
2017-09-04 13:00:51 +00:00
|
|
|
/* Data Plane(UL) : SGW-S1U */
|
|
|
|
sgw_s1u_teid = req->bearer_contexts.s1_u_enodeb_f_teid.data;
|
2020-10-01 17:27:58 +00:00
|
|
|
bearer->sgw_s1u_teid = be32toh(sgw_s1u_teid->teid);
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_gtp2_f_teid_to_ip(sgw_s1u_teid, &bearer->sgw_s1u_ip));
|
|
|
|
|
|
|
|
/* Data Plane(UL) : PGW-S5U */
|
|
|
|
pgw_s5u_teid = req->bearer_contexts.s4_u_sgsn_f_teid.data;
|
|
|
|
bearer->pgw_s5u_teid = be32toh(pgw_s5u_teid->teid);
|
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &bearer->pgw_s5u_ip));
|
2017-09-04 13:00:51 +00:00
|
|
|
|
|
|
|
/* Bearer QoS */
|
2023-01-23 15:01:36 +00:00
|
|
|
if (ogs_gtp2_parse_bearer_qos(
|
|
|
|
&bearer_qos, &req->bearer_contexts.bearer_level_qos) !=
|
|
|
|
req->bearer_contexts.bearer_level_qos.len) {
|
|
|
|
ogs_error("ogs_gtp2_parse_bearer_qos() failed");
|
|
|
|
return;
|
|
|
|
}
|
2021-03-08 12:25:09 +00:00
|
|
|
bearer->qos.index = bearer_qos.qci;
|
2017-09-04 13:00:51 +00:00
|
|
|
bearer->qos.arp.priority_level = bearer_qos.priority_level;
|
|
|
|
bearer->qos.arp.pre_emption_capability =
|
|
|
|
bearer_qos.pre_emption_capability;
|
|
|
|
bearer->qos.arp.pre_emption_vulnerability =
|
|
|
|
bearer_qos.pre_emption_vulnerability;
|
2017-09-04 15:04:05 +00:00
|
|
|
bearer->qos.mbr.downlink = bearer_qos.dl_mbr;
|
|
|
|
bearer->qos.mbr.uplink = bearer_qos.ul_mbr;
|
|
|
|
bearer->qos.gbr.downlink = bearer_qos.dl_gbr;
|
|
|
|
bearer->qos.gbr.uplink = bearer_qos.ul_gbr;
|
2017-09-04 13:00:51 +00:00
|
|
|
|
2021-01-01 02:07:08 +00:00
|
|
|
if (bearer->qos.mbr.downlink || bearer->qos.mbr.uplink ||
|
|
|
|
bearer->qos.gbr.downlink || bearer->qos.gbr.uplink) {
|
|
|
|
if (bearer->qos.mbr.downlink == 0)
|
|
|
|
bearer->qos.mbr.downlink = MAX_BIT_RATE;
|
|
|
|
if (bearer->qos.mbr.uplink == 0)
|
|
|
|
bearer->qos.mbr.uplink = MAX_BIT_RATE;
|
|
|
|
if (bearer->qos.gbr.downlink == 0)
|
|
|
|
bearer->qos.gbr.downlink = MAX_BIT_RATE;
|
|
|
|
if (bearer->qos.gbr.uplink == 0)
|
|
|
|
bearer->qos.gbr.uplink = MAX_BIT_RATE;
|
|
|
|
}
|
|
|
|
|
2017-09-06 15:37:16 +00:00
|
|
|
/* Save Bearer TFT */
|
2019-09-13 12:07:47 +00:00
|
|
|
OGS_TLV_STORE_DATA(&bearer->tft, &req->bearer_contexts.tft);
|
2017-09-06 06:38:24 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
/*
|
|
|
|
* Save Transaction. It will be handled after EMM-attached
|
|
|
|
*
|
|
|
|
* You should not remove OLD bearer->xact.
|
|
|
|
* If GTP-xact Holding timer is expired,
|
|
|
|
* OLD bearer->xact memory will be automatically removed.
|
|
|
|
*/
|
2021-07-15 12:20:56 +00:00
|
|
|
bearer->create.xact = xact;
|
2018-01-14 13:49:29 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
/* Before Activate DEDICATED bearer, check DEFAULT bearer status */
|
2018-01-14 13:49:29 +00:00
|
|
|
default_bearer = mme_default_bearer_in_sess(sess);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!default_bearer) {
|
|
|
|
ogs_error("No Default Bearer");
|
|
|
|
return;
|
|
|
|
}
|
2018-01-14 13:49:29 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
if (OGS_FSM_CHECK(&default_bearer->sm, esm_state_active)) {
|
|
|
|
if (ECM_IDLE(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
|
|
|
MME_STORE_PAGING_INFO(mme_ue,
|
|
|
|
MME_PAGING_TYPE_CREATE_BEARER, bearer);
|
|
|
|
r = s1ap_send_paging(mme_ue, S1AP_CNDomain_ps);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2020-11-07 22:27:12 +00:00
|
|
|
} else {
|
2023-02-20 11:49:48 +00:00
|
|
|
MME_CLEAR_PAGING_INFO(mme_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_activate_dedicated_bearer_context_request(bearer);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
} else {
|
2023-02-20 11:49:48 +00:00
|
|
|
MME_CLEAR_PAGING_INFO(mme_ue);
|
2020-11-07 22:27:12 +00:00
|
|
|
/*
|
|
|
|
* After received Activate EPS default bearer context accept
|
|
|
|
* Invoke nas_eps_send_activate_all_dedicated_bearers()
|
|
|
|
*/
|
2018-01-14 13:49:29 +00:00
|
|
|
}
|
2017-04-28 02:20:09 +00:00
|
|
|
}
|
2017-07-25 12:15:25 +00:00
|
|
|
|
2018-01-17 06:41:45 +00:00
|
|
|
void mme_s11_handle_update_bearer_request(
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_update_bearer_request_t *req)
|
2018-01-17 06:41:45 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2018-01-17 06:41:45 +00:00
|
|
|
mme_bearer_t *bearer = NULL;
|
2020-01-22 12:33:25 +00:00
|
|
|
mme_sess_t *sess = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_bearer_qos_t bearer_qos;
|
2018-01-17 06:41:45 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(xact);
|
|
|
|
ogs_assert(req);
|
2018-01-17 06:41:45 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug("Update Bearer Request");
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/***********************
|
2022-05-12 13:52:36 +00:00
|
|
|
* Check MME-UE Context
|
2022-04-29 12:28:16 +00:00
|
|
|
***********************/
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2019-11-15 14:56:55 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
if (!mme_ue) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("No Context in TEID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
} else {
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
2019-11-15 14:56:55 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (req->bearer_contexts.presence == 0) {
|
|
|
|
ogs_error("No Bearer");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
|
|
|
if (req->bearer_contexts.eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No EPS Bearer ID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
2019-11-15 14:56:55 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
bearer = mme_bearer_find_by_ue_ebi(mme_ue,
|
|
|
|
req->bearer_contexts.eps_bearer_id.u8);
|
|
|
|
if (!bearer) {
|
|
|
|
ogs_error("No Context");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
}
|
2019-11-15 14:56:55 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
2018-01-17 06:41:45 +00:00
|
|
|
return;
|
|
|
|
}
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2021-01-11 04:36:12 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
2020-10-23 17:48:39 +00:00
|
|
|
ogs_assert(bearer);
|
2020-01-22 12:33:25 +00:00
|
|
|
sess = bearer->sess;
|
|
|
|
ogs_assert(sess);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
2022-05-12 13:52:36 +00:00
|
|
|
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
/* Set PTI */
|
2020-01-22 12:33:25 +00:00
|
|
|
sess->pti = OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED;
|
|
|
|
if (req->procedure_transaction_id.presence) {
|
|
|
|
sess->pti = req->procedure_transaction_id.u8;
|
|
|
|
ogs_debug(" PTI[%d]", sess->pti);
|
|
|
|
}
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
/*
|
|
|
|
* Save Transaction. It will be handled after EMM-attached
|
|
|
|
*
|
|
|
|
* You should not remove OLD bearer->xact.
|
|
|
|
* If GTP-xact Holding timer is expired,
|
|
|
|
* OLD bearer->xact memory will be automatically removed.
|
|
|
|
*/
|
2021-07-15 12:20:56 +00:00
|
|
|
bearer->update.xact = xact;
|
2018-01-17 06:41:45 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
if (req->bearer_contexts.bearer_level_qos.presence == 1) {
|
|
|
|
/* Bearer QoS */
|
2023-01-23 15:01:36 +00:00
|
|
|
if (ogs_gtp2_parse_bearer_qos(
|
|
|
|
&bearer_qos, &req->bearer_contexts.bearer_level_qos) !=
|
|
|
|
req->bearer_contexts.bearer_level_qos.len) {
|
|
|
|
ogs_error("ogs_gtp2_parse_bearer_qos() failed");
|
|
|
|
return;
|
|
|
|
}
|
2021-03-08 12:25:09 +00:00
|
|
|
bearer->qos.index = bearer_qos.qci;
|
2020-11-07 22:27:12 +00:00
|
|
|
bearer->qos.arp.priority_level = bearer_qos.priority_level;
|
|
|
|
bearer->qos.arp.pre_emption_capability =
|
|
|
|
bearer_qos.pre_emption_capability;
|
|
|
|
bearer->qos.arp.pre_emption_vulnerability =
|
|
|
|
bearer_qos.pre_emption_vulnerability;
|
|
|
|
bearer->qos.mbr.downlink = bearer_qos.dl_mbr;
|
|
|
|
bearer->qos.mbr.uplink = bearer_qos.ul_mbr;
|
|
|
|
bearer->qos.gbr.downlink = bearer_qos.dl_gbr;
|
|
|
|
bearer->qos.gbr.uplink = bearer_qos.ul_gbr;
|
2018-01-17 06:41:45 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
xact->update_flags |= OGS_GTP_MODIFY_QOS_UPDATE;
|
|
|
|
}
|
2018-01-17 06:41:45 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
if (req->bearer_contexts.tft.presence == 1) {
|
|
|
|
/* Save Bearer TFT */
|
|
|
|
OGS_TLV_STORE_DATA(&bearer->tft, &req->bearer_contexts.tft);
|
2019-12-28 12:46:30 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
xact->update_flags |= OGS_GTP_MODIFY_TFT_UPDATE;
|
|
|
|
}
|
2019-12-28 12:46:30 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
if (req->bearer_contexts.bearer_level_qos.presence == 1 ||
|
|
|
|
req->bearer_contexts.tft.presence == 1) {
|
|
|
|
if (ECM_IDLE(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
|
|
|
MME_STORE_PAGING_INFO(mme_ue,
|
|
|
|
MME_PAGING_TYPE_UPDATE_BEARER, bearer);
|
|
|
|
r = s1ap_send_paging(mme_ue, S1AP_CNDomain_ps);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2020-11-07 22:27:12 +00:00
|
|
|
} else {
|
2023-02-20 11:49:48 +00:00
|
|
|
MME_CLEAR_PAGING_INFO(mme_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_modify_bearer_context_request(bearer,
|
2020-11-07 22:27:12 +00:00
|
|
|
req->bearer_contexts.bearer_level_qos.presence,
|
2023-01-23 01:37:22 +00:00
|
|
|
req->bearer_contexts.tft.presence);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2018-01-17 06:41:45 +00:00
|
|
|
}
|
2019-06-19 09:04:57 +00:00
|
|
|
} else {
|
2023-02-20 11:49:48 +00:00
|
|
|
MME_CLEAR_PAGING_INFO(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("[IGNORE] Update Bearer Request : "
|
2020-11-07 22:27:12 +00:00
|
|
|
"Both QoS and TFT is NULL");
|
|
|
|
|
|
|
|
if (xact->xid & OGS_GTP_CMD_XACT_ID) {
|
|
|
|
/* MME received Bearer Resource Modification Request */
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_bearer_resource_modification_reject(
|
2022-07-19 03:42:02 +00:00
|
|
|
mme_ue, sess->pti,
|
2023-01-23 01:37:22 +00:00
|
|
|
OGS_NAS_ESM_CAUSE_SERVICE_OPTION_NOT_SUPPORTED);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
mme_gtp_send_update_bearer_response(
|
2022-04-12 22:07:39 +00:00
|
|
|
bearer, OGS_GTP2_CAUSE_REQUEST_ACCEPTED));
|
2018-01-17 06:41:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-16 11:49:39 +00:00
|
|
|
void mme_s11_handle_delete_bearer_request(
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_delete_bearer_request_t *req)
|
2018-01-16 11:49:39 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2018-01-16 11:49:39 +00:00
|
|
|
mme_bearer_t *bearer = NULL;
|
2020-01-22 12:33:25 +00:00
|
|
|
mme_sess_t *sess = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2018-01-16 11:49:39 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(xact);
|
|
|
|
ogs_assert(req);
|
2018-01-16 11:49:39 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug("Delete Bearer Request");
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/***********************
|
2022-05-12 13:52:36 +00:00
|
|
|
* Check MME-UE Context
|
2022-04-29 12:28:16 +00:00
|
|
|
***********************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
if (!mme_ue) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("No Context in TEID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
2019-06-19 09:04:57 +00:00
|
|
|
} else {
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
if (req->linked_eps_bearer_id.presence == 1) {
|
|
|
|
/*
|
|
|
|
* << Linked EPS Bearer ID >>
|
|
|
|
*
|
|
|
|
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to SGW/MME.
|
|
|
|
* 2. MME sends Delete Bearer Response to SGW/SMF.
|
|
|
|
*
|
|
|
|
* OR
|
|
|
|
*
|
|
|
|
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to ePDG.
|
|
|
|
* 2. ePDG sends Delete Bearer Response(DEFAULT BEARER) to SMF.
|
|
|
|
*/
|
|
|
|
bearer = mme_bearer_find_by_ue_ebi(
|
|
|
|
mme_ue, req->linked_eps_bearer_id.u8);
|
|
|
|
if (!bearer) {
|
|
|
|
ogs_error("Cannot find Bearer [%d]",
|
|
|
|
req->linked_eps_bearer_id.u8);
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
} else if (req->eps_bearer_ids.presence == 1) {
|
|
|
|
/*
|
|
|
|
* << EPS Bearer IDs >>
|
|
|
|
*
|
|
|
|
* 1. MME sends Bearer Resource Command to SGW/SMF.
|
|
|
|
* 2. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME.
|
|
|
|
* 3. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF.
|
|
|
|
*
|
|
|
|
* OR
|
|
|
|
*
|
|
|
|
* 1. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME.
|
|
|
|
* 2. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF.
|
|
|
|
*/
|
|
|
|
bearer = mme_bearer_find_by_ue_ebi(mme_ue, req->eps_bearer_ids.u8);
|
|
|
|
if (!bearer) {
|
|
|
|
ogs_error("Cannot find Bearer [%d]", req->eps_bearer_ids.u8);
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ogs_error("No Linked EBI or EPS Bearer ID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
2020-10-23 17:48:39 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE,
|
|
|
|
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
2018-01-16 11:49:39 +00:00
|
|
|
return;
|
|
|
|
}
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2019-11-11 14:09:35 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(sgw_ue);
|
2019-11-15 14:56:55 +00:00
|
|
|
|
2020-10-23 17:48:39 +00:00
|
|
|
ogs_assert(bearer);
|
2020-01-22 12:33:25 +00:00
|
|
|
sess = bearer->sess;
|
|
|
|
ogs_assert(sess);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
2022-05-12 13:52:36 +00:00
|
|
|
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
/* Set PTI */
|
2020-01-22 12:33:25 +00:00
|
|
|
sess->pti = OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED;
|
|
|
|
if (req->procedure_transaction_id.presence) {
|
|
|
|
sess->pti = req->procedure_transaction_id.u8;
|
|
|
|
ogs_debug(" PTI[%d]", sess->pti);
|
|
|
|
}
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
/*
|
|
|
|
* Save Transaction. It will be handled after EMM-attached
|
|
|
|
*
|
|
|
|
* You should not remove OLD bearer->xact.
|
|
|
|
* If GTP-xact Holding timer is expired,
|
|
|
|
* OLD bearer->xact memory will be automatically removed.
|
|
|
|
*/
|
2021-07-15 12:20:56 +00:00
|
|
|
bearer->delete.xact = xact;
|
2018-01-16 11:49:39 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
if (ECM_IDLE(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
|
|
|
MME_STORE_PAGING_INFO(mme_ue,
|
|
|
|
MME_PAGING_TYPE_DELETE_BEARER, bearer);
|
|
|
|
r = s1ap_send_paging(mme_ue, S1AP_CNDomain_ps);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2019-06-19 09:04:57 +00:00
|
|
|
} else {
|
2023-02-20 11:49:48 +00:00
|
|
|
MME_CLEAR_PAGING_INFO(mme_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_deactivate_bearer_context_request(bearer);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2018-01-16 11:49:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-25 12:15:25 +00:00
|
|
|
void mme_s11_handle_release_access_bearers_response(
|
2022-06-30 00:11:31 +00:00
|
|
|
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_release_access_bearers_response_t *rsp)
|
2017-07-25 12:15:25 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r, rv;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2020-11-07 22:27:12 +00:00
|
|
|
int action = 0;
|
2017-09-10 14:03:24 +00:00
|
|
|
enb_ue_t *enb_ue = NULL;
|
2017-09-01 12:35:45 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;;
|
2022-06-30 00:11:31 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
2020-11-07 22:27:12 +00:00
|
|
|
mme_sess_t *sess = NULL;
|
|
|
|
mme_bearer_t *bearer = NULL;
|
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(rsp);
|
2017-07-25 12:15:25 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug("Release Access Bearers Response");
|
2018-02-01 13:48:59 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(xact);
|
|
|
|
action = xact->release_action;
|
|
|
|
ogs_assert(action);
|
2024-02-27 12:16:50 +00:00
|
|
|
|
|
|
|
MME_UE_CHECK(OGS_LOG_DEBUG, xact->data);
|
2023-02-20 11:49:48 +00:00
|
|
|
mme_ue = mme_ue_cycle(xact->data);
|
2019-11-15 14:56:55 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_commit() failed");
|
|
|
|
return;
|
|
|
|
}
|
2018-02-01 13:48:59 +00:00
|
|
|
|
2023-02-20 11:49:48 +00:00
|
|
|
if (!mme_ue) {
|
|
|
|
ogs_error("MME-UE Context has already been removed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
2022-06-30 00:11:31 +00:00
|
|
|
/***********************
|
|
|
|
* Check MME-UE Context
|
|
|
|
***********************/
|
|
|
|
if (!mme_ue_from_teid) {
|
2022-06-30 04:33:16 +00:00
|
|
|
ogs_error("No Context in TEID [ACTION:%d]", action);
|
2022-06-30 00:11:31 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Cause Value
|
|
|
|
********************/
|
2019-11-15 14:56:55 +00:00
|
|
|
if (rsp->cause.presence) {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
2019-11-15 14:56:55 +00:00
|
|
|
ogs_assert(cause);
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2019-11-15 14:56:55 +00:00
|
|
|
cause_value = cause->value;
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED)
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("GTP Cause [VALUE:%d, ACTION:%d]", cause_value, action);
|
2019-11-11 14:09:35 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2022-02-19 00:47:44 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_assert(sgw_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
|
|
|
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
2017-08-31 05:03:00 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_list_for_each(&mme_ue->sess_list, sess) {
|
|
|
|
ogs_list_for_each(&sess->bearer_list, bearer) {
|
|
|
|
CLEAR_ENB_S1U_PATH(bearer);
|
|
|
|
}
|
2019-11-15 14:56:55 +00:00
|
|
|
}
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
if (action == OGS_GTP_RELEASE_SEND_UE_CONTEXT_RELEASE_COMMAND) {
|
|
|
|
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
|
|
|
|
if (enb_ue) {
|
2023-01-23 01:37:22 +00:00
|
|
|
r = s1ap_send_ue_context_release_command(enb_ue,
|
2020-11-07 22:27:12 +00:00
|
|
|
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
|
2023-01-23 01:37:22 +00:00
|
|
|
S1AP_UE_CTX_REL_S1_REMOVE_AND_UNLINK, 0);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2020-11-07 22:27:12 +00:00
|
|
|
} else {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("ENB-S1 Context has already been removed");
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
2021-01-25 04:43:42 +00:00
|
|
|
} else if (action == OGS_GTP_RELEASE_S1_CONTEXT_REMOVE_BY_LO_CONNREFUSED) {
|
2022-05-15 13:37:38 +00:00
|
|
|
/* enb_ue_unlink() and enb_ue_remove() has already been executed.
|
|
|
|
* So, there is no `enb_ue` context */
|
2021-01-25 04:43:42 +00:00
|
|
|
|
2022-05-15 13:37:38 +00:00
|
|
|
} else if (action == OGS_GTP_RELEASE_S1_CONTEXT_REMOVE_BY_RESET_ALL) {
|
2021-01-25 04:43:42 +00:00
|
|
|
/*
|
|
|
|
* TS36.413
|
|
|
|
* 8.7.1.2.1 Reset Procedure Initiated from the MME
|
|
|
|
*
|
|
|
|
* The eNB does not need to wait for the release of radio resources
|
|
|
|
* to be completed before returning the RESET ACKNOWLEDGE message.
|
|
|
|
*
|
|
|
|
* 8.7.1.2.2 Reset Procedure Initiated from the E-UTRAN
|
|
|
|
* After the MME has released all assigned S1 resources and
|
|
|
|
* the UE S1AP IDs for all indicated UE associations which can be used
|
|
|
|
* for new UE-associated logical S1-connections over the S1 interface,
|
|
|
|
* the MME shall respond with the RESET ACKNOWLEDGE message.
|
|
|
|
*/
|
|
|
|
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
enb_ue_unlink(mme_ue);
|
2021-01-25 04:43:42 +00:00
|
|
|
|
|
|
|
if (enb_ue) {
|
|
|
|
mme_enb_t *enb = enb_ue->enb;
|
|
|
|
ogs_assert(enb);
|
|
|
|
|
|
|
|
enb_ue_remove(enb_ue);
|
|
|
|
|
2023-01-23 01:37:22 +00:00
|
|
|
if (ogs_list_count(&enb->enb_ue_list) == 0) {
|
|
|
|
r = s1ap_send_s1_reset_ack(enb, NULL);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
|
|
|
}
|
2021-01-25 04:43:42 +00:00
|
|
|
} else {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("ENB-S1 Context has already been removed");
|
2021-01-25 04:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} else if (action == OGS_GTP_RELEASE_S1_CONTEXT_REMOVE_BY_RESET_PARTIAL) {
|
|
|
|
enb_ue_t *iter = NULL;
|
|
|
|
|
|
|
|
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
enb_ue_unlink(mme_ue);
|
2021-01-25 04:43:42 +00:00
|
|
|
|
|
|
|
if (enb_ue) {
|
|
|
|
mme_enb_t *enb = enb_ue->enb;
|
|
|
|
ogs_assert(enb);
|
|
|
|
|
|
|
|
enb_ue_remove(enb_ue);
|
|
|
|
|
|
|
|
ogs_list_for_each(&enb->enb_ue_list, iter) {
|
|
|
|
if (iter->part_of_s1_reset_requested == true) {
|
|
|
|
/* The ENB_UE context
|
|
|
|
* where PartOfS1_interface was requested
|
|
|
|
* still remains */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* All ENB_UE context
|
|
|
|
* where PartOfS1_interface was requested
|
|
|
|
* REMOVED */
|
2021-11-30 13:22:41 +00:00
|
|
|
ogs_assert(enb->s1_reset_ack);
|
2023-01-23 01:37:22 +00:00
|
|
|
r = s1ap_send_to_enb(enb, enb->s1_reset_ack, S1AP_NON_UE_SIGNALLING);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2021-01-25 04:43:42 +00:00
|
|
|
|
|
|
|
/* Clear S1-Reset Ack Buffer */
|
|
|
|
enb->s1_reset_ack = NULL;
|
|
|
|
} else {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("ENB-S1 Context has already been removed");
|
2021-01-25 04:43:42 +00:00
|
|
|
}
|
|
|
|
|
2019-11-11 14:09:35 +00:00
|
|
|
} else {
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_fatal("Invalid action = %d", action);
|
|
|
|
ogs_assert_if_reached();
|
2019-11-11 14:09:35 +00:00
|
|
|
}
|
2017-07-25 12:15:25 +00:00
|
|
|
}
|
2017-08-02 23:18:19 +00:00
|
|
|
|
|
|
|
void mme_s11_handle_downlink_data_notification(
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_downlink_data_notification_t *noti)
|
2017-08-02 23:18:19 +00:00
|
|
|
{
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2023-01-23 01:37:22 +00:00
|
|
|
int r;
|
2020-11-07 22:27:12 +00:00
|
|
|
|
|
|
|
mme_bearer_t *bearer = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2017-08-02 23:18:19 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(xact);
|
|
|
|
ogs_assert(noti);
|
2017-08-02 23:18:19 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug("Downlink Data Notification");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
2022-05-12 13:52:36 +00:00
|
|
|
* Check MME-UE Context
|
2022-04-29 12:28:16 +00:00
|
|
|
************************/
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
if (!mme_ue) {
|
2021-01-05 04:24:22 +00:00
|
|
|
ogs_error("No UE Context");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
2022-04-29 12:28:16 +00:00
|
|
|
} else {
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (noti->eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No Bearer ID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
bearer = mme_bearer_find_by_ue_ebi(mme_ue, noti->eps_bearer_id.u8);
|
|
|
|
if (!bearer) {
|
|
|
|
ogs_error("No Context for EPS Bearer ID[%d]",
|
|
|
|
noti->eps_bearer_id.u8);
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE,
|
|
|
|
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
|
2019-11-15 14:56:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2020-10-21 00:00:02 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_assert(bearer);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
2022-05-12 13:52:36 +00:00
|
|
|
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
2017-08-02 23:18:19 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
/*
|
|
|
|
* Save Transaction. It will be handled after ECM-Connected
|
|
|
|
*
|
|
|
|
* You should not remove OLD bearer->xact.
|
|
|
|
* If GTP-xact Holding timer is expired,
|
|
|
|
* OLD bearer->xact memory will be automatically removed.
|
|
|
|
*/
|
2021-07-15 12:20:56 +00:00
|
|
|
bearer->notify.xact = xact;
|
2020-10-21 00:00:02 +00:00
|
|
|
|
|
|
|
if (noti->cause.presence) {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_cause_t *cause = noti->cause.data;
|
2020-10-21 00:00:02 +00:00
|
|
|
ogs_assert(cause);
|
|
|
|
|
|
|
|
cause_value = cause->value;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* 5.3.4.2 in Spec 23.401
|
|
|
|
* Under certain conditions, the current UE triggered Service Request
|
|
|
|
* procedure can cause unnecessary Downlink Packet Notification messages
|
|
|
|
* which increase the load of the MME.
|
|
|
|
*
|
|
|
|
* This can occur when uplink data sent in step 6 causes a response
|
|
|
|
* on the downlink which arrives at the Serving GW before the Modify Bearer
|
|
|
|
* Request message, step 8. This data cannot be forwarded from the Serving GW
|
|
|
|
* to the eNodeB and hence it triggers a Downlink Data Notification message.
|
|
|
|
*
|
|
|
|
* If the MME receives a Downlink Data Notification after step 2 and
|
|
|
|
* before step 9, the MME shall not send S1 interface paging messages
|
|
|
|
*/
|
|
|
|
if (ECM_IDLE(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
|
|
|
MME_STORE_PAGING_INFO(mme_ue,
|
|
|
|
MME_PAGING_TYPE_DOWNLINK_DATA_NOTIFICATION, bearer);
|
|
|
|
r = s1ap_send_paging(mme_ue, S1AP_CNDomain_ps);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2020-10-21 00:00:02 +00:00
|
|
|
} else if (ECM_CONNECTED(mme_ue)) {
|
2023-02-20 11:49:48 +00:00
|
|
|
MME_CLEAR_PAGING_INFO(mme_ue);
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value == OGS_GTP2_CAUSE_ERROR_INDICATION_RECEIVED) {
|
2020-10-21 00:00:02 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* TS23.007 22. Downlink Data Notification Handling at MME/S4 SGSN
|
|
|
|
*
|
|
|
|
* If the MME/S4 SGSN receives a Downlink Data Notification message from
|
|
|
|
* the SGW as a result of the SGW having received an Error Indication message
|
|
|
|
* from the eNodeB/RNC or S4-SGSN over S4 User Plane, the MME/S4 SGSN should
|
|
|
|
* perform the following:
|
|
|
|
*
|
|
|
|
* - If the UE is in IDLE state, upon receipt of the Downlink Data
|
|
|
|
* Notification message, the MME/S4 SGSN shall perform the Network
|
|
|
|
* Triggered Service Request procedure as specified in 3GPP TS 23.060[5]
|
|
|
|
* and 3GPP TS 23.401 [15].
|
|
|
|
* - If the UE is in CONNECTED state, upon receipt of the Downlink Data
|
|
|
|
* Notification message, the MME shall perform S1 Release procedure and
|
|
|
|
* perform Network Triggered Service Request procedure as specified
|
|
|
|
* in 3GPP TS 23.401 [15].
|
|
|
|
* - If the UE is in CONNECTED state, upon receipt of the Downlink Data
|
|
|
|
* Notification message and Direct Tunnel is used, the S4-SGSN shall
|
|
|
|
* perform Iu Release procedure and perform Network Triggered Service
|
|
|
|
* Request procedure as specified in 3GPP TS 23.060 [5]
|
|
|
|
* if the cause value included in Downlink Data Notification is
|
|
|
|
* "Error Indication received from RNC/eNodeB/S4-SGSN",
|
|
|
|
* - If the UE is in CONNECTED state, upon receipt of the Downlink Data
|
|
|
|
* Notification message and Direct Tunnel is not used, the S4-SGSN should
|
|
|
|
* re-establish all of the S4-U bearers of this UE if the cause value
|
|
|
|
* included in Downlink Data Notification is "Error Indication received
|
|
|
|
* from RNC/eNodeB/S4-SGSN"
|
|
|
|
*/
|
2020-10-29 02:59:27 +00:00
|
|
|
enb_ue_t *enb_ue = enb_ue_cycle(mme_ue->enb_ue);
|
2020-10-21 00:00:02 +00:00
|
|
|
ogs_assert(enb_ue);
|
|
|
|
|
2023-01-23 01:37:22 +00:00
|
|
|
r = s1ap_send_ue_context_release_command(enb_ue,
|
2020-10-21 00:00:02 +00:00
|
|
|
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
|
2023-01-23 01:37:22 +00:00
|
|
|
S1AP_UE_CTX_REL_S1_PAGING, 0);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2020-11-07 22:27:12 +00:00
|
|
|
} else {
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
mme_gtp_send_downlink_data_notification_ack(
|
2022-04-12 22:07:39 +00:00
|
|
|
bearer, OGS_GTP2_CAUSE_UE_ALREADY_RE_ATTACHED));
|
2020-10-21 00:00:02 +00:00
|
|
|
}
|
|
|
|
}
|
2017-08-02 23:18:19 +00:00
|
|
|
}
|
2017-09-13 11:35:19 +00:00
|
|
|
|
|
|
|
void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
|
2022-06-30 00:11:31 +00:00
|
|
|
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_indirect_data_forwarding_tunnel_response_t *rsp)
|
2017-09-13 11:35:19 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int i, r, rv;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
|
|
|
uint8_t session_cause = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2017-09-13 12:51:02 +00:00
|
|
|
mme_bearer_t *bearer = NULL;
|
2022-06-30 00:11:31 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
2017-09-15 03:06:26 +00:00
|
|
|
enb_ue_t *source_ue = NULL;
|
2017-09-13 12:51:02 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_f_teid_t *teid = NULL;
|
2017-09-13 12:51:02 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(rsp);
|
2017-09-13 12:51:02 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug("Create Indirect Data Forwarding Tunnel Response");
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
2022-06-30 00:11:31 +00:00
|
|
|
ogs_assert(xact);
|
2023-02-20 11:49:48 +00:00
|
|
|
mme_ue = mme_ue_cycle(xact->data);
|
2019-11-15 14:56:55 +00:00
|
|
|
|
2019-11-11 14:09:35 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_commit() failed");
|
|
|
|
return;
|
|
|
|
}
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2023-02-20 11:49:48 +00:00
|
|
|
if (!mme_ue) {
|
|
|
|
ogs_error("MME-UE Context has already been removed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
/************************
|
|
|
|
* Getting Cause Value
|
|
|
|
************************/
|
|
|
|
if (rsp->cause.presence && rsp->cause.data) {
|
|
|
|
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
|
|
|
ogs_assert(cause);
|
|
|
|
session_cause = cause->value;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
2022-05-12 13:52:36 +00:00
|
|
|
* Check MME-UE Context
|
2022-04-29 12:28:16 +00:00
|
|
|
************************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2022-06-30 00:11:31 +00:00
|
|
|
if (!mme_ue_from_teid) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] No Context in TEID [Cause:%d]",
|
|
|
|
mme_ue->imsi_bcd, session_cause);
|
2022-06-30 00:11:31 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
2017-09-13 12:51:02 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (rsp->cause.presence == 0) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] No Cause [VALUE:%d]", mme_ue->imsi_bcd, session_cause);
|
2022-04-29 12:28:16 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************
|
|
|
|
* Check Cause Value
|
|
|
|
********************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
if (session_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_error("[%s] GTP Cause [VALUE:%d]", mme_ue->imsi_bcd, session_cause);
|
2022-04-29 12:28:16 +00:00
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
2019-11-15 14:56:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
|
|
|
ogs_assert(mme_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
2022-05-12 13:52:36 +00:00
|
|
|
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2020-07-09 05:38:09 +00:00
|
|
|
for (i = 0; rsp->bearer_contexts[i].presence; i++) {
|
|
|
|
if (rsp->bearer_contexts[i].eps_bearer_id.presence == 0) {
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_error("No EBI");
|
2017-09-13 12:51:02 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
bearer = mme_bearer_find_by_ue_ebi(mme_ue,
|
2020-07-09 05:38:09 +00:00
|
|
|
rsp->bearer_contexts[i].eps_bearer_id.u8);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!bearer) {
|
|
|
|
ogs_error("No Bearer");
|
|
|
|
return;
|
|
|
|
}
|
2017-09-13 12:51:02 +00:00
|
|
|
|
2020-07-09 05:38:09 +00:00
|
|
|
if (rsp->bearer_contexts[i].s4_u_sgsn_f_teid.presence) {
|
|
|
|
teid = rsp->bearer_contexts[i].s4_u_sgsn_f_teid.data;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(teid);
|
2017-09-13 12:51:02 +00:00
|
|
|
|
2020-10-01 17:27:58 +00:00
|
|
|
bearer->sgw_dl_teid = be32toh(teid->teid);
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_f_teid_to_ip(teid, &bearer->sgw_dl_ip);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(rv == OGS_OK);
|
2017-09-13 12:51:02 +00:00
|
|
|
}
|
2020-07-09 05:38:09 +00:00
|
|
|
if (rsp->bearer_contexts[i].s2b_u_epdg_f_teid_5.presence) {
|
|
|
|
teid = rsp->bearer_contexts[i].s2b_u_epdg_f_teid_5.data;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(teid);
|
2017-09-13 12:51:02 +00:00
|
|
|
|
2020-10-01 17:27:58 +00:00
|
|
|
bearer->sgw_ul_teid = be32toh(teid->teid);
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_f_teid_to_ip(teid, &bearer->sgw_ul_ip);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(rv == OGS_OK);
|
2017-09-13 12:51:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-29 02:59:27 +00:00
|
|
|
source_ue = enb_ue_cycle(mme_ue->enb_ue);
|
2019-11-11 14:09:35 +00:00
|
|
|
ogs_assert(source_ue);
|
|
|
|
|
2023-01-23 01:37:22 +00:00
|
|
|
r = s1ap_send_handover_command(source_ue);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2017-09-13 11:35:19 +00:00
|
|
|
}
|
2017-09-14 05:18:47 +00:00
|
|
|
|
|
|
|
void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
|
2022-06-30 00:11:31 +00:00
|
|
|
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_delete_indirect_data_forwarding_tunnel_response_t *rsp)
|
2017-09-14 05:18:47 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r, rv;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
|
|
|
uint8_t session_cause = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2021-02-01 04:01:15 +00:00
|
|
|
int action = 0;
|
2022-06-30 00:11:31 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2017-09-14 05:18:47 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(rsp);
|
2017-09-14 05:18:47 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug("Delete Indirect Data Forwarding Tunnel Response");
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(xact);
|
|
|
|
action = xact->delete_indirect_action;
|
|
|
|
ogs_assert(action);
|
2023-02-20 11:49:48 +00:00
|
|
|
mme_ue = mme_ue_cycle(xact->data);
|
2019-11-15 14:56:55 +00:00
|
|
|
|
2019-11-11 14:09:35 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_commit() failed");
|
|
|
|
return;
|
|
|
|
}
|
2019-11-11 14:09:35 +00:00
|
|
|
|
2023-02-20 11:49:48 +00:00
|
|
|
if (!mme_ue) {
|
|
|
|
ogs_error("MME-UE Context has already been removed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
/************************
|
|
|
|
* Getting Cause Value
|
|
|
|
************************/
|
|
|
|
if (rsp->cause.presence && rsp->cause.data) {
|
|
|
|
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
|
|
|
ogs_assert(cause);
|
|
|
|
session_cause = cause->value;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
2022-05-12 13:52:36 +00:00
|
|
|
* Check MME-UE Context
|
2022-04-29 12:28:16 +00:00
|
|
|
************************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2019-11-15 14:56:55 +00:00
|
|
|
|
2022-06-30 00:11:31 +00:00
|
|
|
if (!mme_ue_from_teid) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] No Context in TEID [Cause:%d]",
|
|
|
|
mme_ue->imsi_bcd, session_cause);
|
2022-06-30 00:11:31 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
|
|
|
|
|
|
if (rsp->cause.presence == 0) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("[%s] No Cause [VALUE:%d]", mme_ue->imsi_bcd, session_cause);
|
2022-04-29 12:28:16 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2019-11-11 14:09:35 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2022-04-29 12:28:16 +00:00
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
2019-11-11 14:09:35 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Cause Value
|
|
|
|
********************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
if (session_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_error("GTP Cause [VALUE:%d]", session_cause);
|
2022-04-29 12:28:16 +00:00
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
|
|
|
ogs_assert(mme_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
2022-05-12 13:52:36 +00:00
|
|
|
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
2017-09-14 05:18:47 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
mme_ue_clear_indirect_tunnel(mme_ue);
|
2021-02-01 04:01:15 +00:00
|
|
|
|
|
|
|
if (action == OGS_GTP_DELETE_INDIRECT_HANDOVER_COMPLETE) {
|
|
|
|
/* Nothing to do */
|
|
|
|
} else if (action == OGS_GTP_DELETE_INDIRECT_HANDOVER_CANCEL) {
|
2023-01-23 01:37:22 +00:00
|
|
|
r = s1ap_send_handover_cancel_ack(mme_ue->enb_ue);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2021-02-01 04:01:15 +00:00
|
|
|
} else {
|
|
|
|
ogs_fatal("Invalid action = %d", action);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
}
|
2017-09-14 05:18:47 +00:00
|
|
|
}
|
2019-12-28 12:46:30 +00:00
|
|
|
|
|
|
|
void mme_s11_handle_bearer_resource_failure_indication(
|
2022-06-30 00:11:31 +00:00
|
|
|
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_bearer_resource_failure_indication_t *ind)
|
2019-12-28 12:46:30 +00:00
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r, rv;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2019-12-28 12:46:30 +00:00
|
|
|
|
|
|
|
mme_bearer_t *bearer = NULL;
|
2021-01-11 04:36:12 +00:00
|
|
|
mme_sess_t *sess = NULL;
|
2022-06-30 00:11:31 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2019-12-28 12:46:30 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_debug("Bearer Resource Failure Indication");
|
|
|
|
|
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
2019-12-28 12:46:30 +00:00
|
|
|
ogs_assert(xact);
|
|
|
|
bearer = xact->data;
|
|
|
|
ogs_assert(ind);
|
2021-01-11 04:36:12 +00:00
|
|
|
sess = bearer->sess;
|
|
|
|
ogs_assert(sess);
|
2023-02-20 11:49:48 +00:00
|
|
|
mme_ue = mme_ue_cycle(sess->mme_ue);
|
2019-12-28 12:46:30 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_commit() failed");
|
|
|
|
return;
|
|
|
|
}
|
2019-12-28 12:46:30 +00:00
|
|
|
|
2023-02-20 11:49:48 +00:00
|
|
|
if (!mme_ue) {
|
|
|
|
ogs_error("MME-UE Context has already been removed");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
2022-06-30 00:11:31 +00:00
|
|
|
if (!mme_ue_from_teid)
|
|
|
|
ogs_error("No Context in TEID");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Cause Value
|
|
|
|
********************/
|
2019-12-28 12:46:30 +00:00
|
|
|
if (ind->cause.presence) {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_cause_t *cause = ind->cause.data;
|
2019-12-28 12:46:30 +00:00
|
|
|
ogs_assert(cause);
|
|
|
|
|
|
|
|
cause_value = cause->value;
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_warn("GTP Cause [VALUE:%d] - Ignored", cause_value);
|
2019-12-28 12:46:30 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("No Cause");
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2021-01-11 04:36:12 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_assert(sgw_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
|
|
|
mme_ue->mme_s11_teid, sgw_ue->sgw_s11_teid);
|
2019-12-28 12:46:30 +00:00
|
|
|
|
2023-01-23 01:37:22 +00:00
|
|
|
r = nas_eps_send_bearer_resource_modification_reject(
|
|
|
|
mme_ue, sess->pti, esm_cause_from_gtp(cause_value));
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2021-01-11 05:01:28 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (!sgw_ue ||
|
|
|
|
cause_value == OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND) {
|
|
|
|
ogs_error("No Bearer");
|
2021-01-11 05:01:28 +00:00
|
|
|
mme_bearer_remove(bearer);
|
|
|
|
}
|
2019-12-28 12:46:30 +00:00
|
|
|
}
|