Merge remote-tracking branch 'origin/fixes-gtp-f1' into integration_2024_w11
This commit is contained in:
@@ -38,31 +38,153 @@
|
||||
|
||||
#include "rrc_extern.h"
|
||||
#include "openair2/RRC/NR/rrc_gNB_NGAP.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
static void setQos(F1AP_NonDynamic5QIDescriptor_t **toFill)
|
||||
static void f1ap_write_drb_qos_param(const f1ap_qos_flow_level_qos_parameters_t *drb_qos_in, F1AP_QoSFlowLevelQoSParameters_t *asn1_qosparam)
|
||||
{
|
||||
asn1cCalloc(*toFill, tmp);
|
||||
/* fiveQI */
|
||||
tmp->fiveQI = 1L;
|
||||
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) {
|
||||
asn1_qosparam->qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
|
||||
asn1cCalloc(asn1_qosparam->qoS_Characteristics.choice.non_Dynamic_5QI, tmp);
|
||||
|
||||
/* 5QI */
|
||||
tmp->fiveQI = drb_qos_char_in->non_dynamic.fiveqi;
|
||||
} else {
|
||||
asn1_qosparam->qoS_Characteristics.present = F1AP_QoS_Characteristics_PR_dynamic_5QI;
|
||||
asn1cCalloc(asn1_qosparam->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 */
|
||||
// asn1cCallocOne(asn1_qosparam->qoS_Characteristics.choice.dynamic_5QI->delayCritical, 1L);
|
||||
|
||||
/* OPTIONAL averagingWindow */
|
||||
// asn1cCallocOne(asn1_qosparam->qoS_Characteristics.choice.dynamic_5QI->averagingWindow, 1L);
|
||||
|
||||
/* OPTIONAL maxDataBurstVolume */
|
||||
// asn1cCallocOne(asn1_qosparam->qoS_Characteristics.choice.dynamic_5QI->maxDataBurstVolume, 1L);
|
||||
}
|
||||
|
||||
{
|
||||
asn1_qosparam->nGRANallocationRetentionPriority.priorityLevel = drb_qos_in->alloc_reten_priority.priority_level;
|
||||
asn1_qosparam->nGRANallocationRetentionPriority.pre_emptionCapability = drb_qos_in->alloc_reten_priority.preemption_capability;
|
||||
asn1_qosparam->nGRANallocationRetentionPriority.pre_emptionVulnerability =
|
||||
drb_qos_in->alloc_reten_priority.preemption_vulnerability;
|
||||
} // nGRANallocationRetentionPriority
|
||||
|
||||
/* OPTIONAL */
|
||||
/* qoSPriorityLevel */
|
||||
/* gBR_QoS_Flow_Information */
|
||||
if (0) {
|
||||
asn1cCallocOne((*toFill)->qoSPriorityLevel, 1L);
|
||||
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);
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxPacketLossRateDownlink */
|
||||
// asn1cCallocOne(asn1_qosparam->gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L);
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxPacketLossRateUplink */
|
||||
//asn1cCallocOne(asn1_qosparam->gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* averagingWindow */
|
||||
/* reflective_QoS_Attribute */
|
||||
if (0) {
|
||||
asn1cCallocOne((*toFill)->averagingWindow, 1L);
|
||||
asn1cCallocOne(asn1_qosparam->reflective_QoS_Attribute, 1L);
|
||||
}
|
||||
}
|
||||
|
||||
static void f1ap_write_drb_nssai(const nssai_t *nssai, F1AP_SNSSAI_t *asn1_nssai)
|
||||
{
|
||||
OCTET_STRING_fromBuf(&asn1_nssai->sST, (char *)&nssai->sst, 1);
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxDataBurstVolume */
|
||||
if (0) {
|
||||
asn1cCallocOne((*toFill)->maxDataBurstVolume, 1L);
|
||||
if (nssai->sd != 0xffffff)
|
||||
OCTET_STRING_fromBuf(asn1_nssai->sD, (char *)&nssai->sd, 3);
|
||||
}
|
||||
|
||||
static void f1ap_write_flows_mapped(const f1ap_flows_mapped_to_drb_t *flows_mapped, F1AP_Flows_Mapped_To_DRB_List_t *asn1_flows_mapped, int n)
|
||||
{
|
||||
for (int k = 0; k < n; k++) {
|
||||
asn1cSequenceAdd(asn1_flows_mapped->list, F1AP_Flows_Mapped_To_DRB_Item_t, flow_item);
|
||||
|
||||
const f1ap_flows_mapped_to_drb_t *qos_flow_in = flows_mapped + k;
|
||||
|
||||
/* qoSFlowIndicator */
|
||||
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;
|
||||
/* 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;
|
||||
|
||||
int type = flow_qos_params_in->qos_characteristics.qos_type;
|
||||
if (type == non_dynamic) {
|
||||
QosParams->present = F1AP_QoS_Characteristics_PR_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 = flow_qos_char_in->dynamic.qos_priority_level;
|
||||
/* packetDelayBudget */
|
||||
tmp->packetDelayBudget = flow_qos_char_in->dynamic.packet_delay_budget;
|
||||
/* packetErrorRate */
|
||||
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 */
|
||||
//asn1cCallocOne(QosParams->choice.dynamic_5QI->delayCritical, 1);
|
||||
|
||||
/* OPTIONAL averagingWindow */
|
||||
//asn1cCallocOne(QosParams->choice.dynamic_5QI->averagingWindow, 1);
|
||||
|
||||
/* OPTIONAL maxDataBurstVolume */
|
||||
//asn1cCallocOne(QosParams->choice.dynamic_5QI->maxDataBurstVolume, 1);
|
||||
}
|
||||
|
||||
/* nGRANallocationRetentionPriority */
|
||||
{
|
||||
flow_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.priorityLevel =
|
||||
flow_qos_params_in->alloc_reten_priority.priority_level;
|
||||
flow_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionCapability =
|
||||
flow_qos_params_in->alloc_reten_priority.preemption_capability;
|
||||
flow_item->qoSFlowLevelQoSParameters.nGRANallocationRetentionPriority.pre_emptionVulnerability =
|
||||
flow_qos_params_in->alloc_reten_priority.preemption_vulnerability;
|
||||
} // nGRANallocationRetentionPriority
|
||||
|
||||
/* OPTIONAL */
|
||||
/* gBR_QoS_Flow_Information */
|
||||
if (0) {
|
||||
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);
|
||||
|
||||
/* OPTIONAL maxPacketLossRateDownlink */
|
||||
//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);
|
||||
}
|
||||
|
||||
/* OPTIONAL reflective_QoS_Attribute */
|
||||
//asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +397,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
|
||||
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++) {
|
||||
//
|
||||
const f1ap_drb_to_be_setup_t *drb = &f1ap_ue_context_setup_req->drbs_to_be_setup[i];
|
||||
asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetup_List.list, F1AP_DRBs_ToBeSetup_ItemIEs_t, drbs_toBeSetup_item_ies);
|
||||
drbs_toBeSetup_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetup_Item;
|
||||
drbs_toBeSetup_item_ies->criticality = F1AP_Criticality_reject;
|
||||
@@ -283,7 +405,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
|
||||
/* 12.1 DRBs_ToBeSetup_Item */
|
||||
F1AP_DRBs_ToBeSetup_Item_t *drbs_toBeSetup_item=&drbs_toBeSetup_item_ies->value.choice.DRBs_ToBeSetup_Item;
|
||||
/* 12.1.1 dRBID */
|
||||
drbs_toBeSetup_item->dRBID = f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id; // 9
|
||||
drbs_toBeSetup_item->dRBID = drb->drb_id;
|
||||
/* 12.1.2 qoSInformation */
|
||||
int some_decide_qos = 0; // BK: Need Check
|
||||
|
||||
@@ -314,6 +436,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
|
||||
}
|
||||
} else {
|
||||
/* 12.1.2 DRB_Information */
|
||||
const f1ap_drb_information_t *drb_info = &drb->drb_info;
|
||||
drbs_toBeSetup_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;
|
||||
@@ -321,90 +444,12 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
|
||||
ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information;
|
||||
F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information;
|
||||
drbs_toBeSetup_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie;
|
||||
|
||||
/* 12.1.2.1 dRB_QoS */
|
||||
{
|
||||
/* qoS_Characteristics */
|
||||
{
|
||||
int some_decide_qoS_characteristics = 0; // BK: Need Check
|
||||
f1ap_write_drb_qos_param(&drb_info->drb_qos, &DRB_Information->dRB_QoS);
|
||||
|
||||
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);
|
||||
} 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;
|
||||
|
||||
/* 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 */
|
||||
/* 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
|
||||
} // nGRANallocationRetentionPriority
|
||||
|
||||
/* OPTIONAL */
|
||||
/* gBR_QoS_Flow_Information */
|
||||
if (0) {
|
||||
asn1cCalloc(DRB_Information->dRB_QoS.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);
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxPacketLossRateDownlink */
|
||||
if (0) {
|
||||
asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L);
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxPacketLossRateUplink */
|
||||
if (0) {
|
||||
asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
|
||||
}
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* reflective_QoS_Attribute */
|
||||
if (0) {
|
||||
asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L);
|
||||
}
|
||||
} // dRB_QoS
|
||||
/* 12.1.2.2 sNSSAI */
|
||||
{
|
||||
/* sST */
|
||||
OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, (char *)&f1ap_ue_context_setup_req->drbs_to_be_setup[i].nssai.sst, 1);
|
||||
|
||||
/* OPTIONAL */
|
||||
const uint32_t sd = (f1ap_ue_context_setup_req->drbs_to_be_setup[i].nssai.sd & 0xffffff);
|
||||
if (sd != 0xffffff)
|
||||
OCTET_STRING_fromBuf(DRB_Information->sNSSAI.sD, (char *)&sd, 3);
|
||||
}
|
||||
f1ap_write_drb_nssai(&drb->nssai, &DRB_Information->sNSSAI);
|
||||
|
||||
/* OPTIONAL */
|
||||
/* 12.1.2.3 notificationControl */
|
||||
@@ -414,108 +459,12 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
|
||||
}
|
||||
|
||||
/* 12.1.2.4 flows_Mapped_To_DRB_List */ // BK: need verifiy
|
||||
|
||||
for (int k = 0; k < 1; k ++) {
|
||||
asn1cSequenceAdd(DRB_Information->flows_Mapped_To_DRB_List.list,
|
||||
F1AP_Flows_Mapped_To_DRB_Item_t, flows_mapped_to_drb_item);
|
||||
/* qoSFlowIndicator */
|
||||
flows_mapped_to_drb_item->qoSFlowIdentifier = 1L;
|
||||
/* qoSFlowLevelQoSParameters */
|
||||
{
|
||||
/* qoS_Characteristics */
|
||||
{
|
||||
int some_decide_qoS_characteristics = 0; // BK: Need Check
|
||||
F1AP_QoS_Characteristics_t *QosParams=&flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.qoS_Characteristics;
|
||||
|
||||
if (some_decide_qoS_characteristics) {
|
||||
QosParams->present = F1AP_QoS_Characteristics_PR_non_Dynamic_5QI;
|
||||
setQos(&QosParams->choice.non_Dynamic_5QI);
|
||||
} else {
|
||||
QosParams->present = F1AP_QoS_Characteristics_PR_dynamic_5QI;
|
||||
asn1cCalloc(QosParams->choice.dynamic_5QI, tmp);
|
||||
/* qoSPriorityLevel */
|
||||
tmp->qoSPriorityLevel = 1L;
|
||||
/* packetDelayBudget */
|
||||
tmp->packetDelayBudget = 1L;
|
||||
/* packetErrorRate */
|
||||
tmp->packetErrorRate.pER_Scalar = 1L;
|
||||
tmp->packetErrorRate.pER_Exponent = 6L;
|
||||
|
||||
/* OPTIONAL */
|
||||
/* delayCritical */
|
||||
if (0) {
|
||||
asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp);
|
||||
*tmp = 1L;
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* averagingWindow */
|
||||
if (0) {
|
||||
asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp);
|
||||
*tmp = 1L;
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxDataBurstVolume */
|
||||
if (0) {
|
||||
asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp);
|
||||
*tmp= 1L;
|
||||
}
|
||||
} // if some_decide_qoS_characteristics
|
||||
} // 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
|
||||
} // nGRANallocationRetentionPriority
|
||||
|
||||
/* OPTIONAL */
|
||||
/* gBR_QoS_Flow_Information */
|
||||
if (0) {
|
||||
asn1cCalloc(flows_mapped_to_drb_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);
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxPacketLossRateDownlink */
|
||||
if (0) {
|
||||
asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L);
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxPacketLossRateUplink */
|
||||
if (0) {
|
||||
asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
|
||||
}
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* reflective_QoS_Attribute */
|
||||
if (0) {
|
||||
asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L);
|
||||
}
|
||||
} // qoSFlowLevelQoSParameters
|
||||
}
|
||||
f1ap_write_flows_mapped(drb_info->flows_mapped_to_drb, &DRB_Information->flows_Mapped_To_DRB_List, drb_info->flows_to_be_setup_length);
|
||||
} // if some_decide_qos
|
||||
|
||||
/* 12.1.3 uLUPTNLInformation_ToBeSetup_List */
|
||||
for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) {
|
||||
/*Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU*/
|
||||
/* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */
|
||||
transport_layer_addr_t addr = { .length= 32, .buffer= { 0 } };
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst,
|
||||
f1ap_ue_context_setup_req->gNB_CU_ue_id,
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id,
|
||||
0xFFFF, // We will set the right value from DU answer
|
||||
-1, // no qfi
|
||||
addr, // We will set the right value from DU answer
|
||||
f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port,
|
||||
cu_f1u_data_req,
|
||||
NULL);
|
||||
DevAssert(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid > 0);
|
||||
/* 12.3.1 ULTunnels_ToBeSetup_Item */
|
||||
asn1cSequenceAdd(drbs_toBeSetup_item->uLUPTNLInformation_ToBeSetup_List.list,
|
||||
F1AP_ULUPTNLInformation_ToBeSetup_Item_t, uLUPTNLInformation_ToBeSetup_Item);
|
||||
@@ -688,11 +637,6 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, sctp_assoc_t assoc_
|
||||
F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel;
|
||||
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
|
||||
OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
|
||||
GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst,
|
||||
f1ap_ue_context_setup_resp->gNB_DU_ue_id,
|
||||
(ebi_t)drbs_setup_item_p->dRBID,
|
||||
drb_p->up_dl_tnl[0].tl_address,
|
||||
drb_p->up_dl_tnl[0].teid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1182,6 +1126,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte
|
||||
ie12->value.present = F1AP_UEContextModificationRequestIEs__value_PR_DRBs_ToBeSetupMod_List;
|
||||
|
||||
for (int i = 0; i < f1ap_ue_context_modification_req->drbs_to_be_setup_length; i++) {
|
||||
const f1ap_drb_to_be_setup_t *drb = &f1ap_ue_context_modification_req->drbs_to_be_setup[i];
|
||||
asn1cSequenceAdd(ie12->value.choice.DRBs_ToBeSetupMod_List.list,
|
||||
F1AP_DRBs_ToBeSetupMod_ItemIEs_t, drbs_toBeSetupMod_item_ies);
|
||||
drbs_toBeSetupMod_item_ies->id = F1AP_ProtocolIE_ID_id_DRBs_ToBeSetupMod_Item;
|
||||
@@ -1191,7 +1136,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte
|
||||
F1AP_DRBs_ToBeSetupMod_Item_t *drbs_toBeSetupMod_item=
|
||||
&drbs_toBeSetupMod_item_ies->value.choice.DRBs_ToBeSetupMod_Item;
|
||||
/* dRBID */
|
||||
drbs_toBeSetupMod_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id;
|
||||
drbs_toBeSetupMod_item->dRBID = drb->drb_id;
|
||||
/* qoSInformation */
|
||||
|
||||
if(f1ap_ue_context_modification_req->QoS_information_type == EUTRAN_QoS){
|
||||
@@ -1235,99 +1180,12 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte
|
||||
ie->value.present = F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information;
|
||||
F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information;
|
||||
drbs_toBeSetupMod_item->qoSInformation.choice.choice_extension = (struct F1AP_ProtocolIE_SingleContainer *)ie;
|
||||
|
||||
/* 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 = drb_qos_in->qos_characteristics.qos_type;
|
||||
f1ap_write_drb_qos_param(&drb_info_in->drb_qos, &DRB_Information->dRB_QoS);
|
||||
|
||||
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;
|
||||
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 = 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 */
|
||||
/* 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
|
||||
|
||||
} // qoS_Characteristics
|
||||
/* nGRANallocationRetentionPriority */
|
||||
{
|
||||
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 */
|
||||
/* gBR_QoS_Flow_Information */
|
||||
if (0) {
|
||||
asn1cCalloc(DRB_Information->dRB_QoS.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);
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxPacketLossRateDownlink */
|
||||
if (0) {
|
||||
asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L);
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxPacketLossRateUplink */
|
||||
if (0) {
|
||||
asn1cCallocOne(DRB_Information->dRB_QoS.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
|
||||
}
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* reflective_QoS_Attribute */
|
||||
if (0) {
|
||||
asn1cCallocOne(DRB_Information->dRB_QoS.reflective_QoS_Attribute, 1L);
|
||||
}
|
||||
} // dRB_QoS
|
||||
/* 12.1.2.2 sNSSAI */
|
||||
{
|
||||
/* sST */
|
||||
OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, (char *)&f1ap_ue_context_modification_req->drbs_to_be_setup[i].nssai.sst, 1);
|
||||
|
||||
/* OPTIONAL */
|
||||
const uint32_t sd = (f1ap_ue_context_modification_req->drbs_to_be_setup[i].nssai.sd & 0xffffff);
|
||||
if (sd != 0xffffff)
|
||||
OCTET_STRING_fromBuf(DRB_Information->sNSSAI.sD, (char *)&sd, 3);
|
||||
}
|
||||
f1ap_write_drb_nssai(&drb->nssai, &DRB_Information->sNSSAI);
|
||||
|
||||
/* OPTIONAL */
|
||||
/* 12.1.2.3 notificationControl */
|
||||
@@ -1337,102 +1195,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte
|
||||
}
|
||||
|
||||
/* 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 = 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 = 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 == non_dynamic) {
|
||||
QosParams->present = F1AP_QoS_Characteristics_PR_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 = flow_qos_char_in->dynamic.qos_priority_level;
|
||||
/* packetDelayBudget */
|
||||
tmp->packetDelayBudget = flow_qos_char_in->dynamic.packet_delay_budget;
|
||||
/* packetErrorRate */
|
||||
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 */
|
||||
if (0) {
|
||||
asn1cCalloc(QosParams->choice.dynamic_5QI->delayCritical, tmp);
|
||||
*tmp = 1L;
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* averagingWindow */
|
||||
if (0) {
|
||||
asn1cCalloc(QosParams->choice.dynamic_5QI->averagingWindow, tmp);
|
||||
*tmp = 1L;
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxDataBurstVolume */
|
||||
if (0) {
|
||||
asn1cCalloc(QosParams->choice.dynamic_5QI->maxDataBurstVolume, tmp);
|
||||
*tmp= 1L;
|
||||
}
|
||||
} // if some_decide_qoS_characteristics
|
||||
|
||||
} // qoS_Characteristics
|
||||
/* nGRANallocationRetentionPriority */
|
||||
{
|
||||
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 */
|
||||
/* gBR_QoS_Flow_Information */
|
||||
if (0) {
|
||||
asn1cCalloc(flows_mapped_to_drb_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);
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxPacketLossRateDownlink */
|
||||
if (0) {
|
||||
asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateDownlink, 1L);
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* maxPacketLossRateUplink */
|
||||
if (0) {
|
||||
asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.gBR_QoS_Flow_Information->maxPacketLossRateUplink, 1L);
|
||||
}
|
||||
}
|
||||
|
||||
/* OPTIONAL */
|
||||
/* reflective_QoS_Attribute */
|
||||
if (0) {
|
||||
asn1cCallocOne(flows_mapped_to_drb_item->qoSFlowLevelQoSParameters.reflective_QoS_Attribute, 1L);
|
||||
}
|
||||
} // qoSFlowLevelQoSParameters
|
||||
}
|
||||
f1ap_write_flows_mapped(drb_info_in->flows_mapped_to_drb, &DRB_Information->flows_Mapped_To_DRB_List, drb_info_in->flows_to_be_setup_length);
|
||||
|
||||
} //QoS information
|
||||
|
||||
@@ -1569,9 +1332,6 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_conte
|
||||
&drbs_toBeReleased_item_ies->value.choice.DRBs_ToBeReleased_Item;
|
||||
/* dRBID */
|
||||
drbs_toBeReleased_item->dRBID = f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id;
|
||||
newGtpuDeleteOneTunnel(getCxt(0)->gtpInst,
|
||||
f1ap_ue_context_modification_req->gNB_CU_ue_id,
|
||||
f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1644,11 +1404,6 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, sctp_assoc_t
|
||||
F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel;
|
||||
BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address);
|
||||
OCTET_STRING_TO_UINT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid);
|
||||
GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(instance)->gtpInst,
|
||||
f1ap_ue_context_modification_resp->gNB_CU_ue_id,
|
||||
(ebi_t)drbs_setupmod_item_p->dRBID,
|
||||
drb_p->up_dl_tnl[0].tl_address,
|
||||
drb_p->up_dl_tnl[0].teid);
|
||||
}
|
||||
}
|
||||
// SRBs_FailedToBeSetupMod_List
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
#include "asn1_msg.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
|
||||
|
||||
@@ -83,7 +82,6 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, sctp_assoc_t assoc_id
|
||||
/* strange: it is not named OLD_GNB_DU_UE... */
|
||||
old_gNB_DU_ue_id_stack = ie->value.choice.GNB_DU_UE_F1AP_ID_1;
|
||||
old_gNB_DU_ue_id = &old_gNB_DU_ue_id_stack;
|
||||
gtpv1u_update_ue_id(getCxt(instance)->gtpInst, old_gNB_DU_ue_id_stack, du_ue_f1ap_id);
|
||||
}
|
||||
|
||||
/* mandatory */
|
||||
|
||||
@@ -40,6 +40,16 @@
|
||||
//Fixme: Uniq dirty DU instance, by global var, datamodel need better management
|
||||
instance_t DUuniqInstance=0;
|
||||
|
||||
static instance_t du_create_gtpu_instance_to_cu(const f1ap_net_config_t *nc)
|
||||
{
|
||||
openAddr_t tmp = {0};
|
||||
strncpy(tmp.originHost, nc->DU_f1_ip_address.ipv4_address, sizeof(tmp.originHost) - 1);
|
||||
strncpy(tmp.destinationHost, nc->CU_f1_ip_address.ipv4_address, sizeof(tmp.destinationHost) - 1);
|
||||
sprintf(tmp.originService, "%d", nc->DUport);
|
||||
sprintf(tmp.destinationService, "%d", nc->CUport);
|
||||
return gtpv1Init(tmp);
|
||||
}
|
||||
|
||||
void du_task_send_sctp_association_req(instance_t instance, f1ap_net_config_t *nc)
|
||||
{
|
||||
DevAssert(nc != NULL);
|
||||
@@ -116,6 +126,10 @@ void *F1AP_DU_task(void *arg) {
|
||||
f1ap_net_config_t *nc = &F1AP_DU_REGISTER_REQ(msg).net_config;
|
||||
createF1inst(myInstance, msgSetup, nc);
|
||||
du_task_send_sctp_association_req(myInstance, nc);
|
||||
instance_t gtpInst = du_create_gtpu_instance_to_cu(nc);
|
||||
AssertFatal(gtpInst != 0, "cannot create DU F1-U GTP module\n");
|
||||
getCxt(myInstance)->gtpInst = gtpInst;
|
||||
DUuniqInstance = gtpInst;
|
||||
} break;
|
||||
|
||||
case F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE:
|
||||
|
||||
@@ -37,25 +37,82 @@
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h"
|
||||
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
bool DURecvCb(protocol_ctxt_t *ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
unsigned char *const sdu_buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id)
|
||||
static void f1ap_read_drb_qos_param(const F1AP_QoSFlowLevelQoSParameters_t *asn1_qos, f1ap_qos_flow_level_qos_parameters_t *drb_qos)
|
||||
{
|
||||
// The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue
|
||||
uint8_t *sdu = malloc16(sdu_buffer_sizeP);
|
||||
memcpy(sdu, sdu_buffer_pP, sdu_buffer_sizeP);
|
||||
du_rlc_data_req(ctxt_pP, srb_flagP, false, rb_idP, muiP, confirmP, sdu_buffer_sizeP, sdu);
|
||||
return true;
|
||||
f1ap_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->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 = 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
for (int k = 0; k < n; k++) {
|
||||
f1ap_flows_mapped_to_drb_t *flows_mapped_to_drb = flows_mapped + k;
|
||||
const F1AP_Flows_Mapped_To_DRB_Item_t *flows_Mapped_To_Drb = asn1_flows_mapped->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;
|
||||
const F1AP_QoSFlowLevelQoSParameters_t *Flow_QoS = &flows_Mapped_To_Drb->qoSFlowLevelQoSParameters;
|
||||
|
||||
/* QoS Characteristics*/
|
||||
f1ap_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->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void f1ap_read_drb_nssai(const F1AP_SNSSAI_t *asn1_nssai, nssai_t *nssai)
|
||||
{
|
||||
OCTET_STRING_TO_INT8(&asn1_nssai->sST, nssai->sst);
|
||||
nssai->sd = 0xffffff;
|
||||
if (asn1_nssai->sD != NULL)
|
||||
memcpy((uint8_t *)&nssai->sd, asn1_nssai->sD->buf, 3);
|
||||
}
|
||||
|
||||
int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
@@ -159,6 +216,36 @@ int DU_handle_UE_CONTEXT_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_i
|
||||
drb_p->rlc_mode = RLC_MODE_TM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (drbs_tobesetup_item_p->qoSInformation.present == F1AP_QoSInformation_PR_eUTRANQoS) {
|
||||
AssertFatal(false, "Decode of eUTRANQoS is not implemented yet");
|
||||
} // EUTRAN QoS Information
|
||||
else {
|
||||
/* 12.1.2 DRB_Information */
|
||||
if (drbs_tobesetup_item_p->qoSInformation.present == F1AP_QoSInformation_PR_choice_extension) {
|
||||
F1AP_QoSInformation_ExtIEs_t *ie =
|
||||
(F1AP_QoSInformation_ExtIEs_t *)drbs_tobesetup_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) {
|
||||
|
||||
const F1AP_DRB_Information_t *dRB_Info = &ie->value.choice.DRB_Information;
|
||||
f1ap_drb_information_t *drb_info = &drb_p->drb_info;
|
||||
|
||||
/* QoS-Flow-Level-QoS-Parameters */
|
||||
/* QoS Characteristics*/
|
||||
f1ap_read_drb_qos_param(&dRB_Info->dRB_QoS, &drb_info->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");
|
||||
f1ap_read_flows_mapped(&dRB_Info->flows_Mapped_To_DRB_List, drb_info->flows_mapped_to_drb, drb_info->flows_to_be_setup_length);
|
||||
|
||||
/* S-NSSAI */
|
||||
f1ap_read_drb_nssai(&dRB_Info->sNSSAI, &drb_p->nssai);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,6 +392,7 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set
|
||||
ie7->criticality = F1AP_Criticality_ignore;
|
||||
ie7->value.present = F1AP_UEContextSetupResponseIEs__value_PR_DRBs_Setup_List;
|
||||
for (int i=0; i< resp->drbs_to_be_setup_length; i++) {
|
||||
f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i];
|
||||
//
|
||||
asn1cSequenceAdd(ie7->value.choice.DRBs_Setup_List.list,
|
||||
F1AP_DRBs_Setup_ItemIEs_t, drbs_setup_item_ies);
|
||||
@@ -315,14 +403,17 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set
|
||||
/* ADD */
|
||||
F1AP_DRBs_Setup_Item_t *drbs_setup_item=&drbs_setup_item_ies->value.choice.DRBs_Setup_Item;
|
||||
/* dRBID */
|
||||
drbs_setup_item->dRBID = resp->drbs_to_be_setup[i].drb_id;
|
||||
drbs_setup_item->dRBID = drb->drb_id;
|
||||
|
||||
/* OPTIONAL */
|
||||
/* lCID */
|
||||
//drbs_setup_item.lCID = (F1AP_LCID_t *)calloc(1, sizeof(F1AP_LCID_t));
|
||||
//drbs_setup_item.lCID = 1L;
|
||||
|
||||
for (int j=0; j<resp->drbs_to_be_setup[i].up_dl_tnl_length; j++) {
|
||||
for (int j = 0; j < drb->up_dl_tnl_length; j++) {
|
||||
const f1ap_up_tnl_t *tnl = &drb->up_dl_tnl[j];
|
||||
DevAssert(tnl->teid > 0);
|
||||
|
||||
/* ADD */
|
||||
asn1cSequenceAdd(drbs_setup_item->dLUPTNLInformation_ToBeSetup_List.list,
|
||||
F1AP_DLUPTNLInformation_ToBeSetup_Item_t, dLUPTNLInformation_ToBeSetup_Item);
|
||||
@@ -330,12 +421,9 @@ int DU_send_UE_CONTEXT_SETUP_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_context_set
|
||||
/* gTPTunnel */
|
||||
asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel);
|
||||
/* transportLayerAddress */
|
||||
struct sockaddr_in addr= {0};
|
||||
inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr);
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr,
|
||||
&gTPTunnel->transportLayerAddress);
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress);
|
||||
/* gTP_TEID */
|
||||
INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID);
|
||||
INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID);
|
||||
} // for j
|
||||
} // for i
|
||||
|
||||
@@ -772,16 +860,6 @@ int DU_send_UE_CONTEXT_RELEASE_COMPLETE(sctp_assoc_t assoc_id, f1ap_ue_context_r
|
||||
return 0;
|
||||
}
|
||||
|
||||
static instance_t du_create_gtpu_instance_to_cu(char *CUaddr, uint16_t CUport, char *DUaddr, uint16_t DUport)
|
||||
{
|
||||
openAddr_t tmp = {0};
|
||||
strncpy(tmp.originHost, DUaddr, sizeof(tmp.originHost)-1);
|
||||
strncpy(tmp.destinationHost, CUaddr, sizeof(tmp.destinationHost)-1);
|
||||
sprintf(tmp.originService, "%d", DUport);
|
||||
sprintf(tmp.destinationService, "%d", CUport);
|
||||
return gtpv1Init(tmp);
|
||||
}
|
||||
|
||||
int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint32_t stream, F1AP_F1AP_PDU_t *pdu)
|
||||
{
|
||||
F1AP_UEContextModificationRequest_t *container;
|
||||
@@ -853,27 +931,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t
|
||||
// 3GPP assumes GTP-U is on port 2152, but OAI is configurable
|
||||
drb_p->up_ul_tnl[0].port = getCxt(instance)->net_config.CUport;
|
||||
|
||||
extern instance_t DUuniqInstance;
|
||||
if (DUuniqInstance == 0) {
|
||||
char gtp_tunnel_ip_address[32];
|
||||
snprintf(gtp_tunnel_ip_address,
|
||||
sizeof(gtp_tunnel_ip_address),
|
||||
"%d.%d.%d.%d",
|
||||
drb_p->up_ul_tnl[0].tl_address & 0xff,
|
||||
(drb_p->up_ul_tnl[0].tl_address >> 8) & 0xff,
|
||||
(drb_p->up_ul_tnl[0].tl_address >> 16) & 0xff,
|
||||
(drb_p->up_ul_tnl[0].tl_address >> 24) & 0xff);
|
||||
getCxt(instance)->gtpInst = du_create_gtpu_instance_to_cu(gtp_tunnel_ip_address,
|
||||
getCxt(instance)->net_config.CUport,
|
||||
getCxt(instance)->net_config.DU_f1_ip_address.ipv4_address,
|
||||
getCxt(instance)->net_config.DUport);
|
||||
AssertFatal(getCxt(instance)->gtpInst > 0, "Failed to create CU F1-U UDP listener");
|
||||
// Fixme: fully inconsistent instances management
|
||||
// dirty global var is a bad fix
|
||||
extern instance_t legacyInstanceMapping;
|
||||
legacyInstanceMapping = DUuniqInstance = getCxt(instance)->gtpInst;
|
||||
}
|
||||
|
||||
switch (drbs_tobesetupmod_item_p->rLCMode) {
|
||||
case F1AP_RLCMode_rlc_am:
|
||||
drb_p->rlc_mode = RLC_MODE_AM;
|
||||
@@ -894,101 +951,22 @@ 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_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;
|
||||
const F1AP_DRB_Information_t *dRB_Info = &ie->value.choice.DRB_Information;
|
||||
f1ap_drb_information_t *drb_info = &drb_p->drb_info;
|
||||
|
||||
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
|
||||
/* QoS-Flow-Level-QoS-Parameters */
|
||||
/* QoS Characteristics*/
|
||||
f1ap_read_drb_qos_param(&dRB_Info->dRB_QoS, &drb_info->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;
|
||||
}
|
||||
}
|
||||
f1ap_read_flows_mapped(&dRB_Info->flows_Mapped_To_DRB_List, drb_info->flows_mapped_to_drb, drb_info->flows_to_be_setup_length);
|
||||
|
||||
/* S-NSSAI */
|
||||
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;
|
||||
f1ap_read_drb_nssai(&dRB_Info->sNSSAI, &drb_p->nssai);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1008,7 +986,6 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t
|
||||
DevAssert(tbrel->id == F1AP_ProtocolIE_ID_id_DRBs_ToBeReleased_Item);
|
||||
DevAssert(tbrel->value.present == F1AP_DRBs_ToBeReleased_ItemIEs__value_PR_DRBs_ToBeReleased_Item);
|
||||
f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id = tbrel->value.choice.DRBs_ToBeReleased_Item.dRBID;
|
||||
newGtpuDeleteOneTunnel(0, f1ap_ue_context_modification_req->gNB_DU_ue_id, f1ap_ue_context_modification_req->drbs_to_be_released[i].rb_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1166,20 +1143,8 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_cont
|
||||
drbs_setupmod_item->dRBID = resp->drbs_to_be_setup[i].drb_id;
|
||||
|
||||
for (int j=0; j<resp->drbs_to_be_setup[i].up_dl_tnl_length; j++) {
|
||||
f1ap_drb_to_be_setup_t *drb = &resp->drbs_to_be_setup[i];
|
||||
transport_layer_addr_t tl_addr = {0};
|
||||
memcpy(tl_addr.buffer, &drb->up_ul_tnl[0].tl_address, sizeof(drb->up_ul_tnl[0].tl_address));
|
||||
tl_addr.length = sizeof(drb->up_ul_tnl[0].tl_address) * 8;
|
||||
drb->up_dl_tnl[j].teid = newGtpuCreateTunnel(getCxt(0)->gtpInst,
|
||||
resp->gNB_DU_ue_id,
|
||||
drb->drb_id,
|
||||
drb->drb_id,
|
||||
drb->up_ul_tnl[j].teid,
|
||||
-1, // no qfi
|
||||
tl_addr,
|
||||
drb->up_ul_tnl[0].port,
|
||||
DURecvCb,
|
||||
NULL);
|
||||
const f1ap_up_tnl_t *tnl = &resp->drbs_to_be_setup[i].up_dl_tnl[j];
|
||||
DevAssert(tnl->teid > 0);
|
||||
|
||||
/* ADD */
|
||||
asn1cSequenceAdd(drbs_setupmod_item->dLUPTNLInformation_ToBeSetup_List.list,
|
||||
@@ -1188,12 +1153,9 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_cont
|
||||
/* gTPTunnel */
|
||||
asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel,gTPTunnel);
|
||||
/* transportLayerAddress */
|
||||
struct sockaddr_in addr= {0};
|
||||
inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr);
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr,
|
||||
&gTPTunnel->transportLayerAddress);
|
||||
TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(tnl->tl_address, &gTPTunnel->transportLayerAddress);
|
||||
/* gTP_TEID */
|
||||
INT32_TO_OCTET_STRING(resp->drbs_to_be_setup[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID);
|
||||
INT32_TO_OCTET_STRING(tnl->teid, &gTPTunnel->gTP_TEID);
|
||||
} // for j
|
||||
} // for i
|
||||
}
|
||||
|
||||
@@ -23,8 +23,11 @@
|
||||
|
||||
#include "mac_proto.h"
|
||||
#include "openair2/F1AP/f1ap_ids.h"
|
||||
#include "openair2/F1AP/f1ap_common.h"
|
||||
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
|
||||
#include "F1AP_CauseRadioNetwork.h"
|
||||
#include "openair3/ocp-gtpu/gtp_itf.h"
|
||||
#include "openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h"
|
||||
|
||||
#include "uper_decoder.h"
|
||||
#include "uper_encoder.h"
|
||||
@@ -34,6 +37,59 @@ const uint64_t qos_fiveqi[26] = {1, 2, 3, 4, 65, 66, 67, 71, 72, 73, 74, 76, 5,
|
||||
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);
|
||||
if (!inst)
|
||||
return -1; // means no F1
|
||||
return inst->gtpInst;
|
||||
}
|
||||
|
||||
static int drb_gtpu_create(instance_t instance,
|
||||
uint32_t ue_id,
|
||||
int incoming_id,
|
||||
int outgoing_id,
|
||||
int qfi,
|
||||
in_addr_t tlAddress, // only IPv4 now
|
||||
teid_t outgoing_teid,
|
||||
gtpCallback callBack,
|
||||
gtpCallbackSDAP callBackSDAP,
|
||||
gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp)
|
||||
{
|
||||
gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0};
|
||||
create_tunnel_req.incoming_rb_id[0] = incoming_id;
|
||||
create_tunnel_req.pdusession_id[0] = outgoing_id;
|
||||
memcpy(&create_tunnel_req.dst_addr[0].buffer, &tlAddress, sizeof(uint8_t) * 4);
|
||||
create_tunnel_req.dst_addr[0].length = 32;
|
||||
create_tunnel_req.outgoing_teid[0] = outgoing_teid;
|
||||
create_tunnel_req.outgoing_qfi[0] = qfi;
|
||||
create_tunnel_req.num_tunnels = 1;
|
||||
create_tunnel_req.ue_id = ue_id;
|
||||
|
||||
// we use gtpv1u_create_ngu_tunnel because it returns the interface
|
||||
// address and port of the interface; apart from that, we also might call
|
||||
// newGtpuCreateTunnel() directly
|
||||
return gtpv1u_create_ngu_tunnel(instance, &create_tunnel_req, create_tunnel_resp, callBack, callBackSDAP);
|
||||
}
|
||||
|
||||
bool DURecvCb(protocol_ctxt_t *ctxt_pP,
|
||||
const srb_flag_t srb_flagP,
|
||||
const rb_id_t rb_idP,
|
||||
const mui_t muiP,
|
||||
const confirm_t confirmP,
|
||||
const sdu_size_t sdu_buffer_sizeP,
|
||||
unsigned char *const sdu_buffer_pP,
|
||||
const pdcp_transmission_mode_t modeP,
|
||||
const uint32_t *sourceL2Id,
|
||||
const uint32_t *destinationL2Id)
|
||||
{
|
||||
// The buffer comes from the stack in gtp-u thread, we have a make a separate buffer to enqueue in a inter-thread message queue
|
||||
uint8_t *sdu = malloc16(sdu_buffer_sizeP);
|
||||
memcpy(sdu, sdu_buffer_pP, sdu_buffer_sizeP);
|
||||
du_rlc_data_req(ctxt_pP, srb_flagP, false, rb_idP, muiP, confirmP, sdu_buffer_sizeP, sdu);
|
||||
return true;
|
||||
}
|
||||
|
||||
static long get_lcid_from_drbid(int drb_id)
|
||||
{
|
||||
return drb_id + 3; /* LCID is DRB + 3 */
|
||||
@@ -133,6 +189,7 @@ static int handle_ue_context_drbs_setup(int rnti,
|
||||
NR_CellGroupConfig_t *cellGroupConfig)
|
||||
{
|
||||
DevAssert(req_drbs != NULL && resp_drbs != NULL && cellGroupConfig != NULL);
|
||||
instance_t f1inst = get_f1_gtp_instance();
|
||||
|
||||
/* Note: the actual GTP tunnels are created in the F1AP breanch of
|
||||
* ue_context_*_response() */
|
||||
@@ -140,12 +197,32 @@ static int handle_ue_context_drbs_setup(int rnti,
|
||||
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(rnti, drb->drb_id, rlc_BearerConfig);
|
||||
|
||||
(*resp_drbs)[i] = *drb;
|
||||
*resp_drb = *drb;
|
||||
// just put same number of tunnels in DL as in UL
|
||||
(*resp_drbs)[i].up_dl_tnl_length = drb->up_ul_tnl_length;
|
||||
DevAssert(drb->up_ul_tnl_length == 1);
|
||||
resp_drb->up_dl_tnl_length = drb->up_ul_tnl_length;
|
||||
|
||||
if (f1inst >= 0) { // we actually use F1-U
|
||||
int qfi = -1; // don't put PDU session marker in GTP
|
||||
gtpv1u_gnb_create_tunnel_resp_t resp_f1 = {0};
|
||||
int ret = drb_gtpu_create(f1inst,
|
||||
rnti,
|
||||
drb->drb_id,
|
||||
drb->drb_id,
|
||||
qfi,
|
||||
drb->up_ul_tnl[0].tl_address,
|
||||
drb->up_ul_tnl[0].teid,
|
||||
DURecvCb,
|
||||
NULL,
|
||||
&resp_f1);
|
||||
AssertFatal(ret >= 0, "Unable to create GTP Tunnel for F1-U\n");
|
||||
memcpy(&resp_drb->up_dl_tnl[0].tl_address, &resp_f1.gnb_addr.buffer, 4);
|
||||
resp_drb->up_dl_tnl[0].teid = resp_f1.gnb_NGu_teid[0];
|
||||
}
|
||||
|
||||
int ret = ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
|
||||
DevAssert(ret == 0);
|
||||
@@ -159,6 +236,7 @@ static int handle_ue_context_drbs_release(int rnti,
|
||||
NR_CellGroupConfig_t *cellGroupConfig)
|
||||
{
|
||||
DevAssert(req_drbs != NULL && cellGroupConfig != NULL);
|
||||
instance_t f1inst = get_f1_gtp_instance();
|
||||
|
||||
cellGroupConfig->rlc_BearerToReleaseList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToReleaseList));
|
||||
AssertFatal(cellGroupConfig->rlc_BearerToReleaseList != NULL, "out of memory\n");
|
||||
@@ -178,6 +256,8 @@ static int handle_ue_context_drbs_release(int rnti,
|
||||
}
|
||||
if (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) {
|
||||
nr_rlc_release_entity(rnti, lcid);
|
||||
if (f1inst >= 0)
|
||||
newGtpuDeleteOneTunnel(f1inst, rnti, drb->rb_id);
|
||||
asn_sequence_del(&cellGroupConfig->rlc_BearerToAddModList->list, idx, 1);
|
||||
long *plcid = malloc(sizeof(*plcid));
|
||||
AssertFatal(plcid != NULL, "out of memory\n");
|
||||
@@ -557,6 +637,10 @@ void ue_context_release_command(const f1ap_ue_context_release_cmd_t *cmd)
|
||||
return;
|
||||
}
|
||||
|
||||
instance_t f1inst = get_f1_gtp_instance();
|
||||
if (f1inst >= 0)
|
||||
newGtpuDeleteAllTunnels(f1inst, cmd->gNB_DU_ue_id);
|
||||
|
||||
if (UE->UE_sched_ctrl.ul_failure || cmd->rrc_container_length == 0) {
|
||||
/* The UE is already not connected anymore or we have nothing to forward*/
|
||||
nr_mac_release_ue(mac, cmd->gNB_DU_ue_id);
|
||||
@@ -632,6 +716,9 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
|
||||
pthread_mutex_unlock(&mac->sched_lock);
|
||||
nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id);
|
||||
nr_rlc_update_rnti(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id);
|
||||
instance_t f1inst = get_f1_gtp_instance();
|
||||
if (f1inst >= 0) // we actually use F1-U
|
||||
gtpv1u_update_ue_id(f1inst, *dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id);
|
||||
}
|
||||
|
||||
/* the DU ue id is the RNTI */
|
||||
|
||||
Reference in New Issue
Block a user