Use F1 UE context setup/modif Request in stack
Use the new, tested F1 UE context setup request and modification requests in the stack. We have to do both at once, because there are some functions that are used by handlers for both messages, notably - handle_ue_context_drbs_setup() - handle_ue_context_srbs_setup() (+ and some functions called by those two). For instance, the first uses the (new/old) type f1ap_drb_to_be_setup_t/f1ap_drb_to_setup_t which is shared. The alternative would be to duplicate the functionality temporarily, and I want to avoid unnecessary code churn.
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include "f1ap_cu_ue_context_management.h"
|
||||
#include "lib/f1ap_rrc_message_transfer.h"
|
||||
#include "lib/f1ap_interface_management.h"
|
||||
#include "lib/f1ap_ue_context.h"
|
||||
#include "f1ap_cu_paging.h"
|
||||
#include "f1ap_cu_task.h"
|
||||
#include "openair2/RRC/NR/nr_rrc_defs.h"
|
||||
@@ -186,13 +187,13 @@ void *F1AP_CU_task(void *arg) {
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_SETUP_REQ: // from rrc
|
||||
CU_send_UE_CONTEXT_SETUP_REQUEST(assoc_id,
|
||||
&F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
|
||||
CU_send_UE_CONTEXT_SETUP_REQUEST(assoc_id, &F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
|
||||
free_ue_context_setup_req(&F1AP_UE_CONTEXT_SETUP_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_MODIFICATION_REQ:
|
||||
CU_send_UE_CONTEXT_MODIFICATION_REQUEST(assoc_id,
|
||||
&F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg));
|
||||
CU_send_UE_CONTEXT_MODIFICATION_REQUEST(assoc_id, &F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg));
|
||||
free_ue_context_mod_req(&F1AP_UE_CONTEXT_MODIFICATION_REQ(received_msg));
|
||||
break;
|
||||
|
||||
case F1AP_UE_CONTEXT_RELEASE_CMD: // from rrc
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,8 +36,7 @@
|
||||
/*
|
||||
* UE Context Setup
|
||||
*/
|
||||
int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id,
|
||||
f1ap_ue_context_setup_t *f1ap_ue_context_setup_req);
|
||||
int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_req_t *req);
|
||||
|
||||
int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
@@ -59,7 +58,7 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t asso
|
||||
/*
|
||||
* UE Context Modification (gNB-CU initiated)
|
||||
*/
|
||||
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_modif_req_t *f1ap_ue_context_modification_req);
|
||||
int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, const f1ap_ue_context_mod_req_t *req);
|
||||
int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
int CU_handle_UE_CONTEXT_MODIFICATION_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu);
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "f1ap_du_rrc_message_transfer.h"
|
||||
#include "lib/f1ap_rrc_message_transfer.h"
|
||||
#include "lib/f1ap_interface_management.h"
|
||||
#include "lib/f1ap_ue_context.h"
|
||||
#include "f1ap_du_task.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
|
||||
|
||||
@@ -34,295 +34,24 @@
|
||||
#include "f1ap_encoder.h"
|
||||
#include "f1ap_itti_messaging.h"
|
||||
#include "f1ap_du_ue_context_management.h"
|
||||
#include "lib/f1ap_ue_context.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_ue_context_setup_req_t req = {0};
|
||||
if (!decode_ue_context_setup_req(pdu, &req)) {
|
||||
LOG_E(F1AP, "cannot decode F1 UE Context Setup Request\n");
|
||||
free_ue_context_setup_req(&req);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ue_context_setup_request(&req);
|
||||
free_ue_context_setup_req(&req);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -893,214 +622,16 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, f1ap_ue_context_r
|
||||
|
||||
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");
|
||||
f1ap_ue_context_mod_req_t req = {0};
|
||||
if (!decode_ue_context_mod_req(pdu, &req)) {
|
||||
LOG_E(F1AP, "cannot decode F1 UE Context Modification Request\n");
|
||||
free_ue_context_mod_req(&req);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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");
|
||||
ue_context_modification_request(&req);
|
||||
free_ue_context_mod_req(&req);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user