Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
spbro
OpenXG-RAN
Commits
bc9f95c9
Commit
bc9f95c9
authored
Mar 18, 2024
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/fixes-gtp-f1' into integration_2024_w11
parents
b6aefac5
73d21d6d
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
378 additions
and
562 deletions
+378
-562
openair2/F1AP/f1ap_cu_ue_context_management.c
openair2/F1AP/f1ap_cu_ue_context_management.c
+151
-396
openair2/F1AP/f1ap_du_rrc_message_transfer.c
openair2/F1AP/f1ap_du_rrc_message_transfer.c
+0
-2
openair2/F1AP/f1ap_du_task.c
openair2/F1AP/f1ap_du_task.c
+14
-0
openair2/F1AP/f1ap_du_ue_context_management.c
openair2/F1AP/f1ap_du_ue_context_management.c
+124
-162
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
+89
-2
No files found.
openair2/F1AP/f1ap_cu_ue_context_management.c
View file @
bc9f95c9
...
...
@@ -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
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
);
f1ap_write_drb_qos_param
(
&
drb_info
->
drb_qos
,
&
DRB_Information
->
dRB_QoS
);
/* 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
);
}
/* 12.1.2.2 sNSSAI */
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_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
);
f1ap_write_drb_qos_param
(
&
drb_info_in
->
drb_qos
,
&
DRB_Information
->
dRB_QoS
);
/* 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
);
}
/* 12.1.2.2 sNSSAI */
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
...
...
openair2/F1AP/f1ap_du_rrc_message_transfer.c
View file @
bc9f95c9
...
...
@@ -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 */
...
...
openair2/F1AP/f1ap_du_task.c
View file @
bc9f95c9
...
...
@@ -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
:
...
...
openair2/F1AP/f1ap_du_ue_context_management.c
View file @
bc9f95c9
...
...
@@ -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
;
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
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
"
);
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
}
...
...
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
View file @
bc9f95c9
...
...
@@ -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 */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment