Commit c8d6edd6 authored by Sriharsha Korada's avatar Sriharsha Korada

Reordering of LCs of a UE based on QoS priorities

parent 3f3a9869
...@@ -126,6 +126,7 @@ typedef struct drb_to_setup_s { ...@@ -126,6 +126,7 @@ typedef struct drb_to_setup_s {
cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS]; cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
} drb_to_setup_t; } drb_to_setup_t;
/*
typedef struct qos_characteristics_s { typedef struct qos_characteristics_s {
union { union {
struct { struct {
...@@ -156,6 +157,8 @@ typedef struct qos_flow_level_qos_parameters_s { ...@@ -156,6 +157,8 @@ typedef struct qos_flow_level_qos_parameters_s {
ngran_allocation_retention_priority_t alloc_reten_priority; // additional members should be added!! ngran_allocation_retention_priority_t alloc_reten_priority; // additional members should be added!!
} qos_flow_level_qos_parameters_t; } qos_flow_level_qos_parameters_t;
*/
typedef struct qos_flow_setup_e { typedef struct qos_flow_setup_e {
long qfi; // qos flow identifier long qfi; // qos flow identifier
qos_flow_level_qos_parameters_t qos_params; qos_flow_level_qos_parameters_t qos_params;
...@@ -179,6 +182,7 @@ typedef struct DRB_nGRAN_to_setup_s { ...@@ -179,6 +182,7 @@ typedef struct DRB_nGRAN_to_setup_s {
cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS]; cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
int numQosFlow2Setup; int numQosFlow2Setup;
qos_flow_to_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS]; qos_flow_to_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS];
qos_flow_level_qos_parameters_t dRB_QoS;
} DRB_nGRAN_to_setup_t; } DRB_nGRAN_to_setup_t;
typedef struct pdu_session_to_setup_s { typedef struct pdu_session_to_setup_s {
......
...@@ -299,7 +299,7 @@ typedef enum preemption_vulnerability_e { ...@@ -299,7 +299,7 @@ typedef enum preemption_vulnerability_e {
PREEMPTABLE, PREEMPTABLE,
} preemption_vulnerability_t; } preemption_vulnerability_t;
typedef struct f1ap_qos_characteristics_s { typedef struct qos_characteristics_s {
union { union {
struct { struct {
long fiveqi; long fiveqi;
...@@ -316,26 +316,26 @@ typedef struct f1ap_qos_characteristics_s { ...@@ -316,26 +316,26 @@ typedef struct f1ap_qos_characteristics_s {
} dynamic; } dynamic;
}; };
fiveQI_type_t qos_type; fiveQI_type_t qos_type;
} f1ap_qos_characteristics_t; } qos_characteristics_t;
typedef struct f1ap_ngran_allocation_retention_priority_s { typedef struct ngran_allocation_retention_priority_s {
uint16_t priority_level; uint16_t priority_level;
preemption_capability_t preemption_capability; preemption_capability_t preemption_capability;
preemption_vulnerability_t preemption_vulnerability; preemption_vulnerability_t preemption_vulnerability;
} f1ap_ngran_allocation_retention_priority_t; } ngran_allocation_retention_priority_t;
typedef struct f1ap_qos_flow_level_qos_parameters_s { typedef struct qos_flow_level_qos_parameters_s {
f1ap_qos_characteristics_t qos_characteristics; qos_characteristics_t qos_characteristics;
f1ap_ngran_allocation_retention_priority_t alloc_reten_priority; ngran_allocation_retention_priority_t alloc_reten_priority;
} f1ap_qos_flow_level_qos_parameters_t; } qos_flow_level_qos_parameters_t;
typedef struct f1ap_flows_mapped_to_drb_s { typedef struct f1ap_flows_mapped_to_drb_s {
long qfi; // qos flow identifier long qfi; // qos flow identifier
f1ap_qos_flow_level_qos_parameters_t qos_params; qos_flow_level_qos_parameters_t qos_params;
} f1ap_flows_mapped_to_drb_t; } f1ap_flows_mapped_to_drb_t;
typedef struct f1ap_drb_information_s { typedef struct f1ap_drb_information_s {
f1ap_qos_flow_level_qos_parameters_t drb_qos; qos_flow_level_qos_parameters_t drb_qos;
f1ap_flows_mapped_to_drb_t *flows_mapped_to_drb; f1ap_flows_mapped_to_drb_t *flows_mapped_to_drb;
uint8_t flows_to_be_setup_length; uint8_t flows_to_be_setup_length;
} f1ap_drb_information_t; } f1ap_drb_information_t;
......
...@@ -707,6 +707,38 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear ...@@ -707,6 +707,38 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear
ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability = ieC6_1_1_1->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability =
rent_priority_in->preemption_vulnerability; rent_priority_in->preemption_vulnerability;
} }
/* DRB qos characteristics */
// optional
E1AP_ProtocolExtensionContainer_4961P45_t *p = calloc(1, sizeof(*p));
ieC6_1_1->iE_Extensions = (struct E1AP_ProtocolExtensionContainer *)p;
asn1cSequenceAdd(p->list, E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs_t, drb_to_setup_item_ng_ran_extIEs);
drb_to_setup_item_ng_ran_extIEs->id = E1AP_ProtocolIE_ID_id_DRB_QoS;
drb_to_setup_item_ng_ran_extIEs->criticality = E1AP_Criticality_reject;
drb_to_setup_item_ng_ran_extIEs->extensionValue.present =
E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs__extensionValue_PR_QoSFlowLevelQoSParameters;
E1AP_QoS_Characteristics_t *drb_QoS_char =
&drb_to_setup_item_ng_ran_extIEs->extensionValue.choice.QoSFlowLevelQoSParameters.qoS_Characteristics;
/* setup DRB priority */
get_drb_characteristics(j->qosFlows,
j->numQosFlow2Setup,
j->qosFlows[0].qos_params.qos_characteristics.qos_type,
&(j->dRB_QoS));
if (j->qosFlows[0].qos_params.qos_characteristics.qos_type == non_dynamic) {
drb_QoS_char->present = E1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
drb_QoS_char->choice.non_Dynamic_5QI->fiveQI = j->dRB_QoS.qos_characteristics.non_dynamic.fiveqi;
} else {
drb_QoS_char->present = E1AP_QoS_Characteristics_PR_dynamic_5QI;
drb_QoS_char->choice.dynamic_5QI->qoSPriorityLevel = j->dRB_QoS.qos_characteristics.dynamic.qos_priority_level;
drb_QoS_char->choice.dynamic_5QI->packetDelayBudget = j->dRB_QoS.qos_characteristics.dynamic.packet_delay_budget;
drb_QoS_char->choice.dynamic_5QI->packetErrorRate.pER_Exponent =
j->dRB_QoS.qos_characteristics.dynamic.packet_error_rate.per_exponent;
drb_QoS_char->choice.dynamic_5QI->packetErrorRate.pER_Scalar =
j->dRB_QoS.qos_characteristics.dynamic.packet_error_rate.per_scalar;
}
/* todo: ngran allocation retention priority for DRB still needs to be implemented */
} }
} }
return 0; return 0;
...@@ -1026,6 +1058,52 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_beare ...@@ -1026,6 +1058,52 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_beare
rent_priority->preemption_vulnerability = rent_priority->preemption_vulnerability =
qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability; qos2Setup->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability;
} }
/* DRB QoS */
if (drb2Setup->iE_Extensions) {
E1AP_ProtocolExtensionContainer_4961P45_t *IE_Ext =
(E1AP_ProtocolExtensionContainer_4961P45_t *)drb2Setup->iE_Extensions;
for (int extid = 0; extid < IE_Ext->list.count; extid++) {
E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs_t *ext = IE_Ext->list.array[extid];
switch (ext->id) {
case E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs__extensionValue_PR_QoSFlowLevelQoSParameters: {
E1AP_QoS_Characteristics_t *drbqos2Setup =
&ext->extensionValue.choice.QoSFlowLevelQoSParameters.qoS_Characteristics;
qos_characteristics_t *drb_qos = &drb->dRB_QoS.qos_characteristics;
if (drbqos2Setup->present == E1AP_QoS_Characteristics_PR_non_Dynamic_5QI) { // non-dynamic
drb_qos->qos_type = non_dynamic;
drb_qos->non_dynamic.fiveqi = drbqos2Setup->choice.non_Dynamic_5QI->fiveQI;
} else if (drbqos2Setup->present == E1AP_QoS_Characteristics_PR_dynamic_5QI) { // dynamic
drb_qos->qos_type = dynamic;
drb_qos->dynamic.qos_priority_level = drbqos2Setup->choice.dynamic_5QI->qoSPriorityLevel;
drb_qos->dynamic.packet_delay_budget = drbqos2Setup->choice.dynamic_5QI->packetDelayBudget;
drb_qos->dynamic.packet_error_rate.per_exponent =
drbqos2Setup->choice.dynamic_5QI->packetErrorRate.pER_Exponent;
drb_qos->dynamic.packet_error_rate.per_scalar = drbqos2Setup->choice.dynamic_5QI->packetErrorRate.pER_Scalar;
}
/* todo: ngran allocation retention priority for DRB still needs to be implemented */
break;
}
case E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs__extensionValue_PR_DAPSRequestInfo:
AssertFatal(1 == 0, "E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs: DAPSRequestInfo not supported yet\n");
break;
case E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs__extensionValue_PR_IgnoreMappingRuleIndication:
AssertFatal(1 == 0, "E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs: IgnoreMappingRuleIndication not supported yet\n");
break;
case E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs__extensionValue_PR_QoS_Flows_DRB_Remapping:
AssertFatal(1 == 0, "E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs: QoS_Flows_DRB_Remapping not supported yet\n");
break;
default:
AssertFatal(1 == 0, "E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs: %d unknown\n", (int)ext->id);
break;
}
}
}
} }
} }
break; break;
......
...@@ -67,5 +67,6 @@ ...@@ -67,5 +67,6 @@
#include <E1AP_PDCP-Configuration.h> #include <E1AP_PDCP-Configuration.h>
#include <E1AP_Slice-Support-List.h> #include <E1AP_Slice-Support-List.h>
#include <E1AP_Slice-Support-Item.h> #include <E1AP_Slice-Support-Item.h>
#include <E1AP_ProtocolExtensionField.h>
#endif #endif
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* For more information about the OpenAirInterface (OAI) Software Alliance: * For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org * contact@openairinterface.org
*/ */
#define _GNU_SOURCE
#include <time.h> #include <time.h>
#include <stdlib.h> #include <stdlib.h>
#include "e1ap_common.h" #include "e1ap_common.h"
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "e1ap_asnc.h" #include "e1ap_asnc.h"
#include "common/openairinterface5g_limits.h" #include "common/openairinterface5g_limits.h"
#include "common/utils/ocp_itti/intertask_interface.h" #include "common/utils/ocp_itti/intertask_interface.h"
#include "common/utils/nr/nr_common.h"
static e1ap_upcp_inst_t *e1ap_inst[NUMBER_OF_gNB_MAX] = {0}; static e1ap_upcp_inst_t *e1ap_inst[NUMBER_OF_gNB_MAX] = {0};
...@@ -243,3 +244,52 @@ int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, E1AP_E1AP_PDU_t *pdu, uin ...@@ -243,3 +244,52 @@ int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, E1AP_E1AP_PDU_t *pdu, uin
return encoded; return encoded;
} }
long get_flow_priority(long fiveqi)
{
for (int id = 0; id < 26; id++) {
if (qos_fiveqi[id] == fiveqi)
return qos_priority[id];
}
AssertFatal(1 == 0, "Invalid 5QI value\n");
}
static int qosflow_cmp(const void *a, const void *b, void *qostype)
{
fiveQI_type_t qos_type = *((fiveQI_type_t *)qostype);
if (qos_type == non_dynamic) { // non-dynamic
long priority1 = get_flow_priority(((qos_flow_to_setup_t *)a)->qos_params.qos_characteristics.non_dynamic.fiveqi);
long priority2 = get_flow_priority(((qos_flow_to_setup_t *)b)->qos_params.qos_characteristics.non_dynamic.fiveqi);
return priority1 - priority2;
} else { // dynamic
long priority1 = ((qos_flow_to_setup_t *)a)->qos_params.qos_characteristics.dynamic.qos_priority_level;
long priority2 = ((qos_flow_to_setup_t *)b)->qos_params.qos_characteristics.dynamic.qos_priority_level;
return priority1 - priority2;
}
}
void get_drb_characteristics(qos_flow_to_setup_t *qos_flows_in,
int num_qos_flows,
fiveQI_type_t qos_type,
qos_flow_level_qos_parameters_t *dRB_QoS)
{
qos_characteristics_t *qos_char_drb = &dRB_QoS->qos_characteristics;
qos_flow_to_setup_t *qos_flow = qos_flows_in;
if (qos_type == non_dynamic) { // non-dynamic
qsort_r(qos_flow, num_qos_flows, sizeof(qos_flow_to_setup_t), qosflow_cmp, (void *)&qos_type);
qos_char_drb->qos_type = non_dynamic;
qos_char_drb->non_dynamic.fiveqi = qos_flow->qos_params.qos_characteristics.non_dynamic.fiveqi;
} else { // dynamic
qsort_r(qos_flow, num_qos_flows, sizeof(qos_flow_to_setup_t), qosflow_cmp, (void *)&qos_type);
qos_char_drb->qos_type = dynamic;
qos_char_drb->dynamic.qos_priority_level = qos_flow->qos_params.qos_characteristics.dynamic.qos_priority_level;
qos_char_drb->dynamic.packet_delay_budget = qos_flow->qos_params.qos_characteristics.dynamic.packet_delay_budget;
qos_char_drb->dynamic.packet_error_rate.per_exponent =
qos_flow->qos_params.qos_characteristics.dynamic.packet_error_rate.per_exponent;
qos_char_drb->dynamic.packet_error_rate.per_scalar =
qos_flow->qos_params.qos_characteristics.dynamic.packet_error_rate.per_scalar;
}
}
...@@ -59,5 +59,12 @@ int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, struct E1AP_E1AP_PDU *pdu ...@@ -59,5 +59,12 @@ int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, struct E1AP_E1AP_PDU *pdu
void e1ap_common_init(); void e1ap_common_init();
void cuup_init_n3(instance_t instance); void cuup_init_n3(instance_t instance);
void get_drb_characteristics(qos_flow_to_setup_t *qos_flows_in,
int num_qos_flows,
fiveQI_type_t qos_type,
qos_flow_level_qos_parameters_t *dRB_QoS);
long get_flow_priority(long fiveqi);
extern const uint64_t qos_fiveqi[];
extern const uint64_t qos_priority[];
#endif /* E1AP_COMMON_H_ */ #endif /* E1AP_COMMON_H_ */
...@@ -1238,11 +1238,11 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte ...@@ -1238,11 +1238,11 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte
/* 12.1.2.1 dRB_QoS */ /* 12.1.2.1 dRB_QoS */
{ {
/* qoS_Characteristics */ /* qoS_Characteristics */
f1ap_qos_flow_level_qos_parameters_t *drb_qos_in = &drb_info_in->drb_qos; 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; 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; qos_characteristics_t *drb_qos_char_in = &drb_qos_in->qos_characteristics;
if (some_decide_qoS_characteristics == non_dynamic) { if (some_decide_qoS_characteristics == non_dynamic) {
DRB_Information->dRB_QoS.qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; 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); asn1cCalloc(DRB_Information->dRB_QoS.qoS_Characteristics.choice.non_Dynamic_5QI, tmp);
...@@ -1347,12 +1347,12 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte ...@@ -1347,12 +1347,12 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte
flows_mapped_to_drb_item->qoSFlowIdentifier = qos_flow_in->qfi; flows_mapped_to_drb_item->qoSFlowIdentifier = qos_flow_in->qfi;
/* qoSFlowLevelQoSParameters */ /* qoSFlowLevelQoSParameters */
{ {
f1ap_qos_flow_level_qos_parameters_t *flow_qos_params_in = &qos_flow_in->qos_params; qos_flow_level_qos_parameters_t *flow_qos_params_in = &qos_flow_in->qos_params;
/* qoS_Characteristics */ /* qoS_Characteristics */
{ {
int some_decide_qoS_characteristics = flow_qos_params_in->qos_characteristics.qos_type; 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 *QosParams = &flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics;
f1ap_qos_characteristics_t *flow_qos_char_in = &flow_qos_params_in->qos_characteristics; qos_characteristics_t *flow_qos_char_in = &flow_qos_params_in->qos_characteristics;
if (some_decide_qoS_characteristics == non_dynamic) { if (some_decide_qoS_characteristics == non_dynamic) {
QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI; QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
......
...@@ -900,11 +900,11 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t ...@@ -900,11 +900,11 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t
/* 12.1.2.1 dRB_QoS */ /* 12.1.2.1 dRB_QoS */
{ {
/* QoS-Flow-Level-QoS-Parameters */ /* QoS-Flow-Level-QoS-Parameters */
f1ap_qos_flow_level_qos_parameters_t *drb_qos = &drb_info->drb_qos; qos_flow_level_qos_parameters_t *drb_qos = &drb_info->drb_qos;
F1AP_QoSFlowLevelQoSParameters_t *dRB_QoS = &dRB_Info->dRB_QoS; F1AP_QoSFlowLevelQoSParameters_t *dRB_QoS = &dRB_Info->dRB_QoS;
{ {
/* QoS Characteristics*/ /* QoS Characteristics*/
f1ap_qos_characteristics_t *drb_qos_char = &drb_qos->qos_characteristics; qos_characteristics_t *drb_qos_char = &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) { if (dRB_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) {
...@@ -946,12 +946,12 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t ...@@ -946,12 +946,12 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t
/* QoS-Flow-Level-QoS-Parameters */ /* QoS-Flow-Level-QoS-Parameters */
{ {
f1ap_qos_flow_level_qos_parameters_t *flow_qos = &flows_mapped_to_drb->qos_params; qos_flow_level_qos_parameters_t *flow_qos = &flows_mapped_to_drb->qos_params;
F1AP_QoSFlowLevelQoSParameters_t *Flow_QoS = &flows_Mapped_To_Drb->qoSFlowLevelQoSParameters; F1AP_QoSFlowLevelQoSParameters_t *Flow_QoS = &flows_Mapped_To_Drb->qoSFlowLevelQoSParameters;
/* QoS Characteristics*/ /* QoS Characteristics*/
{ {
f1ap_qos_characteristics_t *flow_qos_char = &flow_qos->qos_characteristics; qos_characteristics_t *flow_qos_char = &flow_qos->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) { if (Flow_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) {
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
* @ingroup _mac * @ingroup _mac
*/ */
#define _GNU_SOURCE
#include "common/platform_types.h" #include "common/platform_types.h"
#include "common/platform_constants.h" #include "common/platform_constants.h"
...@@ -363,6 +364,40 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort ...@@ -363,6 +364,40 @@ nfapi_nr_pm_list_t init_DL_MIMO_codebook(gNB_MAC_INST *gNB, nr_pdsch_AntennaPort
AssertFatal(false, "Max number of antenna ports supported is currently 16\n"); AssertFatal(false, "Max number of antenna ports supported is currently 16\n");
} }
/**
* This is a QoS comparator function for qsort.
*
* @lcid1 pointer to the first array element
* @lcid1 pointer to the second array element
* @return negative return value means that *p1 goes before *p2
* zero return value means that that *p1 is equivalent to *p2
* positive return value means that *p1 goes after *p2
**/
static int QoS_Comp(const void *lcid1, const void *lcid2, void *sctrl)
{
NR_UE_sched_ctrl_t *sched_ctrl = (NR_UE_sched_ctrl_t *)sctrl;
uint8_t *lc_priority = sched_ctrl->dl_lc_ids_priorities;
return lc_priority[*(uint8_t *)lcid1] - lc_priority[*(uint8_t *)lcid2];
}
void process_lcOrder(NR_UE_sched_ctrl_t *sched_ctrl)
{
/* lc with in each UE are sorted so that lower in value(high priority) lcs are scheduled first*/
qsort_r(sched_ctrl->dl_lc_ids, sched_ctrl->dl_lc_num, sizeof(uint8_t), QoS_Comp, sched_ctrl);
LOG_I(NR_MAC, "Printing logical channel ids sorted by Priority Level:\n");
for (int j = 0; j < sched_ctrl->dl_lc_num; j++) {
uint8_t lcid = sched_ctrl->dl_lc_ids[j];
LOG_I(NR_MAC,
"LCID %d (%s %d) = Priority of %d\n",
lcid,
lcid < 4 ? "SRB" : "DRB",
lcid < 4 ? lcid : lcid - 3,
sched_ctrl->dl_lc_ids_priorities[lcid]); // lcid 0 - SRB0, 1- SRB1, 2 - SRB2, 3 - 31 DRBs,
}
}
static void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list, static void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list,
struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_bearer2release_list, struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_bearer2release_list,
NR_UE_sched_ctrl_t *sched_ctrl) NR_UE_sched_ctrl_t *sched_ctrl)
...@@ -428,6 +463,7 @@ void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_info_t *UE) ...@@ -428,6 +463,7 @@ void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_info_t *UE)
nr_mac_prepare_ra_ue(RC.nrmac[0], UE->rnti, CellGroup); nr_mac_prepare_ra_ue(RC.nrmac[0], UE->rnti, CellGroup);
} }
process_rlcBearerConfig(CellGroup->rlc_BearerToAddModList, CellGroup->rlc_BearerToReleaseList, &UE->UE_sched_ctrl); process_rlcBearerConfig(CellGroup->rlc_BearerToAddModList, CellGroup->rlc_BearerToReleaseList, &UE->UE_sched_ctrl);
process_lcOrder(&UE->UE_sched_ctrl);
} }
static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc) static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_AntennaPorts, int pusch_AntennaPorts, NR_ServingCellConfigCommon_t *scc)
......
...@@ -23,17 +23,13 @@ ...@@ -23,17 +23,13 @@
#include "mac_proto.h" #include "mac_proto.h"
#include "openair2/F1AP/f1ap_ids.h" #include "openair2/F1AP/f1ap_ids.h"
#include "openair2/E1AP/e1ap_common.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h" #include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "F1AP_CauseRadioNetwork.h" #include "F1AP_CauseRadioNetwork.h"
#include "uper_decoder.h" #include "uper_decoder.h"
#include "uper_encoder.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) static long get_lcid_from_drbid(int drb_id)
{ {
return drb_id + 3; /* LCID is DRB + 3 */ return drb_id + 3; /* LCID is DRB + 3 */
...@@ -248,45 +244,32 @@ static void set_nssaiConfig(const int drb_len, const f1ap_drb_to_be_setup_t *req ...@@ -248,45 +244,32 @@ 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) static void set_LCpriority(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"); AssertFatal(req != NULL, "f1ap_ue_context_modif_req is NULL\n");
uint8_t drb_count = req->drbs_to_be_setup_length; uint8_t drb_count = req->drbs_to_be_setup_length;
uint8_t srb_count = req->srbs_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); LOG_I(NR_MAC, "Number of DRBs = %d and SRBs = %d\n", drb_count, srb_count);
/* SRBs*/
for (int i = 0; i < srb_count; i++) {
f1ap_srb_to_be_setup_t *srb_p = &req->srbs_to_be_setup[i];
long srb_id = srb_p->srb_id;
long lc_id = get_lcid_from_srbid(srb_id);
sched_ctrl->dl_lc_ids_priorities[lc_id] = srb_id;
}
/* DRBs*/ /* DRBs*/
for (int i = 0; i < drb_count; i++) { for (int i = 0; i < drb_count; i++) {
f1ap_drb_to_be_setup_t *drb_p = &req->drbs_to_be_setup[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; long drb_id = drb_p->drb_id;
LOG_I(NR_MAC, "number of QOS flows mapped to DRB_id %ld: %d\n", drb_id, nb_qos_flows); long lc_id = get_lcid_from_drbid(drb_id);
for (int q = 0; q < nb_qos_flows; q++) { qos_characteristics_t *qos_char = &drb_p->drb_info.drb_qos.qos_characteristics;
f1ap_flows_mapped_to_drb_t *qos_flow = &drb_p->drb_info.flows_mapped_to_drb[q]; if (qos_char->qos_type == non_dynamic) {
long fiveqi = qos_char->non_dynamic.fiveqi;
f1ap_qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics; sched_ctrl->dl_lc_ids_priorities[lc_id] = get_flow_priority(fiveqi);
uint64_t priority = qos_char->non_dynamic.qos_priority_level; } else {
int64_t fiveqi = qos_char->non_dynamic.fiveqi; sched_ctrl->dl_lc_ids_priorities[lc_id] = qos_char->dynamic.qos_priority_level;
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);
} }
} }
} }
...@@ -351,12 +334,12 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) ...@@ -351,12 +334,12 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name); AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name);
resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3; resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3;
/* Fill the QoS config in MAC for each active DRB */
set_LCpriority(req, &UE->UE_sched_ctrl);
/* TODO: need to apply after UE context reconfiguration confirmed? */ /* TODO: need to apply after UE context reconfiguration confirmed? */
nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup); 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 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); set_nssaiConfig(req->drbs_to_be_setup_length, req->drbs_to_be_setup, &UE->UE_sched_ctrl);
...@@ -455,10 +438,10 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) ...@@ -455,10 +438,10 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name); AssertFatal(enc_rval.encoded > 0, "Could not encode CellGroup, failed element %s\n", enc_rval.failed_type->name);
resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3; resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3;
nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup);
/* Fill the QoS config in MAC for each active DRB */ /* Fill the QoS config in MAC for each active DRB */
set_QoSConfig(req, &UE->UE_sched_ctrl); set_LCpriority(req, &UE->UE_sched_ctrl);
nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup);
/* Set NSSAI config in MAC for each active DRB */ /* 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); set_nssaiConfig(req->drbs_to_be_setup_length, req->drbs_to_be_setup, &UE->UE_sched_ctrl);
......
...@@ -37,4 +37,7 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd); ...@@ -37,4 +37,7 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd);
void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc); void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc);
extern const uint64_t qos_fiveqi[];
extern const uint64_t qos_priority[];
#endif /* MAC_RRC_DL_HANDLER_H */ #endif /* MAC_RRC_DL_HANDLER_H */
...@@ -546,6 +546,13 @@ typedef struct NR_QoS_config_s { ...@@ -546,6 +546,13 @@ typedef struct NR_QoS_config_s {
/*! \brief scheduling control information set through an API */ /*! \brief scheduling control information set through an API */
#define MAX_CSI_REPORTS 48 #define MAX_CSI_REPORTS 48
typedef struct { typedef struct {
/*
Information about the QoS configuration for each LCID/DRB
(0 -CCCH and 1- 3 SRBs(0,1,2), 4-32 DRBs(0, 1, 28))
DRB Identity can be any value [1-32]
*/
NR_QoS_config_t qos_config[NR_MAX_NUM_LCID][NR_MAX_NUM_QFI];
/// CCE index and aggregation, should be coherent with cce_list /// CCE index and aggregation, should be coherent with cce_list
NR_SearchSpace_t *search_space; NR_SearchSpace_t *search_space;
NR_ControlResourceSet_t *coreset; NR_ControlResourceSet_t *coreset;
...@@ -643,8 +650,8 @@ typedef struct { ...@@ -643,8 +650,8 @@ typedef struct {
nr_srs_feedback_t srs_feedback; nr_srs_feedback_t srs_feedback;
nssai_t dl_lc_nssai[NR_MAX_NUM_LCID]; nssai_t dl_lc_nssai[NR_MAX_NUM_LCID];
// Information about the QoS configuration for each LCID/DRB // priorities of lcids
NR_QoS_config_t qos_config[NR_MAX_NUM_LCID - 4][NR_MAX_NUM_QFI]; // 0 -CCCH and 1- 3 SRBs(0,1,2) uint8_t dl_lc_ids_priorities[NR_MAX_NUM_LCID];
} NR_UE_sched_ctrl_t; } NR_UE_sched_ctrl_t;
typedef struct { typedef struct {
......
...@@ -95,6 +95,7 @@ ...@@ -95,6 +95,7 @@
#include <openair3/ocp-gtpu/gtp_itf.h> #include <openair3/ocp-gtpu/gtp_itf.h>
#include <openair2/RRC/NR/nr_rrc_proto.h> #include <openair2/RRC/NR/nr_rrc_proto.h>
#include "openair2/F1AP/f1ap_common.h" #include "openair2/F1AP/f1ap_common.h"
#include "openair2/E1AP/e1ap_common.h"
#include "openair2/F1AP/f1ap_ids.h" #include "openair2/F1AP/f1ap_ids.h"
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h" #include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
#include "cucp_cuup_if.h" #include "cucp_cuup_if.h"
...@@ -2046,7 +2047,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp ...@@ -2046,7 +2047,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
drb->drb_info.flows_mapped_to_drb[j].qfi = drb_config->qosFlows[j].qfi; drb->drb_info.flows_mapped_to_drb[j].qfi = drb_config->qosFlows[j].qfi;
pdusession_level_qos_parameter_t *in_qos_char = get_qos_characteristics(drb_config->qosFlows[j].qfi, RRC_pduSession); pdusession_level_qos_parameter_t *in_qos_char = get_qos_characteristics(drb_config->qosFlows[j].qfi, RRC_pduSession);
f1ap_qos_characteristics_t *qos_char = &drb->drb_info.flows_mapped_to_drb[j].qos_params.qos_characteristics; qos_characteristics_t *qos_char = &drb->drb_info.flows_mapped_to_drb[j].qos_params.qos_characteristics;
if (in_qos_char->fiveQI_type == dynamic) { if (in_qos_char->fiveQI_type == dynamic) {
qos_char->qos_type = dynamic; qos_char->qos_type = dynamic;
qos_char->dynamic.fiveqi = in_qos_char->fiveQI; qos_char->dynamic.fiveqi = in_qos_char->fiveQI;
...@@ -2058,7 +2059,10 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp ...@@ -2058,7 +2059,10 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
} }
} }
/* the DRB QoS parameters: we just reuse the ones from the first flow */ /* the DRB QoS parameters: we just reuse the ones from the first flow */
drb->drb_info.drb_qos = drb->drb_info.flows_mapped_to_drb[0].qos_params; get_drb_characteristics((qos_flow_to_setup_t *)drb->drb_info.flows_mapped_to_drb,
drb->drb_info.flows_to_be_setup_length,
drb->drb_info.flows_mapped_to_drb[0].qos_params.qos_characteristics.qos_type,
&drb->drb_info.drb_qos);
/* pass NSSAI info to MAC */ /* pass NSSAI info to MAC */
drb->nssai = RRC_pduSession->param.nssai; drb->nssai = RRC_pduSession->param.nssai;
......
...@@ -445,9 +445,9 @@ static void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdu ...@@ -445,9 +445,9 @@ static void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdu
ngran_allocation_retention_priority_t *rent_priority = &qos_flow->qos_params.alloc_reten_priority; 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; ngap_allocation_retention_priority_t *rent_priority_in = &qos_session->allocation_retention_priority;
rent_priority->priority_level = rent_priority_in->priority_level; rent_priority->priority_level = (uint16_t)rent_priority_in->priority_level;
rent_priority->preemption_capability = rent_priority_in->pre_emp_capability; rent_priority->preemption_capability = (preemption_capability_t)((uint16_t)rent_priority_in->pre_emp_capability);
rent_priority->preemption_vulnerability = rent_priority_in->pre_emp_vulnerability; rent_priority->preemption_vulnerability = (preemption_vulnerability_t)((uint16_t)rent_priority_in->pre_emp_vulnerability);
} }
} }
} }
......
...@@ -29,6 +29,11 @@ ...@@ -29,6 +29,11 @@
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.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[] = {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[] = {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};
typedef struct { typedef struct {
nr_sdap_entity_t *sdap_entity_llist; nr_sdap_entity_t *sdap_entity_llist;
} nr_sdap_entity_info; } nr_sdap_entity_info;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment