diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index cc29a92ebb21251daec16b18066b7e54d5d6e0aa..6fe48ed611cfdc3a3342f1a06beef44a6787c550 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -38,31 +38,153 @@ #include "rrc_extern.h" #include "openair2/RRC/NR/rrc_gNB_NGAP.h" -#include <openair3/ocp-gtpu/gtp_itf.h> -#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h" -static void setQos(F1AP_NonDynamic5QIDescriptor_t **toFill) +static void f1ap_write_drb_qos_param(const f1ap_qos_flow_level_qos_parameters_t *drb_qos_in, F1AP_QoSFlowLevelQoSParameters_t *asn1_qosparam) { - asn1cCalloc(*toFill, tmp); - /* fiveQI */ - tmp->fiveQI = 1L; + int type = drb_qos_in->qos_characteristics.qos_type; + + 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 */ - /* qoSPriorityLevel */ + /* gBR_QoS_Flow_Information */ if (0) { - asn1cCallocOne((*toFill)->qoSPriorityLevel, 1L); + 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 */ - /* averagingWindow */ + /* reflective_QoS_Attribute */ if (0) { - asn1cCallocOne((*toFill)->averagingWindow, 1L); + 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 */ - /* maxDataBurstVolume */ - if (0) { - asn1cCallocOne((*toFill)->maxDataBurstVolume, 1L); + if (nssai->sd != 0xffffff) + OCTET_STRING_fromBuf(asn1_nssai->sD, (char *)&nssai->sd, 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); } } @@ -275,7 +397,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu 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; @@ -283,7 +405,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu /* 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 = f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id; // 9 + drbs_toBeSetup_item->dRBID = drb->drb_id; /* 12.1.2 qoSInformation */ int some_decide_qos = 0; // BK: Need Check @@ -314,6 +436,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu } } 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; @@ -321,90 +444,12 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu 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 */ - { - /* qoS_Characteristics */ - { - int some_decide_qoS_characteristics = 0; // BK: Need Check - - if (some_decide_qoS_characteristics) { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - setQos(&DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI); - } else { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI, tmp); - /* qoSPriorityLevel */ - tmp->qoSPriorityLevel = 1L; - /* packetDelayBudget */ - tmp->packetDelayBudget = 1L; - /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = 1L; - tmp->packetErrorRate.pER_Exponent = 6L; - - /* OPTIONAL */ - /* delayCritical */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); - } - - /* OPTIONAL */ - /* averagingWindow */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); - } - - /* OPTIONAL */ - /* maxDataBurstVolume */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); - } - } // if some_decide_qoS_characteristics - } // qoS_Characteristics - /* nGRANallocationRetentionPriority */ - { - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(DRB_Information->dRB_QoS.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 */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - } - - /* OPTIONAL */ - /* maxPacketLossRateUplink */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } - } - - /* OPTIONAL */ - /* reflective_QoS_Attribute */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); - } - } // dRB_QoS - /* 12.1.2.2 sNSSAI */ - { - /* sST */ - OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, (char *)&f1ap_ue_context_setup_req->drbs_to_be_setup[i].nssai.sst, 1); + f1ap_write_drb_qos_param(&drb_info->drb_qos, &DRB_Information->dRB_QoS); - /* OPTIONAL */ - const uint32_t sd = (f1ap_ue_context_setup_req->drbs_to_be_setup[i].nssai.sd & 0xffffff); - if (sd != 0xffffff) - OCTET_STRING_fromBuf(DRB_Information->sNSSAI.sD, (char *)&sd, 3); - } + /* 12.1.2.2 sNSSAI */ + f1ap_write_drb_nssai(&drb->nssai, &DRB_Information->sNSSAI); /* OPTIONAL */ /* 12.1.2.3 notificationControl */ @@ -414,108 +459,12 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu } /* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy - - for (int k = 0; k < 1; k ++) { - asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list, - F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item); - /* qoSFlowIndicator */ - flows_mapped_to_drb_item->qoSFlowIdentifier = 1L; - /* qoSFlowLevelQoSParameters */ - { - /* qoS_Characteristics */ - { - int some_decide_qoS_characteristics = 0; // BK: Need Check - F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics; - - if (some_decide_qoS_characteristics) { - QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - setQos(&QosParams->choice.non_Dynamic_5QI); - } else { - QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); - /* qoSPriorityLevel */ - tmp->qoSPriorityLevel = 1L; - /* packetDelayBudget */ - tmp->packetDelayBudget = 1L; - /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = 1L; - tmp->packetErrorRate.pER_Exponent = 6L; - - /* OPTIONAL */ - /* delayCritical */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp); - *tmp = 1L; - } - - /* OPTIONAL */ - /* averagingWindow */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp); - *tmp = 1L; - } - - /* OPTIONAL */ - /* maxDataBurstVolume */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp); - *tmp= 1L; - } - } // if some_decide_qoS_characteristics - } // qoS_Characteristics - /* nGRANallocationRetentionPriority */ - { - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = F1AP_PriorityLevel_highest; // enum - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = F1AP_Pre_emptionCapability_shall_not_trigger_pre_emption; // enum - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = F1AP_Pre_emptionVulnerability_not_pre_emptable; // enum - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(flows_mapped_to_drb_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 */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - } - - /* OPTIONAL */ - /* maxPacketLossRateUplink */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } - } - - /* OPTIONAL */ - /* reflective_QoS_Attribute */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); - } - } // qoSFlowLevelQoSParameters - } + 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++) { - /*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/ - /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */ - transport_layer_addr_t addr = { .length= 32, .buffer= { 0 } }; - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst, - f1ap_ue_context_setup_req->gNB_CU_ue_id, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, - f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, - 0xFFFF, // We will set the right value from DU answer - -1, // no qfi - addr, // We will set the right value from DU answer - f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port, - cu_f1u_data_req, - NULL); + 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); @@ -688,11 +637,6 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_ F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); - GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst, - f1ap_ue_context_setup_resp->gNB_DU_ue_id, - (ebi_t)drbs_setup_item_p->dRBID, - drb_p->up_dl_tnl[0].tl_address, - drb_p->up_dl_tnl[0].teid); } } @@ -1182,6 +1126,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte 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; @@ -1191,7 +1136,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte F1AP_DRBs_ToBeSetupMod_Item_t *drbs_toBeSetupMod_item= &drbs_toBeSetupMod_item_ies->value.choice.DRBs_ToBeSetupMod_Item; /* dRBID */ - drbs_toBeSetupMod_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id; + drbs_toBeSetupMod_item->dRBID = drb->drb_id; /* qoSInformation */ if(f1ap_ue_context_modification_req->QoS_information_type == EUTRAN_QoS){ @@ -1235,99 +1180,12 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte 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 */ - { - /* qoS_Characteristics */ - f1ap_qos_flow_level_qos_parameters_t *drb_qos_in = &drb_info_in->drb_qos; - { - int some_decide_qoS_characteristics = drb_qos_in->qos_characteristics.qos_type; - - f1ap_qos_characteristics_t *drb_qos_char_in = &drb_qos_in->qos_characteristics; - if (some_decide_qoS_characteristics == non_dynamic) { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI, tmp); - - /* 5QI */ - tmp->fiveQI = drb_qos_char_in->non_dynamic.fiveqi; - } else { - DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI; - asn1cCalloc(DRB_Information->dRB_QoS.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 */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L); - } - - /* OPTIONAL */ - /* averagingWindow */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L); - } - - /* OPTIONAL */ - /* maxDataBurstVolume */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L); - } - } // if some_decide_qoS_characteristics - - } // qoS_Characteristics - /* nGRANallocationRetentionPriority */ - { - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.priorityLevel = - drb_qos_in->alloc_reten_priority.priority_level; - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionCapability = - drb_qos_in->alloc_reten_priority.preemption_capability; - DRB_Information->dRB_QoS.nGRANallocationRetentionPriority.pre_emptionVulnerability = - drb_qos_in->alloc_reten_priority.preemption_vulnerability; - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(DRB_Information->dRB_QoS.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 */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - } - - /* OPTIONAL */ - /* maxPacketLossRateUplink */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } - } - - /* OPTIONAL */ - /* reflective_QoS_Attribute */ - if (0) { - asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L); - } - } // dRB_QoS - /* 12.1.2.2 sNSSAI */ - { - /* sST */ - OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, (char *)&f1ap_ue_context_modification_req->drbs_to_be_setup[i].nssai.sst, 1); + f1ap_write_drb_qos_param(&drb_info_in->drb_qos, &DRB_Information->dRB_QoS); - /* OPTIONAL */ - const uint32_t sd = (f1ap_ue_context_modification_req->drbs_to_be_setup[i].nssai.sd & 0xffffff); - if (sd != 0xffffff) - OCTET_STRING_fromBuf(DRB_Information->sNSSAI.sD, (char *)&sd, 3); - } + /* 12.1.2.2 sNSSAI */ + f1ap_write_drb_nssai(&drb->nssai, &DRB_Information->sNSSAI); /* OPTIONAL */ /* 12.1.2.3 notificationControl */ @@ -1337,102 +1195,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte } /* 12.1.2.4 flows_Mapped_To_DRB_List */ - for (int k = 0; k < drb_info_in->flows_to_be_setup_length; k++) { - asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list, - F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item); - - f1ap_flows_mapped_to_drb_t *qos_flow_in = drb_info_in->flows_mapped_to_drb + k; - - /* qoSFlowIndicator */ - flows_mapped_to_drb_item->qoSFlowIdentifier = qos_flow_in->qfi; - /* qoSFlowLevelQoSParameters */ - { - f1ap_qos_flow_level_qos_parameters_t *flow_qos_params_in = &qos_flow_in->qos_params; - /* qoS_Characteristics */ - { - int some_decide_qoS_characteristics = flow_qos_params_in->qos_characteristics.qos_type; - F1AP_QoS_Characteristics_t *QosParams = &flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics; - f1ap_qos_characteristics_t *flow_qos_char_in = &flow_qos_params_in->qos_characteristics; - - if (some_decide_qoS_characteristics == 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 */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp); - *tmp = 1L; - } - - /* OPTIONAL */ - /* averagingWindow */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp); - *tmp = 1L; - } - - /* OPTIONAL */ - /* maxDataBurstVolume */ - if (0) { - asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp); - *tmp= 1L; - } - } // if some_decide_qoS_characteristics - - } // qoS_Characteristics - /* nGRANallocationRetentionPriority */ - { - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = - flow_qos_params_in->alloc_reten_priority.priority_level; - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = - flow_qos_params_in->alloc_reten_priority.preemption_capability; - flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = - flow_qos_params_in->alloc_reten_priority.preemption_vulnerability; - } // nGRANallocationRetentionPriority - - /* OPTIONAL */ - /* gBR_QoS_Flow_Information */ - if (0) { - asn1cCalloc(flows_mapped_to_drb_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 */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L); - } - - /* OPTIONAL */ - /* maxPacketLossRateUplink */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L); - } - } - - /* OPTIONAL */ - /* reflective_QoS_Attribute */ - if (0) { - asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L); - } - } // qoSFlowLevelQoSParameters - } + 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 @@ -1569,9 +1332,6 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte &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; - newGtpuDeleteOneTunnel(getCxt(0)->gtpInst, - f1ap_ue_context_modification_req->gNB_CU_ue_id, - f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id); } } @@ -1644,11 +1404,6 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); - GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst, - f1ap_ue_context_modification_resp->gNB_CU_ue_id, - (ebi_t)drbs_setupmod_item_p->dRBID, - drb_p->up_dl_tnl[0].tl_address, - drb_p->up_dl_tnl[0].teid); } } // SRBs_FailedToBeSetupMod_List diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index 3a2f7ce7250bec848674cfb23442b92b3542f6f2..4a3526dd0a659b2c1f940cc28095b343ef8994e1 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -50,7 +50,6 @@ #include "asn1_msg.h" #include "intertask_interface.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" -#include <openair3/ocp-gtpu/gtp_itf.h> #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" @@ -83,7 +82,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id /* strange: it is not named OLD_GNB_DU_UE... */ old_gNB_DU_ue_id_stack = ie->value.choice.GNB_DU_UE_F1AP_ID_1; old_gNB_DU_ue_id = &old_gNB_DU_ue_id_stack; - gtpv1u_update_ue_id(getCxt(instance)->gtpInst, old_gNB_DU_ue_id_stack, du_ue_f1ap_id); } /* mandatory */ diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index d823a350925a817a2e12a1ca235599c22e301977..c2f690107c3e146c8db7c3d0934e1c857009e54c 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -40,6 +40,16 @@ //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t DUuniqInstance=0; +static instance_t du_create_gtpu_instance_to_cu(const f1ap_net_config_t *nc) +{ + openAddr_t tmp = {0}; + strncpy(tmp.originHost, nc->DU_f1_ip_address.ipv4_address, sizeof(tmp.originHost) - 1); + strncpy(tmp.destinationHost, nc->CU_f1_ip_address.ipv4_address, sizeof(tmp.destinationHost) - 1); + sprintf(tmp.originService, "%d", nc->DUport); + sprintf(tmp.destinationService, "%d", nc->CUport); + return gtpv1Init(tmp); +} + void du_task_send_sctp_association_req(instance_t instance, f1ap_net_config_t *nc) { DevAssert(nc != NULL); @@ -116,6 +126,10 @@ void *F1AP_DU_task(void *arg) { f1ap_net_config_t *nc = &F1AP_DU_REGISTER_REQ(msg).net_config; createF1inst(myInstance, msgSetup, nc); du_task_send_sctp_association_req(myInstance, nc); + instance_t gtpInst = du_create_gtpu_instance_to_cu(nc); + AssertFatal(gtpInst != 0, "cannot create DU F1-U GTP module\n"); + getCxt(myInstance)->gtpInst = gtpInst; + DUuniqInstance = gtpInst; } break; case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE: diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index e306463b667ac6ee5d62d345ac57d74f29d33313..3715c0ae5def2ed156e74a80494a9e3775b2ad45 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -37,25 +37,82 @@ #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" #include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h" -#include <openair3/ocp-gtpu/gtp_itf.h> #include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h" -bool DURecvCb(protocol_ctxt_t *ctxt_pP, - const srb_flag_t srb_flagP, - const rb_id_t rb_idP, - const mui_t muiP, - const confirm_t confirmP, - const sdu_size_t sdu_buffer_sizeP, - unsigned char *const sdu_buffer_pP, - const pdcp_transmission_mode_t modeP, - const uint32_t *sourceL2Id, - const uint32_t *destinationL2Id) +static void f1ap_read_drb_qos_param(const F1AP_QoSFlowLevelQoSParameters_t *asn1_qos, f1ap_qos_flow_level_qos_parameters_t *drb_qos) { - // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue - uint8_t *sdu = malloc16(sdu_buffer_sizeP); - memcpy(sdu, sdu_buffer_pP, sdu_buffer_sizeP); - du_rlc_data_req(ctxt_pP, srb_flagP, false, rb_idP, muiP, confirmP, sdu_buffer_sizeP, sdu); - return true; + 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) + memcpy((uint8_t *)&nssai->sd, asn1_nssai->sD->buf, 3); } int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu) @@ -159,6 +216,36 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_i drb_p->rlc_mode = RLC_MODE_TM; 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); + } + } + } } } @@ -305,6 +392,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set ie7->criticality = F1AP_Criticality_ignore; ie7->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List; for (int i=0; i< resp->drbs_to_be_setup_length; i++) { + f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i]; // asn1cSequenceAdd(ie7->value.choice.DRBs_Setup_List.list, F1AP_DRBs_Setup_ItemIEs_t, drbs_setup_item_ies); @@ -315,14 +403,17 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set /* ADD */ F1AP_DRBs_Setup_Item_t *drbs_setup_item=&drbs_setup_item_ies->value.choice.DRBs_Setup_Item; /* dRBID */ - drbs_setup_item->dRBID = resp->drbs_to_be_setup[i].drb_id; + drbs_setup_item->dRBID = drb->drb_id; /* OPTIONAL */ /* lCID */ //drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t)); //drbs_setup_item.lCID = 1L; - for (int j=0; j<resp->drbs_to_be_setup[i].up_dl_tnl_length; j++) { + for (int j = 0; j < drb->up_dl_tnl_length; j++) { + const f1ap_up_tnl_t *tnl = &drb->up_dl_tnl[j]; + DevAssert(tnl->teid > 0); + /* ADD */ asn1cSequenceAdd(drbs_setup_item->dLUPTNLInformation_ToBeSetup_List.list, F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item); @@ -330,12 +421,9 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set /* gTPTunnel */ asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); /* transportLayerAddress */ - struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, - &gTPTunnel->transportLayerAddress); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ - INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID); } // for j } // for i @@ -772,16 +860,6 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, f1ap_ue_context_r return 0; } -static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, char *DUaddr, uint16_t DUport) -{ - openAddr_t tmp = {0}; - strncpy(tmp.originHost, DUaddr, sizeof(tmp.originHost)-1); - strncpy(tmp.destinationHost, CUaddr, sizeof(tmp.destinationHost)-1); - sprintf(tmp.originService, "%d", DUport); - sprintf(tmp.destinationService, "%d", CUport); - return gtpv1Init(tmp); -} - 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; @@ -853,27 +931,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t // 3GPP assumes GTP-U is on port 2152, but OAI is configurable drb_p->up_ul_tnl[0].port = getCxt(instance)->net_config.CUport; - extern instance_t DUuniqInstance; - if (DUuniqInstance == 0) { - char gtp_tunnel_ip_address[32]; - snprintf(gtp_tunnel_ip_address, - sizeof(gtp_tunnel_ip_address), - "%d.%d.%d.%d", - drb_p->up_ul_tnl[0].tl_address & 0xff, - (drb_p->up_ul_tnl[0].tl_address >> 8) & 0xff, - (drb_p->up_ul_tnl[0].tl_address >> 16) & 0xff, - (drb_p->up_ul_tnl[0].tl_address >> 24) & 0xff); - getCxt(instance)->gtpInst = du_create_gtpu_instance_to_cu(gtp_tunnel_ip_address, - getCxt(instance)->net_config.CUport, - getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address, - getCxt(instance)->net_config.DUport); - AssertFatal(getCxt(instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener"); - // Fixme: fully inconsistent instances management - // dirty global var is a bad fix - extern instance_t legacyInstanceMapping; - legacyInstanceMapping = DUuniqInstance = getCxt(instance)->gtpInst; - } - switch (drbs_tobesetupmod_item_p->rLCMode) { case F1AP_RLCMode_rlc_am: drb_p->rlc_mode = RLC_MODE_AM; @@ -894,101 +951,22 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t (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) { - F1AP_DRB_Information_t *dRB_Info = &ie->value.choice.DRB_Information; - f1ap_drb_information_t *drb_info = &f1ap_ue_context_modification_req->drbs_to_be_setup->drb_info; - - /* 12.1.2.1 dRB_QoS */ - { - /* QoS-Flow-Level-QoS-Parameters */ - f1ap_qos_flow_level_qos_parameters_t *drb_qos = &drb_info->drb_qos; - F1AP_QoSFlowLevelQoSParameters_t *dRB_QoS = &dRB_Info->dRB_QoS; - { - /* QoS Characteristics*/ - f1ap_qos_characteristics_t *drb_qos_char = &drb_qos->qos_characteristics; - F1AP_QoS_Characteristics_t *dRB_QoS_Char = &dRB_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 = dRB_QoS->nGRANallocationRetentionPriority.priorityLevel; - drb_qos->alloc_reten_priority.preemption_vulnerability = - dRB_QoS->nGRANallocationRetentionPriority.pre_emptionVulnerability; - drb_qos->alloc_reten_priority.preemption_capability = - dRB_QoS->nGRANallocationRetentionPriority.pre_emptionVulnerability; - } // dRB_QoS + + 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"); - - for (int k = 0; k < drb_p->drb_info.flows_to_be_setup_length; k++) { - f1ap_flows_mapped_to_drb_t *flows_mapped_to_drb = drb_info->flows_mapped_to_drb + k; - F1AP_Flows_Mapped_To_DRB_Item_t *flows_Mapped_To_Drb = dRB_Info->flows_Mapped_To_DRB_List.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; - F1AP_QoSFlowLevelQoSParameters_t *Flow_QoS = &flows_Mapped_To_Drb->qoSFlowLevelQoSParameters; - - /* QoS Characteristics*/ - { - f1ap_qos_characteristics_t *flow_qos_char = &flow_qos->qos_characteristics; - 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; - } - } + 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 */ - OCTET_STRING_TO_INT8(&dRB_Info->sNSSAI.sST, drb_p->nssai.sst); - if (dRB_Info->sNSSAI.sD != NULL) - memcpy((uint8_t *)&drb_p->nssai.sd, dRB_Info->sNSSAI.sD->buf, 3); - else - drb_p->nssai.sd = 0xffffff; + f1ap_read_drb_nssai(&dRB_Info->sNSSAI, &drb_p->nssai); } } } @@ -1008,7 +986,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t 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; - newGtpuDeleteOneTunnel(0, f1ap_ue_context_modification_req->gNB_DU_ue_id, f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id); } } @@ -1166,20 +1143,8 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_cont drbs_setupmod_item->dRBID = resp->drbs_to_be_setup[i].drb_id; for (int j=0; j<resp->drbs_to_be_setup[i].up_dl_tnl_length; j++) { - f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i]; - transport_layer_addr_t tl_addr = {0}; - memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address)); - tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8; - drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst, - resp->gNB_DU_ue_id, - drb->drb_id, - drb->drb_id, - drb->up_ul_tnl[j].teid, - -1, // no qfi - tl_addr, - drb->up_ul_tnl[0].port, - DURecvCb, - NULL); + const f1ap_up_tnl_t *tnl = &resp->drbs_to_be_setup[i].up_dl_tnl[j]; + DevAssert(tnl->teid > 0); /* ADD */ asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list, @@ -1188,12 +1153,9 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_cont /* gTPTunnel */ asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel); /* transportLayerAddress */ - struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); - TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, - &gTPTunnel->transportLayerAddress); + TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ - INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); + INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID); } // for j } // for i } 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 04f2c2fdc918e6e011542dde55ecd7f1f788d3cd..d537865de5b66fb4850e6a182d85f08dd740df92 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -23,8 +23,11 @@ #include "mac_proto.h" #include "openair2/F1AP/f1ap_ids.h" +#include "openair2/F1AP/f1ap_common.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "F1AP_CauseRadioNetwork.h" +#include "openair3/ocp-gtpu/gtp_itf.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h" #include "uper_decoder.h" #include "uper_encoder.h" @@ -34,6 +37,59 @@ const uint64_t qos_fiveqi[26] = {1, 2, 3, 4, 65, 66, 67, 71, 72, 73, 74, 76, 5, const uint64_t qos_priority[26] = {20, 40, 30, 50, 7, 20, 15, 56, 56, 56, 56, 56, 10, 60, 70, 80, 90, 5, 55, 65, 68, 19, 22, 24, 21, 18}; +static instance_t get_f1_gtp_instance(void) +{ + const f1ap_cudu_inst_t *inst = getCxt(0); + if (!inst) + return -1; // means no F1 + return inst->gtpInst; +} + +static int drb_gtpu_create(instance_t instance, + uint32_t ue_id, + int incoming_id, + int outgoing_id, + int qfi, + in_addr_t tlAddress, // only IPv4 now + teid_t outgoing_teid, + gtpCallback callBack, + gtpCallbackSDAP callBackSDAP, + gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp) +{ + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0}; + create_tunnel_req.incoming_rb_id[0] = incoming_id; + create_tunnel_req.pdusession_id[0] = outgoing_id; + memcpy(&create_tunnel_req.dst_addr[0].buffer, &tlAddress, sizeof(uint8_t) * 4); + create_tunnel_req.dst_addr[0].length = 32; + create_tunnel_req.outgoing_teid[0] = outgoing_teid; + create_tunnel_req.outgoing_qfi[0] = qfi; + create_tunnel_req.num_tunnels = 1; + create_tunnel_req.ue_id = ue_id; + + // we use gtpv1u_create_ngu_tunnel because it returns the interface + // address and port of the interface; apart from that, we also might call + // newGtpuCreateTunnel() directly + return gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, callBack, callBackSDAP); +} + +bool DURecvCb(protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_sizeP, + unsigned char *const sdu_buffer_pP, + const pdcp_transmission_mode_t modeP, + const uint32_t *sourceL2Id, + const uint32_t *destinationL2Id) +{ + // The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue + uint8_t *sdu = malloc16(sdu_buffer_sizeP); + memcpy(sdu, sdu_buffer_pP, sdu_buffer_sizeP); + du_rlc_data_req(ctxt_pP, srb_flagP, false, rb_idP, muiP, confirmP, sdu_buffer_sizeP, sdu); + return true; +} + static long get_lcid_from_drbid(int drb_id) { return drb_id + 3; /* LCID is DRB + 3 */ @@ -133,6 +189,7 @@ static int handle_ue_context_drbs_setup(int rnti, NR_CellGroupConfig_t *cellGroupConfig) { DevAssert(req_drbs != NULL && resp_drbs != NULL && cellGroupConfig != NULL); + instance_t f1inst = get_f1_gtp_instance(); /* Note: the actual GTP tunnels are created in the F1AP breanch of * ue_context_*_response() */ @@ -140,12 +197,32 @@ static int handle_ue_context_drbs_setup(int rnti, 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]; + f1ap_drb_to_be_setup_t *resp_drb = &(*resp_drbs)[i]; NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb); nr_rlc_add_drb(rnti, drb->drb_id, rlc_BearerConfig); - (*resp_drbs)[i] = *drb; + *resp_drb = *drb; // just put same number of tunnels in DL as in UL - (*resp_drbs)[i].up_dl_tnl_length = drb->up_ul_tnl_length; + DevAssert(drb->up_ul_tnl_length == 1); + resp_drb->up_dl_tnl_length = drb->up_ul_tnl_length; + + 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, + rnti, + drb->drb_id, + drb->drb_id, + qfi, + drb->up_ul_tnl[0].tl_address, + drb->up_ul_tnl[0].teid, + DURecvCb, + NULL, + &resp_f1); + AssertFatal(ret >= 0, "Unable to create GTP Tunnel for F1-U\n"); + memcpy(&resp_drb->up_dl_tnl[0].tl_address, &resp_f1.gnb_addr.buffer, 4); + resp_drb->up_dl_tnl[0].teid = resp_f1.gnb_NGu_teid[0]; + } int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); DevAssert(ret == 0); @@ -159,6 +236,7 @@ static int handle_ue_context_drbs_release(int rnti, NR_CellGroupConfig_t *cellGroupConfig) { DevAssert(req_drbs != NULL && cellGroupConfig != NULL); + instance_t f1inst = get_f1_gtp_instance(); cellGroupConfig->rlc_BearerToReleaseList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToReleaseList)); AssertFatal(cellGroupConfig->rlc_BearerToReleaseList != NULL, "out of memory\n"); @@ -178,6 +256,8 @@ static int handle_ue_context_drbs_release(int rnti, } if (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) { nr_rlc_release_entity(rnti, lcid); + if (f1inst >= 0) + newGtpuDeleteOneTunnel(f1inst, rnti, drb->rb_id); asn_sequence_del(&cellGroupConfig->rlc_BearerToAddModList->list, idx, 1); long *plcid = malloc(sizeof(*plcid)); AssertFatal(plcid != NULL, "out of memory\n"); @@ -557,6 +637,10 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd) return; } + instance_t f1inst = get_f1_gtp_instance(); + if (f1inst >= 0) + newGtpuDeleteAllTunnels(f1inst, cmd->gNB_DU_ue_id); + if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) { /* The UE is already not connected anymore or we have nothing to forward*/ nr_mac_release_ue(mac, cmd->gNB_DU_ue_id); @@ -632,6 +716,9 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) pthread_mutex_unlock(&mac->sched_lock); nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id); nr_rlc_update_rnti(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); + instance_t f1inst = get_f1_gtp_instance(); + if (f1inst >= 0) // we actually use F1-U + gtpv1u_update_ue_id(f1inst, *dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); } /* the DU ue id is the RNTI */