Commit 850a0163 authored by Sriharsha Korada's avatar Sriharsha Korada

Implement Qos MAC scheduler

parent 3f3a9869
......@@ -1357,6 +1357,7 @@ set (MAC_NR_SRC
${NR_GNB_MAC_DIR}/gNB_scheduler.c
${NR_GNB_MAC_DIR}/gNB_scheduler_bch.c
${NR_GNB_MAC_DIR}/gNB_scheduler_dlsch.c
${NR_GNB_MAC_DIR}/gNB_qos_aware_scheduler_dlsch.c
${NR_GNB_MAC_DIR}/gNB_scheduler_ulsch.c
${NR_GNB_MAC_DIR}/gNB_scheduler_primitives.c
${NR_GNB_MAC_DIR}/gNB_scheduler_phytest.c
......
......@@ -1709,7 +1709,9 @@ INPUT = \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/NR_MAC_gNB/gNB_qos_aware_scheduler_dlsch.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/NR_MAC_gNB/gNB_qos_aware_scheduler_dlsch.h \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c \
@CMAKE_CURRENT_SOURCE_DIR@/../openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c \
......
......@@ -52,6 +52,7 @@
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n"
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
#define CONFIG_HLP_QOS_AWARE_SCHED "use scheduler for downlink that performs scheduling based on qos priorities\n"
#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n"
#define CONFIG_HLP_DMAMAP "use DMA memory mapping\n"
#define CONFIG_HLP_EXCCLK "tells hardware to use a clock reference (0:internal(default), 1:external, 2:gpsdo)\n"
......
......@@ -55,6 +55,7 @@ extern "C"
#define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n"
#define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n"
#define CONFIG_HLP_QOS_AWARE_SCHED "use scheduler for downlink that performs scheduling based on qos priorities\n"
#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n"
#define CONFIG_HLP_SA "run gNB in standalone mode\n"
#define CONFIG_HLP_SL_MODE "sets the NR sidelink mode (0: not in sidelink mode, 1: in-coverage/gNB, 2: out-of-coverage/no gNB)\n"
......@@ -117,6 +118,7 @@ extern "C"
#define TP_CONFIG softmodem_params.threadPoolConfig
#define CONTINUOUS_TX softmodem_params.continuous_tx
#define PHY_TEST softmodem_params.phy_test
#define QOS_AWARE_SCHEDULER softmodem_params.use_qos_aware_scheduler
#define DO_RA softmodem_params.do_ra
#define SA softmodem_params.sa
#define SL_MODE softmodem_params.sl_mode
......@@ -150,6 +152,7 @@ extern int usrp_tx_thread;
{"rf-config-file", CONFIG_HLP_RFCFGF, 0, .strptr=&RF_CONFIG_FILE, .defstrval=NULL, TYPE_STRING, 0}, \
{"thread-pool", CONFIG_HLP_TPOOL, 0, .strptr=&TP_CONFIG, .defstrval="-1,-1,-1,-1,-1,-1,-1,-1", TYPE_STRING, 0}, \
{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, .iptr=&PHY_TEST, .defintval=0, TYPE_INT, 0}, \
{"use-qos-scheduler", CONFIG_HLP_QOS_AWARE_SCHED, PARAMFLAG_BOOL,.iptr=&QOS_AWARE_SCHEDULER, .defintval=1, TYPE_INT, 0}, \
{"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, .iptr=&DO_RA, .defintval=0, TYPE_INT, 0}, \
{"sa", CONFIG_HLP_SA, PARAMFLAG_BOOL, .iptr=&SA, .defintval=0, TYPE_INT, 0}, \
{"sl-mode", CONFIG_HLP_SL_MODE, 0, .u8ptr=&SL_MODE, .defintval=0, TYPE_UINT8, 0}, \
......@@ -224,6 +227,7 @@ extern int usrp_tx_thread;
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s3a = { config_checkstr_assign_integer, \
{"MONOLITHIC", "PNF", "VNF","UE_STUB_PNF","UE_STUB_OFFNET","STANDALONE_PNF"}, \
{NFAPI_MONOLITHIC, NFAPI_MODE_PNF, NFAPI_MODE_VNF,NFAPI_UE_STUB_PNF,NFAPI_UE_STUB_OFFNET,NFAPI_MODE_STANDALONE_PNF}, \
......@@ -335,6 +339,7 @@ typedef struct {
int hw_timing_advance;
uint32_t send_dmrs_sync;
int use_256qam_table;
int use_qos_aware_scheduler;
int chest_time;
int chest_freq;
uint8_t nfapi;
......
......@@ -126,6 +126,7 @@ typedef struct drb_to_setup_s {
cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
} drb_to_setup_t;
/*
typedef struct qos_characteristics_s {
union {
struct {
......@@ -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!!
} 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;
......@@ -179,6 +182,7 @@ typedef struct DRB_nGRAN_to_setup_s {
cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
int numQosFlow2Setup;
qos_flow_to_setup_t qosFlows[E1AP_MAX_NUM_QOS_FLOWS];
qos_flow_level_qos_parameters_t dRB_QoS;
} DRB_nGRAN_to_setup_t;
typedef struct pdu_session_to_setup_s {
......
......@@ -299,7 +299,7 @@ typedef enum preemption_vulnerability_e {
PREEMPTABLE,
} preemption_vulnerability_t;
typedef struct f1ap_qos_characteristics_s {
typedef struct qos_characteristics_s {
union {
struct {
long fiveqi;
......@@ -316,26 +316,26 @@ typedef struct f1ap_qos_characteristics_s {
} dynamic;
};
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;
preemption_capability_t preemption_capability;
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 {
f1ap_qos_characteristics_t qos_characteristics;
f1ap_ngran_allocation_retention_priority_t alloc_reten_priority;
} f1ap_qos_flow_level_qos_parameters_t;
typedef struct qos_flow_level_qos_parameters_s {
qos_characteristics_t qos_characteristics;
ngran_allocation_retention_priority_t alloc_reten_priority;
} 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;
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;
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;
......
......@@ -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 =
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;
......@@ -1026,6 +1058,52 @@ void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_beare
rent_priority->preemption_vulnerability =
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;
......
......@@ -67,5 +67,6 @@
#include <E1AP_PDCP-Configuration.h>
#include <E1AP_Slice-Support-List.h>
#include <E1AP_Slice-Support-Item.h>
#include <E1AP_ProtocolExtensionField.h>
#endif
......@@ -20,7 +20,7 @@
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#define _GNU_SOURCE
#include <time.h>
#include <stdlib.h>
#include "e1ap_common.h"
......@@ -28,6 +28,7 @@
#include "e1ap_asnc.h"
#include "common/openairinterface5g_limits.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};
......@@ -243,3 +244,52 @@ int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, E1AP_E1AP_PDU_t *pdu, uin
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
void e1ap_common_init();
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_ */
......@@ -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 */
{
/* 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;
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) {
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);
......@@ -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;
/* 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 */
{
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;
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;
......
......@@ -900,11 +900,11 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t
/* 12.1.2.1 dRB_QoS */
{
/* 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;
{
/* 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;
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
/* 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;
/* 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;
if (Flow_QoS_Char->present == F1AP_QoS_Characteristics_PR_non_Dynamic_5QI) {
......
......@@ -29,7 +29,9 @@
* @ingroup _mac
*/
#define _GNU_SOURCE
#define _GNU_SOURCE
#include "common/platform_types.h"
#include "common/platform_constants.h"
#include "common/ran_context.h"
......@@ -363,6 +365,47 @@ 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");
}
/**
* 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_D(NR_MAC, "Printing logical channel ids sorted by Priority Level:\n");
uint8_t priority_ue = 0;
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,
/* determine the priority of the UE as the mean priority of DRBs */
priority_ue += sched_ctrl->dl_lc_ids_priorities[lcid];
}
sched_ctrl->priority_ue = (float)priority_ue / sched_ctrl->dl_lc_num;
LOG_I(NR_MAC, "The priority of the UE is:%f\n", sched_ctrl->priority_ue);
}
static void process_rlcBearerConfig(struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list,
struct NR_CellGroupConfig__rlc_BearerToReleaseList *rlc_bearer2release_list,
NR_UE_sched_ctrl_t *sched_ctrl)
......@@ -428,6 +471,7 @@ void process_CellGroup(NR_CellGroupConfig_t *CellGroup, NR_UE_info_t *UE)
nr_mac_prepare_ra_ue(RC.nrmac[0], UE->rnti, CellGroup);
}
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)
......
This diff is collapsed.
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef QOS_AWARE_DLSCH_SCHEDULER
#define QOS_AWARE_DLSCH_SCHEDULER
#include "NR_MAC_gNB/gNB_scheduler_dlsch.h"
#define LC_iterator(BaSe, VaR) \
LCIDsched_t *VaR##pptr = BaSe, *VaR; \
while ((VaR = (VaR##pptr++)))
int lc_comparator(const void *p, const void *q);
int comparator(const void *p, const void *q);
int preallocate_numrbs_per_lc(LCIDsched_t *lc_sched, int num_rbs_data, float *remainPRBs);
int nr_find_nb_bytes(int bytes,
int oh_bytes,
uint32_t *tbs,
uint16_t *rbsize,
uint16_t nb_rb_max,
NR_sched_pdsch_t *sched_pdsch,
NR_tda_info_t *tda_info);
int nr_get_num_prioritized_bytes(int max_rbsize, UEsched_t *ue_iterator, LCIDsched_t *lc_sched);
uint8_t rb_allocation_lcid(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
LCIDsched_t *lc_sched,
UEsched_t *ue_sched,
int n_rb_sched,
uint16_t *rballoc_mask);
void fill_lc_sched_list(NR_UE_info_t *UE, frame_t frame, int *lc_currid, int ue_currid, LCIDsched_t *lc_sched);
void qos_aware_scheduler_dl(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
NR_UE_info_t **UE_list,
int max_num_ue,
int n_rb_sched,
uint16_t *rballoc_mask);
#endif
......@@ -32,10 +32,10 @@
#include "common/utils/nr/nr_common.h"
/*MAC*/
#include "NR_MAC_COMMON/nr_mac.h"
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "LAYER2/RLC/rlc.h"
#include "LAYER2/NR_MAC_gNB/gNB_qos_aware_scheduler_dlsch.h"
/*NFAPI*/
#include "nfapi_nr_interface.h"
......@@ -380,10 +380,7 @@ void abort_nr_dl_harq(NR_UE_info_t* UE, int8_t harq_pid)
}
static void get_start_stop_allocation(gNB_MAC_INST *mac,
NR_UE_info_t *UE,
int *rbStart,
int *rbStop)
void get_start_stop_allocation(gNB_MAC_INST *mac, NR_UE_info_t *UE, int *rbStart, int *rbStop)
{
NR_UE_DL_BWP_t *dl_bwp = &UE->current_DL_BWP;
NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
......@@ -407,13 +404,13 @@ static void get_start_stop_allocation(gNB_MAC_INST *mac,
}
}
static bool allocate_dl_retransmission(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
uint16_t *rballoc_mask,
int *n_rb_sched,
NR_UE_info_t *UE,
int current_harq_pid)
bool allocate_dl_retransmission(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
uint16_t *rballoc_mask,
int *n_rb_sched,
NR_UE_info_t *UE,
int current_harq_pid)
{
int CC_id = 0;
......@@ -579,13 +576,8 @@ static bool allocate_dl_retransmission(module_id_t module_id,
return true;
}
uint32_t pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
typedef struct UEsched_s {
float coef;
NR_UE_info_t * UE;
} UEsched_t;
static int comparator(const void *p, const void *q) {
int comparator(const void *p, const void *q)
{
return ((UEsched_t*)p)->coef < ((UEsched_t*)q)->coef;
}
......@@ -828,6 +820,8 @@ static void pf_dl(module_id_t module_id,
}
}
uint32_t pf_tbs[3][29]; // pre-computed, approximate TBS values for PF coefficient
static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_frame_t slot)
{
NR_UEs_t *UE_info = &RC.nrmac[module_id]->UE_info;
......@@ -858,14 +852,19 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_
uint16_t *vrb_map = RC.nrmac[module_id]->common_channels[CC_id].vrb_map;
uint16_t rballoc_mask[bwpSize];
int n_rb_sched = 0;
for (int i = 0; i < bwpSize; i++) {
// calculate mask: init with "NOT" vrb_map:
// if any RB in vrb_map is blocked (1), the current RBG will be 0
LOG_D(NR_MAC, "vrb map bit %d\n", vrb_map[i + BWPStart]);
rballoc_mask[i] = (~vrb_map[i+BWPStart])&0x3fff; //bitwise not and 14 symbols
// if all the pdsch symbols are free
if ((rballoc_mask[i]&slbitmap) == slbitmap) {
LOG_D(NR_MAC,
"rballoc_mask bit = %hu, slbitmap = %hu and finally and operation = %hu\n",
rballoc_mask[i],
slbitmap,
(rballoc_mask[i] & slbitmap));
n_rb_sched++;
}
}
......@@ -877,14 +876,14 @@ static void nr_fr1_dlsch_preprocessor(module_id_t module_id, frame_t frame, sub_
int average_agg_level = 4; // TODO find a better estimation
int max_sched_ues = bw / (average_agg_level * NR_NB_REG_PER_CCE);
/* proportional fair scheduling algorithm */
pf_dl(module_id,
frame,
slot,
UE_info->list,
max_sched_ues,
n_rb_sched,
rballoc_mask);
if (get_softmodem_params()->use_qos_aware_scheduler == 0) {
LOG_D(NR_MAC, "Using Proportional Fair scheduler\n");
pf_dl(module_id, frame, slot, UE_info->list, max_sched_ues, n_rb_sched, rballoc_mask);
} else {
LOG_D(NR_MAC, "Using QoS aware scheduler\n");
qos_aware_scheduler_dl(module_id, frame, slot, UE_info->list, max_sched_ues, n_rb_sched, rballoc_mask);
}
}
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id) {
......@@ -1270,8 +1269,9 @@ void nr_schedule_ue_spec(module_id_t module_id,
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
/* limit requested number of bytes to what preprocessor specified, or
* such that TBS is full */
const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer,
bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
uint32_t bytes_in_buffer;
bytes_in_buffer = sched_ctrl->rlc_status[lcid].bytes_in_buffer;
const rlc_buffer_occupancy_t ndata = min(bytes_in_buffer, bufEnd - buf - sizeof(NR_MAC_SUBHEADER_LONG));
tbs_size_t len = mac_rlc_data_req(module_id,
rnti,
module_id,
......
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef DLSCH_SCHEDULER_H
#define DLSCH_SCHEDULER_H
#include "NR_MAC_gNB/nr_mac_gNB.h"
typedef struct UEsched_s {
float coef;
NR_UE_info_t *UE;
uint16_t num_rbs_sched; // number of resource blocks scheduled
bool oh_status;
} UEsched_t;
typedef struct LCIDsched_s {
float coef;
NR_UE_info_t *UE;
uint8_t curr_lcid; // to specify the lcid of the current UE after sorting (not an optimum approach)
uint8_t curr_ue; // to keep track of to which UE this lcid belongs to
uint8_t lcid_priority; // calculated lcid priority based on qos flow priorities
uint16_t num_rbs_lcid_allocated; // number of resource blocks allocated for this LCID initially
uint16_t num_rbs_lcid_used;
uint16_t num_rbs_lcid_remain;
float factor;
uint32_t allocated_bytes;
uint32_t remaining_bytes;
uint16_t overhead;
} LCIDsched_t;
#endif
\ No newline at end of file
......@@ -78,6 +78,16 @@ void nr_schedule_ue_spec(module_id_t module_id,
/* \brief default FR1 DL preprocessor init routine, returns preprocessor to call */
nr_pp_impl_dl nr_init_fr1_dlsch_preprocessor(int CC_id);
void get_start_stop_allocation(gNB_MAC_INST *mac, NR_UE_info_t *UE, int *rbStart, int *rbStop);
bool allocate_dl_retransmission(module_id_t module_id,
frame_t frame,
sub_frame_t slot,
uint16_t *rballoc_mask,
int *n_rb_sched,
NR_UE_info_t *UE,
int current_harq_pid);
void schedule_nr_sib1(module_id_t module_idP,
frame_t frameP,
sub_frame_t slotP,
......
......@@ -23,17 +23,13 @@
#include "mac_proto.h"
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/E1AP/e1ap_common.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "F1AP_CauseRadioNetwork.h"
#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 */
......@@ -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");
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);
/* 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*/
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, "number of QOS flows mapped to DRB_id %ld: %d\n", drb_id, nb_qos_flows);
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);
long lc_id = get_lcid_from_drbid(drb_id);
qos_characteristics_t *qos_char = &drb_p->drb_info.drb_qos.qos_characteristics;
if (qos_char->qos_type == non_dynamic) {
long fiveqi = qos_char->non_dynamic.fiveqi;
sched_ctrl->dl_lc_ids_priorities[lc_id] = get_flow_priority(fiveqi);
} else {
sched_ctrl->dl_lc_ids_priorities[lc_id] = qos_char->dynamic.qos_priority_level;
}
}
}
......@@ -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);
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? */
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);
......@@ -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);
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 */
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_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);
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 */
......@@ -546,6 +546,13 @@ typedef struct NR_QoS_config_s {
/*! \brief scheduling control information set through an API */
#define MAX_CSI_REPORTS 48
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
NR_SearchSpace_t *search_space;
NR_ControlResourceSet_t *coreset;
......@@ -643,8 +650,11 @@ typedef struct {
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)
// priorities of lcids
uint8_t dl_lc_ids_priorities[NR_MAX_NUM_LCID];
// priority assigned to ue
float priority_ue;
} NR_UE_sched_ctrl_t;
typedef struct {
......
......@@ -235,6 +235,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind(const module_id_t module_idP,
nr_rlc_manager_unlock(nr_rlc_ue_manager);
ret.pdus_in_buffer = 0;
/* TODO: creation time may be important (unit: frame, as it seems) */
ret.head_sdu_creation_time = 0;
ret.head_sdu_remaining_size_to_send = 0;
......
......@@ -95,6 +95,7 @@
#include <openair3/ocp-gtpu/gtp_itf.h>
#include <openair2/RRC/NR/nr_rrc_proto.h>
#include "openair2/F1AP/f1ap_common.h"
#include "openair2/E1AP/e1ap_common.h"
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.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
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);
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) {
qos_char->qos_type = dynamic;
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
}
}
/* 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 */
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
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;
rent_priority->priority_level = (uint16_t)rent_priority_in->priority_level;
rent_priority->preemption_capability = (preemption_capability_t)((uint16_t)rent_priority_in->pre_emp_capability);
rent_priority->preemption_vulnerability = (preemption_vulnerability_t)((uint16_t)rent_priority_in->pre_emp_vulnerability);
}
}
}
......
......@@ -29,6 +29,11 @@
#include <string.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 {
nr_sdap_entity_t *sdap_entity_llist;
} 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