2020-06-04 18:12:05 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2019,2020 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 "ngap-path.h"
|
|
|
|
#include "ngap-build.h"
|
|
|
|
#include "gmm-build.h"
|
|
|
|
#include "nas-path.h"
|
|
|
|
|
|
|
|
int nas_5gs_send_to_gnb(amf_ue_t *amf_ue, ogs_pkbuf_t *pkbuf)
|
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int rv;
|
2022-07-21 03:41:19 +00:00
|
|
|
ogs_assert(pkbuf);
|
2020-06-04 18:12:05 +00:00
|
|
|
|
2022-07-21 03:41:19 +00:00
|
|
|
amf_ue = amf_ue_cycle(amf_ue);
|
|
|
|
if (!amf_ue) {
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_error("UE(amf-ue) context has already been removed");
|
2022-07-21 03:41:19 +00:00
|
|
|
ogs_pkbuf_free(pkbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_NOTFOUND;
|
2022-07-21 03:41:19 +00:00
|
|
|
}
|
2020-06-04 18:12:05 +00:00
|
|
|
|
2023-01-23 01:37:22 +00:00
|
|
|
rv = ngap_send_to_ran_ue(amf_ue->ran_ue, pkbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
return rv;
|
2020-06-04 18:12:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int nas_5gs_send_to_downlink_nas_transport(amf_ue_t *amf_ue, ogs_pkbuf_t *pkbuf)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_pkbuf_t *ngapbuf = NULL;
|
2022-07-21 08:13:32 +00:00
|
|
|
ran_ue_t *ran_ue = NULL;
|
2020-06-04 18:12:05 +00:00
|
|
|
|
|
|
|
ogs_assert(pkbuf);
|
2022-07-21 03:41:19 +00:00
|
|
|
|
|
|
|
amf_ue = amf_ue_cycle(amf_ue);
|
|
|
|
if (!amf_ue) {
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_error("UE(amf-ue) context has already been removed");
|
2022-07-20 16:00:44 +00:00
|
|
|
ogs_pkbuf_free(pkbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_NOTFOUND;
|
2022-07-21 03:41:19 +00:00
|
|
|
}
|
2020-06-04 18:12:05 +00:00
|
|
|
|
2022-07-21 08:13:32 +00:00
|
|
|
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
|
|
|
if (!ran_ue) {
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_error("NG context has already been removed");
|
2022-07-21 08:13:32 +00:00
|
|
|
ogs_pkbuf_free(pkbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_NOTFOUND;
|
2022-07-21 08:13:32 +00:00
|
|
|
}
|
|
|
|
|
2022-07-21 03:41:19 +00:00
|
|
|
ngapbuf = ngap_build_downlink_nas_transport(
|
2022-07-21 08:13:32 +00:00
|
|
|
ran_ue, pkbuf, false, false);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!ngapbuf) {
|
|
|
|
ogs_error("ngap_build_downlink_nas_transport() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-04 18:12:05 +00:00
|
|
|
|
2022-07-21 03:41:19 +00:00
|
|
|
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
return rv;
|
2020-06-04 18:12:05 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_registration_accept(amf_ue_t *amf_ue)
|
2020-06-04 18:12:05 +00:00
|
|
|
{
|
|
|
|
int rv;
|
2021-01-23 18:42:59 +00:00
|
|
|
bool transfer_needed = false;
|
2021-01-08 03:26:06 +00:00
|
|
|
|
|
|
|
ran_ue_t *ran_ue = NULL;
|
|
|
|
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_pkbuf_t *ngapbuf = NULL;
|
2020-06-17 05:22:28 +00:00
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
2020-06-04 18:12:05 +00:00
|
|
|
|
2021-01-08 03:26:06 +00:00
|
|
|
ogs_assert(amf_ue);
|
|
|
|
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!ran_ue) {
|
|
|
|
ogs_error("NG context has already been removed");
|
|
|
|
return OGS_NOTFOUND;
|
|
|
|
}
|
2021-01-08 03:26:06 +00:00
|
|
|
|
2021-04-23 06:16:18 +00:00
|
|
|
ogs_debug("[%s] Registration accept", amf_ue->supi);
|
|
|
|
|
|
|
|
if (amf_ue->next.m_tmsi) {
|
|
|
|
if (amf_ue->t3550.pkbuf) {
|
|
|
|
gmmbuf = amf_ue->t3550.pkbuf;
|
|
|
|
} else {
|
|
|
|
gmmbuf = gmm_build_registration_accept(amf_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_registration_accept() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2021-04-23 06:16:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
amf_ue->t3550.pkbuf = ogs_pkbuf_copy(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!amf_ue->t3550.pkbuf) {
|
|
|
|
ogs_error("ogs_pkbuf_copy(amf_ue->t3550.pkbuf) failed");
|
2023-01-23 15:17:10 +00:00
|
|
|
ogs_pkbuf_free(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2021-04-23 06:16:18 +00:00
|
|
|
ogs_timer_start(amf_ue->t3550.timer,
|
|
|
|
amf_timer_cfg(AMF_TIMER_T3550)->duration);
|
|
|
|
} else {
|
|
|
|
gmmbuf = gmm_build_registration_accept(amf_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_registration_accept() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2021-04-23 06:16:18 +00:00
|
|
|
}
|
2020-06-04 18:12:05 +00:00
|
|
|
|
2021-01-23 18:42:59 +00:00
|
|
|
/*
|
|
|
|
* Previously, AMF would sends PDUSessionResourceSetupRequest
|
|
|
|
* when the following conditions were met:
|
|
|
|
* - gNB didn't send UE Context Request IE of InitialUEMessage
|
|
|
|
* - AMF should send SMF generated TRANSFER message(PDU_RES_SETUP_REQ)
|
|
|
|
* to the gNB
|
|
|
|
*
|
|
|
|
* However, in issues #771, the gNB did not accept
|
|
|
|
* PDUSessionResourceSetupRequest. Perhaps the gNB engineer thought
|
|
|
|
* that if gNB needs to send data traffic to the UE, AMF should send
|
|
|
|
* an InitialContextSetupRequest regardless of UE Context Request IE.
|
|
|
|
* This is because gNB requires the kgNB security context
|
|
|
|
* for data connection.
|
|
|
|
*
|
|
|
|
* So, in this case, Open5GS-AMF decided to send
|
|
|
|
* an InitialContexSetupRequest regardless of
|
|
|
|
* whether it received UE Context Request IE of InitialUEMessage.
|
|
|
|
*/
|
|
|
|
transfer_needed = PDU_RES_SETUP_REQ_TRANSFER_NEEDED(amf_ue);
|
|
|
|
|
|
|
|
if (ran_ue->initial_context_setup_request_sent == false &&
|
|
|
|
(ran_ue->ue_context_requested == true || transfer_needed == true)) {
|
2021-01-08 03:26:06 +00:00
|
|
|
ngapbuf = ngap_ue_build_initial_context_setup_request(amf_ue, gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!ngapbuf) {
|
|
|
|
ogs_error("ngap_ue_build_initial_context_setup_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2021-01-08 03:26:06 +00:00
|
|
|
|
|
|
|
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2020-06-04 18:12:05 +00:00
|
|
|
|
2021-01-08 03:26:06 +00:00
|
|
|
ran_ue->initial_context_setup_request_sent = true;
|
|
|
|
} else {
|
2021-01-23 18:42:59 +00:00
|
|
|
if (transfer_needed == true) {
|
2021-01-08 03:26:06 +00:00
|
|
|
ngapbuf = ngap_ue_build_pdu_session_resource_setup_request(
|
|
|
|
amf_ue, gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!ngapbuf) {
|
|
|
|
ogs_error("ngap_ue_build_pdu_session_resource_setup_request()"
|
|
|
|
" failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2021-01-08 03:26:06 +00:00
|
|
|
|
|
|
|
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-01-08 03:26:06 +00:00
|
|
|
} else {
|
|
|
|
ngapbuf = ngap_build_downlink_nas_transport(
|
|
|
|
ran_ue, gmmbuf, true, true);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!ngapbuf) {
|
|
|
|
ogs_error("ngap_build_downlink_nas_transport() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2021-01-08 03:26:06 +00:00
|
|
|
|
|
|
|
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-01-08 03:26:06 +00:00
|
|
|
}
|
|
|
|
}
|
2021-05-16 03:22:10 +00:00
|
|
|
|
2023-01-23 01:37:22 +00:00
|
|
|
return rv;
|
2020-06-04 18:12:05 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_registration_reject(
|
2020-06-04 18:12:05 +00:00
|
|
|
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
|
2022-12-07 06:31:01 +00:00
|
|
|
amf_metrics_inst_by_cause_add(gmm_cause, AMF_METR_CTR_RM_REG_INITFAIL, 1);
|
|
|
|
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_assert(amf_ue);
|
|
|
|
|
|
|
|
ogs_warn("[%s] Registration reject [%d]", amf_ue->suci, gmm_cause);
|
|
|
|
|
|
|
|
gmmbuf = gmm_build_registration_reject(gmm_cause);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_registration_reject() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-22 03:07:14 +00:00
|
|
|
|
2020-06-04 18:12:05 +00:00
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
2020-09-25 01:29:48 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-06-04 18:12:05 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_service_accept(amf_ue_t *amf_ue)
|
2020-06-25 04:37:29 +00:00
|
|
|
{
|
|
|
|
int rv;
|
2021-01-23 18:42:59 +00:00
|
|
|
bool transfer_needed = false;
|
2021-01-08 03:26:06 +00:00
|
|
|
ran_ue_t *ran_ue = NULL;
|
|
|
|
|
2020-06-25 04:37:29 +00:00
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
ogs_pkbuf_t *ngapbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(amf_ue);
|
2021-01-08 03:26:06 +00:00
|
|
|
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!ran_ue) {
|
|
|
|
ogs_error("NG context has already been removed");
|
|
|
|
return OGS_NOTFOUND;
|
|
|
|
}
|
2020-06-25 04:37:29 +00:00
|
|
|
|
2021-04-23 06:16:18 +00:00
|
|
|
ogs_debug("[%s] Service accept", amf_ue->supi);
|
|
|
|
|
2020-06-25 04:37:29 +00:00
|
|
|
gmmbuf = gmm_build_service_accept(amf_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_registration_reject() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-25 04:37:29 +00:00
|
|
|
|
2021-01-23 18:42:59 +00:00
|
|
|
/*
|
|
|
|
* Previously, AMF would sends PDUSessionResourceSetupRequest
|
|
|
|
* when the following conditions were met:
|
|
|
|
* - gNB didn't send UE Context Request IE of InitialUEMessage
|
|
|
|
* - AMF should send SMF generated TRANSFER message(PDU_RES_SETUP_REQ)
|
|
|
|
* to the gNB
|
|
|
|
*
|
|
|
|
* However, in issues #771, the gNB did not accept
|
|
|
|
* PDUSessionResourceSetupRequest. Perhaps the gNB engineer thought
|
|
|
|
* that if gNB needs to send data traffic to the UE, AMF should send
|
|
|
|
* an InitialContextSetupRequest regardless of UE Context Request IE.
|
|
|
|
* This is because gNB requires the kgNB security context
|
|
|
|
* for data connection.
|
|
|
|
*
|
|
|
|
* So, in this case, Open5GS-AMF decided to send
|
|
|
|
* an InitialContexSetupRequest regardless of
|
|
|
|
* whether it received UE Context Request IE of InitialUEMessage.
|
|
|
|
*/
|
|
|
|
transfer_needed = PDU_RES_SETUP_REQ_TRANSFER_NEEDED(amf_ue);
|
|
|
|
|
|
|
|
if (ran_ue->initial_context_setup_request_sent == false &&
|
|
|
|
(ran_ue->ue_context_requested == true || transfer_needed == true)) {
|
2021-01-18 16:48:35 +00:00
|
|
|
ngapbuf = ngap_ue_build_initial_context_setup_request(amf_ue, gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!ngapbuf) {
|
|
|
|
ogs_error("ngap_ue_build_initial_context_setup_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-25 04:37:29 +00:00
|
|
|
|
|
|
|
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2020-06-25 04:37:29 +00:00
|
|
|
|
2021-01-08 03:26:06 +00:00
|
|
|
ran_ue->initial_context_setup_request_sent = true;
|
|
|
|
} else {
|
2021-01-23 18:42:59 +00:00
|
|
|
if (transfer_needed == true) {
|
2021-01-08 03:26:06 +00:00
|
|
|
ngapbuf = ngap_ue_build_pdu_session_resource_setup_request(
|
|
|
|
amf_ue, gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!ngapbuf) {
|
|
|
|
ogs_error("ngap_ue_build_pdu_session_resource_setup_request()"
|
|
|
|
" failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2021-01-08 03:26:06 +00:00
|
|
|
|
|
|
|
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-01-08 03:26:06 +00:00
|
|
|
} else {
|
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-01-08 03:26:06 +00:00
|
|
|
}
|
2020-06-25 04:37:29 +00:00
|
|
|
}
|
2021-05-16 03:22:10 +00:00
|
|
|
|
2023-01-23 01:37:22 +00:00
|
|
|
return rv;
|
2020-06-25 04:37:29 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_service_reject(
|
2020-06-25 04:37:29 +00:00
|
|
|
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(amf_ue);
|
|
|
|
|
2021-04-23 06:16:18 +00:00
|
|
|
ogs_debug("[%s] Service reject", amf_ue->supi);
|
|
|
|
|
2020-06-25 04:37:29 +00:00
|
|
|
gmmbuf = gmm_build_service_reject(amf_ue, gmm_cause);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_registration_reject() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-25 04:37:29 +00:00
|
|
|
|
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-06-25 04:37:29 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue)
|
2020-06-25 04:37:29 +00:00
|
|
|
{
|
2021-05-16 03:22:10 +00:00
|
|
|
int rv;
|
|
|
|
|
2020-06-25 04:37:29 +00:00
|
|
|
ran_ue_t *ran_ue = NULL;
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(amf_ue);
|
2020-10-29 02:59:27 +00:00
|
|
|
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!ran_ue) {
|
|
|
|
ogs_error("NG context has already been removed");
|
|
|
|
return OGS_NOTFOUND;
|
|
|
|
}
|
2020-06-25 04:37:29 +00:00
|
|
|
|
2021-04-23 06:16:18 +00:00
|
|
|
ogs_debug("[%s] De-registration accept", amf_ue->supi);
|
|
|
|
|
2020-06-25 04:37:29 +00:00
|
|
|
if (amf_ue->nas.de_registration.switch_off == 0) {
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
gmmbuf = gmm_build_de_registration_accept(amf_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_registration_reject() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-25 04:37:29 +00:00
|
|
|
|
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("nas_5gs_send_to_downlink_nas_transport() failed");
|
|
|
|
return rv;
|
|
|
|
}
|
2020-06-25 04:37:29 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
rv = ngap_send_ran_ue_context_release_command(ran_ue,
|
2020-06-25 04:37:29 +00:00
|
|
|
NGAP_Cause_PR_nas, NGAP_CauseNas_deregister,
|
|
|
|
NGAP_UE_CTX_REL_NG_REMOVE_AND_UNLINK, 0);
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
return rv;
|
2020-06-25 04:37:29 +00:00
|
|
|
}
|
|
|
|
|
2022-10-24 10:53:28 +00:00
|
|
|
int nas_5gs_send_de_registration_request(amf_ue_t *amf_ue,
|
|
|
|
OpenAPI_deregistration_reason_e dereg_reason)
|
2022-06-21 11:55:37 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
ran_ue_t *ran_ue = NULL;
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(amf_ue);
|
|
|
|
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!ran_ue) {
|
|
|
|
ogs_error("NG context has already been removed");
|
|
|
|
return OGS_NOTFOUND;
|
|
|
|
}
|
2022-06-21 11:55:37 +00:00
|
|
|
|
|
|
|
ogs_debug("[%s] De-registration request", amf_ue->supi);
|
|
|
|
|
|
|
|
if (amf_ue->t3522.pkbuf) {
|
|
|
|
gmmbuf = amf_ue->t3522.pkbuf;
|
|
|
|
} else {
|
2022-10-24 10:53:28 +00:00
|
|
|
gmmbuf = gmm_build_de_registration_request(amf_ue, dereg_reason);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_de_registration_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2022-06-21 11:55:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
amf_ue->t3522.pkbuf = ogs_pkbuf_copy(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!amf_ue->t3522.pkbuf) {
|
|
|
|
ogs_error("ogs_pkbuf_copy(amf_ue->t3522.pkbuf) failed");
|
2023-01-23 15:17:10 +00:00
|
|
|
ogs_pkbuf_free(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2022-06-21 11:55:37 +00:00
|
|
|
ogs_timer_start(amf_ue->t3522.timer,
|
|
|
|
amf_timer_cfg(AMF_TIMER_T3522)->duration);
|
|
|
|
|
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2022-06-21 11:55:37 +00:00
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_identity_request(amf_ue_t *amf_ue)
|
2020-06-04 18:12:05 +00:00
|
|
|
{
|
2020-09-25 01:29:48 +00:00
|
|
|
int rv;
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(amf_ue);
|
|
|
|
|
|
|
|
ogs_debug("Identity request");
|
|
|
|
|
|
|
|
if (amf_ue->t3570.pkbuf) {
|
|
|
|
gmmbuf = amf_ue->t3570.pkbuf;
|
|
|
|
} else {
|
|
|
|
gmmbuf = gmm_build_identity_request(amf_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_identity_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-04 18:12:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
amf_ue->t3570.pkbuf = ogs_pkbuf_copy(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!amf_ue->t3570.pkbuf) {
|
|
|
|
ogs_error("ogs_pkbuf_copy(amf_ue->t3570.pkbuf) failed");
|
2023-01-23 15:17:10 +00:00
|
|
|
ogs_pkbuf_free(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_timer_start(amf_ue->t3570.timer,
|
|
|
|
amf_timer_cfg(AMF_TIMER_T3570)->duration);
|
|
|
|
|
2020-09-25 01:29:48 +00:00
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-06-04 18:12:05 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_authentication_request(amf_ue_t *amf_ue)
|
2020-06-04 18:12:05 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(amf_ue);
|
|
|
|
|
|
|
|
ogs_debug("[%s] Authentication request", amf_ue->suci);
|
|
|
|
|
|
|
|
if (amf_ue->t3560.pkbuf) {
|
|
|
|
gmmbuf = amf_ue->t3560.pkbuf;
|
|
|
|
} else {
|
|
|
|
gmmbuf = gmm_build_authentication_request(amf_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_authentication_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-04 18:12:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
amf_ue->t3560.pkbuf = ogs_pkbuf_copy(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!amf_ue->t3560.pkbuf) {
|
|
|
|
ogs_error("ogs_pkbuf_copy(amf_ue->t3560.pkbuf) failed");
|
2023-01-23 15:17:10 +00:00
|
|
|
ogs_pkbuf_free(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_timer_start(amf_ue->t3560.timer,
|
|
|
|
amf_timer_cfg(AMF_TIMER_T3560)->duration);
|
|
|
|
|
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-06-04 18:12:05 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_authentication_reject(amf_ue_t *amf_ue)
|
2020-06-04 18:12:05 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
|
2022-12-07 06:31:01 +00:00
|
|
|
amf_metrics_inst_by_cause_add(0, AMF_METR_CTR_RM_REG_INITFAIL, 1);
|
|
|
|
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_assert(amf_ue);
|
|
|
|
|
2020-07-26 18:54:30 +00:00
|
|
|
ogs_warn("[%s] Authentication reject", amf_ue->suci);
|
2020-06-04 18:12:05 +00:00
|
|
|
|
|
|
|
gmmbuf = gmm_build_authentication_reject();
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_authentication_reject() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-04 18:12:05 +00:00
|
|
|
|
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-06-04 18:12:05 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_security_mode_command(amf_ue_t *amf_ue)
|
2020-06-04 18:12:05 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(amf_ue);
|
|
|
|
|
|
|
|
ogs_debug("[%s] Security mode command", amf_ue->supi);
|
|
|
|
|
|
|
|
if (amf_ue->t3560.pkbuf) {
|
|
|
|
gmmbuf = amf_ue->t3560.pkbuf;
|
|
|
|
} else {
|
|
|
|
gmmbuf = gmm_build_security_mode_command(amf_ue);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_security_mode_command() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-04 18:12:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
amf_ue->t3560.pkbuf = ogs_pkbuf_copy(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!amf_ue->t3560.pkbuf) {
|
|
|
|
ogs_error("ogs_pkbuf_copy(amf_ue->t3560.pkbuf) failed");
|
2023-01-23 15:17:10 +00:00
|
|
|
ogs_pkbuf_free(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-04 18:12:05 +00:00
|
|
|
ogs_timer_start(amf_ue->t3560.timer,
|
|
|
|
amf_timer_cfg(AMF_TIMER_T3560)->duration);
|
|
|
|
|
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-06-04 18:12:05 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_configuration_update_command(
|
2020-07-09 21:34:41 +00:00
|
|
|
amf_ue_t *amf_ue, gmm_configuration_update_command_param_t *param)
|
2020-06-17 05:22:28 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(amf_ue);
|
|
|
|
|
2021-01-05 04:24:22 +00:00
|
|
|
ogs_info("[%s] Configuration update command", amf_ue->supi);
|
2020-06-17 05:22:28 +00:00
|
|
|
|
|
|
|
if (amf_ue->t3555.pkbuf) {
|
|
|
|
gmmbuf = amf_ue->t3555.pkbuf;
|
2020-07-09 21:34:41 +00:00
|
|
|
|
|
|
|
amf_ue->t3555.pkbuf = ogs_pkbuf_copy(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!amf_ue->t3555.pkbuf) {
|
|
|
|
ogs_error("ogs_pkbuf_copy(amf_ue->t3555.pkbuf) failed");
|
2023-01-23 15:17:10 +00:00
|
|
|
ogs_pkbuf_free(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-07-09 21:34:41 +00:00
|
|
|
ogs_timer_start(amf_ue->t3555.timer,
|
|
|
|
amf_timer_cfg(AMF_TIMER_T3555)->duration);
|
|
|
|
|
2020-06-17 05:22:28 +00:00
|
|
|
} else {
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!param) {
|
|
|
|
ogs_error("No param");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-07-09 21:34:41 +00:00
|
|
|
gmmbuf = gmm_build_configuration_update_command(amf_ue, param);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_configuration_update_command() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-17 05:22:28 +00:00
|
|
|
|
2020-07-09 21:34:41 +00:00
|
|
|
if (param->acknowledgement_requested) {
|
|
|
|
amf_ue->t3555.pkbuf = ogs_pkbuf_copy(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!amf_ue->t3555.pkbuf) {
|
|
|
|
ogs_error("ogs_pkbuf_copy(amf_ue->t3555.pkbuf) failed");
|
2023-01-23 15:17:10 +00:00
|
|
|
ogs_pkbuf_free(gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-07-09 21:34:41 +00:00
|
|
|
ogs_timer_start(amf_ue->t3555.timer,
|
|
|
|
amf_timer_cfg(AMF_TIMER_T3555)->duration);
|
|
|
|
}
|
|
|
|
}
|
2020-06-17 05:22:28 +00:00
|
|
|
|
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-06-17 05:22:28 +00:00
|
|
|
}
|
|
|
|
|
2022-12-04 05:32:19 +00:00
|
|
|
int nas_send_pdu_session_setup_request(amf_sess_t *sess,
|
|
|
|
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
amf_ue_t *amf_ue = NULL;
|
|
|
|
ran_ue_t *ran_ue = NULL;
|
|
|
|
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
ogs_pkbuf_t *ngapbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(sess);
|
|
|
|
amf_ue = amf_ue_cycle(sess->amf_ue);
|
|
|
|
if (!amf_ue) {
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_error("UE(amf-ue) context has already been removed");
|
2022-12-04 05:32:19 +00:00
|
|
|
if (n1smbuf) ogs_pkbuf_free(n1smbuf);
|
|
|
|
ogs_pkbuf_free(n2smbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_NOTFOUND;
|
2022-12-04 05:32:19 +00:00
|
|
|
}
|
|
|
|
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
|
|
|
if (!ran_ue) {
|
|
|
|
ogs_warn("NG context has already been removed");
|
|
|
|
if (n1smbuf) ogs_pkbuf_free(n1smbuf);
|
|
|
|
ogs_pkbuf_free(n2smbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_NOTFOUND;
|
2022-12-04 05:32:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (n1smbuf) {
|
|
|
|
gmmbuf = gmm_build_dl_nas_transport(sess,
|
|
|
|
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0);
|
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_dl_nas_transport() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ran_ue->ue_context_requested == true &&
|
|
|
|
ran_ue->initial_context_setup_request_sent == false) {
|
|
|
|
ngapbuf = ngap_sess_build_initial_context_setup_request(
|
|
|
|
sess, gmmbuf, n2smbuf);
|
|
|
|
if (!ngapbuf) {
|
|
|
|
ogs_error("ngap_sess_build_initial_context_setup_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2022-12-04 05:32:19 +00:00
|
|
|
|
|
|
|
ran_ue->initial_context_setup_request_sent = true;
|
|
|
|
} else {
|
|
|
|
ngapbuf = ngap_sess_build_pdu_session_resource_setup_request(
|
|
|
|
sess, gmmbuf, n2smbuf);
|
|
|
|
if (!ngapbuf) {
|
|
|
|
ogs_error("ngap_sess_build_initial_context_setup_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2022-12-04 05:32:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2021-11-14 12:07:56 +00:00
|
|
|
int nas_send_pdu_session_modification_command(amf_sess_t *sess,
|
|
|
|
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
amf_ue_t *amf_ue = NULL;
|
2022-12-04 05:32:19 +00:00
|
|
|
ran_ue_t *ran_ue = NULL;
|
2021-11-14 12:07:56 +00:00
|
|
|
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
ogs_pkbuf_t *ngapbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(sess);
|
2022-12-04 05:32:19 +00:00
|
|
|
amf_ue = amf_ue_cycle(sess->amf_ue);
|
|
|
|
if (!amf_ue) {
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_error("UE(amf-ue) context has already been removed");
|
2022-12-04 05:32:19 +00:00
|
|
|
if (n1smbuf) ogs_pkbuf_free(n1smbuf);
|
|
|
|
ogs_pkbuf_free(n2smbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_NOTFOUND;
|
2022-12-04 05:32:19 +00:00
|
|
|
}
|
|
|
|
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
|
|
|
if (!ran_ue) {
|
|
|
|
ogs_warn("NG context has already been removed");
|
|
|
|
if (n1smbuf) ogs_pkbuf_free(n1smbuf);
|
|
|
|
ogs_pkbuf_free(n2smbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_NOTFOUND;
|
2022-12-04 05:32:19 +00:00
|
|
|
}
|
2021-11-14 12:07:56 +00:00
|
|
|
|
2022-12-04 05:32:19 +00:00
|
|
|
if (n1smbuf) {
|
|
|
|
gmmbuf = gmm_build_dl_nas_transport(sess,
|
|
|
|
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0);
|
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_dl_nas_transport() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
}
|
2021-11-14 12:07:56 +00:00
|
|
|
|
2022-12-04 05:32:19 +00:00
|
|
|
/*
|
|
|
|
* Issues #1925
|
|
|
|
*
|
|
|
|
* We should not check an activated PSI mask to send DownlinkNASTransport.
|
|
|
|
*
|
|
|
|
* PDUSessionResourceModifyRequest needs to activate QoSFlow with
|
|
|
|
* AddOrModifyQosFlow in the message.
|
|
|
|
*
|
|
|
|
* So, we should always use PDUSessionResourceModifyRequest instead of
|
|
|
|
* send with DownlinkNASTransport.
|
|
|
|
*/
|
2021-11-14 12:07:56 +00:00
|
|
|
ngapbuf = ngap_build_pdu_session_resource_modify_request(
|
|
|
|
sess, gmmbuf, n2smbuf);
|
2022-12-04 05:32:19 +00:00
|
|
|
if (!ngapbuf) {
|
|
|
|
ogs_error("ngap_build_pdu_session_resource_modify_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2021-11-14 12:07:56 +00:00
|
|
|
|
|
|
|
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_send_pdu_session_release_command(amf_sess_t *sess,
|
2020-07-02 05:50:23 +00:00
|
|
|
ogs_pkbuf_t *n1smbuf, ogs_pkbuf_t *n2smbuf)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
amf_ue_t *amf_ue = NULL;
|
2022-12-04 05:32:19 +00:00
|
|
|
ran_ue_t *ran_ue = NULL;
|
2020-07-02 05:50:23 +00:00
|
|
|
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
ogs_pkbuf_t *ngapbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(n2smbuf);
|
2022-12-04 05:32:19 +00:00
|
|
|
ogs_assert(sess);
|
|
|
|
amf_ue = amf_ue_cycle(sess->amf_ue);
|
|
|
|
if (!amf_ue) {
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_error("UE(amf-ue) context has already been removed");
|
2022-12-04 05:32:19 +00:00
|
|
|
if (n1smbuf) ogs_pkbuf_free(n1smbuf);
|
|
|
|
ogs_pkbuf_free(n2smbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_NOTFOUND;
|
2022-12-04 05:32:19 +00:00
|
|
|
}
|
|
|
|
ran_ue = ran_ue_cycle(amf_ue->ran_ue);
|
|
|
|
if (!ran_ue) {
|
|
|
|
ogs_warn("NG context has already been removed");
|
|
|
|
if (n1smbuf) ogs_pkbuf_free(n1smbuf);
|
|
|
|
ogs_pkbuf_free(n2smbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
return OGS_NOTFOUND;
|
2022-12-04 05:32:19 +00:00
|
|
|
}
|
2020-07-02 05:50:23 +00:00
|
|
|
|
2022-12-04 05:32:19 +00:00
|
|
|
if (n1smbuf) {
|
|
|
|
gmmbuf = gmm_build_dl_nas_transport(sess,
|
|
|
|
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, n1smbuf, 0, 0);
|
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_dl_nas_transport() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
}
|
2020-07-02 05:50:23 +00:00
|
|
|
|
2022-12-04 05:32:19 +00:00
|
|
|
/*
|
|
|
|
* Issues #1925
|
|
|
|
*
|
|
|
|
* We should CHECK an activated PSI mask to send DownlinkNASTransport.
|
|
|
|
*
|
|
|
|
* - RAN removed the PDU Session Resource in the following process..
|
|
|
|
* 1. UEContextReleaseRequest
|
|
|
|
* 2. UEContextReleaseCommand
|
|
|
|
* 3. UEContextReleaseComplete.
|
|
|
|
*
|
|
|
|
* - If Service Request has no UpdateDataStatus while waking up UE,
|
|
|
|
* 1. ServiceRequest
|
|
|
|
* 2. InitialContextSetupRequest
|
|
|
|
* 3. InitialContextSetupResponse
|
|
|
|
*
|
|
|
|
* - In this case, we should use the DownlinkNASTransport.
|
|
|
|
* instead of PDUSessionResourceReleaseCommand
|
|
|
|
*/
|
|
|
|
if (ran_ue->psimask.activated & (1 << sess->psi)) {
|
|
|
|
ngapbuf = ngap_build_pdu_session_resource_release_command(
|
|
|
|
sess, gmmbuf, n2smbuf);
|
|
|
|
if (!ngapbuf) {
|
|
|
|
ogs_error(
|
|
|
|
"ngap_build_pdu_session_resource_release_command() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-07-02 05:50:23 +00:00
|
|
|
|
2022-12-04 05:32:19 +00:00
|
|
|
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
} else if (gmmbuf) {
|
2023-01-21 00:02:44 +00:00
|
|
|
ogs_pkbuf_free(n2smbuf);
|
2022-12-04 05:32:19 +00:00
|
|
|
ngapbuf = ngap_build_downlink_nas_transport(
|
|
|
|
ran_ue, gmmbuf, false, false);
|
|
|
|
if (!ngapbuf) {
|
|
|
|
ogs_error("ngap_build_downlink_nas_transport() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
} else {
|
|
|
|
ogs_error("ngap_build_pdu_session_resource_release_command() failed");
|
|
|
|
ogs_error(" ACTIVATED[0x%x] SUPI[%s] PSI[%d]",
|
|
|
|
ran_ue->psimask.activated, amf_ue->supi, sess->psi);
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-07-02 05:50:23 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_gmm_status(amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t cause)
|
2020-06-17 05:22:28 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(amf_ue);
|
|
|
|
|
|
|
|
ogs_debug("[%s] 5GMM status", amf_ue->supi);
|
|
|
|
|
|
|
|
gmmbuf = gmm_build_status(amf_ue, cause);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_status() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-17 05:22:28 +00:00
|
|
|
|
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-06-17 05:22:28 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_gmm_reject(
|
2020-06-17 05:22:28 +00:00
|
|
|
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause)
|
|
|
|
{
|
2021-05-16 03:22:10 +00:00
|
|
|
int rv;
|
2020-06-17 05:22:28 +00:00
|
|
|
ogs_assert(amf_ue);
|
|
|
|
|
|
|
|
switch(amf_ue->nas.message_type) {
|
|
|
|
case OGS_NAS_5GS_REGISTRATION_REQUEST:
|
2021-05-16 03:22:10 +00:00
|
|
|
rv = nas_5gs_send_registration_reject(amf_ue, gmm_cause);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2020-06-17 05:22:28 +00:00
|
|
|
break;
|
2020-06-22 03:07:14 +00:00
|
|
|
case OGS_NAS_5GS_SERVICE_REQUEST:
|
2021-05-16 03:22:10 +00:00
|
|
|
rv = nas_5gs_send_service_reject(amf_ue, gmm_cause);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2020-06-17 05:22:28 +00:00
|
|
|
break;
|
2020-06-22 03:07:14 +00:00
|
|
|
default:
|
|
|
|
ogs_error("Unknown message type [%d]", amf_ue->nas.message_type);
|
2021-05-16 03:22:10 +00:00
|
|
|
rv = OGS_ERROR;
|
2020-06-17 05:22:28 +00:00
|
|
|
}
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-06-17 05:22:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static ogs_nas_5gmm_cause_t gmm_cause_from_sbi(int status)
|
|
|
|
{
|
|
|
|
ogs_nas_5gmm_cause_t gmm_cause;
|
|
|
|
|
|
|
|
switch(status) {
|
|
|
|
case OGS_SBI_HTTP_STATUS_NOT_FOUND:
|
2021-12-08 12:05:16 +00:00
|
|
|
gmm_cause = OGS_5GMM_CAUSE_PLMN_NOT_ALLOWED;
|
2020-06-17 05:22:28 +00:00
|
|
|
break;
|
|
|
|
case OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT:
|
|
|
|
gmm_cause = OGS_5GMM_CAUSE_PAYLOAD_WAS_NOT_FORWARDED;
|
|
|
|
break;
|
|
|
|
case OGS_SBI_HTTP_STATUS_BAD_REQUEST:
|
|
|
|
gmm_cause = OGS_5GMM_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE;
|
|
|
|
break;
|
|
|
|
case OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR:
|
|
|
|
gmm_cause =
|
|
|
|
OGS_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
gmm_cause = OGS_5GMM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return gmm_cause;
|
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int nas_5gs_send_gmm_reject_from_sbi(amf_ue_t *amf_ue, int status)
|
2020-06-17 05:22:28 +00:00
|
|
|
{
|
2021-05-16 03:22:10 +00:00
|
|
|
int rv;
|
|
|
|
|
2020-06-17 05:22:28 +00:00
|
|
|
ogs_assert(amf_ue);
|
2021-05-16 03:22:10 +00:00
|
|
|
rv = nas_5gs_send_gmm_reject(amf_ue, gmm_cause_from_sbi(status));
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
return rv;
|
2020-06-17 05:22:28 +00:00
|
|
|
}
|
|
|
|
|
2021-08-14 03:01:13 +00:00
|
|
|
int nas_5gs_send_dl_nas_transport(amf_sess_t *sess,
|
2020-06-17 05:22:28 +00:00
|
|
|
uint8_t payload_container_type, ogs_pkbuf_t *payload_container,
|
|
|
|
ogs_nas_5gmm_cause_t cause, uint8_t backoff_time)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
ogs_pkbuf_t *gmmbuf = NULL;
|
|
|
|
amf_ue_t *amf_ue = NULL;
|
|
|
|
|
|
|
|
ogs_assert(sess);
|
|
|
|
amf_ue = sess->amf_ue;
|
|
|
|
ogs_assert(amf_ue);
|
|
|
|
|
|
|
|
ogs_assert(payload_container_type);
|
|
|
|
ogs_assert(payload_container);
|
|
|
|
|
2021-08-14 03:01:13 +00:00
|
|
|
ogs_warn("[%s] DL NAS transport", amf_ue->suci);
|
2020-06-17 05:22:28 +00:00
|
|
|
|
|
|
|
gmmbuf = gmm_build_dl_nas_transport(sess,
|
|
|
|
payload_container_type, payload_container, cause, backoff_time);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!gmmbuf) {
|
|
|
|
ogs_error("gmm_build_dl_nas_transport() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-17 05:22:28 +00:00
|
|
|
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
|
2023-01-23 01:37:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2020-06-17 05:22:28 +00:00
|
|
|
}
|
|
|
|
|
2021-08-14 03:01:13 +00:00
|
|
|
/*
|
|
|
|
* TS24.501
|
|
|
|
* 8.2.11 DL NAS transport
|
|
|
|
* 8.2.11.4 5GMM cause
|
|
|
|
*
|
|
|
|
* The AMF shall include this IE when the Payload container IE
|
|
|
|
* contains an uplink payload which was not forwarded and
|
|
|
|
* the Payload container type IE is not set to "Multiple payloads".
|
|
|
|
*
|
|
|
|
* -0-
|
|
|
|
* As such, this function 'nas_5gs_send_gsm_reject()' must be used
|
|
|
|
* only when an N1 SM message has been forwarded to the SMF.
|
|
|
|
*/
|
|
|
|
int nas_5gs_send_gsm_reject(amf_sess_t *sess,
|
|
|
|
uint8_t payload_container_type, ogs_pkbuf_t *payload_container)
|
2020-06-17 05:22:28 +00:00
|
|
|
{
|
2021-05-16 03:22:10 +00:00
|
|
|
int rv;
|
|
|
|
|
2020-06-17 05:22:28 +00:00
|
|
|
ogs_assert(sess);
|
|
|
|
ogs_assert(payload_container_type);
|
|
|
|
ogs_assert(payload_container);
|
|
|
|
|
2021-08-14 03:01:13 +00:00
|
|
|
rv = nas_5gs_send_dl_nas_transport(
|
|
|
|
sess, payload_container_type, payload_container, 0, 0);
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
return rv;
|
2020-06-17 05:22:28 +00:00
|
|
|
}
|
|
|
|
|
2021-08-14 03:01:13 +00:00
|
|
|
int nas_5gs_send_back_gsm_message(
|
|
|
|
amf_sess_t *sess, ogs_nas_5gmm_cause_t cause, uint8_t backoff_time)
|
2020-06-17 05:22:28 +00:00
|
|
|
{
|
2021-05-16 03:22:10 +00:00
|
|
|
int rv;
|
2020-06-17 05:22:28 +00:00
|
|
|
ogs_pkbuf_t *pbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(sess);
|
|
|
|
ogs_assert(sess->payload_container_type);
|
|
|
|
ogs_assert(sess->payload_container);
|
|
|
|
|
|
|
|
pbuf = ogs_pkbuf_copy(sess->payload_container);
|
2023-01-23 01:37:22 +00:00
|
|
|
if (!pbuf) {
|
|
|
|
ogs_error("ogs_pkbuf_copy(pbuf) failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-06-17 05:22:28 +00:00
|
|
|
|
2023-01-23 01:37:22 +00:00
|
|
|
rv = nas_5gs_send_dl_nas_transport(
|
|
|
|
sess, sess->payload_container_type, pbuf, cause, backoff_time);
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
return rv;
|
2021-06-06 13:35:46 +00:00
|
|
|
}
|