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:
@@ -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