Files
openairinterface5g/openair3/NGAP/ngap_gNB_handlers.c
T
Cedric Roux eeca38368e gnb sa: improve security
Note: some modifications have been done to the UE too, but for syntactic
reasons. The UE may fail to work, not tested.

For the UE, we have the problem of handling properly SecurityModeCommand.
We don't verify its integrity. This is a bit complicated to handle properly
and may require some API changes in the PDCP layer. So, as of today, the
integrity of this message is not verified.

Also, NSA mode has been touched, but it should not be a problem. But not
tested, so not sure.
2021-09-06 11:06:47 +02:00

1928 lines
86 KiB
C

/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file ngap_gNB_handlers.c
* \brief ngap messages handlers for gNB part
* \author Yoshio INOUE, Masayuki HARADA
* \email yoshio.inoue@fujitsu.com,masayuki.harada@fujitsu.com (yoshio.inoue%40fujitsu.com%2cmasayuki.harada%40fujitsu.com)
* \date 2020
* \version 0.1
*/
#include <stdint.h>
#include "intertask_interface.h"
#include "asn1_conversions.h"
#include "ngap_common.h"
// #include "ngap_gNB.h"
#include "ngap_gNB_defs.h"
#include "ngap_gNB_handlers.h"
#include "ngap_gNB_decoder.h"
#include "ngap_gNB_ue_context.h"
#include "ngap_gNB_trace.h"
#include "ngap_gNB_nas_procedures.h"
#include "ngap_gNB_management_procedures.h"
#include "ngap_gNB_default_values.h"
#include "assertions.h"
#include "conversions.h"
#include "msc.h"
#include "NGAP_NonDynamic5QIDescriptor.h"
static
int ngap_gNB_handle_ng_setup_response(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
static
int ngap_gNB_handle_ng_setup_failure(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
static
int ngap_gNB_handle_error_indication(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
static
int ngap_gNB_handle_initial_context_request(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
static
int ngap_gNB_handle_ue_context_release_command(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
static
int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
static
int ngap_gNB_handle_paging(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
static
int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
static
int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
static
int ngap_gNB_handle_ng_path_switch_request_ack(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
static
int ngap_gNB_handle_ng_path_switch_request_failure(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
static
int ngap_gNB_handle_ng_ENDC_pdusession_modification_confirm(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu);
/* Handlers matrix. Only gNB related procedure present here */
ngap_message_decoded_callback ngap_messages_callback[][3] = {
{ 0, 0, 0 }, /* AMFConfigurationUpdate */
{ 0, 0, 0 }, /* AMFStatusIndication */
{ 0, 0, 0 }, /* CellTrafficTrace */
{ ngap_gNB_handle_deactivate_trace, 0, 0 }, /* DeactivateTrace */
{ ngap_gNB_handle_nas_downlink, 0, 0 }, /* DownlinkNASTransport */
{ 0, 0, 0 }, /* DownlinkNonUEAssociatedNRPPaTransport */
{ 0, 0, 0 }, /* DownlinkRANConfigurationTransfer */
{ 0, 0, 0 }, /* DownlinkRANStatusTransfer */
{ 0, 0, 0 }, /* DownlinkUEAssociatedNRPPaTransport */
{ ngap_gNB_handle_error_indication, 0, 0 }, /* ErrorIndication */
{ 0, 0, 0 }, /* HandoverCancel */
{ 0, 0, 0 }, /* HandoverNotification */
{ 0, 0, 0 }, /* HandoverPreparation */
{ 0, 0, 0 }, /* HandoverResourceAllocation */
{ ngap_gNB_handle_initial_context_request, 0, 0 }, /* InitialContextSetup */
{ 0, 0, 0 }, /* InitialUEMessage */
{ 0, 0, 0 }, /* LocationReportingControl */
{ 0, 0, 0 }, /* LocationReportingFailureIndication */
{ 0, 0, 0 }, /* LocationReport */
{ 0, 0, 0 }, /* NASNonDeliveryIndication */
{ 0, 0, 0 }, /* NGReset */
{ 0, ngap_gNB_handle_ng_setup_response, ngap_gNB_handle_ng_setup_failure }, /* NGSetup */
{ 0, 0, 0 }, /* OverloadStart */
{ 0, 0, 0 }, /* OverloadStop */
{ ngap_gNB_handle_paging, 0, 0 }, /* Paging */
{ 0, ngap_gNB_handle_ng_path_switch_request_ack, ngap_gNB_handle_ng_path_switch_request_failure }, /* PathSwitchRequest */
{ ngap_gNB_handle_pdusession_modify_request, 0, 0 }, /* PDUSessionResourceModify */
{ 0, ngap_gNB_handle_ng_ENDC_pdusession_modification_confirm, 0 }, /* PDUSessionResourceModifyIndication */
{ ngap_gNB_handle_pdusession_release_command, 0, 0 }, /* PDUSessionResourceRelease */
{ ngap_gNB_handle_pdusession_setup_request, 0, 0 }, /* PDUSessionResourceSetup */
{ 0, 0, 0 }, /* PDUSessionResourceNotify */
{ 0, 0, 0 }, /* PrivateMessage */
{ 0, 0, 0 }, /* PWSCancel */
{ 0, 0, 0 }, /* PWSFailureIndication */
{ 0, 0, 0 }, /* PWSRestartIndication */
{ 0, 0, 0 }, /* RANConfigurationUpdate */
{ 0, 0, 0 }, /* RerouteNASRequest */
{ 0, 0, 0 }, /* RRCInactiveTransitionReport */
{ 0, 0, 0 }, /* TraceFailureIndication */
{ ngap_gNB_handle_trace_start, 0, 0 }, /* TraceStart */
{ 0, 0, 0 }, /* UEContextModification */
{ ngap_gNB_handle_ue_context_release_command, 0, 0 }, /* UEContextRelease */
{ 0, 0, 0 }, /* UEContextReleaseRequest */
{ 0, 0, 0 }, /* UERadioCapabilityCheck */
{ 0, 0, 0 }, /* UERadioCapabilityInfoIndication */
{ 0, 0, 0 }, /* UETNLABindingRelease */
{ 0, 0, 0 }, /* UplinkNASTransport */
{ 0, 0, 0 }, /* UplinkNonUEAssociatedNRPPaTransport */
{ 0, 0, 0 }, /* UplinkRANConfigurationTransfer */
{ 0, 0, 0 }, /* UplinkRANStatusTransfer */
{ 0, 0, 0 }, /* UplinkUEAssociatedNRPPaTransport */
{ 0, 0, 0 }, /* WriteReplaceWarning */
{ 0, 0, 0 }, /* SecondaryRATDataUsageReport */
};
char *ngap_direction2String(int ngap_dir) {
static char *ngap_direction_String[] = {
"", /* Nothing */
"Originating message", /* originating message */
"Successfull outcome", /* successfull outcome */
"UnSuccessfull outcome", /* successfull outcome */
};
return(ngap_direction_String[ngap_dir]);
}
void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shutdown) {
if (sctp_shutdown) {
/* A previously connected AMF has been shutdown */
/* TODO check if it was used by some gNB and send a message to inform these gNB if there is no more associated AMF */
if (amf_desc_p->state == NGAP_GNB_STATE_CONNECTED) {
amf_desc_p->state = NGAP_GNB_STATE_DISCONNECTED;
if (amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb > 0) {
/* Decrease associated AMF number */
amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb --;
}
/* If there are no more associated AMF, inform gNB app */
if (amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb == 0) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_DEREGISTERED_GNB_IND);
NGAP_DEREGISTERED_GNB_IND(message_p).nb_amf = 0;
itti_send_msg_to_task(TASK_GNB_APP, amf_desc_p->ngap_gNB_instance->instance, message_p);
}
}
} else {
/* Check that at least one setup message is pending */
DevCheck(amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb > 0, amf_desc_p->ngap_gNB_instance->instance,
amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb, 0);
if (amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb > 0) {
/* Decrease pending messages number */
amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb --;
}
/* If there are no more pending messages, inform gNB app */
if (amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb == 0) {
MessageDef *message_p;
message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_REGISTER_GNB_CNF);
NGAP_REGISTER_GNB_CNF(message_p).nb_amf = amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb;
itti_send_msg_to_task(TASK_GNB_APP, amf_desc_p->ngap_gNB_instance->instance, message_p);
}
}
}
int ngap_gNB_handle_message(uint32_t assoc_id, int32_t stream,
const uint8_t *const data, const uint32_t data_length) {
NGAP_NGAP_PDU_t pdu;
int ret;
DevAssert(data != NULL);
memset(&pdu, 0, sizeof(pdu));
if (ngap_gNB_decode_pdu(&pdu, data, data_length) < 0) {
NGAP_ERROR("Failed to decode PDU\n");
return -1;
}
/* Checking procedure Code and direction of message */
if (pdu.choice.initiatingMessage->procedureCode >= sizeof(ngap_messages_callback) / (3 * sizeof(
ngap_message_decoded_callback))
|| (pdu.present > NGAP_NGAP_PDU_PR_unsuccessfulOutcome)) {
NGAP_ERROR("[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
assoc_id, pdu.choice.initiatingMessage->procedureCode, pdu.present);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu);
return -1;
}
/* No handler present.
* This can mean not implemented or no procedure for gNB (wrong direction).
*/
if (ngap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1] == NULL) {
NGAP_ERROR("[SCTP %d] No handler for procedureCode %ld in %s\n",
assoc_id, pdu.choice.initiatingMessage->procedureCode,
ngap_direction2String(pdu.present - 1));
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu);
return -1;
}
/* Calling the right handler */
ret = (*ngap_messages_callback[pdu.choice.initiatingMessage->procedureCode][pdu.present - 1])
(assoc_id, stream, &pdu);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_NGAP_NGAP_PDU, &pdu);
return ret;
}
static
int ngap_gNB_handle_ng_setup_failure(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
NGAP_NGSetupFailure_t *container;
NGAP_NGSetupFailureIEs_t *ie;
ngap_gNB_amf_data_t *amf_desc_p;
DevAssert(pdu != NULL);
container = &pdu->choice.unsuccessfulOutcome->value.choice.NGSetupFailure;
/* S1 Setup Failure == Non UE-related procedure -> stream 0 */
if (stream != 0) {
NGAP_WARN("[SCTP %d] Received s1 setup failure on stream != 0 (%d)\n",
assoc_id, stream);
}
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received S1 setup response for non existing "
"AMF context\n", assoc_id);
return -1;
}
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_NGSetupFailureIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_Cause,true);
if ((ie->value.choice.Cause.present == NGAP_Cause_PR_misc) &&
(ie->value.choice.Cause.choice.misc == NGAP_CauseMisc_unspecified)) {
NGAP_WARN("Received NG setup failure for AMF... AMF is not ready\n");
} else {
NGAP_ERROR("Received NG setup failure for AMF... please check your parameters\n");
}
amf_desc_p->state = NGAP_GNB_STATE_WAITING;
ngap_handle_ng_setup_message(amf_desc_p, 0);
return 0;
}
static
int ngap_gNB_handle_ng_setup_response(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
NGAP_NGSetupResponse_t *container;
NGAP_NGSetupResponseIEs_t *ie;
ngap_gNB_amf_data_t *amf_desc_p;
int i;
DevAssert(pdu != NULL);
container = &pdu->choice.successfulOutcome->value.choice.NGSetupResponse;
/* NG Setup Response == Non UE-related procedure -> stream 0 */
if (stream != 0) {
NGAP_ERROR("[SCTP %d] Received ng setup response on stream != 0 (%d)\n",
assoc_id, stream);
return -1;
}
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received NG setup response for non existing "
"AMF context\n", assoc_id);
return -1;
}
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_NGSetupResponseIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_ServedGUAMIList, true);
/* The list of served guami can contain at most 256 elements.
* NR related guami is the first element in the list, i.e with an id of 0.
*/
NGAP_DEBUG("servedGUAMIs.list.count %d\n", ie->value.choice.ServedGUAMIList.list.count);
DevAssert(ie->value.choice.ServedGUAMIList.list.count > 0);
DevAssert(ie->value.choice.ServedGUAMIList.list.count <= NGAP_maxnoofServedGUAMIs);
for (i = 0; i < ie->value.choice.ServedGUAMIList.list.count; i++) {
NGAP_ServedGUAMIItem_t *guami_item_p;
struct served_guami_s *new_guami_p;
guami_item_p = ie->value.choice.ServedGUAMIList.list.array[i];
new_guami_p = calloc(1, sizeof(struct served_guami_s));
STAILQ_INIT(&new_guami_p->served_plmns);
STAILQ_INIT(&new_guami_p->served_region_ids);
STAILQ_INIT(&new_guami_p->amf_set_ids);
STAILQ_INIT(&new_guami_p->amf_pointers);
NGAP_PLMNIdentity_t *plmn_identity_p;
struct plmn_identity_s *new_plmn_identity_p;
plmn_identity_p = &guami_item_p->gUAMI.pLMNIdentity;
new_plmn_identity_p = calloc(1, sizeof(struct plmn_identity_s));
TBCD_TO_MCC_MNC(plmn_identity_p, new_plmn_identity_p->mcc,
new_plmn_identity_p->mnc, new_plmn_identity_p->mnc_digit_length);
STAILQ_INSERT_TAIL(&new_guami_p->served_plmns, new_plmn_identity_p, next);
new_guami_p->nb_served_plmns++;
NGAP_AMFRegionID_t *amf_region_id_p;
struct served_region_id_s *new_region_id_p;
amf_region_id_p = &guami_item_p->gUAMI.aMFRegionID;
new_region_id_p = calloc(1, sizeof(struct served_region_id_s));
OCTET_STRING_TO_INT8(amf_region_id_p, new_region_id_p->amf_region_id);
STAILQ_INSERT_TAIL(&new_guami_p->served_region_ids, new_region_id_p, next);
new_guami_p->nb_region_id++;
NGAP_AMFSetID_t *amf_set_id_p;
struct amf_set_id_s *new_amf_set_id_p;
amf_set_id_p = &guami_item_p->gUAMI.aMFSetID;
new_amf_set_id_p = calloc(1, sizeof(struct amf_set_id_s));
OCTET_STRING_TO_INT16(amf_set_id_p, new_amf_set_id_p->amf_set_id);
STAILQ_INSERT_TAIL(&new_guami_p->amf_set_ids, new_amf_set_id_p, next);
new_guami_p->nb_amf_set_id++;
NGAP_AMFPointer_t *amf_pointer_p;
struct amf_pointer_s *new_amf_pointer_p;
amf_pointer_p = &guami_item_p->gUAMI.aMFPointer;
new_amf_pointer_p = calloc(1, sizeof(struct amf_pointer_s));
OCTET_STRING_TO_INT8(amf_pointer_p, new_amf_pointer_p->amf_pointer);
STAILQ_INSERT_TAIL(&new_guami_p->amf_pointers, new_amf_pointer_p, next);
new_guami_p->nb_amf_pointer++;
STAILQ_INSERT_TAIL(&amf_desc_p->served_guami, new_guami_p, next);
}
/* Set the capacity of this AMF */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_NGSetupResponseIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_RelativeAMFCapacity, true);
amf_desc_p->relative_amf_capacity = ie->value.choice.RelativeAMFCapacity;
/* mandatory set the amf name */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_NGSetupResponseIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_AMFName, true);
if (ie) {
amf_desc_p->amf_name = calloc(ie->value.choice.AMFName.size + 1, sizeof(char));
memcpy(amf_desc_p->amf_name, ie->value.choice.AMFName.buf,
ie->value.choice.AMFName.size);
/* Convert the amf name to a printable string */
amf_desc_p->amf_name[ie->value.choice.AMFName.size] = '\0';
}
/* mandatory set the plmn supports */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_NGSetupResponseIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_PLMNSupportList, true);
NGAP_DEBUG("PLMNSupportList.list.count %d\n", ie->value.choice.PLMNSupportList.list.count);
DevAssert(ie->value.choice.PLMNSupportList.list.count > 0);
DevAssert(ie->value.choice.PLMNSupportList.list.count <= NGAP_maxnoofPLMNs);
STAILQ_INIT(&amf_desc_p->plmn_supports);
for (i = 0; i < ie->value.choice.ServedGUAMIList.list.count; i++) {
NGAP_PLMNSupportItem_t *plmn_support_item_p;
struct plmn_support_s *new_plmn_support_p;
NGAP_SliceSupportItem_t *slice_support_item_p;
struct slice_support_s *new_slice_support_p;
plmn_support_item_p = ie->value.choice.PLMNSupportList.list.array[i];
new_plmn_support_p = calloc(1, sizeof(struct plmn_support_s));
TBCD_TO_MCC_MNC(&plmn_support_item_p->pLMNIdentity, new_plmn_support_p->plmn_identity.mcc,
new_plmn_support_p->plmn_identity.mnc, new_plmn_support_p->plmn_identity.mnc_digit_length);
NGAP_DEBUG("PLMNSupportList.list.count %d\n", plmn_support_item_p->sliceSupportList.list.count);
DevAssert(plmn_support_item_p->sliceSupportList.list.count > 0);
DevAssert(plmn_support_item_p->sliceSupportList.list.count <= NGAP_maxnoofSliceItems);
STAILQ_INIT(&new_plmn_support_p->slice_supports);
for(int j=0; j<plmn_support_item_p->sliceSupportList.list.count; j++) {
slice_support_item_p = plmn_support_item_p->sliceSupportList.list.array[j];
new_slice_support_p = calloc(1, sizeof(struct slice_support_s));
OCTET_STRING_TO_INT8(&slice_support_item_p->s_NSSAI.sST, new_slice_support_p->sST);
if(slice_support_item_p->s_NSSAI.sD != NULL) {
new_slice_support_p->sD_flag = 1;
new_slice_support_p->sD[0] = slice_support_item_p->s_NSSAI.sD->buf[0];
new_slice_support_p->sD[1] = slice_support_item_p->s_NSSAI.sD->buf[1];
new_slice_support_p->sD[2] = slice_support_item_p->s_NSSAI.sD->buf[2];
}
STAILQ_INSERT_TAIL(&new_plmn_support_p->slice_supports, new_slice_support_p, next);
}
STAILQ_INSERT_TAIL(&amf_desc_p->plmn_supports, new_plmn_support_p, next);
}
/* The association is now ready as gNB and AMF know parameters of each other.
* Mark the association as UP to enable UE contexts creation.
*/
amf_desc_p->state = NGAP_GNB_STATE_CONNECTED;
amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb ++;
ngap_handle_ng_setup_message(amf_desc_p, 0);
return 0;
}
static
int ngap_gNB_handle_error_indication(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
NGAP_ErrorIndication_t *container;
NGAP_ErrorIndicationIEs_t *ie;
ngap_gNB_amf_data_t *amf_desc_p;
uint64_t amf_ue_ngap_id;
DevAssert(pdu != NULL);
container = &pdu->choice.initiatingMessage->value.choice.ErrorIndication;
/* NG Setup Failure == Non UE-related procedure -> stream 0 */
if (stream != 0) {
NGAP_WARN("[SCTP %d] Received ng Error indication on stream != 0 (%d)\n",
assoc_id, stream);
}
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received ng Error indication for non existing "
"AMF context\n", assoc_id);
return -1;
}
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_ErrorIndicationIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, false);
/* optional */
if (ie != NULL) {
asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id);
NGAP_WARN("Received NG Error indication AMF UE NGAP ID 0x%lx\n", amf_ue_ngap_id);
}
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_ErrorIndicationIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, false);
/* optional */
if (ie != NULL) {
NGAP_WARN("Received NG Error indication gNB UE NGAP ID 0x%lx\n", ie->value.choice.RAN_UE_NGAP_ID);
}
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_ErrorIndicationIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_Cause, false);
/* optional */
if (ie) {
switch(ie->value.choice.Cause.present) {
case NGAP_Cause_PR_NOTHING:
NGAP_WARN("Received NG Error indication cause NOTHING\n");
break;
case NGAP_Cause_PR_radioNetwork:
switch (ie->value.choice.Cause.choice.radioNetwork) {
case NGAP_CauseRadioNetwork_unspecified:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_unspecified\n");
break;
case NGAP_CauseRadioNetwork_txnrelocoverall_expiry:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_txnrelocoverall_expiry\n");
break;
case NGAP_CauseRadioNetwork_successful_handover:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_successful_handover\n");
break;
case NGAP_CauseRadioNetwork_release_due_to_ngran_generated_reason:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_release_due_to_ngran_generated_reason\n");
break;
case NGAP_CauseRadioNetwork_release_due_to_5gc_generated_reason:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_release_due_to_5gc_generated_reason\n");
break;
case NGAP_CauseRadioNetwork_handover_cancelled:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_handover_cancelled\n");
break;
case NGAP_CauseRadioNetwork_partial_handover:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_partial_handover\n");
break;
case NGAP_CauseRadioNetwork_ho_failure_in_target_5GC_ngran_node_or_target_system:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ho_failure_in_target_5GC_ngran_node_or_target_system\n");
break;
case NGAP_CauseRadioNetwork_ho_target_not_allowed:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ho_target_not_allowed\n");
break;
case NGAP_CauseRadioNetwork_tngrelocoverall_expiry:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_tngrelocoverall_expiry\n");
break;
case NGAP_CauseRadioNetwork_tngrelocprep_expiry:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_tngrelocprep_expiry\n");
break;
case NGAP_CauseRadioNetwork_cell_not_available:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_cell_not_available\n");
break;
case NGAP_CauseRadioNetwork_unknown_targetID:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_unknown_targetID\n");
break;
case NGAP_CauseRadioNetwork_no_radio_resources_available_in_target_cell:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_no_radio_resources_available_in_target_cell\n");
break;
case NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID\n");
break;
case NGAP_CauseRadioNetwork_inconsistent_remote_UE_NGAP_ID:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_inconsistent_remote_UE_NGAP_ID\n");
break;
case NGAP_CauseRadioNetwork_handover_desirable_for_radio_reason:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_handover_desirable_for_radio_reason\n");
break;
case NGAP_CauseRadioNetwork_time_critical_handover:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_time_critical_handover\n");
break;
case NGAP_CauseRadioNetwork_resource_optimisation_handover:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_resource_optimisation_handover\n");
break;
case NGAP_CauseRadioNetwork_reduce_load_in_serving_cell:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_reduce_load_in_serving_cell\n");
break;
case NGAP_CauseRadioNetwork_user_inactivity:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_user_inactivity\n");
break;
case NGAP_CauseRadioNetwork_radio_connection_with_ue_lost:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_radio_connection_with_ue_lost\n");
break;
case NGAP_CauseRadioNetwork_radio_resources_not_available:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_radio_resources_not_available\n");
break;
case NGAP_CauseRadioNetwork_invalid_qos_combination:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_invalid_qos_combination\n");
break;
case NGAP_CauseRadioNetwork_failure_in_radio_interface_procedure:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_failure_in_radio_interface_procedure\n");
break;
case NGAP_CauseRadioNetwork_interaction_with_other_procedure:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_interaction_with_other_procedure\n");
break;
case NGAP_CauseRadioNetwork_unknown_PDU_session_ID:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_unknown_PDU_session_ID\n");
break;
case NGAP_CauseRadioNetwork_unkown_qos_flow_ID:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_unkown_qos_flow_ID\n");
break;
case NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_multiple_PDU_session_ID_instances\n");
break;
case NGAP_CauseRadioNetwork_multiple_qos_flow_ID_instances:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_multiple_qos_flow_ID_instances\n");
break;
case NGAP_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported\n");
break;
case NGAP_CauseRadioNetwork_ng_intra_system_handover_triggered:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ng_intra_system_handover_triggered\n");
break;
case NGAP_CauseRadioNetwork_ng_inter_system_handover_triggered:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ng_inter_system_handover_triggered\n");
break;
case NGAP_CauseRadioNetwork_xn_handover_triggered:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_xn_handover_triggered\n");
break;
case NGAP_CauseRadioNetwork_not_supported_5QI_value:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_not_supported_5QI_value\n");
break;
case NGAP_CauseRadioNetwork_ue_context_transfer:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ue_context_transfer\n");
break;
case NGAP_CauseRadioNetwork_ims_voice_eps_fallback_or_rat_fallback_triggered:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ims_voice_eps_fallback_or_rat_fallback_triggered\n");
break;
case NGAP_CauseRadioNetwork_up_integrity_protection_not_possible:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_up_integrity_protection_not_possible\n");
break;
case NGAP_CauseRadioNetwork_up_confidentiality_protection_not_possible:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_up_confidentiality_protection_not_possible\n");
break;
case NGAP_CauseRadioNetwork_slice_not_supported:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_slice_not_supported\n");
break;
case NGAP_CauseRadioNetwork_ue_in_rrc_inactive_state_not_reachable:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ue_in_rrc_inactive_state_not_reachable\n");
break;
case NGAP_CauseRadioNetwork_redirection:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_redirection\n");
break;
case NGAP_CauseRadioNetwork_resources_not_available_for_the_slice:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_resources_not_available_for_the_slice\n");
break;
case NGAP_CauseRadioNetwork_ue_max_integrity_protected_data_rate_reason:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_ue_max_integrity_protected_data_rate_reason\n");
break;
case NGAP_CauseRadioNetwork_release_due_to_cn_detected_mobility:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_release_due_to_cn_detected_mobility\n");
break;
case NGAP_CauseRadioNetwork_n26_interface_not_available:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_n26_interface_not_available\n");
break;
case NGAP_CauseRadioNetwork_release_due_to_pre_emption:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_release_due_to_pre_emption\n");
break;
case NGAP_CauseRadioNetwork_multiple_location_reporting_reference_ID_instances:
NGAP_WARN("Received NG Error indication NGAP_CauseRadioNetwork_multiple_location_reporting_reference_ID_instances\n");
break;
default:
NGAP_WARN("Received NG Error indication cause radio network case not handled\n");
}
break;
case NGAP_Cause_PR_transport:
switch (ie->value.choice.Cause.choice.transport) {
case NGAP_CauseTransport_transport_resource_unavailable:
NGAP_WARN("Received NG Error indication NGAP_CauseTransport_transport_resource_unavailable\n");
break;
case NGAP_CauseTransport_unspecified:
NGAP_WARN("Received NG Error indication NGAP_CauseTransport_unspecified\n");
break;
default:
NGAP_WARN("Received NG Error indication cause transport case not handled\n");
}
break;
case NGAP_Cause_PR_nas:
switch (ie->value.choice.Cause.choice.nas) {
case NGAP_CauseNas_normal_release:
NGAP_WARN("Received NG Error indication NGAP_CauseNas_normal_release\n");
break;
case NGAP_CauseNas_authentication_failure:
NGAP_WARN("Received NG Error indication NGAP_CauseNas_authentication_failure\n");
break;
case NGAP_CauseNas_deregister:
NGAP_WARN("Received NG Error indication NGAP_CauseNas_deregister\n");
break;
case NGAP_CauseNas_unspecified:
NGAP_WARN("Received NG Error indication NGAP_CauseNas_unspecified\n");
break;
default:
NGAP_WARN("Received NG Error indication cause nas case not handled\n");
}
break;
case NGAP_Cause_PR_protocol:
switch (ie->value.choice.Cause.choice.protocol) {
case NGAP_CauseProtocol_transfer_syntax_error:
NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_transfer_syntax_error\n");
break;
case NGAP_CauseProtocol_abstract_syntax_error_reject:
NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_abstract_syntax_error_reject\n");
break;
case NGAP_CauseProtocol_abstract_syntax_error_ignore_and_notify:
NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_abstract_syntax_error_ignore_and_notify\n");
break;
case NGAP_CauseProtocol_message_not_compatible_with_receiver_state:
NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_message_not_compatible_with_receiver_state\n");
break;
case NGAP_CauseProtocol_semantic_error:
NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_semantic_error\n");
break;
case NGAP_CauseProtocol_abstract_syntax_error_falsely_constructed_message:
NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_abstract_syntax_error_falsely_constructed_message\n");
break;
case NGAP_CauseProtocol_unspecified:
NGAP_WARN("Received NG Error indication NGAP_CauseProtocol_unspecified\n");
break;
default:
NGAP_WARN("Received NG Error indication cause protocol case not handled\n");
}
break;
case NGAP_Cause_PR_misc:
switch (ie->value.choice.Cause.choice.protocol) {
case NGAP_CauseMisc_control_processing_overload:
NGAP_WARN("Received NG Error indication NGAP_CauseMisc_control_processing_overload\n");
break;
case NGAP_CauseMisc_not_enough_user_plane_processing_resources:
NGAP_WARN("Received NG Error indication NGAP_CauseMisc_not_enough_user_plane_processing_resources\n");
break;
case NGAP_CauseMisc_hardware_failure:
NGAP_WARN("Received NG Error indication NGAP_CauseMisc_hardware_failure\n");
break;
case NGAP_CauseMisc_om_intervention:
NGAP_WARN("Received NG Error indication NGAP_CauseMisc_om_intervention\n");
break;
case NGAP_CauseMisc_unspecified:
NGAP_WARN("Received NG Error indication NGAP_CauseMisc_unspecified\n");
break;
case NGAP_CauseMisc_unknown_PLMN:
NGAP_WARN("Received NG Error indication NGAP_CauseMisc_unknown_PLMN\n");
break;
default:
NGAP_WARN("Received NG Error indication cause misc case not handled\n");
}
break;
default:
NGAP_WARN("Received NG Error indication cause NGAP_Cause_PR_choice_Extensions\n");
break;
}
}
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_ErrorIndicationIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_CriticalityDiagnostics, false);
if (ie) {
// TODO continue
}
// TODO continue
return 0;
}
static
int ngap_gNB_handle_initial_context_request(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
int i;
ngap_gNB_amf_data_t *amf_desc_p = NULL;
ngap_gNB_ue_context_t *ue_desc_p = NULL;
MessageDef *message_p = NULL;
NGAP_InitialContextSetupRequest_t *container;
NGAP_InitialContextSetupRequestIEs_t *ie;
NGAP_RAN_UE_NGAP_ID_t ran_ue_ngap_id;
uint64_t amf_ue_ngap_id;
DevAssert(pdu != NULL);
container = &pdu->choice.initiatingMessage->value.choice.InitialContextSetupRequest;
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received initial context setup request for non "
"existing AMF context\n", assoc_id);
return -1;
}
/* id-AMF-UE-NGAP-ID */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id);
} else {
return -1;
}
/* id-RAN-UE-NGAP-ID */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
ran_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID;
if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance,
ran_ue_ngap_id)) == NULL) {
NGAP_ERROR("[SCTP %d] Received initial context setup request for non "
"existing UE context 0x%06lx\n", assoc_id,
ran_ue_ngap_id);
return -1;
}
} else {
return -1;
}
/* Initial context request = UE-related procedure -> stream != 0 */
//if (stream == 0) {
// NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
// assoc_id, stream);
// return -1;
//}
ue_desc_p->rx_stream = stream;
ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id;
message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_INITIAL_CONTEXT_SETUP_REQ);
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id;
ue_desc_p->ue_initial_id = 0;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).gNB_ue_ngap_id = ue_desc_p->gNB_ue_ngap_id;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).amf_ue_ngap_id = ue_desc_p->amf_ue_ngap_id;
/* id-UEAggregateMaximumBitRate */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate, false);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitRate.uEAggregateMaximumBitRateUL),
&(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_ul));
asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitRate.uEAggregateMaximumBitRateDL),
&(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl));
} else {
NGAP_ERROR("could not found NGAP_ProtocolIE_ID_id_UEAggregateMaximumBitRate\n");
}
/* id-GUAMI */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_GUAMI, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
TBCD_TO_MCC_MNC(&ie->value.choice.GUAMI.pLMNIdentity, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.mcc,
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.mnc, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.mnc_len);
OCTET_STRING_TO_INT8(&ie->value.choice.GUAMI.aMFRegionID, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.amf_region_id);
OCTET_STRING_TO_INT16(&ie->value.choice.GUAMI.aMFSetID, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.amf_set_id);
OCTET_STRING_TO_INT8(&ie->value.choice.GUAMI.aMFPointer, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).guami.amf_pointer);
} else {/* ie != NULL */
return -1;
}
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq, false);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_of_pdusessions =
ie->value.choice.PDUSessionResourceSetupListCxtReq.list.count;
for (i = 0; i < ie->value.choice.PDUSessionResourceSetupListCxtReq.list.count; i++) {
NGAP_PDUSessionResourceSetupItemCxtReq_t *item_p;
asn_dec_rval_t dec_rval;
NGAP_PDUSessionResourceSetupRequestTransfer_t *pdusessionTransfer_p = NULL;
NGAP_PDUSessionResourceSetupRequestTransferIEs_t *pdusessionTransfer_ies = NULL;
item_p = (NGAP_PDUSessionResourceSetupItemCxtReq_t *)ie->value.choice.PDUSessionResourceSetupListCxtReq.list.array[i];
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].pdusession_id = item_p->pDUSessionID;
if (item_p->nAS_PDU != NULL) {
/* Only copy NAS pdu if present */
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.length = item_p->nAS_PDU->size;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.buffer =
malloc(sizeof(uint8_t) * item_p->nAS_PDU->size);
memcpy(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.buffer,
item_p->nAS_PDU->buf, item_p->nAS_PDU->size);
NGAP_DEBUG("Received NAS message with the PDUSESSION setup procedure\n");
} else {
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.length = 0;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nas_pdu.buffer = NULL;
}
dec_rval = aper_decode(NULL,
&asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer,
(void **)&pdusessionTransfer_p,
item_p->pDUSessionResourceSetupRequestTransfer.buf,
item_p->pDUSessionResourceSetupRequestTransfer.size, 0, 0);
if(dec_rval.code != RC_OK) {
NGAP_ERROR("could not decode PDUSessionResourceSetupRequestTransfer\n");
return -1;
}
for(int j=0; j< pdusessionTransfer_p->protocolIEs.list.count; j++) {
pdusessionTransfer_ies = pdusessionTransfer_p->protocolIEs.list.array[j];
switch(pdusessionTransfer_ies->id) {
/* optional PDUSessionAggregateMaximumBitRate */
case NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate:
break;
/* mandatory UL-NGU-UP-TNLInformation */
case NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLInformation:
{
NGAP_GTPTunnel_t *gTPTunnel_p;
gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel;
/* Set the transport layer address */
memcpy(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].upf_addr.buffer,
gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size);
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].upf_addr.length =
gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused;
/* GTP tunnel endpoint ID */
OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].gtp_teid);
}
break;
/* optional AdditionalUL-NGU-UP-TNLInformation */
case NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation:
break;
/* optional DataForwardingNotPossible */
case NGAP_ProtocolIE_ID_id_DataForwardingNotPossible:
break;
/* mandatory PDUSessionType */
case NGAP_ProtocolIE_ID_id_PDUSessionType:
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType;
break;
/* optional SecurityIndication */
case NGAP_ProtocolIE_ID_id_SecurityIndication:
break;
/* optional NetworkInstance */
case NGAP_ProtocolIE_ID_id_NetworkInstance:
break;
/* mandatory QosFlowSetupRequestList */
case NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList:
{
NGAP_QosFlowSetupRequestItem_t *qosFlowItem_p;
NGAP_DEBUG("QosFlowSetupRequestList.list.count %d\n", pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count);
DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count > 0);
DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count <= NGAP_maxnoofQosFlows);
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count;
for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; qosIdx++) {
qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.array[qosIdx];
/* Set the QOS informations */
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){
if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].fiveQI =
(uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI;
}
}
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.priority_level =
qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability =
qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionCapability;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).pdusession_param[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability =
qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionVulnerability;
}
}
break;
/* optional CommonNetworkInstance */
case NGAP_ProtocolIE_ID_id_CommonNetworkInstance:
break;
default:
NGAP_ERROR("could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id);
return -1;
}
}
} /* for i... */
} else {/* ie != NULL */
NGAP_ERROR("could not found NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListCxtReq\n");
}
/* id-AllowedNSSAI */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_AllowedNSSAI, true);
//if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
NGAP_AllowedNSSAI_Item_t *allow_nssai_item_p = NULL;
//NGAP_DEBUG("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count);
//DevAssert(ie->value.choice.AllowedNSSAI.list.count > 0);
//DevAssert(ie->value.choice.AllowedNSSAI.list.count <= NGAP_maxnoofAllowedS_NSSAIs);
if (ie == NULL) {
NGAP_WARN("AllowedNSSAI not present, forging 2 NSSAI\n");
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = 2;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sST = 01;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD_flag = 1;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD[0] = 01;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD[1] = 02;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[0].sD[2] = 03;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sST = 01;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD_flag = 1;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[0] = 00;//11;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[1] = 00;//22;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[1].sD[2] = 01;//33;
} else {
NGAP_INFO("AllowedNSSAI.list.count %d\n", ie->value.choice.AllowedNSSAI.list.count);
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_allowed_nssais = ie->value.choice.AllowedNSSAI.list.count;
for(i = 0; i < ie->value.choice.AllowedNSSAI.list.count; i++) {
allow_nssai_item_p = ie->value.choice.AllowedNSSAI.list.array[i];
OCTET_STRING_TO_INT8(&allow_nssai_item_p->s_NSSAI.sST, NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sST);
if(allow_nssai_item_p->s_NSSAI.sD != NULL) {
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD_flag = 1;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD[0] = allow_nssai_item_p->s_NSSAI.sD->buf[0];
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD[1] = allow_nssai_item_p->s_NSSAI.sD->buf[1];
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).allowed_nssai[i].sD[2] = allow_nssai_item_p->s_NSSAI.sD->buf[2];
}
}
}
//} else {/* ie != NULL */
// return -1;
//}
/* id-UESecurityCapabilities */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_UESecurityCapabilities, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.nRencryption_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.nRencryptionAlgorithms);
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.nRintegrity_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.nRintegrityProtectionAlgorithms);
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.eUTRAencryption_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.eUTRAencryptionAlgorithms);
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.eUTRAintegrity_algorithms =
BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.eUTRAintegrityProtectionAlgorithms);
} else {/* ie != NULL */
return -1;
}
/* id-SecurityKey : Copy the security key */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_SecurityKey, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
memcpy(&NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key,
ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size);
} else {/* ie != NULL */
return -1;
}
/* id-MobilityRestrictionList */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_MobilityRestrictionList, false);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
NGAP_MobilityRestrictionList_t *mobility_rest_list_p = NULL;
mobility_rest_list_p = &ie->value.choice.MobilityRestrictionList;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction_flag = 1;
TBCD_TO_MCC_MNC(&mobility_rest_list_p->servingPLMN,
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction.serving_plmn.mcc,
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction.serving_plmn.mnc,
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).mobility_restriction.serving_plmn.mnc_digit_length);
}
/* id-NAS-PDU */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_InitialContextSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_NAS_PDU, false);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
if(ie->value.choice.NAS_PDU.size > 0) {
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu_flag = 1;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu.length = ie->value.choice.NAS_PDU.size;
NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu.buffer = malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size);
memcpy(NGAP_INITIAL_CONTEXT_SETUP_REQ(message_p).nas_pdu.buffer,
ie->value.choice.NAS_PDU.buf, ie->value.choice.NAS_PDU.size);
}
}
itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p);
return 0;
}
static
int ngap_gNB_handle_ue_context_release_command(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
ngap_gNB_amf_data_t *amf_desc_p = NULL;
ngap_gNB_ue_context_t *ue_desc_p = NULL;
MessageDef *message_p = NULL;
uint64_t amf_ue_ngap_id;
NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id;
NGAP_UEContextReleaseCommand_t *container;
NGAP_UEContextReleaseCommand_IEs_t *ie;
DevAssert(pdu != NULL);
container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand;
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received UE context release command for non "
"existing AMF context\n", assoc_id);
return -1;
}
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_UEContextReleaseCommand_IEs_t, ie, container,
NGAP_ProtocolIE_ID_id_UE_NGAP_IDs, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
switch (ie->value.choice.UE_NGAP_IDs.present) {
case NGAP_UE_NGAP_IDs_PR_uE_NGAP_ID_pair:
gnb_ue_ngap_id = ie->value.choice.UE_NGAP_IDs.choice.uE_NGAP_ID_pair->rAN_UE_NGAP_ID;
asn_INTEGER2ulong(&(ie->value.choice.UE_NGAP_IDs.choice.uE_NGAP_ID_pair->aMF_UE_NGAP_ID), &amf_ue_ngap_id);
MSC_LOG_RX_MESSAGE(
MSC_NGAP_GNB,
MSC_NGAP_AMF,
NULL,0,
"0 UEContextRelease/%s gNB_ue_ngap_id "NGAP_UE_ID_FMT" amf_ue_ngap_id "NGAP_UE_ID_FMT" len %u",
ngap_direction2String(pdu->present - 1),
gnb_ue_ngap_id,
amf_ue_ngap_id);
if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance,
gnb_ue_ngap_id)) == NULL) {
NGAP_ERROR("[SCTP %d] Received UE context release command for non "
"existing UE context 0x%06lx\n",
assoc_id,
gnb_ue_ngap_id);
return -1;
} else {
MSC_LOG_TX_MESSAGE(
MSC_NGAP_GNB,
MSC_RRC_GNB,
NULL,0,
"0 NGAP_UE_CONTEXT_RELEASE_COMMAND/%d gNB_ue_ngap_id "NGAP_UE_ID_FMT" ",
gnb_ue_ngap_id);
message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_UE_CONTEXT_RELEASE_COMMAND);
if (ue_desc_p->amf_ue_ngap_id == 0) { // case of Detach Request and switch off from RRC_IDLE mode
ue_desc_p->amf_ue_ngap_id = amf_ue_ngap_id;
}
NGAP_UE_CONTEXT_RELEASE_COMMAND(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id;
itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p);
return 0;
}
break;
//#warning "TODO mapping amf_ue_ngap_id gnb_ue_ngap_id?"
case NGAP_UE_NGAP_IDs_PR_aMF_UE_NGAP_ID:
asn_INTEGER2ulong(&(ie->value.choice.UE_NGAP_IDs.choice.aMF_UE_NGAP_ID), &amf_ue_ngap_id);
NGAP_ERROR("TO DO mapping amf_ue_ngap_id gnb_ue_ngap_id");
(void)amf_ue_ngap_id; /* TODO: remove - it's to remove gcc warning about unused var */
case NGAP_UE_NGAP_IDs_PR_NOTHING:
default:
NGAP_ERROR("NGAP_UE_CONTEXT_RELEASE_COMMAND not processed, missing info elements");
return -1;
}
} else {
return -1;
}
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_UEContextReleaseCommand_IEs_t, ie, container,
NGAP_ProtocolIE_ID_id_Cause, true);
/* TBD */
return 0;
}
static
int ngap_gNB_handle_pdusession_setup_request(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
// NGAP_AMF_UE_NGAP_ID_t amf_ue_ngap_id;
uint64_t amf_ue_ngap_id;
NGAP_RAN_UE_NGAP_ID_t ran_ue_ngap_id;
ngap_gNB_amf_data_t *amf_desc_p = NULL;
ngap_gNB_ue_context_t *ue_desc_p = NULL;
MessageDef *message_p = NULL;
NGAP_PDUSessionResourceSetupRequest_t *container;
NGAP_PDUSessionResourceSetupRequestIEs_t *ie;
DevAssert(pdu != NULL);
container = &pdu->choice.initiatingMessage->value.choice.PDUSessionResourceSetupRequest;
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received pdu session resource setup request for non "
"existing AMF context\n", assoc_id);
return -1;
}
/* id-AMF-UE-NGAP-ID */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id);
} else {
return -1;
}
/* id-gNB-UE-NGAP-ID */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
ran_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID;
} else {
return -1;
}
if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance,
ran_ue_ngap_id)) == NULL) {
NGAP_ERROR("[SCTP %d] Received pdu session resource setup request for non "
"existing UE context 0x%06lx\n", assoc_id,
ran_ue_ngap_id);
return -1;
}
/* Initial context request = UE-related procedure -> stream != 0 */
// if (stream == 0) {
// NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
// assoc_id, stream);
// return -1;
// }
ue_desc_p->rx_stream = stream;
if ( ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) {
NGAP_WARN("UE context amf_ue_ngap_id is different form that of the message (%lu != %lu)",
(uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id);
}
message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_SETUP_REQ);
NGAP_PDUSESSION_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id;
ue_desc_p->ue_initial_id = 0;
NGAP_PDUSESSION_SETUP_REQ(message_p).gNB_ue_ngap_id = ue_desc_p->gNB_ue_ngap_id;
NGAP_PDUSESSION_SETUP_REQ(message_p).amf_ue_ngap_id = ue_desc_p->amf_ue_ngap_id;
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceSetupRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSUReq, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
NGAP_PDUSESSION_SETUP_REQ(message_p).nb_pdusessions_tosetup =
ie->value.choice.PDUSessionResourceSetupListSUReq.list.count;
for (int i = 0; i < ie->value.choice.PDUSessionResourceSetupListSUReq.list.count; i++) {
NGAP_PDUSessionResourceSetupItemSUReq_t *item_p;
asn_dec_rval_t dec_rval;
NGAP_PDUSessionResourceSetupRequestTransfer_t *pdusessionTransfer_p = NULL;
NGAP_PDUSessionResourceSetupRequestTransferIEs_t *pdusessionTransfer_ies = NULL;
item_p = (NGAP_PDUSessionResourceSetupItemSUReq_t *)ie->value.choice.PDUSessionResourceSetupListSUReq.list.array[i];
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].pdusession_id = item_p->pDUSessionID;
// check for the NAS PDU
if (item_p->pDUSessionNAS_PDU->size > 0 ) {
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.length = item_p->pDUSessionNAS_PDU->size;
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionNAS_PDU->size);
memcpy(NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.buffer,
item_p->pDUSessionNAS_PDU->buf, item_p->pDUSessionNAS_PDU->size);
// NGAP_INFO("received a NAS PDU with size %d (%02x.%02x)\n",NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.length, item_p->nAS_PDU.buf[0], item_p->nAS_PDU.buf[1]);
} else {
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.length = 0;
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nas_pdu.buffer = NULL;
NGAP_WARN("NAS PDU is not provided, generate a PDUSESSION_SETUP Failure (TBD) back to AMF \n");
}
dec_rval = aper_decode(NULL,
&asn_DEF_NGAP_PDUSessionResourceSetupRequestTransfer,
(void **)&pdusessionTransfer_p,
item_p->pDUSessionResourceSetupRequestTransfer.buf,
item_p->pDUSessionResourceSetupRequestTransfer.size, 0, 0);
if(dec_rval.code != RC_OK) {
NGAP_ERROR("could not decode PDUSessionResourceSetupRequestTransfer\n");
return -1;
}
for(int j=0; j< pdusessionTransfer_p->protocolIEs.list.count; j++) {
pdusessionTransfer_ies = pdusessionTransfer_p->protocolIEs.list.array[j];
switch(pdusessionTransfer_ies->id) {
/* optional PDUSessionAggregateMaximumBitRate */
case NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate:
break;
/* mandatory UL-NGU-UP-TNLInformation */
case NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLInformation:
{
NGAP_GTPTunnel_t *gTPTunnel_p;
gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel;
/* The transport layer address for the IP packets */
OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].gtp_teid);
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].upf_addr.length =
gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused;
memcpy(NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].upf_addr.buffer ,
gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size);
}
break;
/* optional AdditionalUL-NGU-UP-TNLInformation */
case NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation:
break;
/* optional DataForwardingNotPossible */
case NGAP_ProtocolIE_ID_id_DataForwardingNotPossible:
break;
/* mandatory PDUSessionType */
case NGAP_ProtocolIE_ID_id_PDUSessionType:
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].upf_addr.pdu_session_type = (uint8_t)pdusessionTransfer_ies->value.choice.PDUSessionType;
break;
/* optional SecurityIndication */
case NGAP_ProtocolIE_ID_id_SecurityIndication:
break;
/* optional NetworkInstance */
case NGAP_ProtocolIE_ID_id_NetworkInstance:
break;
/* mandatory QosFlowSetupRequestList */
case NGAP_ProtocolIE_ID_id_QosFlowSetupRequestList:
{
NGAP_QosFlowSetupRequestItem_t *qosFlowItem_p;
NGAP_DEBUG("servedGUAMIs.list.count %d\n", pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count);
DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count > 0);
DevAssert(pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count <= NGAP_maxnoofQosFlows);
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count;
for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.count; qosIdx++){
qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowSetupRequestList.list.array[qosIdx];
/* Set the QOS informations */
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.present == NGAP_QosCharacteristics_PR_nonDynamic5QI){
if(qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI != NULL){
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].fiveQI =
(uint64_t)qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics.choice.nonDynamic5QI->fiveQI;
}
}
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.priority_level =
qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.priorityLevelARP;
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability =
qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionCapability;
NGAP_PDUSESSION_SETUP_REQ(message_p).pdusession_setup_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability =
qosFlowItem_p->qosFlowLevelQosParameters.allocationAndRetentionPriority.pre_emptionVulnerability;
}
}
break;
/* optional CommonNetworkInstance */
case NGAP_ProtocolIE_ID_id_CommonNetworkInstance:
break;
default:
NGAP_ERROR("could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id);
return -1;
}
}/* for j... */
} /* for i... */
itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p);
}else {/* ie == NULL */
NGAP_ERROR("could not found NGAP_ProtocolIE_ID_id_PDUSessionResourceSetupListSUReq\n");
return -1;
}
return 0;
}
static
int ngap_gNB_handle_paging(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
ngap_gNB_amf_data_t *amf_desc_p = NULL;
ngap_gNB_instance_t *ngap_gNB_instance = NULL;
MessageDef *message_p = NULL;
NGAP_Paging_t *container;
NGAP_PagingIEs_t *ie;
DevAssert(pdu != NULL);
container = &pdu->choice.initiatingMessage->value.choice.Paging;
// received Paging Message from AMF
NGAP_DEBUG("[SCTP %d] Received Paging Message From AMF\n",assoc_id);
/* Paging procedure -> stream != 0 */
if (stream == 0) {
LOG_W(NGAP,"[SCTP %d] Received Paging procedure on stream (%d)\n",
assoc_id, stream);
return -1;
}
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received Paging for non "
"existing AMF context\n", assoc_id);
return -1;
}
ngap_gNB_instance = amf_desc_p->ngap_gNB_instance;
if (ngap_gNB_instance == NULL) {
NGAP_ERROR("[SCTP %d] Received Paging for non existing AMF context : ngap_gNB_instance is NULL\n",
assoc_id);
return -1;
}
message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PAGING_IND);
/* convert NGAP_PagingIEs_t to ngap_paging_ind_t */
/* id-UEIdentityIndexValue : convert UE Identity Index value */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_UEPagingIdentity, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
OCTET_STRING_TO_INT16(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->aMFSetID, NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_set_id);
OCTET_STRING_TO_INT8(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->aMFPointer, NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_pointer);
OCTET_STRING_TO_INT32(&ie->value.choice.UEPagingIdentity.choice.fiveG_S_TMSI->fiveG_TMSI, NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.m_tmsi);
NGAP_DEBUG("[SCTP %d] Received Paging Identity amf_set_id %d, amf_pointer %d, m_tmsi %d\n",
assoc_id,
NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_set_id,
NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_pointer,
NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.m_tmsi);
} else {
return -1;
}
NGAP_PAGING_IND(message_p).paging_drx = NGAP_PAGING_DRX_256;
/* id-pagingDRX */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_PagingDRX, false);
/* optional */
if (ie) {
NGAP_PAGING_IND(message_p).paging_drx = ie->value.choice.PagingDRX;
} else {
NGAP_PAGING_IND(message_p).paging_drx = NGAP_PAGING_DRX_256;
}
memset (&NGAP_PAGING_IND(message_p).plmn_identity[0], 0, sizeof(plmn_identity_t)*256);
memset (&NGAP_PAGING_IND(message_p).tac[0], 0, sizeof(int16_t)*256);
NGAP_PAGING_IND(message_p).tai_size = 0;
/* id-TAIList */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PagingIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_TAIListForPaging, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
NGAP_INFO("[SCTP %d] Received Paging taiList For Paging: count %d\n", assoc_id, ie->value.choice.TAIListForPaging.list.count);
for (int i = 0; i < ie->value.choice.TAIListForPaging.list.count; i++) {
NGAP_TAIListForPagingItem_t *item_p;
item_p = (NGAP_TAIListForPagingItem_t *)ie->value.choice.TAIListForPaging.list.array[i];
TBCD_TO_MCC_MNC(&(item_p->tAI.pLMNIdentity), NGAP_PAGING_IND(message_p).plmn_identity[i].mcc,
NGAP_PAGING_IND(message_p).plmn_identity[i].mnc,
NGAP_PAGING_IND(message_p).plmn_identity[i].mnc_digit_length);
OCTET_STRING_TO_INT16(&(item_p->tAI.tAC), NGAP_PAGING_IND(message_p).tac[i]);
NGAP_PAGING_IND(message_p).tai_size++;
NGAP_DEBUG("[SCTP %d] Received Paging: MCC %d, MNC %d, TAC %d\n", assoc_id,
NGAP_PAGING_IND(message_p).plmn_identity[i].mcc,
NGAP_PAGING_IND(message_p).plmn_identity[i].mnc,
NGAP_PAGING_IND(message_p).tac[i]);
}
} else {
return -1;
}
//paging parameter values
NGAP_DEBUG("[SCTP %d] Received Paging parameters: Paging Identity amf_set_id %d amf_pointer %d m_tmsi %d paging_drx %d paging_priority %d\n",assoc_id,
NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_set_id,
NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.amf_pointer,
NGAP_PAGING_IND(message_p).ue_paging_identity.s_tmsi.m_tmsi,
NGAP_PAGING_IND(message_p).paging_drx, NGAP_PAGING_IND(message_p).paging_priority);
/* send message to RRC */
itti_send_msg_to_task(TASK_RRC_GNB, ngap_gNB_instance->instance, message_p);
return 0;
}
static
int ngap_gNB_handle_pdusession_modify_request(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
int i, nb_of_pdusessions_failed;
ngap_gNB_amf_data_t *amf_desc_p = NULL;
ngap_gNB_ue_context_t *ue_desc_p = NULL;
MessageDef *message_p = NULL;
NGAP_PDUSessionResourceModifyRequest_t *container;
NGAP_PDUSessionResourceModifyRequestIEs_t *ie;
NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id;
uint64_t amf_ue_ngap_id;
DevAssert(pdu != NULL);
container = &pdu->choice.initiatingMessage->value.choice.PDUSessionResourceModifyRequest;
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received PDUSession Resource modify request for non "
"existing AMF context\n", assoc_id);
return -1;
}
/* id-AMF-UE-NGAP-ID */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id);
} else {
return -1;
}
/* id-RAN-UE-NGAP-ID */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
gnb_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID;
} else {
return -1;
}
if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance,
gnb_ue_ngap_id)) == NULL) {
NGAP_ERROR("[SCTP %d] Received PDUSession Resource modify request for non "
"existing UE context 0x%08lx\n", assoc_id,
gnb_ue_ngap_id);
return -1;
}
/* PDUSession Resource modify request = UE-related procedure -> stream != 0 */
if (stream == 0) {
NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
assoc_id, stream);
return -1;
}
ue_desc_p->rx_stream = stream;
if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) {
NGAP_WARN("UE context amf_ue_ngap_id is different form that of the message (%ld != %ld)",
(uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id);
message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, NGAP_PDUSESSION_MODIFY_RESP);
NGAP_PDUSESSION_MODIFY_RESP (message_p).gNB_ue_ngap_id = gnb_ue_ngap_id;
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModReq, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
for(nb_of_pdusessions_failed = 0; nb_of_pdusessions_failed < ie->value.choice.PDUSessionResourceModifyListModReq.list.count; nb_of_pdusessions_failed++) {
NGAP_PDUSessionResourceModifyItemModReq_t *item_p;
item_p = (NGAP_PDUSessionResourceModifyItemModReq_t *)ie->value.choice.PDUSessionResourceModifyListModReq.list.array[nb_of_pdusessions_failed];
NGAP_PDUSESSION_MODIFY_RESP(message_p).pdusessions_failed[nb_of_pdusessions_failed].pdusession_id = item_p->pDUSessionID;
NGAP_PDUSESSION_MODIFY_RESP(message_p).pdusessions_failed[nb_of_pdusessions_failed].cause = NGAP_Cause_PR_radioNetwork;
NGAP_PDUSESSION_MODIFY_RESP(message_p).pdusessions_failed[nb_of_pdusessions_failed].cause_value = NGAP_CauseRadioNetwork_unknown_local_UE_NGAP_ID;
}
} else {
return -1;
}
NGAP_PDUSESSION_MODIFY_RESP(message_p).nb_of_pdusessions_failed = nb_of_pdusessions_failed;
ngap_gNB_pdusession_modify_resp(amf_desc_p->ngap_gNB_instance->instance,
&NGAP_PDUSESSION_MODIFY_RESP(message_p));
itti_free(TASK_RRC_GNB,message_p);
message_p = NULL;
return -1;
}
message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_MODIFY_REQ);
NGAP_PDUSESSION_MODIFY_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id;
NGAP_PDUSESSION_MODIFY_REQ(message_p).amf_ue_ngap_id = amf_ue_ngap_id;
NGAP_PDUSESSION_MODIFY_REQ(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id;
/* id-PDUSessionResourceModifyListModReq */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceModifyRequestIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_PDUSessionResourceModifyListModReq, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
NGAP_PDUSESSION_MODIFY_REQ(message_p).nb_pdusessions_tomodify =
ie->value.choice.PDUSessionResourceModifyListModReq.list.count;
for (i = 0; i < ie->value.choice.PDUSessionResourceModifyListModReq.list.count; i++) {
NGAP_PDUSessionResourceModifyItemModReq_t *item_p;
asn_dec_rval_t dec_rval;
NGAP_PDUSessionResourceModifyRequestTransfer_t *pdusessionTransfer_p = NULL;
NGAP_PDUSessionResourceModifyRequestTransferIEs_t *pdusessionTransfer_ies = NULL;
item_p = (NGAP_PDUSessionResourceModifyItemModReq_t *)ie->value.choice.PDUSessionResourceModifyListModReq.list.array[i];
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].pdusession_id = item_p->pDUSessionID;
// check for the NAS PDU
if (item_p->nAS_PDU != NULL && item_p->nAS_PDU->size > 0 ) {
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.length = item_p->nAS_PDU->size;
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU->size);
memcpy(NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.buffer,
item_p->nAS_PDU->buf, item_p->nAS_PDU->size);
} else {
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.length = 0;
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nas_pdu.buffer = NULL;
continue;
}
dec_rval = aper_decode(NULL,
&asn_DEF_NGAP_PDUSessionResourceModifyRequestTransfer,
(void **)&pdusessionTransfer_p,
item_p->pDUSessionResourceModifyRequestTransfer.buf,
item_p->pDUSessionResourceModifyRequestTransfer.size, 0, 0);
if(dec_rval.code != RC_OK) {
NGAP_ERROR("could not decode PDUSessionResourceModifyRequestTransfer\n");
return -1;
}
for(int j=0; j< pdusessionTransfer_p->protocolIEs.list.count; j++) {
pdusessionTransfer_ies = pdusessionTransfer_p->protocolIEs.list.array[j];
switch(pdusessionTransfer_ies->id) {
/* optional PDUSessionAggregateMaximumBitRate */
case NGAP_ProtocolIE_ID_id_PDUSessionAggregateMaximumBitRate:
break;
/* optional UL-NGU-UP-TNLModifyList */
case NGAP_ProtocolIE_ID_id_UL_NGU_UP_TNLModifyList:
break;
/* optional NetworkInstance */
case NGAP_ProtocolIE_ID_id_NetworkInstance:
break;
/* optional QosFlowAddOrModifyRequestList */
case NGAP_ProtocolIE_ID_id_QosFlowAddOrModifyRequestList:
{
NGAP_QosFlowAddOrModifyRequestItem_t *qosFlowItem_p;
NGAP_DEBUG("QosFlowAddOrModifyRequestList.list.count %d\n", pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count);
DevAssert(pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count > 0);
DevAssert(pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count <= NGAP_maxnoofQosFlows);
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].nb_qos = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count;
for(int qosIdx = 0; qosIdx < pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.count; qosIdx++) {
qosFlowItem_p = pdusessionTransfer_ies->value.choice.QosFlowAddOrModifyRequestList.list.array[qosIdx];
/* Set the QOS informations */
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier;
if(qosFlowItem_p->qosFlowLevelQosParameters) {
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.priority_level =
qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.priorityLevelARP;
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_capability =
qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.pre_emptionCapability;
NGAP_PDUSESSION_MODIFY_REQ(message_p).pdusession_modify_params[i].qos[qosIdx].allocation_retention_priority.pre_emp_vulnerability =
qosFlowItem_p->qosFlowLevelQosParameters->allocationAndRetentionPriority.pre_emptionVulnerability;
}
}
}
break;
/* optional QosFlowToReleaseList */
case NGAP_ProtocolIE_ID_id_QosFlowToReleaseList:
break;
/* optional AdditionalUL-NGU-UP-TNLInformation */
case NGAP_ProtocolIE_ID_id_AdditionalUL_NGU_UP_TNLInformation:
break;
/* optional CommonNetworkInstance */
case NGAP_ProtocolIE_ID_id_CommonNetworkInstance:
break;
default:
NGAP_ERROR("could not found protocolIEs id %ld\n", pdusessionTransfer_ies->id);
return -1;
}
}
}
itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p);
} else { /* of if (ie != NULL)*/
return -1;
}
return 0;
}
// handle pdu session release command and send it to rrc_end
static
int ngap_gNB_handle_pdusession_release_command(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
int i;
ngap_gNB_amf_data_t *amf_desc_p = NULL;
ngap_gNB_ue_context_t *ue_desc_p = NULL;
MessageDef *message_p = NULL;
NGAP_PDUSessionResourceReleaseCommand_t *container;
NGAP_PDUSessionResourceReleaseCommandIEs_t *ie;
NGAP_RAN_UE_NGAP_ID_t gnb_ue_ngap_id;
uint64_t amf_ue_ngap_id;
DevAssert(pdu != NULL);
container = &pdu->choice.initiatingMessage->value.choice.PDUSessionResourceReleaseCommand;
if ((amf_desc_p = ngap_gNB_get_AMF(NULL, assoc_id, 0)) == NULL) {
NGAP_ERROR("[SCTP %d] Received pdu session release command for non existing AMF context\n", assoc_id);
return -1;
}
/* id-AMF-UE-NGAP-ID */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceReleaseCommandIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_AMF_UE_NGAP_ID, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
asn_INTEGER2ulong(&(ie->value.choice.AMF_UE_NGAP_ID), &amf_ue_ngap_id);
} else {
return -1;
}
/* id-RAN-UE-NGAP-ID */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceReleaseCommandIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_RAN_UE_NGAP_ID, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
gnb_ue_ngap_id = ie->value.choice.RAN_UE_NGAP_ID;
} else {
return -1;
}
if ((ue_desc_p = ngap_gNB_get_ue_context(amf_desc_p->ngap_gNB_instance,
gnb_ue_ngap_id)) == NULL) {
NGAP_ERROR("[SCTP %d] Received PDUSession Resource release command for non existing UE context 0x%08lx\n", assoc_id,
ie->value.choice.RAN_UE_NGAP_ID);
return -1;
}
/* Initial context request = UE-related procedure -> stream != 0 */
// if (stream == 0) {
// NGAP_ERROR("[SCTP %d] Received UE-related procedure on stream (%d)\n",
// assoc_id, stream);
// return -1;
// }
ue_desc_p->rx_stream = stream;
if (ue_desc_p->amf_ue_ngap_id != amf_ue_ngap_id) {
NGAP_WARN("UE context amf_ue_ngap_id is different form that of the message (%lu != %lu)",
(uint64_t)ue_desc_p->amf_ue_ngap_id, amf_ue_ngap_id);
}
NGAP_DEBUG("[SCTP %d] Received pdu session release command for gNB_UE_NGAP_ID %lu amf_ue_ngap_id %lu\n",
assoc_id, gnb_ue_ngap_id, amf_ue_ngap_id);
message_p = itti_alloc_new_message(TASK_NGAP, 0, NGAP_PDUSESSION_RELEASE_COMMAND);
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).gNB_ue_ngap_id = gnb_ue_ngap_id;
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).amf_ue_ngap_id = amf_ue_ngap_id;
/* id-NAS-PDU */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceReleaseCommandIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_NAS_PDU, false);
if(ie && ie->value.choice.NAS_PDU.size > 0) {
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.length = ie->value.choice.NAS_PDU.size;
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.buffer = malloc(sizeof(uint8_t) * ie->value.choice.NAS_PDU.size);
memcpy(NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.buffer,
ie->value.choice.NAS_PDU.buf,
ie->value.choice.NAS_PDU.size);
} else {
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.length = 0;
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nas_pdu.buffer = NULL;
}
/* id-PDUSessionResourceToReleaseListRelCmd */
NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_PDUSessionResourceReleaseCommandIEs_t, ie, container,
NGAP_ProtocolIE_ID_id_PDUSessionResourceToReleaseListRelCmd, true);
if (ie != NULL) { /* checked by macro but cppcheck doesn't see it */
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).nb_pdusessions_torelease = ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count;
for (i = 0; i < ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.count; i++) {
NGAP_PDUSessionResourceToReleaseItemRelCmd_t *item_p;
item_p = (NGAP_PDUSessionResourceToReleaseItemRelCmd_t *)ie->value.choice.PDUSessionResourceToReleaseListRelCmd.list.array[i];
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].pdusession_id = item_p->pDUSessionID;
if(item_p->pDUSessionResourceReleaseCommandTransfer.size > 0) {
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = item_p->pDUSessionResourceReleaseCommandTransfer.size;
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = malloc(sizeof(uint8_t) * item_p->pDUSessionResourceReleaseCommandTransfer.size);
memcpy(NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer,
item_p->pDUSessionResourceReleaseCommandTransfer.buf,
item_p->pDUSessionResourceReleaseCommandTransfer.size);
}else {
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_length = 0;
NGAP_PDUSESSION_RELEASE_COMMAND(message_p).pdusession_release_params[i].transfer_buffer = NULL;
NGAP_ERROR("[NGAP] Received pdu session release command for pDUSessionResourceReleaseCommandTransfer is NULL!\n");
}
NGAP_DEBUG("[NGAP] Received pdu session release command for pDUSessionID id %ld\n", item_p->pDUSessionID);
}
} else {
return -1;
}
itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p);
return 0;
}
static
int ngap_gNB_handle_ng_path_switch_request_ack(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
// TODO
return 0;
}
static
int ngap_gNB_handle_ng_path_switch_request_failure(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu) {
// TODO
return 0;
}
static
int ngap_gNB_handle_ng_ENDC_pdusession_modification_confirm(uint32_t assoc_id,
uint32_t stream,
NGAP_NGAP_PDU_t *pdu){
LOG_W(NGAP, "Implementation of NGAP Pdusession Modification confirm handler is pending...\n");
return 0;
}