diff --git a/openair2/COMMON/f1ap_messages_def.h b/openair2/COMMON/f1ap_messages_def.h index 405ecae3d5..c713361aa5 100644 --- a/openair2/COMMON/f1ap_messages_def.h +++ b/openair2/COMMON/f1ap_messages_def.h @@ -56,9 +56,9 @@ MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQUIRED, MESSAGE_PRIORITY_MED, f1ap_ue /* RRC -> F1AP messages */ MESSAGE_DEF(F1AP_DL_RRC_MESSAGE , MESSAGE_PRIORITY_MED, f1ap_dl_rrc_message_t , f1ap_dl_rrc_message ) //MESSAGE_DEF(F1AP_INITIAL_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED, f1ap_initial_context_setup_req_t , f1ap_initial_context_setup_req ) -MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_req) +MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_req_t, f1ap_ue_context_setup_req) MESSAGE_DEF(F1AP_UE_CONTEXT_SETUP_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_setup_t, f1ap_ue_context_setup_resp) -MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_req_t, f1ap_ue_context_modification_req) +MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REQ, MESSAGE_PRIORITY_MED, f1ap_ue_context_mod_req_t, f1ap_ue_context_mod_req) MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_RESP, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_resp_t, f1ap_ue_context_modification_resp) MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_CONFIRM, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_confirm_t, f1ap_ue_context_modification_confirm) MESSAGE_DEF(F1AP_UE_CONTEXT_MODIFICATION_REFUSE, MESSAGE_PRIORITY_MED, f1ap_ue_context_modif_refuse_t, f1ap_ue_context_modification_refuse) diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 9992473c9e..73b8162eb4 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -55,7 +55,7 @@ #define F1AP_UL_RRC_MESSAGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ul_rrc_message #define F1AP_UE_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_req #define F1AP_UE_CONTEXT_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_setup_resp -#define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_req +#define F1AP_UE_CONTEXT_MODIFICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_mod_req #define F1AP_UE_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_resp #define F1AP_UE_CONTEXT_MODIFICATION_FAIL(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_fail #define F1AP_UE_CONTEXT_MODIFICATION_REQUIRED(mSGpTR) (mSGpTR)->ittiMsg.f1ap_ue_context_modification_required @@ -645,7 +645,7 @@ typedef struct f1ap_ue_context_setup_s { uint8_t *rrc_container; int rrc_container_length; TransmActionInd_t *transm_action_ind; -} f1ap_ue_context_setup_t, f1ap_ue_context_modif_req_t, f1ap_ue_context_modif_resp_t; +} f1ap_ue_context_setup_t, f1ap_ue_context_modif_resp_t; typedef enum F1ap_Cause_e { F1AP_CAUSE_NOTHING, /* No components present */ diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index 4528a7766f..85375e4109 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -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 diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index f4bffe6144..9dc9e8c086 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -34,6 +34,7 @@ #include "f1ap_encoder.h" #include "f1ap_itti_messaging.h" #include "f1ap_cu_ue_context_management.h" +#include "lib/f1ap_ue_context.h" #include #include "rrc_extern.h" @@ -44,572 +45,25 @@ #include "openair2/E2AP/RAN_FUNCTION/O-RAN/ran_func_rc_extern.h" #endif -static void f1ap_write_drb_qos_param(const f1ap_qos_flow_level_qos_parameters_t *drb_qos_in, F1AP_QoSFlowLevelQoSParameters_t *asn1_qosparam) +int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_req_t *req) { - int type = drb_qos_in->qos_characteristics.qos_type; + F1AP_F1AP_PDU_t *pdu = encode_ue_context_setup_req(req); - const f1ap_qos_characteristics_t *drb_qos_char_in = &drb_qos_in->qos_characteristics; - if (type == NON_DYNAMIC) { - asn1_qosparam->qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - asn1cCalloc(asn1_qosparam->qoS_Characteristics.choice.non_Dynamic_5QI, tmp); - - /* 5QI */ - tmp->fiveQI = drb_qos_char_in->non_dynamic.fiveqi; - } else { - asn1_qosparam->qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(asn1_qosparam->qoS_Characteristics.choice.dynamic_5QI, tmp); - /* qoSPriorityLevel */ - tmp->qoSPriorityLevel = drb_qos_char_in->dynamic.qos_priority_level; - /* packetDelayBudget */ - tmp->packetDelayBudget = drb_qos_char_in->dynamic.packet_delay_budget; - /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = drb_qos_char_in->dynamic.packet_error_rate.per_scalar; - tmp->packetErrorRate.pER_Exponent = drb_qos_char_in->dynamic.packet_error_rate.per_scalar; - - /* OPTIONAL delayCritical */ - // asn1cCallocOne(asn1_qosparam->qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); - - /* OPTIONAL averagingWindow */ - // asn1cCallocOne(asn1_qosparam->qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); - - /* OPTIONAL maxDataBurstVolume */ - // asn1cCallocOne(asn1_qosparam->qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); - } - - { - asn1_qosparam->nGRANallocationRetentionPriority.priorityLevel = drb_qos_in->alloc_reten_priority.priority_level; - asn1_qosparam->nGRANallocationRetentionPriority.pre_emptionCapability = drb_qos_in->alloc_reten_priority.preemption_capability; - asn1_qosparam->nGRANallocationRetentionPriority.pre_emptionVulnerability = - drb_qos_in->alloc_reten_priority.preemption_vulnerability; - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(asn1_qosparam->gBR_QoS_Flow_Information, tmp); - asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); - - /* OPTIONAL */ - /* maxPacketLossRateDownlink */ - // asn1cCallocOne(asn1_qosparam->gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - - /* OPTIONAL */ - /* maxPacketLossRateUplink */ - //asn1cCallocOne(asn1_qosparam->gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } - - /* OPTIONAL */ - /* reflective_QoS_Attribute */ - if (0) { - asn1cCallocOne(asn1_qosparam->reflective_QoS_Attribute, 1L); - } -} - -static void f1ap_write_drb_nssai(const nssai_t *nssai, F1AP_SNSSAI_t *asn1_nssai) -{ - OCTET_STRING_fromBuf(&asn1_nssai->sST, (char *)&nssai->sst, 1); - - /* OPTIONAL */ - if (nssai->sd != 0xffffff) { - char sd_buffer[3]; - INT24_TO_BUFFER(nssai->sd, sd_buffer); - asn1cCalloc(asn1_nssai->sD, sD); - OCTET_STRING_fromBuf(sD, sd_buffer, 3); - } -} - -static void f1ap_write_flows_mapped(const f1ap_flows_mapped_to_drb_t *flows_mapped, F1AP_Flows_Mapped_To_DRB_List_t *asn1_flows_mapped, int n) -{ - for (int k = 0; k < n; k++) { - asn1cSequenceAdd(asn1_flows_mapped->list, F1AP_Flows_Mapped_To_DRB_Item_t, flow_item); - - const f1ap_flows_mapped_to_drb_t *qos_flow_in = flows_mapped + k; - - /* qoSFlowIndicator */ - flow_item->qoSFlowIdentifier = qos_flow_in->qfi; - - /* qoSFlowLevelQoSParameters */ - const f1ap_qos_flow_level_qos_parameters_t *flow_qos_params_in = &qos_flow_in->qos_params; - /* qoS_Characteristics */ - - F1AP_QoS_Characteristics_t *QosParams = &flow_item->qoSFlowLevelQoSParameters.qoS_Characteristics; - const f1ap_qos_characteristics_t *flow_qos_char_in = &flow_qos_params_in->qos_characteristics; - - int type = flow_qos_params_in->qos_characteristics.qos_type; - if (type == NON_DYNAMIC) { - QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - asn1cCalloc(QosParams->choice.non_Dynamic_5QI, tmp); - - /* 5QI */ - tmp->fiveQI = flow_qos_char_in->non_dynamic.fiveqi; - } else { - QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); - /* qoSPriorityLevel */ - tmp->qoSPriorityLevel = flow_qos_char_in->dynamic.qos_priority_level; - /* packetDelayBudget */ - tmp->packetDelayBudget = flow_qos_char_in->dynamic.packet_delay_budget; - /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = flow_qos_char_in->dynamic.packet_error_rate.per_scalar; - tmp->packetErrorRate.pER_Exponent = flow_qos_char_in->dynamic.packet_error_rate.per_exponent; - - /* OPTIONAL delayCritical */ - //asn1cCallocOne(QosParams->choice.dynamic_5QI->delayCritical, 1); - - /* OPTIONAL averagingWindow */ - //asn1cCallocOne(QosParams->choice.dynamic_5QI->averagingWindow, 1); - - /* OPTIONAL maxDataBurstVolume */ - //asn1cCallocOne(QosParams->choice.dynamic_5QI->maxDataBurstVolume, 1); - } - - /* nGRANallocationRetentionPriority */ - { - flow_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = - flow_qos_params_in->alloc_reten_priority.priority_level; - flow_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = - flow_qos_params_in->alloc_reten_priority.preemption_capability; - flow_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = - flow_qos_params_in->alloc_reten_priority.preemption_vulnerability; - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(flow_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp); - asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L); - asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L); - - /* OPTIONAL maxPacketLossRateDownlink */ - //asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - - /* OPTIONAL maxPacketLossRateUplink */ - //asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } - - /* OPTIONAL reflective_QoS_Attribute */ - //asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); - } -} - -int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setup_t *f1ap_ue_context_setup_req) -{ - F1AP_F1AP_PDU_t pdu= {0}; - /* Create */ - /* 0. Message Type */ - pdu.present = F1AP_F1AP_PDU_PR_initiatingMessage; - asn1cCalloc(pdu.choice.initiatingMessage, tmp); - tmp->procedureCode = F1AP_ProcedureCode_id_UEContextSetup; - tmp->criticality = F1AP_Criticality_reject; - tmp->value.present = F1AP_InitiatingMessage__value_PR_UEContextSetupRequest; - F1AP_UEContextSetupRequest_t *out = &pdu.choice.initiatingMessage->value.choice.UEContextSetupRequest; - /* mandatory */ - /* c1. GNB_CU_UE_F1AP_ID */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie1); - ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; - ie1->criticality = F1AP_Criticality_reject; - ie1->value.present = F1AP_UEContextSetupRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_CU_ue_id; - - /* optional */ - /* c2. GNB_DU_UE_F1AP_ID */ - if (f1ap_ue_context_setup_req->gNB_DU_ue_id) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie2); - ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; - ie2->criticality = F1AP_Criticality_ignore; - ie2->value.present = F1AP_UEContextSetupRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_ue_context_setup_req->gNB_DU_ue_id; - } - - /* mandatory */ - /* c3. SpCell_ID */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_SpCell_ID; - ie3->criticality = F1AP_Criticality_reject; - ie3->value.present = F1AP_UEContextSetupRequestIEs__value_PR_NRCGI; - /* - nRCGI */ - addnRCGI(ie3->value.choice.NRCGI, f1ap_ue_context_setup_req); - /* mandatory */ - /* c4. ServCellIndex */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_ServCellIndex; - ie4->criticality = F1AP_Criticality_reject; - ie4->value.present = F1AP_UEContextSetupRequestIEs__value_PR_ServCellIndex; - ie4->value.choice.ServCellIndex = 0; - - /* optional */ - /* c5. CellULConfigured */ - if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie5); - ie5->id = F1AP_ProtocolIE_ID_id_SpCellULConfigured; - ie5->criticality = F1AP_Criticality_ignore; - ie5->value.present = F1AP_UEContextSetupRequestIEs__value_PR_CellULConfigured; - ie5->value.choice.CellULConfigured = F1AP_CellULConfigured_ul; - } - - /* mandatory */ - /* c6. CUtoDURRCInformation */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie6); - ie6->id = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation; - ie6->criticality = F1AP_Criticality_reject; - ie6->value.present = F1AP_UEContextSetupRequestIEs__value_PR_CUtoDURRCInformation; - - if (f1ap_ue_context_setup_req->cu_to_du_rrc_information!=NULL) { - /* optional */ - /* 6.1 cG_ConfigInfo */ - if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo_length > 0) { - DevAssert(f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo != NULL); - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.cG_ConfigInfo, cG_ConfigInfo); - OCTET_STRING_fromBuf(cG_ConfigInfo, (const char *)f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo, - f1ap_ue_context_setup_req->cu_to_du_rrc_information->cG_ConfigInfo_length); - } - - /* optional */ - /* 6.2 uE_CapabilityRAT_ContainerList */ - if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){ - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, uE_CapabilityRAT_ContainerList ); - OCTET_STRING_fromBuf(uE_CapabilityRAT_ContainerList, (const char *)f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, - f1ap_ue_context_setup_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); - } - /* optional */ - /* 6.3 measConfig */ - if(f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig!=NULL){ - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.measConfig, measConfig); - OCTET_STRING_fromBuf(measConfig, (const char*)f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig, - f1ap_ue_context_setup_req->cu_to_du_rrc_information->measConfig_length); - } - - /* optional */ - /* HandoverPreparationInformation */ - if (f1ap_ue_context_setup_req->cu_to_du_rrc_information->handoverPreparationInfo_length > 0) { - DevAssert(f1ap_ue_context_setup_req->cu_to_du_rrc_information->handoverPreparationInfo != NULL); - F1AP_ProtocolExtensionContainer_10696P60_t *p = calloc(1, sizeof(*p)); - ie6->value.choice.CUtoDURRCInformation.iE_Extensions = (struct F1AP_ProtocolExtensionContainer *)p; - asn1cSequenceAdd(p->list, F1AP_CUtoDURRCInformation_ExtIEs_t, ie_ext); - ie_ext->id = F1AP_ProtocolIE_ID_id_HandoverPreparationInformation; - ie_ext->criticality = F1AP_Criticality_ignore; - ie_ext->extensionValue.present = F1AP_CUtoDURRCInformation_ExtIEs__extensionValue_PR_HandoverPreparationInformation; - OCTET_STRING_fromBuf(&ie_ext->extensionValue.choice.HandoverPreparationInformation, - (const char *)f1ap_ue_context_setup_req->cu_to_du_rrc_information->handoverPreparationInfo, - f1ap_ue_context_setup_req->cu_to_du_rrc_information->handoverPreparationInfo_length); - } - } - - /* optional */ - if (0) { - /* c7. Candidate_SpCell_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie7); - ie7->id = F1AP_ProtocolIE_ID_id_Candidate_SpCell_List; // 90 - ie7->criticality = F1AP_Criticality_ignore; - ie7->value.present = F1AP_UEContextSetupRequestIEs__value_PR_Candidate_SpCell_List; - - for (int i = 0; i < 1; i++) { - asn1cSequenceAdd(ie7->value.choice.Candidate_SpCell_List.list, F1AP_Candidate_SpCell_ItemIEs_t, candidate_spCell_item_ies); - candidate_spCell_item_ies->id = F1AP_ProtocolIE_ID_id_Candidate_SpCell_Item; // 91 - candidate_spCell_item_ies->criticality = F1AP_Criticality_ignore; - candidate_spCell_item_ies->value.present = F1AP_Candidate_SpCell_ItemIEs__value_PR_Candidate_SpCell_Item; - /* 7.1 Candidate_SpCell_Item */ - F1AP_Candidate_SpCell_Item_t *candidate_spCell_item = &candidate_spCell_item_ies->value.choice.Candidate_SpCell_Item; - /* - candidate_SpCell_ID */ - // FixMe: first cell ??? - addnRCGI(candidate_spCell_item->candidate_SpCell_ID, f1ap_ue_context_setup_req); - /* TODO add correct mcc/mnc */ - } - } - - /* optional */ - /* c8. DRXCycle */ - if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie8); - ie8->id = F1AP_ProtocolIE_ID_id_DRXCycle; - ie8->criticality = F1AP_Criticality_ignore; - ie8->value.present = F1AP_UEContextSetupRequestIEs__value_PR_DRXCycle; - /* 8.1 longDRXCycleLength */ - ie8->value.choice.DRXCycle.longDRXCycleLength = F1AP_LongDRXCycleLength_ms10; // enum - - /* optional */ - /* 8.2 shortDRXCycleLength */ - if (0) { - asn1cCallocOne(ie6->value.choice.DRXCycle.shortDRXCycleLength, - F1AP_ShortDRXCycleLength_ms2); // enum - } - - /* optional */ - /* 8.3 shortDRXCycleTimer */ - if (0) { - asn1cCallocOne(ie8->value.choice.DRXCycle.shortDRXCycleTimer, - 123L); - } - } - - /* optional */ - /* c9. ResourceCoordinationTransferContainer */ - if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie9); - ie9->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer; - ie9->criticality = F1AP_Criticality_ignore; - ie9->value.present = F1AP_UEContextSetupRequestIEs__value_PR_ResourceCoordinationTransferContainer; - ie9->value.choice.ResourceCoordinationTransferContainer.buf = malloc(4); - ie9->value.choice.ResourceCoordinationTransferContainer.size = 4; - strncpy((char *)ie9->value.choice.ResourceCoordinationTransferContainer.buf, "123", 4); - OCTET_STRING_fromBuf(&ie9->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); - } - - /* optional */ - if (0) { - /* c10. SCell_ToBeSetup_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie10); - ie10->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_List; - ie10->criticality = F1AP_Criticality_ignore; - ie10->value.present = F1AP_UEContextSetupRequestIEs__value_PR_SCell_ToBeSetup_List; - - for (int i = 0; i < 1; i++) { - asn1cSequenceAdd(ie10->value.choice.SCell_ToBeSetup_List.list, F1AP_SCell_ToBeSetup_ItemIEs_t, scell_toBeSetup_item_ies); - scell_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_Item; // 53 - scell_toBeSetup_item_ies->criticality = F1AP_Criticality_ignore; - scell_toBeSetup_item_ies->value.present = F1AP_SCell_ToBeSetup_ItemIEs__value_PR_SCell_ToBeSetup_Item; - /* 10.1 SCell_ToBeSetup_Item */ - F1AP_SCell_ToBeSetup_Item_t *scell_toBeSetup_item = &scell_toBeSetup_item_ies->value.choice.SCell_ToBeSetup_Item; - /* 10.1.1 sCell_ID */ - addnRCGI(scell_toBeSetup_item->sCell_ID, f1ap_ue_context_setup_req); - /* TODO correct MCC/MNC */ - /* 10.1.2 sCellIndex */ - scell_toBeSetup_item->sCellIndex = 3; // issue here - - /* OPTIONAL */ - /* 10.1.3 sCellULConfigured*/ - if (0) { - asn1cCallocOne(scell_toBeSetup_item->sCellULConfigured, - F1AP_CellULConfigured_ul_and_sul); // enum - } - } - } - - /* mandatory */ - /* c11. SRBs_ToBeSetup_List */ - if(f1ap_ue_context_setup_req->srbs_to_be_setup_length > 0){ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie11); - ie11->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_List; - ie11->criticality = F1AP_Criticality_reject; // ? - ie11->value.present = F1AP_UEContextSetupRequestIEs__value_PR_SRBs_ToBeSetup_List; - - for (int i=0; isrbs_to_be_setup_length; i++) { - asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetup_List.list, F1AP_SRBs_ToBeSetup_ItemIEs_t, srbs_toBeSetup_item_ies); - srbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item; // 73 - srbs_toBeSetup_item_ies->criticality = F1AP_Criticality_reject; - srbs_toBeSetup_item_ies->value.present = F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item; - /* 11.1 SRBs_ToBeSetup_Item */ - F1AP_SRBs_ToBeSetup_Item_t *srbs_toBeSetup_item=&srbs_toBeSetup_item_ies->value.choice.SRBs_ToBeSetup_Item; - /* 11.1.1 sRBID */ - srbs_toBeSetup_item->sRBID = f1ap_ue_context_setup_req->srbs_to_be_setup[i].srb_id; - /* OPTIONAL */ - /* 11.1.2 duplicationIndication */ - asn1cCallocOne(srbs_toBeSetup_item->duplicationIndication, - F1AP_DuplicationIndication_true); // enum - } - } - - /* mandatory */ - /* c12. DRBs_ToBeSetup_List */ - if(f1ap_ue_context_setup_req->drbs_to_be_setup_length){ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie12); - ie12->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_List; - ie12->criticality = F1AP_Criticality_reject; - ie12->value.present = F1AP_UEContextSetupRequestIEs__value_PR_DRBs_ToBeSetup_List; - - for (int i = 0; i < f1ap_ue_context_setup_req->drbs_to_be_setup_length; i++) { - const f1ap_drb_to_be_setup_t *drb = &f1ap_ue_context_setup_req->drbs_to_be_setup[i]; - asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetup_List.list, F1AP_DRBs_ToBeSetup_ItemIEs_t, drbs_toBeSetup_item_ies); - drbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item; - drbs_toBeSetup_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeSetup_item_ies->value.present = F1AP_DRBs_ToBeSetup_ItemIEs__value_PR_DRBs_ToBeSetup_Item; - /* 12.1 DRBs_ToBeSetup_Item */ - F1AP_DRBs_ToBeSetup_Item_t *drbs_toBeSetup_item=&drbs_toBeSetup_item_ies->value.choice.DRBs_ToBeSetup_Item; - /* 12.1.1 dRBID */ - drbs_toBeSetup_item->dRBID = drb->drb_id; - /* 12.1.2 qoSInformation */ - int some_decide_qos = 0; // BK: Need Check - - if (some_decide_qos) { - drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; - /* 12.1.2.1 eUTRANQoS */ - asn1cCalloc(drbs_toBeSetup_item->qoSInformation.choice.eUTRANQoS, eUTRANQoS); - /* 12.1.2.1.1 qCI */ - eUTRANQoS->qCI = 254L; - /* 12.1.2.1.2 allocationAndRetentionPriority */ - { - /* 12.1.2.1.2.1 priorityLevel */ - eUTRANQoS->allocationAndRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum - /* 12.1.2.1.2.2 pre_emptionCapability */ - eUTRANQoS->allocationAndRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_may_trigger_pre_emption; // enum - /* 12.1.2.1.2.2 pre_emptionVulnerability */ - eUTRANQoS->allocationAndRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum - } - - /* OPTIONAL */ - /* 12.1.2.1.3 gbrQosInformation */ - if (0) { - eUTRANQoS->gbrQosInformation = (F1AP_GBR_QosInformation_t *)calloc(1, sizeof(F1AP_GBR_QosInformation_t)); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateDL, 1L); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_MaximumBitrateUL, 1L); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateDL, 1L); - asn_long2INTEGER(&eUTRANQoS->gbrQosInformation->e_RAB_GuaranteedBitrateUL, 1L); - } - } else { - /* 12.1.2 DRB_Information */ - const f1ap_drb_information_t *drb_info = &drb->drb_info; - drbs_toBeSetup_item->qoSInformation.present = F1AP_QoSInformation_PR_choice_extension; - F1AP_QoSInformation_ExtIEs_t *ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(*ie)); - ie->id = F1AP_ProtocolIE_ID_id_DRB_Information; - ie->criticality = F1AP_Criticality_reject; - ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information; - F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information; - drbs_toBeSetup_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie; - - /* 12.1.2.1 dRB_QoS */ - f1ap_write_drb_qos_param(&drb_info->drb_qos, &DRB_Information->dRB_QoS); - - /* 12.1.2.2 sNSSAI */ - f1ap_write_drb_nssai(&drb->nssai, &DRB_Information->sNSSAI); - - /* OPTIONAL */ - /* 12.1.2.3 notificationControl */ - if (0) { - asn1cCallocOne(DRB_Information->notificationControl, - F1AP_NotificationControl_active); // enum - } - - /* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy - f1ap_write_flows_mapped(drb_info->flows_mapped_to_drb, &DRB_Information->flows_Mapped_To_DRB_List, drb_info->flows_to_be_setup_length); - } // if some_decide_qos - - /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ - for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { - DevAssert(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid > 0); - /* 12.3.1 ULTunnels_ToBeSetup_Item */ - asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list, - F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); - uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc( uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, - gTPTunnel); - /* 12.3.1.1.1 transportLayerAddress */ - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].tl_address, - &gTPTunnel->transportLayerAddress); - /* 12.3.1.1.2 gTP_TEID */ - INT32_TO_OCTET_STRING(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid, - &gTPTunnel->gTP_TEID); - } - - /* 12.1.4 rLCMode */ - /* TODO use rlc_mode from f1ap_drb_to_be_setup */ - switch (f1ap_ue_context_setup_req->drbs_to_be_setup[i].rlc_mode) { - case F1AP_RLC_MODE_AM: - drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_am; - break; - case F1AP_RLC_MODE_UM_BIDIR: - drbs_toBeSetup_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; - break; - default: - AssertFatal(false, "modes other than AM/UM-Bidir not supported\n"); - break; - } - - /* OPTIONAL */ - /* 12.1.5 ULConfiguration */ - if (0) { - asn1cCalloc(drbs_toBeSetup_item->uLConfiguration, tmp); - tmp->uLUEConfiguration = F1AP_ULUEConfiguration_no_data; - } - - /* OPTIONAL */ - /* 12.1.6 duplicationActivation */ - if (0) { - asn1cCalloc(drbs_toBeSetup_item->duplicationActivation, tmp); - *tmp = F1AP_DuplicationActivation_active; // enum - } - } - } - - /* OPTIONAL */ - /* InactivityMonitoringRequest */ - if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie12); - ie12->id = F1AP_ProtocolIE_ID_id_InactivityMonitoringRequest; - ie12->criticality = F1AP_Criticality_reject; - ie12->value.present = F1AP_UEContextSetupRequestIEs__value_PR_InactivityMonitoringRequest; - ie12->value.choice.InactivityMonitoringRequest = F1AP_InactivityMonitoringRequest_true; // 0 - } - - /* OPTIONAL */ - /* RAT_FrequencyPriorityInformation */ - if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie13); - ie13->id = F1AP_ProtocolIE_ID_id_RAT_FrequencyPriorityInformation; - ie13->criticality = F1AP_Criticality_reject; - ie13->value.present = F1AP_UEContextSetupRequestIEs__value_PR_RAT_FrequencyPriorityInformation; - int endc = 1; // RK: Get this from somewhere ... - - if (endc) { - ie13->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_eNDC; - ie13->value.choice.RAT_FrequencyPriorityInformation.choice.eNDC = 11L; - } else { - ie13->value.choice.RAT_FrequencyPriorityInformation.present = F1AP_RAT_FrequencyPriorityInformation_PR_nGRAN; - ie13->value.choice.RAT_FrequencyPriorityInformation.choice.nGRAN = 11L; - } - } - - /* OPTIONAL */ - /* RRCContainer */ - if(f1ap_ue_context_setup_req->rrc_container_length > 0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie14); - ie14->id = F1AP_ProtocolIE_ID_id_RRCContainer; - ie14->criticality = F1AP_Criticality_ignore; - ie14->value.present = F1AP_UEContextSetupRequestIEs__value_PR_RRCContainer; - OCTET_STRING_fromBuf(&ie14->value.choice.RRCContainer, (const char *)f1ap_ue_context_setup_req->rrc_container, - f1ap_ue_context_setup_req->rrc_container_length); - } - - /* OPTIONAL */ - /* MaskedIMEISV */ - if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextSetupRequestIEs_t, ie15); - ie15->id = F1AP_ProtocolIE_ID_id_MaskedIMEISV; - ie15->criticality = F1AP_Criticality_reject; - ie15->value.present = F1AP_UEContextSetupRequestIEs__value_PR_MaskedIMEISV; - MaskedIMEISV_TO_BIT_STRING(12340000l, &ie15->value.choice.MaskedIMEISV); // size (64) - } - - /* encode */ - uint8_t *buffer=NULL; - uint32_t len=0; - - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { + uint8_t *buffer = NULL; + uint32_t len = 0; + if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { LOG_E(F1AP, "Failed to encode F1 UE CONTEXT SETUP REQUEST\n"); return -1; } + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); + #ifdef E2_AGENT - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[0], f1ap_ue_context_setup_req->gNB_CU_ue_id); + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[0], req->gNB_CU_ue_id); signal_ue_id(&ue_context_p->ue_context, F1_NETWORK_INTERFACE_TYPE, 0); #endif - // xer_fprint(stdout, &asn_DEF_F1AP_F1AP_PDU, (void *)pdu); - // asn_encode_to_new_buffer_result_t res = { NULL, {0, NULL, NULL} }; - // res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_F1AP_F1AP_PDU, pdu); - // buffer = res.buffer; - // len = res.result.encoded; - // if (res.result.encoded <= 0) { - // LOG_E(F1AP, "ASN1 message encoding failed (%s, %lu)!\n", res.result.failed_type->name, res.result.encoded); - // return -1; - // } - LOG_D(F1AP,"F1AP UEContextSetupRequest Encoded %u bits\n", len); - f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); return 0; } @@ -935,459 +389,19 @@ int CU_handle_UE_CONTEXT_RELEASE_COMPLETE(instance_t instance, sctp_assoc_t asso return 0; } -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) { - F1AP_F1AP_PDU_t pdu= {0}; - F1AP_UEContextModificationRequest_t *out; + F1AP_F1AP_PDU_t *pdu = encode_ue_context_mod_req(req); + 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_UEContextModification; - tmp->criticality = F1AP_Criticality_reject; - tmp->value.present = F1AP_InitiatingMessage__value_PR_UEContextModificationRequest; - out = &tmp->value.choice.UEContextModificationRequest; - /* mandatory */ - /* c1. GNB_CU_UE_F1AP_ID */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie1); - ie1->id = F1AP_ProtocolIE_ID_id_gNB_CU_UE_F1AP_ID; - ie1->criticality = F1AP_Criticality_reject; - ie1->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_CU_UE_F1AP_ID; - ie1->value.choice.GNB_CU_UE_F1AP_ID = f1ap_ue_context_modification_req->gNB_CU_ue_id; - /* mandatory */ - /* c2. GNB_DU_UE_F1AP_ID */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie2); - ie2->id = F1AP_ProtocolIE_ID_id_gNB_DU_UE_F1AP_ID; - ie2->criticality = F1AP_Criticality_reject; - ie2->value.present = F1AP_UEContextModificationRequestIEs__value_PR_GNB_DU_UE_F1AP_ID; - ie2->value.choice.GNB_DU_UE_F1AP_ID = f1ap_ue_context_modification_req->gNB_DU_ue_id; - - /* optional */ - /* c3. NRCGI */ - if (true) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_SpCell_ID; - ie3->criticality = F1AP_Criticality_ignore; - ie3->value.present = F1AP_UEContextModificationRequestIEs__value_PR_NRCGI; - /* - nRCGI */ - - f1ap_served_cell_info_t nrcgi = { - .plmn = f1ap_ue_context_modification_req->plmn, - .nr_cellid = f1ap_ue_context_modification_req->nr_cellid, - }; - addnRCGI(ie3->value.choice.NRCGI, &nrcgi); - } - - /* optional */ - /* c4. ServCellIndex */ - if(0){ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie4); - ie4->id = F1AP_ProtocolIE_ID_id_ServCellIndex; - ie4->criticality = F1AP_Criticality_reject; - ie4->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ServCellIndex; - ie4->value.choice.ServCellIndex = 5L; - } - - /* optional */ - /* c5. DRXCycle */ - if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie5); - ie5->id = F1AP_ProtocolIE_ID_id_DRXCycle; - ie5->criticality = F1AP_Criticality_ignore; - ie5->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRXCycle; - ie5->value.choice.DRXCycle.longDRXCycleLength = F1AP_LongDRXCycleLength_ms10; // enum - - if (0) { - asn1cCallocOne(ie5->value.choice.DRXCycle.shortDRXCycleLength, - F1AP_ShortDRXCycleLength_ms2); // enum - } - - if (0) { - asn1cCallocOne(ie5->value.choice.DRXCycle.shortDRXCycleTimer, 123L); - } - } - - /* optional */ - /* c6. CUtoDURRCInformation */ - if (f1ap_ue_context_modification_req->cu_to_du_rrc_information!=NULL) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie6); - ie6->id = F1AP_ProtocolIE_ID_id_CUtoDURRCInformation; - ie6->criticality = F1AP_Criticality_reject; - ie6->value.present = F1AP_UEContextModificationRequestIEs__value_PR_CUtoDURRCInformation; - /* 6.1 cG_ConfigInfo */ - if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo!=NULL){ - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.cG_ConfigInfo, cG_ConfigInfo); - OCTET_STRING_fromBuf(cG_ConfigInfo, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo, - f1ap_ue_context_modification_req->cu_to_du_rrc_information->cG_ConfigInfo_length); - } - /* optional */ - /* 6.2 uE_CapabilityRAT_ContainerList */ - if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList!=NULL){ - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.uE_CapabilityRAT_ContainerList, uE_CapabilityRAT_ContainerList ); - OCTET_STRING_fromBuf(uE_CapabilityRAT_ContainerList, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, - f1ap_ue_context_modification_req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length) ; - } - /* optional */ - /* 6.3 measConfig */ - if(f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig!=NULL){ - asn1cCalloc(ie6->value.choice.CUtoDURRCInformation.measConfig, measConfig); - OCTET_STRING_fromBuf(measConfig, (const char *)f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig, - f1ap_ue_context_modification_req->cu_to_du_rrc_information->measConfig_length); - } - } - - /* optional */ - /* c7. TransmissionActionIndicator */ - if (f1ap_ue_context_modification_req->transm_action_ind != NULL) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie7); - ie7->id = F1AP_ProtocolIE_ID_id_TransmissionActionIndicator; - ie7->criticality = F1AP_Criticality_ignore; - ie7->value.present = F1AP_UEContextModificationRequestIEs__value_PR_TransmissionActionIndicator; - ie7->value.choice.TransmissionActionIndicator = *f1ap_ue_context_modification_req->transm_action_ind; - // 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"); - } - - /* optional */ - /* c8. ResourceCoordinationTransferContainer */ - if (0) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie8); - ie8->id = F1AP_ProtocolIE_ID_id_ResourceCoordinationTransferContainer; - ie8->criticality = F1AP_Criticality_ignore; - ie8->value.present = F1AP_UEContextModificationRequestIEs__value_PR_ResourceCoordinationTransferContainer; - OCTET_STRING_fromBuf(&ie8->value.choice.ResourceCoordinationTransferContainer, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); - } - - /* optional */ - /* c7. RRCRconfigurationCompleteIndicator */ - if (f1ap_ue_context_modification_req->ReconfigComplOutcome == RRCreconf_success) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie71); - ie71->id = F1AP_ProtocolIE_ID_id_RRCReconfigurationCompleteIndicator; - ie71->criticality = F1AP_Criticality_ignore; - ie71->value.present = F1AP_UEContextModificationRequestIEs__value_PR_RRCReconfigurationCompleteIndicator; - ie71->value.choice.RRCReconfigurationCompleteIndicator = F1AP_RRCReconfigurationCompleteIndicator_true; - } - - /* optional */ - /* c8. RRCContainer */ - if (f1ap_ue_context_modification_req->rrc_container != NULL) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie81); - ie81->id = F1AP_ProtocolIE_ID_id_RRCContainer; - ie81->criticality = F1AP_Criticality_ignore; - ie81->value.present = F1AP_UEContextModificationRequestIEs__value_PR_RRCContainer; - OCTET_STRING_fromBuf(&ie81->value.choice.RRCContainer, (const char*)f1ap_ue_context_modification_req->rrc_container, - f1ap_ue_context_modification_req->rrc_container_length); - } - - /* optional */ - /* c9. SCell_ToBeSetupMod_List */ - if(0){ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie9); - ie9->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_List; - ie9->criticality = F1AP_Criticality_ignore; - ie9->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeSetupMod_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie9->value.choice.SCell_ToBeSetupMod_List.list, - F1AP_SCell_ToBeSetupMod_ItemIEs_t, scell_toBeSetupMod_item_ies); - scell_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeSetupMod_Item; - scell_toBeSetupMod_item_ies->criticality = F1AP_Criticality_ignore; - scell_toBeSetupMod_item_ies->value.present = F1AP_SCell_ToBeSetupMod_ItemIEs__value_PR_SCell_ToBeSetupMod_Item; - /* 8.1 SCell_ToBeSetup_Item */ - F1AP_SCell_ToBeSetupMod_Item_t *scell_toBeSetupMod_item= - &scell_toBeSetupMod_item_ies->value.choice.SCell_ToBeSetupMod_Item; - // /* - sCell_ID */ - f1ap_served_cell_info_t hardCoded = {0}; - addnRCGI(scell_toBeSetupMod_item->sCell_ID, &hardCoded); - /* sCellIndex */ - scell_toBeSetupMod_item->sCellIndex = 6; // issue here - } - } - - /* optional */ - /* c10. SCell_ToBeRemoved_List */ - if(0){ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie10); - ie10->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_List; - ie10->criticality = F1AP_Criticality_ignore; - ie10->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SCell_ToBeRemoved_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie10->value.choice.SCell_ToBeRemoved_List.list, - F1AP_SCell_ToBeRemoved_ItemIEs_t, scell_toBeRemoved_item_ies); - scell_toBeRemoved_item_ies = (F1AP_SCell_ToBeRemoved_ItemIEs_t *)calloc(1, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); - //memset((void *)&scell_toBeRemoved_item_ies, 0, sizeof(F1AP_SCell_ToBeRemoved_ItemIEs_t)); - scell_toBeRemoved_item_ies->id = F1AP_ProtocolIE_ID_id_SCell_ToBeRemoved_Item; - scell_toBeRemoved_item_ies->criticality = F1AP_Criticality_ignore; - scell_toBeRemoved_item_ies->value.present = F1AP_SCell_ToBeRemoved_ItemIEs__value_PR_SCell_ToBeRemoved_Item; - /* 10.1 SCell_ToBeRemoved_Item */ - F1AP_SCell_ToBeRemoved_Item_t *scell_toBeRemoved_item= - &scell_toBeRemoved_item_ies->value.choice.SCell_ToBeRemoved_Item; - /* - sCell_ID */ - f1ap_served_cell_info_t hardCoded = {0}; - addnRCGI(scell_toBeRemoved_item->sCell_ID, &hardCoded); - } - } - - /* mandatory */ - /* c11. SRBs_ToBeSetupMod_List */ - if(f1ap_ue_context_modification_req->srbs_to_be_setup_length > 0){ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie11); - ie11->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_List; - ie11->criticality = F1AP_Criticality_reject; - ie11->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeSetupMod_List; - - for (int i=0; isrbs_to_be_setup_length; i++) { - // - asn1cSequenceAdd(ie11->value.choice.SRBs_ToBeSetupMod_List, F1AP_SRBs_ToBeSetupMod_ItemIEs_t, srbs_toBeSetupMod_item_ies); - srbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeSetupMod_Item; // 73 - srbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; - srbs_toBeSetupMod_item_ies->value.present = F1AP_SRBs_ToBeSetupMod_ItemIEs__value_PR_SRBs_ToBeSetupMod_Item; - /* 11.1 SRBs_ToBeSetup_Item */ - F1AP_SRBs_ToBeSetupMod_Item_t *srbs_toBeSetupMod_item=&srbs_toBeSetupMod_item_ies->value.choice.SRBs_ToBeSetupMod_Item; - /* 11.1.1 sRBID */ - srbs_toBeSetupMod_item->sRBID = f1ap_ue_context_modification_req->srbs_to_be_setup[i].srb_id; - /* OPTIONAL */ - /* 11.1.2 duplicationIndication */ - asn1cCallocOne(srbs_toBeSetupMod_item->duplicationIndication, - F1AP_DuplicationIndication_true); // enum - } - } - - /* mandatory */ - /* c12. DRBs_ToBeSetupMod_List */ - if(f1ap_ue_context_modification_req->drbs_to_be_setup_length){ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie12); - ie12->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_List; - ie12->criticality = F1AP_Criticality_reject; - ie12->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List; - - for (int i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_setup_length; i++) { - const f1ap_drb_to_be_setup_t *drb = &f1ap_ue_context_modification_req->drbs_to_be_setup[i]; - asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetupMod_List.list, - F1AP_DRBs_ToBeSetupMod_ItemIEs_t, drbs_toBeSetupMod_item_ies); - drbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item; - drbs_toBeSetupMod_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeSetupMod_item_ies->value.present = F1AP_DRBs_ToBeSetupMod_ItemIEs__value_PR_DRBs_ToBeSetupMod_Item; - /* 12.1 DRBs_ToBeSetupMod_Item */ - F1AP_DRBs_ToBeSetupMod_Item_t *drbs_toBeSetupMod_item= - &drbs_toBeSetupMod_item_ies->value.choice.DRBs_ToBeSetupMod_Item; - /* dRBID */ - drbs_toBeSetupMod_item->dRBID = drb->drb_id; - /* qoSInformation */ - - if(f1ap_ue_context_modification_req->QoS_information_type == EUTRAN_QoS){ - drbs_toBeSetupMod_item->qoSInformation.present = F1AP_QoSInformation_PR_eUTRANQoS; - drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); - drbs_toBeSetupMod_item->qoSInformation.choice.eUTRANQoS->qCI = 253L; - /* uLUPTNLInformation_ToBeSetup_List */ - int maxnoofULTunnels = 1; // 2; - - for (int j=0; juLUPTNLInformation_ToBeSetup_List.list, - F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); - uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, - gTPTunnel); - /* transportLayerAddress */ - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); - /* gTP_TEID */ - OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "4567", - strlen("4567")); - } - - /* rLCMode */ - drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; // enum - - /* OPTIONAL */ - /* ULConfiguration */ - if (0) { - drbs_toBeSetupMod_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); - } - } //QoS information - - else{ - /* 12.1.2 DRB_Information */ - f1ap_drb_information_t *drb_info_in = &f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_info; - drbs_toBeSetupMod_item->qoSInformation.present = F1AP_QoSInformation_PR_choice_extension; - F1AP_QoSInformation_ExtIEs_t *ie = (F1AP_QoSInformation_ExtIEs_t *)calloc(1, sizeof(*ie)); - ie->id = F1AP_ProtocolIE_ID_id_DRB_Information; - ie->criticality = F1AP_Criticality_reject; - ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information; - F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information; - drbs_toBeSetupMod_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie; - - /* 12.1.2.1 dRB_QoS */ - f1ap_write_drb_qos_param(&drb_info_in->drb_qos, &DRB_Information->dRB_QoS); - - /* 12.1.2.2 sNSSAI */ - f1ap_write_drb_nssai(&drb->nssai, &DRB_Information->sNSSAI); - - /* OPTIONAL */ - /* 12.1.2.3 notificationControl */ - if (0) { - asn1cCallocOne(DRB_Information->notificationControl, - F1AP_NotificationControl_active); // enum - } - - /* 12.1.2.4 flows_Mapped_To_DRB_List */ - f1ap_write_flows_mapped(drb_info_in->flows_mapped_to_drb, &DRB_Information->flows_Mapped_To_DRB_List, drb_info_in->flows_to_be_setup_length); - - } //QoS information - - /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ - for (int j = 0; j < f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { - /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context modification response from the DU */ - asn1cSequenceAdd(drbs_toBeSetupMod_item->uLUPTNLInformation_ToBeSetup_List.list, - F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); - uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc( uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, - gTPTunnel); - /* 12.3.1.1.1 transportLayerAddress */ - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].tl_address, - &gTPTunnel->transportLayerAddress); - /* 12.3.1.1.2 gTP_TEID */ - INT32_TO_OCTET_STRING(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid, - &gTPTunnel->gTP_TEID); - } - /* 12.1.4 rLCMode */ - /* TODO use rlc_mode from f1ap_drb_to_be_setup */ - switch (f1ap_ue_context_modification_req->drbs_to_be_setup[i].rlc_mode) { - case F1AP_RLC_MODE_AM: - drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_am; - break; - case F1AP_RLC_MODE_UM_BIDIR: - drbs_toBeSetupMod_item->rLCMode = F1AP_RLCMode_rlc_um_bidirectional; - break; - default: - AssertFatal(false, "modes other than AM/UM-Bidir not supported\n"); - break; - } - - /* OPTIONAL */ - /* 12.1.5 ULConfiguration */ - if (0) { - asn1cCalloc(drbs_toBeSetupMod_item->uLConfiguration, tmp); - tmp->uLUEConfiguration = F1AP_ULUEConfiguration_no_data; - } - - /* OPTIONAL */ - /* 12.1.6 duplicationActivation */ - if (0) { - asn1cCalloc(drbs_toBeSetupMod_item->duplicationActivation, tmp); - *tmp = F1AP_DuplicationActivation_active; // enum - } - } - } - - /* optional */ - if(0){ - /* c13. DRBs_ToBeModified_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie13); - ie13->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_List; - ie13->criticality = F1AP_Criticality_reject; - ie13->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeModified_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd( ie13->value.choice.DRBs_ToBeModified_List.list, - F1AP_DRBs_ToBeModified_ItemIEs_t, drbs_toBeModified_item_ies); - drbs_toBeModified_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeModified_Item; - drbs_toBeModified_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeModified_item_ies->value.present = F1AP_DRBs_ToBeModified_ItemIEs__value_PR_DRBs_ToBeModified_Item; - /* 13.1 SRBs_ToBeModified_Item */ - F1AP_DRBs_ToBeModified_Item_t *drbs_toBeModified_item= - &drbs_toBeModified_item_ies->value.choice.DRBs_ToBeModified_Item; - /* dRBID */ - drbs_toBeModified_item->dRBID = 30L; - /* qoSInformation */ - asn1cCalloc(drbs_toBeModified_item->qoSInformation, tmp); - tmp->present = F1AP_QoSInformation_PR_eUTRANQoS; - tmp->choice.eUTRANQoS = (F1AP_EUTRANQoS_t *)calloc(1, sizeof(F1AP_EUTRANQoS_t)); - tmp->choice.eUTRANQoS->qCI = 254L; - /* ULTunnels_ToBeModified_List */ - int maxnoofULTunnels = 1; // 2; - - for (int j=0; juLUPTNLInformation_ToBeSetup_List.list, - F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item); - uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.present = F1AP_UPTransportLayerInformation_PR_gTPTunnel; - asn1cCalloc(uLUPTNLInformation_ToBeSetup_Item->uLUPTNLInformation.choice.gTPTunnel, - gTPTunnel); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(1234, &gTPTunnel->transportLayerAddress); - OCTET_STRING_fromBuf(&gTPTunnel->gTP_TEID, "1204", - strlen("1204")); - } - - /* OPTIONAL */ - /* ULConfiguration */ - if (0) { - drbs_toBeModified_item->uLConfiguration = (F1AP_ULConfiguration_t *)calloc(1, sizeof(F1AP_ULConfiguration_t)); - } - } - } - - /* optional */ - if(0){ - /* c14. SRBs_ToBeReleased_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie14); - ie14->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_List; - ie14->criticality = F1AP_Criticality_reject; - ie14->value.present = F1AP_UEContextModificationRequestIEs__value_PR_SRBs_ToBeReleased_List; - - for (int i=0; i<1; i++) { - // - asn1cSequenceAdd(ie14->value.choice.SRBs_ToBeReleased_List.list, - F1AP_SRBs_ToBeReleased_ItemIEs_t, srbs_toBeReleased_item_ies); - srbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_SRBs_ToBeReleased_Item; - srbs_toBeReleased_item_ies->criticality = F1AP_Criticality_ignore; - srbs_toBeReleased_item_ies->value.present = F1AP_SRBs_ToBeReleased_ItemIEs__value_PR_SRBs_ToBeReleased_Item; - /* 9.1 SRBs_ToBeReleased_Item */ - F1AP_SRBs_ToBeReleased_Item_t *srbs_toBeReleased_item= - &srbs_toBeReleased_item_ies->value.choice.SRBs_ToBeReleased_Item; - /* - sRBID */ - srbs_toBeReleased_item->sRBID = 2L; - } - } - - /* optional */ - if (f1ap_ue_context_modification_req->drbs_to_be_released_length > 0) { - /* c15. DRBs_ToBeReleased_List */ - asn1cSequenceAdd(out->protocolIEs.list, F1AP_UEContextModificationRequestIEs_t, ie15); - ie15->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_List; - ie15->criticality = F1AP_Criticality_reject; - ie15->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeReleased_List; - - for (int i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_released_length; i++) { - // - asn1cSequenceAdd(ie15->value.choice.DRBs_ToBeReleased_List.list, - F1AP_DRBs_ToBeReleased_ItemIEs_t, drbs_toBeReleased_item_ies); - drbs_toBeReleased_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item; - drbs_toBeReleased_item_ies->criticality = F1AP_Criticality_reject; - drbs_toBeReleased_item_ies->value.present = F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item; - /* 14.1 SRBs_ToBeReleased_Item */ - F1AP_DRBs_ToBeReleased_Item_t *drbs_toBeReleased_item= - &drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item; - /* dRBID */ - drbs_toBeReleased_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id; - } - } - - /* encode */ - if (f1ap_encode_pdu(&pdu, &buffer, &len) < 0) { - LOG_E(F1AP, "Failed to encode F1 UE CONTEXT_MODIFICATION REQUEST\n"); + if (f1ap_encode_pdu(pdu, &buffer, &len) < 0) { + LOG_E(F1AP, "Failed to encode F1 UE Context Modification Request\n"); return -1; } + f1ap_itti_send_sctp_data_req(assoc_id, buffer, len); + ASN_STRUCT_FREE(asn_DEF_F1AP_F1AP_PDU, pdu); return 0; } diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.h b/openair2/F1AP/f1ap_cu_ue_context_management.h index 05e67930b3..ed76189c19 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.h +++ b/openair2/F1AP/f1ap_cu_ue_context_management.h @@ -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); diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index c231561eec..cd76933d44 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -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 diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index cd9b2865c9..13c9e92ec5 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -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; } diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index ed03ba76a5..5f2e9b9dfa 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -33,6 +33,7 @@ #include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h" #include "lib/f1ap_rrc_message_transfer.h" #include "lib/f1ap_interface_management.h" +#include "lib/f1ap_ue_context.h" #include "executables/softmodem-common.h" @@ -222,18 +223,18 @@ void gnb_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_upd LOG_I(MAC, "received gNB-DU configuration update acknowledge\n"); } -static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_setup_t *srb, +static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_setup_t *srb, const nr_rlc_configuration_t *rlc_config) { - long priority = srb->srb_id == 2 ? 3 : 1; // see 38.331 sec 9.2.1 + long priority = srb->id == 2 ? 3 : 1; // see 38.331 sec 9.2.1 e_NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration bucket = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5; - return get_SRB_RLC_BearerConfig(get_lcid_from_srbid(srb->srb_id), priority, bucket, rlc_config); + return get_SRB_RLC_BearerConfig(get_lcid_from_srbid(srb->id), priority, bucket, rlc_config); } static int handle_ue_context_srbs_setup(NR_UE_info_t *UE, int srbs_len, - const f1ap_srb_to_be_setup_t *req_srbs, + const f1ap_srb_to_setup_t *req_srbs, f1ap_srb_to_be_setup_t **resp_srbs, NR_CellGroupConfig_t *cellGroupConfig, const nr_rlc_configuration_t *rlc_config) @@ -243,15 +244,15 @@ static int handle_ue_context_srbs_setup(NR_UE_info_t *UE, *resp_srbs = calloc(srbs_len, sizeof(**resp_srbs)); AssertFatal(*resp_srbs != NULL, "out of memory\n"); for (int i = 0; i < srbs_len; i++) { - const f1ap_srb_to_be_setup_t *srb = &req_srbs[i]; + const f1ap_srb_to_setup_t *srb = &req_srbs[i]; NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_srb(srb, rlc_config); - nr_rlc_add_srb(UE->rnti, srb->srb_id, rlc_BearerConfig); + nr_rlc_add_srb(UE->rnti, srb->id, rlc_BearerConfig); int priority = rlc_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority; nr_lc_config_t c = {.lcid = rlc_BearerConfig->logicalChannelIdentity, .priority = priority}; nr_mac_add_lcid(&UE->UE_sched_ctrl, &c); - (*resp_srbs)[i].srb_id = srb->srb_id; + (*resp_srbs)[i].srb_id = srb->id; (*resp_srbs)[i].lcid = c.lcid; if (rlc_BearerConfig->logicalChannelIdentity == 1) { @@ -268,12 +269,12 @@ static int handle_ue_context_srbs_setup(NR_UE_info_t *UE, return srbs_len; } -static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_setup_t *drb, +static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_setup_t *drb, const nr_rlc_configuration_t *rlc_config) { const NR_RLC_Config_PR rlc_conf = drb->rlc_mode == F1AP_RLC_MODE_AM ? NR_RLC_Config_PR_am : NR_RLC_Config_PR_um_Bi_Directional; long priority = 13; // hardcoded for the moment - return get_DRB_RLC_BearerConfig(get_lcid_from_drbid(drb->drb_id), drb->drb_id, rlc_conf, priority, rlc_config); + return get_DRB_RLC_BearerConfig(get_lcid_from_drbid(drb->id), drb->id, rlc_conf, priority, rlc_config); } static int get_non_dynamic_priority(int fiveqi) @@ -285,20 +286,20 @@ static int get_non_dynamic_priority(int fiveqi) return 0; } -static NR_QoS_config_t get_qos_config(const f1ap_qos_characteristics_t *qos_char) +static NR_QoS_config_t get_qos_config(const f1ap_qos_flow_param_t *qos) { NR_QoS_config_t qos_c = {0}; - switch (qos_char->qos_type) { + switch (qos->qos_type) { case DYNAMIC: - qos_c.priority = qos_char->dynamic.qos_priority_level; - qos_c.fiveQI = qos_char->dynamic.fiveqi > 0 ? qos_char->dynamic.fiveqi : 0; + qos_c.priority = qos->dyn.prio; + qos_c.fiveQI = 0; // does not exist for non-dynamic break; case NON_DYNAMIC: - qos_c.fiveQI = qos_char->non_dynamic.fiveqi; - qos_c.priority = get_non_dynamic_priority(qos_char->non_dynamic.fiveqi); + qos_c.fiveQI = qos->nondyn.fiveQI; + qos_c.priority = get_non_dynamic_priority(qos_c.fiveQI); break; default: - AssertFatal(false, "illegal QoS type %d\n", qos_char->qos_type); + AssertFatal(false, "illegal QoS type %d\n", qos->qos_type); break; } return qos_c; @@ -306,7 +307,7 @@ static NR_QoS_config_t get_qos_config(const f1ap_qos_characteristics_t *qos_char static int handle_ue_context_drbs_setup(NR_UE_info_t *UE, int drbs_len, - const f1ap_drb_to_be_setup_t *req_drbs, + const f1ap_drb_to_setup_t *req_drbs, f1ap_drb_to_be_setup_t **resp_drbs, NR_CellGroupConfig_t *cellGroupConfig, const nr_rlc_configuration_t *rlc_config) @@ -319,32 +320,34 @@ static int handle_ue_context_drbs_setup(NR_UE_info_t *UE, *resp_drbs = calloc(drbs_len, sizeof(**resp_drbs)); AssertFatal(*resp_drbs != NULL, "out of memory\n"); for (int i = 0; i < drbs_len; i++) { - const f1ap_drb_to_be_setup_t *drb = &req_drbs[i]; + const f1ap_drb_to_setup_t *drb = &req_drbs[i]; + AssertFatal(drb->qos_choice == F1AP_QOS_CHOICE_NR, "only NR QoS supported\n"); f1ap_drb_to_be_setup_t *resp_drb = &(*resp_drbs)[i]; NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb, rlc_config); - nr_rlc_add_drb(UE->rnti, drb->drb_id, rlc_BearerConfig); + nr_rlc_add_drb(UE->rnti, drb->id, rlc_BearerConfig); - nr_lc_config_t c = {.lcid = rlc_BearerConfig->logicalChannelIdentity, .nssai = drb->nssai}; + nr_lc_config_t c = {.lcid = rlc_BearerConfig->logicalChannelIdentity, .nssai = drb->nr.nssai}; int prio = 100; - for (int q = 0; q < drb->drb_info.flows_to_be_setup_length; ++q) { - c.qos_config[q] = get_qos_config(&drb->drb_info.flows_mapped_to_drb[q].qos_params.qos_characteristics); + for (int q = 0; q < drb->nr.flows_len; ++q) { + c.qos_config[q] = get_qos_config(&drb->nr.flows[q].param); prio = min(prio, c.qos_config[q].priority); } c.priority = prio; nr_mac_add_lcid(&UE->UE_sched_ctrl, &c); - *resp_drb = *drb; + resp_drb->drb_id = drb->id; + // TODO lcid // just put same number of tunnels in DL as in UL - DevAssert(drb->up_ul_tnl_length == 1); - resp_drb->up_dl_tnl_length = drb->up_ul_tnl_length; + DevAssert(drb->up_ul_tnl_len == 1); + resp_drb->up_dl_tnl_length = drb->up_ul_tnl_len; if (f1inst >= 0) { // we actually use F1-U int qfi = -1; // don't put PDU session marker in GTP gtpv1u_gnb_create_tunnel_resp_t resp_f1 = {0}; int ret = drb_gtpu_create(f1inst, UE->rnti, - drb->drb_id, - drb->drb_id, + drb->id, + drb->id, qfi, drb->up_ul_tnl[0].tl_address, drb->up_ul_tnl[0].teid, @@ -366,7 +369,7 @@ static int handle_ue_context_drbs_setup(NR_UE_info_t *UE, static int handle_ue_context_drbs_release(NR_UE_info_t *UE, int drbs_len, - const f1ap_drb_to_be_released_t *req_drbs, + const f1ap_drb_to_release_t *req_drbs, NR_CellGroupConfig_t *cellGroupConfig) { DevAssert(req_drbs != NULL && cellGroupConfig != NULL); @@ -378,9 +381,9 @@ static int handle_ue_context_drbs_release(NR_UE_info_t *UE, /* Note: the actual GTP tunnels are already removed in the F1AP message * decoding */ for (int i = 0; i < drbs_len; i++) { - const f1ap_drb_to_be_released_t *drb = &req_drbs[i]; + const f1ap_drb_to_release_t *drb = &req_drbs[i]; - long lcid = get_lcid_from_drbid(drb->rb_id); + long lcid = get_lcid_from_drbid(drb->id); int idx = 0; while (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) { const NR_RLC_BearerConfig_t *bc = cellGroupConfig->rlc_BearerToAddModList->list.array[idx]; @@ -392,7 +395,7 @@ static int handle_ue_context_drbs_release(NR_UE_info_t *UE, nr_mac_remove_lcid(&UE->UE_sched_ctrl, lcid); nr_rlc_release_entity(UE->rnti, lcid); if (f1inst >= 0) - newGtpuDeleteOneTunnel(f1inst, UE->rnti, drb->rb_id); + newGtpuDeleteOneTunnel(f1inst, UE->rnti, drb->id); asn_sequence_del(&cellGroupConfig->rlc_BearerToAddModList->list, idx, 1); long *plcid = malloc(sizeof(*plcid)); AssertFatal(plcid, "out of memory\n"); @@ -600,34 +603,30 @@ static NR_UE_info_t *create_new_UE(gNB_MAC_INST *mac, uint32_t cu_id, const NR_C return UE; } -void ue_context_setup_request(const f1ap_ue_context_setup_t *req) +void ue_context_setup_request(const f1ap_ue_context_setup_req_t *req) { const bool is_SA = IS_SA_MODE(get_softmodem_params()); gNB_MAC_INST *mac = RC.nrmac[0]; - /* response has same type as request... */ + + /* TODO: update response */ f1ap_ue_context_setup_t resp = { .gNB_CU_ue_id = req->gNB_CU_ue_id, - .gNB_DU_ue_id = req->gNB_DU_ue_id, }; - /* gNB-DU UE ID is optional. As of now, the F1AP module fills -1 (on uint, so - * 0xffffffff), but the DU uses the RNTI, so check if it's a legal RNTI in - * which case we consider; if not, assume no DU UE ID given */ - bool ue_id_provided = resp.gNB_DU_ue_id > 0 && resp.gNB_DU_ue_id < 0xffff; + bool ue_id_provided = req->gNB_DU_ue_id != NULL; - NR_UE_NR_Capability_t *ue_cap = NULL; + const f1ap_cu_to_du_rrc_info_t *cu2du = &req->cu_to_du_rrc_info; NR_CG_ConfigInfo_t *cg_configinfo = NULL; - if (req->cu_to_du_rrc_information != NULL) { - const cu_to_du_rrc_information_t *cu2du = req->cu_to_du_rrc_information; - if (cu2du->cG_ConfigInfo != NULL) - cg_configinfo = get_cg_config_info(cu2du->cG_ConfigInfo, cu2du->cG_ConfigInfo_length); - if (cu2du->handoverPreparationInfo != NULL) { - ue_cap = get_ue_nr_cap_from_ho_prep_info(cu2du->handoverPreparationInfo, cu2du->handoverPreparationInfo_length); - } else if (cu2du->uE_CapabilityRAT_ContainerList != NULL) { - ue_cap = get_ue_nr_cap(req->gNB_DU_ue_id, cu2du->uE_CapabilityRAT_ContainerList, cu2du->uE_CapabilityRAT_ContainerList_length); - } - AssertFatal(cu2du->measConfig == NULL, "MeasConfig not handled\n"); + if (cu2du->cg_configinfo != NULL) + cg_configinfo = get_cg_config_info(cu2du->cg_configinfo->buf, cu2du->cg_configinfo->len); + NR_UE_NR_Capability_t *ue_cap = NULL; + if (cu2du->ho_prep_info != NULL) { + ue_cap = get_ue_nr_cap_from_ho_prep_info(cu2du->ho_prep_info->buf, cu2du->ho_prep_info->len); + } else if (cu2du->ue_cap != NULL) { + ue_cap = get_ue_nr_cap(*req->gNB_DU_ue_id, cu2du->ue_cap->buf, cu2du->ue_cap->len); } + AssertFatal(cu2du->meas_config == NULL, "MeasConfig not handled\n"); + /* 38.473: "For DC operation, the CG-ConfigInfo IE shall be included in the CU * to DU RRC Information IE at the gNB acting as secondary node" As of now, * we only handle NSA => we check we have CG-ConfigInfo if not SA or have SA @@ -643,25 +642,26 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) resp.crnti = &UE->rnti; } else { DevAssert(is_SA); - UE = find_nr_UE(&mac->UE_info, req->gNB_DU_ue_id); + UE = find_nr_UE(&mac->UE_info, *req->gNB_DU_ue_id); } AssertFatal(UE, "no UE found or could not be created, but UE Context Setup Failed not implemented\n"); + resp.gNB_DU_ue_id = UE->rnti; NR_CellGroupConfig_t *new_CellGroup = clone_CellGroupConfig(UE->CellGroup); - if (req->srbs_to_be_setup_length > 0) { + if (req->srbs_len > 0) { resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(UE, - req->srbs_to_be_setup_length, - req->srbs_to_be_setup, + req->srbs_len, + req->srbs, &resp.srbs_to_be_setup, new_CellGroup, &mac->rlc_config); } - if (req->drbs_to_be_setup_length > 0) { + if (req->drbs_len > 0) { resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(UE, - req->drbs_to_be_setup_length, - req->drbs_to_be_setup, + req->drbs_len, + req->drbs, &resp.drbs_to_be_setup, new_CellGroup, &mac->rlc_config); @@ -669,7 +669,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) if (req->rrc_container != NULL) { logical_chan_id_t id = 1; - nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, id, req->rrc_container, req->rrc_container_length); + nr_rlc_srb_recv_sdu(UE->rnti, id, req->rrc_container->buf, req->rrc_container->len); } NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; @@ -722,7 +722,7 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) free(resp.du_to_cu_rrc_information); } -void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) +void ue_context_modification_request(const f1ap_ue_context_mod_req_t *req) { gNB_MAC_INST *mac = RC.nrmac[0]; f1ap_ue_context_modif_resp_t resp = { @@ -731,12 +731,13 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) }; NR_UE_NR_Capability_t *ue_cap = NULL; - if (req->cu_to_du_rrc_information != NULL) { - AssertFatal(req->cu_to_du_rrc_information->cG_ConfigInfo == NULL, "CG-ConfigInfo not handled\n"); - ue_cap = get_ue_nr_cap(req->gNB_DU_ue_id, - req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList, - req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList_length); - AssertFatal(req->cu_to_du_rrc_information->measConfig == NULL, "MeasConfig not handled\n"); + if (req->cu_to_du_rrc_info != NULL) { + AssertFatal(req->cu_to_du_rrc_info->cg_configinfo == NULL, "CG-ConfigInfo not handled\n"); + if (req->cu_to_du_rrc_info->ue_cap) { + byte_array_t *b = req->cu_to_du_rrc_info->ue_cap; + ue_cap = get_ue_nr_cap(req->gNB_DU_ue_id, b->buf, b->len); + } + AssertFatal(req->cu_to_du_rrc_info->meas_config == NULL, "MeasConfig not handled\n"); } NR_SCHED_LOCK(&mac->sched_lock); @@ -749,39 +750,38 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) NR_CellGroupConfig_t *new_CellGroup = clone_CellGroupConfig(UE->CellGroup); - if (req->srbs_to_be_setup_length > 0) { + if (req->srbs_len > 0) { resp.srbs_to_be_setup_length = handle_ue_context_srbs_setup(UE, - req->srbs_to_be_setup_length, - req->srbs_to_be_setup, + req->srbs_len, + req->srbs, &resp.srbs_to_be_setup, new_CellGroup, &mac->rlc_config); } - if (req->drbs_to_be_setup_length > 0) { + if (req->drbs_len > 0) { resp.drbs_to_be_setup_length = handle_ue_context_drbs_setup(UE, - req->drbs_to_be_setup_length, - req->drbs_to_be_setup, + req->drbs_len, + req->drbs, &resp.drbs_to_be_setup, new_CellGroup, &mac->rlc_config); } - if (req->drbs_to_be_released_length > 0) { - resp.drbs_to_be_released_length = - handle_ue_context_drbs_release(UE, req->drbs_to_be_released_length, req->drbs_to_be_released, new_CellGroup); + if (req->drbs_rel_len > 0) { + resp.drbs_to_be_released_length = handle_ue_context_drbs_release(UE, req->drbs_rel_len, req->drbs_rel, new_CellGroup); } if (req->rrc_container != NULL) { logical_chan_id_t id = 1; - nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, id, req->rrc_container, req->rrc_container_length); + nr_rlc_srb_recv_sdu(req->gNB_DU_ue_id, id, req->rrc_container->buf, req->rrc_container->len); } NR_ServingCellConfigCommon_t *scc = mac->common_channels[0].ServingCellConfigCommon; - if (req->ReconfigComplOutcome != RRCreconf_info_not_present && req->ReconfigComplOutcome != RRCreconf_success) { + if (req->reconfig_compl && *req->reconfig_compl != RRCreconf_success) { LOG_E(NR_MAC, "RRC reconfiguration outcome unsuccessful, but no rollback mechanism implemented to come back to old configuration\n"); - } else if (req->ReconfigComplOutcome == RRCreconf_success) { + } else if (req->reconfig_compl) { LOG_I(NR_MAC, "DU received confirmation of successful RRC Reconfiguration\n"); if (UE->reconfigSpCellConfig) { // in case of reestablishment, the spCellConfig had to be released @@ -807,8 +807,7 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) update_cellGroupConfig(new_CellGroup, UE->uid, UE->capability, &mac->radio_config, scc); } - if (req->srbs_to_be_setup_length > 0 || req->drbs_to_be_setup_length > 0 || req->drbs_to_be_released_length > 0 - || ue_cap != NULL) { + if (req->srbs_len > 0 || req->drbs_len > 0 || req->drbs_rel_len > 0 || ue_cap != NULL) { resp.du_to_cu_rrc_information = calloc(1, sizeof(du_to_cu_rrc_information_t)); AssertFatal(resp.du_to_cu_rrc_information != NULL, "out of memory\n"); resp.du_to_cu_rrc_information->cellGroupConfig = calloc(1, 1024); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h index e9aceb1192..b3ecdad270 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h @@ -32,8 +32,8 @@ void f1_setup_response(const f1ap_setup_resp_t *resp); void f1_setup_failure(const f1ap_setup_failure_t *failure); void gnb_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration_update_acknowledge_t *ack); NR_CellGroupConfig_t *clone_CellGroupConfig(const NR_CellGroupConfig_t *orig); -void ue_context_setup_request(const f1ap_ue_context_setup_t *req); -void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req); +void ue_context_setup_request(const f1ap_ue_context_setup_req_t *req); +void ue_context_modification_request(const f1ap_ue_context_mod_req_t *req); void ue_context_modification_confirm(const f1ap_ue_context_modif_confirm_t *confirm); void ue_context_modification_refuse(const f1ap_ue_context_modif_refuse_t *refuse); void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd); diff --git a/openair2/RRC/NR/mac_rrc_dl.h b/openair2/RRC/NR/mac_rrc_dl.h index d6937591b5..f93bc1b7fe 100644 --- a/openair2/RRC/NR/mac_rrc_dl.h +++ b/openair2/RRC/NR/mac_rrc_dl.h @@ -33,8 +33,8 @@ typedef void (*f1_setup_failure_func_t)(sctp_assoc_t assoc_id, const f1ap_setup_ typedef void (*gnb_du_configuration_update_ack_func_t)(sctp_assoc_t assoc_id, const f1ap_gnb_du_configuration_update_acknowledge_t *ack); -typedef void (*ue_context_setup_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req); -typedef void (*ue_context_modification_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req); +typedef void (*ue_context_setup_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_req_t *req); +typedef void (*ue_context_modification_request_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_mod_req_t *req); typedef void (*ue_context_modification_confirm_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_confirm_t *confirm); typedef void (*ue_context_modification_refuse_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_refuse_t *refuse); typedef void (*ue_context_release_command_func_t)(sctp_assoc_t assoc_id, const f1ap_ue_context_release_cmd_t *cmd); diff --git a/openair2/RRC/NR/mac_rrc_dl_direct.c b/openair2/RRC/NR/mac_rrc_dl_direct.c index 4f8d45ac8c..29592d4e43 100644 --- a/openair2/RRC/NR/mac_rrc_dl_direct.c +++ b/openair2/RRC/NR/mac_rrc_dl_direct.c @@ -58,13 +58,13 @@ static void gnb_du_configuration_update_ack_direct(sctp_assoc_t assoc_id, const gnb_du_configuration_update_acknowledge(ack); } -static void ue_context_setup_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req) +static void ue_context_setup_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_req_t *req) { AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); ue_context_setup_request(req); } -static void ue_context_modification_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req) +static void ue_context_modification_request_direct(sctp_assoc_t assoc_id, const f1ap_ue_context_mod_req_t *req) { AssertFatal(assoc_id == -1, "illegal assoc_id %d\n", assoc_id); ue_context_modification_request(req); diff --git a/openair2/RRC/NR/mac_rrc_dl_f1ap.c b/openair2/RRC/NR/mac_rrc_dl_f1ap.c index 30c4f910ee..47d1bc1d7e 100644 --- a/openair2/RRC/NR/mac_rrc_dl_f1ap.c +++ b/openair2/RRC/NR/mac_rrc_dl_f1ap.c @@ -32,6 +32,7 @@ #include "nr_rrc_defs.h" #include "lib/f1ap_rrc_message_transfer.h" #include "lib/f1ap_interface_management.h" +#include "lib/f1ap_ue_context.h" static void f1_reset_cu_initiated_f1ap(sctp_assoc_t assoc_id, const f1ap_reset_t *reset) { @@ -75,116 +76,19 @@ static void gnb_du_configuration_update_ack_f1ap(sctp_assoc_t assoc_id, const f1 itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_setup_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_t *req) +static void ue_context_setup_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_setup_req_t *req) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ); msg->ittiMsgHeader.originInstance = assoc_id; - f1ap_ue_context_setup_t *f1ap_msg = &F1AP_UE_CONTEXT_SETUP_REQ(msg); - *f1ap_msg = *req; - if (req->cu_to_du_rrc_information != NULL) { - f1ap_msg->cu_to_du_rrc_information = calloc(1, sizeof(*f1ap_msg->cu_to_du_rrc_information)); - AssertFatal(f1ap_msg->cu_to_du_rrc_information != NULL, "out of memory\n"); - const cu_to_du_rrc_information_t *du2cu_req = req->cu_to_du_rrc_information; - if (req->cu_to_du_rrc_information->cG_ConfigInfo != NULL) { - cu_to_du_rrc_information_t* du2cu_new = f1ap_msg->cu_to_du_rrc_information; - du2cu_new->cG_ConfigInfo_length = du2cu_req->cG_ConfigInfo_length; - du2cu_new->cG_ConfigInfo = malloc_or_fail(du2cu_new->cG_ConfigInfo_length); - memcpy(du2cu_new->cG_ConfigInfo, du2cu_req->cG_ConfigInfo, du2cu_new->cG_ConfigInfo_length); - } - AssertFatal(req->cu_to_du_rrc_information->measConfig == NULL && req->cu_to_du_rrc_information->measConfig_length == 0, "cg_ConfigInfo not implemented\n"); - if (req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList != NULL) { - cu_to_du_rrc_information_t* du2cu_new = f1ap_msg->cu_to_du_rrc_information; - DevAssert(du2cu_req->uE_CapabilityRAT_ContainerList_length > 0); - du2cu_new->uE_CapabilityRAT_ContainerList_length = du2cu_req->uE_CapabilityRAT_ContainerList_length; - du2cu_new->uE_CapabilityRAT_ContainerList = malloc(du2cu_new->uE_CapabilityRAT_ContainerList_length); - AssertFatal(du2cu_new->uE_CapabilityRAT_ContainerList != NULL, "out of memory\n"); - memcpy(du2cu_new->uE_CapabilityRAT_ContainerList, du2cu_req->uE_CapabilityRAT_ContainerList, du2cu_new->uE_CapabilityRAT_ContainerList_length); - } - if (req->cu_to_du_rrc_information->handoverPreparationInfo != NULL) { - cu_to_du_rrc_information_t *du2cu_new = f1ap_msg->cu_to_du_rrc_information; - DevAssert(du2cu_req->handoverPreparationInfo_length > 0); - du2cu_new->handoverPreparationInfo_length = du2cu_req->handoverPreparationInfo_length; - du2cu_new->handoverPreparationInfo = malloc_or_fail(du2cu_new->handoverPreparationInfo_length); - memcpy(du2cu_new->handoverPreparationInfo, du2cu_req->handoverPreparationInfo, du2cu_new->handoverPreparationInfo_length); - } - } - if (req->drbs_to_be_setup_length > 0) { - int n = req->drbs_to_be_setup_length; - f1ap_msg->drbs_to_be_setup_length = n; - f1ap_msg->drbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->drbs_to_be_setup)); - AssertFatal(f1ap_msg->drbs_to_be_setup != NULL, "out of memory\n"); - memcpy(f1ap_msg->drbs_to_be_setup, req->drbs_to_be_setup, n * sizeof(*f1ap_msg->drbs_to_be_setup)); - } - if (req->srbs_to_be_setup_length > 0) { - int n = req->srbs_to_be_setup_length; - f1ap_msg->srbs_to_be_setup_length = n; - f1ap_msg->srbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->srbs_to_be_setup)); - AssertFatal(f1ap_msg->srbs_to_be_setup != NULL, "out of memory\n"); - memcpy(f1ap_msg->srbs_to_be_setup, req->srbs_to_be_setup, n * sizeof(*f1ap_msg->srbs_to_be_setup)); - } - if (req->rrc_container_length > 0) { - f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container)); - AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n"); - f1ap_msg->rrc_container_length = req->rrc_container_length; - memcpy(f1ap_msg->rrc_container, req->rrc_container, req->rrc_container_length); - } + F1AP_UE_CONTEXT_SETUP_REQ(msg) = cp_ue_context_setup_req(req); itti_send_msg_to_task(TASK_CU_F1, 0, msg); } -static void ue_context_modification_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_modif_req_t *req) +static void ue_context_modification_request_f1ap(sctp_assoc_t assoc_id, const f1ap_ue_context_mod_req_t *req) { MessageDef *msg = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_MODIFICATION_REQ); msg->ittiMsgHeader.originInstance = assoc_id; - f1ap_ue_context_modif_req_t *f1ap_msg = &F1AP_UE_CONTEXT_MODIFICATION_REQ(msg); - *f1ap_msg = *req; - if (req->cu_to_du_rrc_information != NULL) { - f1ap_msg->cu_to_du_rrc_information = calloc(1, sizeof(*f1ap_msg->cu_to_du_rrc_information)); - AssertFatal(f1ap_msg->cu_to_du_rrc_information != NULL, "out of memory\n"); - AssertFatal(req->cu_to_du_rrc_information->cG_ConfigInfo == NULL && req->cu_to_du_rrc_information->cG_ConfigInfo_length == 0, "cg_ConfigInfo not implemented\n"); - AssertFatal(req->cu_to_du_rrc_information->measConfig == NULL && req->cu_to_du_rrc_information->measConfig_length == 0, "cg_ConfigInfo not implemented\n"); - if (req->cu_to_du_rrc_information->uE_CapabilityRAT_ContainerList != NULL) { - const cu_to_du_rrc_information_t *du2cu_req = req->cu_to_du_rrc_information; - cu_to_du_rrc_information_t* du2cu_new = f1ap_msg->cu_to_du_rrc_information; - DevAssert(du2cu_req->uE_CapabilityRAT_ContainerList_length > 0); - du2cu_new->uE_CapabilityRAT_ContainerList_length = du2cu_req->uE_CapabilityRAT_ContainerList_length; - du2cu_new->uE_CapabilityRAT_ContainerList = malloc(du2cu_new->uE_CapabilityRAT_ContainerList_length); - AssertFatal(du2cu_new->uE_CapabilityRAT_ContainerList != NULL, "out of memory\n"); - memcpy(du2cu_new->uE_CapabilityRAT_ContainerList, du2cu_req->uE_CapabilityRAT_ContainerList, du2cu_new->uE_CapabilityRAT_ContainerList_length); - } - } - AssertFatal(req->drbs_to_be_modified_length == 0, "drbs_to_be_modified not supported yet\n"); - if (req->drbs_to_be_setup_length > 0) { - int n = req->drbs_to_be_setup_length; - f1ap_msg->drbs_to_be_setup_length = n; - f1ap_msg->drbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->drbs_to_be_setup)); - AssertFatal(f1ap_msg->drbs_to_be_setup != NULL, "out of memory\n"); - memcpy(f1ap_msg->drbs_to_be_setup, req->drbs_to_be_setup, n * sizeof(*f1ap_msg->drbs_to_be_setup)); - } - if (req->srbs_to_be_setup_length > 0) { - int n = req->srbs_to_be_setup_length; - f1ap_msg->srbs_to_be_setup_length = n; - f1ap_msg->srbs_to_be_setup = calloc(n, sizeof(*f1ap_msg->srbs_to_be_setup)); - AssertFatal(f1ap_msg->srbs_to_be_setup != NULL, "out of memory\n"); - memcpy(f1ap_msg->srbs_to_be_setup, req->srbs_to_be_setup, n * sizeof(*f1ap_msg->srbs_to_be_setup)); - } - if (req->drbs_to_be_released_length > 0) { - int n = req->drbs_to_be_released_length; - f1ap_msg->drbs_to_be_released_length = n; - f1ap_msg->drbs_to_be_released = calloc(n, sizeof(*f1ap_msg->drbs_to_be_released)); - AssertFatal(f1ap_msg->drbs_to_be_released != NULL, "out of memory\n"); - memcpy(f1ap_msg->drbs_to_be_released, req->drbs_to_be_released, n * sizeof(*f1ap_msg->drbs_to_be_released)); - } - if (req->rrc_container_length > 0) { - f1ap_msg->rrc_container = calloc(req->rrc_container_length, sizeof(*f1ap_msg->rrc_container)); - AssertFatal(f1ap_msg->rrc_container != NULL, "out of memory\n"); - f1ap_msg->rrc_container_length = req->rrc_container_length; - memcpy(f1ap_msg->rrc_container, req->rrc_container, req->rrc_container_length); - } - if (req->transm_action_ind != NULL) { - f1ap_msg->transm_action_ind = malloc(sizeof *f1ap_msg->transm_action_ind); - AssertFatal(f1ap_msg->transm_action_ind != NULL, "out of memory\n"); - *f1ap_msg->transm_action_ind = *req->transm_action_ind; - } + F1AP_UE_CONTEXT_MODIFICATION_REQ(msg) = cp_ue_context_mod_req(req); itti_send_msg_to_task(TASK_CU_F1, 0, msg); } diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 3a4fed6411..3ac774c69f 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -107,14 +107,14 @@ int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib, uint3 void rrc_gNB_generate_UeContextSetupRequest(const gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, int n_drbs, - const f1ap_drb_to_be_setup_t *drbs); + const f1ap_drb_to_setup_t *drbs); void rrc_gNB_generate_UeContextModificationRequest(const gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, int n_drbs, - const f1ap_drb_to_be_setup_t *drbs, + const f1ap_drb_to_setup_t *drbs, int n_rel_drbs, - const f1ap_drb_to_be_released_t *rel_drbs); + const f1ap_drb_to_release_t *rel_drbs); void free_RRCReconfiguration_params(nr_rrc_reconfig_param_t params); @@ -123,6 +123,6 @@ byte_array_t rrc_gNB_encode_RRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t * nr_rrc_reconfig_param_t get_RRCReconfiguration_params(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, uint8_t srb_reest_bitmap, bool drb_reestablish); pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi, rrc_pdu_session_param_t *pduSession); -f1ap_qos_characteristics_t get_qos_char_from_qos_flow_param(const pdusession_level_qos_parameter_t *qos_param); +f1ap_qos_flow_param_t get_qos_char_from_qos_flow_param(const pdusession_level_qos_parameter_t *qos_param); void openair_rrc_gNB_configuration(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration); #endif diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index e08a0a4d9e..6e53de1c10 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -80,6 +80,7 @@ #include "openair2/F1AP/f1ap_ids.h" #include "openair2/F1AP/lib/f1ap_rrc_message_transfer.h" #include "openair2/F1AP/lib/f1ap_interface_management.h" +#include "openair2/F1AP/lib/f1ap_ue_context.h" #include "rrc_gNB_NGAP.h" #include "rrc_gNB_du.h" #include "rrc_gNB_mobility.h" @@ -1774,12 +1775,14 @@ static void handle_rrcReconfigurationComplete(gNB_RRC_INST *rrc, gNB_RRC_UE_t *U f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); RETURN_IF_INVALID_ASSOC_ID(ue_data.du_assoc_id); - f1ap_ue_context_modif_req_t ue_context_modif_req = { + ReconfigurationCompl_t rc = RRCreconf_success; + f1ap_ue_context_mod_req_t req = { .gNB_CU_ue_id = UE->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, - .ReconfigComplOutcome = RRCreconf_success, + .reconfig_compl = &rc, }; - rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req); + rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &req); + /* nothing to be freed */ } static void rrc_gNB_generate_UECapabilityEnquiry(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue) @@ -2364,18 +2367,26 @@ pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi, rrc_pdu } /* \bref return F1AP QoS characteristics based on Qos flow parameters */ -f1ap_qos_characteristics_t get_qos_char_from_qos_flow_param(const pdusession_level_qos_parameter_t *qos_param) +f1ap_qos_flow_param_t get_qos_char_from_qos_flow_param(const pdusession_level_qos_parameter_t *qos_param) { - f1ap_qos_characteristics_t qos_char = {0}; + f1ap_qos_flow_param_t qos_char = {0}; if (qos_param->fiveQI_type == DYNAMIC) { qos_char.qos_type = DYNAMIC; - qos_char.dynamic.fiveqi = qos_param->fiveQI; - qos_char.dynamic.qos_priority_level = qos_param->qos_priority; + qos_char.dyn.prio = qos_param->qos_priority; + qos_char.dyn.pdb = 100; // TODO + qos_char.dyn.per.scalar = 10; // TODO + qos_char.dyn.per.exponent = 100; // TODO } else { qos_char.qos_type = NON_DYNAMIC; - qos_char.non_dynamic.fiveqi = qos_param->fiveQI; - qos_char.non_dynamic.qos_priority_level = qos_param->qos_priority; + qos_char.nondyn.fiveQI = qos_param->fiveQI; } + const ngap_allocation_retention_priority_t *a = &qos_param->allocation_retention_priority; + qos_char.arp.prio = a->priority_level; + qos_char.arp.preempt_cap = a->pre_emp_capability == NGAP_PRE_EMPTION_CAPABILITY_MAY_TRIGGER_PREEMPTION + ? MAY_TRIGGER_PREEMPTION + : SHALL_NOT_TRIGGER_PREEMPTION; + qos_char.arp.preempt_vuln = + a->pre_emp_vulnerability == NGAP_PRE_EMPTION_VULNERABILITY_PREEMPTABLE ? PREEMPTABLE : NOT_PREEMPTABLE; return qos_char; } @@ -2385,38 +2396,52 @@ static int fill_drb_to_be_setup_from_e1_resp(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const pdu_session_setup_t *pduSession, int numPduSession, - f1ap_drb_to_be_setup_t drbs[32]) + f1ap_drb_to_setup_t drbs[32]) { int nb_drb = 0; for (int p = 0; p < numPduSession; ++p) { - rrc_pdu_session_param_t *RRC_pduSession = find_pduSession(UE, pduSession[p].id, false); - DevAssert(RRC_pduSession); + rrc_pdu_session_param_t *pdu = find_pduSession(UE, pduSession[p].id, false); + DevAssert(pdu); for (int i = 0; i < pduSession[p].numDRBSetup; i++) { const DRB_nGRAN_setup_t *drb_config = &pduSession[p].DRBnGRanList[i]; - f1ap_drb_to_be_setup_t *drb = &drbs[nb_drb]; - drb->drb_id = pduSession[p].DRBnGRanList[i].id; - drb->rlc_mode = rrc->configuration.um_on_default_drb ? F1AP_RLC_MODE_UM_BIDIR : F1AP_RLC_MODE_AM; - drb->up_ul_tnl[0].tl_address = drb_config->UpParamList[0].tl_info.tlAddress; - drb->up_ul_tnl[0].port = rrc->eth_params_s.my_portd; - drb->up_ul_tnl[0].teid = drb_config->UpParamList[0].tl_info.teId; - drb->up_ul_tnl_length = 1; + drb_t *rrc_drb = get_drb(UE, pduSession[p].DRBnGRanList[i].id); + DevAssert(rrc_drb); + + f1ap_drb_to_setup_t *drb = &drbs[nb_drb]; + drb->id = rrc_drb->drb_id; + + drb->qos_choice = F1AP_QOS_CHOICE_NR; /* pass QoS info to MAC */ int nb_qos_flows = drb_config->numQosFlowSetup; AssertFatal(nb_qos_flows > 0, "must map at least one flow to a DRB\n"); - drb->drb_info.flows_to_be_setup_length = nb_qos_flows; - drb->drb_info.flows_mapped_to_drb = calloc(nb_qos_flows, sizeof(f1ap_flows_mapped_to_drb_t)); - AssertFatal(drb->drb_info.flows_mapped_to_drb, "could not allocate memory\n"); + drb->nr.flows_len = nb_qos_flows; + drb->nr.flows = calloc_or_fail(nb_qos_flows, sizeof(*drb->nr.flows)); for (int j = 0; j < nb_qos_flows; j++) { - drb->drb_info.flows_mapped_to_drb[j].qfi = drb_config->qosFlows[j].qfi; - pdusession_level_qos_parameter_t *in_qos_char = get_qos_characteristics(drb_config->qosFlows[j].qfi, RRC_pduSession); - drb->drb_info.flows_mapped_to_drb[j].qos_params.qos_characteristics = get_qos_char_from_qos_flow_param(in_qos_char); + int qfi = drb_config->qosFlows[j].qfi; + /* find the QoS characteristics stored at RRC based on QFI returned + * from E1. We expect this to correspond to a QFI we passed to E1 + * previously, so we expect it to exist. */ + pdusession_level_qos_parameter_t *qos_param = get_qos_characteristics(qfi, pdu); + DevAssert(qos_param); + f1ap_drb_flows_mapped_t *flow = &drb->nr.flows[j]; + flow->qfi = qfi; + flow->param = get_qos_char_from_qos_flow_param(qos_param); } /* the DRB QoS parameters: we just reuse the ones from the first flow */ - drb->drb_info.drb_qos = drb->drb_info.flows_mapped_to_drb[0].qos_params; + drb->nr.drb_qos = drb->nr.flows[0].param; /* pass NSSAI info to MAC */ - drb->nssai = RRC_pduSession->param.nssai; + drb->nr.nssai = pdu->param.nssai; + + drb->up_ul_tnl[0].tl_address = drb_config->UpParamList[0].tl_info.tlAddress; + drb->up_ul_tnl[0].teid = drb_config->UpParamList[0].tl_info.teId; + drb->up_ul_tnl_len = 1; + drb->rlc_mode = rrc->configuration.um_on_default_drb ? F1AP_RLC_MODE_UM_BIDIR : F1AP_RLC_MODE_AM; + drb->dl_pdcp_sn_len = malloc_or_fail(sizeof(*drb->dl_pdcp_sn_len)); + *drb->dl_pdcp_sn_len = rrc_drb->pdcp_config.pdcp_SN_SizeDL == 1 ? F1AP_PDCP_SN_18B : F1AP_PDCP_SN_12B; + drb->ul_pdcp_sn_len = malloc_or_fail(sizeof(*drb->ul_pdcp_sn_len)); + *drb->ul_pdcp_sn_len = rrc_drb->pdcp_config.pdcp_SN_SizeUL == 1 ? F1AP_PDCP_SN_18B : F1AP_PDCP_SN_12B; nb_drb++; } @@ -2463,7 +2488,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp } /* Instruction towards the DU for DRB configuration and tunnel creation */ - f1ap_drb_to_be_setup_t drbs[32]; // maximum DRB can be 32 + f1ap_drb_to_setup_t drbs[32]; // maximum DRB can be 32 int nb_drb = fill_drb_to_be_setup_from_e1_resp(rrc, UE, resp->pduSession, resp->numPDUSessions, drbs); if (!UE->f1_ue_context_active) @@ -3001,7 +3026,7 @@ int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib1, uint void rrc_gNB_generate_UeContextSetupRequest(const gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, int n_drbs, - const f1ap_drb_to_be_setup_t *drbs) + const f1ap_drb_to_setup_t *drbs) //----------------------------------------------------------------------------- { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; @@ -3009,47 +3034,51 @@ void rrc_gNB_generate_UeContextSetupRequest(const gNB_RRC_INST *rrc, AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); - cu_to_du_rrc_information_t cu2du = {0}; - cu_to_du_rrc_information_t *cu2du_p = NULL; + f1ap_cu_to_du_rrc_info_t cu2du = {0}; if (ue_p->ue_cap_buffer.len > 0 && ue_p->ue_cap_buffer.buf != NULL) { - cu2du_p = &cu2du; - cu2du.uE_CapabilityRAT_ContainerList = ue_p->ue_cap_buffer.buf; - cu2du.uE_CapabilityRAT_ContainerList_length = ue_p->ue_cap_buffer.len; + cu2du.ue_cap = &ue_p->ue_cap_buffer; } int nb_srb = 1; - f1ap_srb_to_be_setup_t srbs[1] = {{.srb_id = 2, .lcid = 2}}; + f1ap_srb_to_setup_t srbs[1] = {{.id = 2, }}; activate_srb(ue_p, 2); + /* gNB-DU UE Aggregate Maximum Bit Rate Uplink is C- ifDRBSetup */ + uint64_t agg_mbr = 1000000000 /* bps */, *agg_mbr_p = NULL; + if (n_drbs > 0) + agg_mbr_p = &agg_mbr; + /* the callback will fill the UE context setup request and forward it */ f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); RETURN_IF_INVALID_ASSOC_ID(ue_data.du_assoc_id); - f1ap_ue_context_setup_t ue_context_setup_req = { + f1ap_ue_context_setup_req_t ue_context_setup_req = { .gNB_CU_ue_id = ue_p->rrc_ue_id, - .gNB_DU_ue_id = ue_data.secondary_ue, + .gNB_DU_ue_id = &ue_data.secondary_ue, .plmn.mcc = rrc->configuration.plmn[0].mcc, .plmn.mnc = rrc->configuration.plmn[0].mnc, .plmn.mnc_digit_length = rrc->configuration.plmn[0].mnc_digit_length, .nr_cellid = rrc->nr_cellid, - .servCellId = 0, /* TODO: correct value? */ - .srbs_to_be_setup_length = nb_srb, - .srbs_to_be_setup = srbs, - .drbs_to_be_setup_length = n_drbs, - .drbs_to_be_setup = (f1ap_drb_to_be_setup_t *)drbs, - .cu_to_du_rrc_information = cu2du_p, + .servCellIndex = 0, /* TODO: correct value? */ + .srbs_len = nb_srb, + .srbs = srbs, + .drbs_len = n_drbs, + .drbs = (f1ap_drb_to_setup_t *) drbs, // cast to avoid warning on const + .cu_to_du_rrc_info = cu2du, + .gnb_du_ue_agg_mbr_ul = agg_mbr_p, }; rrc->mac_rrc.ue_context_setup_request(ue_data.du_assoc_id, &ue_context_setup_req); LOG_I(RRC, "UE %d trigger UE context setup request with %d DRBs\n", ue_p->rrc_ue_id, n_drbs); + // nothing to free for ue_context_setup_req } //----------------------------------------------------------------------------- void rrc_gNB_generate_UeContextModificationRequest(const gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, int n_drbs, - const f1ap_drb_to_be_setup_t *drbs, + const f1ap_drb_to_setup_t *drbs, int n_rel_drbs, - const f1ap_drb_to_be_released_t *rel_drbs) + const f1ap_drb_to_release_t *rel_drbs) //----------------------------------------------------------------------------- { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; @@ -3058,30 +3087,23 @@ void rrc_gNB_generate_UeContextModificationRequest(const gNB_RRC_INST *rrc, AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); - cu_to_du_rrc_information_t cu2du = {0}; - cu_to_du_rrc_information_t *cu2du_p = NULL; + f1ap_cu_to_du_rrc_info_t cu2du = {0}; if (ue_p->ue_cap_buffer.len > 0 && ue_p->ue_cap_buffer.buf != NULL) { - cu2du_p = &cu2du; - cu2du.uE_CapabilityRAT_ContainerList = ue_p->ue_cap_buffer.buf; - cu2du.uE_CapabilityRAT_ContainerList_length = ue_p->ue_cap_buffer.len; + cu2du.ue_cap = &ue_p->ue_cap_buffer; } f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); RETURN_IF_INVALID_ASSOC_ID(ue_data.du_assoc_id); - f1ap_ue_context_modif_req_t ue_context_modif_req = { + f1ap_ue_context_mod_req_t ue_context_modif_req = { .gNB_CU_ue_id = ue_p->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, - .plmn.mcc = rrc->configuration.plmn[0].mcc, - .plmn.mnc = rrc->configuration.plmn[0].mnc, - .plmn.mnc_digit_length = rrc->configuration.plmn[0].mnc_digit_length, - .nr_cellid = rrc->nr_cellid, - .servCellId = 0, /* TODO: correct value? */ - .drbs_to_be_setup_length = n_drbs, - .drbs_to_be_setup = (f1ap_drb_to_be_setup_t *)drbs, - .drbs_to_be_released_length = n_rel_drbs, - .drbs_to_be_released = (f1ap_drb_to_be_released_t *)rel_drbs, - .cu_to_du_rrc_information = cu2du_p, + .drbs_len = n_drbs, + .drbs = (f1ap_drb_to_setup_t *)drbs, + .drbs_rel_len = n_rel_drbs, + .drbs_rel = (f1ap_drb_to_release_t *)rel_drbs, + .cu_to_du_rrc_info = &cu2du, }; rrc->mac_rrc.ue_context_modification_request(ue_data.du_assoc_id, &ue_context_modif_req); LOG_I(RRC, "UE %d trigger UE context modification request with %d DRBs\n", ue_p->rrc_ue_id, n_drbs); + // nothing to free } diff --git a/openair2/RRC/NR/rrc_gNB_mobility.c b/openair2/RRC/NR/rrc_gNB_mobility.c index 647f253989..a08e446ef1 100644 --- a/openair2/RRC/NR/rrc_gNB_mobility.c +++ b/openair2/RRC/NR/rrc_gNB_mobility.c @@ -31,6 +31,7 @@ #include "rrc_gNB_UE_context.h" #include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" #include "openair2/F1AP/f1ap_ids.h" +#include "openair2/F1AP/lib/f1ap_ue_context.h" #include "MESSAGES/asn1_msg.h" #include "nr_pdcp/nr_pdcp_oai_api.h" #include "openair3/SECU/key_nas_deriver.h" @@ -61,7 +62,7 @@ static void free_ho_ctx(nr_handover_context_t *ho_ctx) free(ho_ctx); } -static int fill_drb_to_be_setup(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, f1ap_drb_to_be_setup_t drbs[MAX_DRBS_PER_UE]) +static int fill_drb_to_be_setup(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, f1ap_drb_to_setup_t drbs[MAX_DRBS_PER_UE]) { int nb_drb = 0; for (int i = 0; i < MAX_DRBS_PER_UE; ++i) { @@ -69,34 +70,38 @@ static int fill_drb_to_be_setup(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, f1ap_ if (rrc_drb->status == DRB_INACTIVE) continue; - f1ap_drb_to_be_setup_t *drb = &drbs[nb_drb]; + f1ap_drb_to_setup_t *drb = &drbs[nb_drb]; nb_drb++; - drb->drb_id = rrc_drb->drb_id; - drb->rlc_mode = rrc->configuration.um_on_default_drb ? F1AP_RLC_MODE_UM_BIDIR : F1AP_RLC_MODE_AM; - memcpy(&drb->up_ul_tnl[0].tl_address, &rrc_drb->cuup_tunnel_config.addr.buffer, sizeof(uint8_t) * 4); - drb->up_ul_tnl[0].port = rrc->eth_params_s.my_portd; - drb->up_ul_tnl[0].teid = rrc_drb->cuup_tunnel_config.teid; - drb->up_ul_tnl_length = 1; - /* fetch an existing PDU session for this DRB */ - rrc_pdu_session_param_t *pdu = find_pduSession_from_drbId(ue, drb->drb_id); - AssertFatal(pdu != NULL, "no PDU session for DRB ID %ld\n", drb->drb_id); - drb->nssai = pdu->param.nssai; - + rrc_pdu_session_param_t *pdu = find_pduSession_from_drbId(ue, rrc_drb->drb_id); + AssertFatal(pdu != NULL, "no PDU session for DRB ID %d\n", rrc_drb->drb_id); // for the moment, we only support one QoS flow. Put a reminder in case // this changes AssertFatal(pdu->param.nb_qos == 1, "only 1 Qos flow supported\n"); - drb->drb_info.flows_to_be_setup_length = 1; - drb->drb_info.flows_mapped_to_drb = calloc_or_fail(1, sizeof(drb->drb_info.flows_mapped_to_drb[0])); - AssertFatal(drb->drb_info.flows_mapped_to_drb, "could not allocate memory\n"); int qfi = rrc_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[0]; - DevAssert(qfi > 0); - drb->drb_info.flows_mapped_to_drb[0].qfi = qfi; - pdusession_level_qos_parameter_t *in_qos_char = get_qos_characteristics(qfi, pdu); - drb->drb_info.flows_mapped_to_drb[0].qos_params.qos_characteristics = get_qos_char_from_qos_flow_param(in_qos_char); + pdusession_level_qos_parameter_t *qos_param = get_qos_characteristics(qfi, pdu); + drb->id = rrc_drb->drb_id; + + drb->qos_choice = F1AP_QOS_CHOICE_NR; + drb->nr.nssai = pdu->param.nssai; + drb->nr.flows_len = 1; + drb->nr.flows = calloc_or_fail(1, sizeof(*drb->nr.flows)); + DevAssert(qfi > 0); + drb->nr.flows[0].qfi = qfi; + drb->nr.flows[0].param = get_qos_char_from_qos_flow_param(qos_param); /* the DRB QoS parameters: we just reuse the ones from the first flow */ - drb->drb_info.drb_qos = drb->drb_info.flows_mapped_to_drb[0].qos_params; + drb->nr.drb_qos = drb->nr.flows[0].param; + + memcpy(&drb->up_ul_tnl[0].tl_address, &rrc_drb->cuup_tunnel_config.addr.buffer, sizeof(uint8_t) * 4); + drb->up_ul_tnl[0].teid = rrc_drb->cuup_tunnel_config.teid; + drb->up_ul_tnl_len = 1; + + drb->rlc_mode = rrc->configuration.um_on_default_drb ? F1AP_RLC_MODE_UM_BIDIR : F1AP_RLC_MODE_AM; + drb->dl_pdcp_sn_len = malloc_or_fail(sizeof(*drb->dl_pdcp_sn_len)); + *drb->dl_pdcp_sn_len = rrc_drb->pdcp_config.pdcp_SN_SizeDL == 1 ? F1AP_PDCP_SN_18B : F1AP_PDCP_SN_12B; + drb->ul_pdcp_sn_len = malloc_or_fail(sizeof(*drb->ul_pdcp_sn_len)); + *drb->ul_pdcp_sn_len = rrc_drb->pdcp_config.pdcp_SN_SizeUL == 1 ? F1AP_PDCP_SN_18B : F1AP_PDCP_SN_12B;; } return nb_drb; } @@ -168,32 +173,38 @@ static void nr_initiate_handover(const gNB_RRC_INST *rrc, target_du->assoc_id, target_du->setup_req->cell[0].info.nr_pci); - cu_to_du_rrc_information_t cu2du = { - .handoverPreparationInfo = ho_prep_info->buf, - .handoverPreparationInfo_length = ho_prep_info->len, - }; - - f1ap_drb_to_be_setup_t drbs[MAX_DRBS_PER_UE] = {0}; + f1ap_drb_to_setup_t *drbs = calloc_or_fail(MAX_DRBS_PER_UE, sizeof(*drbs)); int nb_drb = fill_drb_to_be_setup(rrc, ue, drbs); - f1ap_srb_to_be_setup_t srbs[2] = {{.srb_id = 1, .lcid = 1}, {.srb_id = 2, .lcid = 2}}; + int nb_srb = 2; + f1ap_srb_to_setup_t *srbs = calloc_or_fail(nb_srb, sizeof(*srbs)); + srbs[0].id = 1; + srbs[1].id = 2; + + byte_array_t *hpi = malloc_or_fail(sizeof(*hpi)); + *hpi = copy_byte_array(*ho_prep_info); + + uint64_t *ue_agg_mbr = malloc_or_fail(sizeof(*ue_agg_mbr)); + *ue_agg_mbr = 1000000000 /*bps*/; + f1ap_served_cell_info_t *cell_info = &target_du->setup_req->cell[0].info; RETURN_IF_INVALID_ASSOC_ID(target_du->assoc_id); - f1ap_ue_context_setup_t ue_context_setup_req = { + f1ap_ue_context_setup_req_t ue_context_setup_req = { .gNB_CU_ue_id = ue->rrc_ue_id, - .gNB_DU_ue_id = 0, /* TODO: this should be optional! */ .plmn.mcc = cell_info->plmn.mcc, .plmn.mnc = cell_info->plmn.mnc, .plmn.mnc_digit_length = cell_info->plmn.mnc_digit_length, .nr_cellid = cell_info->nr_cellid, - .servCellId = 0, // TODO: correct value? - .srbs_to_be_setup_length = 2, - .srbs_to_be_setup = srbs, - .drbs_to_be_setup_length = nb_drb, - .drbs_to_be_setup = drbs, - .cu_to_du_rrc_information = &cu2du, + .servCellIndex = 0, // TODO: correct value? + .srbs_len = nb_srb, + .srbs = srbs, + .drbs_len = nb_drb, + .drbs = drbs, + .cu_to_du_rrc_info.ho_prep_info = hpi, + .gnb_du_ue_agg_mbr_ul = ue_agg_mbr, }; rrc->mac_rrc.ue_context_setup_request(target_du->assoc_id, &ue_context_setup_req); + free_ue_context_setup_req(&ue_context_setup_req); } /* @@ -214,15 +225,15 @@ void nr_rrc_trigger_n2_ho(gNB_RRC_INST *rrc, int nr_cgi, uint8_t *ho_prep_info, typedef struct deliver_ue_ctxt_modification_data_t { gNB_RRC_INST *rrc; - f1ap_ue_context_modif_req_t *modification_req; + f1ap_ue_context_mod_req_t *modification_req; sctp_assoc_t assoc_id; } deliver_ue_ctxt_modification_data_t; static void rrc_deliver_ue_ctxt_modif_req(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) { DevAssert(deliver_pdu_data != NULL); deliver_ue_ctxt_modification_data_t *data = deliver_pdu_data; - data->modification_req->rrc_container = (uint8_t*)buf; - data->modification_req->rrc_container_length = size; + byte_array_t ba = {.buf = (uint8_t *) buf, .len = size}; + data->modification_req->rrc_container = &ba; data->rrc->mac_rrc.ue_context_modification_request(data->assoc_id, data->modification_req); } static void rrc_gNB_trigger_reconfiguration_for_handover(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, uint8_t *rrc_reconf, int rrc_reconf_len) @@ -231,12 +242,9 @@ static void rrc_gNB_trigger_reconfiguration_for_handover(gNB_RRC_INST *rrc, gNB_ TransmActionInd_t transmission_action_indicator = TransmActionInd_STOP; RETURN_IF_INVALID_ASSOC_ID(ue_data.du_assoc_id); - f1ap_ue_context_modif_req_t ue_context_modif_req = { + f1ap_ue_context_mod_req_t ue_context_modif_req = { .gNB_CU_ue_id = ue->rrc_ue_id, .gNB_DU_ue_id = ue_data.secondary_ue, - .plmn = rrc->configuration.plmn[0], - .nr_cellid = rrc->nr_cellid, // TODO target cell ID - .servCellId = 0, // TODO: correct value? .transm_action_ind = &transmission_action_indicator, }; deliver_ue_ctxt_modification_data_t data = {.rrc = rrc, diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 8ac172a21e..1ccdb3439a 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -71,6 +71,7 @@ #include "xer_decoder.h" #include "xer_encoder.h" #include "f1ap_common.h" +#include "lib/f1ap_ue_context.h" // In case of phy-test and do-ra mode, read UE capabilities directly from file // and put it into a CG-ConfigInfo field @@ -137,18 +138,16 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, x2ap_ENDC_sgnb_addition_req_t *m, sctp_ nr_pdcp_entity_security_keys_and_algos_t security_parameters = {0}; uint8_t tmp[1024]; - uint8_t *cgci_buf = NULL; - uint32_t cgci_len = 0; + byte_array_t cgci = {0}; if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) { DevAssert(m == NULL); UE->rb_config = get_default_rbconfig(10 /* EPS bearer ID */, 1 /* drb ID */, NR_CipheringAlgorithm_nea0, NR_SecurityConfig__keyToUse_master, &rrc->pdcp_config); - cgci_len = cg_config_info_from_ue_cap_file(sizeof tmp, tmp); - DevAssert(cgci_len > 0); - cgci_buf = tmp; + int len = cg_config_info_from_ue_cap_file(sizeof tmp, tmp); + DevAssert(len > 0); + cgci = create_byte_array(len, tmp); } else { DevAssert(m != NULL); - cgci_buf = m->rrc_buffer; - cgci_len = m->rrc_buffer_size; + cgci = create_byte_array(m->rrc_buffer_size, m->rrc_buffer); /* TODO: handle more than one bearer */ if (m->nb_e_rabs_tobeadded != 1) { @@ -272,25 +271,24 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, x2ap_ENDC_sgnb_addition_req_t *m, sctp_ UE->rb_config->drb_ToAddModList, &security_parameters); - cu_to_du_rrc_information_t cu2du = { - .cG_ConfigInfo = cgci_buf, - .cG_ConfigInfo_length = cgci_len, - }; /* assumption: only a single bearer, see above */ NR_DRB_ToAddModList_t *rb_list = UE->rb_config->drb_ToAddModList; AssertFatal(rb_list->list.count == 1, "can only handle one bearer for NSA/phy-test/do-ra, but has %d\n", rb_list->list.count); int drb_id = rb_list->list.array[0]->drb_Identity; - f1ap_flows_mapped_to_drb_t *flow = calloc(1, sizeof(f1ap_flows_mapped_to_drb_t)); - flow->qos_params.qos_characteristics.qos_type = NON_DYNAMIC; - flow->qfi = flow->qos_params.qos_characteristics.non_dynamic.fiveqi = 9; - f1ap_drb_to_be_setup_t drbs = { - .drb_id = drb_id, - .rlc_mode = F1AP_RLC_MODE_UM_BIDIR, // hardcoded keep it backwards compatible for now - // rrc->configuration.um_on_default_drb ? F1AP_RLC_MODE_UM_BIDIR : F1AP_RLC_MODE_AM, - .up_ul_tnl_length = 1, - .drb_info.flows_to_be_setup_length = 1, - .drb_info.flows_mapped_to_drb = flow, - }; + f1ap_drb_to_setup_t *drb = calloc_or_fail(1, sizeof(*drb)); + drb->id = drb_id; + // hardcoded keep it backwards compatible for now + // rrc->configuration.um_on_default_drb ? F1AP_RLC_MODE_UM_BIDIR : F1AP_RLC_MODE_AM, + drb->rlc_mode = F1AP_RLC_MODE_UM_BIDIR; + drb->up_ul_tnl_len = 1; + drb->qos_choice = F1AP_QOS_CHOICE_NR; // we don't have EUTRAN yet, "approximate" it + drb->nr.flows_len = 1; + f1ap_drb_flows_mapped_t *flow = drb->nr.flows = calloc_or_fail(drb->nr.flows_len, sizeof(*flow)); + flow->qfi = 9; + flow->param.qos_type = NON_DYNAMIC; + flow->param.nondyn.fiveQI = 9; + flow->param.arp.prio = 5; + // Note: E1 support for NSA/phy-test/do-ra not implemented yet instance_t f1inst = get_f1_gtp_instance(); if (f1inst >= 0) { @@ -305,25 +303,30 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, x2ap_ENDC_sgnb_addition_req_t *m, sctp_ gtpv1u_gnb_create_tunnel_resp_t resp = {0}; int ret = gtpv1u_create_ngu_tunnel(f1inst, &req, &resp, NULL, NULL); AssertFatal(ret == 0, "gtpv1u_create_ngu_tunnel failed: ret %d\n", ret); - drbs.up_ul_tnl[0].port = rrc->eth_params_s.my_portd; - memcpy(&drbs.up_ul_tnl[0].tl_address, &resp.gnb_addr.buffer, 4); - drbs.up_ul_tnl[0].teid = resp.gnb_NGu_teid[0]; + memcpy(&drb->up_ul_tnl[0].tl_address, &resp.gnb_addr.buffer, 4); + drb->up_ul_tnl[0].teid = resp.gnb_NGu_teid[0]; + drb->up_ul_tnl_len = 1; } - f1ap_ue_context_setup_t req = { + uint64_t *ue_agg_mbr_ul = malloc_or_fail(sizeof(*ue_agg_mbr_ul)); + *ue_agg_mbr_ul = 1000000000; + byte_array_t *cg_configinfo = malloc_or_fail(sizeof(*cg_configinfo)); + *cg_configinfo = cgci; + f1ap_ue_context_setup_req_t req = { .gNB_CU_ue_id = UE->rrc_ue_id, - .gNB_DU_ue_id = 0xffffffff, /* not known yet */ .plmn.mcc = rrc->configuration.plmn[0].mcc, .plmn.mnc = rrc->configuration.plmn[0].mnc, .plmn.mnc_digit_length = rrc->configuration.plmn[0].mnc_digit_length, .nr_cellid = rrc->nr_cellid, - .servCellId = 0, - .drbs_to_be_setup_length = 1, - .drbs_to_be_setup = &drbs, - .cu_to_du_rrc_information = &cu2du, + .servCellIndex = 0, + .drbs_len = 1, + .drbs = drb, + .cu_to_du_rrc_info.cg_configinfo = cg_configinfo, + .gnb_du_ue_agg_mbr_ul = ue_agg_mbr_ul, }; f1_ue_data_t ue_data = cu_get_f1_ue_data(UE->rrc_ue_id); RETURN_IF_INVALID_ASSOC_ID(ue_data.du_assoc_id); rrc->mac_rrc.ue_context_setup_request(ue_data.du_assoc_id, &req); + free_ue_context_setup_req(&req); } static NR_RRCReconfiguration_IEs_t *get_default_reconfig(const NR_CellGroupConfig_t *secondaryCellGroup)