Compare commits

...

1 Commits

Author SHA1 Message Date
Sriharsha Korada
398ae02ab9 F1 and E1 changes to send DRB priority 2024-10-30 17:13:55 +00:00
17 changed files with 660 additions and 179 deletions

View File

@@ -29,6 +29,6 @@ typedef struct nssai_s {
uint32_t sd;
} nssai_t;
typedef enum { NON_DYNAMIC, DYNAMIC } fiveQI_t;
// typedef enum { NON_DYNAMIC, DYNAMIC } fiveQI_t;
#endif

View File

@@ -29,6 +29,7 @@
#include "common/ngran_types.h"
#include "f1ap_messages_types.h"
#include "ngap_messages_types.h"
#include "qos_flow_messages_types.h"
#define E1AP_MAX_NUM_TRANSAC_IDS 4
#define E1AP_MAX_NUM_PLMNS 4
@@ -147,36 +148,6 @@ 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 {
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_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;
@@ -208,6 +179,7 @@ typedef struct DRB_nGRAN_to_setup_s {
/* DRB QoS Flows Parameters (clause 9.3.1.26) */
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, DRB_nGRAN_to_mod_t;
/**

View File

@@ -24,7 +24,9 @@
#include <netinet/in.h>
#include <netinet/sctp.h>
#include "common/5g_platform_types.h"
#include "s1ap_messages_types.h"
#include "ngap_messages_types.h"
#include "qos_flow_messages_types.h"
//-------------------------------------------------------------------------------------------//
// Defines to access message fields.
@@ -359,53 +361,13 @@ 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_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;
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;

View File

@@ -32,6 +32,8 @@
#include "common/platform_constants.h"
#include "common/platform_types.h"
#include "common/5g_platform_types.h"
#include "common/ngran_types.h"
#include "qos_flow_messages_types.h"
#include "LTE_asn_constant.h"
#include "s1ap_messages_types.h"
//-------------------------------------------------------------------------------------------//
@@ -203,6 +205,7 @@ typedef struct pdusession_level_qos_parameter_s {
uint64_t qos_priority;
fiveQI_t fiveQI_type;
ngap_allocation_retention_priority_t allocation_retention_priority;
gbr_qos_flow_information_t gbr_qos_flow_level_qos_params;
} pdusession_level_qos_parameter_t;
typedef struct ngap_guami_s {

View File

@@ -0,0 +1,144 @@
/*
* 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 QOSFLOW_MESSAGES_TYPES_H_
#define QOSFLOW_MESSAGES_TYPES_H_
#define STANDARIZED_5QI_NUM 26
typedef enum { NON_DYNAMIC_5QI, DYNAMIC_5QI } fiveQI_t;
typedef enum { GBR, NON_GBR, DELAY_CRITICAL_GBR } qos_flow_type_t;
typedef enum qos_priority_e {
PRIORITY_20 = 20,
PRIORITY_40 = 40,
PRIORITY_30 = 30,
PRIORITY_50 = 50,
PRIORITY_7 = 7,
PRIORITY_15 = 15,
PRIORITY_56 = 56,
PRIORITY_10 = 10,
PRIORITY_60 = 60,
PRIORITY_70 = 70,
PRIORITY_80 = 80,
PRIORITY_90 = 90,
PRIORITY_5 = 5,
PRIORITY_55 = 55,
PRIORITY_65 = 65,
PRIORITY_68 = 68,
PRIORITY_19 = 19,
PRIORITY_22 = 22,
PRIORITY_24 = 24,
PRIORITY_21 = 21,
PRIORITY_18 = 18
} qos_priority_t;
typedef enum qos_fiveqi_e {
FIVEQI_1 = 1,
FIVEQI_2 = 2,
FIVEQI_3 = 3,
FIVEQI_4 = 4,
FIVEQI_65 = 65,
FIVEQI_66 = 66,
FIVEQI_67 = 67,
FIVEQI_71 = 71,
FIVEQI_72 = 72,
FIVEQI_73 = 73,
FIVEQI_74 = 74,
FIVEQI_76 = 76,
FIVEQI_5 = 5,
FIVEQI_6 = 6,
FIVEQI_7 = 7,
FIVEQI_8 = 8,
FIVEQI_9 = 9,
FIVEQI_69 = 69,
FIVEQI_70 = 70,
FIVEQI_79 = 79,
FIVEQI_80 = 80,
FIVEQI_82 = 82,
FIVEQI_83 = 83,
FIVEQI_84 = 84,
FIVEQI_85 = 85,
FIVEQI_86 = 86
} qos_fiveqi_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 {
long fiveqi;
long qos_priority_level;
} non_dynamic_t;
typedef struct {
long per_scalar;
long per_exponent;
} packet_error_rate_t;
typedef struct {
long fiveqi; // -1 -> optional
long qos_priority_level;
long packet_delay_budget;
packet_error_rate_t packet_error_rate;
} dynamic_t;
typedef struct qos_characteristics_s {
union {
non_dynamic_t non_dynamic;
dynamic_t dynamic;
};
fiveQI_t qos_type;
} qos_characteristics_t;
typedef struct ngran_allocation_retention_priority_s {
uint16_t priority_level;
preemption_capability_t preemption_capability;
preemption_vulnerability_t preemption_vulnerability;
} ngran_allocation_retention_priority_t;
typedef struct gbr_qos_flow_information_s {
long mbr_dl;
long mbr_ul;
long gbr_dl;
long gbr_ul;
} gbr_qos_flow_information_t;
typedef struct qos_flow_level_qos_parameters_s {
qos_characteristics_t qos_characteristics;
ngran_allocation_retention_priority_t alloc_reten_priority;
gbr_qos_flow_information_t *gbr_qos_flow_info;
} qos_flow_level_qos_parameters_t;
typedef struct standard_5QI_characteristics_e {
uint64_t five_QI;
uint64_t priority_level;
uint64_t resource_type;
} standard_5QI_characteristics_t;
#endif /* QOSFLOW_MESSAGES_TYPES_H_ */

View File

@@ -0,0 +1,36 @@
/*
* 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
*
* Author and copyright: Laurent Thomas, open-cells.com
*
* 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_VALUES_H_
#define QOS_VALUES_H_
void get_drb_characteristics(qos_flow_to_setup_t *qos_flows_in, int num_qos_flows, qos_flow_level_qos_parameters_t *dRB_QoS);
// based on the 5QI value, its corresponding parameters are searched from the standarized table of 5QI to QoS mapping
uint64_t get_5QI_id(uint64_t fiveqi);
int get_non_dynamic_priority(int fiveqi);
extern const standard_5QI_characteristics_t params_5QI[];
#endif /* E1AP_COMMON_H_ */

View File

@@ -33,6 +33,7 @@
#include "e1ap_default_values.h"
#include "gtp_itf.h"
#include "openair2/LAYER2/nr_pdcp/cucp_cuup_handler.h"
#include "openair2/COMMON/qos_values.h"
#define E1AP_NUM_MSG_HANDLERS 14
typedef int (*e1ap_message_processing_t)(sctp_assoc_t assoc_id, e1ap_upcp_inst_t *inst, const E1AP_E1AP_PDU_t *message_p);
@@ -160,6 +161,49 @@ int e1ap_send_ERROR_INDICATION(instance_t instance, E1AP_ErrorIndication_t *Erro
return -1;
}
static void e1ap_read_qos_flow_qos_parameters(const E1AP_QoS_Flow_QoS_Parameter_List_t *asn1_qos_param_list,
qos_flow_to_setup_t *flows_mapped,
int n)
{
for (int k = 0; k < asn1_qos_param_list->list.count; k++) {
qos_flow_to_setup_t *qos_flow = flows_mapped + k;
E1AP_QoS_Flow_QoS_Parameter_Item_t *qos2Setup = asn1_qos_param_list->list.array[k];
qos_flow->qfi = qos2Setup->qoS_Flow_Identifier;
qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics;
E1AP_QoSFlowLevelQoSParameters_t *e1ap_qosparam = &qos2Setup->qoSFlowLevelQoSParameters;
E1AP_QoS_Characteristics_t *e1ap_qoschar = &e1ap_qosparam->qoS_Characteristics;
if (e1ap_qoschar->present == E1AP_QoS_Characteristics_PR_non_Dynamic_5QI) {
qos_char->qos_type = NON_DYNAMIC_5QI;
qos_char->non_dynamic.fiveqi = e1ap_qoschar->choice.non_Dynamic_5QI->fiveQI;
} else {
E1AP_Dynamic5QIDescriptor_t *dynamic5QI = e1ap_qoschar->choice.dynamic_5QI;
qos_char->qos_type = DYNAMIC_5QI;
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;
}
ngran_allocation_retention_priority_t *rent_priority = &qos_flow->qos_params.alloc_reten_priority;
E1AP_NGRANAllocationAndRetentionPriority_t *e1ap_rent_priority = &e1ap_qosparam->nGRANallocationRetentionPriority;
rent_priority->priority_level = e1ap_rent_priority->priorityLevel;
rent_priority->preemption_capability = e1ap_rent_priority->pre_emptionCapability;
rent_priority->preemption_vulnerability = e1ap_rent_priority->pre_emptionVulnerability;
gbr_qos_flow_information_t *gbr_qos_info = qos_flow->qos_params.gbr_qos_flow_info;
E1AP_GBR_QoSFlowInformation_t *gbr_qos2setup = qos2Setup->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information;
if (gbr_qos2setup) {
asn_INTEGER2long(&gbr_qos2setup->guaranteedFlowBitRateDownlink, &gbr_qos_info->gbr_dl);
asn_INTEGER2long(&gbr_qos2setup->guaranteedFlowBitRateUplink, &gbr_qos_info->gbr_ul);
asn_INTEGER2long(&gbr_qos2setup->maxFlowBitRateDownlink, &gbr_qos_info->mbr_dl);
asn_INTEGER2long(&gbr_qos2setup->maxFlowBitRateUplink, &gbr_qos_info->mbr_ul);
}
}
}
/*
E1 Setup: can be sent on both ways, to be refined
*/
@@ -682,17 +726,19 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear
}
/* QoS Flows */
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->qfi;
asn1cSequenceAdd(ieC6_1_1->qos_flow_Information_To_Be_Setup, E1AP_QoS_Flow_QoS_Parameter_Item_t, ieC6_1_1_1_1);
ieC6_1_1_1_1->qoS_Flow_Identifier = k->qfi;
/* QoS Characteristics */
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);
E1AP_QoSFlowLevelQoSParameters_t *e1ap_qosparam = &ieC6_1_1_1_1->qoSFlowLevelQoSParameters;
E1AP_QoS_Characteristics_t *e1ap_qoschar = &e1ap_qosparam->qoS_Characteristics;
if (qos_char_in->qos_type == NON_DYNAMIC_5QI) { // non Dynamic 5QI
e1ap_qoschar->present = E1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
asn1cCalloc(e1ap_qoschar->choice.non_Dynamic_5QI, non_Dynamic_5QI);
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);
e1ap_qoschar->present = E1AP_QoS_Characteristics_PR_dynamic_5QI;
asn1cCalloc(e1ap_qoschar->choice.dynamic_5QI, dynamic_5QI);
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;
@@ -700,12 +746,61 @@ static int fill_BEARER_CONTEXT_SETUP_REQUEST(e1ap_bearer_setup_req_t *const bear
}
/* QoS Retention Priority */
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;
E1AP_NGRANAllocationAndRetentionPriority_t *e1ap_rent_priority = &e1ap_qosparam->nGRANallocationRetentionPriority;
e1ap_rent_priority->priorityLevel = rent_priority_in->priority_level;
e1ap_rent_priority->pre_emptionCapability = rent_priority_in->preemption_capability;
e1ap_rent_priority->pre_emptionVulnerability = rent_priority_in->preemption_vulnerability;
gbr_qos_flow_information_t *gbr_qos_info = k->qos_params.gbr_qos_flow_info;
E1AP_GBR_QoSFlowInformation_t *e1ap_gbr_qosinfo = e1ap_qosparam->gBR_QoS_Flow_Information;
if (gbr_qos_info != NULL) {
asn_long2INTEGER(&e1ap_gbr_qosinfo->maxFlowBitRateDownlink, gbr_qos_info->mbr_dl);
asn_long2INTEGER(&e1ap_gbr_qosinfo->maxFlowBitRateUplink, gbr_qos_info->mbr_ul);
asn_long2INTEGER(&e1ap_gbr_qosinfo->guaranteedFlowBitRateDownlink, gbr_qos_info->gbr_dl);
asn_long2INTEGER(&e1ap_gbr_qosinfo->guaranteedFlowBitRateUplink, gbr_qos_info->gbr_ul);
}
}
/* 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 characteristics */
// get_drb_characteristics(j->qosFlows, j->numQosFlow2Setup, &(j->dRB_QoS));
qos_characteristics_t *drb_QoS_char_in = &j->dRB_QoS.qos_characteristics;
if (drb_QoS_char_in->qos_type == NON_DYNAMIC_5QI) {
drb_QoS_char->present = E1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
asn1cCalloc(drb_QoS_char->choice.non_Dynamic_5QI, non_Dynamic_5QI);
non_Dynamic_5QI->fiveQI = drb_QoS_char_in->non_dynamic.fiveqi;
} else {
drb_QoS_char->present = E1AP_QoS_Characteristics_PR_dynamic_5QI;
asn1cCalloc(drb_QoS_char->choice.dynamic_5QI, dynamic_5QI);
dynamic_5QI->qoSPriorityLevel = drb_QoS_char_in->dynamic.qos_priority_level;
dynamic_5QI->packetDelayBudget = drb_QoS_char_in->dynamic.packet_delay_budget;
dynamic_5QI->packetErrorRate.pER_Exponent = drb_QoS_char_in->dynamic.packet_error_rate.per_exponent;
dynamic_5QI->packetErrorRate.pER_Scalar = drb_QoS_char_in->dynamic.packet_error_rate.per_scalar;
}
/* GBR Info for DRB */
E1AP_GBR_QoSFlowInformation_t *drb_QoS_gbr_info =
drb_to_setup_item_ng_ran_extIEs->extensionValue.choice.QoSFlowLevelQoSParameters.gBR_QoS_Flow_Information;
gbr_qos_flow_information_t *drb_QoS_gbr_info_in = j->dRB_QoS.gbr_qos_flow_info;
if (drb_QoS_gbr_info_in) {
asn_long2INTEGER(&drb_QoS_gbr_info->guaranteedFlowBitRateDownlink, drb_QoS_gbr_info_in->gbr_dl);
asn_long2INTEGER(&drb_QoS_gbr_info->guaranteedFlowBitRateUplink, drb_QoS_gbr_info_in->gbr_ul);
asn_long2INTEGER(&drb_QoS_gbr_info->maxFlowBitRateDownlink, drb_QoS_gbr_info_in->mbr_dl);
asn_long2INTEGER(&drb_QoS_gbr_info->maxFlowBitRateUplink, drb_QoS_gbr_info_in->mbr_ul);
}
/* todo: ngran allocation retention priority for DRB still needs to be implemented */
}
}
return 0;
@@ -870,7 +965,7 @@ int e1apCUUP_send_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance)
return -1;
}
static void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_req_t *bearerCxt)
void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1ap_bearer_setup_req_t *bearerCxt)
{
const E1AP_BearerContextSetupRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextSetupRequest;
E1AP_BearerContextSetupRequestIEs_t *ie;
@@ -994,32 +1089,75 @@ static void extract_BEARER_CONTEXT_SETUP_REQUEST(const E1AP_E1AP_PDU_t *pdu, e1a
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_flow = drb->qosFlows + k;
E1AP_QoS_Flow_QoS_Parameter_Item_t *qos2Setup = qos2SetupList->list.array[k];
qos_flow->qfi = qos2Setup->qoS_Flow_Identifier;
e1ap_read_qos_flow_qos_parameters(qos2SetupList, drb->qosFlows, qos2SetupList->list.count);
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_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_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;
/* 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_ProtocolIE_ID_id_DRB_QoS:
DevAssert(ext->criticality == E1AP_Criticality_reject);
switch (ext->extensionValue.present) {
case E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs__extensionValue_PR_NOTHING:
break;
case E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs__extensionValue_PR_QoSFlowLevelQoSParameters: {
LOG_E(E1AP,
"E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs: Received QoSFlowLevelQoSParameters(%d) extension\n",
(int)ext->id);
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_5QI;
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_5QI;
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;
}
gbr_qos_flow_information_t *drb_gbr_qos_info = drb->dRB_QoS.gbr_qos_flow_info;
E1AP_GBR_QoSFlowInformation_t *drb_gbr_qos2setup =
ext->extensionValue.choice.QoSFlowLevelQoSParameters.gBR_QoS_Flow_Information;
if (drb_gbr_qos2setup) {
asn_INTEGER2long(&drb_gbr_qos2setup->guaranteedFlowBitRateDownlink, &drb_gbr_qos_info->gbr_dl);
asn_INTEGER2long(&drb_gbr_qos2setup->guaranteedFlowBitRateUplink, &drb_gbr_qos_info->gbr_ul);
asn_INTEGER2long(&drb_gbr_qos2setup->maxFlowBitRateDownlink, &drb_gbr_qos_info->mbr_dl);
asn_INTEGER2long(&drb_gbr_qos2setup->maxFlowBitRateUplink, &drb_gbr_qos_info->mbr_ul);
}
/* 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:
LOG_E(E1AP, "E1AP_DRB_To_Setup_Item_NG_RAN_ExtIEs: %d unknown extension id\n", (int)ext->id);
break;
}
}
}
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;
}
}
}
@@ -1395,6 +1533,65 @@ static void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *p
dl_up_param->cell_group_id = dl_up_param_in->cell_Group_ID;
}
}
E1AP_QoS_Flow_QoS_Parameter_List_t *qos2modifyList = drb2Mod->flow_Mapping_Information;
drb->numQosFlow2Setup = qos2modifyList->list.count;
e1ap_read_qos_flow_qos_parameters(qos2modifyList, drb->qosFlows, qos2modifyList->list.count);
/* DRB QoS */
if (drb2Mod->iE_Extensions) {
E1AP_ProtocolExtensionContainer_4961P46_t *IE_Ext =
(E1AP_ProtocolExtensionContainer_4961P46_t *)drb2Mod->iE_Extensions;
for (int extid = 0; extid < IE_Ext->list.count; extid++) {
E1AP_DRB_To_Setup_Mod_Item_NG_RAN_ExtIEs_t *ext = IE_Ext->list.array[extid];
switch (ext->id) {
case E1AP_ProtocolIE_ID_id_DRB_QoS:
DevAssert(ext->criticality == E1AP_Criticality_reject);
switch (ext->extensionValue.present) {
case E1AP_DRB_To_Modify_Item_NG_RAN_ExtIEs__extensionValue_PR_NOTHING:
break;
case E1AP_DRB_To_Modify_Item_NG_RAN_ExtIEs__extensionValue_PR_QoSFlowLevelQoSParameters: {
LOG_E(E1AP,
"E1AP_DRB_To_Modify_Item_NG_RAN_ExtIEs: Received QoSFlowLevelQoSParameters(%d) extension\n",
(int)ext->id);
E1AP_QoS_Characteristics_t *drbqos2Mod =
&ext->extensionValue.choice.QoSFlowLevelQoSParameters.qoS_Characteristics;
qos_characteristics_t *drb_qos = &drb->dRB_QoS.qos_characteristics;
if (drbqos2Mod->present == E1AP_QoS_Characteristics_PR_non_Dynamic_5QI) { // non-dynamic
drb_qos->qos_type = NON_DYNAMIC_5QI;
drb_qos->non_dynamic.fiveqi = drbqos2Mod->choice.non_Dynamic_5QI->fiveQI;
} else if (drbqos2Mod->present == E1AP_QoS_Characteristics_PR_dynamic_5QI) { // dynamic
drb_qos->qos_type = DYNAMIC_5QI;
drb_qos->dynamic.qos_priority_level = drbqos2Mod->choice.dynamic_5QI->qoSPriorityLevel;
drb_qos->dynamic.packet_delay_budget = drbqos2Mod->choice.dynamic_5QI->packetDelayBudget;
drb_qos->dynamic.packet_error_rate.per_exponent =
drbqos2Mod->choice.dynamic_5QI->packetErrorRate.pER_Exponent;
drb_qos->dynamic.packet_error_rate.per_scalar =
drbqos2Mod->choice.dynamic_5QI->packetErrorRate.pER_Scalar;
}
gbr_qos_flow_information_t *drb_gbr_qos_info = drb->dRB_QoS.gbr_qos_flow_info;
E1AP_GBR_QoSFlowInformation_t *drb_gbr_qos2mod =
ext->extensionValue.choice.QoSFlowLevelQoSParameters.gBR_QoS_Flow_Information;
if (drb_gbr_qos2mod) {
asn_INTEGER2long(&drb_gbr_qos2mod->guaranteedFlowBitRateDownlink, &drb_gbr_qos_info->gbr_dl);
asn_INTEGER2long(&drb_gbr_qos2mod->guaranteedFlowBitRateUplink, &drb_gbr_qos_info->gbr_ul);
asn_INTEGER2long(&drb_gbr_qos2mod->maxFlowBitRateDownlink, &drb_gbr_qos_info->mbr_dl);
asn_INTEGER2long(&drb_gbr_qos2mod->maxFlowBitRateUplink, &drb_gbr_qos_info->mbr_ul);
}
/* todo: ngran allocation retention priority for DRB still needs to be implemented */
break;
}
default:
LOG_E(E1AP, "E1AP_DRB_To_Modify_Item_NG_RAN_ExtIEs: %d unknown extension id\n", (int)ext->id);
break;
}
}
}
}
}
}
break;

View File

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

View File

@@ -21,6 +21,7 @@
* contact@openairinterface.org
*/
#define _GNU_SOURCE
#include <time.h>
#include <stdlib.h>
#include "e1ap_common.h"
@@ -28,6 +29,7 @@
#include "e1ap_asnc.h"
#include "common/openairinterface5g_limits.h"
#include "common/utils/ocp_itti/intertask_interface.h"
#include "openair2/COMMON/qos_values.h"
static e1ap_upcp_inst_t *e1ap_inst[NUMBER_OF_gNB_MAX] = {0};
@@ -243,3 +245,68 @@ int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, E1AP_E1AP_PDU_t *pdu, uin
return encoded;
}
uint64_t get_5QI_id(uint64_t fiveqi)
{
for (int id = 0; id < STANDARIZED_5QI_NUM; id++) {
if (params_5QI[id].five_QI == fiveqi)
return id;
}
AssertFatal(1 == 0, "Invalid 5QI value\n");
}
int get_non_dynamic_priority(int fiveqi)
{
for (int i = 0; i < STANDARIZED_5QI_NUM; ++i)
if (params_5QI[i].five_QI == fiveqi)
return params_5QI[i].priority_level;
AssertFatal(false, "illegal 5QI value %d\n", fiveqi);
return 0;
}
static int qos_cmp(const void *a, const void *b)
{
qos_characteristics_t *flow1 = &((qos_flow_to_setup_t *)a)->qos_params.qos_characteristics;
qos_characteristics_t *flow2 = &((qos_flow_to_setup_t *)b)->qos_params.qos_characteristics;
int priority1 =
flow1->qos_type == DYNAMIC_5QI ? flow1->dynamic.qos_priority_level : get_non_dynamic_priority(flow1->non_dynamic.fiveqi);
int priority2 =
flow2->qos_type == DYNAMIC_5QI ? flow2->dynamic.qos_priority_level : get_non_dynamic_priority(flow2->non_dynamic.fiveqi);
return priority1 - priority2;
}
void get_drb_characteristics(qos_flow_to_setup_t *qos_flows_in, int num_qos_flows, 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;
qsort(qos_flow, num_qos_flows, sizeof(qos_flow_to_setup_t), qos_cmp);
qos_characteristics_t *qos_char = &qos_flow->qos_params.qos_characteristics;
if (qos_char->qos_type == NON_DYNAMIC_5QI) {
non_dynamic_t *flow_char_non = &qos_char->non_dynamic;
non_dynamic_t *drb_char_non = &qos_char_drb->non_dynamic;
qos_char_drb->qos_type = NON_DYNAMIC_5QI;
drb_char_non->fiveqi = flow_char_non->fiveqi;
} else {
dynamic_t *flow_char_dy = &qos_char->dynamic;
dynamic_t *drb_char_dy = &qos_char_drb->dynamic;
qos_char_drb->qos_type = DYNAMIC_5QI;
drb_char_dy->qos_priority_level = flow_char_dy->qos_priority_level;
drb_char_dy->packet_delay_budget = flow_char_dy->packet_delay_budget;
drb_char_dy->packet_error_rate.per_exponent = flow_char_dy->packet_error_rate.per_exponent;
drb_char_dy->packet_error_rate.per_scalar = flow_char_dy->packet_error_rate.per_scalar;
}
/* GBR Information for a DRB */
gbr_qos_flow_information_t *gbr_in = qos_flow->qos_params.gbr_qos_flow_info;
if (gbr_in) {
dRB_QoS->gbr_qos_flow_info = calloc(1, sizeof(gbr_qos_flow_information_t));
dRB_QoS->gbr_qos_flow_info->gbr_dl = gbr_in->gbr_dl;
dRB_QoS->gbr_qos_flow_info->gbr_ul = gbr_in->gbr_ul;
dRB_QoS->gbr_qos_flow_info->mbr_dl = gbr_in->mbr_dl;
dRB_QoS->gbr_qos_flow_info->mbr_ul = gbr_in->mbr_ul;
}
}

View File

@@ -39,12 +39,13 @@
#include "rrc_extern.h"
#include "openair2/RRC/NR/rrc_gNB_NGAP.h"
static void f1ap_write_drb_qos_param(const f1ap_qos_flow_level_qos_parameters_t *drb_qos_in, F1AP_QoSFlowLevelQoSParameters_t *asn1_qosparam)
static void f1ap_write_drb_qos_param(const qos_flow_level_qos_parameters_t *drb_qos_in,
F1AP_QoSFlowLevelQoSParameters_t *asn1_qosparam)
{
int type = drb_qos_in->qos_characteristics.qos_type;
const f1ap_qos_characteristics_t *drb_qos_char_in = &drb_qos_in->qos_characteristics;
if (type == NON_DYNAMIC) {
const qos_characteristics_t *drb_qos_char_in = &drb_qos_in->qos_characteristics;
if (type == NON_DYNAMIC_5QI) {
asn1_qosparam->qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
asn1cCalloc(asn1_qosparam->qoS_Characteristics.choice.non_Dynamic_5QI, tmp);
@@ -80,12 +81,13 @@ static void f1ap_write_drb_qos_param(const f1ap_qos_flow_level_qos_parameters_t
/* OPTIONAL */
/* gBR_QoS_Flow_Information */
if (0) {
if (drb_qos_in->gbr_qos_flow_info) {
gbr_qos_flow_information_t *gbr_qos_flowinfo = drb_qos_in->gbr_qos_flow_info;
asn1cCalloc(asn1_qosparam->gBR_QoS_Flow_Information, tmp);
asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L);
asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L);
asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L);
asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L);
asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, gbr_qos_flowinfo->mbr_dl);
asn_long2INTEGER(&tmp->maxFlowBitRateUplink, gbr_qos_flowinfo->mbr_ul);
asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, gbr_qos_flowinfo->gbr_dl);
asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, gbr_qos_flowinfo->gbr_ul);
/* OPTIONAL */
/* maxPacketLossRateDownlink */
@@ -93,7 +95,7 @@ static void f1ap_write_drb_qos_param(const f1ap_qos_flow_level_qos_parameters_t
/* OPTIONAL */
/* maxPacketLossRateUplink */
//asn1cCallocOne(asn1_qosparam->gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
// asn1cCallocOne(asn1_qosparam->gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
}
/* OPTIONAL */
@@ -127,14 +129,14 @@ static void f1ap_write_flows_mapped(const f1ap_flows_mapped_to_drb_t *flows_mapp
flow_item->qoSFlowIdentifier = qos_flow_in->qfi;
/* qoSFlowLevelQoSParameters */
const f1ap_qos_flow_level_qos_parameters_t *flow_qos_params_in = &qos_flow_in->qos_params;
const qos_flow_level_qos_parameters_t *flow_qos_params_in = &qos_flow_in->qos_params;
/* qoS_Characteristics */
F1AP_QoS_Characteristics_t *QosParams = &flow_item->qoSFlowLevelQoSParameters.qoS_Characteristics;
const f1ap_qos_characteristics_t *flow_qos_char_in = &flow_qos_params_in->qos_characteristics;
const qos_characteristics_t *flow_qos_char_in = &flow_qos_params_in->qos_characteristics;
int type = flow_qos_params_in->qos_characteristics.qos_type;
if (type == NON_DYNAMIC) {
if (type == NON_DYNAMIC_5QI) {
QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
asn1cCalloc(QosParams->choice.non_Dynamic_5QI, tmp);
@@ -173,18 +175,20 @@ static void f1ap_write_flows_mapped(const f1ap_flows_mapped_to_drb_t *flows_mapp
/* OPTIONAL */
/* gBR_QoS_Flow_Information */
if (0) {
if (flow_qos_params_in->gbr_qos_flow_info) {
gbr_qos_flow_information_t *gbr_qos_flowinfo = flow_qos_params_in->gbr_qos_flow_info;
asn1cCalloc(flow_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information, tmp);
asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, 1L);
asn_long2INTEGER(&tmp->maxFlowBitRateUplink, 1L);
asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, 1L);
asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, 1L);
asn_long2INTEGER(&tmp->maxFlowBitRateDownlink, gbr_qos_flowinfo->mbr_dl);
asn_long2INTEGER(&tmp->maxFlowBitRateUplink, gbr_qos_flowinfo->mbr_ul);
asn_long2INTEGER(&tmp->guaranteedFlowBitRateDownlink, gbr_qos_flowinfo->gbr_dl);
asn_long2INTEGER(&tmp->guaranteedFlowBitRateUplink, gbr_qos_flowinfo->gbr_ul);
/* OPTIONAL maxPacketLossRateDownlink */
//asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L);
// asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink,
// 1L);
/* OPTIONAL maxPacketLossRateUplink */
//asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
// asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
}
/* OPTIONAL reflective_QoS_Attribute */

View File

@@ -39,19 +39,19 @@
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
static void f1ap_read_drb_qos_param(const F1AP_QoSFlowLevelQoSParameters_t *asn1_qos, f1ap_qos_flow_level_qos_parameters_t *drb_qos)
static void f1ap_read_drb_qos_param(const F1AP_QoSFlowLevelQoSParameters_t *asn1_qos, qos_flow_level_qos_parameters_t *drb_qos)
{
f1ap_qos_characteristics_t *drb_qos_char = &drb_qos->qos_characteristics;
qos_characteristics_t *drb_qos_char = &drb_qos->qos_characteristics;
const F1AP_QoS_Characteristics_t *dRB_QoS_Char = &asn1_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->qos_type = NON_DYNAMIC_5QI;
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->qos_type = DYNAMIC_5QI;
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;
@@ -64,6 +64,16 @@ static void f1ap_read_drb_qos_param(const F1AP_QoSFlowLevelQoSParameters_t *asn1
drb_qos->alloc_reten_priority.priority_level = asn1_qos->nGRANallocationRetentionPriority.priorityLevel;
drb_qos->alloc_reten_priority.preemption_vulnerability = asn1_qos->nGRANallocationRetentionPriority.pre_emptionVulnerability;
drb_qos->alloc_reten_priority.preemption_capability = asn1_qos->nGRANallocationRetentionPriority.pre_emptionVulnerability;
/* gbr qos information */
if (asn1_qos->gBR_QoS_Flow_Information) {
asn1cCalloc(drb_qos->gbr_qos_flow_info, tmp);
F1AP_GBR_QoSFlowInformation_t *gbr_qos_flowinfo = asn1_qos->gBR_QoS_Flow_Information;
asn_INTEGER2long(&gbr_qos_flowinfo->guaranteedFlowBitRateDownlink, &tmp->gbr_dl);
asn_INTEGER2long(&gbr_qos_flowinfo->guaranteedFlowBitRateUplink, &tmp->gbr_ul);
asn_INTEGER2long(&gbr_qos_flowinfo->maxFlowBitRateDownlink, &tmp->mbr_dl);
asn_INTEGER2long(&gbr_qos_flowinfo->maxFlowBitRateUplink, &tmp->mbr_ul);
}
}
static void f1ap_read_flows_mapped(const F1AP_Flows_Mapped_To_DRB_List_t *asn1_flows_mapped, f1ap_flows_mapped_to_drb_t *flows_mapped, int n)
@@ -76,21 +86,21 @@ static void f1ap_read_flows_mapped(const F1AP_Flows_Mapped_To_DRB_List_t *asn1_f
/* 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;
const 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;
const 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->qos_type = NON_DYNAMIC_5QI;
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->qos_type = DYNAMIC_5QI;
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;
@@ -103,6 +113,16 @@ static void f1ap_read_flows_mapped(const F1AP_Flows_Mapped_To_DRB_List_t *asn1_f
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;
/* gbr qos information */
if (Flow_QoS->gBR_QoS_Flow_Information) {
F1AP_GBR_QoSFlowInformation_t *gbr_qos_flowinfo = Flow_QoS->gBR_QoS_Flow_Information;
asn1cCalloc(flow_qos->gbr_qos_flow_info, tmp);
asn_INTEGER2long(&gbr_qos_flowinfo->guaranteedFlowBitRateDownlink, &tmp->gbr_dl);
asn_INTEGER2long(&gbr_qos_flowinfo->guaranteedFlowBitRateUplink, &tmp->gbr_ul);
asn_INTEGER2long(&gbr_qos_flowinfo->maxFlowBitRateDownlink, &tmp->mbr_dl);
asn_INTEGER2long(&gbr_qos_flowinfo->maxFlowBitRateUplink, &tmp->mbr_ul);
}
}
}
}

View File

@@ -24,6 +24,7 @@
#include "mac_proto.h"
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/F1AP/f1ap_common.h"
#include "openair2/COMMON/qos_values.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "F1AP_CauseRadioNetwork.h"
#include "NR_HandoverPreparationInformation.h"
@@ -36,11 +37,6 @@
#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 instance_t get_f1_gtp_instance(void)
{
const f1ap_cudu_inst_t *inst = getCxt(0);
@@ -257,26 +253,17 @@ static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_set
return get_DRB_RLC_BearerConfig(get_lcid_from_drbid(drb->drb_id), drb->drb_id, rlc_conf, priority);
}
static int get_non_dynamic_priority(int fiveqi)
{
for (int i = 0; i < sizeofArray(qos_fiveqi); ++i)
if (qos_fiveqi[i] == fiveqi)
return qos_priority[i];
AssertFatal(false, "illegal 5QI value %d\n", fiveqi);
return 0;
}
static NR_QoS_config_t get_qos_config(const f1ap_qos_characteristics_t *qos_char)
static NR_QoS_config_t get_qos_config(const qos_characteristics_t *qos_char)
{
NR_QoS_config_t qos_c = {0};
switch (qos_char->qos_type) {
case DYNAMIC:
case DYNAMIC_5QI:
qos_c.priority = qos_char->dynamic.qos_priority_level;
qos_c.fiveQI = qos_char->dynamic.fiveqi > 0 ? qos_char->dynamic.fiveqi : 0;
break;
case NON_DYNAMIC:
case NON_DYNAMIC_5QI:
qos_c.fiveQI = qos_char->non_dynamic.fiveqi;
qos_c.priority = get_non_dynamic_priority(qos_char->non_dynamic.fiveqi);
qos_c.priority = params_5QI[get_5QI_id(qos_c.fiveQI)].priority_level;
break;
default:
AssertFatal(false, "illegal QoS type %d\n", qos_char->qos_type);
@@ -285,6 +272,39 @@ static NR_QoS_config_t get_qos_config(const f1ap_qos_characteristics_t *qos_char
return qos_c;
}
static int get_qos_priority(const qos_characteristics_t *qos_char)
{
int prio;
if (qos_char->qos_type == NON_DYNAMIC_5QI)
prio = get_non_dynamic_priority(qos_char->non_dynamic.fiveqi);
else
prio = qos_char->dynamic.qos_priority_level;
return prio;
}
static nr_lc_config_t nr_prepare_lcconfig(long lcid, const f1ap_drb_to_be_setup_t *drb)
{
const gbr_qos_flow_information_t *gbr_qos_info_drb = drb->drb_info.drb_qos.gbr_qos_flow_info;
const qos_characteristics_t *qos_char = &drb->drb_info.drb_qos.qos_characteristics;
nr_lc_config_t c = {.lcid = lcid, .nssai = drb->nssai};
for (int q = 0; q < drb->drb_info.flows_to_be_setup_length; ++q) {
c.qos_config[q] = get_qos_config(&drb->drb_info.flows_mapped_to_drb[q].qos_params.qos_characteristics);
}
c.priority = get_qos_priority(qos_char);
int m_bitrate = gbr_qos_info_drb ? gbr_qos_info_drb->gbr_dl : 0;
int g_bitrate = gbr_qos_info_drb ? gbr_qos_info_drb->mbr_dl : 0;
c.guaranteed_bitrate = g_bitrate;
c.max_bitrate = m_bitrate;
return c;
}
static int handle_ue_context_drbs_setup(NR_UE_info_t *UE,
int drbs_len,
const f1ap_drb_to_be_setup_t *req_drbs,
@@ -300,17 +320,13 @@ static int handle_ue_context_drbs_setup(NR_UE_info_t *UE,
AssertFatal(*resp_drbs != NULL, "out of memory\n");
for (int i = 0; i < drbs_len; i++) {
const f1ap_drb_to_be_setup_t *drb = &req_drbs[i];
f1ap_drb_to_be_setup_t *resp_drb = &(*resp_drbs)[i];
NR_RLC_BearerConfig_t *rlc_BearerConfig = get_bearerconfig_from_drb(drb);
nr_rlc_add_drb(UE->rnti, drb->drb_id, rlc_BearerConfig);
nr_lc_config_t c = {.lcid = rlc_BearerConfig->logicalChannelIdentity, .nssai = drb->nssai};
int prio = 100;
for (int q = 0; q < drb->drb_info.flows_to_be_setup_length; ++q) {
c.qos_config[q] = get_qos_config(&drb->drb_info.flows_mapped_to_drb[q].qos_params.qos_characteristics);
prio = min(prio, c.qos_config[q].priority);
}
c.priority = prio;
nr_lc_config_t c = nr_prepare_lcconfig(rlc_BearerConfig->logicalChannelIdentity, drb);
nr_mac_add_lcid(&UE->UE_sched_ctrl, &c);
*resp_drb = *drb;

View File

@@ -569,6 +569,8 @@ typedef struct nr_lc_config {
int priority;
/// associated NSSAI for DRB
nssai_t nssai;
uint64_t max_bitrate;
uint64_t guaranteed_bitrate;
/// QoS config for DRB
NR_QoS_config_t qos_config[NR_MAX_NUM_QFI];
} nr_lc_config_t;

View File

@@ -131,6 +131,6 @@ void rrc_gNB_generate_UeContextModificationRequest(const gNB_RRC_INST *rrc,
const f1ap_drb_to_be_released_t *rel_drbs);
pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi, rrc_pdu_session_param_t *pduSession);
f1ap_qos_characteristics_t get_qos_char_from_qos_flow_param(const pdusession_level_qos_parameter_t *qos_param);
qos_characteristics_t get_qos_char_from_qos_flow_param(const pdusession_level_qos_parameter_t *qos_param);
#endif

View File

@@ -97,6 +97,7 @@
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/F1AP/lib/f1ap_lib_extern.h"
#include "openair2/SDAP/nr_sdap/nr_sdap_entity.h"
#include "openair2/COMMON/qos_values.h"
#include "openair2/E1AP/e1ap.h"
#include "cucp_cuup_if.h"
#include "lib/f1ap_interface_management.h"
@@ -2191,16 +2192,16 @@ pdusession_level_qos_parameter_t *get_qos_characteristics(const int qfi, rrc_pdu
return NULL;
}
/* \bref return F1AP QoS characteristics based on Qos flow parameters */
f1ap_qos_characteristics_t get_qos_char_from_qos_flow_param(const pdusession_level_qos_parameter_t *qos_param)
/* \bref return qos characteristics based on Qos flow parameters */
static qos_characteristics_t get_qos_char_from_qos_flow_param(const pdusession_level_qos_parameter_t *qos_param)
{
f1ap_qos_characteristics_t qos_char = {0};
if (qos_param->fiveQI_type == DYNAMIC) {
qos_char.qos_type = DYNAMIC;
qos_characteristics_t qos_char = {0};
if (qos_param->fiveQI_type == DYNAMIC_5QI) {
qos_char.qos_type = DYNAMIC_5QI;
qos_char.dynamic.fiveqi = qos_param->fiveQI;
qos_char.dynamic.qos_priority_level = qos_param->qos_priority;
} else {
qos_char.qos_type = NON_DYNAMIC;
qos_char.qos_type = NON_DYNAMIC_5QI;
qos_char.non_dynamic.fiveqi = qos_param->fiveQI;
qos_char.non_dynamic.qos_priority_level = qos_param->qos_priority;
}
@@ -2238,10 +2239,28 @@ static int fill_drb_to_be_setup_from_e1_resp(const gNB_RRC_INST *rrc,
for (int j = 0; j < nb_qos_flows; j++) {
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);
drb->drb_info.flows_mapped_to_drb[j].qos_params.qos_characteristics = get_qos_char_from_qos_flow_param(in_qos_char);
qos_flow_level_qos_parameters_t *qos_params = &drb->drb_info.flows_mapped_to_drb[j].qos_params;
qos_characteristics_t *qos_char = &qos_params->qos_characteristics;
if (in_qos_char->fiveQI_type == DYNAMIC_5QI) {
qos_char->qos_type = DYNAMIC_5QI;
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_5QI;
qos_char->non_dynamic.fiveqi = in_qos_char->fiveQI;
qos_char->non_dynamic.qos_priority_level = in_qos_char->qos_priority;
}
gbr_qos_flow_information_t *gbr_qos_info = &in_qos_char->gbr_qos_flow_level_qos_params;
asn1cCalloc(qos_params->gbr_qos_flow_info, gbr_info);
memcpy(gbr_info, gbr_qos_info, sizeof(gbr_qos_flow_information_t));
}
/* 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.drb_qos);
/* pass NSSAI info to MAC */
drb->nssai = RRC_pduSession->param.nssai;

View File

@@ -221,11 +221,11 @@ static void fill_qos(NGAP_QosFlowSetupRequestList_t *qos, pdusession_t *session)
AssertFatal(qosChar, "Qos characteristics are not available for qos flow index %d\n", qosIdx);
if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) {
AssertFatal(qosChar->choice.dynamic5QI, "Non-Dynamic 5QI is NULL\n");
session->qos[qosIdx].fiveQI_type = NON_DYNAMIC;
session->qos[qosIdx].fiveQI_type = NON_DYNAMIC_5QI;
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_type = DYNAMIC_5QI;
session->qos[qosIdx].fiveQI = (uint64_t)(*qosChar->choice.dynamic5QI->fiveQI);
}
@@ -385,7 +385,7 @@ void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession
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) {
if (qos_char->qos_type == DYNAMIC_5QI) {
qos_char->dynamic.fiveqi = qos_session->fiveQI;
qos_char->dynamic.qos_priority_level = qos_session->qos_priority;
} else {
@@ -395,9 +395,16 @@ void trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession
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);
/* todo: should be modified here for gbr info of the qos flow (temporary fix) */
if ((qos_char->qos_type == NON_DYNAMIC_5QI && qos_session->fiveQI < 5) || qos_char->qos_type == DYNAMIC_5QI) {
qos_session->gbr_qos_flow_level_qos_params.gbr_dl = (long)ueAggMaxBitRateDownlink;
asn1cCalloc(qos_flow->qos_params.gbr_qos_flow_info, gbr_ie);
gbr_ie->gbr_dl = qos_session->gbr_qos_flow_level_qos_params.gbr_dl;
}
}
}
}
@@ -796,11 +803,11 @@ static void fill_qos2(NGAP_QosFlowAddOrModifyRequestList_t *qos, pdusession_t *s
AssertFatal(qosChar, "Qos characteristics are not available for qos flow index %d\n", qosIdx);
if (qosChar->present == NGAP_QosCharacteristics_PR_nonDynamic5QI) {
AssertFatal(qosChar->choice.dynamic5QI, "Non-Dynamic 5QI is NULL\n");
session->qos[qosIdx].fiveQI_type = NON_DYNAMIC;
session->qos[qosIdx].fiveQI_type = NON_DYNAMIC_5QI;
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_type = DYNAMIC_5QI;
session->qos[qosIdx].fiveQI = (uint64_t)(*qosChar->choice.dynamic5QI->fiveQI);
}

View File

@@ -24,11 +24,42 @@
#include <openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h>
#include <openair3/ocp-gtpu/gtp_itf.h>
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h"
#include "openair2/COMMON/qos_flow_messages_types.h"
#include <stdlib.h>
#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 standard_5QI_characteristics_t params_5QI[] = {
{FIVEQI_1, PRIORITY_20, GBR},
{FIVEQI_2, PRIORITY_40, GBR},
{FIVEQI_3, PRIORITY_30, GBR},
{FIVEQI_4, PRIORITY_50, GBR},
{FIVEQI_65, PRIORITY_7, GBR},
{FIVEQI_66, PRIORITY_20, GBR},
{FIVEQI_67, PRIORITY_15, GBR},
{FIVEQI_71, PRIORITY_56, GBR},
{FIVEQI_72, PRIORITY_56, GBR},
{FIVEQI_73, PRIORITY_56, GBR},
{FIVEQI_74, PRIORITY_56, GBR},
{FIVEQI_76, PRIORITY_56, GBR},
{FIVEQI_5, PRIORITY_10, GBR},
{FIVEQI_6, PRIORITY_60, NON_GBR},
{FIVEQI_7, PRIORITY_70, NON_GBR},
{FIVEQI_8, PRIORITY_80, NON_GBR},
{FIVEQI_9, PRIORITY_90, NON_GBR},
{FIVEQI_69, PRIORITY_5, NON_GBR},
{FIVEQI_70, PRIORITY_55, NON_GBR},
{FIVEQI_79, PRIORITY_65, NON_GBR},
{FIVEQI_80, PRIORITY_68, NON_GBR},
{FIVEQI_82, PRIORITY_19, NON_GBR},
{FIVEQI_83, PRIORITY_22, DELAY_CRITICAL_GBR},
{FIVEQI_84, PRIORITY_24, DELAY_CRITICAL_GBR},
{FIVEQI_85, PRIORITY_21, DELAY_CRITICAL_GBR},
{FIVEQI_86, PRIORITY_18, DELAY_CRITICAL_GBR},
};
typedef struct {
nr_sdap_entity_t *sdap_entity_llist;
} nr_sdap_entity_info;