diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index ea879e93b4..ea6c8b860e 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -43,6 +43,7 @@ #define NR_NB_REG_PER_CCE 6 #define NR_NB_SC_PER_RB 12 #define NR_MAX_NUM_LCID 32 +#define NR_MAX_NUM_QFI 64 typedef enum { nr_FR1 = 0, diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index c50efd337f..966489c11a 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -118,17 +118,39 @@ typedef struct drb_to_setup_s { cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS]; } drb_to_setup_t; -typedef struct qos_flow_to_setup_s { - long id; - fiveQI_type_t fiveQI_type; - long fiveQI; - long qoSPriorityLevel; - long packetDelayBudget; - long packetError_scalar; - long packetError_exponent; - long priorityLevel; - long pre_emptionCapability; - long pre_emptionVulnerability; +typedef struct qos_characteristics_s { + union { + struct { + long fiveqi; + long qos_priority_level; + } non_dynamic; + struct { + long fiveqi; // -1 -> optional + long qos_priority_level; + long packet_delay_budget; + struct { + long per_scalar; + long per_exponent; + } packet_error_rate; + } dynamic; + }; + fiveQI_type_t qos_type; +} qos_characteristics_t; + +typedef struct ngran_allocation_retention_priority_s { + uint16_t priority_level; + long preemption_capability; + long preemption_vulnerability; +} ngran_allocation_retention_priority_t; + +typedef struct qos_flow_level_qos_parameters_s { + qos_characteristics_t qos_characteristics; + ngran_allocation_retention_priority_t alloc_reten_priority; // additional members should be added!! +} qos_flow_level_qos_parameters_t; + +typedef struct qos_flow_setup_e { + long qfi; // qos flow identifier + qos_flow_level_qos_parameters_t qos_params; } qos_flow_to_setup_t; typedef struct DRB_nGRAN_to_setup_s { @@ -198,7 +220,7 @@ typedef struct e1ap_bearer_release_cplt_s { } e1ap_bearer_release_cplt_t; typedef struct qos_flow_setup_s { - long id; + long qfi; } qos_flow_setup_t; typedef struct DRB_nGRAN_setup_s { diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index d7d46f3bef..c0d5c1b437 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -284,12 +284,64 @@ typedef struct f1ap_up_tnl_s { uint16_t port; } f1ap_up_tnl_t; +typedef enum preemption_capability_e { + SHALL_NOT_TRIGGER_PREEMPTION, + MAY_TRIGGER_PREEMPTION, +} preemption_capability_t; + +typedef enum preemption_vulnerability_e { + NOT_PREEMPTABLE, + PREEMPTABLE, +} preemption_vulnerability_t; + +typedef struct f1ap_qos_characteristics_s { + union { + struct { + long fiveqi; + long qos_priority_level; + } non_dynamic; + struct { + long fiveqi; // -1 -> optional + long qos_priority_level; + long packet_delay_budget; + struct { + long per_scalar; + long per_exponent; + } packet_error_rate; + } dynamic; + }; + fiveQI_type_t qos_type; +} f1ap_qos_characteristics_t; + +typedef struct f1ap_ngran_allocation_retention_priority_s { + uint16_t priority_level; + preemption_capability_t preemption_capability; + preemption_vulnerability_t preemption_vulnerability; +} f1ap_ngran_allocation_retention_priority_t; + +typedef struct f1ap_qos_flow_level_qos_parameters_s { + f1ap_qos_characteristics_t qos_characteristics; + f1ap_ngran_allocation_retention_priority_t alloc_reten_priority; +} f1ap_qos_flow_level_qos_parameters_t; + +typedef struct f1ap_flows_mapped_to_drb_s { + long qfi; // qos flow identifier + f1ap_qos_flow_level_qos_parameters_t qos_params; +} f1ap_flows_mapped_to_drb_t; + +typedef struct f1ap_drb_information_s { + f1ap_qos_flow_level_qos_parameters_t drb_qos; + f1ap_flows_mapped_to_drb_t *flows_mapped_to_drb; + uint8_t flows_to_be_setup_length; +} f1ap_drb_information_t; + typedef struct f1ap_drb_to_be_setup_s { long drb_id; f1ap_up_tnl_t up_ul_tnl[2]; uint8_t up_ul_tnl_length; f1ap_up_tnl_t up_dl_tnl[2]; uint8_t up_dl_tnl_length; + f1ap_drb_information_t drb_info; rlc_mode_t rlc_mode; nssai_t nssai; } f1ap_drb_to_be_setup_t; diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 25889468f2..66b8719cc8 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -150,14 +150,14 @@ typedef enum ngap_priority_level_s { } ngap_priority_level_t; typedef enum ngap_pre_emp_capability_e { - NGAP_PRE_EMPTION_CAPABILITY_ENABLED = 0, - NGAP_PRE_EMPTION_CAPABILITY_DISABLED = 1, + NGAP_PRE_EMPTION_CAPABILITY_SHALL_NOT_TRIGGER_PREEMPTION = 0, + NGAP_PRE_EMPTION_CAPABILITY_MAY_TRIGGER_PREEMPTION = 1, NGAP_PRE_EMPTION_CAPABILITY_MAX, } ngap_pre_emp_capability_t; typedef enum ngap_pre_emp_vulnerability_e { - NGAP_PRE_EMPTION_VULNERABILITY_ENABLED = 0, - NGAP_PRE_EMPTION_VULNERABILITY_DISABLED = 1, + NGAP_PRE_EMPTION_VULNERABILITY_NOT_PREEMPTABLE = 0, + NGAP_PRE_EMPTION_VULNERABILITY_PREEMPTABLE = 1, NGAP_PRE_EMPTION_VULNERABILITY_MAX, } ngap_pre_emp_vulnerability_t; @@ -202,6 +202,7 @@ typedef struct nssai_s { typedef struct pdusession_level_qos_parameter_s { uint8_t qfi; uint64_t fiveQI; + uint64_t qos_priority; fiveQI_type_t fiveQI_type; ngap_allocation_retention_priority_t allocation_retention_priority; } pdusession_level_qos_parameter_t; diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 077c67ca98..3d32d90d4d 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -655,24 +655,28 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear for (qos_flow_to_setup_t *k=j->qosFlows; k < j->qosFlows+j->numQosFlow2Setup; k++) { asn1cSequenceAdd(ieC6_1_1->qos_flow_Information_To_Be_Setup, E1AP_QoS_Flow_QoS_Parameter_Item_t, ieC6_1_1_1); - ieC6_1_1_1->qoS_Flow_Identifier = k->id; + ieC6_1_1_1->qoS_Flow_Identifier = k->qfi; - if (k->fiveQI_type == non_dynamic) { // non Dynamic 5QI + qos_characteristics_t *qos_char_in = &k->qos_params.qos_characteristics; + if (qos_char_in->qos_type == non_dynamic) { // non Dynamic 5QI ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.present = E1AP_QoS_Characteristics_PR_non_Dynamic_5QI; asn1cCalloc(ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI, non_Dynamic_5QI); - non_Dynamic_5QI->fiveQI = k->fiveQI; + non_Dynamic_5QI->fiveQI = qos_char_in->non_dynamic.fiveqi; } else { // dynamic 5QI ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.present = E1AP_QoS_Characteristics_PR_dynamic_5QI; asn1cCalloc(ieC6_1_1_1->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI, dynamic_5QI); - dynamic_5QI->qoSPriorityLevel = k->qoSPriorityLevel; - dynamic_5QI->packetDelayBudget = k->packetDelayBudget; - dynamic_5QI->packetErrorRate.pER_Scalar = k->packetError_scalar; - dynamic_5QI->packetErrorRate.pER_Exponent = k->packetError_exponent; + dynamic_5QI->qoSPriorityLevel = qos_char_in->dynamic.qos_priority_level; + dynamic_5QI->packetDelayBudget = qos_char_in->dynamic.packet_delay_budget; + dynamic_5QI->packetErrorRate.pER_Scalar = qos_char_in->dynamic.packet_error_rate.per_scalar; + dynamic_5QI->packetErrorRate.pER_Exponent = qos_char_in->dynamic.packet_error_rate.per_exponent; } - ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = k->priorityLevel; - ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = k->pre_emptionCapability; - ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = k->pre_emptionVulnerability; + ngran_allocation_retention_priority_t *rent_priority_in = &k->qos_params.alloc_reten_priority; + ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel = rent_priority_in->priority_level; + ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability = + rent_priority_in->preemption_capability; + ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = + rent_priority_in->preemption_vulnerability; } } } @@ -775,7 +779,7 @@ static void fill_BEARER_CONTEXT_SETUP_RESPONSE(const e1ap_bearer_setup_resp_t *r for (const qos_flow_setup_t *k=j->qosFlows; k < j->qosFlows+j->numQosFlowSetup; k++) { asn1cSequenceAdd(ieC3_1_1->flow_Setup_List.list, E1AP_QoS_Flow_Item_t, ieC3_1_1_1); - ieC3_1_1_1->qoS_Flow_Identifier = k->id; + ieC3_1_1_1->qoS_Flow_Identifier = k->qfi; } } @@ -953,27 +957,32 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, E1AP_QoS_Flow_QoS_Parameter_List_t *qos2SetupList = &drb2Setup->qos_flow_Information_To_Be_Setup; drb->numQosFlow2Setup = qos2SetupList->list.count; for (int k=0; k < qos2SetupList->list.count; k++) { - qos_flow_to_setup_t *qos = drb->qosFlows + k; + qos_flow_to_setup_t *qos_flow = drb->qosFlows + k; E1AP_QoS_Flow_QoS_Parameter_Item_t *qos2Setup = qos2SetupList->list.array[k]; - qos->id = qos2Setup->qoS_Flow_Identifier; + qos_flow->qfi = qos2Setup->qoS_Flow_Identifier; + qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics; if (qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.present == E1AP_QoS_Characteristics_PR_non_Dynamic_5QI) { - qos->fiveQI_type = non_dynamic; - qos->fiveQI = qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI; + qos_char->qos_type = non_dynamic; + qos_char->non_dynamic.fiveqi = + qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.non_Dynamic_5QI->fiveQI; } else { E1AP_Dynamic5QIDescriptor_t *dynamic5QI = qos2Setup->qoSFlowLevelQoSParameters.qoS_Characteristics.choice.dynamic_5QI; - qos->fiveQI_type = dynamic; - qos->qoSPriorityLevel = dynamic5QI->qoSPriorityLevel; - qos->packetDelayBudget = dynamic5QI->packetDelayBudget; - qos->packetError_scalar = dynamic5QI->packetErrorRate.pER_Scalar; - qos->packetError_exponent = dynamic5QI->packetErrorRate.pER_Exponent; + qos_char->qos_type = dynamic; + qos_char->dynamic.qos_priority_level = dynamic5QI->qoSPriorityLevel; + qos_char->dynamic.packet_delay_budget = dynamic5QI->packetDelayBudget; + qos_char->dynamic.packet_error_rate.per_scalar = dynamic5QI->packetErrorRate.pER_Scalar; + qos_char->dynamic.packet_error_rate.per_exponent = dynamic5QI->packetErrorRate.pER_Exponent; } - qos->priorityLevel = qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel; - qos->pre_emptionCapability = qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability; - qos->pre_emptionVulnerability = qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability; + ngran_allocation_retention_priority_t *rent_priority = &qos_flow->qos_params.alloc_reten_priority; + rent_priority->priority_level = qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel; + rent_priority->preemption_capability = + qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability; + rent_priority->preemption_vulnerability = + qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability; } } } @@ -1076,6 +1085,14 @@ void extract_BEARER_CONTEXT_SETUP_RESPONSE(const E1AP_E1AP_PDU_t *pdu, AssertFatal(false, "gTPTunnel information in required\n"); } } + + // Qos Flow Information + drbSetup->numQosFlowSetup = drb->flow_Setup_List.list.count; + for (int q = 0; q < drb->flow_Setup_List.list.count; q++) { + qos_flow_setup_t *qosflowSetup = &drbSetup->qosFlows[q]; + E1AP_QoS_Flow_Item_t *in_qosflowSetup = drb->flow_Setup_List.list.array[q]; + qosflowSetup->qfi = in_qosflowSetup->qoS_Flow_Identifier; + } } } break; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 94cecd6254..08090a1395 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -41,27 +41,28 @@ #include #include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h" -static void setQos(F1AP_NonDynamic5QIDescriptor_t *toFill) { - asn1cCalloc(toFill, tmp); +static void setQos(F1AP_NonDynamic5QIDescriptor_t **toFill) +{ + asn1cCalloc(*toFill, tmp); /* fiveQI */ tmp->fiveQI = 1L; /* OPTIONAL */ /* qoSPriorityLevel */ if (0) { - asn1cCallocOne(toFill->qoSPriorityLevel, 1L); + asn1cCallocOne((*toFill)->qoSPriorityLevel, 1L); } /* OPTIONAL */ /* averagingWindow */ if (0) { - asn1cCallocOne(toFill->averagingWindow, 1L); + asn1cCallocOne((*toFill)->averagingWindow, 1L); } /* OPTIONAL */ /* maxDataBurstVolume */ if (0) { - asn1cCallocOne(toFill->maxDataBurstVolume, 1L); + asn1cCallocOne((*toFill)->maxDataBurstVolume, 1L); } } @@ -271,8 +272,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu 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; - LOG_I(F1AP, "Length of drbs_to_be_setup: %d \n", f1ap_ue_context_setup_req->drbs_to_be_setup_length); + 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++) { // @@ -329,7 +329,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu 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); + 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); @@ -429,7 +429,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu if (some_decide_qoS_characteristics) { QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - setQos(QosParams->choice.non_Dynamic_5QI); + setQos(&QosParams->choice.non_Dynamic_5QI); } else { QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI; asn1cCalloc(QosParams->choice.dynamic_5QI, tmp); @@ -1227,6 +1227,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte else{ /* 12.1.2 DRB_Information */ + f1ap_drb_information_t *drb_info_in = &f1ap_ue_context_modification_req->drbs_to_be_setup->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; @@ -1237,48 +1238,56 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte /* 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 = 0; // BK: Need Check + int some_decide_qoS_characteristics = drb_qos_in->qos_characteristics.qos_type; - if (some_decide_qoS_characteristics) { + 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; - setQos(DRB_Information->dRB_QoS.qoS_Characteristics.choice.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 = 1L; - /* packetDelayBudget */ - tmp->packetDelayBudget = 1L; - /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = 1L; - tmp->packetErrorRate.pER_Exponent = 6L; + 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 */ + /* 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 */ + /* 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 + /* 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 + 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 */ @@ -1327,33 +1336,40 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte F1AP_NotificationControl_active); // enum } - /* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy - - for (int k = 0; k < 1; k ++) { + /* 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 = 1L; + 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 = 0; // BK: Need Check - F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.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) { + if (some_decide_qoS_characteristics == non_dynamic) { QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; - setQos(QosParams->choice.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 = 1L; + tmp->qoSPriorityLevel = flow_qos_char_in->dynamic.qos_priority_level; /* packetDelayBudget */ - tmp->packetDelayBudget = 1L; + tmp->packetDelayBudget = flow_qos_char_in->dynamic.packet_delay_budget; /* packetErrorRate */ - tmp->packetErrorRate.pER_Scalar = 1L; - tmp->packetErrorRate.pER_Exponent = 6L; + 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 */ @@ -1380,9 +1396,12 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte } // 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 + 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 */ diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index fe7b8c78f5..4eee1ba6b1 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -893,11 +893,99 @@ 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_Information = &ie->value.choice.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 + + // 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; + } + } + /* S-NSSAI */ - OCTET_STRING_TO_INT8(&DRB_Information->sNSSAI.sST, drb_p->nssai.sst); - if (DRB_Information->sNSSAI.sD != NULL) - memcpy((uint8_t *)&drb_p->nssai.sd, DRB_Information->sNSSAI.sD->buf, 3); + 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; } 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 5157ff453f..ab6e56f4f1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -30,6 +30,11 @@ #include "uper_decoder.h" #include "uper_encoder.h" +// Standarized 5QI values and Default Priority levels as mentioned in 3GPP TS 23.501 Table 5.7.4-1 +const uint64_t qos_fiveqi[26] = {1, 2, 3, 4, 65, 66, 67, 71, 72, 73, 74, 76, 5, 6, 7, 8, 9, 69, 70, 79, 80, 82, 83, 84, 85, 86}; +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 long get_lcid_from_drbid(int drb_id) { return drb_id + 3; /* LCID is DRB + 3 */ @@ -243,6 +248,49 @@ static void set_nssaiConfig(const int drb_len, const f1ap_drb_to_be_setup_t *req } } +static void set_QoSConfig(const f1ap_ue_context_modif_req_t *req, NR_UE_sched_ctrl_t *sched_ctrl) +{ + AssertFatal(req != NULL, "f1ap_ue_context_modif_req is NULL\n"); + uint8_t drb_count = req->drbs_to_be_setup_length; + uint8_t srb_count = req->srbs_to_be_setup_length; + LOG_I(NR_MAC, "Number of DRBs = %d and SRBs = %d\n", drb_count, srb_count); + + /* DRBs*/ + for (int i = 0; i < drb_count; i++) { + f1ap_drb_to_be_setup_t *drb_p = &req->drbs_to_be_setup[i]; + uint8_t nb_qos_flows = drb_p->drb_info.flows_to_be_setup_length; + long drb_id = drb_p->drb_id; + LOG_I(NR_MAC, "In %s: number of QOS flows mapped to DRB_id %d: %ld \n", __func__, drb_count, drb_id); + + for (int q = 0; q < nb_qos_flows; q++) { + f1ap_flows_mapped_to_drb_t *qos_flow = &drb_p->drb_info.flows_mapped_to_drb[q]; + + f1ap_qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics; + uint64_t priority = qos_char->non_dynamic.qos_priority_level; + int64_t fiveqi = qos_char->non_dynamic.fiveqi; + if (qos_char->qos_type == dynamic) { + priority = qos_char->dynamic.qos_priority_level; + fiveqi = qos_char->dynamic.fiveqi > 0 ? qos_char->dynamic.fiveqi : 0; + } + if (qos_char->qos_type == non_dynamic) { + LOG_D(NR_MAC, "Qos Priority level is considered from the standarsdized 5QI to QoS mapping table\n"); + for (int id = 0; id < 26; id++) { + if (qos_fiveqi[id] == fiveqi) + priority = qos_priority[id]; + } + } + sched_ctrl->qos_config[drb_id - 1][q].fiveQI = fiveqi; + sched_ctrl->qos_config[drb_id - 1][q].priority = priority; + LOG_D(NR_MAC, + "In %s: drb_id %ld: 5QI %lu priority %lu\n", + __func__, + drb_id, + sched_ctrl->qos_config[drb_id - 1][q].fiveQI, + sched_ctrl->qos_config[drb_id - 1][q].priority); + } + } +} + void ue_context_setup_request(const f1ap_ue_context_setup_t *req) { gNB_MAC_INST *mac = RC.nrmac[0]; @@ -309,6 +357,9 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) /* TODO: need to apply after UE context reconfiguration confirmed? */ nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup); + /* Fill the QoS config in MAC for each active DRB */ + set_QoSConfig(req, &UE->UE_sched_ctrl); + /* Set NSSAI config in MAC for each active DRB */ set_nssaiConfig(req->drbs_to_be_setup_length, req->drbs_to_be_setup, &UE->UE_sched_ctrl); @@ -409,6 +460,9 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup); + /* Fill the QoS config in MAC for each active DRB */ + set_QoSConfig(req, &UE->UE_sched_ctrl); + /* Set NSSAI config in MAC for each active DRB */ set_nssaiConfig(req->drbs_to_be_setup_length, req->drbs_to_be_setup, &UE->UE_sched_ctrl); } else { diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index b205abafd0..4a3902eea1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -536,6 +536,11 @@ typedef struct NR_UE_ul_harq { NR_sched_pusch_t sched_pusch; } NR_UE_ul_harq_t; +typedef struct NR_QoS_config_s { + uint64_t fiveQI; + uint64_t priority; +} NR_QoS_config_t; + /*! \brief scheduling control information set through an API */ #define MAX_CSI_REPORTS 48 typedef struct { @@ -635,6 +640,9 @@ typedef struct { /// sri, ul_ri and tpmi based on SRS nr_srs_feedback_t srs_feedback; nssai_t dl_lc_nssai[NR_MAX_NUM_LCID]; + + // Information about the QoS configuration for each LCID/DRB + NR_QoS_config_t qos_config[NR_MAX_NUM_LCID - 4][NR_MAX_NUM_QFI]; // 0 -CCCH and 1- 3 SRBs(0,1,2) } NR_UE_sched_ctrl_t; typedef struct { diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index c9bbc6cd05..412a974406 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -53,8 +53,8 @@ static void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, const asn1cCalloc(sdap_config->mappedQoS_FlowsToAdd, FlowsToAdd); for (int j=0; j < drb->numQosFlow2Setup; j++) { - asn1cSequenceAdd(FlowsToAdd->list, NR_QFI_t, id); - *id = drb->qosFlows[j].id; + asn1cSequenceAdd(FlowsToAdd->list, NR_QFI_t, qfi); + *qfi = drb->qosFlows[j].qfi; } sdap_config->mappedQoS_FlowsToRelease = NULL; @@ -164,8 +164,11 @@ void e1_bearer_context_setup(const e1ap_bearer_setup_req_t *req) DRB_nGRAN_setup_t *resp_drb = &resp_pdu->DRBnGRanList[0]; resp_drb->id = req_drb->id; resp_drb->numQosFlowSetup = req_drb->numQosFlow2Setup; - for (int k = 0; k < resp_drb->numQosFlowSetup; k++) - resp_drb->qosFlows[k].id = req_drb->qosFlows[k].id; + for (int k = 0; k < resp_drb->numQosFlowSetup; k++) { + const qos_flow_to_setup_t *qosflow2Setup = &req_drb->qosFlows[k]; + qos_flow_setup_t *qosflowSetup = &resp_drb->qosFlows[k]; + qosflowSetup->qfi = qosflow2Setup->qfi; + } // GTP tunnel for N3/to core gtpv1u_gnb_create_tunnel_resp_t resp_n3 = {0}; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index dea1494f17..70b18b3409 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2027,6 +2027,17 @@ unsigned int mask_flip(unsigned int x) { return((((x>>8) + (x<<8))&0xffff)>>6); } +static pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi, rrc_pdu_session_param_t *pduSession) +{ + pdusession_t *pdu = &pduSession->param; + for (int i = 0; i < pdu->nb_qos; i++) { + if (qfi == pdu->qos[i].qfi) + return &pdu->qos[i]; + } + AssertFatal(1 == 0, "The pdu session %d does not contain a qos flow with qfi = %d\n", pdu->pdusession_id, qfi); + return NULL; +} + void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp, instance_t instance) { gNB_RRC_INST *rrc = RC.nrrrc[0]; @@ -2060,12 +2071,34 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp rrc_pdu_session_param_t *RRC_pduSession = find_pduSession(UE, resp->pduSession[0].id, false); DevAssert(RRC_pduSession); for (int i = 0; i < nb_drb; i++) { + DRB_nGRAN_setup_t *drb_config = &resp->pduSession[0].DRBnGRanList[i]; drbs[i].drb_id = resp->pduSession[0].DRBnGRanList[i].id; drbs[i].rlc_mode = rrc->configuration.um_on_default_drb ? RLC_MODE_UM : RLC_MODE_AM; - drbs[i].up_ul_tnl[0].tl_address = resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress; + drbs[i].up_ul_tnl[0].tl_address = drb_config->UpParamList[0].tlAddress; drbs[i].up_ul_tnl[0].port = rrc->eth_params_s.my_portd; - drbs[i].up_ul_tnl[0].teid = resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId; + drbs[i].up_ul_tnl[0].teid = drb_config->UpParamList[0].teId; drbs[i].up_ul_tnl_length = 1; + + /* pass QoS info to MAC */ + int nb_qos_flows = drb_config->numQosFlowSetup; + drbs[i].drb_info.flows_to_be_setup_length = nb_qos_flows; + drbs[i].drb_info.flows_mapped_to_drb = (f1ap_flows_mapped_to_drb_t *)calloc(nb_qos_flows, sizeof(f1ap_flows_mapped_to_drb_t)); + AssertFatal(drbs[i].drb_info.flows_mapped_to_drb, "could not allocate memory\n"); + for (int j = 0; j < nb_qos_flows; j++) { + drbs[i].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); + f1ap_qos_characteristics_t *qos_char = &drbs[i].drb_info.flows_mapped_to_drb[j].qos_params.qos_characteristics; + if (in_qos_char->fiveQI_type == dynamic) { + qos_char->qos_type = dynamic; + qos_char->dynamic.fiveqi = in_qos_char->fiveQI; + qos_char->dynamic.qos_priority_level = in_qos_char->qos_priority; + } else { + qos_char->qos_type = non_dynamic; + qos_char->non_dynamic.fiveqi = in_qos_char->fiveQI; + qos_char->non_dynamic.qos_priority_level = in_qos_char->qos_priority; + } + } /* pass NSSAI info to MAC */ drbs[i].nssai = RRC_pduSession->param.nssai; } @@ -2261,7 +2294,11 @@ void *rrc_gnb_task(void *args_p) { itti_receive_msg(TASK_RRC_GNB, &msg_p); const char *msg_name_p = ITTI_MSG_NAME(msg_p); instance = ITTI_MSG_DESTINATION_INSTANCE(msg_p); - LOG_D(NR_RRC, "Received Msg %s\n", msg_name_p); + LOG_D(NR_RRC, + "RRC GNB Task Received %s for instance %ld from task %s\n", + ITTI_MSG_NAME(msg_p), + ITTI_MSG_DESTINATION_INSTANCE(msg_p), + ITTI_MSG_ORIGIN_NAME(msg_p)); switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: LOG_W(NR_RRC, " *** Exiting NR_RRC thread\n"); diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index f6059a91a9..b659ccc2f8 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -68,6 +68,7 @@ #include "NGAP_QosFlowSetupRequestItem.h" #include "NGAP_QosFlowAddOrModifyRequestItem.h" #include "NGAP_NonDynamic5QIDescriptor.h" +#include "NGAP_Dynamic5QIDescriptor.h" #include "conversions.h" #include "RRC/NR/rrc_gNB_radio_bearers.h" @@ -263,10 +264,15 @@ static void fill_qos(NGAP_QosFlowSetupRequestList_t *qos, pdusession_t *session) // Set the QOS informations session->qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; NGAP_QosCharacteristics_t *qosChar = &qosFlowItem_p->qosFlowLevelQosParameters.qosCharacteristics; + AssertFatal(qosChar, "Qos characteristics are not available for qos flow index %d\n", qosIdx); if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) { - if (qosChar->choice.nonDynamic5QI != NULL) { - session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI; - } + AssertFatal(qosChar->choice.dynamic5QI, "Non-Dynamic 5QI is NULL\n"); + session->qos[qosIdx].fiveQI_type = non_dynamic; + session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI; + } else { + AssertFatal(qosChar->choice.dynamic5QI, "Dynamic 5QI is NULL\n"); + session->qos[qosIdx].fiveQI_type = dynamic; + session->qos[qosIdx].fiveQI = (uint64_t)(*qosChar->choice.dynamic5QI->fiveQI); } ngap_allocation_retention_priority_t *tmp = &session->qos[qosIdx].allocation_retention_priority; @@ -820,15 +826,25 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins drb->numQosFlow2Setup = session->nb_qos; for (int k=0; k < drb->numQosFlow2Setup; k++) { - qos_flow_to_setup_t *qos = drb->qosFlows + k; + qos_flow_to_setup_t *qos_flow = drb->qosFlows + k; + pdusession_level_qos_parameter_t *qos_session = session->qos + k; - qos->id = session->qos[k].qfi; - qos->fiveQI = session->qos[k].fiveQI; - qos->fiveQI_type = session->qos[k].fiveQI_type; + qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics; + qos_flow->qfi = qos_session->qfi; + qos_char->qos_type = qos_session->fiveQI_type; + if (qos_char->qos_type == dynamic) { + qos_char->dynamic.fiveqi = qos_session->fiveQI; + qos_char->dynamic.qos_priority_level = qos_session->qos_priority; + } else { + qos_char->non_dynamic.fiveqi = qos_session->fiveQI; + qos_char->non_dynamic.qos_priority_level = qos_session->qos_priority; + } - qos->qoSPriorityLevel = session->qos[k].allocation_retention_priority.priority_level; - qos->pre_emptionCapability = session->qos[k].allocation_retention_priority.pre_emp_capability; - qos->pre_emptionVulnerability = session->qos[k].allocation_retention_priority.pre_emp_vulnerability; + ngran_allocation_retention_priority_t *rent_priority = &qos_flow->qos_params.alloc_reten_priority; + ngap_allocation_retention_priority_t *rent_priority_in = &qos_session->allocation_retention_priority; + rent_priority->priority_level = rent_priority_in->priority_level; + rent_priority->preemption_capability = rent_priority_in->pre_emp_capability; + rent_priority->preemption_vulnerability = rent_priority_in->pre_emp_vulnerability; } } } @@ -854,12 +870,15 @@ static void fill_qos2(NGAP_QosFlowAddOrModifyRequestList_t *qos, pdusession_t *s // Set the QOS informations session->qos[qosIdx].qfi = (uint8_t)qosFlowItem_p->qosFlowIdentifier; NGAP_QosCharacteristics_t *qosChar = &qosFlowItem_p->qosFlowLevelQosParameters->qosCharacteristics; + AssertFatal(qosChar, "Qos characteristics are not available for qos flow index %d\n", qosIdx); if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) { - if (qosChar->choice.nonDynamic5QI != NULL) { - session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI; - } - } else if (qosChar->present == NGAP_QosCharacteristics_PR_dynamic5QI) { - // TODO + AssertFatal(qosChar->choice.dynamic5QI, "Non-Dynamic 5QI is NULL\n"); + session->qos[qosIdx].fiveQI_type = non_dynamic; + session->qos[qosIdx].fiveQI = (uint64_t)qosChar->choice.nonDynamic5QI->fiveQI; + } else { + AssertFatal(qosChar->choice.dynamic5QI, "Dynamic 5QI is NULL\n"); + session->qos[qosIdx].fiveQI_type = dynamic; + session->qos[qosIdx].fiveQI = (uint64_t)(*qosChar->choice.dynamic5QI->fiveQI); } ngap_allocation_retention_priority_t *tmp = &session->qos[qosIdx].allocation_retention_priority;