F1AP and E1AP interface changes for QoS
- Implement: Extend the F1 encoding and decoding with Qos - Implement: E1 decoding for QoS - Fix: Modify the UE_MODIFICATION_REQUEST_MSG towards DU to contain QoS info based on E1AP context response - Fix: Modify the E1AP and F1AP message structures - Fill the Qos configuration to send to MAC
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
+40
-23
@@ -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;
|
||||
|
||||
@@ -41,27 +41,28 @@
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user