Bug fixed for 5G core

This commit is contained in:
Sukchan Lee 2020-06-25 00:37:29 -04:00
parent d652075ab9
commit 6e84ac670d
44 changed files with 1750 additions and 1281 deletions

View File

@ -20,7 +20,7 @@
/*******************************************************************************
* This file had been created by gtp-tlv.py script v0.1.0
* Please do not modify this file but regenerate it via script.
* Created on: 2020-03-25 15:39:06.344431 by acetcom
* Created on: 2020-06-25 00:24:05.837938 by acetcom
* from 29274-d80.docx
******************************************************************************/

View File

@ -20,7 +20,7 @@
/*******************************************************************************
* This file had been created by gtp-tlv.py script v0.1.0
* Please do not modify this file but regenerate it via script.
* Created on: 2020-03-25 15:39:06.337683 by acetcom
* Created on: 2020-06-25 00:24:05.831453 by acetcom
* from 29274-d80.docx
******************************************************************************/

View File

@ -28,6 +28,36 @@
extern "C" {
#endif
#define OGS_5GS_GTP_HEADER_LEN 16
typedef struct ogs_5gs_gtp_header_s {
union {
struct {
ED6(uint8_t version:3;,
uint8_t protocol_type:1;,
uint8_t reserved:1;,
uint8_t next_extension:1;,
uint8_t seqence_number:1;,
uint8_t n_pdu_number:1;)
};
uint8_t flags;
};
uint8_t type;
uint16_t length;
uint32_t teid;
struct {
#define OGS_GTP_EXTENSION_HEADER_TYPE_PDU_SESSION_CONTAINER 0x85
#define OGS_GTP_EXTENSION_HEADER_TYPE_NO_MORE_EXTENSION_HEADERS 0x0
uint32_t type;
uint8_t len;
#define OGS_GTP_EXTENSION_HEADER_PDU_TYPE_UL_PDU_SESSION_INFORMATION 1
ED2(uint8_t pdu_type:4;,
uint8_t spare1:4;);
ED2(uint8_t spare2:2;,
uint8_t qos_flow_identifier:6;);
uint8_t next_type;
} extension_header;
} __attribute__ ((packed)) ogs_5gs_gtp_header_t;
/* 8.4 Cause */
#define OGS_GTP_CAUSE_LOCAL_DETACH 2
#define OGS_GTP_CAUSE_COMPLETE_DETACH_3

View File

@ -284,6 +284,12 @@ static connection_t *connection_add(ogs_sbi_client_t *client,
CURLOPT_POSTFIELDS, request->http.content);
curl_easy_setopt(conn->easy,
CURLOPT_POSTFIELDSIZE, request->http.content_length);
#if 1 /* Disable HTTP/1.1 100 Continue : Use "Expect:" in libcurl */
conn->header_list = curl_slist_append(
conn->header_list, "Expect:");
#else
curl_easy_setopt(conn->easy, CURLOPT_EXPECT_100_TIMEOUT_MS, 0L);
#endif
}
}

View File

@ -1,64 +0,0 @@
/*
* 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 "amf-path.h"
void amf_send_delete_session_or_de_register(amf_ue_t *amf_ue)
{
ogs_assert(amf_ue);
if (SESSION_CONTEXT_IS_AVAILABLE(amf_ue)) {
amf_sbi_send_release_all_sm_contexts(amf_ue);
} else {
nas_5gs_send_de_registration_accept(amf_ue);
}
}
void amf_send_delete_session_or_amf_ue_context_release(amf_ue_t *amf_ue)
{
ogs_assert(amf_ue);
if (SESSION_CONTEXT_IS_AVAILABLE(amf_ue)) {
amf_sbi_send_release_all_sm_contexts(amf_ue);
} else {
ran_ue_t *ran_ue = amf_ue->ran_ue;
if (ran_ue) {
ngap_send_ue_context_release_command(ran_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
} else {
ogs_warn("No NG Context");
}
}
}
void amf_send_delete_session_or_ran_ue_context_release(ran_ue_t *ran_ue)
{
amf_ue_t *amf_ue = NULL;
ogs_assert(ran_ue);
amf_ue = ran_ue->amf_ue;
if (amf_ue && SESSION_CONTEXT_IS_AVAILABLE(amf_ue)) {
amf_sbi_send_release_all_sm_contexts(amf_ue);
} else {
ngap_send_ue_context_release_command(ran_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0);
}
}

View File

@ -1,39 +0,0 @@
/*
* 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/>.
*/
#ifndef AMF_PATH_H
#define AMF_PATH_H
#include "sbi-path.h"
#include "nas-path.h"
#include "ngap-path.h"
#ifdef __cplusplus
extern "C" {
#endif
void amf_send_delete_session_or_de_register(amf_ue_t *amf_ue);
void amf_send_delete_session_or_amf_ue_context_release(amf_ue_t *amf_ue);
void amf_send_delete_session_or_ran_ue_context_release(ran_ue_t *ran_ue);
#ifdef __cplusplus
}
#endif
#endif /* AMF_PATH_H */

View File

@ -20,7 +20,6 @@
#include "sbi-path.h"
#include "ngap-path.h"
#include "nas-path.h"
#include "amf-path.h"
#include "nnrf-handler.h"
#include "namf-handler.h"
#include "nsmf-handler.h"
@ -371,9 +370,6 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_timer_stop(amf_ue->sbi.client_wait.timer);
ogs_fsm_dispatch(&amf_ue->sm, e);
if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_exception)) {
amf_send_delete_session_or_amf_ue_context_release(amf_ue);
}
break;
CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
@ -391,16 +387,19 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
ogs_timer_stop(sess->sbi.client_wait.timer);
SWITCH(sbi_message.h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
amf_nsmf_pdu_session_handle_update_sm_context(
sess, &sbi_message);
break;
CASE(OGS_SBI_RESOURCE_NAME_RELEASE)
amf_nsmf_pdu_session_handle_release_sm_context(
sess, &sbi_message);
break;
DEFAULT
ogs_fsm_dispatch(&amf_ue->sm, e);
if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_exception)) {
amf_send_delete_session_or_amf_ue_context_release(amf_ue);
}
amf_nsmf_pdu_session_handle_create_sm_context(
sess, &sbi_message);
END
break;
@ -650,9 +649,6 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e)
e->nas.message = &nas_message;
ogs_fsm_dispatch(&amf_ue->sm, e);
if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_exception)) {
amf_send_delete_session_or_amf_ue_context_release(amf_ue);
}
ogs_pkbuf_free(pkbuf);
break;

View File

@ -1386,16 +1386,6 @@ void amf_ue_set_supi(amf_ue_t *amf_ue, char *supi)
ogs_hash_set(self.supi_hash, amf_ue->supi, strlen(amf_ue->supi), amf_ue);
}
bool amf_ue_activation_synched(amf_ue_t *amf_ue)
{
amf_sess_t *sess = NULL;
ogs_list_for_each(&amf_ue->sess_list, sess)
if (sess->ueUpCnxState != sess->smfUpCnxState) return false;
return true;
}
void amf_ue_associate_ran_ue(amf_ue_t *amf_ue, ran_ue_t *ran_ue)
{
ogs_assert(amf_ue);
@ -1524,6 +1514,16 @@ amf_sess_t *amf_sess_find_by_psi(amf_ue_t *amf_ue, uint8_t psi)
return NULL;
}
bool amf_sess_sync_done(amf_ue_t *amf_ue)
{
amf_sess_t *sess = NULL;
ogs_list_for_each(&amf_ue->sess_list, sess)
if (sess->sbi.running) return false;
return true;
}
int amf_find_served_tai(ogs_5gs_tai_t *tai)
{
int i = 0, j = 0, k = 0;

View File

@ -220,6 +220,9 @@ struct amf_ue_s {
uint8_t message_type; /* Type of last specific NAS message received */
int access_type; /* 3GPP or Non-3GPP */
/* InitialUEMessage or UplinkNASTrasnport */
NGAP_ProcedureCode_t ngapProcedureCode;
union {
struct {
ED3(uint8_t tsc:1;,
@ -232,6 +235,13 @@ struct amf_ue_s {
uint8_t data;
};
struct {
ED4(uint8_t uplink_data_status:1;,
uint8_t pdu_session_status:1;,
uint8_t allowed_pdu_session_status:1;,
uint8_t reserved:5;)
} present;
} __attribute__ ((packed)) nas;
/* UE identity */
@ -380,12 +390,8 @@ typedef struct amf_sess_s {
char *sm_context_ref; /* smContextRef from SMF */
#define SESSION_CONTEXT_IS_AVAILABLE(__aMF) \
((__aMF) && (ogs_list_first((&(__aMF)->sess_list))) && \
(((amf_sess_t *)ogs_list_first((&(__aMF)->sess_list)))->sm_context_ref))
#define SESSION_UP_CNX_STATE_SYNCHED(__aMF) \
(amf_ue_activation_synched(__aMF) == true)
#define SESSION_SYNC_DONE(__aMF) \
(amf_sess_sync_done(__aMF) == true)
/* UE session context is activated or not */
OpenAPI_up_cnx_state_e ueUpCnxState;
@ -457,8 +463,6 @@ void amf_ue_set_suci(amf_ue_t *amf_ue,
ogs_nas_5gs_mobile_identity_t *mobile_identity);
void amf_ue_set_supi(amf_ue_t *amf_ue, char *supi);
bool amf_ue_activation_synched(amf_ue_t *amf_ue);
int amf_ue_have_indirect_tunnel(amf_ue_t *amf_ue);
int amf_ue_clear_indirect_tunnel(amf_ue_t *amf_ue);
@ -522,6 +526,8 @@ void amf_sess_remove_all(amf_ue_t *amf_ue);
amf_sess_t *amf_sess_find_by_psi(amf_ue_t *amf_ue, uint8_t psi);
amf_sess_t *amf_sess_find_by_dnn(amf_ue_t *amf_ue, char *dnn);
bool amf_sess_sync_done(amf_ue_t *amf_ue);
int amf_find_served_tai(ogs_5gs_tai_t *tai);
ogs_s_nssai_t *amf_find_s_nssai(
ogs_plmn_id_t *served_plmn_id, ogs_s_nssai_t *s_nssai);

View File

@ -24,10 +24,10 @@
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __gmm_log_domain
static uint16_t get_pdu_session_status(amf_ue_t *amf_ue, bool reactivation);
static uint16_t get_pdu_session_status(amf_ue_t *amf_ue);
static uint16_t get_pdu_session_reactivation_result(amf_ue_t *amf_ue);
ogs_pkbuf_t *gmm_build_registration_accept(
amf_ue_t *amf_ue, bool reactivation_result)
ogs_pkbuf_t *gmm_build_registration_accept(amf_ue_t *amf_ue)
{
int i;
int served_tai_index = 0;
@ -44,6 +44,8 @@ ogs_pkbuf_t *gmm_build_registration_accept(
ogs_nas_nssai_t *allowed_nssai = &registration_accept->allowed_nssai;
ogs_nas_5gs_network_feature_support_t *network_feature_support =
&registration_accept->network_feature_support;
ogs_nas_pdu_session_status_t *pdu_session_status =
&registration_accept->pdu_session_status;
ogs_nas_pdu_session_reactivation_result_t *pdu_session_reactivation_result =
&registration_accept->pdu_session_reactivation_result;
ogs_nas_gprs_timer_3_t *t3512_value = &registration_accept->t3512_value;
@ -139,12 +141,23 @@ ogs_pkbuf_t *gmm_build_registration_accept(
registration_accept->t3502_value.value = 12;
#endif
if (reactivation_result) {
if (amf_ue->nas.present.pdu_session_status) {
registration_accept->presencemask |=
OGS_NAS_5GS_REGISTRATION_ACCEPT_PDU_SESSION_STATUS_PRESENT;
pdu_session_status->length = 2;
pdu_session_status->psi = get_pdu_session_status(amf_ue);
ogs_debug("[%s] PDU Session Status : %04x",
amf_ue->supi, pdu_session_status->psi);
}
if (amf_ue->nas.present.uplink_data_status) {
registration_accept->presencemask |=
OGS_NAS_5GS_REGISTRATION_ACCEPT_PDU_SESSION_REACTIVATION_RESULT_PRESENT;
pdu_session_reactivation_result->length = 2;
pdu_session_reactivation_result->psi =
get_pdu_session_status(amf_ue, true);
get_pdu_session_reactivation_result(amf_ue);
ogs_debug("[%s] PDU Session Reactivation Result : %04x",
amf_ue->supi, pdu_session_reactivation_result->psi);
}
pkbuf = nas_5gs_security_encode(amf_ue, &message);
@ -168,6 +181,108 @@ ogs_pkbuf_t *gmm_build_registration_reject(ogs_nas_5gmm_cause_t gmm_cause)
return ogs_nas_5gs_plain_encode(&message);
}
ogs_pkbuf_t *gmm_build_service_accept(amf_ue_t *amf_ue)
{
ogs_nas_5gs_message_t message;
ogs_nas_5gs_service_accept_t *service_accept = &message.gmm.service_accept;
ogs_nas_pdu_session_status_t *pdu_session_status = NULL;
ogs_nas_pdu_session_reactivation_result_t *pdu_session_reactivation_result;
ogs_assert(amf_ue);
pdu_session_status = &service_accept->pdu_session_status;
ogs_assert(pdu_session_status);
pdu_session_reactivation_result = &service_accept->
pdu_session_reactivation_result;
ogs_assert(pdu_session_reactivation_result);
ogs_debug("[%s] Service accept", amf_ue->supi);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_SERVICE_ACCEPT;
if (amf_ue->nas.present.pdu_session_status) {
service_accept->presencemask |=
OGS_NAS_5GS_SERVICE_ACCEPT_PDU_SESSION_STATUS_PRESENT;
pdu_session_status->length = 2;
pdu_session_status->psi = get_pdu_session_status(amf_ue);
ogs_debug("[%s] PDU Session Status : %04x",
amf_ue->supi, pdu_session_status->psi);
}
if (amf_ue->nas.present.uplink_data_status) {
service_accept->presencemask |=
OGS_NAS_5GS_SERVICE_ACCEPT_PDU_SESSION_REACTIVATION_RESULT_PRESENT;
pdu_session_reactivation_result->length = 2;
pdu_session_reactivation_result->psi =
get_pdu_session_reactivation_result(amf_ue);
ogs_debug("[%s] PDU Session Reactivation Result : %04x",
amf_ue->supi, pdu_session_reactivation_result->psi);
}
return nas_5gs_security_encode(amf_ue, &message);
}
ogs_pkbuf_t *gmm_build_service_reject(
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause)
{
ogs_nas_5gs_message_t message;
ogs_nas_5gs_service_reject_t *service_reject = &message.gmm.service_reject;
ogs_nas_pdu_session_status_t *pdu_session_status = NULL;
ogs_assert(amf_ue);
pdu_session_status = &service_reject->pdu_session_status;
ogs_debug("Service reject");
memset(&message, 0, sizeof(message));
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_SERVICE_REJECT;
service_reject->gmm_cause = gmm_cause;
if (amf_ue->nas.present.pdu_session_status) {
service_reject->presencemask |=
OGS_NAS_5GS_SERVICE_REJECT_PDU_SESSION_STATUS_PRESENT;
pdu_session_status->length = 2;
pdu_session_status->psi = get_pdu_session_status(amf_ue);
ogs_debug("[%s] PDU Session Status : %04x",
amf_ue->supi, pdu_session_status->psi);
}
return ogs_nas_5gs_plain_encode(&message);
}
ogs_pkbuf_t *gmm_build_de_registration_accept(amf_ue_t *amf_ue)
{
ogs_nas_5gs_message_t message;
ogs_assert(amf_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
ogs_debug("[%s] De-registration accept", amf_ue->supi);
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_DEREGISTRATION_ACCEPT;
return nas_5gs_security_encode(amf_ue, &message);
}
ogs_pkbuf_t *gmm_build_identity_request(amf_ue_t *amf_ue)
{
ogs_nas_5gs_message_t message;
@ -489,94 +604,6 @@ ogs_pkbuf_t *gmm_build_dl_nas_transport(amf_sess_t *sess,
return gmmbuf;
}
ogs_pkbuf_t *gmm_build_service_accept(
amf_ue_t *amf_ue, bool reactivation_result)
{
ogs_nas_5gs_message_t message;
ogs_nas_5gs_service_accept_t *service_accept = &message.gmm.service_accept;
ogs_nas_pdu_session_reactivation_result_t *pdu_session_reactivation_result;
ogs_assert(amf_ue);
pdu_session_reactivation_result = &service_accept->
pdu_session_reactivation_result;
ogs_assert(pdu_session_reactivation_result);
ogs_debug("[%s] Service accept", amf_ue->supi);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_SERVICE_ACCEPT;
if (reactivation_result) {
service_accept->presencemask |=
OGS_NAS_5GS_SERVICE_ACCEPT_PDU_SESSION_REACTIVATION_RESULT_PRESENT;
pdu_session_reactivation_result->length = 2;
pdu_session_reactivation_result->psi =
get_pdu_session_status(amf_ue, true);
}
return nas_5gs_security_encode(amf_ue, &message);
}
ogs_pkbuf_t *gmm_build_service_reject(amf_ue_t *amf_ue,
ogs_nas_5gmm_cause_t gmm_cause, bool pdu_session_status_present)
{
ogs_nas_5gs_message_t message;
ogs_nas_5gs_service_reject_t *service_reject = &message.gmm.service_reject;
ogs_nas_pdu_session_status_t *pdu_session_status = NULL;
ogs_assert(amf_ue);
pdu_session_status = &service_reject->pdu_session_status;
ogs_debug("Service reject");
memset(&message, 0, sizeof(message));
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_SERVICE_REJECT;
service_reject->gmm_cause = gmm_cause;
if (pdu_session_status_present) {
service_reject->presencemask |=
OGS_NAS_5GS_SERVICE_REJECT_PDU_SESSION_STATUS_PRESENT;
pdu_session_status->length = 2;
pdu_session_status->psi = get_pdu_session_status(amf_ue, false);
}
return ogs_nas_5gs_plain_encode(&message);
}
ogs_pkbuf_t *gmm_build_de_registration_accept(amf_ue_t *amf_ue)
{
ogs_nas_5gs_message_t message;
ogs_assert(amf_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
ogs_debug("[%s] De-registration accept", amf_ue->supi);
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_DEREGISTRATION_ACCEPT;
return nas_5gs_security_encode(amf_ue, &message);
}
#if 0
ogs_pkbuf_t *gmm_build_tau_accept(amf_ue_t *amf_ue)
{
@ -780,7 +807,7 @@ ogs_pkbuf_t *gmm_build_status(amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t cause)
return nas_5gs_security_encode(amf_ue, &message);
}
static uint16_t get_pdu_session_status(amf_ue_t *amf_ue, bool reactivation)
static uint16_t get_pdu_session_status(amf_ue_t *amf_ue)
{
amf_sess_t *sess = NULL;
@ -790,13 +817,27 @@ static uint16_t get_pdu_session_status(amf_ue_t *amf_ue, bool reactivation)
ogs_assert(amf_ue);
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (reactivation) {
if (sess->smfUpCnxState != OpenAPI_up_cnx_state_ACTIVATING)
psimask |= (1 << sess->psi);
} else {
if (sess->smfUpCnxState == OpenAPI_up_cnx_state_ACTIVATING)
psimask |= (1 << sess->psi);
}
psimask |= (1 << sess->psi);
}
status |= (psimask << 8);
status |= (psimask >> 8);
return status;
}
static uint16_t get_pdu_session_reactivation_result(amf_ue_t *amf_ue)
{
amf_sess_t *sess = NULL;
uint16_t psimask = 0;
uint16_t status = 0;
ogs_assert(amf_ue);
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED)
psimask |= (1 << sess->psi);
}
status |= (psimask << 8);

View File

@ -26,10 +26,15 @@
extern "C" {
#endif
ogs_pkbuf_t *gmm_build_registration_accept(
amf_ue_t *amf_ue, bool reactivation_result);
ogs_pkbuf_t *gmm_build_registration_accept(amf_ue_t *amf_ue);
ogs_pkbuf_t *gmm_build_registration_reject(ogs_nas_5gmm_cause_t gmm_cause);
ogs_pkbuf_t *gmm_build_service_accept(amf_ue_t *amf_ue);
ogs_pkbuf_t *gmm_build_service_reject(
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause);
ogs_pkbuf_t *gmm_build_de_registration_accept(amf_ue_t *amf_ue);
ogs_pkbuf_t *gmm_build_identity_request(amf_ue_t *amf_ue);
ogs_pkbuf_t *gmm_build_security_mode_command(amf_ue_t *amf_ue);
@ -43,14 +48,6 @@ ogs_pkbuf_t *gmm_build_dl_nas_transport(amf_sess_t *sess,
uint8_t payload_container_type, ogs_pkbuf_t *payload,
ogs_nas_5gmm_cause_t cause, uint8_t backoff_time);
ogs_pkbuf_t *gmm_build_service_accept(
amf_ue_t *amf_ue, bool reactivation_result);
ogs_pkbuf_t *gmm_build_service_reject(amf_ue_t *amf_ue,
ogs_nas_5gmm_cause_t gmm_cause, bool pdu_session_status_present);
ogs_pkbuf_t *gmm_build_de_registration_accept(amf_ue_t *amf_ue);
ogs_pkbuf_t *gmm_build_tau_accept(amf_ue_t *amf_ue);
ogs_pkbuf_t *gmm_build_tau_reject(
ogs_nas_5gmm_cause_t gmm_cause, amf_ue_t *amf_ue);

View File

@ -21,7 +21,6 @@
#include "ngap-path.h"
#include "nas-path.h"
#include "amf-path.h"
#include "sbi-path.h"
#include "gmm-handler.h"
@ -57,6 +56,8 @@ int gmm_handle_registration_request(amf_ue_t *amf_ue,
ue_security_capability = &registration_request->ue_security_capability;
ogs_assert(ue_security_capability);
ogs_debug("Registration request");
if (!mobile_identity->length || !mobile_identity->buffer) {
ogs_error("No Mobile Identity");
nas_5gs_send_registration_reject(amf_ue,
@ -203,9 +204,7 @@ int gmm_handle_registration_update(amf_ue_t *amf_ue,
ogs_nas_5gs_registration_request_t *registration_request)
{
amf_sess_t *sess = NULL;
bool handled = false;
amf_nsmf_pdu_session_update_sm_context_param_t param;
uint16_t psimask;
ogs_nas_5gs_tracking_area_identity_t *last_visited_registered_tai = NULL;
ogs_nas_uplink_data_status_t *uplink_data_status = NULL;
@ -222,6 +221,14 @@ int gmm_handle_registration_update(amf_ue_t *amf_ue,
pdu_session_status = &registration_request->pdu_session_status;
ogs_assert(pdu_session_status);
if (registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT) {
return gmm_handle_nas_message_container(
amf_ue, &registration_request->nas_message_container);
}
if (registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_LAST_VISITED_REGISTERED_TAI_PRESENT) {
@ -244,88 +251,226 @@ int gmm_handle_registration_update(amf_ue_t *amf_ue,
sizeof(registration_request->ue_usage_setting.length));
}
handled = false;
if ((registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT) == 0) {
amf_ue->nas.present.allowed_pdu_session_status = 0;
} else {
amf_ue->nas.present.allowed_pdu_session_status = 1;
ogs_error("Not implemented for Allowed PDU Session Status IE");
}
if (registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_UPLINK_DATA_STATUS_PRESENT) {
if ((registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_UPLINK_DATA_STATUS_PRESENT) == 0) {
amf_ue->nas.present.uplink_data_status = 0;
} else {
amf_ue->nas.present.uplink_data_status = 1;
uint16_t psimask = 0;
psimask = 0;
psimask |= uplink_data_status->psi << 8;
psimask |= uplink_data_status->psi >> 8;
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (psimask & (1 << sess->psi)) {
if (sess->smfUpCnxState == OpenAPI_up_cnx_state_ACTIVATED) {
/* Nothing */
} else if (sess->smfUpCnxState ==
OpenAPI_up_cnx_state_ACTIVATING) {
handled = true;
} else if (sess->smfUpCnxState ==
OpenAPI_up_cnx_state_DEACTIVATED) {
/* UPDATE_UpCnxState - ACTIVATING */
sess->ueUpCnxState = OpenAPI_up_cnx_state_ACTIVATING;
memset(&param, 0, sizeof(param));
param.upCnxState = sess->ueUpCnxState;
amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_SMF, sess, &param,
amf_nsmf_pdu_session_build_update_sm_context);
handled = true;
}
if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED)
amf_sbi_send_activating_session(sess);
}
}
}
if (!handled) {
nas_5gs_send_registration_accept(amf_ue, true);
return OGS_OK;
}
if ((registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_PDU_SESSION_STATUS_PRESENT) == 0) {
amf_ue->nas.present.pdu_session_status = 0;
} else {
amf_ue->nas.present.pdu_session_status = 1;
} else if (registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_PDU_SESSION_STATUS_PRESENT) {
uint16_t psimask = 0;
psimask = 0;
psimask |= pdu_session_status->psi << 8;
psimask |= pdu_session_status->psi >> 8;
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (psimask & (1 << sess->psi)) {
if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED) {
/* UPDATE_UpCnxState - ACTIVATING */
sess->ueUpCnxState = OpenAPI_up_cnx_state_ACTIVATING;
memset(&param, 0, sizeof(param));
param.upCnxState = sess->ueUpCnxState;
amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_SMF, sess, &param,
amf_nsmf_pdu_session_build_update_sm_context);
handled = true;
} else {
ogs_error("Not implemented "
"for AMF active in PDU Session Status IE");
nas_5gs_send_registration_reject(amf_ue,
OGS_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
return OGS_ERROR;
}
if ((psimask & (1 << sess->psi)) == 0) {
amf_sbi_send_release_session(sess);
}
}
if (!handled) {
nas_5gs_send_registration_accept(amf_ue, false);
return OGS_OK;
}
} else if (registration_request->presencemask &
OGS_NAS_5GS_REGISTRATION_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT) {
ogs_error("Not implemented Allowed PDU Session Status IE");
nas_5gs_send_registration_reject(amf_ue,
OGS_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
return OGS_ERROR;
}
if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_registered)) {
if (SESSION_SYNC_DONE(amf_ue))
nas_5gs_send_registration_accept(amf_ue);
}
return OGS_OK;
}
int gmm_handle_service_request(amf_ue_t *amf_ue,
ogs_nas_5gs_service_request_t *service_request)
{
ogs_nas_key_set_identifier_t *ngksi = NULL;
ogs_assert(amf_ue);
ngksi = &service_request->ngksi;
ogs_assert(ngksi);
ogs_debug("Service request");
amf_ue->nas.message_type = OGS_NAS_5GS_SERVICE_REQUEST;
amf_ue->nas.tsc = ngksi->tsc;
amf_ue->nas.ksi = ngksi->value;
ogs_debug(" OGS_NAS_5GS TYPE[%d] TSC[%d] KSI[%d] SERVICE[0x%x]",
amf_ue->nas.message_type,
amf_ue->nas.tsc, amf_ue->nas.ksi, amf_ue->nas.data);
/*
* REGISTRATION_REQUEST
* Clear EBI generator
* Clear Timer and Message
*
* TAU_REQUEST
* Clear Timer and Message
*
* SERVICE_REQUEST
* Clear Timer and Message
*
* EXTENDED_SERVICE_REQUEST
* Clear Timer and Message
*/
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
if (SECURITY_CONTEXT_IS_VALID(amf_ue)) {
ogs_kdf_kgnb_and_kn3iwf(
amf_ue->kamf, amf_ue->ul_count.i32,
amf_ue->nas.access_type, amf_ue->kgnb);
ogs_kdf_nh_gnb(amf_ue->kamf, amf_ue->kgnb, amf_ue->nh);
amf_ue->nhcc = 1;
}
ogs_debug("[%s] 5G-S_GUTI[AMF_ID:0x%x,M_TMSI:0x%x]",
AMF_UE_HAVE_SUCI(amf_ue) ? amf_ue->suci : "Unknown ID",
ogs_amf_id_hexdump(&amf_ue->guti.amf_id), amf_ue->guti.m_tmsi);
return OGS_OK;
}
int gmm_handle_service_update(amf_ue_t *amf_ue,
ogs_nas_5gs_service_request_t *service_request)
{
amf_sess_t *sess = NULL;
uint16_t psimask = 0;
ogs_nas_uplink_data_status_t *uplink_data_status = NULL;
ogs_nas_pdu_session_status_t *pdu_session_status = NULL;
ogs_nas_allowed_pdu_session_status_t *allowed_pdu_session_status = NULL;
ogs_assert(amf_ue);
uplink_data_status = &service_request->uplink_data_status;
ogs_assert(uplink_data_status);
pdu_session_status = &service_request->pdu_session_status;
ogs_assert(pdu_session_status);
allowed_pdu_session_status = &service_request->allowed_pdu_session_status;
ogs_assert(allowed_pdu_session_status);
if (service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT) {
return gmm_handle_nas_message_container(
amf_ue, &service_request->nas_message_container);
}
if ((service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT) == 0) {
amf_ue->nas.present.allowed_pdu_session_status = 0;
} else {
amf_ue->nas.present.allowed_pdu_session_status = 1;
ogs_error("Not implemented for Allowed PDU Session Status IE");
}
if ((service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_UPLINK_DATA_STATUS_PRESENT) == 0) {
amf_ue->nas.present.uplink_data_status = 0;
} else {
amf_ue->nas.present.uplink_data_status = 1;
psimask = 0;
psimask |= uplink_data_status->psi << 8;
psimask |= uplink_data_status->psi >> 8;
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (psimask & (1 << sess->psi)) {
if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED)
amf_sbi_send_activating_session(sess);
}
}
}
/*
* TS24.501
* 5.6.1.5 Service request procedure not accepted by the network
*
* If the AMF needs to initiate PDU session status synchronisation
* or a PDU session status IE was included in the SERVICE REQUEST message,
* the AMF shall include a PDU session status IE in the SERVICE REJECT
* message to indicate which PDU sessions associated with the access type
* the SERVICE REJECT message is sent over are active in the AMF.
* If the PDU session status IE is included in the SERVICE REJECT message
* and if the message is integrity protected, then the UE shall perform
* a local release of all those PDU sessions which are active
* on the UE side associated with the access type the SERVICE REJECT
* message is sent over, but are indicated by the AMF as being inactive.
*/
if ((service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_PDU_SESSION_STATUS_PRESENT) == 0) {
amf_ue->nas.present.pdu_session_status = 0;
} else {
amf_ue->nas.present.pdu_session_status = 1;
psimask = 0;
psimask |= pdu_session_status->psi << 8;
psimask |= pdu_session_status->psi >> 8;
ogs_list_for_each(&amf_ue->sess_list, sess) {
if ((psimask & (1 << sess->psi)) == 0)
amf_sbi_send_release_session(sess);
}
}
if (SESSION_SYNC_DONE(amf_ue))
nas_5gs_send_service_accept(amf_ue);
return OGS_OK;
}
int gmm_handle_deregistration_request(amf_ue_t *amf_ue,
ogs_nas_5gs_deregistration_request_from_ue_t *deregistration_request)
{
ogs_nas_de_registration_type_t *de_registration_type = NULL;
ogs_assert(amf_ue);
ogs_assert(deregistration_request);
de_registration_type = &deregistration_request->de_registration_type;
ogs_debug("[%s] Deregistration request", amf_ue->supi);
/* Set 5GS Attach Type */
memcpy(&amf_ue->nas.de_registration,
de_registration_type, sizeof(ogs_nas_de_registration_type_t));
amf_ue->nas.message_type = OGS_NAS_5GS_DEREGISTRATION_REQUEST;
amf_ue->nas.tsc = de_registration_type->tsc;
amf_ue->nas.ksi = de_registration_type->ksi;
ogs_debug("[%s] OGS_NAS_5GS TYPE[%d] TSC[%d] KSI[%d] "
"DEREGISTRATION[0x%x]",
amf_ue->suci, amf_ue->nas.message_type,
amf_ue->nas.tsc, amf_ue->nas.ksi, amf_ue->nas.data);
if (deregistration_request->de_registration_type.switch_off)
ogs_debug(" Switch-Off");
amf_sbi_send_release_all_sessions(amf_ue);
if (SESSION_SYNC_DONE(amf_ue))
nas_5gs_send_de_registration_accept(amf_ue);
return OGS_OK;
}
@ -409,234 +554,6 @@ int gmm_handle_identity_response(amf_ue_t *amf_ue,
return OGS_OK;
}
int gmm_handle_deregistration_request(amf_ue_t *amf_ue,
ogs_nas_5gs_deregistration_request_from_ue_t *deregistration_request)
{
ogs_nas_de_registration_type_t *de_registration_type = NULL;
ogs_assert(amf_ue);
ogs_assert(deregistration_request);
de_registration_type = &deregistration_request->de_registration_type;
ogs_debug("[%s] Deregistration request", amf_ue->supi);
/* Set 5GS Attach Type */
memcpy(&amf_ue->nas.de_registration,
de_registration_type, sizeof(ogs_nas_de_registration_type_t));
amf_ue->nas.message_type = OGS_NAS_5GS_DEREGISTRATION_REQUEST;
amf_ue->nas.tsc = de_registration_type->tsc;
amf_ue->nas.ksi = de_registration_type->ksi;
ogs_debug("[%s] OGS_NAS_5GS TYPE[%d] TSC[%d] KSI[%d] "
"DEREGISTRATION[0x%x]",
amf_ue->suci, amf_ue->nas.message_type,
amf_ue->nas.tsc, amf_ue->nas.ksi, amf_ue->nas.data);
if (deregistration_request->de_registration_type.switch_off)
ogs_debug(" Switch-Off");
amf_send_delete_session_or_de_register(amf_ue);
return OGS_OK;
}
int gmm_handle_service_request(amf_ue_t *amf_ue,
ogs_nas_5gs_service_request_t *service_request)
{
ogs_nas_key_set_identifier_t *ngksi = NULL;
ogs_assert(amf_ue);
ngksi = &service_request->ngksi;
ogs_assert(ngksi);
amf_ue->nas.message_type = OGS_NAS_5GS_SERVICE_REQUEST;
amf_ue->nas.tsc = ngksi->tsc;
amf_ue->nas.ksi = ngksi->value;
ogs_debug(" OGS_NAS_5GS TYPE[%d] TSC[%d] KSI[%d] SERVICE[0x%x]",
amf_ue->nas.message_type,
amf_ue->nas.tsc, amf_ue->nas.ksi, amf_ue->nas.data);
/*
* REGISTRATION_REQUEST
* Clear EBI generator
* Clear Timer and Message
*
* TAU_REQUEST
* Clear Timer and Message
*
* SERVICE_REQUEST
* Clear Timer and Message
*
* EXTENDED_SERVICE_REQUEST
* Clear Timer and Message
*/
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
if (SECURITY_CONTEXT_IS_VALID(amf_ue)) {
ogs_kdf_kgnb_and_kn3iwf(
amf_ue->kamf, amf_ue->ul_count.i32,
amf_ue->nas.access_type, amf_ue->kgnb);
ogs_kdf_nh_gnb(amf_ue->kamf, amf_ue->kgnb, amf_ue->nh);
amf_ue->nhcc = 1;
}
ogs_debug("[%s] 5G-S_GUTI[AMF_ID:0x%x,M_TMSI:0x%x]",
AMF_UE_HAVE_SUCI(amf_ue) ? amf_ue->suci : "Unknown ID",
ogs_amf_id_hexdump(&amf_ue->guti.amf_id), amf_ue->guti.m_tmsi);
if (!AMF_UE_HAVE_SUCI(amf_ue)) {
ogs_debug("Service request : Unknown UE");
nas_5gs_send_service_reject(amf_ue,
OGS_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK, false);
return OGS_ERROR;
}
if (!SECURITY_CONTEXT_IS_VALID(amf_ue)) {
ogs_debug("No Security Context");
nas_5gs_send_service_reject(amf_ue,
OGS_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK, false);
return OGS_ERROR;
}
if (service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT) {
return gmm_handle_nas_message_container(
amf_ue, &service_request->nas_message_container);
}
return gmm_handle_service_update(amf_ue, service_request);
}
int gmm_handle_service_update(amf_ue_t *amf_ue,
ogs_nas_5gs_service_request_t *service_request)
{
amf_sess_t *sess = NULL;
ogs_nas_uplink_data_status_t *uplink_data_status = NULL;
ogs_nas_pdu_session_status_t *pdu_session_status = NULL;
ogs_nas_allowed_pdu_session_status_t *allowed_pdu_session_status = NULL;
amf_nsmf_pdu_session_update_sm_context_param_t param;
bool handled;
ogs_assert(amf_ue);
uplink_data_status = &service_request->uplink_data_status;
ogs_assert(uplink_data_status);
pdu_session_status = &service_request->pdu_session_status;
ogs_assert(pdu_session_status);
allowed_pdu_session_status = &service_request->allowed_pdu_session_status;
ogs_assert(allowed_pdu_session_status);
handled = false;
if (service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_UPLINK_DATA_STATUS_PRESENT) {
uint16_t psimask = 0;
psimask |= uplink_data_status->psi << 8;
psimask |= uplink_data_status->psi >> 8;
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (psimask & (1 << sess->psi)) {
if (sess->smfUpCnxState == OpenAPI_up_cnx_state_ACTIVATED) {
/* Nothing */
} else if (sess->smfUpCnxState ==
OpenAPI_up_cnx_state_ACTIVATING) {
handled = true;
} else if (sess->smfUpCnxState ==
OpenAPI_up_cnx_state_DEACTIVATED) {
/* UPDATE_UpCnxState - ACTIVATING */
sess->ueUpCnxState = OpenAPI_up_cnx_state_ACTIVATING;
memset(&param, 0, sizeof(param));
param.upCnxState = sess->ueUpCnxState;
amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_SMF, sess, &param,
amf_nsmf_pdu_session_build_update_sm_context);
handled = true;
}
}
}
if (!handled) {
nas_5gs_send_service_accept(amf_ue, true);
return OGS_OK;
}
} else if (service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_PDU_SESSION_STATUS_PRESENT) {
uint16_t psimask = 0;
psimask |= pdu_session_status->psi << 8;
psimask |= pdu_session_status->psi >> 8;
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (psimask & (1 << sess->psi)) {
/*
* TS24.501
* 5.6.1.5 Service request procedure not accepted by the network
*
* If the AMF needs to initiate PDU session status synchronisation
* or a PDU session status IE was included in the SERVICE REQUEST message,
* the AMF shall include a PDU session status IE in the SERVICE REJECT
* message to indicate which PDU sessions associated with the access type
* the SERVICE REJECT message is sent over are active in the AMF.
* If the PDU session status IE is included in the SERVICE REJECT message
* and if the message is integrity protected, then the UE shall perform
* a local release of all those PDU sessions which are active
* on the UE side associated with the access type the SERVICE REJECT
* message is sent over, but are indicated by the AMF as being inactive.
*/
if (sess->smfUpCnxState == OpenAPI_up_cnx_state_DEACTIVATED) {
/* UPDATE_UpCnxState - ACTIVATING */
sess->ueUpCnxState = OpenAPI_up_cnx_state_ACTIVATING;
memset(&param, 0, sizeof(param));
param.upCnxState = sess->ueUpCnxState;
amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_SMF, sess, &param,
amf_nsmf_pdu_session_build_update_sm_context);
handled = true;
} else {
ogs_error("Not implemented "
"for AMF active in PDU Session Status IE");
nas_5gs_send_service_reject(amf_ue,
OGS_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,
true);
return OGS_ERROR;
}
}
}
if (!handled) {
nas_5gs_send_service_accept(amf_ue, false);
return OGS_OK;
}
} else if (service_request->presencemask &
OGS_NAS_5GS_SERVICE_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT) {
ogs_error("Not implemented Allowed PDU Session Status IE");
nas_5gs_send_service_reject(amf_ue,
OGS_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK,
true);
return OGS_ERROR;
}
if (!handled) {
ogs_error("No Session Status IE");
nas_5gs_send_service_reject(amf_ue,
OGS_5GMM_CAUSE_SEMANTICALLY_INCORRECT_MESSAGE, false);
return OGS_ERROR;
}
return OGS_OK;
}
#if 0
int gmm_handle_tau_request(amf_ue_t *amf_ue,
ogs_nas_5gs_tracking_area_update_request_t *tau_request)
@ -774,87 +691,6 @@ int gmm_handle_tau_request(amf_ue_t *amf_ue,
return OGS_OK;
}
int gmm_handle_extended_service_request(amf_ue_t *amf_ue,
ogs_nas_5gs_extended_service_request_t *extended_service_request)
{
int served_tai_index = 0;
ogs_nas_service_type_t *service_type =
&extended_service_request->service_type;
ogs_nas_mobile_identity_t *mobile_identity =
&extended_service_request->m_tmsi;
ogs_nas_mobile_identity_tmsi_t *mobile_identity_tmsi = NULL;
ran_ue_t *ran_ue = NULL;
ogs_assert(amf_ue);
ran_ue = amf_ue->ran_ue;
ogs_assert(ran_ue);
/* Set Service Type */
memcpy(&amf_ue->nas.service, service_type,
sizeof(ogs_nas_service_type_t));
amf_ue->nas.message_type = AMF_5GS_TYPE_EXTENDED_SERVICE_REQUEST;
amf_ue->nas.ksi = service_type->nas_key_set_identifier;
ogs_debug(" OGS_NAS_5GS TYPE[%d] KSI[%d] SERVICE[0x%x]",
amf_ue->nas.message_type, amf_ue->nas.ksi, amf_ue->nas.value);
/*
* REGISTRATION_REQUEST
* Clear EBI generator
* Clear Timer and Message
*
* TAU_REQUEST
* Clear Timer and Message
*
* SERVICE_REQUEST
* Clear Timer and Message
*
* EXTENDED_SERVICE_REQUEST
* Clear Timer and Message
*/
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
ogs_debug(" OLD TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&amf_ue->tai.plmn_id), amf_ue->tai.tac);
ogs_debug(" OLD NR_CGI[PLMN_ID:%06x,CELL_ID:%d]",
ogs_plmn_id_hexdump(&amf_ue->e_cgi.plmn_id), amf_ue->e_cgi.cell_id);
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&ran_ue->saved.tai.plmn_id),
ran_ue->saved.tai.tac);
ogs_debug(" NR_CGI[PLMN_ID:%06x,CELL_ID:%d]",
ogs_plmn_id_hexdump(&ran_ue->saved.e_cgi.plmn_id),
ran_ue->saved.e_cgi.cell_id);
/* Copy TAI and ECGI from ran_ue */
memcpy(&amf_ue->tai, &ran_ue->saved.tai, sizeof(ogs_5gs_tai_t));
memcpy(&amf_ue->e_cgi, &ran_ue->saved.e_cgi, sizeof(ogs_e_cgi_t));
/* Check TAI */
served_tai_index = amf_find_served_tai(&amf_ue->tai);
if (served_tai_index < 0) {
/* Send TAU reject */
ogs_warn("Cannot find Served TAI[PLMN_ID:%06x,TAC:%d]",
ogs_plmn_id_hexdump(&amf_ue->tai.plmn_id), amf_ue->tai.tac);
nas_5gs_send_tau_reject(amf_ue, EMM_CAUSE_TRACKING_AREA_NOT_ALLOWED);
return OGS_ERROR;
}
ogs_debug(" SERVED_TAI_INDEX[%d]", served_tai_index);
switch(mobile_identity->tmsi.type) {
case OGS_NAS_MOBILE_IDENTITY_TMSI:
mobile_identity_tmsi = &mobile_identity->tmsi;
ogs_debug(" M-TMSI:[0x%x] IMSI:[%s]",
mobile_identity_tmsi->tmsi,
AMF_UE_HAVE_IMSI(amf_ue) ? amf_ue->imsi_bcd : "Unknown");
break;
default:
ogs_error("Unknown TMSI type [%d]", mobile_identity->tmsi.type);
break;
}
return OGS_OK;
}
#endif
int gmm_handle_security_mode_complete(amf_ue_t *amf_ue,

View File

@ -30,19 +30,26 @@ int gmm_handle_registration_request(amf_ue_t *amf_ue,
ogs_nas_5gs_registration_request_t *registration_request);
int gmm_handle_registration_update(amf_ue_t *amf_ue,
ogs_nas_5gs_registration_request_t *registration_request);
int gmm_handle_service_request(amf_ue_t *amf_ue,
ogs_nas_5gs_service_request_t *service_request);
int gmm_handle_service_update(amf_ue_t *amf_ue,
ogs_nas_5gs_service_request_t *service_request);
int gmm_handle_deregistration_request(amf_ue_t *amf_ue,
ogs_nas_5gs_deregistration_request_from_ue_t *deregistration_request);
int gmm_handle_authentication_response(amf_ue_t *amf_ue,
ogs_nas_5gs_authentication_response_t *authentication_response);
int gmm_handle_identity_response(amf_ue_t *amf_ue,
ogs_nas_5gs_identity_response_t *identity_response);
int gmm_handle_deregistration_request(amf_ue_t *amf_ue,
ogs_nas_5gs_deregistration_request_from_ue_t *deregistration_request);
int gmm_handle_security_mode_complete(amf_ue_t *amf_ue,
ogs_nas_5gs_security_mode_complete_t *security_mode_complete);
int gmm_handle_service_request(amf_ue_t *amf_ue,
ogs_nas_5gs_service_request_t *service_request);
int gmm_handle_service_update(amf_ue_t *amf_ue,
ogs_nas_5gs_service_request_t *service_request);
int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
ogs_nas_5gs_ul_nas_transport_t *ul_nas_transport);
#if 0
int gmm_handle_tau_request(amf_ue_t *amf_ue,
@ -52,12 +59,6 @@ int gmm_handle_extended_service_request(amf_ue_t *amf_ue,
ogs_nas_5gs_extended_service_request_t *extended_service_request);
#endif
int gmm_handle_security_mode_complete(amf_ue_t *amf_ue,
ogs_nas_5gs_security_mode_complete_t *security_mode_complete);
int gmm_handle_ul_nas_transport(amf_ue_t *amf_ue,
ogs_nas_5gs_ul_nas_transport_t *ul_nas_transport);
#ifdef __cplusplus
}
#endif

View File

@ -23,7 +23,6 @@
#include "nas-path.h"
#include "nas-security.h"
#include "ngap-path.h"
#include "amf-path.h"
#include "nausf-handler.h"
#include "nsmf-handler.h"
#include "sbi-path.h"
@ -97,9 +96,6 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
#endif
ogs_nas_security_header_type_t h;
ogs_sbi_response_t *sbi_response = NULL;
ogs_sbi_message_t *sbi_message = NULL;
ogs_assert(e);
if (e->sess) {
@ -113,9 +109,10 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
return;
break;
case OGS_FSM_EXIT_SIG:
return;
break;
case AMF_EVT_5GMM_MESSAGE:
nas_message = e->nas.message;
ogs_assert(nas_message);
@ -123,7 +120,83 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
ran_ue = amf_ue->ran_ue;
ogs_assert(ran_ue);
h.type = e->nas.type;
amf_ue->nas.ngapProcedureCode = e->ngap.code;
switch (nas_message->gmm.h.message_type) {
case OGS_NAS_5GS_REGISTRATION_REQUEST:
rv = gmm_handle_registration_request(
amf_ue, &nas_message->gmm.registration_request);
if (rv != OGS_OK) {
ogs_error("gmm_handle_registration_request() failed");
OGS_FSM_TRAN(s, gmm_state_exception);
break;
}
if (!AMF_UE_HAVE_SUCI(amf_ue)) {
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
nas_5gs_send_identity_request(amf_ue);
break;
}
if (h.integrity_protected && SECURITY_CONTEXT_IS_VALID(amf_ue)) {
rv = gmm_handle_registration_update(
amf_ue, &nas_message->gmm.registration_request);
if (rv != OGS_OK) {
ogs_error("gmm_handle_registration_update() failed");
amf_sbi_send_release_all_sessions(amf_ue);
OGS_FSM_TRAN(s, &gmm_state_authentication);
break;
}
} else {
amf_sbi_send_release_all_sessions(amf_ue);
if (SESSION_SYNC_DONE(amf_ue)) {
amf_ue_sbi_discover_and_send(
OpenAPI_nf_type_AUSF, amf_ue, NULL,
amf_nausf_auth_build_authenticate);
}
OGS_FSM_TRAN(s, &gmm_state_authentication);
}
break;
case OGS_NAS_5GS_SERVICE_REQUEST:
rv = gmm_handle_service_request(
amf_ue, &nas_message->gmm.service_request);
if (rv != OGS_OK) {
ogs_error("gmm_handle_service_request() failed");
OGS_FSM_TRAN(s, gmm_state_exception);
break;
}
if (!AMF_UE_HAVE_SUCI(amf_ue)) {
ogs_error("Service request : Unknown UE");
nas_5gs_send_service_reject(amf_ue,
OGS_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
OGS_FSM_TRAN(s, gmm_state_exception);
break;
}
if (!h.integrity_protected || !SECURITY_CONTEXT_IS_VALID(amf_ue)) {
ogs_error("No Security Context");
nas_5gs_send_service_reject(amf_ue,
OGS_5GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
OGS_FSM_TRAN(s, gmm_state_exception);
break;
}
rv = gmm_handle_service_update(
amf_ue, &nas_message->gmm.service_request);
if (rv != OGS_OK) {
ogs_error("gmm_handle_service_update() failed");
OGS_FSM_TRAN(s, gmm_state_exception);
}
break;
case OGS_NAS_5GS_IDENTITY_RESPONSE:
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
@ -132,36 +205,24 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
if (rv != OGS_OK) {
ogs_error("gmm_handle_identity_response() failed");
OGS_FSM_TRAN(s, gmm_state_exception);
return;
break;
}
if (!AMF_UE_HAVE_SUCI(amf_ue)) {
ogs_error("No SUCI");
OGS_FSM_TRAN(s, gmm_state_exception);
return;
break;
}
break;
case OGS_NAS_5GS_REGISTRATION_REQUEST:
ogs_debug("Registration request");
rv = gmm_handle_registration_request(
amf_ue, &nas_message->gmm.registration_request);
if (rv != OGS_OK) {
ogs_error("gmm_handle_registration_request() failed");
OGS_FSM_TRAN(s, gmm_state_exception);
return;
amf_sbi_send_release_all_sessions(amf_ue);
if (SESSION_SYNC_DONE(amf_ue)) {
amf_ue_sbi_discover_and_send(OpenAPI_nf_type_AUSF, amf_ue, NULL,
amf_nausf_auth_build_authenticate);
}
OGS_FSM_TRAN(s, &gmm_state_authentication);
break;
case OGS_NAS_5GS_SERVICE_REQUEST:
ogs_debug("Service request");
rv = gmm_handle_service_request(
amf_ue, &nas_message->gmm.service_request);
if (rv != OGS_OK) {
ogs_error("gmm_handle_service_request() failed");
OGS_FSM_TRAN(s, gmm_state_exception);
}
return;
#if 0
case OGS_NAS_5GS_TRACKING_AREA_UPDATE_REQUEST:
ogs_error("[%s] Tracking area update request",
@ -171,7 +232,7 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
if (rv != OGS_OK) {
ogs_error("gmm_handle_tau_request() failed");
OGS_FSM_TRAN(s, gmm_state_exception);
return;
break;
}
if (!AMF_UE_HAVE_SUCI(amf_ue)) {
@ -179,30 +240,65 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
nas_5gs_send_tau_reject(amf_ue,
GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
OGS_FSM_TRAN(s, &gmm_state_exception);
return;
break;
}
break;
case AMF_EPS_TYPE_TAU_REQUEST:
procedureCode = e->ngap_code;
if (!SESSION_CONTEXT_IS_AVAILABLE(amf_ue)) {
ogs_warn("No PDN Connection : UE[%s]", amf_ue->imsi_bcd);
nas_5gs_send_tau_reject(amf_ue,
GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
OGS_FSM_TRAN(s, gmm_state_exception);
break;
}
if (!SECURITY_CONTEXT_IS_VALID(amf_ue)) {
amf_s6a_send_air(amf_ue, NULL);
OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_authentication);
break;
}
if (procedureCode == NGAP_ProcedureCode_id_initialUEMessage) {
ogs_debug(" Iniital UE Message");
if (amf_ue->nas_5gs.update.active_flag) {
nas_5gs_send_tau_accept(amf_ue,
NGAP_ProcedureCode_id_InitialContextSetup);
} else {
nas_5gs_send_tau_accept(amf_ue,
NGAP_ProcedureCode_id_downlinkNASTransport);
amf_send_release_access_bearer_or_ue_context_release(ran_ue);
}
} else if (procedureCode == NGAP_ProcedureCode_id_uplinkNASTransport) {
ogs_debug(" Uplink NAS Transport");
nas_5gs_send_tau_accept(amf_ue,
NGAP_ProcedureCode_id_downlinkNASTransport);
} else {
ogs_fatal("Invalid Procedure Code[%d]", (int)procedureCode);
}
break;
case OGS_NAS_5GS_TRACKING_AREA_UPDATE_COMPLETE:
ogs_error("[%s] Tracking area update complete", amf_ue->supi);
return;
break;
#endif
case OGS_NAS_5GS_5GMM_STATUS:
ogs_warn("[%s] 5GMM STATUS : Cause[%d]", amf_ue->suci,
nas_message->gmm.gmm_status.gmm_cause);
OGS_FSM_TRAN(s, &gmm_state_exception);
return;
break;
case OGS_NAS_5GS_DEREGISTRATION_REQUEST:
gmm_handle_deregistration_request(
amf_ue, &nas_message->gmm.deregistration_request_from_ue);
OGS_FSM_TRAN(s, &gmm_state_de_registered);
return;
break;
case OGS_NAS_5GS_CONFIGURATION_UPDATE_COMPLETE:
ogs_debug("[%s] Configuration update complete", amf_ue->supi);
CLEAR_AMF_UE_TIMER(amf_ue->t3555);
return;
break;
case OGS_NAS_5GS_UL_NAS_TRANSPORT:
rv = gmm_handle_ul_nas_transport(
@ -211,43 +307,13 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
nas_5gs_send_gmm_status(
amf_ue, OGS_5GMM_CAUSE_INVALID_MANDATORY_INFORMATION);
}
return;
break;
default:
ogs_error("Unknown message [%d]", nas_message->gmm.h.message_type);
return;
}
break;
case AMF_EVT_SBI_CLIENT:
sbi_response = e->sbi.response;
ogs_assert(sbi_response);
sbi_message = e->sbi.message;
ogs_assert(sbi_message);
ogs_assert(sess);
SWITCH(sbi_message->h.service.name)
CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
SWITCH(sbi_message->h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
amf_nsmf_pdu_session_handle_update_sm_context(
sess, sbi_message);
break;
DEFAULT
amf_nsmf_pdu_session_handle_create_sm_context(
sess, sbi_message);
END
break;
DEFAULT
ogs_error("Invalid service name [%s]", sbi_message->h.service.name);
ogs_assert_if_reached();
END
return;
case AMF_EVT_5GMM_TIMER:
switch (e->timer_id) {
case AMF_TIMER_T3513:
@ -306,86 +372,9 @@ static void common_register_state(ogs_fsm_t *s, amf_event_t *e)
ogs_error("Unknown timer[%s:%d]",
amf_timer_get_name(e->timer_id), e->timer_id);
}
return;
break;
default:
ogs_error("Unknown event[%s]", amf_event_get_name(e));
return;
}
if (!AMF_UE_HAVE_SUCI(amf_ue)) {
CLEAR_AMF_UE_TIMER(amf_ue->t3570);
nas_5gs_send_identity_request(amf_ue);
return;
}
ran_ue = amf_ue->ran_ue;
ogs_assert(ran_ue);
switch (amf_ue->nas.message_type) {
case OGS_NAS_5GS_REGISTRATION_REQUEST:
h.type = e->nas.type;
if (h.integrity_protected && SECURITY_CONTEXT_IS_VALID(amf_ue)) {
rv = gmm_handle_registration_update(
amf_ue, &nas_message->gmm.registration_request);
if (rv != OGS_OK) {
ogs_error("gmm_handle_registration_update() failed");
amf_sbi_send_release_all_sm_contexts(amf_ue);
OGS_FSM_TRAN(s, &gmm_state_authentication);
break;
}
OGS_FSM_TRAN(s, &gmm_state_initial_context_setup);
} else {
if (SESSION_CONTEXT_IS_AVAILABLE(amf_ue)) {
amf_sbi_send_release_all_sm_contexts(amf_ue);
} else {
amf_ue_sbi_discover_and_send(OpenAPI_nf_type_AUSF, amf_ue, NULL,
amf_nausf_auth_build_authenticate);
}
OGS_FSM_TRAN(s, &gmm_state_authentication);
}
break;
#if 0
case AMF_EPS_TYPE_TAU_REQUEST:
procedureCode = e->ngap_code;
if (!SESSION_CONTEXT_IS_AVAILABLE(amf_ue)) {
ogs_warn("No PDN Connection : UE[%s]", amf_ue->imsi_bcd);
nas_5gs_send_tau_reject(amf_ue,
GMM_CAUSE_UE_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK);
OGS_FSM_TRAN(s, gmm_state_exception);
break;
}
if (!SECURITY_CONTEXT_IS_VALID(amf_ue)) {
amf_s6a_send_air(amf_ue, NULL);
OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_authentication);
break;
}
if (procedureCode == NGAP_ProcedureCode_id_initialUEMessage) {
ogs_debug(" Iniital UE Message");
if (amf_ue->nas_5gs.update.active_flag) {
nas_5gs_send_tau_accept(amf_ue,
NGAP_ProcedureCode_id_InitialContextSetup);
} else {
nas_5gs_send_tau_accept(amf_ue,
NGAP_ProcedureCode_id_downlinkNASTransport);
amf_send_release_access_bearer_or_ue_context_release(ran_ue);
}
} else if (procedureCode == NGAP_ProcedureCode_id_uplinkNASTransport) {
ogs_debug(" Uplink NAS Transport");
nas_5gs_send_tau_accept(amf_ue,
NGAP_ProcedureCode_id_downlinkNASTransport);
} else {
ogs_fatal("Invalid Procedure Code[%d]", (int)procedureCode);
}
break;
#endif
default:
ogs_error("Invalid NAS-5GS[%d]", amf_ue->nas.message_type);
break;
}
}
@ -469,6 +458,7 @@ void gmm_state_authentication(ogs_fsm_t *s, amf_event_t *e)
authentication_failure_parameter->auts,
amf_nausf_auth_build_authenticate);
return;
default:
ogs_error("Unknown GMM_CAUSE{%d] in Authentication"
" failure",
@ -712,7 +702,7 @@ void gmm_state_security_mode(ogs_fsm_t *s, amf_event_t *e)
case OGS_NAS_5GS_SERVICE_REQUEST:
ogs_debug("[%s] Service request", amf_ue->supi);
nas_5gs_send_service_reject(amf_ue,
OGS_5GMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED, false);
OGS_5GMM_CAUSE_SECURITY_MODE_REJECTED_UNSPECIFIED);
OGS_FSM_TRAN(s, &gmm_state_exception);
break;
@ -883,7 +873,7 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
break;
CASE(OGS_SBI_RESOURCE_NAME_UE_CONTEXT_IN_SMF_DATA)
nas_5gs_send_registration_accept(amf_ue, false);
nas_5gs_send_accept(amf_ue);
break;
DEFAULT
@ -897,25 +887,10 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
END
break;
CASE(OGS_SBI_SERVICE_NAME_NSMF_PDUSESSION)
SWITCH(sbi_message->h.resource.component[2])
CASE(OGS_SBI_RESOURCE_NAME_MODIFY)
amf_nsmf_pdu_session_handle_update_sm_context(
sess, sbi_message);
if (SESSION_UP_CNX_STATE_SYNCHED(amf_ue))
OGS_FSM_TRAN(&amf_ue->sm, &gmm_state_registered);
break;
DEFAULT
ogs_error("Invalid resource name [%s]",
sbi_message->h.resource.component[2]);
END
break;
DEFAULT
ogs_error("Invalid service name [%s]", sbi_message->h.service.name);
ogs_assert_if_reached();
END
break;
@ -944,7 +919,7 @@ void gmm_state_initial_context_setup(ogs_fsm_t *s, amf_event_t *e)
break;
}
amf_sbi_send_release_all_sm_contexts(amf_ue);
amf_sbi_send_release_all_sessions(amf_ue);
OGS_FSM_TRAN(s, &gmm_state_authentication);
break;
@ -992,6 +967,12 @@ void gmm_state_exception(ogs_fsm_t *s, amf_event_t *e)
switch (e->id) {
case OGS_FSM_ENTRY_SIG:
CLEAR_AMF_UE_ALL_TIMERS(amf_ue);
amf_sbi_send_release_all_sessions(amf_ue);
if (SESSION_SYNC_DONE(amf_ue))
ngap_send_amf_ue_context_release_command(amf_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
break;
case OGS_FSM_EXIT_SIG:
break;

View File

@ -48,7 +48,6 @@ libamf_sources = files('''
gmm-sm.c
amf-sm.c
amf-path.c
init.c
'''.split())

View File

@ -63,14 +63,13 @@ int nas_5gs_send_to_downlink_nas_transport(amf_ue_t *amf_ue, ogs_pkbuf_t *pkbuf)
return OGS_OK;
}
void nas_5gs_send_registration_accept(
amf_ue_t *amf_ue, bool reactivation_result)
void nas_5gs_send_registration_accept(amf_ue_t *amf_ue)
{
int rv;
ogs_pkbuf_t *ngapbuf = NULL;
ogs_pkbuf_t *gmmbuf = NULL;
gmmbuf = gmm_build_registration_accept(amf_ue, reactivation_result);
gmmbuf = gmm_build_registration_accept(amf_ue);
ogs_expect_or_return(gmmbuf);
ngapbuf = ngap_build_initial_context_setup_request(amf_ue, gmmbuf);
@ -97,6 +96,93 @@ void nas_5gs_send_registration_reject(
ogs_expect_or_return(rv == OGS_OK);
}
void nas_5gs_send_service_accept(amf_ue_t *amf_ue)
{
int rv;
ogs_pkbuf_t *gmmbuf = NULL;
ogs_pkbuf_t *ngapbuf = NULL;
ogs_assert(amf_ue);
gmmbuf = gmm_build_service_accept(amf_ue);
ogs_expect_or_return(gmmbuf);
switch (amf_ue->nas.ngapProcedureCode) {
case NGAP_ProcedureCode_id_InitialUEMessage:
ngapbuf = ngap_build_initial_context_setup_request(amf_ue, gmmbuf);
ogs_expect_or_return(ngapbuf);
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
ogs_expect_or_return(rv == OGS_OK);
break;
case NGAP_ProcedureCode_id_UplinkNASTransport:
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
ogs_expect_or_return(rv == OGS_OK);
break;
default:
ogs_error("Invalid NGAP ProcedureCode [%d]",
(int)amf_ue->nas.ngapProcedureCode);
return;
}
}
void nas_5gs_send_service_reject(
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause)
{
int rv;
ogs_pkbuf_t *gmmbuf = NULL;
ogs_assert(amf_ue);
gmmbuf = gmm_build_service_reject(amf_ue, gmm_cause);
ogs_expect_or_return(gmmbuf);
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
ogs_expect(rv == OGS_OK);
}
void nas_5gs_send_accept(amf_ue_t *amf_ue)
{
ogs_assert(amf_ue);
switch(amf_ue->nas.message_type) {
case OGS_NAS_5GS_REGISTRATION_REQUEST:
nas_5gs_send_registration_accept(amf_ue);
break;
case OGS_NAS_5GS_SERVICE_REQUEST:
nas_5gs_send_service_accept(amf_ue);
break;
default:
ogs_error("Unknown message type [%d]", amf_ue->nas.message_type);
}
}
void nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue)
{
ran_ue_t *ran_ue = NULL;
ogs_pkbuf_t *gmmbuf = NULL;
ogs_assert(amf_ue);
ran_ue = amf_ue->ran_ue;
ogs_assert(ran_ue);
if (amf_ue->nas.de_registration.switch_off == 0) {
int rv;
gmmbuf = gmm_build_de_registration_accept(amf_ue);
ogs_expect_or_return(gmmbuf);
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
ogs_expect_or_return(rv == OGS_OK);
}
ngap_send_ran_ue_context_release_command(ran_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_deregister,
NGAP_UE_CTX_REL_NG_REMOVE_AND_UNLINK, 0);
}
void nas_5gs_send_identity_request(amf_ue_t *amf_ue)
{
ogs_pkbuf_t *gmmbuf = NULL;
@ -268,7 +354,7 @@ void nas_5gs_send_gmm_reject(
nas_5gs_send_registration_reject(amf_ue, gmm_cause);
break;
case OGS_NAS_5GS_SERVICE_REQUEST:
nas_5gs_send_service_reject(amf_ue, gmm_cause, true);
nas_5gs_send_service_reject(amf_ue, gmm_cause);
break;
default:
ogs_error("Unknown message type [%d]", amf_ue->nas.message_type);
@ -365,65 +451,6 @@ void nas_5gs_send_back_5gsm_message_from_sbi(amf_sess_t *sess, int status)
nas_5gs_send_back_5gsm_message(sess, gmm_cause_from_sbi(status));
}
void nas_5gs_send_service_accept(
amf_ue_t *amf_ue, bool reactivation_result)
{
int rv;
ogs_pkbuf_t *gmmbuf = NULL;
ogs_pkbuf_t *ngapbuf = NULL;
ogs_assert(amf_ue);
gmmbuf = gmm_build_service_accept(amf_ue, reactivation_result);
ogs_expect_or_return(gmmbuf);
ngapbuf = ngap_build_initial_context_setup_request(amf_ue, gmmbuf);
ogs_expect_or_return(ngapbuf);
rv = nas_5gs_send_to_gnb(amf_ue, ngapbuf);
ogs_expect_or_return(rv == OGS_OK);
}
void nas_5gs_send_service_reject(amf_ue_t *amf_ue,
ogs_nas_5gmm_cause_t gmm_cause, bool pdu_session_status_present)
{
int rv;
ogs_pkbuf_t *gmmbuf = NULL;
ogs_assert(amf_ue);
gmmbuf = gmm_build_service_reject(amf_ue,
gmm_cause, pdu_session_status_present);
ogs_expect_or_return(gmmbuf);
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
ogs_expect(rv == OGS_OK);
}
void nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue)
{
ran_ue_t *ran_ue = NULL;
ogs_pkbuf_t *gmmbuf = NULL;
ogs_assert(amf_ue);
ran_ue = amf_ue->ran_ue;
ogs_assert(ran_ue);
if (amf_ue->nas.de_registration.switch_off == 0) {
int rv;
gmmbuf = gmm_build_de_registration_accept(amf_ue);
ogs_expect_or_return(gmmbuf);
rv = nas_5gs_send_to_downlink_nas_transport(amf_ue, gmmbuf);
ogs_expect_or_return(rv == OGS_OK);
}
ngap_send_ue_context_release_command(ran_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_deregister,
NGAP_UE_CTX_REL_NG_REMOVE_AND_UNLINK, 0);
}
#if 0
void nas_5gs_send_tau_accept(
amf_ue_t *amf_ue, NGAP_ProcedureCode_t procedureCode)

View File

@ -32,11 +32,18 @@ int nas_5gs_send_to_gnb(amf_ue_t *amf_ue, ogs_pkbuf_t *pkbuf);
int nas_5gs_send_to_downlink_nas_transport(
amf_ue_t *amf_ue, ogs_pkbuf_t *pkbuf);
void nas_5gs_send_registration_accept(
amf_ue_t *amf_ue, bool reactivation_result);
void nas_5gs_send_registration_accept(amf_ue_t *amf_ue);
void nas_5gs_send_registration_reject(
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause);
void nas_5gs_send_service_accept(amf_ue_t *amf_ue);
void nas_5gs_send_service_reject(
amf_ue_t *amf_ue, ogs_nas_5gmm_cause_t gmm_cause);
void nas_5gs_send_accept(amf_ue_t *amf_ue);
void nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue);
void nas_5gs_send_identity_request(amf_ue_t *amf_ue);
void nas_5gs_send_authentication_request(amf_ue_t *amf_ue);
@ -66,13 +73,6 @@ void nas_5gs_send_back_5gsm_message(
amf_sess_t *sess, ogs_nas_5gmm_cause_t gmm_cause);
void nas_5gs_send_back_5gsm_message_from_sbi(amf_sess_t *sess, int status);
void nas_5gs_send_service_accept(
amf_ue_t *amf_ue, bool reactivation_result);
void nas_5gs_send_service_reject(amf_ue_t *amf_ue,
ogs_nas_5gmm_cause_t gmm_cause, bool pdu_session_status_present);
void nas_5gs_send_de_registration_accept(amf_ue_t *amf_ue);
#if 0
void nas_5gs_send_tau_accept(
amf_ue_t *amf_ue, S1AP_ProcedureCode_t procedureCode);

View File

@ -18,7 +18,8 @@
*/
#include "ngap-handler.h"
#include "amf-path.h"
#include "ngap-path.h"
#include "sbi-path.h"
static bool served_tai_is_found(amf_gnb_t *gnb)
{
@ -865,7 +866,9 @@ void ngap_handle_initial_context_setup_failure(
* may in principle be adopted. The RAN should ensure
* that no hanging resources remain at the RAN.
*/
amf_send_delete_session_or_ran_ue_context_release(ran_ue);
ngap_send_session_sync_or_context_release_command(ran_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0);
}
#if 0
@ -993,14 +996,11 @@ void ngap_handle_ue_context_release_request(
int i;
char buf[OGS_ADDRSTRLEN];
uint64_t amf_ue_ngap_id;
bool handled;
ran_ue_t *ran_ue = NULL;
amf_ue_t *amf_ue = NULL;
amf_sess_t *sess = NULL;
amf_nsmf_pdu_session_update_sm_context_param_t param;
NGAP_InitiatingMessage_t *initiatingMessage = NULL;
NGAP_UEContextReleaseRequest_t *UEContextReleaseRequest = NULL;
@ -1097,93 +1097,48 @@ void ngap_handle_ue_context_release_request(
amf_ue = ran_ue->amf_ue;
if (!amf_ue) {
ogs_debug("No UE Context");
ngap_send_ue_context_release_command(ran_ue,
ngap_send_ran_ue_context_release_command(ran_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0);
return;
}
} else {
if (!PDUSessionList) {
amf_sbi_send_deactivate_all_sessions(
amf_ue, Cause->present, (int)Cause->choice.radioNetwork);
} else {
for (i = 0; i < PDUSessionList->list.count; i++) {
PDUSessionItem = (NGAP_PDUSessionResourceItemCxtRelReq_t *)
PDUSessionList->list.array[i];
ogs_list_for_each(&amf_ue->sess_list, sess) {
}
if (!PDUSessionItem) {
ogs_error("No PDUSessionResourceSetupItemSURes");
ngap_send_error_indication2(
amf_ue, NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error);
return;
}
handled = false;
if (PDUSessionItem->pDUSessionID ==
OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED) {
ogs_error("PDU Session Identity is unassigned");
ngap_send_error_indication2(
amf_ue, NGAP_Cause_PR_protocol,
NGAP_CauseProtocol_semantic_error);
return;
}
if (!PDUSessionList) {
ogs_list_for_each(&amf_ue->sess_list, sess) {
if (sess->smfUpCnxState != OpenAPI_up_cnx_state_DEACTIVATED) {
/* UPDATE_UpCnxState - DEACTIVATED */
sess->ueUpCnxState = OpenAPI_up_cnx_state_DEACTIVATED;
memset(&param, 0, sizeof(param));
param.upCnxState = sess->ueUpCnxState;
param.ngApCause.group = Cause->present;
param.ngApCause.value = (int)Cause->choice.radioNetwork;
amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_SMF, sess, &param,
amf_nsmf_pdu_session_build_update_sm_context);
handled = true;
sess = amf_sess_find_by_psi(amf_ue,
PDUSessionItem->pDUSessionID);
if (sess)
amf_sbi_send_deactivate_session(
sess, Cause->present,
(int)Cause->choice.radioNetwork);
}
}
if (!handled) {
ngap_send_ue_context_release_command(ran_ue,
if (SESSION_SYNC_DONE(amf_ue))
ngap_send_amf_ue_context_release_command(amf_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0);
}
return;
}
for (i = 0; i < PDUSessionList->list.count; i++) {
PDUSessionItem = (NGAP_PDUSessionResourceItemCxtRelReq_t *)
PDUSessionList->list.array[i];
if (!PDUSessionItem) {
ogs_error("No PDUSessionResourceSetupItemSURes");
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error);
return;
}
if (PDUSessionItem->pDUSessionID ==
OGS_NAS_PDU_SESSION_IDENTITY_UNASSIGNED) {
ogs_error("PDU Session Identity is unassigned");
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_protocol, NGAP_CauseProtocol_semantic_error);
return;
}
sess = amf_sess_find_by_psi(amf_ue, PDUSessionItem->pDUSessionID);
if (!sess) {
ogs_error("Cannot find PDU Session ID [%d]",
(int)PDUSessionItem->pDUSessionID);
ngap_send_error_indication2(amf_ue,
NGAP_Cause_PR_radioNetwork,
NGAP_CauseRadioNetwork_unknown_PDU_session_ID);
return;
}
if (sess->smfUpCnxState != OpenAPI_up_cnx_state_DEACTIVATED) {
/* UPDATE_UpCnxState - DEACTIVATED */
sess->ueUpCnxState = OpenAPI_up_cnx_state_DEACTIVATED;
memset(&param, 0, sizeof(param));
param.upCnxState = sess->ueUpCnxState;
param.ngApCause.group = Cause->present;
param.ngApCause.value = (int)Cause->choice.radioNetwork;
amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_SMF, sess, &param,
amf_nsmf_pdu_session_build_update_sm_context);
handled = true;
}
}
if (!handled) {
ogs_error("SMF has already been deactivated");
amf_send_delete_session_or_amf_ue_context_release(amf_ue);
}
}

View File

@ -25,6 +25,7 @@
#include "ngap-path.h"
#include "nas-security.h"
#include "nas-path.h"
#include "sbi-path.h"
int ngap_open(void)
{
@ -298,7 +299,7 @@ void ngap_send_ue_context_modification_request(amf_ue_t *amf_ue)
}
#endif
void ngap_send_ue_context_release_command(
void ngap_send_ran_ue_context_release_command(
ran_ue_t *ran_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay)
{
@ -338,6 +339,45 @@ void ngap_send_ue_context_release_command(
}
}
void ngap_send_amf_ue_context_release_command(
amf_ue_t *amf_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay)
{
ogs_assert(amf_ue);
ran_ue_t *ran_ue = amf_ue->ran_ue;
if (ran_ue) {
ngap_send_ran_ue_context_release_command(ran_ue,
group, cause, action, delay);
ogs_debug(" SUPI[%s]", amf_ue->supi);
} else {
ogs_error("[%s] No NG Context - "
"Group[%d] Cause[%d] Action[%d] Delay[%d]",
amf_ue->supi, group, (int)cause, action, delay);
}
}
void ngap_send_session_sync_or_context_release_command(
ran_ue_t *ran_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay)
{
amf_ue_t *amf_ue = NULL;
ogs_assert(ran_ue);
amf_ue = ran_ue->amf_ue;
if (!amf_ue) {
ngap_send_ran_ue_context_release_command(ran_ue,
group, cause, action, delay);
} else {
amf_sbi_send_release_all_sessions(amf_ue);
if (SESSION_SYNC_DONE(amf_ue)) {
ngap_send_ran_ue_context_release_command(ran_ue,
group, cause, action, delay);
}
}
}
#if 0
void ngap_send_paging(amf_ue_t *amf_ue, NGAP_CNDomain_t cn_domain)
{

View File

@ -53,7 +53,15 @@ void ngap_send_ng_setup_failure(
void ngap_send_initial_context_setup_request(amf_ue_t *amf_ue);
void ngap_send_ue_context_modification_request(amf_ue_t *amf_ue);
void ngap_send_ue_context_release_command(
void ngap_send_ran_ue_context_release_command(
ran_ue_t *ran_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay);
void ngap_send_amf_ue_context_release_command(
amf_ue_t *amf_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay);
void ngap_send_session_sync_or_context_release_command(
ran_ue_t *ran_ue, NGAP_Cause_PR group, long cause,
uint8_t action, uint32_t delay);

View File

@ -81,9 +81,14 @@ void amf_nnrf_handle_nf_status_subscribe(
duration = diff - (int)VALIDITY_MARGIN;
if (duration < (int)VALIDITY_MINIMUM) {
ogs_warn("[%s] Validation period [%d seconds, %s] is too small",
subscription->id,
(int)diff, SubscriptionData->validity_time);
char buf[64];
strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", &local);
ogs_warn("[%s] Validation period [%lld seconds, "
"(%lld)(%lld)(%s)(%s)] is too small", subscription->id,
(long long)diff,
(long long)ogs_mktime(&next),
(long long)ogs_mktime(&local),
SubscriptionData->validity_time, buf);
duration = VALIDITY_MINIMUM;
ogs_warn("[%s] Forced to %d seconds",
subscription->id, VALIDITY_MINIMUM);

View File

@ -160,10 +160,8 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
* 6. UEContextReleaseComplete
*/
if (SESSION_UP_CNX_STATE_SYNCHED(amf_ue)) {
ran_ue_t *ran_ue = amf_ue->ran_ue;
ogs_assert(ran_ue);
ngap_send_ue_context_release_command(ran_ue,
if (SESSION_SYNC_DONE(amf_ue)) {
ngap_send_amf_ue_context_release_command(amf_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0);
}
@ -215,19 +213,8 @@ int amf_nsmf_pdu_session_handle_update_sm_context(
sess->n2smbuf = ogs_pkbuf_copy(n2smbuf);
ogs_assert(sess->n2smbuf);
if (SESSION_UP_CNX_STATE_SYNCHED(amf_ue)) {
switch(amf_ue->nas.message_type) {
case OGS_NAS_5GS_REGISTRATION_REQUEST:
nas_5gs_send_registration_accept(amf_ue, true);
break;
case OGS_NAS_5GS_SERVICE_REQUEST:
nas_5gs_send_service_accept(amf_ue, true);
break;
default:
ogs_error("Unknown message type [%d]",
amf_ue->nas.message_type);
}
}
if (SESSION_SYNC_DONE(amf_ue))
nas_5gs_send_accept(amf_ue);
} else {
ogs_error("Invalid UpCnxState [UE:%d,SMF:%d]",
@ -298,51 +285,55 @@ int amf_nsmf_pdu_session_handle_release_sm_context(
ogs_debug("Release SM Context [%d]", recvmsg->res_status);
if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_authentication)) {
if (ogs_list_count(&amf_ue->sess_list) == 1) /* Last Session */ {
if (SESSION_SYNC_DONE(amf_ue)) {
if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_authentication)) {
amf_ue_sbi_discover_and_send(OpenAPI_nf_type_AUSF, amf_ue, NULL,
amf_nausf_auth_build_authenticate);
}
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_de_registered)) {
if (ogs_list_count(&amf_ue->sess_list) == 1) /* Last Session */ {
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_de_registered)) {
nas_5gs_send_de_registration_accept(amf_ue);
} else if (OGS_FSM_CHECK(&amf_ue->sm,
gmm_state_initial_context_setup)) {
/*
* 1. Initial context setup failure
* 2. Release All SM contexts
* 3. UE Context release command
* 4. UE Context release complete
*/
ngap_send_amf_ue_context_release_command(amf_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_NG_CONTEXT_REMOVE, 0);
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_registered)) {
nas_5gs_send_accept(amf_ue);
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_exception)) {
/*
* 1. GMM Exception
* 2. Release All SM contexts
* 3. UE Context release command
* 4. UE Context release complete
*/
ngap_send_amf_ue_context_release_command(amf_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_security_mode)) {
ogs_error("Releasing SM Context in security-mode STATE");
} else {
ogs_error("Releasing SM Context : INVALID STATE");
}
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_registered) ||
OGS_FSM_CHECK(&amf_ue->sm, gmm_state_exception)) {
/*
* TODO : PDUSessionResourceReleaseCommand
*
if (OGS_FSM_CHECK(&bearer->sm, esm_state_pdn_will_disconnect)) {
nas_eps_send_deactivate_bearer_context_request(bearer);
mme_sess_remove() should not be called here.
Session will be removed if Deactivate bearer context
accept is received
CLEAR_SGW_S1U_PATH(sess);
return;
} else if (OGS_FSM_CHECK(&bearer->sm, esm_state_active) ||
OGS_FSM_CHECK(&bearer->sm, esm_state_inactive)) {
}
*/
if (ogs_list_count(&amf_ue->sess_list) == 1) /* Last Session */ {
ran_ue_t *ran_ue = amf_ue->ran_ue;
if (ran_ue) {
ngap_send_ue_context_release_command(ran_ue,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release,
NGAP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
} else {
ogs_error("gNB-NG Context has already been removed");
}
}
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_security_mode)) {
ogs_error("Releasing SM Context in security-mode STATE");
} else if (OGS_FSM_CHECK(&amf_ue->sm, gmm_state_initial_context_setup)) {
ogs_error("Releasing SM Context in initial context setup STATE");
} else {
ogs_error("Releasing SM Context : INVALID STATE");
}
amf_sess_remove(sess);

View File

@ -164,15 +164,70 @@ void amf_sess_sbi_discover_and_send(
}
}
void amf_sbi_send_release_all_sm_contexts(amf_ue_t *amf_ue)
void amf_sbi_send_activating_session(amf_sess_t *sess)
{
amf_nsmf_pdu_session_update_sm_context_param_t param;
ogs_assert(sess);
/* UPDATE_UpCnxState - ACTIVATING */
sess->ueUpCnxState = OpenAPI_up_cnx_state_ACTIVATING;
memset(&param, 0, sizeof(param));
param.upCnxState = sess->ueUpCnxState;
amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_SMF, sess, &param,
amf_nsmf_pdu_session_build_update_sm_context);
}
void amf_sbi_send_deactivate_session(
amf_sess_t *sess, int group, int cause)
{
amf_nsmf_pdu_session_update_sm_context_param_t param;
ogs_assert(sess);
/* UPDATE_UpCnxState - DEACTIVATED */
sess->ueUpCnxState = OpenAPI_up_cnx_state_DEACTIVATED;
if (sess->smfUpCnxState != OpenAPI_up_cnx_state_DEACTIVATED) {
memset(&param, 0, sizeof(param));
param.upCnxState = sess->ueUpCnxState;
param.ngApCause.group = group;
param.ngApCause.value = cause;
amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_SMF, sess, &param,
amf_nsmf_pdu_session_build_update_sm_context);
}
}
void amf_sbi_send_deactivate_all_sessions(
amf_ue_t *amf_ue, int group, int cause)
{
amf_sess_t *sess = NULL;
ogs_assert(amf_ue);
ogs_list_for_each(&amf_ue->sess_list, sess) {
amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_SMF, sess, NULL,
amf_nsmf_pdu_session_build_release_sm_context);
}
ogs_list_for_each(&amf_ue->sess_list, sess)
amf_sbi_send_deactivate_session(sess, group, cause);
}
void amf_sbi_send_release_session(amf_sess_t *sess)
{
ogs_assert(sess);
amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_SMF, sess, NULL,
amf_nsmf_pdu_session_build_release_sm_context);
}
void amf_sbi_send_release_all_sessions(amf_ue_t *amf_ue)
{
amf_sess_t *sess = NULL;
ogs_assert(amf_ue);
ogs_list_for_each(&amf_ue->sess_list, sess)
amf_sbi_send_release_session(sess);
}

View File

@ -40,7 +40,15 @@ void amf_sess_sbi_discover_and_send(
OpenAPI_nf_type_e nf_type, amf_sess_t *sess, void *data,
ogs_sbi_request_t *(*build)(amf_sess_t *sess, void *data));
void amf_sbi_send_release_all_sm_contexts(amf_ue_t *amf_ue);
void amf_sbi_send_activating_session(amf_sess_t *sess);
void amf_sbi_send_deactivate_session(
amf_sess_t *sess, int group, int cause);
void amf_sbi_send_deactivate_all_sessions(
amf_ue_t *amf_ue, int group, int cause);
void amf_sbi_send_release_session(amf_sess_t *sess);
void amf_sbi_send_release_all_sessions(amf_ue_t *amf_ue);
#ifdef __cplusplus
}

View File

@ -79,9 +79,14 @@ void ausf_nnrf_handle_nf_status_subscribe(
duration = diff - (int)VALIDITY_MARGIN;
if (duration < (int)VALIDITY_MINIMUM) {
ogs_warn("[%s] Validation period [%d seconds, %s] is too small",
subscription->id,
(int)diff, SubscriptionData->validity_time);
char buf[64];
strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", &local);
ogs_warn("[%s] Validation period [%lld seconds, "
"(%lld)(%lld)(%s)(%s)] is too small", subscription->id,
(long long)diff,
(long long)ogs_mktime(&next),
(long long)ogs_mktime(&local),
SubscriptionData->validity_time, buf);
duration = VALIDITY_MINIMUM;
ogs_warn("[%s] Forced to %d seconds",
subscription->id, VALIDITY_MINIMUM);

View File

@ -79,9 +79,14 @@ void smf_nnrf_handle_nf_status_subscribe(
duration = diff - (int)VALIDITY_MARGIN;
if (duration < (int)VALIDITY_MINIMUM) {
ogs_warn("[%s] Validation period [%d seconds, %s] is too small",
subscription->id,
(int)diff, SubscriptionData->validity_time);
char buf[64];
strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", &local);
ogs_warn("[%s] Validation period [%lld seconds, "
"(%lld)(%lld)(%s)(%s)] is too small", subscription->id,
(long long)diff,
(long long)ogs_mktime(&next),
(long long)ogs_mktime(&local),
SubscriptionData->validity_time, buf);
duration = VALIDITY_MINIMUM;
ogs_warn("[%s] Forced to %d seconds",
subscription->id, VALIDITY_MINIMUM);

View File

@ -79,9 +79,14 @@ void udm_nnrf_handle_nf_status_subscribe(
duration = diff - (int)VALIDITY_MARGIN;
if (duration < (int)VALIDITY_MINIMUM) {
ogs_warn("[%s] Validation period [%d seconds, %s] is too small",
subscription->id,
(int)diff, SubscriptionData->validity_time);
char buf[64];
strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", &local);
ogs_warn("[%s] Validation period [%lld seconds, "
"(%lld)(%lld)(%s)(%s)] is too small", subscription->id,
(long long)diff,
(long long)ogs_mktime(&next),
(long long)ogs_mktime(&local),
SubscriptionData->validity_time, buf);
duration = VALIDITY_MINIMUM;
ogs_warn("[%s] Forced to %d seconds",
subscription->id, VALIDITY_MINIMUM);

View File

@ -79,9 +79,14 @@ void udr_nnrf_handle_nf_status_subscribe(
duration = diff - (int)VALIDITY_MARGIN;
if (duration < (int)VALIDITY_MINIMUM) {
ogs_warn("[%s] Validation period [%d seconds, %s] is too small",
subscription->id,
(int)diff, SubscriptionData->validity_time);
char buf[64];
strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", &local);
ogs_warn("[%s] Validation period [%lld seconds, "
"(%lld)(%lld)(%s)(%s)] is too small", subscription->id,
(long long)diff,
(long long)ogs_mktime(&next),
(long long)ogs_mktime(&local),
SubscriptionData->validity_time, buf);
duration = VALIDITY_MINIMUM;
ogs_warn("[%s] Forced to %d seconds",
subscription->id, VALIDITY_MINIMUM);

View File

@ -87,7 +87,8 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
ssize_t size;
ogs_pkbuf_t *pkbuf = NULL;
uint32_t len = OGS_GTPV1U_HEADER_LEN;
ogs_gtp_header_t *gtp_h = NULL;
uint32_t extension_header_type = 0;
ogs_5gs_gtp_header_t *gtp_h = NULL;
struct ip *ip_h = NULL;
uint32_t teid;
@ -113,13 +114,25 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
ogs_assert(pkbuf);
ogs_assert(pkbuf->len);
gtp_h = (ogs_gtp_header_t *)pkbuf->data;
if (gtp_h->flags & OGS_GTPU_FLAGS_S) len += 4;
gtp_h = (ogs_5gs_gtp_header_t *)pkbuf->data;
teid = be32toh(gtp_h->teid);
ogs_debug("[UPF] RECV GPU-U from SGW : TEID[0x%x]", teid);
ogs_debug("[UPF] RECV GPU-U from gNB : TEID[0x%x]", teid);
/* Remove GTP header and send packets to TUN interface */
if (gtp_h->seqence_number) len += 4;
if (gtp_h->next_extension) {
extension_header_type = be32toh(gtp_h->extension_header.type);
switch (extension_header_type) {
case OGS_GTP_EXTENSION_HEADER_TYPE_PDU_SESSION_CONTAINER:
len += 8; /* TODO : QoS QFI */
break;
default:
ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
ogs_error("[DROP] Cannot decode extension header");
goto cleanup;
}
}
ogs_assert(ogs_pkbuf_pull(pkbuf, len));
ip_h = (struct ip *)pkbuf->data;
@ -140,7 +153,7 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data)
subnet = sess->ipv6->subnet;
if (!subnet) {
ogs_log_hexdump(OGS_LOG_TRACE, pkbuf->data, pkbuf->len);
ogs_log_hexdump(OGS_LOG_ERROR, pkbuf->data, pkbuf->len);
ogs_error("[DROP] Cannot find subnet V:%d, IPv4:%p, IPv6:%p",
ip_h->ip_v, sess->ipv4, sess->ipv6);
goto cleanup;

View File

@ -62,31 +62,42 @@ typedef struct test_sess_s test_sess_t;
typedef struct test_registration_request_type_s {
union {
struct {
ED7(uint8_t integrity_protected:1;,
ED8(uint8_t integrity_protected:1;,
uint8_t guti:1;,
uint8_t requested_nssai:1;,
uint8_t last_visited_registered_tai:1;,
uint8_t ue_usage_setting:1;,
uint8_t uplink_data_status:1;,
uint8_t reserved:2;)
uint8_t pdu_session_status:1;,
uint8_t allowed_pdu_session_status:1;)
};
uint8_t value;
};
struct {
uint16_t pdu_session_status;
uint16_t uplink_data_status;
uint16_t allowed_pdu_session_status;
} psimask;
} __attribute__ ((packed)) test_registration_request_type_t;
typedef struct test_service_request_type_s {
union {
struct {
ED5(uint8_t integrity_protected:1;,
ED6(uint8_t integrity_protected:1;,
uint8_t ciphered:1;,
uint8_t pdu_session_status:1;,
uint8_t uplink_data_status:1;,
uint8_t allowed_pdu_session_status:1;,
uint8_t reserved:4;)
uint8_t reserved:3;)
};
uint8_t value;
};
uint8_t service_type;
uint16_t psimask;
struct {
uint16_t pdu_session_status;
uint16_t uplink_data_status;
uint16_t allowed_pdu_session_status;
} psimask;
} __attribute__ ((packed)) test_service_request_type_t;
typedef struct test_ue_s {
@ -162,6 +173,9 @@ typedef struct test_ue_s {
test_service_request_type_t service_request_type;
uint8_t gmm_message_type; /* Last received 5GMM message type */
uint16_t pdu_session_status;
uint16_t pdu_session_reactivation_result;
test_sess_t *sess;
} test_ue_t;

View File

@ -19,7 +19,8 @@
#include "test-common.h"
ogs_pkbuf_t *testgmm_build_registration_request(test_ue_t *test_ue)
ogs_pkbuf_t *testgmm_build_registration_request(
test_ue_t *test_ue, ogs_pkbuf_t *nasbuf)
{
test_sess_t *sess = NULL;
uint16_t psimask = 0;
@ -39,6 +40,10 @@ ogs_pkbuf_t *testgmm_build_registration_request(test_ue_t *test_ue)
&registration_request->s1_ue_network_capability;
ogs_nas_uplink_data_status_t *uplink_data_status =
&registration_request->uplink_data_status;
ogs_nas_pdu_session_status_t *pdu_session_status =
&registration_request->pdu_session_status;
ogs_nas_allowed_pdu_session_status_t *allowed_pdu_session_status =
&registration_request->allowed_pdu_session_status;
ogs_nas_nssai_t *requested_nssai = &registration_request->requested_nssai;
ogs_nas_5gs_tracking_area_identity_t *last_visited_registered_tai =
@ -46,6 +51,9 @@ ogs_pkbuf_t *testgmm_build_registration_request(test_ue_t *test_ue)
ogs_nas_ue_usage_setting_t *ue_usage_setting =
&registration_request->ue_usage_setting;
ogs_nas_message_container_t *nas_message_container =
&registration_request->nas_message_container;
ogs_nas_5gs_mobile_identity_guti_t mobile_identity_guti;
ogs_assert(test_ue);
@ -83,10 +91,31 @@ ogs_pkbuf_t *testgmm_build_registration_request(test_ue_t *test_ue)
if (test_ue->registration_request_type.uplink_data_status) {
registration_request->presencemask |=
OGS_NAS_5GS_REGISTRATION_REQUEST_UPLINK_DATA_STATUS_PRESENT;
psimask = 1 << sess->psi;
uplink_data_status->length = 2;
uplink_data_status->psi |= psimask << 8;
uplink_data_status->psi |= psimask >> 8;
uplink_data_status->psi |=
test_ue->registration_request_type.psimask.uplink_data_status << 8;
uplink_data_status->psi |=
test_ue->registration_request_type.psimask.uplink_data_status >> 8;
}
if (test_ue->registration_request_type.pdu_session_status) {
registration_request->presencemask |=
OGS_NAS_5GS_REGISTRATION_REQUEST_PDU_SESSION_STATUS_PRESENT;
pdu_session_status->length = 2;
pdu_session_status->psi |=
test_ue->registration_request_type.psimask.pdu_session_status << 8;
pdu_session_status->psi |=
test_ue->registration_request_type.psimask.pdu_session_status >> 8;
}
if (test_ue->registration_request_type.allowed_pdu_session_status) {
registration_request->presencemask |=
OGS_NAS_5GS_REGISTRATION_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT;
allowed_pdu_session_status->length = 2;
allowed_pdu_session_status->psi |= test_ue->
registration_request_type.psimask.allowed_pdu_session_status << 8;
allowed_pdu_session_status->psi |= test_ue->
registration_request_type.psimask.allowed_pdu_session_status >> 8;
}
registration_request->presencemask |=
@ -142,12 +171,184 @@ ogs_pkbuf_t *testgmm_build_registration_request(test_ue_t *test_ue)
ue_usage_setting->data_centric = 1;
}
if (nasbuf) {
registration_request->presencemask |=
OGS_NAS_5GS_REGISTRATION_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT;
nas_message_container->length = nasbuf->len;
nas_message_container->buffer = nasbuf->data;
ogs_pkbuf_free(nasbuf);
}
if (test_ue->registration_request_type.integrity_protected)
return test_nas_5gs_security_encode(test_ue, &message);
else
return ogs_nas_5gs_plain_encode(&message);
}
ogs_pkbuf_t *testgmm_build_registration_complete(test_ue_t *test_ue)
{
ogs_nas_5gs_message_t message;
ogs_pkbuf_t *pkbuf = NULL;
ogs_nas_5gs_registration_complete_t *registration_complete =
&message.gmm.registration_complete;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_REGISTRATION_COMPLETE;
return test_nas_5gs_security_encode(test_ue, &message);
}
ogs_pkbuf_t *testgmm_build_service_request(
test_ue_t *test_ue, ogs_pkbuf_t *nasbuf)
{
ogs_nas_5gs_message_t message;
ogs_pkbuf_t *pkbuf = NULL;
ogs_nas_5gs_service_request_t *service_request =
&message.gmm.service_request;
ogs_nas_5gs_mobile_identity_s_tmsi_t mobile_identity_s_tmsi;
ogs_nas_message_container_t *nas_message_container =
&service_request->nas_message_container;
ogs_nas_uplink_data_status_t *uplink_data_status =
&service_request->uplink_data_status;
ogs_nas_pdu_session_status_t *pdu_session_status =
&service_request->pdu_session_status;
ogs_nas_allowed_pdu_session_status_t *allowed_pdu_session_status =
&service_request->allowed_pdu_session_status;
ogs_assert(test_ue);
uplink_data_status = &service_request->uplink_data_status;
memset(&message, 0, sizeof(message));
if (test_ue->service_request_type.integrity_protected) {
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
if (test_ue->service_request_type.ciphered)
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
else
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED;
}
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_SERVICE_REQUEST;
service_request->ngksi.type = test_ue->service_request_type.service_type;
service_request->ngksi.tsc = test_ue->nas.tsc;
service_request->ngksi.value = test_ue->nas.ksi;
ogs_assert(test_ue->nas_guti.m_tmsi);
memset(&mobile_identity_s_tmsi, 0, sizeof(mobile_identity_s_tmsi));
mobile_identity_s_tmsi.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_S_TMSI;
mobile_identity_s_tmsi.m_tmsi = htobe32(test_ue->nas_guti.m_tmsi);
mobile_identity_s_tmsi.set1 = test_ue->nas_guti.amf_id.set1;
mobile_identity_s_tmsi.set2 = test_ue->nas_guti.amf_id.set2;
mobile_identity_s_tmsi.pointer = test_ue->nas_guti.amf_id.pointer;
service_request->s_tmsi.length = sizeof(mobile_identity_s_tmsi);
service_request->s_tmsi.buffer = &mobile_identity_s_tmsi;
if (nasbuf) {
service_request->presencemask |=
OGS_NAS_5GS_SERVICE_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT;
nas_message_container->length = nasbuf->len;
nas_message_container->buffer = nasbuf->data;
ogs_pkbuf_free(nasbuf);
}
if (test_ue->service_request_type.uplink_data_status) {
service_request->presencemask |=
OGS_NAS_5GS_SERVICE_REQUEST_UPLINK_DATA_STATUS_PRESENT;
uplink_data_status->length = 2;
uplink_data_status->psi |=
test_ue->service_request_type.psimask.uplink_data_status << 8;
uplink_data_status->psi |=
test_ue->service_request_type.psimask.uplink_data_status >> 8;
}
if (test_ue->service_request_type.pdu_session_status) {
service_request->presencemask |=
OGS_NAS_5GS_SERVICE_REQUEST_PDU_SESSION_STATUS_PRESENT;
pdu_session_status->length = 2;
pdu_session_status->psi |=
test_ue->service_request_type.psimask.pdu_session_status << 8;
pdu_session_status->psi |=
test_ue->service_request_type.psimask.pdu_session_status >> 8;
}
if (test_ue->service_request_type.allowed_pdu_session_status) {
service_request->presencemask |=
OGS_NAS_5GS_SERVICE_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT;
allowed_pdu_session_status->length = 2;
allowed_pdu_session_status->psi |= test_ue->
service_request_type.psimask.allowed_pdu_session_status << 8;
allowed_pdu_session_status->psi |= test_ue->
service_request_type.psimask.allowed_pdu_session_status >> 8;
}
if (test_ue->service_request_type.integrity_protected)
return test_nas_5gs_security_encode(test_ue, &message);
else
return ogs_nas_5gs_plain_encode(&message);
}
ogs_pkbuf_t *testgmm_build_de_registration_request(
test_ue_t *test_ue, bool switch_off)
{
ogs_nas_5gs_message_t message;
ogs_pkbuf_t *pkbuf = NULL;
ogs_nas_5gs_deregistration_request_from_ue_t
*deregistration_request_from_ue =
&message.gmm.deregistration_request_from_ue;
ogs_nas_de_registration_type_t *de_registration_type =
&deregistration_request_from_ue->de_registration_type;
ogs_nas_5gs_mobile_identity_guti_t mobile_identity_guti;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_DEREGISTRATION_REQUEST;
de_registration_type->ksi = test_ue->nas.ksi;
de_registration_type->switch_off = switch_off;
de_registration_type->access_type = test_ue->nas.access_type;
if (test_ue->nas_guti.m_tmsi) {
ogs_nas_5gs_nas_guti_to_mobilty_identity_guti(
&test_ue->nas_guti, &mobile_identity_guti);
deregistration_request_from_ue->mobile_identity.length =
sizeof(ogs_nas_5gs_mobile_identity_guti_t);
deregistration_request_from_ue->mobile_identity.buffer =
&mobile_identity_guti;
} else {
deregistration_request_from_ue->mobile_identity.length =
test_ue->mobile_identity_suci_length;
deregistration_request_from_ue->mobile_identity.buffer =
&test_ue->mobile_identity_suci;
}
return test_nas_5gs_security_encode(test_ue, &message);
}
ogs_pkbuf_t *testgmm_build_identity_response(test_ue_t *test_ue)
{
ogs_nas_5gs_message_t message;
@ -319,116 +520,6 @@ ogs_pkbuf_t *testgmm_build_security_mode_complete(
return test_nas_5gs_security_encode(test_ue, &message);
}
ogs_pkbuf_t *testgmm_build_registration_complete(test_ue_t *test_ue)
{
ogs_nas_5gs_message_t message;
ogs_pkbuf_t *pkbuf = NULL;
ogs_nas_5gs_registration_complete_t *registration_complete =
&message.gmm.registration_complete;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_REGISTRATION_COMPLETE;
return test_nas_5gs_security_encode(test_ue, &message);
}
ogs_pkbuf_t *testgmm_build_service_request(
test_ue_t *test_ue, ogs_pkbuf_t *nasbuf)
{
ogs_nas_5gs_message_t message;
ogs_pkbuf_t *pkbuf = NULL;
ogs_nas_5gs_service_request_t *service_request =
&message.gmm.service_request;
ogs_nas_5gs_mobile_identity_s_tmsi_t mobile_identity_s_tmsi;
ogs_nas_message_container_t *nas_message_container =
&service_request->nas_message_container;
ogs_nas_uplink_data_status_t *uplink_data_status =
&service_request->uplink_data_status;
ogs_nas_pdu_session_status_t *pdu_session_status =
&service_request->pdu_session_status;
ogs_nas_allowed_pdu_session_status_t *allowed_pdu_session_status =
&service_request->allowed_pdu_session_status;
ogs_assert(test_ue);
uplink_data_status = &service_request->uplink_data_status;
memset(&message, 0, sizeof(message));
if (test_ue->service_request_type.integrity_protected) {
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
}
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_SERVICE_REQUEST;
service_request->ngksi.type = test_ue->service_request_type.service_type;
service_request->ngksi.tsc = test_ue->nas.tsc;
service_request->ngksi.value = test_ue->nas.ksi;
ogs_assert(test_ue->nas_guti.m_tmsi);
memset(&mobile_identity_s_tmsi, 0, sizeof(mobile_identity_s_tmsi));
mobile_identity_s_tmsi.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_S_TMSI;
mobile_identity_s_tmsi.m_tmsi = htobe32(test_ue->nas_guti.m_tmsi);
mobile_identity_s_tmsi.set1 = test_ue->nas_guti.amf_id.set1;
mobile_identity_s_tmsi.set2 = test_ue->nas_guti.amf_id.set2;
mobile_identity_s_tmsi.pointer = test_ue->nas_guti.amf_id.pointer;
service_request->s_tmsi.length = sizeof(mobile_identity_s_tmsi);
service_request->s_tmsi.buffer = &mobile_identity_s_tmsi;
if (nasbuf) {
service_request->presencemask |=
OGS_NAS_5GS_SERVICE_REQUEST_NAS_MESSAGE_CONTAINER_PRESENT;
nas_message_container->length = nasbuf->len;
nas_message_container->buffer = nasbuf->data;
ogs_pkbuf_free(nasbuf);
}
if (test_ue->service_request_type.uplink_data_status) {
service_request->presencemask |=
OGS_NAS_5GS_SERVICE_REQUEST_UPLINK_DATA_STATUS_PRESENT;
uplink_data_status->length = 2;
uplink_data_status->psi |= test_ue->service_request_type.psimask << 8;
uplink_data_status->psi |= test_ue->service_request_type.psimask >> 8;
}
if (test_ue->service_request_type.pdu_session_status) {
service_request->presencemask |=
OGS_NAS_5GS_SERVICE_REQUEST_PDU_SESSION_STATUS_PRESENT;
pdu_session_status->length = 2;
pdu_session_status->psi |= test_ue->service_request_type.psimask << 8;
pdu_session_status->psi |= test_ue->service_request_type.psimask >> 8;
}
if (test_ue->service_request_type.allowed_pdu_session_status) {
service_request->presencemask |=
OGS_NAS_5GS_SERVICE_REQUEST_ALLOWED_PDU_SESSION_STATUS_PRESENT;
allowed_pdu_session_status->length = 2;
allowed_pdu_session_status->psi |=
test_ue->service_request_type.psimask << 8;
allowed_pdu_session_status->psi |=
test_ue->service_request_type.psimask >> 8;
}
if (test_ue->service_request_type.integrity_protected)
return test_nas_5gs_security_encode(test_ue, &message);
else
return ogs_nas_5gs_plain_encode(&message);
}
ogs_pkbuf_t *testgmm_build_configuration_update_complete(test_ue_t *test_ue)
{
ogs_nas_5gs_message_t message;
@ -540,51 +631,6 @@ ogs_pkbuf_t *testgmm_build_ul_nas_transport(test_sess_t *test_sess,
return pkbuf;
}
ogs_pkbuf_t *testgmm_build_de_registration_request(
test_ue_t *test_ue, bool switch_off)
{
ogs_nas_5gs_message_t message;
ogs_pkbuf_t *pkbuf = NULL;
ogs_nas_5gs_deregistration_request_from_ue_t
*deregistration_request_from_ue =
&message.gmm.deregistration_request_from_ue;
ogs_nas_de_registration_type_t *de_registration_type =
&deregistration_request_from_ue->de_registration_type;
ogs_nas_5gs_mobile_identity_guti_t mobile_identity_guti;
ogs_assert(test_ue);
memset(&message, 0, sizeof(message));
message.h.security_header_type =
OGS_NAS_SECURITY_HEADER_INTEGRITY_PROTECTED_AND_CIPHERED;
message.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GMM;
message.gmm.h.message_type = OGS_NAS_5GS_DEREGISTRATION_REQUEST;
de_registration_type->ksi = test_ue->nas.ksi;
de_registration_type->switch_off = switch_off;
de_registration_type->access_type = test_ue->nas.access_type;
if (test_ue->nas_guti.m_tmsi) {
ogs_nas_5gs_nas_guti_to_mobilty_identity_guti(
&test_ue->nas_guti, &mobile_identity_guti);
deregistration_request_from_ue->mobile_identity.length =
sizeof(ogs_nas_5gs_mobile_identity_guti_t);
deregistration_request_from_ue->mobile_identity.buffer =
&mobile_identity_guti;
} else {
deregistration_request_from_ue->mobile_identity.length =
test_ue->mobile_identity_suci_length;
deregistration_request_from_ue->mobile_identity.buffer =
&test_ue->mobile_identity_suci;
}
return test_nas_5gs_security_encode(test_ue, &message);
}
ogs_pkbuf_t *testgmm_build_gmm_status(
test_ue_t *test_ue, ogs_nas_5gmm_cause_t gmm_cause)
{

View File

@ -24,7 +24,15 @@
extern "C" {
#endif
ogs_pkbuf_t *testgmm_build_registration_request(test_ue_t *test_ue);
ogs_pkbuf_t *testgmm_build_registration_request(
test_ue_t *test_ue, ogs_pkbuf_t *nasbuf);
ogs_pkbuf_t *testgmm_build_registration_complete(test_ue_t *test_ue);
ogs_pkbuf_t *testgmm_build_service_request(
test_ue_t *test_ue, ogs_pkbuf_t *nasbuf);
ogs_pkbuf_t *testgmm_build_de_registration_request(
test_ue_t *test_ue, bool switch_off);
ogs_pkbuf_t *testgmm_build_identity_response(test_ue_t *test_ue);
ogs_pkbuf_t *testgmm_build_authentication_response(test_ue_t *test_ue);
@ -32,14 +40,9 @@ ogs_pkbuf_t *testgmm_build_authentication_failure(
test_ue_t *test_ue, ogs_nas_5gmm_cause_t gmm_cause);
ogs_pkbuf_t *testgmm_build_security_mode_complete(
test_ue_t *test_ue, ogs_pkbuf_t *nasbuf);
ogs_pkbuf_t *testgmm_build_registration_complete(test_ue_t *test_ue);
ogs_pkbuf_t *testgmm_build_service_request(
test_ue_t *test_ue, ogs_pkbuf_t *nasbuf);
ogs_pkbuf_t *testgmm_build_configuration_update_complete(test_ue_t *test_ue);
ogs_pkbuf_t *testgmm_build_ul_nas_transport(test_sess_t *test_sess,
uint8_t payload_type, ogs_pkbuf_t *payload);
ogs_pkbuf_t *testgmm_build_de_registration_request(
test_ue_t *test_ue, bool switch_off);
ogs_pkbuf_t *testgmm_build_gmm_status(
test_ue_t *test_ue, ogs_nas_5gmm_cause_t gmm_cause);

View File

@ -19,6 +19,85 @@
#include "test-common.h"
void testgmm_handle_registration_accept(test_ue_t *test_ue,
ogs_nas_5gs_registration_accept_t *registration_accept)
{
ogs_nas_pdu_session_status_t *pdu_session_status = NULL;
ogs_nas_pdu_session_reactivation_result_t *pdu_session_reactivation_result;
ogs_assert(test_ue);
ogs_assert(registration_accept);
pdu_session_status = &registration_accept->pdu_session_status;
pdu_session_reactivation_result =
&registration_accept->pdu_session_reactivation_result;
if (registration_accept->presencemask &
OGS_NAS_5GS_REGISTRATION_ACCEPT_5G_GUTI_PRESENT) {
ogs_nas_5gs_mobile_identity_t *mobile_identity = NULL;
ogs_nas_5gs_mobile_identity_guti_t *mobile_identity_guti = NULL;
mobile_identity = &registration_accept->guti;
mobile_identity_guti = mobile_identity->buffer;
memcpy(&test_ue->nas_guti.nas_plmn_id,
&mobile_identity_guti->nas_plmn_id, OGS_PLMN_ID_LEN);
memcpy(&test_ue->nas_guti.amf_id,
&mobile_identity_guti->amf_id, sizeof(ogs_amf_id_t));
test_ue->nas_guti.m_tmsi = be32toh(mobile_identity_guti->m_tmsi);
}
test_ue->pdu_session_status = 0;
test_ue->pdu_session_reactivation_result = 0;
if (registration_accept->presencemask &
OGS_NAS_5GS_REGISTRATION_ACCEPT_PDU_SESSION_STATUS_PRESENT)
test_ue->pdu_session_status = pdu_session_status->psi;
if (registration_accept->presencemask &
OGS_NAS_5GS_REGISTRATION_ACCEPT_PDU_SESSION_REACTIVATION_RESULT_PRESENT)
test_ue->pdu_session_reactivation_result =
pdu_session_reactivation_result->psi;
}
void testgmm_handle_service_accept(test_ue_t *test_ue,
ogs_nas_5gs_service_accept_t *service_accept)
{
ogs_nas_pdu_session_status_t *pdu_session_status = NULL;
ogs_nas_pdu_session_reactivation_result_t *pdu_session_reactivation_result;
ogs_assert(test_ue);
ogs_assert(service_accept);
pdu_session_status = &service_accept->pdu_session_status;
pdu_session_reactivation_result =
&service_accept->pdu_session_reactivation_result;
test_ue->pdu_session_status = 0;
test_ue->pdu_session_reactivation_result = 0;
if (service_accept->presencemask &
OGS_NAS_5GS_SERVICE_ACCEPT_PDU_SESSION_STATUS_PRESENT)
test_ue->pdu_session_status = pdu_session_status->psi;
if (service_accept->presencemask &
OGS_NAS_5GS_SERVICE_ACCEPT_PDU_SESSION_REACTIVATION_RESULT_PRESENT)
test_ue->pdu_session_reactivation_result =
pdu_session_reactivation_result->psi;
}
void testgmm_handle_service_reject(test_ue_t *test_ue,
ogs_nas_5gs_service_reject_t *service_reject)
{
ogs_nas_pdu_session_status_t *pdu_session_status = NULL;
ogs_assert(test_ue);
ogs_assert(service_reject);
pdu_session_status = &service_reject->pdu_session_status;
test_ue->pdu_session_status = 0;
if (service_reject->presencemask &
OGS_NAS_5GS_SERVICE_REJECT_PDU_SESSION_STATUS_PRESENT)
test_ue->pdu_session_status = pdu_session_status->psi;
}
void testgmm_handle_identity_request(test_ue_t *test_ue,
ogs_nas_5gs_identity_request_t *identity_request)
{
@ -88,28 +167,6 @@ void testgmm_handle_security_mode_command(test_ue_t *test_ue,
test_ue->security_context_available = 1;
}
void testgmm_handle_registration_accept(test_ue_t *test_ue,
ogs_nas_5gs_registration_accept_t *registration_accept)
{
ogs_assert(test_ue);
ogs_assert(registration_accept);
if (registration_accept->presencemask &
OGS_NAS_5GS_REGISTRATION_ACCEPT_5G_GUTI_PRESENT) {
ogs_nas_5gs_mobile_identity_t *mobile_identity = NULL;
ogs_nas_5gs_mobile_identity_guti_t *mobile_identity_guti = NULL;
mobile_identity = &registration_accept->guti;
mobile_identity_guti = mobile_identity->buffer;
memcpy(&test_ue->nas_guti.nas_plmn_id,
&mobile_identity_guti->nas_plmn_id, OGS_PLMN_ID_LEN);
memcpy(&test_ue->nas_guti.amf_id,
&mobile_identity_guti->amf_id, sizeof(ogs_amf_id_t));
test_ue->nas_guti.m_tmsi = be32toh(mobile_identity_guti->m_tmsi);
}
}
void testgmm_handle_dl_nas_transport(test_ue_t *test_ue,
ogs_nas_5gs_dl_nas_transport_t *dl_nas_transport)
{

View File

@ -24,14 +24,18 @@
extern "C" {
#endif
void testgmm_handle_registration_accept(test_ue_t *test_ue,
ogs_nas_5gs_registration_accept_t *registration_accept);
void testgmm_handle_service_accept(test_ue_t *test_ue,
ogs_nas_5gs_service_accept_t *service_accept);
void testgmm_handle_service_reject(test_ue_t *test_ue,
ogs_nas_5gs_service_reject_t *service_reject);
void testgmm_handle_identity_request(test_ue_t *test_ue,
ogs_nas_5gs_identity_request_t *identity_request);
void testgmm_handle_authentication_request(test_ue_t *test_ue,
ogs_nas_5gs_authentication_request_t *authentication_request);
void testgmm_handle_security_mode_command(test_ue_t *test_ue,
ogs_nas_5gs_security_mode_command_t *security_mode_command);
void testgmm_handle_registration_accept(test_ue_t *test_ue,
ogs_nas_5gs_registration_accept_t *registration_accept);
void testgmm_handle_dl_nas_transport(test_ue_t *test_ue,
ogs_nas_5gs_dl_nas_transport_t *dl_nas_transport);

View File

@ -114,7 +114,7 @@ int test_gtpu_build_ping(ogs_pkbuf_t **sendbuf,
{
int rv;
ogs_pkbuf_t *pkbuf = NULL;
ogs_gtp_header_t *gtp_h = NULL;
ogs_5gs_gtp_header_t *gtp_h = NULL;
ogs_ipsubnet_t dst_ipsub;
ogs_assert(sess);
@ -127,18 +127,28 @@ int test_gtpu_build_ping(ogs_pkbuf_t **sendbuf,
ogs_pkbuf_put(pkbuf, 200);
memset(pkbuf->data, 0, pkbuf->len);
gtp_h = (ogs_gtp_header_t *)pkbuf->data;
gtp_h->flags = 0x30;
gtp_h = (ogs_5gs_gtp_header_t *)pkbuf->data;
gtp_h->flags = 0x34;
gtp_h->type = OGS_GTPU_MSGTYPE_GPDU;
gtp_h->teid = htonl(sess->upf_n3_teid);
gtp_h->teid = htobe32(sess->upf_n3_teid);
gtp_h->extension_header.type =
htobe32(OGS_GTP_EXTENSION_HEADER_TYPE_PDU_SESSION_CONTAINER);
gtp_h->extension_header.len = 1;
gtp_h->extension_header.pdu_type =
OGS_GTP_EXTENSION_HEADER_PDU_TYPE_UL_PDU_SESSION_INFORMATION;
gtp_h->extension_header.qos_flow_identifier = 1;
gtp_h->extension_header.next_type =
OGS_GTP_EXTENSION_HEADER_TYPE_NO_MORE_EXTENSION_HEADERS;
if (dst_ipsub.family == AF_INET) {
struct ip *ip_h = NULL;
struct icmp *icmp_h = NULL;
gtp_h->length = htons(sizeof *ip_h + ICMP_MINLEN);
#define GTP_EXTENSION_HEADER_SIZE 8
gtp_h->length = htobe16(
sizeof *ip_h + ICMP_MINLEN + GTP_EXTENSION_HEADER_SIZE);
ip_h = (struct ip *)(pkbuf->data + OGS_GTPV1U_HEADER_LEN);
ip_h = (struct ip *)(pkbuf->data + OGS_5GS_GTP_HEADER_LEN);
icmp_h = (struct icmp *)((uint8_t *)ip_h + sizeof *ip_h);
ip_h->ip_v = 4;
@ -148,7 +158,7 @@ int test_gtpu_build_ping(ogs_pkbuf_t **sendbuf,
ip_h->ip_off = 0;
ip_h->ip_ttl = 255;
ip_h->ip_p = IPPROTO_ICMP;
ip_h->ip_len = gtp_h->length;
ip_h->ip_len = htobe16(sizeof *ip_h + ICMP_MINLEN);
ip_h->ip_src.s_addr = sess->ue_ip.addr;
ip_h->ip_dst.s_addr = dst_ipsub.sub[0];
ip_h->ip_sum = ogs_in_cksum((uint16_t *)ip_h, sizeof *ip_h);
@ -169,7 +179,7 @@ int test_gtpu_build_ping(ogs_pkbuf_t **sendbuf,
plen = htons(sizeof *icmp6_h);
nxt = IPPROTO_ICMPV6;
p = (uint8_t *)pkbuf->data + OGS_GTPV1U_HEADER_LEN;
p = (uint8_t *)pkbuf->data + OGS_5GS_GTP_HEADER_LEN;
ip6_h = (struct ip6_hdr *)p;
icmp6_h = (struct icmp6_hdr *)((uint8_t *)ip6_h + sizeof *ip6_h);

View File

@ -32,11 +32,21 @@ void testgmm_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
test_ue->gmm_message_type = message.gmm.h.message_type;
switch (message.gmm.h.message_type) {
case OGS_NAS_5GS_IDENTITY_REQUEST:
testgmm_handle_identity_request(test_ue, &message.gmm.identity_request);
case OGS_NAS_5GS_REGISTRATION_ACCEPT:
testgmm_handle_registration_accept(test_ue,
&message.gmm.registration_request);
break;
case OGS_NAS_5GS_REGISTRATION_REJECT:
break;
case OGS_NAS_5GS_SERVICE_ACCEPT:
testgmm_handle_service_accept(test_ue, &message.gmm.service_accept);
break;
case OGS_NAS_5GS_SERVICE_REJECT:
testgmm_handle_service_reject(test_ue, &message.gmm.service_reject);
break;
case OGS_NAS_5GS_IDENTITY_REQUEST:
testgmm_handle_identity_request(test_ue, &message.gmm.identity_request);
break;
case OGS_NAS_5GS_AUTHENTICATION_REQUEST:
testgmm_handle_authentication_request(test_ue,
&message.gmm.authentication_request);
@ -45,12 +55,6 @@ void testgmm_recv(test_ue_t *test_ue, ogs_pkbuf_t *pkbuf)
break;
case OGS_NAS_5GS_SECURITY_MODE_COMMAND:
break;
case OGS_NAS_5GS_REGISTRATION_ACCEPT:
testgmm_handle_registration_accept(test_ue,
&message.gmm.authentication_request);
break;
case OGS_NAS_5GS_SERVICE_ACCEPT:
break;
case OGS_NAS_5GS_CONFIGURATION_UPDATE_COMMAND:
break;
case OGS_NAS_5GS_DL_NAS_TRANSPORT:

View File

@ -183,7 +183,7 @@ static void test1_func(abts_case *tc, void *data)
bson_destroy(doc);
/* Send Registration request */
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, false);
ABTS_PTR_NOTNULL(tc, sendbuf);
@ -209,7 +209,7 @@ static void test1_func(abts_case *tc, void *data)
testngap_recv(&test_ue, recvbuf);
/* Send Security mode complete */
nasbuf = testgmm_build_registration_request(&test_ue);
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
gmmbuf = testgmm_build_security_mode_complete(&test_ue, nasbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);

View File

@ -183,7 +183,7 @@ static void test1_func(abts_case *tc, void *data)
bson_destroy(doc);
/* Send Registration request */
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, false);
ABTS_PTR_NOTNULL(tc, sendbuf);

View File

@ -183,13 +183,13 @@ static void test1_func(abts_case *tc, void *data)
bson_destroy(doc);
/* Send Registration request */
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue.registration_request_type.requested_nssai = 1;
test_ue.registration_request_type.last_visited_registered_tai = 1;
test_ue.registration_request_type.ue_usage_setting = 1;
nasbuf = testgmm_build_registration_request(&test_ue);
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, false);

View File

@ -183,13 +183,13 @@ static void test1_func(abts_case *tc, void *data)
bson_destroy(doc);
/* Send Registration request */
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue.registration_request_type.requested_nssai = 1;
test_ue.registration_request_type.last_visited_registered_tai = 1;
test_ue.registration_request_type.ue_usage_setting = 1;
nasbuf = testgmm_build_registration_request(&test_ue);
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, false);

View File

@ -184,13 +184,13 @@ static void test1_func(abts_case *tc, void *data)
/* Send Registration request */
test_ue.registration_request_type.guti = 1;
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue.registration_request_type.requested_nssai = 1;
test_ue.registration_request_type.last_visited_registered_tai = 1;
test_ue.registration_request_type.ue_usage_setting = 1;
nasbuf = testgmm_build_registration_request(&test_ue);
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, false);
@ -321,20 +321,29 @@ static void test1_func(abts_case *tc, void *data)
ogs_msleep(50);
/* Send Registration request */
test_ue.registration_request_type.integrity_protected = 1;
/* Send Registration request : Uplink Data Status */
test_ue.registration_request_type.integrity_protected = 0;
test_ue.registration_request_type.uplink_data_status = 1;
gmmbuf = testgmm_build_registration_request(&test_ue);
test_ue.registration_request_type.psimask.uplink_data_status =
1 << test_sess.psi;
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
test_ue.registration_request_type.integrity_protected = 1;
test_ue.registration_request_type.uplink_data_status = 0;
gmmbuf = testgmm_build_registration_request(&test_ue, nasbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Initial context setup request */
/* Receive Registration accept */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
ABTS_INT_EQUAL(tc, 0x0000, test_ue.pdu_session_reactivation_result);
/* Send Initial context setup response */
sendbuf = testngap_build_initial_context_setup_response(
@ -364,12 +373,12 @@ static void test1_func(abts_case *tc, void *data)
/* Send Registration request - INVALID_GUTI */
test_ue.nas_guti.m_tmsi = 0x1234;
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue.registration_request_type.integrity_protected = 0;
test_ue.registration_request_type.uplink_data_status = 0;
nasbuf = testgmm_build_registration_request(&test_ue);
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, true);

View File

@ -183,13 +183,13 @@ static void test1_func(abts_case *tc, void *data)
bson_destroy(doc);
/* Send Registration request */
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue.registration_request_type.requested_nssai = 1;
test_ue.registration_request_type.last_visited_registered_tai = 1;
test_ue.registration_request_type.ue_usage_setting = 1;
nasbuf = testgmm_build_registration_request(&test_ue);
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, false);
@ -287,7 +287,7 @@ static void test1_func(abts_case *tc, void *data)
test_ue.registration_request_type.integrity_protected = 1;
test_ue.registration_request_type.guti = 1;
test_ue.registration_request_type.uplink_data_status = 1;
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, true);
@ -338,7 +338,7 @@ static void test1_func(abts_case *tc, void *data)
test_ue.nas_guti.m_tmsi = 0x1234;
/* Send Registration request */
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, true);

View File

@ -183,13 +183,13 @@ static void test1_func(abts_case *tc, void *data)
bson_destroy(doc);
/* Send Registration request */
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue.registration_request_type.requested_nssai = 1;
test_ue.registration_request_type.last_visited_registered_tai = 1;
test_ue.registration_request_type.ue_usage_setting = 1;
nasbuf = testgmm_build_registration_request(&test_ue);
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, false);
@ -285,8 +285,6 @@ static void test1_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_msleep(50);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
@ -330,12 +328,18 @@ static void test1_func(abts_case *tc, void *data)
rv = testgnb_gtpu_send(gtpu, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Service request */
/*
* Send Service request Using InitialUEMessage
* - PDU Session Status
*/
test_ue.service_request_type.integrity_protected = 0;
test_ue.service_request_type.pdu_session_status = 1;
test_ue.service_request_type.psimask = 1 << test_sess.psi;
test_ue.service_request_type.psimask.pdu_session_status =
1 << test_sess.psi;
nasbuf = testgmm_build_service_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
test_ue.service_request_type.integrity_protected = 1;
test_ue.service_request_type.pdu_session_status = 0;
gmmbuf = testgmm_build_service_request(&test_ue, nasbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
@ -349,6 +353,8 @@ static void test1_func(abts_case *tc, void *data)
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
ABTS_INT_EQUAL(tc, 0x2000, test_ue.pdu_session_status);
ABTS_INT_EQUAL(tc, 0x0000, test_ue.pdu_session_reactivation_result);
/* Send Initial context setup response */
sendbuf = testngap_build_initial_context_setup_response(
@ -400,13 +406,20 @@ static void test1_func(abts_case *tc, void *data)
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Service request */
/*
* Send Service request Using InitialUEMessage
* - Uplink Data Status
*/
test_ue.service_request_type.integrity_protected = 0;
test_ue.service_request_type.uplink_data_status = 1;
test_ue.service_request_type.
psimask.uplink_data_status = 1 << test_sess.psi;
test_ue.service_request_type.pdu_session_status = 0;
test_ue.service_request_type.psimask = 1 << test_sess.psi;
nasbuf = testgmm_build_service_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
test_ue.service_request_type.integrity_protected = 1;
test_ue.service_request_type.uplink_data_status = 0;
test_ue.service_request_type.pdu_session_status = 0;
gmmbuf = testgmm_build_service_request(&test_ue, nasbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
@ -420,6 +433,8 @@ static void test1_func(abts_case *tc, void *data)
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
ABTS_INT_EQUAL(tc, 0x0000, test_ue.pdu_session_status);
ABTS_INT_EQUAL(tc, 0x0000, test_ue.pdu_session_reactivation_result);
test_sess.gnb_n3_teid = 5;
@ -631,13 +646,13 @@ static void test2_func(abts_case *tc, void *data)
bson_destroy(doc);
/* Send Registration request */
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue.registration_request_type.requested_nssai = 1;
test_ue.registration_request_type.last_visited_registered_tai = 1;
test_ue.registration_request_type.ue_usage_setting = 1;
nasbuf = testgmm_build_registration_request(&test_ue);
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, false);
@ -706,7 +721,7 @@ static void test2_func(abts_case *tc, void *data)
/* Send UE context release request */
sendbuf = testngap_build_ue_context_release_request(&test_ue,
NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_user_inactivity,
false);
true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
@ -724,14 +739,16 @@ static void test2_func(abts_case *tc, void *data)
ogs_msleep(50);
/* Send Service request */
/*
* Send Service request Using InitialUEMessage
* - PDU Session Status
*/
test_ue.service_request_type.integrity_protected = 0;
test_ue.service_request_type.pdu_session_status = 1;
#if 0
test_ue.service_request_type.psimask = 1 << test_sess.psi;
#endif
nasbuf = testgmm_build_service_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
test_ue.service_request_type.integrity_protected = 1;
test_ue.service_request_type.pdu_session_status = 0;
gmmbuf = testgmm_build_service_request(&test_ue, nasbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
@ -744,6 +761,8 @@ static void test2_func(abts_case *tc, void *data)
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
ABTS_INT_EQUAL(tc, 0x0000, test_ue.pdu_session_status);
ABTS_INT_EQUAL(tc, 0x0000, test_ue.pdu_session_reactivation_result);
/* Send Initial context setup response */
sendbuf = testngap_build_initial_context_setup_response(&test_ue, NULL);
@ -772,12 +791,403 @@ static void test2_func(abts_case *tc, void *data)
test_ue_remove(&test_ue);
}
static void test3_func(abts_case *tc, void *data)
{
int rv;
ogs_socknode_t *ngap;
ogs_socknode_t *gtpu;
ogs_pkbuf_t *gmmbuf;
ogs_pkbuf_t *gsmbuf;
ogs_pkbuf_t *nasbuf;
ogs_pkbuf_t *sendbuf;
ogs_pkbuf_t *recvbuf;
ogs_ngap_message_t message;
int i;
int msgindex = 0;
ogs_nas_5gs_mobile_identity_suci_t mobile_identity_suci;
test_ue_t test_ue;
test_sess_t test_sess;
uint8_t tmp[OGS_MAX_SDU_LEN];
const char *_k_string = "70d49a71dd1a2b806a25abe0ef749f1e";
uint8_t k[OGS_KEY_LEN];
const char *_opc_string = "6f1bf53d624b3a43af6592854e2444c7";
uint8_t opc[OGS_KEY_LEN];
mongoc_collection_t *collection = NULL;
bson_t *doc = NULL;
int64_t count = 0;
bson_error_t error;
const char *json =
"{"
"\"_id\" : { \"$oid\" : \"597223158b8861d7605378c6\" }, "
"\"imsi\" : \"901700000021309\","
"\"ambr\" : { "
"\"uplink\" : { \"$numberLong\" : \"1024000\" }, "
"\"downlink\" : { \"$numberLong\" : \"1024000\" } "
"},"
"\"pdn\" : ["
"{"
"\"apn\" : \"internet\", "
"\"_id\" : { \"$oid\" : \"597223158b8861d7605378c7\" }, "
"\"ambr\" : {"
"\"uplink\" : { \"$numberLong\" : \"1024000\" }, "
"\"downlink\" : { \"$numberLong\" : \"1024000\" } "
"},"
"\"qos\" : { "
"\"qci\" : 9, "
"\"arp\" : { "
"\"priority_level\" : 8,"
"\"pre_emption_vulnerability\" : 1, "
"\"pre_emption_capability\" : 1"
"} "
"}, "
"\"type\" : 2"
"}"
"],"
"\"security\" : { "
"\"k\" : \"70d49a71dd1a2b806a25abe0ef749f1e\", "
"\"opc\" : \"6f1bf53d624b3a43af6592854e2444c7\", "
"\"amf\" : \"8000\", "
"\"sqn\" : { \"$numberLong\" : \"25235952177090\" } "
"}, "
"\"subscribed_rau_tau_timer\" : 12,"
"\"network_access_mode\" : 2, "
"\"subscriber_status\" : 0, "
"\"access_restriction_data\" : 32, "
"\"__v\" : 0 "
"}";
/* Setup Test UE & Session Context */
memset(&test_ue, 0, sizeof(test_ue));
memset(&test_sess, 0, sizeof(test_sess));
test_sess.test_ue = &test_ue;
test_ue.sess = &test_sess;
test_ue.nas.registration.type = OGS_NAS_KSI_NO_KEY_IS_AVAILABLE;
test_ue.nas.registration.follow_on_request = 1;
test_ue.nas.registration.value = OGS_NAS_5GS_REGISTRATION_TYPE_INITIAL;
memset(&mobile_identity_suci, 0, sizeof(mobile_identity_suci));
mobile_identity_suci.h.supi_format = OGS_NAS_5GS_SUPI_FORMAT_IMSI;
mobile_identity_suci.h.type = OGS_NAS_5GS_MOBILE_IDENTITY_SUCI;
ogs_nas_from_plmn_id(&mobile_identity_suci.nas_plmn_id,
&test_self()->tai.plmn_id);
mobile_identity_suci.routing_indicator1 = 0;
mobile_identity_suci.routing_indicator2 = 0xf;
mobile_identity_suci.routing_indicator3 = 0xf;
mobile_identity_suci.routing_indicator4 = 0xf;
mobile_identity_suci.protection_scheme_id = OGS_NAS_5GS_NULL_SCHEME;
mobile_identity_suci.home_network_pki_value = 0;
mobile_identity_suci.scheme_output[0] = 0;
mobile_identity_suci.scheme_output[1] = 0;
mobile_identity_suci.scheme_output[2] = 0x20;
mobile_identity_suci.scheme_output[3] = 0x31;
mobile_identity_suci.scheme_output[4] = 0x90;
test_ue_set_mobile_identity_suci(&test_ue, &mobile_identity_suci, 13);
test_ue.nas.access_type = OGS_ACCESS_TYPE_3GPP;
test_ue.abba_len = 2;
OGS_HEX(_k_string, strlen(_k_string), test_ue.k);
OGS_HEX(_opc_string, strlen(_opc_string), test_ue.opc);
test_sess.psi = 5;
test_sess.pti = 1;
test_sess.pdu_session_type = OGS_PDU_SESSION_TYPE_IPV4V6;
test_sess.dnn = (char *)"internet";
memset(&test_sess.gnb_n3_ip, 0, sizeof(test_sess.gnb_n3_ip));
test_sess.gnb_n3_ip.ipv4 = true;
test_sess.gnb_n3_ip.addr = inet_addr("127.0.0.5");
test_sess.gnb_n3_teid = 3;
/* gNB connects to AMF */
ngap = testgnb_ngap_client("127.0.0.2");
ABTS_PTR_NOTNULL(tc, ngap);
/* gNB connects to UPF */
gtpu = testgnb_gtpu_server("127.0.0.5");
ABTS_PTR_NOTNULL(tc, gtpu);
/* Send NG-Setup Reqeust */
sendbuf = testngap_build_ng_setup_request(0x000102);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive NG-Setup Response */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
/********** Insert Subscriber in Database */
collection = mongoc_client_get_collection(
ogs_mongoc()->client, ogs_mongoc()->name, "subscribers");
ABTS_PTR_NOTNULL(tc, collection);
doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi));
ABTS_PTR_NOTNULL(tc, doc);
count = mongoc_collection_count (
collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
if (count) {
ABTS_TRUE(tc, mongoc_collection_remove(collection,
MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error))
}
bson_destroy(doc);
doc = bson_new_from_json((const uint8_t *)json, -1, &error);;
ABTS_PTR_NOTNULL(tc, doc);
ABTS_TRUE(tc, mongoc_collection_insert(collection,
MONGOC_INSERT_NONE, doc, NULL, &error));
bson_destroy(doc);
doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi));
ABTS_PTR_NOTNULL(tc, doc);
do {
count = mongoc_collection_count (
collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
} while (count == 0);
bson_destroy(doc);
/* Send Registration request */
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue.registration_request_type.requested_nssai = 1;
test_ue.registration_request_type.last_visited_registered_tai = 1;
test_ue.registration_request_type.ue_usage_setting = 1;
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, false);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Authentication request */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
/* Send Authentication response */
gmmbuf = testgmm_build_authentication_response(&test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Security mode command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
/* Send Security mode complete */
gmmbuf = testgmm_build_security_mode_complete(&test_ue, nasbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Initial context setup request */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
/* Send UE radio capability info indication */
sendbuf = testngap_build_ue_radio_capability_info_indication(&test_ue);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send Initial context setup response */
sendbuf = testngap_build_initial_context_setup_response(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_msleep(50);
/* Send Registration complete */
gmmbuf = testgmm_build_registration_complete(&test_ue);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Configuration update command */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
/* Send PDU session establishment request */
gsmbuf = testgsm_build_pdu_session_establishment_request(&test_sess);
ABTS_PTR_NOTNULL(tc, gsmbuf);
gmmbuf = testgmm_build_ul_nas_transport(&test_sess,
OGS_NAS_PAYLOAD_CONTAINER_N1_SM_INFORMATION, gsmbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive PDU session establishment accept */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_build_ping(&sendbuf, &test_sess, "10.45.0.1");
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testgnb_gtpu_send(gtpu, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
ogs_msleep(50);
/* Send PDU session resource setup response */
sendbuf = testngap_build_pdu_session_resource_setup_response(&test_sess);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_build_ping(&sendbuf, &test_sess, "10.45.0.1");
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testgnb_gtpu_send(gtpu, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
ogs_msleep(50);
/*
* Send Service request Using InitialUEMessage
* - Uplink Data Status
* - PDU Session Status
*/
test_ue.service_request_type.integrity_protected = 0;
test_ue.service_request_type.uplink_data_status = 1;
test_ue.service_request_type.psimask.uplink_data_status =
1 << test_sess.psi;
test_ue.service_request_type.pdu_session_status = 1;
test_ue.service_request_type.psimask.pdu_session_status =
1 << test_sess.psi;
nasbuf = testgmm_build_service_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
test_ue.service_request_type.integrity_protected = 1;
test_ue.service_request_type.uplink_data_status = 0;
test_ue.service_request_type.pdu_session_status = 0;
gmmbuf = testgmm_build_service_request(&test_ue, nasbuf);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, true);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Service accept */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
ABTS_INT_EQUAL(tc, 0x2000, test_ue.pdu_session_status);
ABTS_INT_EQUAL(tc, 0x0000, test_ue.pdu_session_reactivation_result);
/* Send Initial context setup response */
sendbuf = testngap_build_initial_context_setup_response(
&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_build_ping(&sendbuf, &test_sess, "10.45.0.1");
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testgnb_gtpu_send(gtpu, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
/*
* Send Service request Using UplinkNASTransport
* - Uplink Data Status
*/
test_ue.service_request_type.integrity_protected = 1;
test_ue.service_request_type.ciphered = 1;
test_ue.service_request_type.uplink_data_status = 1;
test_ue.service_request_type.psimask.uplink_data_status =
1 << test_sess.psi;
gmmbuf = testgmm_build_service_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
sendbuf = testngap_build_uplink_nas_transport(&test_ue, gmmbuf);
ABTS_PTR_NOTNULL(tc, sendbuf);
rv = testgnb_ngap_send(ngap, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive Service accept */
recvbuf = testgnb_ngap_read(ngap);
ABTS_PTR_NOTNULL(tc, recvbuf);
testngap_recv(&test_ue, recvbuf);
ABTS_INT_EQUAL(tc, 0x0000, test_ue.pdu_session_reactivation_result);
/* Send GTP-U ICMP Packet */
rv = test_gtpu_build_ping(&sendbuf, &test_sess, "10.45.0.1");
ABTS_INT_EQUAL(tc, OGS_OK, rv);
rv = testgnb_gtpu_send(gtpu, sendbuf);
ABTS_INT_EQUAL(tc, OGS_OK, rv);
/* Receive GTP-U ICMP Packet */
recvbuf = testgnb_gtpu_read(gtpu);
ABTS_PTR_NOTNULL(tc, recvbuf);
ogs_pkbuf_free(recvbuf);
ogs_msleep(50);
/********** Remove Subscriber in Database */
doc = BCON_NEW("imsi", BCON_UTF8(test_ue.imsi));
ABTS_PTR_NOTNULL(tc, doc);
ABTS_TRUE(tc, mongoc_collection_remove(collection,
MONGOC_REMOVE_SINGLE_REMOVE, doc, NULL, &error))
bson_destroy(doc);
mongoc_collection_destroy(collection);
/* gNB disonncect from UPF */
testgnb_gtpu_close(gtpu);
/* gNB disonncect from AMF */
testgnb_ngap_close(ngap);
/* Clear Test UE Context */
test_ue_remove(&test_ue);
}
abts_suite *test_idle(abts_suite *suite)
{
suite = ADD_SUITE(suite)
abts_run_test(suite, test1_func, NULL);
abts_run_test(suite, test2_func, NULL);
abts_run_test(suite, test3_func, NULL);
return suite;
}

View File

@ -183,13 +183,13 @@ static void test1_func(abts_case *tc, void *data)
bson_destroy(doc);
/* Send Registration request */
gmmbuf = testgmm_build_registration_request(&test_ue);
gmmbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, gmmbuf);
test_ue.registration_request_type.requested_nssai = 1;
test_ue.registration_request_type.last_visited_registered_tai = 1;
test_ue.registration_request_type.ue_usage_setting = 1;
nasbuf = testgmm_build_registration_request(&test_ue);
nasbuf = testgmm_build_registration_request(&test_ue, NULL);
ABTS_PTR_NOTNULL(tc, nasbuf);
sendbuf = testngap_build_initial_ue_message(&test_ue, gmmbuf, false);