Files
openairinterface5g/openair2/F1AP/f1ap_du_ue_context_management.c
T
Robert Schmidt b4a7a1a194 Allow F1 to be used in do-ra
This is preparatory work to allow NSA-like modes to be used over F1 in
the future. Notably, it fills the F1 message for UE context setup with
GTP TEID, and fills additional information to "make the F1 encoder
happy" (fill in QFI etc). Also, provide some F1 fixes to make this work.
Remove stale UE connections, if relevant.
2025-05-04 09:34:42 +02:00

1681 lines
81 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 f1ap_du_ue_context_management.c
* \brief F1AP UE Context Management, DU side
* \author EURECOM/NTUST
* \date 2018
* \version 0.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr, bing-kai.hong@eurecom.fr
* \note
* \warning
*/
#include "f1ap_common.h"
#include "f1ap_encoder.h"
#include "f1ap_itti_messaging.h"
#include "f1ap_du_ue_context_management.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
static void f1ap_read_drb_qos_param(const F1AP_QoSFlowLevelQoSParameters_t *asn1_qos, f1ap_qos_flow_level_qos_parameters_t *drb_qos)
{
f1ap_qos_characteristics_t *drb_qos_char = &drb_qos->qos_characteristics;
const F1AP_QoS_Characteristics_t *dRB_QoS_Char = &asn1_qos->qoS_Characteristics;
if (dRB_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) {
drb_qos_char->qos_type = NON_DYNAMIC;
drb_qos_char->non_dynamic.fiveqi = dRB_QoS_Char->choice.non_Dynamic_5QI->fiveQI;
drb_qos_char->non_dynamic.qos_priority_level = (dRB_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel != NULL)
? *dRB_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel
: -1;
} else {
drb_qos_char->qos_type = DYNAMIC;
drb_qos_char->dynamic.fiveqi =
(dRB_QoS_Char->choice.dynamic_5QI->fiveQI != NULL) ? *dRB_QoS_Char->choice.dynamic_5QI->fiveQI : -1;
drb_qos_char->dynamic.qos_priority_level = dRB_QoS_Char->choice.dynamic_5QI->qoSPriorityLevel;
drb_qos_char->dynamic.packet_delay_budget = dRB_QoS_Char->choice.dynamic_5QI->packetDelayBudget;
drb_qos_char->dynamic.packet_error_rate.per_scalar = dRB_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Scalar;
drb_qos_char->dynamic.packet_error_rate.per_exponent = dRB_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Exponent;
}
/* nGRANallocationRetentionPriority */
drb_qos->alloc_reten_priority.priority_level = asn1_qos->nGRANallocationRetentionPriority.priorityLevel;
drb_qos->alloc_reten_priority.preemption_vulnerability = asn1_qos->nGRANallocationRetentionPriority.pre_emptionVulnerability;
drb_qos->alloc_reten_priority.preemption_capability = asn1_qos->nGRANallocationRetentionPriority.pre_emptionVulnerability;
}
static void f1ap_read_flows_mapped(const F1AP_Flows_Mapped_To_DRB_List_t *asn1_flows_mapped, f1ap_flows_mapped_to_drb_t *flows_mapped, int n)
{
for (int k = 0; k < n; k++) {
f1ap_flows_mapped_to_drb_t *flows_mapped_to_drb = flows_mapped + k;
const F1AP_Flows_Mapped_To_DRB_Item_t *flows_Mapped_To_Drb = asn1_flows_mapped->list.array[0] + k;
flows_mapped_to_drb->qfi = flows_Mapped_To_Drb->qoSFlowIdentifier;
/* QoS-Flow-Level-QoS-Parameters */
{
f1ap_qos_flow_level_qos_parameters_t *flow_qos = &flows_mapped_to_drb->qos_params;
const F1AP_QoSFlowLevelQoSParameters_t *Flow_QoS = &flows_Mapped_To_Drb->qoSFlowLevelQoSParameters;
/* QoS Characteristics*/
f1ap_qos_characteristics_t *flow_qos_char = &flow_qos->qos_characteristics;
const F1AP_QoS_Characteristics_t *Flow_QoS_Char = &Flow_QoS->qoS_Characteristics;
if (Flow_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) {
flow_qos_char->qos_type = NON_DYNAMIC;
flow_qos_char->non_dynamic.fiveqi = Flow_QoS_Char->choice.non_Dynamic_5QI->fiveQI;
flow_qos_char->non_dynamic.qos_priority_level = (Flow_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel != NULL)
? *Flow_QoS_Char->choice.non_Dynamic_5QI->qoSPriorityLevel
: -1;
} else {
flow_qos_char->qos_type = DYNAMIC;
flow_qos_char->dynamic.fiveqi =
(Flow_QoS_Char->choice.dynamic_5QI->fiveQI != NULL) ? *Flow_QoS_Char->choice.dynamic_5QI->fiveQI : -1;
flow_qos_char->dynamic.qos_priority_level = Flow_QoS_Char->choice.dynamic_5QI->qoSPriorityLevel;
flow_qos_char->dynamic.packet_delay_budget = Flow_QoS_Char->choice.dynamic_5QI->packetDelayBudget;
flow_qos_char->dynamic.packet_error_rate.per_scalar = Flow_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Scalar;
flow_qos_char->dynamic.packet_error_rate.per_exponent = Flow_QoS_Char->choice.dynamic_5QI->packetErrorRate.pER_Exponent;
}
/* nGRANallocationRetentionPriority */
flow_qos->alloc_reten_priority.priority_level = Flow_QoS->nGRANallocationRetentionPriority.priorityLevel;
flow_qos->alloc_reten_priority.preemption_vulnerability = Flow_QoS->nGRANallocationRetentionPriority.pre_emptionVulnerability;
flow_qos->alloc_reten_priority.preemption_capability = Flow_QoS->nGRANallocationRetentionPriority.pre_emptionVulnerability;
}
}
}
static void f1ap_read_drb_nssai(const F1AP_SNSSAI_t *asn1_nssai, nssai_t *nssai)
{
OCTET_STRING_TO_INT8(&asn1_nssai->sST, nssai->sst);
nssai->sd = 0xffffff;
if (asn1_nssai->sD != NULL) {
BUFFER_TO_INT24(asn1_nssai->sD->buf, nssai->sd);
}
}
int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
{
F1AP_UEContextSetupRequest_t *container;
int i;
DevAssert(pdu);
f1ap_ue_context_setup_t ue_context_setup = {0};
f1ap_ue_context_setup_t *f1ap_ue_context_setup_req = &ue_context_setup;
container = &pdu->choice.initiatingMessage->value.choice.UEContextSetupRequest;
/* GNB_CU_UE_F1AP_ID */
F1AP_UEContextSetupRequestIEs_t *ieCU;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieCU, container,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
f1ap_ue_context_setup_req->gNB_CU_ue_id = ieCU->value.choice.GNB_CU_UE_F1AP_ID;
/* optional */
/* GNB_DU_UE_F1AP_ID */
F1AP_UEContextSetupRequestIEs_t *ieDU_UE;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieDU_UE, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, false);
// this should be optional. At present, the DU uses the RNTI, and hence, this
// value cannot exceed 0xffff (or something below, whatever is a valid
// C-RNTI). So we use a value > 0xffff to mark optionality
f1ap_ue_context_setup_req->gNB_DU_ue_id = -1; // 0xffffffff
if (ieDU_UE != NULL)
f1ap_ue_context_setup_req->gNB_DU_ue_id = ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID;
/* SpCell_ID */
F1AP_UEContextSetupRequestIEs_t *ieNet;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieNet, container,
F1AP_ProtocolIE_ID_id_SpCell_ID, true);
PLMNID_TO_MCC_MNC(&ieNet->value.choice.NRCGI.pLMN_Identity,
f1ap_ue_context_setup_req->plmn.mcc,
f1ap_ue_context_setup_req->plmn.mnc,
f1ap_ue_context_setup_req->plmn.mnc_digit_length);
BIT_STRING_TO_NR_CELL_IDENTITY(&ieNet->value.choice.NRCGI.nRCellIdentity, f1ap_ue_context_setup_req->nr_cellid);
/* ServCellIndex */
F1AP_UEContextSetupRequestIEs_t *ieCell;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieCell, container,
F1AP_ProtocolIE_ID_id_ServCellIndex, true);
f1ap_ue_context_setup_req->servCellIndex = ieCell->value.choice.ServCellIndex;
/* optional */
/* CellULConfigured */
F1AP_UEContextSetupRequestIEs_t *ieULCell;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieULCell, container,
F1AP_ProtocolIE_ID_id_SpCellULConfigured, false); // SpCellULConfigured
if (ieULCell) {
/* correct here */
f1ap_ue_context_setup_req->cellULConfigured = malloc(sizeof(uint32_t));
if (f1ap_ue_context_setup_req->cellULConfigured)
*f1ap_ue_context_setup_req->cellULConfigured = ieULCell->value.choice.CellULConfigured;
} else {
f1ap_ue_context_setup_req->cellULConfigured = NULL;
}
F1AP_UEContextSetupRequestIEs_t *ieCuRrcInfo;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieCuRrcInfo, container,
F1AP_ProtocolIE_ID_id_CUtoDURRCInformation, false);
if(ieCuRrcInfo!=NULL){
f1ap_ue_context_setup_req->cu_to_du_rrc_information = (cu_to_du_rrc_information_t *)calloc(1,sizeof(cu_to_du_rrc_information_t));
cu_to_du_rrc_information_t *cu2du = f1ap_ue_context_setup_req->cu_to_du_rrc_information;
const F1AP_CUtoDURRCInformation_t *cu2duie = &ieCuRrcInfo->value.choice.CUtoDURRCInformation;
if (cu2duie->cG_ConfigInfo != NULL) {
cu2du->cG_ConfigInfo = malloc_or_fail(cu2duie->cG_ConfigInfo->size);
cu2du->cG_ConfigInfo_length = cu2duie->cG_ConfigInfo->size;
memcpy(cu2du->cG_ConfigInfo, cu2duie->cG_ConfigInfo->buf, cu2du->cG_ConfigInfo_length);
}
if(cu2duie->uE_CapabilityRAT_ContainerList!=NULL){
cu2du->uE_CapabilityRAT_ContainerList = calloc(1, cu2duie->uE_CapabilityRAT_ContainerList->size);
memcpy(cu2du->uE_CapabilityRAT_ContainerList,
cu2duie->uE_CapabilityRAT_ContainerList->buf,
cu2duie->uE_CapabilityRAT_ContainerList->size);
cu2du->uE_CapabilityRAT_ContainerList_length = cu2duie->uE_CapabilityRAT_ContainerList->size;
LOG_D(F1AP, "Size f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length: %d \n", f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length);
}
if (cu2duie->iE_Extensions != NULL) {
const F1AP_ProtocolExtensionContainer_10696P60_t *ext = (const F1AP_ProtocolExtensionContainer_10696P60_t *)cu2duie->iE_Extensions;
for (int i = 0; i < ext->list.count; ++i) {
const F1AP_CUtoDURRCInformation_ExtIEs_t *cu2du_info = ext->list.array[i];
switch (cu2du_info->id) {
case F1AP_ProtocolIE_ID_id_HandoverPreparationInformation:
DevAssert(cu2du_info->extensionValue.present == F1AP_CUtoDURRCInformation_ExtIEs__extensionValue_PR_HandoverPreparationInformation);
const F1AP_HandoverPreparationInformation_t *hopi = &cu2du_info->extensionValue.choice.MeasurementTimingConfiguration;
cu2du->handoverPreparationInfo = calloc_or_fail(1, hopi->size);
memcpy(cu2du->handoverPreparationInfo, hopi->buf, hopi->size);
cu2du->handoverPreparationInfo_length = hopi->size;
break;
default:
LOG_W(F1AP, "unsupported CUtoDURRCInformation_ExtIE %ld encountered, ignoring\n", cu2du_info->id);
break;
}
}
}
}
/* DRB */
F1AP_UEContextSetupRequestIEs_t *ieDrb;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieDrb, container,
F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List, false);
if(ieDrb!=NULL) {
f1ap_ue_context_setup_req->drbs_to_be_setup_length = ieDrb->value.choice.DRBs_ToBeSetup_List.list.count;
f1ap_ue_context_setup_req->drbs_to_be_setup = calloc(f1ap_ue_context_setup_req->drbs_to_be_setup_length,
sizeof(f1ap_drb_to_be_setup_t));
AssertFatal(f1ap_ue_context_setup_req->drbs_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_req->drbs_to_be_setup\n");
for (i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; ++i) {
f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_setup_req->drbs_to_be_setup[i];
F1AP_DRBs_ToBeSetup_Item_t *drbs_tobesetup_item_p =
&((F1AP_DRBs_ToBeSetup_ItemIEs_t *)ieDrb->value.choice.DRBs_ToBeSetup_List.list.array[i])->value.choice.DRBs_ToBeSetup_Item;
drb_p->drb_id = drbs_tobesetup_item_p->dRBID;
/* TODO in the following, assume only one UP UL TNL is present.
* this matches/assumes OAI CU implementation, can be up to 2! */
drb_p->up_ul_tnl_length = 1;
AssertFatal(drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.count > 0,
"no UL UP TNL Information in DRBs to be Setup list\n");
F1AP_ULUPTNLInformation_ToBeSetup_Item_t *ul_up_tnl_info_p = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)drbs_tobesetup_item_p->uLUPTNLInformation_ToBeSetup_List.list.array[0];
F1AP_GTPTunnel_t *ul_up_tnl0 = ul_up_tnl_info_p->uLUPTNLInformation.choice.gTPTunnel;
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&ul_up_tnl0->transportLayerAddress, drb_p->up_ul_tnl[0].tl_address);
OCTET_STRING_TO_UINT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].teid);
// 3GPP assumes GTP-U is on port 2152, but OAI is configurable
drb_p->up_ul_tnl[0].port = getCxt(instance)->net_config.CUport;
switch (drbs_tobesetup_item_p->rLCMode) {
case F1AP_RLCMode_rlc_am:
drb_p->rlc_mode = F1AP_RLC_MODE_AM;
break;
case F1AP_RLCMode_rlc_um_bidirectional:
drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR;
break;
default:
LOG_W(F1AP, "unsupported RLC Mode %ld received: setting UM bidir\n", drbs_tobesetup_item_p->rLCMode);
drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR;
break;
}
if (drbs_tobesetup_item_p->qoSInformation.present == F1AP_QoSInformation_PR_eUTRANQoS) {
AssertFatal(false, "Decode of eUTRANQoS is not implemented yet");
} // EUTRAN QoS Information
else {
/* 12.1.2 DRB_Information */
if (drbs_tobesetup_item_p->qoSInformation.present == F1AP_QoSInformation_PR_choice_extension) {
F1AP_QoSInformation_ExtIEs_t *ie =
(F1AP_QoSInformation_ExtIEs_t *)drbs_tobesetup_item_p->qoSInformation.choice.choice_extension;
if (ie->id == F1AP_ProtocolIE_ID_id_DRB_Information && ie->criticality == F1AP_Criticality_reject
&& ie->value.present == F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information) {
const F1AP_DRB_Information_t *dRB_Info = &ie->value.choice.DRB_Information;
f1ap_drb_information_t *drb_info = &drb_p->drb_info;
/* QoS-Flow-Level-QoS-Parameters */
/* QoS Characteristics*/
f1ap_read_drb_qos_param(&dRB_Info->dRB_QoS, &drb_info->drb_qos);
// 12.1.2.4 flows_Mapped_To_DRB_List
drb_info->flows_to_be_setup_length = dRB_Info->flows_Mapped_To_DRB_List.list.count;
drb_info->flows_mapped_to_drb = calloc(drb_info->flows_to_be_setup_length, sizeof(f1ap_flows_mapped_to_drb_t));
AssertFatal(drb_info->flows_mapped_to_drb, "could not allocate memory for drb_p->drb_info.flows_mapped_to_drb\n");
f1ap_read_flows_mapped(&dRB_Info->flows_Mapped_To_DRB_List, drb_info->flows_mapped_to_drb, drb_info->flows_to_be_setup_length);
/* S-NSSAI */
f1ap_read_drb_nssai(&dRB_Info->sNSSAI, &drb_p->nssai);
}
}
}
}
}
/* SRB */
F1AP_UEContextSetupRequestIEs_t *ieSrb;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieSrb, container,
F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_List, false);
if(ieSrb != NULL) {
f1ap_ue_context_setup_req->srbs_to_be_setup_length = ieSrb->value.choice.SRBs_ToBeSetup_List.list.count;
f1ap_ue_context_setup_req->srbs_to_be_setup = calloc(f1ap_ue_context_setup_req->srbs_to_be_setup_length,
sizeof(f1ap_srb_to_be_setup_t));
AssertFatal(f1ap_ue_context_setup_req->srbs_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_req->srbs_to_be_setup\n");
for (i = 0; i < f1ap_ue_context_setup_req->srbs_to_be_setup_length; ++i) {
f1ap_srb_to_be_setup_t *srb_p = &f1ap_ue_context_setup_req->srbs_to_be_setup[i];
F1AP_SRBs_ToBeSetup_Item_t *srbs_tobesetup_item_p;
srbs_tobesetup_item_p = &((F1AP_SRBs_ToBeSetup_ItemIEs_t *)ieSrb->value.choice.SRBs_ToBeSetup_List.list.array[i])->value.choice.SRBs_ToBeSetup_Item;
srb_p->srb_id = srbs_tobesetup_item_p->sRBID;
}
}
/* RRCContainer */
F1AP_UEContextSetupRequestIEs_t *ieRRC;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextSetupRequestIEs_t, ieRRC, container,
F1AP_ProtocolIE_ID_id_RRCContainer, false);
if (ieRRC) {
/* correct here */
if ( ieRRC->value.choice.RRCContainer.size ) {
f1ap_ue_context_setup_req->rrc_container = malloc(ieRRC->value.choice.RRCContainer.size);
memcpy(f1ap_ue_context_setup_req->rrc_container,
ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size);
f1ap_ue_context_setup_req->rrc_container_length = ieRRC->value.choice.RRCContainer.size;
} else {
LOG_E(F1AP, " RRCContainer in UEContextSetupRequestIEs size id 0\n");
}
}
ue_context_setup_request(f1ap_ue_context_setup_req);
return 0;
}
int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *resp)
{
F1AP_F1AP_PDU_t pdu= {0};
F1AP_UEContextSetupResponse_t *out;
uint8_t *buffer=NULL;
uint32_t len=0;
/* Create */
/* 0. Message Type */
pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
asn1cCalloc(pdu.choice.successfulOutcome, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_UEContextSetup;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextSetupResponse;
out = &tmp->value.choice.UEContextSetupResponse;
/* mandatory */
/* c1. GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_UEContextSetupResponseIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = resp->gNB_CU_ue_id;
/* mandatory */
/* c2. GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_UEContextSetupResponseIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = resp->gNB_DU_ue_id;
/* mandatory */
/* c3. DUtoCURRCInformation */
if(resp->du_to_cu_rrc_information){
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation;
ie3->criticality = F1AP_Criticality_reject;
ie3->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DUtoCURRCInformation;
if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){
/* cellGroupConfig */
OCTET_STRING_fromBuf(&ie3->value.choice.DUtoCURRCInformation.cellGroupConfig, (const char *)resp->du_to_cu_rrc_information->cellGroupConfig,
resp->du_to_cu_rrc_information->cellGroupConfig_length);
}
/* OPTIONAL */
/* measGapConfig */
if (resp->du_to_cu_rrc_information->measGapConfig!=NULL) {
OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.measGapConfig, (const char *)resp->du_to_cu_rrc_information->measGapConfig,
resp->du_to_cu_rrc_information->measGapConfig_length);
}
/* OPTIONAL */
/* requestedP_MaxFR1 */
if (resp->du_to_cu_rrc_information->requestedP_MaxFR1!=NULL) {
OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.requestedP_MaxFR1, (const char *)resp->du_to_cu_rrc_information->requestedP_MaxFR1,
resp->du_to_cu_rrc_information->requestedP_MaxFR1_length);
}
}
/* optional */
/* c4. C_RNTI */
if (resp->crnti!=NULL) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie4);
ie4->id = F1AP_ProtocolIE_ID_id_C_RNTI;
ie4->criticality = F1AP_Criticality_ignore;
ie4->value.present = F1AP_UEContextSetupResponseIEs__value_PR_C_RNTI;
ie4->value.choice.C_RNTI = *resp->crnti;
}
/* optional */
/* c5. ResourceCoordinationTransferContainer */
if (0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie5);
ie5->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer;
ie5->criticality = F1AP_Criticality_ignore;
ie5->value.present = F1AP_UEContextSetupResponseIEs__value_PR_ResourceCoordinationTransferContainer;
OCTET_STRING_fromBuf(&ie5->value.choice.ResourceCoordinationTransferContainer, "asdsa",
strlen("asdsa"));
}
/* optional */
/* c6. FullConfiguration */
if (0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie6);
ie6->id = F1AP_ProtocolIE_ID_id_FullConfiguration;
ie6->criticality = F1AP_Criticality_ignore;
ie6->value.present = F1AP_UEContextSetupResponseIEs__value_PR_FullConfiguration;
ie6->value.choice.FullConfiguration = F1AP_FullConfiguration_full; //enum
}
/* mandatory */
/* c7. DRBs_Setup_List */
if(resp->drbs_to_be_setup_length > 0){
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie7);
ie7->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_List;
ie7->criticality = F1AP_Criticality_ignore;
ie7->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List;
for (int i=0; i< resp->drbs_to_be_setup_length; i++) {
f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i];
//
asn1cSequenceAdd(ie7->value.choice.DRBs_Setup_List.list,
F1AP_DRBs_Setup_ItemIEs_t, drbs_setup_item_ies);
drbs_setup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Setup_Item;
drbs_setup_item_ies->criticality = F1AP_Criticality_ignore;
drbs_setup_item_ies->value.present = F1AP_DRBs_Setup_ItemIEs__value_PR_DRBs_Setup_Item;
/* 7.1 DRBs_Setup_Item */
/* ADD */
F1AP_DRBs_Setup_Item_t *drbs_setup_item=&drbs_setup_item_ies->value.choice.DRBs_Setup_Item;
/* dRBID */
drbs_setup_item->dRBID = drb->drb_id;
/* OPTIONAL */
/* lCID */
//drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t));
//drbs_setup_item.lCID = 1L;
for (int j = 0; j < drb->up_dl_tnl_length; j++) {
const f1ap_up_tnl_t *tnl = &drb->up_dl_tnl[j];
DevAssert(tnl->teid > 0);
/* ADD */
asn1cSequenceAdd(drbs_setup_item->dLUPTNLInformation_ToBeSetup_List.list,
F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item);
dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
/* gTPTunnel */
asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel);
/* transportLayerAddress */
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress);
/* gTP_TEID */
INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID);
} // for j
} // for i
}
/* mandatory */
/* c8. SRBs_FailedToBeSetup_List */
if(0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie8);
ie8->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetup_List;
ie8->criticality = F1AP_Criticality_ignore;
ie8->value.present = F1AP_UEContextSetupResponseIEs__value_PR_SRBs_FailedToBeSetup_List;
for (int i=0; i<1; i++) {
//
asn1cSequenceAdd(ie8->value.choice.SRBs_FailedToBeSetup_List.list,
F1AP_SRBs_FailedToBeSetup_ItemIEs_t, srbs_failedToBeSetup_item_ies);
srbs_failedToBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetup_Item;
srbs_failedToBeSetup_item_ies->criticality = F1AP_Criticality_ignore;
srbs_failedToBeSetup_item_ies->value.present = F1AP_SRBs_FailedToBeSetup_ItemIEs__value_PR_SRBs_FailedToBeSetup_Item;
/* 8.1 SRBs_Setup_Item */
F1AP_SRBs_FailedToBeSetup_Item_t *srbs_failedToBeSetup_item=
&srbs_failedToBeSetup_item_ies->value.choice.SRBs_FailedToBeSetup_Item;
/* sRBID */
srbs_failedToBeSetup_item->sRBID = 13L;
/* cause */
asn1cCalloc(srbs_failedToBeSetup_item->cause, tmp);
// dummy value
tmp->present = F1AP_Cause_PR_radioNetwork;
switch(tmp->present) {
case F1AP_Cause_PR_radioNetwork:
tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified;
break;
case F1AP_Cause_PR_transport:
tmp->choice.transport = F1AP_CauseTransport_unspecified;
break;
case F1AP_Cause_PR_protocol:
tmp->choice.protocol = F1AP_CauseProtocol_unspecified;
break;
case F1AP_Cause_PR_misc:
tmp->choice.misc = F1AP_CauseMisc_unspecified;
break;
case F1AP_Cause_PR_NOTHING:
default:
break;
} // switch
} // for i
}
/* */
/* c9. DRBs_FailedToBeSetup_List */
if(0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie9);
ie9->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetup_List;
ie9->criticality = F1AP_Criticality_ignore;
ie9->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_FailedToBeSetup_List;
for (int i=0; i<1; i++) {
asn1cSequenceAdd(ie9->value.choice.DRBs_FailedToBeSetup_List.list,
F1AP_DRBs_FailedToBeSetup_ItemIEs_t, drbs_failedToBeSetup_item_ies);
drbs_failedToBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetup_Item;
drbs_failedToBeSetup_item_ies->criticality = F1AP_Criticality_ignore;
drbs_failedToBeSetup_item_ies->value.present = F1AP_DRBs_FailedToBeSetup_ItemIEs__value_PR_DRBs_FailedToBeSetup_Item;
/* 9.1 DRBs_Setup_Item */
/* ADD */
F1AP_DRBs_FailedToBeSetup_Item_t *drbs_failedToBeSetup_item=
&drbs_failedToBeSetup_item_ies->value.choice.DRBs_FailedToBeSetup_Item;
/* dRBID */
drbs_failedToBeSetup_item->dRBID = 14;
/* cause */
asn1cCalloc(drbs_failedToBeSetup_item->cause,tmp);
// dummy value
tmp->present = F1AP_Cause_PR_radioNetwork;
switch(tmp->present) {
case F1AP_Cause_PR_radioNetwork:
tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified;
break;
case F1AP_Cause_PR_transport:
tmp->choice.transport = F1AP_CauseTransport_unspecified;
break;
case F1AP_Cause_PR_protocol:
tmp->choice.protocol = F1AP_CauseProtocol_unspecified;
break;
case F1AP_Cause_PR_misc:
tmp->choice.misc = F1AP_CauseMisc_unspecified;
break;
case F1AP_Cause_PR_NOTHING:
default:
break;
} // switch
} // for i
}
// /* */
/* c10. SCell_FailedtoSetup_List */
if(0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie10);
ie10->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetup_List;
ie10->criticality = F1AP_Criticality_ignore;
ie10->value.present = F1AP_UEContextSetupResponseIEs__value_PR_SCell_FailedtoSetup_List;
for (int i=0; i<1; i++) {
asn1cSequenceAdd(ie10->value.choice.SCell_FailedtoSetup_List.list,
F1AP_SCell_FailedtoSetup_ItemIEs_t, sCell_FailedtoSetup_item_ies);
sCell_FailedtoSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetup_Item;
sCell_FailedtoSetup_item_ies->criticality = F1AP_Criticality_ignore;
sCell_FailedtoSetup_item_ies->value.present = F1AP_SCell_FailedtoSetup_ItemIEs__value_PR_SCell_FailedtoSetup_Item;
/* 10.1 DRBs_Setup_Item */
F1AP_SCell_FailedtoSetup_Item_t *sCell_FailedtoSetup_item=
&sCell_FailedtoSetup_item_ies->value.choice.SCell_FailedtoSetup_Item;
/* sCell_ID */
AssertFatal(false, "handle correct CellID\n");
f1ap_served_cell_info_t cellID = {0};
addnRCGI(sCell_FailedtoSetup_item->sCell_ID, &cellID);
/* cause */
asn1cCalloc(sCell_FailedtoSetup_item->cause, tmp);
// dummy value
tmp->present = F1AP_Cause_PR_radioNetwork;
switch(tmp->present) {
case F1AP_Cause_PR_radioNetwork:
tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unspecified;
break;
case F1AP_Cause_PR_transport:
tmp->choice.transport = F1AP_CauseTransport_unspecified;
break;
case F1AP_Cause_PR_protocol:
tmp->choice.protocol = F1AP_CauseProtocol_unspecified;
break;
case F1AP_Cause_PR_misc:
tmp->choice.misc = F1AP_CauseMisc_unspecified;
break;
case F1AP_Cause_PR_NOTHING:
default:
break;
} // switch
} // for i
}
/* mandatory */
/* c11. SRBs_Setup_List */
if(resp->srbs_to_be_setup_length > 0){
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie11);
ie11->id = F1AP_ProtocolIE_ID_id_SRBs_Setup_List;
ie11->criticality = F1AP_Criticality_ignore;
ie11->value.present = F1AP_UEContextSetupResponseIEs__value_PR_SRBs_Setup_List;
for (int i=0; i< resp->srbs_to_be_setup_length; i++) {//
asn1cSequenceAdd(ie11->value.choice.SRBs_Setup_List.list,
F1AP_SRBs_Setup_ItemIEs_t, srbs_setup_item_ies);
srbs_setup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_Setup_Item;
srbs_setup_item_ies->criticality = F1AP_Criticality_ignore;
srbs_setup_item_ies->value.present = F1AP_SRBs_Setup_ItemIEs__value_PR_SRBs_Setup_Item;
/* 11.1 SRBs_Setup_Item */
/* ADD */
F1AP_SRBs_Setup_Item_t *srbs_setup_item=&srbs_setup_item_ies->value.choice.SRBs_Setup_Item;
/* sRBID */
srbs_setup_item->sRBID = resp->srbs_to_be_setup[i].srb_id;
srbs_setup_item->lCID = resp->srbs_to_be_setup[i].lcid;
}
}
/* Optional */
/* c12. InactivityMonitoringResponse */
if (0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie11);
ie11->id = F1AP_ProtocolIE_ID_id_InactivityMonitoringResponse;
ie11->criticality = F1AP_Criticality_ignore;
ie11->value.present = F1AP_UEContextSetupResponseIEs__value_PR_InactivityMonitoringResponse;
ie11->value.choice.InactivityMonitoringResponse = F1AP_InactivityMonitoringResponse_not_supported;
}
/* Optional */
/* c13. CriticalityDiagnostics */
if (0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupResponseIEs_t, ie12);
ie12->id = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics;
ie12->criticality = F1AP_Criticality_ignore;
ie12->value.present = F1AP_UEContextSetupResponseIEs__value_PR_CriticalityDiagnostics;
asn1cCallocOne(ie12->value.choice.CriticalityDiagnostics.procedureCode,
F1AP_ProcedureCode_id_UEContextSetup);
asn1cCallocOne(ie12->value.choice.CriticalityDiagnostics.triggeringMessage,
F1AP_TriggeringMessage_initiating_message);
asn1cCallocOne(ie12->value.choice.CriticalityDiagnostics.procedureCriticality,
F1AP_Criticality_reject);
asn1cCallocOne(ie12->value.choice.CriticalityDiagnostics.transactionID,
0);
}
/* encode */
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(F1AP, "Failed to encode F1 UE CONTEXT SETUP RESPONSE\n");
return -1;
}
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0;
}
int DU_send_UE_CONTEXT_SETUP_FAILURE(sctp_assoc_t assoc_id)
{
AssertFatal(1==0,"Not implemented yet\n");
}
int DU_send_UE_CONTEXT_RELEASE_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_release_req_t *req)
{
F1AP_F1AP_PDU_t pdu = {0};
F1AP_UEContextReleaseRequest_t *out;
uint8_t *buffer=NULL;
uint32_t len=0;
/* Create */
/* 0. Message Type */
pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
asn1cCalloc(pdu.choice.initiatingMessage, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_UEContextReleaseRequest;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_InitiatingMessage__value_PR_UEContextReleaseRequest;
out = &tmp->value.choice.UEContextReleaseRequest;
/* mandatory */
/* c1. GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseRequestIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = req->gNB_CU_ue_id;
/* mandatory */
/* c2. GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseRequestIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = req->gNB_DU_ue_id;
/* mandatory */
/* c3. Cause */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseRequestIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_Cause;
ie3->criticality = F1AP_Criticality_ignore;
ie3->value.present = F1AP_UEContextReleaseRequestIEs__value_PR_Cause;
switch (req->cause) {
case F1AP_CAUSE_RADIO_NETWORK:
ie3->value.choice.Cause.present = F1AP_Cause_PR_radioNetwork;
ie3->value.choice.Cause.choice.radioNetwork = req->cause_value;
break;
case F1AP_CAUSE_TRANSPORT:
ie3->value.choice.Cause.present = F1AP_Cause_PR_transport;
ie3->value.choice.Cause.choice.transport = req->cause_value;
break;
case F1AP_CAUSE_PROTOCOL:
ie3->value.choice.Cause.present = F1AP_Cause_PR_protocol;
ie3->value.choice.Cause.choice.protocol = req->cause_value;
break;
case F1AP_CAUSE_MISC:
ie3->value.choice.Cause.present = F1AP_Cause_PR_misc;
ie3->value.choice.Cause.choice.misc = req->cause_value;
break;
case F1AP_CAUSE_NOTHING:
default:
ie3->value.choice.Cause.present = F1AP_Cause_PR_NOTHING;
break;
}
/* encode */
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(F1AP, "Failed to encode F1 context release request\n");
return -1;
}
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0;
}
int DU_handle_UE_CONTEXT_RELEASE_COMMAND(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
{
F1AP_UEContextReleaseCommand_t *container;
F1AP_UEContextReleaseCommandIEs_t *ie;
f1ap_ue_context_release_req_t ue_context_release = {0};
f1ap_ue_context_release_req_t *f1ap_ue_context_release_cmd = &ue_context_release;
DevAssert(pdu);
container = &pdu->choice.initiatingMessage->value.choice.UEContextReleaseCommand;
// GNB_CU_UE_F1AP_ID
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
f1ap_ue_context_release_cmd->gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
// GNB_DU_UE_F1AP_ID
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
f1ap_ue_context_release_cmd->gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
// We don't need the Cause
// Optional RRC Container: if present, send to UE
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_RRCContainer, false);
if (ie != NULL) {
f1ap_ue_context_release_cmd->rrc_container = malloc(ie->value.choice.RRCContainer.size);
AssertFatal(f1ap_ue_context_release_cmd->rrc_container != NULL, "out of memory\n");
memcpy(f1ap_ue_context_release_cmd->rrc_container, ie->value.choice.RRCContainer.buf, ie->value.choice.RRCContainer.size);
f1ap_ue_context_release_cmd->rrc_container_length = ie->value.choice.RRCContainer.size;
// conditionally have SRB ID if there is RRC container
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container, F1AP_ProtocolIE_ID_id_SRBID, true);
f1ap_ue_context_release_cmd->srb_id = ie->value.choice.SRBID;
}
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextReleaseCommandIEs_t, ie, container,
F1AP_ProtocolIE_ID_id_Cause, true);
switch (ie->value.choice.Cause.present){
case F1AP_Cause_PR_radioNetwork:
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_RADIO_NETWORK;
break;
case F1AP_Cause_PR_transport:
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_TRANSPORT;
break;
case F1AP_Cause_PR_protocol:
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_PROTOCOL;
break;
case F1AP_Cause_PR_misc:
f1ap_ue_context_release_cmd->cause = F1AP_CAUSE_MISC;
break;
default:
LOG_W(F1AP, "Unknown cause for UE context release command\n");
break;
}
ue_context_release_command(f1ap_ue_context_release_cmd);
return 0;
}
int DU_send_UE_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, f1ap_ue_context_release_complete_t *complete)
{
F1AP_F1AP_PDU_t pdu= {0};
F1AP_UEContextReleaseComplete_t *out;
/* Create */
/* 0. Message Type */
pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
asn1cCalloc(pdu.choice.successfulOutcome, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_UEContextRelease;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextReleaseComplete;
out = &tmp->value.choice.UEContextReleaseComplete;
/* mandatory */
/* c1. GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextReleaseCompleteIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = complete->gNB_CU_ue_id;
/* mandatory */
/* c2. GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list,F1AP_UEContextReleaseCompleteIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = complete->gNB_DU_ue_id;
/* optional -> currently not used */
/* c3. CriticalityDiagnostics */
//if (0) {
// ie = (F1AP_UEContextReleaseCompleteIEs_t *)calloc(1, sizeof(F1AP_UEContextReleaseCompleteIEs_t));
// ie->id = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics;
// ie->criticality = F1AP_Criticality_ignore;
// ie->value.present = F1AP_UEContextReleaseCompleteIEs__value_PR_CriticalityDiagnostics;
// // dummy value
// /* optional */
// /* procedureCode */
// if (0) {
// ie->value.choice.CriticalityDiagnostics.procedureCode = (F1AP_ProcedureCode_t *)calloc(1, sizeof(F1AP_ProcedureCode_t));
// ie->value.choice.CriticalityDiagnostics.procedureCode = 0L;
// }
// /* optional */
// /* triggeringMessage */
// if (0) {
// ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)calloc(1, sizeof(F1AP_TriggeringMessage_t));
// ie->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)F1AP_TriggeringMessage_successful_outcome;
// }
// /* optional */
// /* procedureCriticality */
// if (0) {
// ie->value.choice.CriticalityDiagnostics.procedureCriticality = (F1AP_Criticality_t *)calloc(1, sizeof(F1AP_Criticality_t));
// ie->value.choice.CriticalityDiagnostics.procedureCriticality = F1AP_Criticality_reject;
// }
// /* optional */
// /* transactionID */
// if (0) {
// ie->value.choice.CriticalityDiagnostics.transactionID = (F1AP_TransactionID_t *)calloc(1, sizeof(F1AP_TransactionID_t));
// ie->value.choice.CriticalityDiagnostics.transactionID = 0L;
// }
// /* optional */
// /* F1AP_CriticalityDiagnostics_IE_List */
// if (0) {
// for (i=0;
// i<0;
// i++) {
// F1AP_CriticalityDiagnostics_IE_Item_t *criticalityDiagnostics_ie_item = (F1AP_CriticalityDiagnostics_IE_Item_t *)calloc(1, sizeof(F1AP_CriticalityDiagnostics_IE_Item_t));;
// criticalityDiagnostics_ie_item->iECriticality = F1AP_Criticality_reject;
// criticalityDiagnostics_ie_item->iE_ID = 0L;
// criticalityDiagnostics_ie_item->typeOfError = F1AP_TypeOfError_not_understood;
// asn1cSeqAdd(&ie->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics->list,
// criticalityDiagnostics_ie_item);
// }
// }
// asn1cSeqAdd(&out->protocolIEs.list, ie);
//}
/* encode */
uint8_t *buffer;
uint32_t len;
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(F1AP, "Failed to encode F1 context release complete\n");
return -1;
}
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0;
}
int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
{
F1AP_UEContextModificationRequest_t *container;
int i;
f1ap_ue_context_modif_req_t ue_context_modification = {0};
f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req = &ue_context_modification;
container = &pdu->choice.initiatingMessage->value.choice.UEContextModificationRequest;
/* mandatory */
/* GNB_CU_UE_F1AP_ID */
F1AP_UEContextModificationRequestIEs_t *ieCU;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieCU, container,
F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
f1ap_ue_context_modification_req->gNB_CU_ue_id = ieCU->value.choice.GNB_CU_UE_F1AP_ID;
/* mandatory */
/* GNB_DU_UE_F1AP_ID */
F1AP_UEContextModificationRequestIEs_t *ieDU_UE;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieDU_UE, container,
F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
f1ap_ue_context_modification_req->gNB_DU_ue_id = ieDU_UE->value.choice.GNB_DU_UE_F1AP_ID;
/* SRB */
F1AP_UEContextModificationRequestIEs_t *ieSrb;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieSrb, container,
F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List, false);
F1AP_UEContextModificationRequestIEs_t *ieTxInd;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t,
ieTxInd,
container,
F1AP_ProtocolIE_ID_id_TransmissionActionIndicator,
false);
if (ieTxInd != NULL) {
f1ap_ue_context_modification_req->transm_action_ind = calloc_or_fail(1, sizeof(*f1ap_ue_context_modification_req->transm_action_ind));
*f1ap_ue_context_modification_req->transm_action_ind = ieTxInd->value.choice.TransmissionActionIndicator;
// Stop is guaranteed to be 0, by restart might be different from 1
static_assert((int)F1AP_TransmissionActionIndicator_restart == (int)TransmActionInd_RESTART,
"mismatch of ASN.1 and internal representation\n");
}
if(ieSrb != NULL) {
f1ap_ue_context_modification_req->srbs_to_be_setup_length = ieSrb->value.choice.SRBs_ToBeSetupMod_List.list.count;
f1ap_ue_context_modification_req->srbs_to_be_setup = calloc(f1ap_ue_context_modification_req->srbs_to_be_setup_length,
sizeof(f1ap_srb_to_be_setup_t));
AssertFatal(f1ap_ue_context_modification_req->srbs_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_req->srbs_to_be_setup\n");
for (i = 0; i < f1ap_ue_context_modification_req->srbs_to_be_setup_length; ++i) {
f1ap_srb_to_be_setup_t *srb_p = &f1ap_ue_context_modification_req->srbs_to_be_setup[i];
F1AP_SRBs_ToBeSetupMod_Item_t *srbs_tobesetupmod_item_p;
srbs_tobesetupmod_item_p = &((F1AP_SRBs_ToBeSetupMod_ItemIEs_t *)ieSrb->value.choice.SRBs_ToBeSetupMod_List.list.array[i])->value.choice.SRBs_ToBeSetupMod_Item;
srb_p->srb_id = srbs_tobesetupmod_item_p->sRBID;
}
}
/* DRB */
F1AP_UEContextModificationRequestIEs_t *ieDrb;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieDrb, container,
F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List, false);
if(ieDrb!=NULL) {
f1ap_ue_context_modification_req->drbs_to_be_setup_length = ieDrb->value.choice.DRBs_ToBeSetupMod_List.list.count;
f1ap_ue_context_modification_req->drbs_to_be_setup = calloc(f1ap_ue_context_modification_req->drbs_to_be_setup_length,
sizeof(f1ap_drb_to_be_setup_t));
AssertFatal(f1ap_ue_context_modification_req->drbs_to_be_setup,
"could not allocate memory for f1ap_ue_context_setup_req->drbs_to_be_setup\n");
for (i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_setup_length; ++i) {
f1ap_drb_to_be_setup_t *drb_p = &f1ap_ue_context_modification_req->drbs_to_be_setup[i];
F1AP_DRBs_ToBeSetupMod_Item_t *drbs_tobesetupmod_item_p =
&((F1AP_DRBs_ToBeSetupMod_ItemIEs_t *)ieDrb->value.choice.DRBs_ToBeSetupMod_List.list.array[i])->value.choice.DRBs_ToBeSetupMod_Item;
drb_p->drb_id = drbs_tobesetupmod_item_p->dRBID;
/* TODO in the following, assume only one UP UL TNL is present.
* this matches/assumes OAI CU implementation, can be up to 2! */
drb_p->up_ul_tnl_length = 1;
AssertFatal(drbs_tobesetupmod_item_p->uLUPTNLInformation_ToBeSetup_List.list.count > 0,
"no UL UP TNL Information in DRBs to be Setup list\n");
F1AP_ULUPTNLInformation_ToBeSetup_Item_t *ul_up_tnl_info_p = (F1AP_ULUPTNLInformation_ToBeSetup_Item_t *)drbs_tobesetupmod_item_p->uLUPTNLInformation_ToBeSetup_List.list.array[0];
F1AP_GTPTunnel_t *ul_up_tnl0 = ul_up_tnl_info_p->uLUPTNLInformation.choice.gTPTunnel;
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&ul_up_tnl0->transportLayerAddress, drb_p->up_ul_tnl[0].tl_address);
OCTET_STRING_TO_UINT32(&ul_up_tnl0->gTP_TEID, drb_p->up_ul_tnl[0].teid);
// 3GPP assumes GTP-U is on port 2152, but OAI is configurable
drb_p->up_ul_tnl[0].port = getCxt(instance)->net_config.CUport;
switch (drbs_tobesetupmod_item_p->rLCMode) {
case F1AP_RLCMode_rlc_am:
drb_p->rlc_mode = F1AP_RLC_MODE_AM;
break;
case F1AP_RLCMode_rlc_um_bidirectional:
drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR;
break;
default:
LOG_W(F1AP, "unsupported RLC Mode %ld received: setting UM bidir\n", drbs_tobesetupmod_item_p->rLCMode);
drb_p->rlc_mode = F1AP_RLC_MODE_UM_BIDIR;
break;
}
if (drbs_tobesetupmod_item_p->qoSInformation.present == F1AP_QoSInformation_PR_eUTRANQoS) {
AssertFatal(false, "Decode of eUTRANQoS is not implemented yet");
} // EUTRAN QoS Information
else {
/* 12.1.2 DRB_Information */
if (drbs_tobesetupmod_item_p->qoSInformation.present == F1AP_QoSInformation_PR_choice_extension) {
F1AP_QoSInformation_ExtIEs_t *ie =
(F1AP_QoSInformation_ExtIEs_t *)drbs_tobesetupmod_item_p->qoSInformation.choice.choice_extension;
if (ie->id == F1AP_ProtocolIE_ID_id_DRB_Information && ie->criticality == F1AP_Criticality_reject
&& ie->value.present == F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information) {
const F1AP_DRB_Information_t *dRB_Info = &ie->value.choice.DRB_Information;
f1ap_drb_information_t *drb_info = &drb_p->drb_info;
/* QoS-Flow-Level-QoS-Parameters */
/* QoS Characteristics*/
f1ap_read_drb_qos_param(&dRB_Info->dRB_QoS, &drb_info->drb_qos);
// 12.1.2.4 flows_Mapped_To_DRB_List
drb_info->flows_to_be_setup_length = dRB_Info->flows_Mapped_To_DRB_List.list.count;
drb_info->flows_mapped_to_drb = calloc(drb_info->flows_to_be_setup_length, sizeof(f1ap_flows_mapped_to_drb_t));
AssertFatal(drb_info->flows_mapped_to_drb, "could not allocate memory for drb_p->drb_info.flows_mapped_to_drb\n");
f1ap_read_flows_mapped(&dRB_Info->flows_Mapped_To_DRB_List, drb_info->flows_mapped_to_drb, drb_info->flows_to_be_setup_length);
/* S-NSSAI */
f1ap_read_drb_nssai(&dRB_Info->sNSSAI, &drb_p->nssai);
}
}
}
}
}
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieDrb, container,
F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List, false);
if (ieDrb != NULL) {
f1ap_ue_context_modification_req->drbs_to_be_released_length = ieDrb->value.choice.DRBs_ToBeReleased_List.list.count;
f1ap_ue_context_modification_req->drbs_to_be_released =
calloc(f1ap_ue_context_modification_req->drbs_to_be_released_length, sizeof(f1ap_drb_to_be_released_t));
AssertFatal(f1ap_ue_context_modification_req->drbs_to_be_released,
"could not allocate memory for f1ap_ue_context_released_req->drbs_to_be_released\n");
for (i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_released_length; ++i) {
F1AP_DRBs_ToBeReleased_ItemIEs_t *tbrel = (F1AP_DRBs_ToBeReleased_ItemIEs_t *)ieDrb->value.choice.DRBs_ToBeReleased_List.list.array[i];
DevAssert(tbrel->id == F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item);
DevAssert(tbrel->value.present == F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item);
f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id = tbrel->value.choice.DRBs_ToBeReleased_Item.dRBID;
}
}
/* RRC Reconfiguration Complete indicator */
F1AP_UEContextModificationRequestIEs_t *ieReconf;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieReconf, container,
F1AP_ProtocolIE_ID_id_RRCReconfigurationCompleteIndicator, false);
if(ieReconf) {
switch(ieReconf->value.choice.RRCReconfigurationCompleteIndicator){
case F1AP_RRCReconfigurationCompleteIndicator_true:
f1ap_ue_context_modification_req->ReconfigComplOutcome = RRCreconf_success;
break;
case F1AP_RRCReconfigurationCompleteIndicator_failure:
f1ap_ue_context_modification_req->ReconfigComplOutcome = RRCreconf_failure;
break;
}
}
/* RRCContainer */
F1AP_UEContextModificationRequestIEs_t *ieRRC;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t, ieRRC, container,
F1AP_ProtocolIE_ID_id_RRCContainer, false);
if (ieRRC) {
/* correct here */
if ( ieRRC->value.choice.RRCContainer.size ) {
f1ap_ue_context_modification_req->rrc_container = malloc(ieRRC->value.choice.RRCContainer.size);
memcpy(f1ap_ue_context_modification_req->rrc_container,
ieRRC->value.choice.RRCContainer.buf, ieRRC->value.choice.RRCContainer.size);
f1ap_ue_context_modification_req->rrc_container_length = ieRRC->value.choice.RRCContainer.size;
} else {
LOG_E(F1AP, " RRCContainer in UEContextModificationRequestIEs size id 0\n");
}
} else {
LOG_D(F1AP, "can't find RRCContainer in UEContextModificationRequestIEs by id %ld \n", F1AP_ProtocolIE_ID_id_RRCContainer);
}
/* CU2DU Information */
F1AP_UEContextModificationRequestIEs_t *ieCU2DU = NULL;
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRequestIEs_t,
ieCU2DU,
container,
F1AP_ProtocolIE_ID_id_CUtoDURRCInformation,
false);
if (ieCU2DU != NULL) {
f1ap_ue_context_modification_req->cu_to_du_rrc_information =
calloc(1, sizeof(*f1ap_ue_context_modification_req->cu_to_du_rrc_information));
AssertFatal(f1ap_ue_context_modification_req->cu_to_du_rrc_information != NULL, "out of memory\n");
cu_to_du_rrc_information_t *cu2du = f1ap_ue_context_modification_req->cu_to_du_rrc_information;
const F1AP_CUtoDURRCInformation_t *cu2duie = &ieCU2DU->value.choice.CUtoDURRCInformation;
if (cu2duie->cG_ConfigInfo != NULL)
LOG_W(F1AP, "UE RNTI %04x: ignoring cg_ConfigInfo, not implemented\n", f1ap_ue_context_modification_req->gNB_DU_ue_id);
if (cu2duie->measConfig != NULL)
LOG_W(F1AP, "UE RNTI %04x: ignoring measConfig, not implemented\n", f1ap_ue_context_modification_req->gNB_DU_ue_id);
if (cu2duie->uE_CapabilityRAT_ContainerList != NULL) {
F1AP_UE_CapabilityRAT_ContainerList_t *uecap = cu2duie->uE_CapabilityRAT_ContainerList;
cu2du->uE_CapabilityRAT_ContainerList = calloc(uecap->size, sizeof(*cu2du->uE_CapabilityRAT_ContainerList));
AssertFatal(cu2du->uE_CapabilityRAT_ContainerList != NULL, "out of memory\n");
cu2du->uE_CapabilityRAT_ContainerList_length = uecap->size;
memcpy(cu2du->uE_CapabilityRAT_ContainerList, uecap->buf, uecap->size);
}
}
ue_context_modification_request(f1ap_ue_context_modification_req);
return 0;
}
int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_modif_resp_t *resp)
{
F1AP_F1AP_PDU_t pdu= {0};
F1AP_UEContextModificationResponse_t *out;
uint8_t *buffer=NULL;
uint32_t len=0;
/* Create */
/* 0. Message Type */
pdu.present = F1AP_F1AP_PDU_PR_successfulOutcome;
asn1cCalloc(pdu.choice.successfulOutcome,tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_UEContextModification;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_SuccessfulOutcome__value_PR_UEContextModificationResponse;
out = &tmp->value.choice.UEContextModificationResponse;
/* mandatory */
/* c1. GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_UEContextModificationResponseIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = resp->gNB_CU_ue_id;
/* mandatory */
/* c2. GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_UEContextModificationResponseIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = resp->gNB_DU_ue_id;
/* optional */
/* c3. ResourceCoordinationTransferContainer */
if (0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer;
ie3->criticality = F1AP_Criticality_ignore;
ie3->value.present = F1AP_UEContextModificationResponseIEs__value_PR_ResourceCoordinationTransferContainer;
OCTET_STRING_fromBuf(&ie3->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as",
strlen("asdsa1d32sa1d31asd31as"));
}
/* optional */
/* c4. DUtoCURRCInformation */
if(resp->du_to_cu_rrc_information!=NULL){
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie4);
ie4->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation;
ie4->criticality = F1AP_Criticality_reject;
ie4->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DUtoCURRCInformation;
if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){
/* cellGroupConfig */
OCTET_STRING_fromBuf(&ie4->value.choice.DUtoCURRCInformation.cellGroupConfig, (const char *)resp->du_to_cu_rrc_information->cellGroupConfig,
resp->du_to_cu_rrc_information->cellGroupConfig_length);
}
/* OPTIONAL */
/* measGapConfig */
if (resp->du_to_cu_rrc_information->measGapConfig!=NULL) {
OCTET_STRING_fromBuf(ie4->value.choice.DUtoCURRCInformation.measGapConfig, (const char *)resp->du_to_cu_rrc_information->measGapConfig,
resp->du_to_cu_rrc_information->measGapConfig_length);
}
/* OPTIONAL */
/* requestedP_MaxFR1 */
if (resp->du_to_cu_rrc_information->requestedP_MaxFR1!=NULL) {
OCTET_STRING_fromBuf(ie4->value.choice.DUtoCURRCInformation.requestedP_MaxFR1, (const char *)resp->du_to_cu_rrc_information->requestedP_MaxFR1,
resp->du_to_cu_rrc_information->requestedP_MaxFR1_length);
}
}
/* optional */
/* c5. DRBs_Setup_List */
if(resp->drbs_to_be_setup_length > 0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie5);
ie5->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_List;
ie5->criticality = F1AP_Criticality_ignore;
ie5->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_SetupMod_List;
for (int i=0; i< resp->drbs_to_be_setup_length; i++) {
asn1cSequenceAdd(ie5->value.choice.DRBs_SetupMod_List.list, F1AP_DRBs_SetupMod_ItemIEs_t, drbs_setupmod_item_ies);
drbs_setupmod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_SetupMod_Item;
drbs_setupmod_item_ies->criticality = F1AP_Criticality_ignore;
drbs_setupmod_item_ies->value.present = F1AP_DRBs_SetupMod_ItemIEs__value_PR_DRBs_SetupMod_Item;
/* 7.1 DRBs_Setup_Item */
/* ADD */
F1AP_DRBs_SetupMod_Item_t *drbs_setupmod_item=&drbs_setupmod_item_ies->value.choice.DRBs_SetupMod_Item;
/* dRBID */
drbs_setupmod_item->dRBID = resp->drbs_to_be_setup[i].drb_id;
for (int j=0; j<resp->drbs_to_be_setup[i].up_dl_tnl_length; j++) {
const f1ap_up_tnl_t *tnl = &resp->drbs_to_be_setup[i].up_dl_tnl[j];
DevAssert(tnl->teid > 0);
/* ADD */
asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list,
F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item);
dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
/* gTPTunnel */
asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel);
/* transportLayerAddress */
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress);
/* gTP_TEID */
INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID);
} // for j
} // for i
}
/* optional */
/* c6. DRBs_Modified_List */
if(resp->drbs_to_be_modified_length > 0){
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie6);
ie6->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_List;
ie6->criticality = F1AP_Criticality_ignore;
ie6->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_Modified_List;
for (int i=0; i<resp->drbs_to_be_modified_length; i++) {
asn1cSequenceAdd(ie6->value.choice.DRBs_Modified_List.list,
F1AP_DRBs_Modified_ItemIEs_t, drbs_modified_item_ies);
drbs_modified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_Modified_Item;
drbs_modified_item_ies->criticality = F1AP_Criticality_ignore;
drbs_modified_item_ies->value.present = F1AP_DRBs_Modified_ItemIEs__value_PR_DRBs_Modified_Item;
/* DRBs_modified_Item */
F1AP_DRBs_Modified_Item_t *drbs_modified_item= &drbs_modified_item_ies->value.choice.DRBs_Modified_Item;
/* dRBID */
drbs_modified_item->dRBID = resp->drbs_to_be_modified[i].drb_id;
/* ULTunnels_Modified_List */
for (int j=0; j<resp->drbs_to_be_modified[i].up_dl_tnl_length; j++) {
/* DLTunnels_Modified_Item */
asn1cSequenceAdd(drbs_modified_item->dLUPTNLInformation_ToBeSetup_List.list,
F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item);
asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item, tmp);
tmp->dLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel;
asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, gTPTunnel);
/* transportLayerAddress */
struct sockaddr_in addr= {0};
inet_pton(AF_INET, getCxt(0)->net_config.DU_f1u_ip_address, &addr.sin_addr.s_addr);
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress);
/* gTP_TEID */
INT32_TO_OCTET_STRING(resp->drbs_to_be_modified[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID);
}
}
}
/* optional */
/* c7. SRBs_FailedToBeSetupMod_List */
if(resp->srbs_failed_to_be_setup_length > 0){
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie7);
ie7->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_List;
ie7->criticality = F1AP_Criticality_reject;
ie7->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SRBs_FailedToBeSetupMod_List;
for (int i=0; i<resp->srbs_to_be_setup_length; i++) {
asn1cSequenceAdd(ie7->value.choice.SRBs_FailedToBeSetupMod_List.list,
F1AP_SRBs_FailedToBeSetupMod_ItemIEs_t, srbs_failedToBeSetupMod_item_ies);
srbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_FailedToBeSetupMod_Item;
srbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore;
srbs_failedToBeSetupMod_item_ies->value.present = F1AP_SRBs_FailedToBeSetupMod_ItemIEs__value_PR_SRBs_FailedToBeSetupMod_Item;
/* 9.1 SRBs_FailedToBeSetupMod_Item */
F1AP_SRBs_FailedToBeSetupMod_Item_t *srbs_failedToBeSetupMod_item=
&srbs_failedToBeSetupMod_item_ies->value.choice.SRBs_FailedToBeSetupMod_Item;
/* - sRBID */
srbs_failedToBeSetupMod_item->sRBID = resp->srbs_failed_to_be_setup[i].rb_id;
asn1cCalloc(srbs_failedToBeSetupMod_item->cause, tmp);
tmp->present = F1AP_Cause_PR_radioNetwork;
tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id;
}
}
/* optional */
/* c8. DRBs_FailedToBeSetupMod_List */
if(resp->drbs_failed_to_be_setup_length > 0){
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie8);
ie8->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_List;
ie8->criticality = F1AP_Criticality_reject;
ie8->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeSetupMod_List;
for (int i=0; i<resp->drbs_failed_to_be_setup_length; i++) {
asn1cSequenceAdd(ie8->value.choice.DRBs_FailedToBeSetupMod_List.list,
F1AP_DRBs_FailedToBeSetupMod_ItemIEs_t, drbs_failedToBeSetupMod_item_ies);
drbs_failedToBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeSetupMod_Item;
drbs_failedToBeSetupMod_item_ies->criticality = F1AP_Criticality_reject;
drbs_failedToBeSetupMod_item_ies->value.present = F1AP_DRBs_FailedToBeSetupMod_ItemIEs__value_PR_DRBs_FailedToBeSetupMod_Item;
/* DRBs_FailedToBeSetupMod_Item */
F1AP_DRBs_FailedToBeSetupMod_Item_t *drbs_failedToBeSetupMod_item=
&drbs_failedToBeSetupMod_item_ies->value.choice.DRBs_FailedToBeSetupMod_Item;
/* dRBID */
drbs_failedToBeSetupMod_item->dRBID = resp->drbs_failed_to_be_setup[i].rb_id;
drbs_failedToBeSetupMod_item->cause = (F1AP_Cause_t *)calloc(1, sizeof(F1AP_Cause_t));
drbs_failedToBeSetupMod_item->cause->present = F1AP_Cause_PR_radioNetwork;
drbs_failedToBeSetupMod_item->cause->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id;
}
}
/* optional */
/* c9. SCell_FailedtoSetupMod_List */
if(0){
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie9);
ie9->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_List;
ie9->criticality = F1AP_Criticality_ignore;
ie9->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SCell_FailedtoSetupMod_List;
for (int i=0; i<1; i++) {
asn1cSequenceAdd(ie9->value.choice.SCell_FailedtoSetupMod_List.list,
F1AP_SCell_FailedtoSetupMod_ItemIEs_t, scell_failedtoSetupMod_item_ies);
scell_failedtoSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_FailedtoSetupMod_Item;
scell_failedtoSetupMod_item_ies->criticality = F1AP_Criticality_ignore;
scell_failedtoSetupMod_item_ies->value.present = F1AP_SCell_FailedtoSetupMod_ItemIEs__value_PR_SCell_FailedtoSetupMod_Item;
/* 8.1 SCell_ToBeSetup_Item */
F1AP_SCell_FailedtoSetupMod_Item_t *scell_failedtoSetupMod_item=&scell_failedtoSetupMod_item_ies->value.choice.SCell_FailedtoSetupMod_Item;
/* - sCell_ID */
addnRCGI(scell_failedtoSetupMod_item->sCell_ID, &getCxt(0)->setupReq.cell[i].info);
asn1cCalloc(scell_failedtoSetupMod_item->cause, tmp);
tmp->present = F1AP_Cause_PR_radioNetwork;
tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id;
}
}
/* optional */
/* c10. DRBs_FailedToBeModified_List */
if(0){
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie10);
ie10->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_List;
ie10->criticality = F1AP_Criticality_reject;
ie10->value.present = F1AP_UEContextModificationResponseIEs__value_PR_DRBs_FailedToBeModified_List;
for (int i=0; i<1; i++) {
asn1cSequenceAdd(ie10->value.choice.DRBs_FailedToBeModified_List.list,
F1AP_DRBs_FailedToBeModified_ItemIEs_t, drbs_failedToBeModified_item_ies);
drbs_failedToBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_FailedToBeModified_Item;
drbs_failedToBeModified_item_ies->criticality = F1AP_Criticality_reject;
drbs_failedToBeModified_item_ies->value.present = F1AP_DRBs_FailedToBeModified_ItemIEs__value_PR_DRBs_FailedToBeModified_Item;
/* 13.1 DRBs_FailedToBeModified_Item */
F1AP_DRBs_FailedToBeModified_Item_t *drbs_failedToBeModified_item=
&drbs_failedToBeModified_item_ies->value.choice.DRBs_FailedToBeModified_Item ;
/* dRBID */
drbs_failedToBeModified_item->dRBID = 30L;
asn1cCalloc(drbs_failedToBeModified_item->cause, tmp);
tmp->present = F1AP_Cause_PR_radioNetwork;
tmp->choice.radioNetwork = F1AP_CauseRadioNetwork_unknown_or_already_allocated_gnb_du_ue_f1ap_id;
}
}
// /* */
/* c11. CriticalityDiagnostics */
if (0) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie11);
ie11->id = F1AP_ProtocolIE_ID_id_CriticalityDiagnostics;
ie11->criticality = F1AP_Criticality_ignore;
ie11->value.present = F1AP_UEContextModificationResponseIEs__value_PR_CriticalityDiagnostics;
// dummy value
/* optional */
/* procedureCode */
if (0) {
ie11->value.choice.CriticalityDiagnostics.procedureCode = (F1AP_ProcedureCode_t *)calloc(1, sizeof(F1AP_ProcedureCode_t));
*ie11->value.choice.CriticalityDiagnostics.procedureCode = 0L;
}
/* optional */
/* triggeringMessage */
if (0) {
ie11->value.choice.CriticalityDiagnostics.triggeringMessage = (F1AP_TriggeringMessage_t *)calloc(1, sizeof(F1AP_TriggeringMessage_t));
*ie11->value.choice.CriticalityDiagnostics.triggeringMessage = F1AP_TriggeringMessage_successful_outcome;
}
/* optional */
/* procedureCriticality */
if (0) {
ie11->value.choice.CriticalityDiagnostics.procedureCriticality = (F1AP_Criticality_t *)calloc(1, sizeof(F1AP_Criticality_t));
*ie11->value.choice.CriticalityDiagnostics.procedureCriticality = F1AP_Criticality_reject;
}
/* optional */
/* transactionID */
if (0) {
ie11->value.choice.CriticalityDiagnostics.transactionID = (F1AP_TransactionID_t *)calloc(1, sizeof(F1AP_TransactionID_t));
*ie11->value.choice.CriticalityDiagnostics.transactionID = 0L;
}
/* optional */
/* F1AP_CriticalityDiagnostics_IE_List */
if (0) {
for (int i=0; i<0; i++) {
asn1cSequenceAdd(ie11->value.choice.CriticalityDiagnostics.iEsCriticalityDiagnostics->list, F1AP_CriticalityDiagnostics_IE_Item_t, criticalityDiagnostics_ie_item);
criticalityDiagnostics_ie_item->iECriticality = F1AP_Criticality_reject;
criticalityDiagnostics_ie_item->iE_ID = 0L;
criticalityDiagnostics_ie_item->typeOfError = F1AP_TypeOfError_not_understood;
}
}
}
/* optional */
/* c12. SRBs_Setup_List */
if(resp->srbs_to_be_setup_length > 0){
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationResponseIEs_t, ie12);
ie12->id = F1AP_ProtocolIE_ID_id_SRBs_SetupMod_List;
ie12->criticality = F1AP_Criticality_ignore;
ie12->value.present = F1AP_UEContextModificationResponseIEs__value_PR_SRBs_SetupMod_List;
for (int i=0; i< resp->srbs_to_be_setup_length; i++) {//
asn1cSequenceAdd(ie12->value.choice.SRBs_SetupMod_List.list,
F1AP_SRBs_SetupMod_ItemIEs_t, srbs_setupmod_item_ies);
srbs_setupmod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_SetupMod_Item;
srbs_setupmod_item_ies->criticality = F1AP_Criticality_ignore;
srbs_setupmod_item_ies->value.present = F1AP_SRBs_SetupMod_ItemIEs__value_PR_SRBs_SetupMod_Item;
/* 11.1 SRBs_Setup_Item */
/* ADD */
F1AP_SRBs_SetupMod_Item_t *srbs_setupmod_item=&srbs_setupmod_item_ies->value.choice.SRBs_SetupMod_Item;
/* sRBID */
srbs_setupmod_item->sRBID = resp->srbs_to_be_setup[i].srb_id;
srbs_setupmod_item->lCID = resp->srbs_to_be_setup[i].srb_id;
}
}
/* encode */
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(F1AP, "Failed to encode F1 UE CONTEXT MODIFICATION RESPONSE\n");
return -1;
}
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0;
}
int DU_send_UE_CONTEXT_MODIFICATION_FAILURE(sctp_assoc_t assoc_id) {
AssertFatal(1==0,"Not implemented yet\n");
}
int DU_send_UE_CONTEXT_MODIFICATION_REQUIRED(sctp_assoc_t assoc_id, f1ap_ue_context_modif_required_t *required)
{
/* 0. Message Type */
F1AP_F1AP_PDU_t pdu = {0};
pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage;
asn1cCalloc(pdu.choice.initiatingMessage, tmp);
tmp->procedureCode = F1AP_ProcedureCode_id_UEContextModificationRequired;
tmp->criticality = F1AP_Criticality_reject;
tmp->value.present = F1AP_InitiatingMessage__value_PR_UEContextModificationRequired;
F1AP_UEContextModificationRequired_t *out = &tmp->value.choice.UEContextModificationRequired;
/* mandatory GNB_CU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie1);
ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID;
ie1->criticality = F1AP_Criticality_reject;
ie1->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_GNB_CU_UE_F1AP_ID;
ie1->value.choice.GNB_CU_UE_F1AP_ID = required->gNB_CU_ue_id;
/* mandatory: GNB_DU_UE_F1AP_ID */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie2);
ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID;
ie2->criticality = F1AP_Criticality_reject;
ie2->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_GNB_DU_UE_F1AP_ID;
ie2->value.choice.GNB_DU_UE_F1AP_ID = required->gNB_DU_ue_id;
/* optional: Resource Coordination Transfer Container */
/* not implemented!*/
/* optional: DU-to-CU RRC Container */
if (required->du_to_cu_rrc_information) {
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie3);
ie3->id = F1AP_ProtocolIE_ID_id_DUtoCURRCInformation;
ie3->criticality = F1AP_Criticality_reject;
ie3->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_DUtoCURRCInformation;
const du_to_cu_rrc_information_t *du2cu = required->du_to_cu_rrc_information;
AssertFatal(du2cu->cellGroupConfig != NULL, "du2cu cellGroupConfig is mandatory!\n");
/* mandatorycellGroupConfig */
OCTET_STRING_fromBuf(&ie3->value.choice.DUtoCURRCInformation.cellGroupConfig,
(const char *)du2cu->cellGroupConfig,
du2cu->cellGroupConfig_length);
/* optional: measGapConfig */
if (du2cu->measGapConfig != NULL) {
OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.measGapConfig,
(const char *)du2cu->measGapConfig,
du2cu->measGapConfig_length);
}
/* optional: requestedP_MaxFR1 */
if (du2cu->requestedP_MaxFR1 != NULL) {
OCTET_STRING_fromBuf(ie3->value.choice.DUtoCURRCInformation.requestedP_MaxFR1,
(const char *)du2cu->requestedP_MaxFR1,
du2cu->requestedP_MaxFR1_length);
}
}
/* optional: DRB required to be modified */
/* not implemented */
/* optional: SRB required to be released */
/* not implemented */
/* optional: DRB required to be released */
/* not implemented */
/* mandatory: cause */
asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequiredIEs_t, ie4);
ie4->id = F1AP_ProtocolIE_ID_id_Cause;
ie4->criticality = F1AP_Criticality_reject;
ie4->value.present = F1AP_UEContextModificationRequiredIEs__value_PR_Cause;
F1AP_Cause_t *cause = &ie4->value.choice.Cause;
switch (required->cause) {
case F1AP_CAUSE_RADIO_NETWORK:
cause->present = F1AP_Cause_PR_radioNetwork;
cause->choice.radioNetwork = required->cause_value;
break;
case F1AP_CAUSE_TRANSPORT:
cause->present = F1AP_Cause_PR_transport;
cause->choice.transport = required->cause_value;
break;
case F1AP_CAUSE_PROTOCOL:
cause->present = F1AP_Cause_PR_protocol;
cause->choice.protocol = required->cause_value;
break;
case F1AP_CAUSE_MISC:
cause->present = F1AP_Cause_PR_misc;
cause->choice.misc = required->cause_value;
break;
case F1AP_CAUSE_NOTHING:
default:
cause->present = F1AP_Cause_PR_NOTHING;
break;
} // switch
/* optional: BH RLC Channel Required to be Released List */
/* not implemented */
/* optional: SL DRB Required to Be Modified List */
/* not implemented */
/* optional: SL DRB Required to be Released List */
/* not implemented */
/* optional: Candidate Cells To Be Cancelled List */
/* not implemented */
/* encode */
uint8_t *buffer = NULL;
uint32_t len = 0;
if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) {
LOG_E(F1AP, "Failed to encode F1 context release request\n");
return -1;
}
f1ap_itti_send_sctp_data_req(assoc_id, buffer, len);
return 0;
}
int DU_handle_UE_CONTEXT_MODIFICATION_CONFIRM(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
{
F1AP_UEContextModificationConfirm_t *container = &pdu->choice.successfulOutcome->value.choice.UEContextModificationConfirm;
f1ap_ue_context_modif_confirm_t confirm = {0};
F1AP_UEContextModificationConfirmIEs_t *ie = NULL;
/* mandatory: GNB_CU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
confirm.gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
/* mandatory: GNB_DU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
confirm.gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
/* optional: Resource Coordination Transfer Container */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
ie,
container,
F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer,
false);
AssertFatal(ie == NULL, "handling of Resource Coordination Transfer Container not implemented\n");
/* optional: DRBS Modified List */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
ie,
container,
F1AP_ProtocolIE_ID_id_DRBs_Modified_List,
false);
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
/* optional: RRC Container */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t, ie, container, F1AP_ProtocolIE_ID_id_RRCContainer, false);
if (ie != NULL) {
F1AP_RRCContainer_t *rrc_container = &ie->value.choice.RRCContainer;
confirm.rrc_container = malloc(rrc_container->size);
AssertFatal(confirm.rrc_container != NULL, "memory allocation failed\n");
memcpy(confirm.rrc_container, rrc_container->buf, rrc_container->size);
confirm.rrc_container_length = rrc_container->size;
}
/* optional: Criticality Diagnostics */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
ie,
container,
F1AP_ProtocolIE_ID_id_CriticalityDiagnostics,
false);
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
/* optional: Execute Duplication */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
ie,
container,
F1AP_ProtocolIE_ID_id_ExecuteDuplication,
false);
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
/* optional: Resource Coordination Transfer Information */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
ie,
container,
F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferInformation,
false);
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
/* optional: SL DRB Modified List */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationConfirmIEs_t,
ie,
container,
F1AP_ProtocolIE_ID_id_SLDRBs_Modified_List,
false);
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
ue_context_modification_confirm(&confirm);
return 0;
}
int DU_handle_UE_CONTEXT_MODIFICATION_REFUSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
{
F1AP_UEContextModificationRefuse_t *container = &pdu->choice.unsuccessfulOutcome->value.choice.UEContextModificationRefuse;
f1ap_ue_context_modif_refuse_t refuse = {0};
F1AP_UEContextModificationRefuseIEs_t *ie = NULL;
/* mandatory: GNB_CU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID, true);
refuse.gNB_CU_ue_id = ie->value.choice.GNB_CU_UE_F1AP_ID;
/* mandatory: GNB_DU_UE_F1AP_ID */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID, true);
refuse.gNB_DU_ue_id = ie->value.choice.GNB_DU_UE_F1AP_ID;
/* mandatory: Cause */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t, ie, container, F1AP_ProtocolIE_ID_id_Cause, true);
switch (ie->value.choice.Cause.present) {
case F1AP_Cause_PR_radioNetwork:
refuse.cause = F1AP_CAUSE_RADIO_NETWORK;
refuse.cause_value = ie->value.choice.Cause.choice.radioNetwork;
break;
case F1AP_Cause_PR_transport:
refuse.cause = F1AP_CAUSE_TRANSPORT;
refuse.cause_value = ie->value.choice.Cause.choice.transport;
break;
case F1AP_Cause_PR_protocol:
refuse.cause = F1AP_CAUSE_PROTOCOL;
refuse.cause_value = ie->value.choice.Cause.choice.protocol;
break;
case F1AP_Cause_PR_misc:
refuse.cause = F1AP_CAUSE_MISC;
refuse.cause_value = ie->value.choice.Cause.choice.misc;
break;
default:
LOG_W(F1AP, "Unknown cause for UE Context Modification Refuse message\n");
/* fall through */
case F1AP_Cause_PR_NOTHING:
refuse.cause = F1AP_CAUSE_NOTHING;
break;
}
/* optional: Criticality Diagnostics */
F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_UEContextModificationRefuseIEs_t,
ie,
container,
F1AP_ProtocolIE_ID_id_CriticalityDiagnostics,
false);
AssertFatal(ie == NULL, "handling of DRBs Modified List not implemented\n");
ue_context_modification_refuse(&refuse);
return 0;
}