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
65d494fb
Commit
65d494fb
authored
May 06, 2024
by
Jaroslava Fiedlerova
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/f1ap_uecontext_refactoring' into integration_2024_w18
parents
944925ff
0fb0b055
Changes
37
Show whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
1509 additions
and
927 deletions
+1509
-927
ci-scripts/conf_files/gnb.sa.band78.51prb.usrpb200.conf
ci-scripts/conf_files/gnb.sa.band78.51prb.usrpb200.conf
+1
-1
openair2/COMMON/f1ap_messages_def.h
openair2/COMMON/f1ap_messages_def.h
+3
-0
openair2/COMMON/f1ap_messages_types.h
openair2/COMMON/f1ap_messages_types.h
+59
-4
openair2/COMMON/ngap_messages_types.h
openair2/COMMON/ngap_messages_types.h
+2
-0
openair2/F1AP/f1ap_cu_interface_management.c
openair2/F1AP/f1ap_cu_interface_management.c
+397
-5
openair2/F1AP/f1ap_cu_interface_management.h
openair2/F1AP/f1ap_cu_interface_management.h
+4
-3
openair2/F1AP/f1ap_cu_task.c
openair2/F1AP/f1ap_cu_task.c
+3
-0
openair2/F1AP/f1ap_cu_ue_context_management.c
openair2/F1AP/f1ap_cu_ue_context_management.c
+48
-47
openair2/F1AP/f1ap_du_interface_management.c
openair2/F1AP/f1ap_du_interface_management.c
+212
-341
openair2/F1AP/f1ap_du_interface_management.h
openair2/F1AP/f1ap_du_interface_management.h
+2
-3
openair2/F1AP/f1ap_du_task.c
openair2/F1AP/f1ap_du_task.c
+4
-0
openair2/F1AP/f1ap_handlers.c
openair2/F1AP/f1ap_handlers.c
+1
-1
openair2/GNB_APP/gnb_config.c
openair2/GNB_APP/gnb_config.c
+60
-19
openair2/LAYER2/NR_MAC_gNB/config.c
openair2/LAYER2/NR_MAC_gNB/config.c
+0
-7
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
+6
-0
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h
+1
-0
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h
+1
-0
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c
+61
-2
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c
+42
-2
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+1
-0
openair2/RRC/NR/MESSAGES/asn1_msg.c
openair2/RRC/NR/MESSAGES/asn1_msg.c
+9
-6
openair2/RRC/NR/MESSAGES/asn1_msg.h
openair2/RRC/NR/MESSAGES/asn1_msg.h
+1
-1
openair2/RRC/NR/mac_rrc_dl.h
openair2/RRC/NR/mac_rrc_dl.h
+2
-0
openair2/RRC/NR/mac_rrc_dl_direct.c
openair2/RRC/NR/mac_rrc_dl_direct.c
+7
-0
openair2/RRC/NR/mac_rrc_dl_f1ap.c
openair2/RRC/NR/mac_rrc_dl_f1ap.c
+10
-0
openair2/RRC/NR/nr_rrc_config.c
openair2/RRC/NR/nr_rrc_config.c
+91
-0
openair2/RRC/NR/nr_rrc_config.h
openair2/RRC/NR/nr_rrc_config.h
+5
-0
openair2/RRC/NR/nr_rrc_defs.h
openair2/RRC/NR/nr_rrc_defs.h
+9
-4
openair2/RRC/NR/nr_rrc_proto.h
openair2/RRC/NR/nr_rrc_proto.h
+18
-7
openair2/RRC/NR/rrc_gNB.c
openair2/RRC/NR/rrc_gNB.c
+209
-350
openair2/RRC/NR/rrc_gNB_NGAP.c
openair2/RRC/NR/rrc_gNB_NGAP.c
+20
-60
openair2/RRC/NR/rrc_gNB_NGAP.h
openair2/RRC/NR/rrc_gNB_NGAP.h
+4
-1
openair2/RRC/NR/rrc_gNB_UE_context.c
openair2/RRC/NR/rrc_gNB_UE_context.c
+0
-1
openair2/RRC/NR/rrc_gNB_du.c
openair2/RRC/NR/rrc_gNB_du.c
+184
-50
openair2/RRC/NR/rrc_gNB_du.h
openair2/RRC/NR/rrc_gNB_du.h
+2
-0
openair3/NGAP/ngap_gNB_context_management_procedures.c
openair3/NGAP/ngap_gNB_context_management_procedures.c
+15
-1
openair3/UTILS/conversions.h
openair3/UTILS/conversions.h
+15
-11
No files found.
ci-scripts/conf_files/gnb.sa.band78.51prb.usrpb200.conf
View file @
65d494fb
...
...
@@ -30,7 +30,7 @@ gNBs =
absoluteFrequencySSB
=
620736
;
dl_frequencyBand
=
78
;
# this is 3300.30 MHz
dl_absoluteFrequencyPointA
=
6200
52
;
dl_absoluteFrequencyPointA
=
6200
20
;
#scs-SpecificCarrierList
dl_offstToCarrier
=
0
;
# subcarrierSpacing
...
...
openair2/COMMON/f1ap_messages_def.h
View file @
65d494fb
...
...
@@ -27,11 +27,14 @@ MESSAGE_DEF(F1AP_DU_REGISTER_REQ, MESSAGE_PRIORITY_MED, f1ap_du_register_req_t,
MESSAGE_DEF
(
F1AP_SETUP_REQ
,
MESSAGE_PRIORITY_MED
,
f1ap_setup_req_t
,
f1ap_setup_req
)
MESSAGE_DEF
(
F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE
,
MESSAGE_PRIORITY_MED
,
f1ap_gnb_cu_configuration_update_acknowledge_t
,
f1ap_gnb_cu_configuration_update_acknowledge
)
MESSAGE_DEF
(
F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE
,
MESSAGE_PRIORITY_MED
,
f1ap_gnb_cu_configuration_update_failure_t
,
f1ap_gnb_cu_configuration_update_failure
)
MESSAGE_DEF
(
F1AP_GNB_DU_CONFIGURATION_UPDATE
,
MESSAGE_PRIORITY_MED
,
f1ap_gnb_du_configuration_update_t
,
f1ap_gnb_du_configuration_update
)
/* F1AP -> eNB_DU or eNB_CU_RRC -> F1AP application layer messages */
MESSAGE_DEF
(
F1AP_SETUP_RESP
,
MESSAGE_PRIORITY_MED
,
f1ap_setup_resp_t
,
f1ap_setup_resp
)
MESSAGE_DEF
(
F1AP_SETUP_FAILURE
,
MESSAGE_PRIORITY_MED
,
f1ap_setup_failure_t
,
f1ap_setup_failure
)
MESSAGE_DEF
(
F1AP_GNB_CU_CONFIGURATION_UPDATE
,
MESSAGE_PRIORITY_MED
,
f1ap_gnb_cu_configuration_update_t
,
f1ap_gnb_cu_configuration_update
)
MESSAGE_DEF
(
F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
,
MESSAGE_PRIORITY_MED
,
f1ap_gnb_du_configuration_update_acknowledge_t
,
f1ap_gnb_du_configuration_update_acknowledge
)
MESSAGE_DEF
(
F1AP_GNB_DU_CONFIGURATION_UPDATE_FAILURE
,
MESSAGE_PRIORITY_MED
,
f1ap_gnb_du_configuration_update_failure_t
,
f1ap_gnb_du_configuration_update_failure
)
/* F1AP -> RRC to inform about lost connection */
MESSAGE_DEF
(
F1AP_LOST_CONNECTION
,
MESSAGE_PRIORITY_MED
,
f1ap_lost_connection_t
,
f1ap_lost_connection
)
...
...
openair2/COMMON/f1ap_messages_types.h
View file @
65d494fb
...
...
@@ -39,6 +39,10 @@
#define F1AP_GNB_CU_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update
#define F1AP_GNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update_acknowledge
#define F1AP_GNB_CU_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_cu_configuration_update_failure
#define F1AP_GNB_DU_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update
#define F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update_acknowledge
#define F1AP_GNB_DU_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_gnb_du_configuration_update_failure
#define F1AP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.f1ap_setup_failure
#define F1AP_LOST_CONNECTION(mSGpTR) (mSGpTR)->ittiMsg.f1ap_lost_connection
...
...
@@ -125,10 +129,9 @@ typedef struct f1ap_served_cell_info_t {
/* Tracking area code */
uint32_t
*
tac
;
// Number of sli
d
e support items (max 16, could be increased to as much as 1024)
// Number of sli
c
e support items (max 16, could be increased to as much as 1024)
uint16_t
num_ssi
;
uint8_t
sst
;
uint8_t
sd
;
nssai_t
nssai
[
16
];
f1ap_mode_t
mode
;
union
{
...
...
@@ -136,7 +139,8 @@ typedef struct f1ap_served_cell_info_t {
f1ap_tdd_info_t
tdd
;
};
char
*
measurement_timing_information
;
uint8_t
*
measurement_timing_config
;
int
measurement_timing_config_len
;
}
f1ap_served_cell_info_t
;
typedef
struct
f1ap_gnb_du_system_info_t
{
...
...
@@ -247,6 +251,57 @@ typedef struct f1ap_gnb_cu_configuration_update_failure_s {
uint16_t
criticality_diagnostics
;
}
f1ap_gnb_cu_configuration_update_failure_t
;
/*DU configuration messages*/
typedef
struct
f1ap_gnb_du_configuration_update_s
{
/*TODO UPDATE TO SUPPORT DU CONFIG*/
/* Transaction ID */
uint64_t
transaction_id
;
/// int cells_to_add
uint16_t
num_cells_to_add
;
struct
{
f1ap_served_cell_info_t
info
;
f1ap_gnb_du_system_info_t
*
sys_info
;
}
cell_to_add
[
F1AP_MAX_NB_CELLS
];
/// int cells_to_modify
uint16_t
num_cells_to_modify
;
struct
{
f1ap_plmn_t
old_plmn
;
uint64_t
old_nr_cellid
;
// NR Global Cell Id
f1ap_served_cell_info_t
info
;
f1ap_gnb_du_system_info_t
*
sys_info
;
}
cell_to_modify
[
F1AP_MAX_NB_CELLS
];
/// int cells_to_delete
uint16_t
num_cells_to_delete
;
struct
{
// NR CGI
f1ap_plmn_t
plmn
;
uint64_t
nr_cellid
;
// NR Global Cell Id
}
cell_to_delete
[
F1AP_MAX_NB_CELLS
];
/// string holding gNB_CU_name
uint64_t
*
gNB_DU_ID
;
}
f1ap_gnb_du_configuration_update_t
;
typedef
struct
f1ap_gnb_du_configuration_update_acknowledge_s
{
/// ulong transaction id
uint64_t
transaction_id
;
/// string holding gNB_CU_name
char
*
gNB_CU_name
;
/// number of DU cells to activate
uint16_t
num_cells_to_activate
;
// 0< num_cells_to_activate <= 512;
served_cells_to_activate_t
cells_to_activate
[
F1AP_MAX_NB_CELLS
];
}
f1ap_gnb_du_configuration_update_acknowledge_t
;
typedef
struct
f1ap_gnb_du_configuration_update_failure_s
{
/*TODO UPDATE TO SUPPORT DU CONFIG*/
uint16_t
cause
;
uint16_t
time_to_wait
;
uint16_t
criticality_diagnostics
;
}
f1ap_gnb_du_configuration_update_failure_t
;
typedef
struct
f1ap_dl_rrc_message_s
{
uint32_t
gNB_CU_ue_id
;
...
...
openair2/COMMON/ngap_messages_types.h
View file @
65d494fb
...
...
@@ -583,6 +583,8 @@ typedef struct ngap_ue_ctxt_modification_resp_s {
typedef
struct
ngap_ue_release_complete_s
{
uint32_t
gNB_ue_ngap_id
;
int
num_pdu_sessions
;
uint32_t
pdu_session_id
[
256
];
}
ngap_ue_release_complete_t
;
//-------------------------------------------------------------------------------------------//
...
...
openair2/F1AP/f1ap_cu_interface_management.c
View file @
65d494fb
...
...
@@ -67,6 +67,40 @@ int CU_send_ERROR_INDICATION(sctp_assoc_t assoc_id, F1AP_ErrorIndication_t *Erro
AssertFatal
(
1
==
0
,
"Not implemented yet
\n
"
);
}
static
uint8_t
*
cp_octet_string
(
const
OCTET_STRING_t
*
os
,
int
*
len
)
{
uint8_t
*
buf
=
calloc
(
os
->
size
,
sizeof
(
*
buf
));
AssertFatal
(
buf
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
buf
,
os
->
buf
,
os
->
size
);
*
len
=
os
->
size
;
return
buf
;
}
static
int
read_slice_info
(
const
F1AP_ServedPLMNs_Item_t
*
plmn
,
nssai_t
*
nssai
,
int
max_nssai
)
{
if
(
plmn
->
iE_Extensions
==
NULL
)
return
0
;
const
F1AP_ProtocolExtensionContainer_10696P34_t
*
p
=
(
F1AP_ProtocolExtensionContainer_10696P34_t
*
)
plmn
->
iE_Extensions
;
if
(
p
->
list
.
count
==
0
)
return
0
;
const
F1AP_ServedPLMNs_ItemExtIEs_t
*
splmn
=
p
->
list
.
array
[
0
];
DevAssert
(
splmn
->
id
==
F1AP_ProtocolIE_ID_id_TAISliceSupportList
);
DevAssert
(
splmn
->
extensionValue
.
present
==
F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList
);
const
F1AP_SliceSupportList_t
*
ssl
=
&
splmn
->
extensionValue
.
choice
.
SliceSupportList
;
AssertFatal
(
ssl
->
list
.
count
<=
max_nssai
,
"cannot handle more than 16 slices
\n
"
);
for
(
int
s
=
0
;
s
<
ssl
->
list
.
count
;
++
s
)
{
const
F1AP_SliceSupportItem_t
*
sl
=
ssl
->
list
.
array
[
s
];
nssai_t
*
n
=
&
nssai
[
s
];
OCTET_STRING_TO_INT8
(
&
sl
->
sNSSAI
.
sST
,
n
->
sst
);
n
->
sd
=
0xffffff
;
if
(
sl
->
sNSSAI
.
sD
!=
NULL
)
OCTET_STRING_TO_INT24
(
sl
->
sNSSAI
.
sD
,
n
->
sd
);
}
return
ssl
->
list
.
count
;
}
/*
F1 Setup
...
...
@@ -144,6 +178,9 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3
req
->
cell
[
i
].
info
.
nr_pci
=
servedCellInformation
->
nRPCI
;
LOG_D
(
F1AP
,
"req->nr_pci[%d] %d
\n
"
,
i
,
req
->
cell
[
i
].
info
.
nr_pci
);
AssertFatal
(
servedCellInformation
->
servedPLMNs
.
list
.
count
==
1
,
"only one PLMN handled
\n
"
);
req
->
cell
[
i
].
info
.
num_ssi
=
read_slice_info
(
servedCellInformation
->
servedPLMNs
.
list
.
array
[
0
],
req
->
cell
[
i
].
info
.
nssai
,
16
);
// FDD Cells
if
(
servedCellInformation
->
nR_Mode_Info
.
present
==
F1AP_NR_Mode_Info_PR_fDD
)
{
req
->
cell
[
i
].
info
.
mode
=
F1AP_MODE_FDD
;
...
...
@@ -187,6 +224,11 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3
AssertFatal
(
false
,
"unknown NR Mode info %d
\n
"
,
servedCellInformation
->
nR_Mode_Info
.
present
);
}
/* MeasurementConfig */
if
(
servedCellInformation
->
measurementTimingConfiguration
.
size
>
0
)
req
->
cell
[
i
].
info
.
measurement_timing_config
=
cp_octet_string
(
&
servedCellInformation
->
measurementTimingConfiguration
,
&
req
->
cell
[
i
].
info
.
measurement_timing_config_len
);
struct
F1AP_GNB_DU_System_Information
*
DUsi
=
served_cells_item
->
gNB_DU_System_Information
;
if
(
DUsi
!=
NULL
)
{
// System Information
...
...
@@ -431,17 +473,367 @@ int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *
int
CU_handle_gNB_DU_CONFIGURATION_UPDATE
(
instance_t
instance
,
sctp_assoc_t
assoc_id
,
uint32_t
stream
,
F1AP_F1AP_PDU_t
*
pdu
)
{
AssertFatal
(
1
==
0
,
"Not implemented yet
\n
"
);
LOG_D
(
F1AP
,
"CU_handle_gNB_DU_CONFIGURATION_UPDATE
\n
"
);
F1AP_GNBDUConfigurationUpdate_t
*
container
;
F1AP_GNBDUConfigurationUpdateIEs_t
*
ie
;
int
i
=
0
;
DevAssert
(
pdu
!=
NULL
);
container
=
&
pdu
->
choice
.
initiatingMessage
->
value
.
choice
.
GNBDUConfigurationUpdate
;
/* gNB DU Configuration Update == Non UE-related procedure -> stream 0 */
if
(
stream
!=
0
)
{
LOG_W
(
F1AP
,
"[SCTP %d] Received f1 setup request on stream != 0 (%d)
\n
"
,
assoc_id
,
stream
);
}
MessageDef
*
message_p
=
itti_alloc_new_message
(
TASK_CU_F1
,
0
,
F1AP_GNB_DU_CONFIGURATION_UPDATE
);
message_p
->
ittiMsgHeader
.
originInstance
=
assoc_id
;
f1ap_gnb_du_configuration_update_t
*
req
=
&
F1AP_GNB_DU_CONFIGURATION_UPDATE
(
message_p
);
/* 3GPP TS 38.473 Transaction ID*/
F1AP_FIND_PROTOCOLIE_BY_ID
(
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie
,
container
,
F1AP_ProtocolIE_ID_id_TransactionID
,
true
);
req
->
transaction_id
=
ie
->
value
.
choice
.
TransactionID
;
LOG_D
(
F1AP
,
"req->transaction_id %lu
\n
"
,
req
->
transaction_id
);
/* 3GPP TS 38.473 Served Cells To Add List */
F1AP_FIND_PROTOCOLIE_BY_ID
(
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie
,
container
,
F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List
,
false
);
if
(
ie
!=
NULL
)
{
req
->
num_cells_to_add
=
ie
->
value
.
choice
.
Served_Cells_To_Add_List
.
list
.
count
;
LOG_D
(
F1AP
,
"req->num_cells_to_add %d
\n
"
,
req
->
num_cells_to_add
);
for
(
i
=
0
;
i
<
req
->
num_cells_to_add
;
i
++
)
{
F1AP_Served_Cells_To_Add_Item_t
*
served_cells_item
=
&
((
F1AP_Served_Cells_To_Add_ItemIEs_t
*
)
ie
->
value
.
choice
.
Served_Cells_To_Add_List
.
list
.
array
[
i
])
->
value
.
choice
.
Served_Cells_To_Add_Item
;
F1AP_Served_Cell_Information_t
*
servedCellInformation
=
&
served_cells_item
->
served_Cell_Information
;
/* tac */
if
(
servedCellInformation
->
fiveGS_TAC
)
{
req
->
cell_to_add
[
i
].
info
.
tac
=
malloc
(
sizeof
(
*
req
->
cell_to_add
[
i
].
info
.
tac
));
AssertFatal
(
req
->
cell_to_add
[
i
].
info
.
tac
!=
NULL
,
"out of memory
\n
"
);
OCTET_STRING_TO_INT24
(
servedCellInformation
->
fiveGS_TAC
,
*
req
->
cell_to_add
[
i
].
info
.
tac
);
LOG_D
(
F1AP
,
"req->tac[%d] %d
\n
"
,
i
,
*
req
->
cell_to_add
[
i
].
info
.
tac
);
}
/* - nRCGI */
TBCD_TO_MCC_MNC
(
&
(
servedCellInformation
->
nRCGI
.
pLMN_Identity
),
req
->
cell_to_add
[
i
].
info
.
plmn
.
mcc
,
req
->
cell_to_add
[
i
].
info
.
plmn
.
mnc
,
req
->
cell_to_add
[
i
].
info
.
plmn
.
mnc_digit_length
);
// NR cellID
BIT_STRING_TO_NR_CELL_IDENTITY
(
&
servedCellInformation
->
nRCGI
.
nRCellIdentity
,
req
->
cell_to_add
[
i
].
info
.
nr_cellid
);
LOG_D
(
F1AP
,
"[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu
\n
"
,
assoc_id
,
req
->
cell_to_add
[
i
].
info
.
plmn
.
mcc
,
req
->
cell_to_add
[
i
].
info
.
plmn
.
mnc
,
(
long
long
unsigned
int
)
req
->
cell_to_add
[
i
].
info
.
nr_cellid
);
/* - nRPCI */
req
->
cell_to_add
[
i
].
info
.
nr_pci
=
servedCellInformation
->
nRPCI
;
LOG_D
(
F1AP
,
"req->nr_pci[%d] %d
\n
"
,
i
,
req
->
cell_to_add
[
i
].
info
.
nr_pci
);
AssertFatal
(
servedCellInformation
->
servedPLMNs
.
list
.
count
==
1
,
"only one PLMN handled
\n
"
);
req
->
cell_to_add
[
i
].
info
.
num_ssi
=
read_slice_info
(
servedCellInformation
->
servedPLMNs
.
list
.
array
[
0
],
req
->
cell_to_add
[
i
].
info
.
nssai
,
16
);
// FDD Cells
if
(
servedCellInformation
->
nR_Mode_Info
.
present
==
F1AP_NR_Mode_Info_PR_fDD
)
{
req
->
cell_to_add
[
i
].
info
.
mode
=
F1AP_MODE_FDD
;
f1ap_fdd_info_t
*
FDDs
=
&
req
->
cell_to_add
[
i
].
info
.
fdd
;
F1AP_FDD_Info_t
*
fDD_Info
=
servedCellInformation
->
nR_Mode_Info
.
choice
.
fDD
;
FDDs
->
ul_freqinfo
.
arfcn
=
fDD_Info
->
uL_NRFreqInfo
.
nRARFCN
;
AssertFatal
(
fDD_Info
->
uL_NRFreqInfo
.
freqBandListNr
.
list
.
count
==
1
,
"cannot handle more than one frequency band
\n
"
);
for
(
int
f
=
0
;
f
<
fDD_Info
->
uL_NRFreqInfo
.
freqBandListNr
.
list
.
count
;
f
++
)
{
F1AP_FreqBandNrItem_t
*
FreqItem
=
fDD_Info
->
uL_NRFreqInfo
.
freqBandListNr
.
list
.
array
[
f
];
FDDs
->
ul_freqinfo
.
band
=
FreqItem
->
freqBandIndicatorNr
;
AssertFatal
(
FreqItem
->
supportedSULBandList
.
list
.
count
==
0
,
"cannot handle SUL bands!
\n
"
);
}
FDDs
->
dl_freqinfo
.
arfcn
=
fDD_Info
->
dL_NRFreqInfo
.
nRARFCN
;
int
dlBands
=
fDD_Info
->
dL_NRFreqInfo
.
freqBandListNr
.
list
.
count
;
AssertFatal
(
dlBands
==
0
,
"cannot handled more than one frequency band
\n
"
);
for
(
int
dlB
=
0
;
dlB
<
dlBands
;
dlB
++
)
{
F1AP_FreqBandNrItem_t
*
FreqItem
=
fDD_Info
->
dL_NRFreqInfo
.
freqBandListNr
.
list
.
array
[
dlB
];
FDDs
->
dl_freqinfo
.
band
=
FreqItem
->
freqBandIndicatorNr
;
int
num_available_supported_SULBands
=
FreqItem
->
supportedSULBandList
.
list
.
count
;
AssertFatal
(
num_available_supported_SULBands
==
0
,
"cannot handle SUL bands!
\n
"
);
}
FDDs
->
ul_tbw
.
scs
=
fDD_Info
->
uL_Transmission_Bandwidth
.
nRSCS
;
FDDs
->
ul_tbw
.
nrb
=
nrb_lut
[
fDD_Info
->
uL_Transmission_Bandwidth
.
nRNRB
];
FDDs
->
dl_tbw
.
scs
=
fDD_Info
->
dL_Transmission_Bandwidth
.
nRSCS
;
FDDs
->
dl_tbw
.
nrb
=
nrb_lut
[
fDD_Info
->
dL_Transmission_Bandwidth
.
nRNRB
];
}
else
if
(
servedCellInformation
->
nR_Mode_Info
.
present
==
F1AP_NR_Mode_Info_PR_tDD
)
{
req
->
cell_to_add
[
i
].
info
.
mode
=
F1AP_MODE_TDD
;
f1ap_tdd_info_t
*
TDDs
=
&
req
->
cell_to_add
[
i
].
info
.
tdd
;
F1AP_TDD_Info_t
*
tDD_Info
=
servedCellInformation
->
nR_Mode_Info
.
choice
.
tDD
;
TDDs
->
freqinfo
.
arfcn
=
tDD_Info
->
nRFreqInfo
.
nRARFCN
;
AssertFatal
(
tDD_Info
->
nRFreqInfo
.
freqBandListNr
.
list
.
count
==
1
,
"cannot handle more than one frequency band
\n
"
);
for
(
int
f
=
0
;
f
<
tDD_Info
->
nRFreqInfo
.
freqBandListNr
.
list
.
count
;
f
++
)
{
struct
F1AP_FreqBandNrItem
*
FreqItem
=
tDD_Info
->
nRFreqInfo
.
freqBandListNr
.
list
.
array
[
f
];
TDDs
->
freqinfo
.
band
=
FreqItem
->
freqBandIndicatorNr
;
int
num_available_supported_SULBands
=
FreqItem
->
supportedSULBandList
.
list
.
count
;
AssertFatal
(
num_available_supported_SULBands
==
0
,
"cannot hanlde SUL bands!
\n
"
);
}
TDDs
->
tbw
.
scs
=
tDD_Info
->
transmission_Bandwidth
.
nRSCS
;
TDDs
->
tbw
.
nrb
=
nrb_lut
[
tDD_Info
->
transmission_Bandwidth
.
nRNRB
];
}
else
{
AssertFatal
(
false
,
"unknown NR Mode info %d
\n
"
,
servedCellInformation
->
nR_Mode_Info
.
present
);
}
/* MeasurementConfig */
if
(
servedCellInformation
->
measurementTimingConfiguration
.
size
>
0
)
req
->
cell_to_add
[
i
].
info
.
measurement_timing_config
=
cp_octet_string
(
&
servedCellInformation
->
measurementTimingConfiguration
,
&
req
->
cell_to_add
[
i
].
info
.
measurement_timing_config_len
);
struct
F1AP_GNB_DU_System_Information
*
DUsi
=
served_cells_item
->
gNB_DU_System_Information
;
// System Information
req
->
cell_to_add
[
i
].
sys_info
=
calloc
(
1
,
sizeof
(
*
req
->
cell_to_add
[
i
].
sys_info
));
AssertFatal
(
req
->
cell_to_add
[
i
].
sys_info
!=
NULL
,
"out of memory
\n
"
);
f1ap_gnb_du_system_info_t
*
sys_info
=
req
->
cell_to_add
[
i
].
sys_info
;
/* mib */
sys_info
->
mib
=
calloc
(
DUsi
->
mIB_message
.
size
,
sizeof
(
char
));
memcpy
(
sys_info
->
mib
,
DUsi
->
mIB_message
.
buf
,
DUsi
->
mIB_message
.
size
);
sys_info
->
mib_length
=
DUsi
->
mIB_message
.
size
;
/* sib1 */
sys_info
->
sib1
=
calloc
(
DUsi
->
sIB1_message
.
size
,
sizeof
(
char
));
memcpy
(
sys_info
->
sib1
,
DUsi
->
sIB1_message
.
buf
,
DUsi
->
sIB1_message
.
size
);
sys_info
->
sib1_length
=
DUsi
->
sIB1_message
.
size
;
}
}
else
{
req
->
num_cells_to_add
=
0
;
}
/* 3GPP TS 38.473 Served Cells To Modify List */
F1AP_FIND_PROTOCOLIE_BY_ID
(
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie
,
container
,
F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List
,
false
);
if
(
ie
)
{
req
->
num_cells_to_modify
=
ie
->
value
.
choice
.
Served_Cells_To_Modify_List
.
list
.
count
;
LOG_D
(
F1AP
,
"req->num_cells_to_modify %d
\n
"
,
req
->
num_cells_to_modify
);
for
(
i
=
0
;
i
<
req
->
num_cells_to_modify
;
i
++
)
{
F1AP_Served_Cells_To_Modify_Item_t
*
served_cells_item
=
&
((
F1AP_Served_Cells_To_Modify_ItemIEs_t
*
)
ie
->
value
.
choice
.
Served_Cells_To_Modify_List
.
list
.
array
[
i
])
->
value
.
choice
.
Served_Cells_To_Modify_Item
;
/* OLD NRCGI */
TBCD_TO_MCC_MNC
(
&
(
served_cells_item
->
oldNRCGI
.
pLMN_Identity
),
req
->
cell_to_modify
[
i
].
old_plmn
.
mcc
,
req
->
cell_to_modify
[
i
].
old_plmn
.
mnc
,
req
->
cell_to_modify
[
i
].
old_plmn
.
mnc_digit_length
);
BIT_STRING_TO_NR_CELL_IDENTITY
(
&
served_cells_item
->
oldNRCGI
.
nRCellIdentity
,
req
->
cell_to_modify
[
i
].
old_nr_cellid
);
F1AP_Served_Cell_Information_t
*
servedCellInformation
=
&
served_cells_item
->
served_Cell_Information
;
/* SERVED CELL INFORMATION*/
/* tac */
if
(
servedCellInformation
->
fiveGS_TAC
)
{
req
->
cell_to_modify
[
i
].
info
.
tac
=
malloc
(
sizeof
(
*
req
->
cell_to_modify
[
i
].
info
.
tac
));
AssertFatal
(
req
->
cell_to_modify
[
i
].
info
.
tac
!=
NULL
,
"out of memory
\n
"
);
OCTET_STRING_TO_INT16
(
servedCellInformation
->
fiveGS_TAC
,
*
req
->
cell_to_modify
[
i
].
info
.
tac
);
LOG_D
(
F1AP
,
"req->tac[%d] %d
\n
"
,
i
,
*
req
->
cell_to_modify
[
i
].
info
.
tac
);
}
/* - nRCGI */
TBCD_TO_MCC_MNC
(
&
(
servedCellInformation
->
nRCGI
.
pLMN_Identity
),
req
->
cell_to_modify
[
i
].
info
.
plmn
.
mcc
,
req
->
cell_to_modify
[
i
].
info
.
plmn
.
mnc
,
req
->
cell_to_modify
[
i
].
info
.
plmn
.
mnc_digit_length
);
// NR cellID
BIT_STRING_TO_NR_CELL_IDENTITY
(
&
servedCellInformation
->
nRCGI
.
nRCellIdentity
,
req
->
cell_to_modify
[
i
].
info
.
nr_cellid
);
LOG_D
(
F1AP
,
"[SCTP %d] Received nRCGI: MCC %d, MNC %d, CELL_ID %llu
\n
"
,
assoc_id
,
req
->
cell_to_modify
[
i
].
info
.
plmn
.
mcc
,
req
->
cell_to_modify
[
i
].
info
.
plmn
.
mnc
,
(
long
long
unsigned
int
)
req
->
cell_to_modify
[
i
].
info
.
nr_cellid
);
/* - nRPCI */
req
->
cell_to_modify
[
i
].
info
.
nr_pci
=
servedCellInformation
->
nRPCI
;
LOG_D
(
F1AP
,
"req->nr_pci[%d] %d
\n
"
,
i
,
req
->
cell_to_modify
[
i
].
info
.
nr_pci
);
// FDD Cells
if
(
servedCellInformation
->
nR_Mode_Info
.
present
==
F1AP_NR_Mode_Info_PR_fDD
)
{
req
->
cell_to_modify
[
i
].
info
.
mode
=
F1AP_MODE_FDD
;
f1ap_fdd_info_t
*
FDDs
=
&
req
->
cell_to_modify
[
i
].
info
.
fdd
;
F1AP_FDD_Info_t
*
fDD_Info
=
servedCellInformation
->
nR_Mode_Info
.
choice
.
fDD
;
FDDs
->
ul_freqinfo
.
arfcn
=
fDD_Info
->
uL_NRFreqInfo
.
nRARFCN
;
AssertFatal
(
fDD_Info
->
uL_NRFreqInfo
.
freqBandListNr
.
list
.
count
==
1
,
"cannot handle more than one frequency band
\n
"
);
for
(
int
f
=
0
;
f
<
fDD_Info
->
uL_NRFreqInfo
.
freqBandListNr
.
list
.
count
;
f
++
)
{
F1AP_FreqBandNrItem_t
*
FreqItem
=
fDD_Info
->
uL_NRFreqInfo
.
freqBandListNr
.
list
.
array
[
f
];
FDDs
->
ul_freqinfo
.
band
=
FreqItem
->
freqBandIndicatorNr
;
AssertFatal
(
FreqItem
->
supportedSULBandList
.
list
.
count
==
0
,
"cannot handle SUL bands!
\n
"
);
}
FDDs
->
dl_freqinfo
.
arfcn
=
fDD_Info
->
dL_NRFreqInfo
.
nRARFCN
;
int
dlBands
=
fDD_Info
->
dL_NRFreqInfo
.
freqBandListNr
.
list
.
count
;
AssertFatal
(
dlBands
==
0
,
"cannot handled more than one frequency band
\n
"
);
for
(
int
dlB
=
0
;
dlB
<
dlBands
;
dlB
++
)
{
F1AP_FreqBandNrItem_t
*
FreqItem
=
fDD_Info
->
dL_NRFreqInfo
.
freqBandListNr
.
list
.
array
[
dlB
];
FDDs
->
dl_freqinfo
.
band
=
FreqItem
->
freqBandIndicatorNr
;
int
num_available_supported_SULBands
=
FreqItem
->
supportedSULBandList
.
list
.
count
;
AssertFatal
(
num_available_supported_SULBands
==
0
,
"cannot handle SUL bands!
\n
"
);
}
FDDs
->
ul_tbw
.
scs
=
fDD_Info
->
uL_Transmission_Bandwidth
.
nRSCS
;
FDDs
->
ul_tbw
.
nrb
=
nrb_lut
[
fDD_Info
->
uL_Transmission_Bandwidth
.
nRNRB
];
FDDs
->
dl_tbw
.
scs
=
fDD_Info
->
dL_Transmission_Bandwidth
.
nRSCS
;
FDDs
->
dl_tbw
.
nrb
=
nrb_lut
[
fDD_Info
->
dL_Transmission_Bandwidth
.
nRNRB
];
}
else
if
(
servedCellInformation
->
nR_Mode_Info
.
present
==
F1AP_NR_Mode_Info_PR_tDD
)
{
req
->
cell_to_modify
[
i
].
info
.
mode
=
F1AP_MODE_TDD
;
f1ap_tdd_info_t
*
TDDs
=
&
req
->
cell_to_modify
[
i
].
info
.
tdd
;
F1AP_TDD_Info_t
*
tDD_Info
=
servedCellInformation
->
nR_Mode_Info
.
choice
.
tDD
;
TDDs
->
freqinfo
.
arfcn
=
tDD_Info
->
nRFreqInfo
.
nRARFCN
;
AssertFatal
(
tDD_Info
->
nRFreqInfo
.
freqBandListNr
.
list
.
count
==
1
,
"cannot handle more than one frequency band
\n
"
);
for
(
int
f
=
0
;
f
<
tDD_Info
->
nRFreqInfo
.
freqBandListNr
.
list
.
count
;
f
++
)
{
struct
F1AP_FreqBandNrItem
*
FreqItem
=
tDD_Info
->
nRFreqInfo
.
freqBandListNr
.
list
.
array
[
f
];
TDDs
->
freqinfo
.
band
=
FreqItem
->
freqBandIndicatorNr
;
int
num_available_supported_SULBands
=
FreqItem
->
supportedSULBandList
.
list
.
count
;
AssertFatal
(
num_available_supported_SULBands
==
0
,
"cannot hanlde SUL bands!
\n
"
);
}
TDDs
->
tbw
.
scs
=
tDD_Info
->
transmission_Bandwidth
.
nRSCS
;
TDDs
->
tbw
.
nrb
=
nrb_lut
[
tDD_Info
->
transmission_Bandwidth
.
nRNRB
];
}
else
{
AssertFatal
(
false
,
"unknown NR Mode info %d
\n
"
,
servedCellInformation
->
nR_Mode_Info
.
present
);
}
/* MeasurementConfig */
if
(
servedCellInformation
->
measurementTimingConfiguration
.
size
>
0
)
req
->
cell_to_modify
[
i
].
info
.
measurement_timing_config
=
cp_octet_string
(
&
servedCellInformation
->
measurementTimingConfiguration
,
&
req
->
cell_to_modify
[
i
].
info
.
measurement_timing_config_len
);
/*gNB DU SYSTEM INFORMATION */
struct
F1AP_GNB_DU_System_Information
*
DUsi
=
served_cells_item
->
gNB_DU_System_Information
;
if
(
DUsi
!=
NULL
)
{
// System Information
req
->
cell_to_modify
[
i
].
sys_info
=
calloc
(
1
,
sizeof
(
*
req
->
cell_to_modify
[
i
].
sys_info
));
AssertFatal
(
req
->
cell_to_modify
[
i
].
sys_info
!=
NULL
,
"out of memory
\n
"
);
f1ap_gnb_du_system_info_t
*
sys_info
=
req
->
cell_to_modify
[
i
].
sys_info
;
/* mib */
sys_info
->
mib
=
calloc
(
DUsi
->
mIB_message
.
size
,
sizeof
(
char
));
AssertFatal
(
req
->
cell_to_modify
[
i
].
sys_info
->
mib
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
sys_info
->
mib
,
DUsi
->
mIB_message
.
buf
,
DUsi
->
mIB_message
.
size
);
sys_info
->
mib_length
=
DUsi
->
mIB_message
.
size
;
/* sib1 */
sys_info
->
sib1
=
calloc
(
DUsi
->
sIB1_message
.
size
,
sizeof
(
char
));
AssertFatal
(
req
->
cell_to_modify
[
i
].
sys_info
->
sib1
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
sys_info
->
sib1
,
DUsi
->
sIB1_message
.
buf
,
DUsi
->
sIB1_message
.
size
);
sys_info
->
sib1_length
=
DUsi
->
sIB1_message
.
size
;
}
}
}
else
{
req
->
num_cells_to_modify
=
0
;
}
/* 3GPP TS 38.473 Served Cells To Delete List */
F1AP_FIND_PROTOCOLIE_BY_ID
(
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie
,
container
,
F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List
,
false
);
if
(
ie
)
{
req
->
num_cells_to_delete
=
ie
->
value
.
choice
.
Served_Cells_To_Delete_List
.
list
.
count
;
LOG_D
(
F1AP
,
"req->num_cells_to_delete %d
\n
"
,
req
->
num_cells_to_delete
);
for
(
i
=
0
;
i
<
req
->
num_cells_to_delete
;
i
++
)
{
F1AP_Served_Cells_To_Delete_Item_t
*
served_cells_item
=
&
((
F1AP_Served_Cells_To_Delete_ItemIEs_t
*
)
ie
->
value
.
choice
.
Served_Cells_To_Delete_List
.
list
.
array
[
i
])
->
value
.
choice
.
Served_Cells_To_Delete_Item
;
/* - Old nRCGI */
TBCD_TO_MCC_MNC
(
&
(
served_cells_item
->
oldNRCGI
.
pLMN_Identity
),
req
->
cell_to_delete
[
i
].
plmn
.
mcc
,
req
->
cell_to_delete
[
i
].
plmn
.
mnc
,
req
->
cell_to_delete
[
i
].
plmn
.
mnc_digit_length
);
// NR cellID
BIT_STRING_TO_NR_CELL_IDENTITY
(
&
served_cells_item
->
oldNRCGI
.
nRCellIdentity
,
req
->
cell_to_delete
[
i
].
nr_cellid
);
LOG_D
(
F1AP
,
"[SCTP %d] Received nRCGI to delete: MCC %d, MNC %d, CELL_ID %llu
\n
"
,
assoc_id
,
req
->
cell_to_delete
[
i
].
plmn
.
mcc
,
req
->
cell_to_delete
[
i
].
plmn
.
mnc
,
(
long
long
unsigned
int
)
req
->
cell_to_delete
[
i
].
nr_cellid
);
}
}
else
{
req
->
num_cells_to_delete
=
0
;
}
/* 3GPP TS 38.473 Cells Status List */
F1AP_FIND_PROTOCOLIE_BY_ID
(
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie
,
container
,
F1AP_ProtocolIE_ID_id_Cells_Status_List
,
false
);
/* 3GPP TS 38.473 Dedicated SI Delivery Needed UE List */
F1AP_FIND_PROTOCOLIE_BY_ID
(
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie
,
container
,
F1AP_ProtocolIE_ID_id_Dedicated_SIDelivery_NeededUE_List
,
false
);
/* 3GPP TS 38.473 gNB-DU ID */
F1AP_FIND_PROTOCOLIE_BY_ID
(
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie
,
container
,
F1AP_ProtocolIE_ID_id_gNB_DU_ID
,
false
);
if
(
ie
!=
NULL
)
asn_INTEGER2ulong
(
&
ie
->
value
.
choice
.
GNB_DU_ID
,
req
->
gNB_DU_ID
);
/* 3GPP TS 38.473 gNB-DU TNL Association To Remove List */
F1AP_FIND_PROTOCOLIE_BY_ID
(
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie
,
container
,
F1AP_ProtocolIE_ID_id_GNB_DU_TNL_Association_To_Remove_List
,
false
);
LOG_D
(
F1AP
,
"Sending F1AP_GNB_DU_CONFIGURATION_UPDATE ITTI message
\n
"
);
itti_send_msg_to_task
(
TASK_RRC_GNB
,
GNB_MODULE_ID_TO_INSTANCE
(
instance
),
message_p
);
return
0
;
}
int
CU_send_gNB_DU_CONFIGURATION_FAILURE
(
sctp_assoc_t
assoc_id
,
F1AP_GNBDUConfigurationUpdateFailure_t
*
GNBDUConfigurationUpdateFailure
)
{
f1ap_gnb_du_configuration_update_failure_t
*
GNBDUConfigurationUpdateFailure
)
{
AssertFatal
(
1
==
0
,
"Not implemented yet
\n
"
);
}
int
CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
(
sctp_assoc_t
assoc_id
,
F1AP_GNBDUConfigurationUpdateAcknowledge_t
*
GNBDUConfigurationUpdateAcknowledge
)
{
AssertFatal
(
1
==
0
,
"Not implemented yet
\n
"
);
int
CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
(
sctp_assoc_t
assoc_id
,
f1ap_gnb_du_configuration_update_acknowledge_t
*
GNBDUConfigurationUpdateAcknowledge
)
{
F1AP_F1AP_PDU_t
pdu
=
{};
uint8_t
*
buffer
;
uint32_t
len
;
/* Create */
/* 0. Message */
pdu
.
present
=
F1AP_F1AP_PDU_PR_successfulOutcome
;
asn1cCalloc
(
pdu
.
choice
.
successfulOutcome
,
succOut
);
succOut
->
procedureCode
=
F1AP_ProcedureCode_id_gNBDUConfigurationUpdate
;
succOut
->
criticality
=
F1AP_Criticality_reject
;
succOut
->
value
.
present
=
F1AP_SuccessfulOutcome__value_PR_GNBDUConfigurationUpdateAcknowledge
;
F1AP_GNBDUConfigurationUpdateAcknowledge_t
*
ack
=
&
succOut
->
value
.
choice
.
GNBDUConfigurationUpdateAcknowledge
;
/* Mandatory */
/* Transaction Id */
asn1cSequenceAdd
(
ack
->
protocolIEs
.
list
,
F1AP_GNBDUConfigurationUpdateAcknowledgeIEs_t
,
ie1
);
ie1
->
id
=
F1AP_ProtocolIE_ID_id_TransactionID
;
ie1
->
criticality
=
F1AP_Criticality_reject
;
ie1
->
value
.
present
=
F1AP_GNBDUConfigurationUpdateAcknowledgeIEs__value_PR_TransactionID
;
ie1
->
value
.
choice
.
TransactionID
=
GNBDUConfigurationUpdateAcknowledge
->
transaction_id
;
/* Todo add optional fields */
/* encode */
if
(
f1ap_encode_pdu
(
&
pdu
,
&
buffer
,
&
len
)
<
0
)
{
LOG_E
(
F1AP
,
"Failed to encode F1 gNB-DU CONFIGURATION UPDATE
\n
"
);
return
-
1
;
}
LOG_DUMPMSG
(
F1AP
,
LOG_DUMP_CHAR
,
buffer
,
len
,
"F1AP gNB-DU CONFIGURATION UPDATE : "
);
ASN_STRUCT_RESET
(
asn_DEF_F1AP_F1AP_PDU
,
&
pdu
);
f1ap_itti_send_sctp_data_req
(
assoc_id
,
buffer
,
len
);
return
0
;
}
/*
...
...
openair2/F1AP/f1ap_cu_interface_management.h
View file @
65d494fb
...
...
@@ -62,10 +62,11 @@ int CU_send_F1_SETUP_FAILURE(sctp_assoc_t assoc_id, const f1ap_setup_failure_t *
int
CU_handle_gNB_DU_CONFIGURATION_UPDATE
(
instance_t
instance
,
sctp_assoc_t
assoc_id
,
uint32_t
stream
,
F1AP_F1AP_PDU_t
*
pdu
);
int
CU_send_gNB_DU_CONFIGURATION_FAILURE
(
sctp_assoc_t
assoc_id
,
F1AP_GNBDUConfigurationUpdateF
ailure_t
*
GNBDUConfigurationUpdateFailure
);
f1ap_gnb_du_configuration_update_f
ailure_t
*
GNBDUConfigurationUpdateFailure
);
int
CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
(
sctp_assoc_t
assoc_id
,
F1AP_GNBDUConfigurationUpdateAcknowledge_t
*
GNBDUConfigurationUpdateAcknowledge
);
int
CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
(
sctp_assoc_t
assoc_id
,
f1ap_gnb_du_configuration_update_acknowledge_t
*
GNBDUConfigurationUpdateAcknowledge
);
/*
* gNB-CU Configuration Update
...
...
openair2/F1AP/f1ap_cu_task.c
View file @
65d494fb
...
...
@@ -174,6 +174,9 @@ void *F1AP_CU_task(void *arg) {
&
F1AP_GNB_CU_CONFIGURATION_UPDATE
(
received_msg
));
break
;
case
F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
:
CU_send_gNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
(
assoc_id
,
&
F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
(
received_msg
));
break
;
case
F1AP_DL_RRC_MESSAGE
:
// from rrc
CU_send_DL_RRC_MESSAGE_TRANSFER
(
assoc_id
,
&
F1AP_DL_RRC_MESSAGE
(
received_msg
));
...
...
openair2/F1AP/f1ap_cu_ue_context_management.c
View file @
65d494fb
...
...
@@ -274,27 +274,27 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
}
}
/* mandatory */
/* optional */
if
(
0
)
{
/* c7. Candidate_SpCell_List */
asn1cSequenceAdd
(
out
->
protocolIEs
.
list
,
F1AP_UEContextSetupRequestIEs_t
,
ie7
);
ie7
->
id
=
F1AP_ProtocolIE_ID_id_Candidate_SpCell_List
;
//
90
ie7
->
id
=
F1AP_ProtocolIE_ID_id_Candidate_SpCell_List
;
//
90
ie7
->
criticality
=
F1AP_Criticality_ignore
;
ie7
->
value
.
present
=
F1AP_UEContextSetupRequestIEs__value_PR_Candidate_SpCell_List
;
for
(
int
i
=
0
;
i
<
1
;
i
++
)
{
asn1cSequenceAdd
(
ie7
->
value
.
choice
.
Candidate_SpCell_List
.
list
,
F1AP_Candidate_SpCell_ItemIEs_t
,
candidate_spCell_item_ies
);
for
(
int
i
=
0
;
i
<
1
;
i
++
)
{
asn1cSequenceAdd
(
ie7
->
value
.
choice
.
Candidate_SpCell_List
.
list
,
F1AP_Candidate_SpCell_ItemIEs_t
,
candidate_spCell_item_ies
);
candidate_spCell_item_ies
->
id
=
F1AP_ProtocolIE_ID_id_Candidate_SpCell_Item
;
// 91
candidate_spCell_item_ies
->
criticality
=
F1AP_Criticality_reject
;
candidate_spCell_item_ies
->
criticality
=
F1AP_Criticality_ignore
;
candidate_spCell_item_ies
->
value
.
present
=
F1AP_Candidate_SpCell_ItemIEs__value_PR_Candidate_SpCell_Item
;
/* 7.1 Candidate_SpCell_Item */
F1AP_Candidate_SpCell_Item_t
*
candidate_spCell_item
=
&
candidate_spCell_item_ies
->
value
.
choice
.
Candidate_SpCell_Item
;
F1AP_Candidate_SpCell_Item_t
*
candidate_spCell_item
=
&
candidate_spCell_item_ies
->
value
.
choice
.
Candidate_SpCell_Item
;
/* - candidate_SpCell_ID */
//
FixMe: first cell ???
addnRCGI
(
candidate_spCell_item
->
candidate_SpCell_ID
,
f1ap_ue_context_setup_req
);
//
FixMe: first cell ???
addnRCGI
(
candidate_spCell_item
->
candidate_SpCell_ID
,
f1ap_ue_context_setup_req
);
/* TODO add correct mcc/mnc */
}
}
/* optional */
/* c8. DRXCycle */
...
...
@@ -335,21 +335,21 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
strlen
(
"asdsa1d32sa1d31asd31as"
));
}
/* mandatory */
/* optional */
if
(
0
)
{
/* c10. SCell_ToBeSetup_List */
asn1cSequenceAdd
(
out
->
protocolIEs
.
list
,
F1AP_UEContextSetupRequestIEs_t
,
ie10
);
ie10
->
id
=
F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_List
;
ie10
->
criticality
=
F1AP_Criticality_ignore
;
ie10
->
value
.
present
=
F1AP_UEContextSetupRequestIEs__value_PR_SCell_ToBeSetup_List
;
for
(
int
i
=
0
;
i
<
1
;
i
++
)
{
//
for
(
int
i
=
0
;
i
<
1
;
i
++
)
{
asn1cSequenceAdd
(
ie10
->
value
.
choice
.
SCell_ToBeSetup_List
.
list
,
F1AP_SCell_ToBeSetup_ItemIEs_t
,
scell_toBeSetup_item_ies
);
scell_toBeSetup_item_ies
->
id
=
F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_Item
;
//
53
scell_toBeSetup_item_ies
->
id
=
F1AP_ProtocolIE_ID_id_SCell_ToBeSetup_Item
;
//
53
scell_toBeSetup_item_ies
->
criticality
=
F1AP_Criticality_ignore
;
scell_toBeSetup_item_ies
->
value
.
present
=
F1AP_SCell_ToBeSetup_ItemIEs__value_PR_SCell_ToBeSetup_Item
;
/* 10.1 SCell_ToBeSetup_Item */
F1AP_SCell_ToBeSetup_Item_t
*
scell_toBeSetup_item
=
&
scell_toBeSetup_item_ies
->
value
.
choice
.
SCell_ToBeSetup_Item
;
F1AP_SCell_ToBeSetup_Item_t
*
scell_toBeSetup_item
=
&
scell_toBeSetup_item_ies
->
value
.
choice
.
SCell_ToBeSetup_Item
;
/* 10.1.1 sCell_ID */
addnRCGI
(
scell_toBeSetup_item
->
sCell_ID
,
f1ap_ue_context_setup_req
);
/* TODO correct MCC/MNC */
...
...
@@ -363,6 +363,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
F1AP_CellULConfigured_ul_and_sul
);
// enum
}
}
}
/* mandatory */
/* c11. SRBs_ToBeSetup_List */
...
...
@@ -375,7 +376,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
for
(
int
i
=
0
;
i
<
f1ap_ue_context_setup_req
->
srbs_to_be_setup_length
;
i
++
)
{
asn1cSequenceAdd
(
ie11
->
value
.
choice
.
SRBs_ToBeSetup_List
.
list
,
F1AP_SRBs_ToBeSetup_ItemIEs_t
,
srbs_toBeSetup_item_ies
);
srbs_toBeSetup_item_ies
->
id
=
F1AP_ProtocolIE_ID_id_SRBs_ToBeSetup_Item
;
// 73
srbs_toBeSetup_item_ies
->
criticality
=
F1AP_Criticality_ignore
;
srbs_toBeSetup_item_ies
->
criticality
=
F1AP_Criticality_reject
;
srbs_toBeSetup_item_ies
->
value
.
present
=
F1AP_SRBs_ToBeSetup_ItemIEs__value_PR_SRBs_ToBeSetup_Item
;
/* 11.1 SRBs_ToBeSetup_Item */
F1AP_SRBs_ToBeSetup_Item_t
*
srbs_toBeSetup_item
=&
srbs_toBeSetup_item_ies
->
value
.
choice
.
SRBs_ToBeSetup_Item
;
...
...
@@ -539,7 +540,7 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_ue_context_setu
if
(
f1ap_ue_context_setup_req
->
rrc_container_length
>
0
)
{
asn1cSequenceAdd
(
out
->
protocolIEs
.
list
,
F1AP_UEContextSetupRequestIEs_t
,
ie14
);
ie14
->
id
=
F1AP_ProtocolIE_ID_id_RRCContainer
;
ie14
->
criticality
=
F1AP_Criticality_reject
;
ie14
->
criticality
=
F1AP_Criticality_ignore
;
ie14
->
value
.
present
=
F1AP_UEContextSetupRequestIEs__value_PR_RRCContainer
;
OCTET_STRING_fromBuf
(
&
ie14
->
value
.
choice
.
RRCContainer
,
(
const
char
*
)
f1ap_ue_context_setup_req
->
rrc_container
,
f1ap_ue_context_setup_req
->
rrc_container_length
);
...
...
openair2/F1AP/f1ap_du_interface_management.c
View file @
65d494fb
...
...
@@ -83,153 +83,80 @@ int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint3
AssertFatal
(
1
==
0
,
"Not implemented yet
\n
"
);
}
/*
F1 Setup
*/
// SETUP REQUEST
int
DU_send_F1_SETUP_REQUEST
(
sctp_assoc_t
assoc_id
,
f1ap_setup_req_t
*
setup_req
)
static
F1AP_Served_Cell_Information_t
encode_served_cell_info
(
const
f1ap_served_cell_info_t
*
c
)
{
F1AP_F1AP_PDU_t
pdu
=
{
0
};
uint8_t
*
buffer
;
uint32_t
len
;
/* Create */
/* 0. pdu Type */
pdu
.
present
=
F1AP_F1AP_PDU_PR_initiatingMessage
;
asn1cCalloc
(
pdu
.
choice
.
initiatingMessage
,
initMsg
);
initMsg
->
procedureCode
=
F1AP_ProcedureCode_id_F1Setup
;
initMsg
->
criticality
=
F1AP_Criticality_reject
;
initMsg
->
value
.
present
=
F1AP_InitiatingMessage__value_PR_F1SetupRequest
;
F1AP_F1SetupRequest_t
*
f1Setup
=
&
initMsg
->
value
.
choice
.
F1SetupRequest
;
/* mandatory */
/* c1. Transaction ID (integer value) */
asn1cSequenceAdd
(
f1Setup
->
protocolIEs
.
list
,
F1AP_F1SetupRequestIEs_t
,
ieC1
);
ieC1
->
id
=
F1AP_ProtocolIE_ID_id_TransactionID
;
ieC1
->
criticality
=
F1AP_Criticality_reject
;
ieC1
->
value
.
present
=
F1AP_F1SetupRequestIEs__value_PR_TransactionID
;
ieC1
->
value
.
choice
.
TransactionID
=
F1AP_get_next_transaction_identifier
(
0
,
0
);
/* mandatory */
/* c2. GNB_DU_ID (integer value) */
asn1cSequenceAdd
(
f1Setup
->
protocolIEs
.
list
,
F1AP_F1SetupRequestIEs_t
,
ieC2
);
ieC2
->
id
=
F1AP_ProtocolIE_ID_id_gNB_DU_ID
;
ieC2
->
criticality
=
F1AP_Criticality_reject
;
ieC2
->
value
.
present
=
F1AP_F1SetupRequestIEs__value_PR_GNB_DU_ID
;
asn_int642INTEGER
(
&
ieC2
->
value
.
choice
.
GNB_DU_ID
,
setup_req
->
gNB_DU_id
);
/* optional */
/* c3. GNB_DU_Name */
if
(
setup_req
->
gNB_DU_name
!=
NULL
)
{
asn1cSequenceAdd
(
f1Setup
->
protocolIEs
.
list
,
F1AP_F1SetupRequestIEs_t
,
ieC3
);
ieC3
->
id
=
F1AP_ProtocolIE_ID_id_gNB_DU_Name
;
ieC3
->
criticality
=
F1AP_Criticality_ignore
;
ieC3
->
value
.
present
=
F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Name
;
char
*
gNB_DU_name
=
setup_req
->
gNB_DU_name
;
OCTET_STRING_fromBuf
(
&
ieC3
->
value
.
choice
.
GNB_DU_Name
,
gNB_DU_name
,
strlen
(
gNB_DU_name
));
}
/* mandatory */
/* c4. served cells list */
asn1cSequenceAdd
(
f1Setup
->
protocolIEs
.
list
,
F1AP_F1SetupRequestIEs_t
,
ieCells
);
ieCells
->
id
=
F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List
;
ieCells
->
criticality
=
F1AP_Criticality_reject
;
ieCells
->
value
.
present
=
F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Served_Cells_List
;
int
num_cells_available
=
setup_req
->
num_cells_available
;
LOG_D
(
F1AP
,
"num_cells_available = %d
\n
"
,
num_cells_available
);
for
(
int
i
=
0
;
i
<
num_cells_available
;
i
++
)
{
/* mandatory */
/* 4.1 served cells item */
f1ap_served_cell_info_t
*
cell
=
&
setup_req
->
cell
[
i
].
info
;
asn1cSequenceAdd
(
ieCells
->
value
.
choice
.
GNB_DU_Served_Cells_List
.
list
,
F1AP_GNB_DU_Served_Cells_ItemIEs_t
,
duServedCell
);
duServedCell
->
id
=
F1AP_ProtocolIE_ID_id_GNB_DU_Served_Cells_Item
;
duServedCell
->
criticality
=
F1AP_Criticality_reject
;
duServedCell
->
value
.
present
=
F1AP_GNB_DU_Served_Cells_ItemIEs__value_PR_GNB_DU_Served_Cells_Item
;
F1AP_GNB_DU_Served_Cells_Item_t
*
gnb_du_served_cells_item
=&
duServedCell
->
value
.
choice
.
GNB_DU_Served_Cells_Item
;
/* 4.1.1 served cell Information */
F1AP_Served_Cell_Information_t
*
served_cell_information
=
&
gnb_du_served_cells_item
->
served_Cell_Information
;
addnRCGI
(
served_cell_information
->
nRCGI
,
cell
);
F1AP_Served_Cell_Information_t
scell_info
=
{
0
};
addnRCGI
(
scell_info
.
nRCGI
,
c
);
/* - nRPCI */
served_cell_information
->
nRPCI
=
cell
->
nr_pci
;
// int 0..1007
scell_info
.
nRPCI
=
c
->
nr_pci
;
// int 0..1007
/* - fiveGS_TAC */
if
(
cell
->
tac
!=
NULL
)
{
uint32_t
tac
=
htonl
(
*
cell
->
tac
);
asn1cCalloc
(
served_cell_information
->
fiveGS_TAC
,
netOrder
);
OCTET_STRING_fromBuf
(
netOrder
,
((
char
*
)
&
tac
)
+
1
,
3
);
if
(
c
->
tac
!=
NULL
)
{
uint32_t
tac
=
htonl
(
*
c
->
tac
);
asn1cCalloc
(
scell_info
.
fiveGS_TAC
,
netOrder
);
OCTET_STRING_fromBuf
(
netOrder
,
((
char
*
)
&
tac
)
+
1
,
3
);
}
/* - Configured_EPS_TAC */
if
(
0
)
{
served_cell_information
->
configured_EPS_TAC
=
(
F1AP_Configured_EPS_TAC_t
*
)
calloc
(
1
,
sizeof
(
F1AP_Configured_EPS_TAC_t
));
OCTET_STRING_fromBuf
(
served_cell_information
->
configured_EPS_TAC
,
"2"
,
2
);
if
(
0
)
{
scell_info
.
configured_EPS_TAC
=
(
F1AP_Configured_EPS_TAC_t
*
)
calloc
(
1
,
sizeof
(
F1AP_Configured_EPS_TAC_t
));
OCTET_STRING_fromBuf
(
scell_info
.
configured_EPS_TAC
,
"2"
,
2
);
}
/* servedPLMN information */
asn1cSequenceAdd
(
served_cell_information
->
servedPLMNs
.
list
,
F1AP_ServedPLMNs_Item_t
,
servedPLMN_item
);
MCC_MNC_TO_PLMNID
(
cell
->
plmn
.
mcc
,
cell
->
plmn
.
mnc
,
cell
->
plmn
.
mnc_digit_length
,
&
servedPLMN_item
->
pLMN_Identity
);
// // /* - CHOICE NR-MODE-Info */
F1AP_NR_Mode_Info_t
*
nR_Mode_Info
=
&
served_cell_information
->
nR_Mode_Info
;
asn1cSequenceAdd
(
scell_info
.
servedPLMNs
.
list
,
F1AP_ServedPLMNs_Item_t
,
servedPLMN_item
);
MCC_MNC_TO_PLMNID
(
c
->
plmn
.
mcc
,
c
->
plmn
.
mnc
,
c
->
plmn
.
mnc_digit_length
,
&
servedPLMN_item
->
pLMN_Identity
);
F1AP_NR_Mode_Info_t
*
nR_Mode_Info
=
&
scell_info
.
nR_Mode_Info
;
if
(
c
->
num_ssi
>
0
)
{
F1AP_ProtocolExtensionContainer_10696P34_t
*
p
=
calloc
(
1
,
sizeof
(
*
p
));
servedPLMN_item
->
iE_Extensions
=
(
struct
F1AP_ProtocolExtensionContainer
*
)
p
;
asn1cSequenceAdd
(
p
->
list
,
F1AP_ServedPLMNs_ItemExtIEs_t
,
served_plmns_itemExtIEs
);
servedPLMN_item
->
iE_Extensions
=
(
struct
F1AP_ProtocolExtensionContainer
*
)
p
;
asn1cSequenceAdd
(
p
->
list
,
F1AP_ServedPLMNs_ItemExtIEs_t
,
served_plmns_itemExtIEs
);
served_plmns_itemExtIEs
->
criticality
=
F1AP_Criticality_ignore
;
served_plmns_itemExtIEs
->
id
=
F1AP_ProtocolIE_ID_id_TAISliceSupportList
;
served_plmns_itemExtIEs
->
extensionValue
.
present
=
F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList
;
F1AP_SliceSupportList_t
*
slice_support_list
=
&
served_plmns_itemExtIEs
->
extensionValue
.
choice
.
SliceSupportList
;
/* get list of sst/sd from configuration file */
paramdef_t
SNSSAIParams
[]
=
GNBSNSSAIPARAMS_DESC
;
paramlist_def_t
SNSSAIParamList
=
{
GNB_CONFIG_STRING_SNSSAI_LIST
,
NULL
,
0
};
char
sstr
[
100
];
/* TODO: be sure that %d in the line below is at the right place */
sprintf
(
sstr
,
"%s.[%d].%s.[0]"
,
GNB_CONFIG_STRING_GNB_LIST
,
i
,
GNB_CONFIG_STRING_PLMN_LIST
);
config_getlist
(
config_get_if
(),
&
SNSSAIParamList
,
SNSSAIParams
,
sizeofArray
(
SNSSAIParams
),
sstr
);
AssertFatal
(
SNSSAIParamList
.
numelt
>
0
,
"no slice configuration found (snssaiList in the configuration file)
\n
"
);
AssertFatal
(
SNSSAIParamList
.
numelt
<=
1024
,
"maximum size for slice support list is 1024, see F1AP 38.473 9.3.1.37
\n
"
);
for
(
int
s
=
0
;
s
<
SNSSAIParamList
.
numelt
;
s
++
)
{
uint32_t
sst
;
uint32_t
sd
;
bool
has_sd
;
sst
=
*
SNSSAIParamList
.
paramarray
[
s
][
GNB_SLICE_SERVICE_TYPE_IDX
].
uptr
;
has_sd
=
*
SNSSAIParamList
.
paramarray
[
s
][
GNB_SLICE_DIFFERENTIATOR_IDX
].
uptr
!=
0xffffff
;
for
(
int
s
=
0
;
s
<
c
->
num_ssi
;
s
++
)
{
asn1cSequenceAdd
(
slice_support_list
->
list
,
F1AP_SliceSupportItem_t
,
slice
);
INT8_TO_OCTET_STRING
(
sst
,
&
slice
->
sNSSAI
.
sST
)
;
if
(
has_sd
)
{
sd
=
*
SNSSAIParamList
.
paramarray
[
s
][
GNB_SLICE_DIFFERENTIATOR_IDX
].
uptr
;
const
nssai_t
*
nssai
=
&
c
->
nssai
[
s
]
;
INT8_TO_OCTET_STRING
(
nssai
->
sst
,
&
slice
->
sNSSAI
.
sST
);
if
(
nssai
->
sd
!=
0xffffff
)
{
asn1cCalloc
(
slice
->
sNSSAI
.
sD
,
tmp
);
INT24_TO_OCTET_STRING
(
sd
,
tmp
);
INT24_TO_OCTET_STRING
(
nssai
->
sd
,
tmp
);
}
}
}
if
(
setup_req
->
cell
[
i
].
info
.
mode
==
F1AP_MODE_FDD
)
{
// FDD
const
f1ap_fdd_info_t
*
fdd
=
&
setup_req
->
cell
[
i
].
info
.
fdd
;
if
(
c
->
mode
==
F1AP_MODE_FDD
)
{
// FDD
const
f1ap_fdd_info_t
*
fdd
=
&
c
->
fdd
;
nR_Mode_Info
->
present
=
F1AP_NR_Mode_Info_PR_fDD
;
asn1cCalloc
(
nR_Mode_Info
->
choice
.
fDD
,
fDD_Info
);
/* FDD.1 UL NRFreqInfo */
/* FDD.1.1 UL NRFreqInfo ARFCN */
fDD_Info
->
uL_NRFreqInfo
.
nRARFCN
=
fdd
->
ul_freqinfo
.
arfcn
;
// Integer
/* FDD.1.2 F1AP_SUL_Information */
/* FDD.1.3 freqBandListNr */
int
fdd_ul_num_available_freq_Bands
=
1
;
for
(
int
fdd_ul_j
=
0
;
fdd_ul_j
<
fdd_ul_num_available_freq_Bands
;
fdd_ul_
j
++
)
{
int
ul_band
=
1
;
for
(
int
j
=
0
;
j
<
ul_band
;
j
++
)
{
asn1cSequenceAdd
(
fDD_Info
->
uL_NRFreqInfo
.
freqBandListNr
.
list
,
F1AP_FreqBandNrItem_t
,
nr_freqBandNrItem
);
/* FDD.1.3.1 freqBandIndicatorNr*/
nr_freqBandNrItem
->
freqBandIndicatorNr
=
fdd
->
ul_freqinfo
.
band
;
/* FDD.1.3.2 supportedSULBandList*/
}
// for FDD : UL freq_Bands
}
/* FDD.2 DL NRFreqInfo */
/* FDD.2.1 DL NRFreqInfo ARFCN */
fDD_Info
->
dL_NRFreqInfo
.
nRARFCN
=
fdd
->
dl_freqinfo
.
arfcn
;
// Integer
/* FDD.2.2 F1AP_SUL_Information */
/* FDD.2.3 freqBandListNr */
int
fdd_dl_num_available_freq_B
ands
=
1
;
for
(
int
fdd_dl_j
=
0
;
fdd_dl_j
<
fdd_dl_num_available_freq_Bands
;
fdd_dl_
j
++
)
{
int
dl_b
ands
=
1
;
for
(
int
j
=
0
;
j
<
dl_bands
;
j
++
)
{
asn1cSequenceAdd
(
fDD_Info
->
dL_NRFreqInfo
.
freqBandListNr
.
list
,
F1AP_FreqBandNrItem_t
,
nr_freqBandNrItem
);
/* FDD.2.3.1 freqBandIndicatorNr*/
nr_freqBandNrItem
->
freqBandIndicatorNr
=
fdd
->
dl_freqinfo
.
band
;
...
...
@@ -243,47 +170,118 @@ int DU_send_F1_SETUP_REQUEST(sctp_assoc_t assoc_id, f1ap_setup_req_t *setup_req)
/* FDD.4 DL Transmission Bandwidth */
fDD_Info
->
dL_Transmission_Bandwidth
.
nRSCS
=
fdd
->
dl_tbw
.
scs
;
fDD_Info
->
dL_Transmission_Bandwidth
.
nRNRB
=
to_NRNRB
(
fdd
->
dl_tbw
.
nrb
);
}
else
if
(
setup_req
->
cell
[
i
].
info
.
mode
==
F1AP_MODE_TDD
)
{
// TDD
const
f1ap_tdd_info_t
*
tdd
=
&
setup_req
->
cell
[
i
].
info
.
tdd
;
}
else
if
(
c
->
mode
==
F1AP_MODE_TDD
)
{
const
f1ap_tdd_info_t
*
tdd
=
&
c
->
tdd
;
nR_Mode_Info
->
present
=
F1AP_NR_Mode_Info_PR_tDD
;
asn1cCalloc
(
nR_Mode_Info
->
choice
.
tDD
,
tDD_Info
);
/* TDD.1 nRFreqInfo */
/* TDD.1.1 nRFreqInfo ARFCN */
tDD_Info
->
nRFreqInfo
.
nRARFCN
=
tdd
->
freqinfo
.
arfcn
;
// Integer
tDD_Info
->
nRFreqInfo
.
nRARFCN
=
tdd
->
freqinfo
.
arfcn
;
/* TDD.1.2 F1AP_SUL_Information */
/* TDD.1.3 freqBandListNr */
int
tdd_num_available_freq_B
ands
=
1
;
for
(
int
j
=
0
;
j
<
tdd_num_available_freq_B
ands
;
j
++
)
{
int
b
ands
=
1
;
for
(
int
j
=
0
;
j
<
b
ands
;
j
++
)
{
asn1cSequenceAdd
(
tDD_Info
->
nRFreqInfo
.
freqBandListNr
.
list
,
F1AP_FreqBandNrItem_t
,
nr_freqBandNrItem
);
/* TDD.1.3.1 freqBandIndicatorNr*/
nr_freqBandNrItem
->
freqBandIndicatorNr
=
tdd
->
freqinfo
.
band
;
/* TDD.1.3.2 supportedSULBandList*/
}
// for TDD : freq_Bands
}
/* TDD.2 transmission_Bandwidth */
tDD_Info
->
transmission_Bandwidth
.
nRSCS
=
tdd
->
tbw
.
scs
;
tDD_Info
->
transmission_Bandwidth
.
nRNRB
=
to_NRNRB
(
tdd
->
tbw
.
nrb
);
}
else
{
AssertFatal
(
false
,
"unknown mode %d
\n
"
,
setup_req
->
cell
[
i
].
info
.
mode
);
AssertFatal
(
false
,
"unknown mode %d
\n
"
,
c
->
mode
);
}
/* - measurementTimingConfiguration */
char
*
measurementTimingConfiguration
=
cell
->
measurement_timing_information
;
// sept. 2018
OCTET_STRING_fromBuf
(
&
served_cell_information
->
measurementTimingConfiguration
,
measurementTimingConfiguration
,
strlen
(
measurementTimingConfiguration
));
/* 4.1.2 gNB-DU System Information */
if
(
setup_req
->
cell
[
i
].
sys_info
!=
NULL
)
{
asn1cCalloc
(
gnb_du_served_cells_item
->
gNB_DU_System_Information
,
gNB_DU_System_Information
);
const
f1ap_gnb_du_system_info_t
*
sys_info
=
setup_req
->
cell
[
i
].
sys_info
;
OCTET_STRING_fromBuf
(
&
scell_info
.
measurementTimingConfiguration
,
(
const
char
*
)
c
->
measurement_timing_config
,
c
->
measurement_timing_config_len
);
return
scell_info
;
}
static
F1AP_GNB_DU_System_Information_t
*
encode_system_info
(
const
f1ap_gnb_du_system_info_t
*
sys_info
)
{
if
(
sys_info
==
NULL
)
return
NULL
;
/* optional: can be NULL */
F1AP_GNB_DU_System_Information_t
*
enc_sys_info
=
calloc
(
1
,
sizeof
(
*
enc_sys_info
));
AssertFatal
(
enc_sys_info
!=
NULL
,
"out of memory
\n
"
);
AssertFatal
(
sys_info
->
mib
!=
NULL
,
"MIB must be present in DU sys info
\n
"
);
OCTET_STRING_fromBuf
(
&
gNB_DU_System_Information
->
mIB_message
,
(
const
char
*
)
sys_info
->
mib
,
sys_info
->
mib_length
);
OCTET_STRING_fromBuf
(
&
enc_sys_info
->
mIB_message
,
(
const
char
*
)
sys_info
->
mib
,
sys_info
->
mib_length
);
AssertFatal
(
sys_info
->
sib1
!=
NULL
,
"SIB1 must be present in DU sys info
\n
"
);
OCTET_STRING_fromBuf
(
&
gNB_DU_System_Information
->
sIB1_message
,
(
const
char
*
)
sys_info
->
sib1
,
sys_info
->
sib1_length
);
OCTET_STRING_fromBuf
(
&
enc_sys_info
->
sIB1_message
,
(
const
char
*
)
sys_info
->
sib1
,
sys_info
->
sib1_length
);
return
enc_sys_info
;
}
// SETUP REQUEST
int
DU_send_F1_SETUP_REQUEST
(
sctp_assoc_t
assoc_id
,
const
f1ap_setup_req_t
*
setup_req
)
{
F1AP_F1AP_PDU_t
pdu
=
{
0
};
uint8_t
*
buffer
;
uint32_t
len
;
/* Create */
/* 0. pdu Type */
pdu
.
present
=
F1AP_F1AP_PDU_PR_initiatingMessage
;
asn1cCalloc
(
pdu
.
choice
.
initiatingMessage
,
initMsg
);
initMsg
->
procedureCode
=
F1AP_ProcedureCode_id_F1Setup
;
initMsg
->
criticality
=
F1AP_Criticality_reject
;
initMsg
->
value
.
present
=
F1AP_InitiatingMessage__value_PR_F1SetupRequest
;
F1AP_F1SetupRequest_t
*
f1Setup
=
&
initMsg
->
value
.
choice
.
F1SetupRequest
;
/* mandatory */
/* c1. Transaction ID (integer value) */
asn1cSequenceAdd
(
f1Setup
->
protocolIEs
.
list
,
F1AP_F1SetupRequestIEs_t
,
ieC1
);
ieC1
->
id
=
F1AP_ProtocolIE_ID_id_TransactionID
;
ieC1
->
criticality
=
F1AP_Criticality_reject
;
ieC1
->
value
.
present
=
F1AP_F1SetupRequestIEs__value_PR_TransactionID
;
ieC1
->
value
.
choice
.
TransactionID
=
F1AP_get_next_transaction_identifier
(
0
,
0
);
/* mandatory */
/* c2. GNB_DU_ID (integer value) */
asn1cSequenceAdd
(
f1Setup
->
protocolIEs
.
list
,
F1AP_F1SetupRequestIEs_t
,
ieC2
);
ieC2
->
id
=
F1AP_ProtocolIE_ID_id_gNB_DU_ID
;
ieC2
->
criticality
=
F1AP_Criticality_reject
;
ieC2
->
value
.
present
=
F1AP_F1SetupRequestIEs__value_PR_GNB_DU_ID
;
asn_int642INTEGER
(
&
ieC2
->
value
.
choice
.
GNB_DU_ID
,
setup_req
->
gNB_DU_id
);
/* optional */
/* c3. GNB_DU_Name */
if
(
setup_req
->
gNB_DU_name
!=
NULL
)
{
asn1cSequenceAdd
(
f1Setup
->
protocolIEs
.
list
,
F1AP_F1SetupRequestIEs_t
,
ieC3
);
ieC3
->
id
=
F1AP_ProtocolIE_ID_id_gNB_DU_Name
;
ieC3
->
criticality
=
F1AP_Criticality_ignore
;
ieC3
->
value
.
present
=
F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Name
;
char
*
gNB_DU_name
=
setup_req
->
gNB_DU_name
;
OCTET_STRING_fromBuf
(
&
ieC3
->
value
.
choice
.
GNB_DU_Name
,
gNB_DU_name
,
strlen
(
gNB_DU_name
));
}
/* mandatory */
/* c4. served cells list */
asn1cSequenceAdd
(
f1Setup
->
protocolIEs
.
list
,
F1AP_F1SetupRequestIEs_t
,
ieCells
);
ieCells
->
id
=
F1AP_ProtocolIE_ID_id_gNB_DU_Served_Cells_List
;
ieCells
->
criticality
=
F1AP_Criticality_reject
;
ieCells
->
value
.
present
=
F1AP_F1SetupRequestIEs__value_PR_GNB_DU_Served_Cells_List
;
int
num_cells_available
=
setup_req
->
num_cells_available
;
LOG_D
(
F1AP
,
"num_cells_available = %d
\n
"
,
num_cells_available
);
for
(
int
i
=
0
;
i
<
num_cells_available
;
i
++
)
{
/* mandatory */
/* 4.1 served cells item */
const
f1ap_served_cell_info_t
*
cell
=
&
setup_req
->
cell
[
i
].
info
;
const
f1ap_gnb_du_system_info_t
*
sys_info
=
setup_req
->
cell
[
i
].
sys_info
;
asn1cSequenceAdd
(
ieCells
->
value
.
choice
.
GNB_DU_Served_Cells_List
.
list
,
F1AP_GNB_DU_Served_Cells_ItemIEs_t
,
duServedCell
);
duServedCell
->
id
=
F1AP_ProtocolIE_ID_id_GNB_DU_Served_Cells_Item
;
duServedCell
->
criticality
=
F1AP_Criticality_reject
;
duServedCell
->
value
.
present
=
F1AP_GNB_DU_Served_Cells_ItemIEs__value_PR_GNB_DU_Served_Cells_Item
;
F1AP_GNB_DU_Served_Cells_Item_t
*
scell_item
=
&
duServedCell
->
value
.
choice
.
GNB_DU_Served_Cells_Item
;
scell_item
->
served_Cell_Information
=
encode_served_cell_info
(
cell
);
scell_item
->
gNB_DU_System_Information
=
encode_system_info
(
sys_info
);
}
/* mandatory */
...
...
@@ -534,7 +532,7 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3
gNB-DU Configuration Update
*/
int
DU_send_gNB_DU_CONFIGURATION_UPDATE
(
sctp_assoc_t
assoc_id
,
f1ap_setup_req_t
*
f1ap_setup_req
)
int
DU_send_gNB_DU_CONFIGURATION_UPDATE
(
sctp_assoc_t
assoc_id
,
const
f1ap_gnb_du_configuration_update_t
*
upd
)
{
F1AP_F1AP_PDU_t
pdu
=
{
0
};
uint8_t
*
buffer
=
NULL
;
...
...
@@ -546,227 +544,100 @@ int DU_send_gNB_DU_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id, f1ap_setup_req_t
initMsg
->
procedureCode
=
F1AP_ProcedureCode_id_gNBDUConfigurationUpdate
;
initMsg
->
criticality
=
F1AP_Criticality_reject
;
initMsg
->
value
.
present
=
F1AP_InitiatingMessage__value_PR_GNBDUConfigurationUpdate
;
F1AP_GNBDUConfigurationUpdate_t
*
out
=
&
pdu
.
choice
.
initiatingMessage
->
value
.
choice
.
GNBDUConfigurationUpdate
;
F1AP_GNBDUConfigurationUpdate_t
*
out
=
&
initMsg
->
value
.
choice
.
GNBDUConfigurationUpdate
;
/* mandatory */
/* c1. Transaction ID (integer value) */
asn1cSequenceAdd
(
out
,
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie1
);
asn1cSequenceAdd
(
out
->
protocolIEs
.
list
,
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie1
);
ie1
->
id
=
F1AP_ProtocolIE_ID_id_TransactionID
;
ie1
->
criticality
=
F1AP_Criticality_reject
;
ie1
->
value
.
present
=
F1AP_GNBDUConfigurationUpdateIEs__value_PR_TransactionID
;
ie1
->
value
.
choice
.
TransactionID
=
F1AP_get_next_transaction_identifier
(
0
,
0
);
ie1
->
value
.
choice
.
TransactionID
=
upd
->
transaction_id
;
/* mandatory */
/* c2. Served_Cells_To_Add */
asn1cSequenceAdd
(
out
,
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie2
);
if
(
upd
->
num_cells_to_add
>
0
)
{
AssertFatal
(
false
,
"code for adding cells not tested
\n
"
);
asn1cSequenceAdd
(
out
->
protocolIEs
.
list
,
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie2
);
ie2
->
id
=
F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_List
;
ie2
->
criticality
=
F1AP_Criticality_reject
;
ie2
->
value
.
present
=
F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Add_List
;
for
(
int
j
=
0
;
j
<
1
;
j
++
)
{
//
asn1cSequenceAdd
(
ie2
->
value
.
choice
.
Served_Cells_To_Add_List
.
list
,
F1AP_Served_Cells_To_Add_ItemIEs_t
,
served_cells_to_add_item_ies
);
for
(
int
j
=
0
;
j
<
upd
->
num_cells_to_add
;
j
++
)
{
const
f1ap_served_cell_info_t
*
cell
=
&
upd
->
cell_to_add
[
j
].
info
;
const
f1ap_gnb_du_system_info_t
*
sys_info
=
upd
->
cell_to_add
[
j
].
sys_info
;
asn1cSequenceAdd
(
ie2
->
value
.
choice
.
Served_Cells_To_Add_List
.
list
,
F1AP_Served_Cells_To_Add_ItemIEs_t
,
served_cells_to_add_item_ies
);
served_cells_to_add_item_ies
->
id
=
F1AP_ProtocolIE_ID_id_Served_Cells_To_Add_Item
;
served_cells_to_add_item_ies
->
criticality
=
F1AP_Criticality_reject
;
served_cells_to_add_item_ies
->
value
.
present
=
F1AP_Served_Cells_To_Add_ItemIEs__value_PR_Served_Cells_To_Add_Item
;
F1AP_Served_Cells_To_Add_Item_t
*
served_cells_to_add_item
=
&
served_cells_to_add_item_ies
->
value
.
choice
.
Served_Cells_To_Add_Item
;
F1AP_Served_Cell_Information_t
*
served_cell_information
=&
served_cells_to_add_item
->
served_Cell_Information
;
/* - nRCGI */
addnRCGI
(
served_cell_information
->
nRCGI
,
&
f1ap_setup_req
->
cell
[
j
].
info
);
/* - nRPCI */
/* 2.1.1 serverd cell Information */
f1ap_served_cell_info_t
*
cell
=
&
f1ap_setup_req
->
cell
[
j
].
info
;
served_cell_information
->
nRPCI
=
cell
->
nr_pci
;
// int 0..1007
/* - fiveGS_TAC */
if
(
cell
->
tac
!=
NULL
)
{
uint32_t
tac
=
htonl
(
*
cell
->
tac
);
served_cell_information
->
fiveGS_TAC
=
calloc
(
1
,
sizeof
(
*
served_cell_information
->
fiveGS_TAC
));
OCTET_STRING_fromBuf
(
served_cell_information
->
fiveGS_TAC
,
((
char
*
)
&
tac
)
+
1
,
3
);
}
/* - Configured_EPS_TAC */
if
(
1
)
{
served_cell_information
->
configured_EPS_TAC
=
(
F1AP_Configured_EPS_TAC_t
*
)
calloc
(
1
,
sizeof
(
F1AP_Configured_EPS_TAC_t
));
OCTET_STRING_fromBuf
(
served_cell_information
->
configured_EPS_TAC
,
"2"
,
2
);
}
asn1cSequenceAdd
(
served_cell_information
->
servedPLMNs
.
list
,
F1AP_ServedPLMNs_Item_t
,
servedPLMN_item
);
MCC_MNC_TO_PLMNID
(
cell
->
plmn
.
mcc
,
cell
->
plmn
.
mnc
,
cell
->
plmn
.
mnc_digit_length
,
&
servedPLMN_item
->
pLMN_Identity
);
// // /* - CHOICE NR-MODE-Info */
F1AP_NR_Mode_Info_t
*
nR_Mode_Info
=&
served_cell_information
->
nR_Mode_Info
;
LOG_E
(
F1AP
,
"Here hardcoded values instead of values from configuration file
\n
"
);
if
(
cell
->
mode
==
F1AP_MODE_FDD
)
{
nR_Mode_Info
->
present
=
F1AP_NR_Mode_Info_PR_fDD
;
/* > FDD >> FDD Info */
asn1cCalloc
(
nR_Mode_Info
->
choice
.
fDD
,
fDD_Info
);
/* >>> UL NRFreqInfo */
fDD_Info
->
uL_NRFreqInfo
.
nRARFCN
=
999L
;
asn1cSequenceAdd
(
fDD_Info
->
uL_NRFreqInfo
.
freqBandListNr
.
list
,
F1AP_FreqBandNrItem_t
,
ul_freqBandNrItem
);
ul_freqBandNrItem
->
freqBandIndicatorNr
=
888L
;
asn1cSequenceAdd
(
ul_freqBandNrItem
->
supportedSULBandList
.
list
,
F1AP_SupportedSULFreqBandItem_t
,
ul_supportedSULFreqBandItem
);
ul_supportedSULFreqBandItem
->
freqBandIndicatorNr
=
777L
;
/* >>> DL NRFreqInfo */
fDD_Info
->
dL_NRFreqInfo
.
nRARFCN
=
666L
;
asn1cSequenceAdd
(
fDD_Info
->
dL_NRFreqInfo
.
freqBandListNr
.
list
,
F1AP_FreqBandNrItem_t
,
dl_freqBandNrItem
);
dl_freqBandNrItem
->
freqBandIndicatorNr
=
555L
;
asn1cSequenceAdd
(
dl_freqBandNrItem
->
supportedSULBandList
.
list
,
F1AP_SupportedSULFreqBandItem_t
,
dl_supportedSULFreqBandItem
);
dl_supportedSULFreqBandItem
->
freqBandIndicatorNr
=
444L
;
/* >>> UL Transmission Bandwidth */
fDD_Info
->
uL_Transmission_Bandwidth
.
nRSCS
=
F1AP_NRSCS_scs15
;
fDD_Info
->
uL_Transmission_Bandwidth
.
nRNRB
=
F1AP_NRNRB_nrb11
;
/* >>> DL Transmission Bandwidth */
fDD_Info
->
dL_Transmission_Bandwidth
.
nRSCS
=
F1AP_NRSCS_scs15
;
fDD_Info
->
dL_Transmission_Bandwidth
.
nRNRB
=
F1AP_NRNRB_nrb11
;
}
else
if
(
cell
->
mode
==
F1AP_MODE_TDD
)
{
// TDD
nR_Mode_Info
->
present
=
F1AP_NR_Mode_Info_PR_tDD
;
/* > TDD >> TDD Info */
asn1cCalloc
(
nR_Mode_Info
->
choice
.
tDD
,
tDD_Info
);
/* >>> ARFCN */
tDD_Info
->
nRFreqInfo
.
nRARFCN
=
999L
;
// Integer
asn1cSequenceAdd
(
tDD_Info
->
nRFreqInfo
.
freqBandListNr
.
list
,
F1AP_FreqBandNrItem_t
,
nr_freqBandNrItem
);
nr_freqBandNrItem
->
freqBandIndicatorNr
=
555L
;
asn1cSequenceAdd
(
nr_freqBandNrItem
->
supportedSULBandList
.
list
,
F1AP_SupportedSULFreqBandItem_t
,
nr_supportedSULFreqBandItem
);
nr_supportedSULFreqBandItem
->
freqBandIndicatorNr
=
444L
;
tDD_Info
->
transmission_Bandwidth
.
nRSCS
=
F1AP_NRSCS_scs15
;
tDD_Info
->
transmission_Bandwidth
.
nRNRB
=
F1AP_NRNRB_nrb11
;
}
else
{
AssertFatal
(
false
,
"illegal mode %d
\n
"
,
cell
->
mode
);
F1AP_Served_Cells_To_Add_Item_t
*
served_cells_to_add_item
=
&
served_cells_to_add_item_ies
->
value
.
choice
.
Served_Cells_To_Add_Item
;
served_cells_to_add_item
->
served_Cell_Information
=
encode_served_cell_info
(
cell
);
served_cells_to_add_item
->
gNB_DU_System_Information
=
encode_system_info
(
sys_info
);
}
/* - measurementTimingConfiguration */
char
*
measurementTimingConfiguration
=
"0"
;
// sept. 2018
OCTET_STRING_fromBuf
(
&
served_cell_information
->
measurementTimingConfiguration
,
measurementTimingConfiguration
,
strlen
(
measurementTimingConfiguration
));
/* 2.1.2 gNB-DU System Information */
asn1cCalloc
(
served_cells_to_add_item
->
gNB_DU_System_Information
,
gNB_DU_System_Information
);
OCTET_STRING_fromBuf
(
&
gNB_DU_System_Information
->
mIB_message
,
// sept. 2018
"1"
,
sizeof
(
"1"
));
OCTET_STRING_fromBuf
(
&
gNB_DU_System_Information
->
sIB1_message
,
// sept. 2018
"1"
,
sizeof
(
"1"
));
}
/* mandatory */
/* c3. Served_Cells_To_Modify */
asn1cSequenceAdd
(
out
,
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie3
);
if
(
upd
->
num_cells_to_modify
>
0
)
{
asn1cSequenceAdd
(
out
->
protocolIEs
.
list
,
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie3
);
ie3
->
id
=
F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_List
;
ie3
->
criticality
=
F1AP_Criticality_reject
;
ie3
->
value
.
present
=
F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Modify_List
;
for
(
int
i
=
0
;
i
<
1
;
i
++
)
{
//
f1ap_served_cell_info_t
*
cell
=
&
f1ap_setup_req
->
cell
[
i
].
info
;
asn1cSequenceAdd
(
ie3
->
value
.
choice
.
Served_Cells_To_Modify_List
.
list
,
F1AP_Served_Cells_To_Modify_ItemIEs_t
,
served_cells_to_modify_item_ies
);
for
(
int
i
=
0
;
i
<
upd
->
num_cells_to_modify
;
i
++
)
{
const
f1ap_served_cell_info_t
*
cell
=
&
upd
->
cell_to_modify
[
i
].
info
;
const
f1ap_gnb_du_system_info_t
*
sys_info
=
upd
->
cell_to_modify
[
i
].
sys_info
;
asn1cSequenceAdd
(
ie3
->
value
.
choice
.
Served_Cells_To_Modify_List
.
list
,
F1AP_Served_Cells_To_Modify_ItemIEs_t
,
served_cells_to_modify_item_ies
);
served_cells_to_modify_item_ies
->
id
=
F1AP_ProtocolIE_ID_id_Served_Cells_To_Modify_Item
;
served_cells_to_modify_item_ies
->
criticality
=
F1AP_Criticality_reject
;
served_cells_to_modify_item_ies
->
value
.
present
=
F1AP_Served_Cells_To_Modify_ItemIEs__value_PR_Served_Cells_To_Modify_Item
;
F1AP_Served_Cells_To_Modify_Item_t
*
served_cells_to_modify_item
=&
served_cells_to_modify_item_ies
->
value
.
choice
.
Served_Cells_To_Modify_Item
;
/* 3.1 oldNRCGI */
//addnRGCI(served_cells_to_modify_item->oldNRCGI, f1ap_setup_req->cell[i]);
/* 3.2.1 serverd cell Information */
F1AP_Served_Cell_Information_t
*
served_cell_information
=
&
served_cells_to_modify_item
->
served_Cell_Information
;
/* - nRCGI */
//addnRGCI(served_cell_information->nRCGI,f1ap_setup_req->cell[i]);
/* - nRPCI */
served_cell_information
->
nRPCI
=
cell
->
nr_pci
;
// int 0..1007
/* - fiveGS_TAC */
asn1cCalloc
(
served_cell_information
->
fiveGS_TAC
,
tac
);
OCTET_STRING_fromBuf
(
tac
,
(
const
char
*
)
&
cell
->
tac
,
3
);
F1AP_Served_Cells_To_Modify_Item_t
*
served_cells_to_modify_item
=
&
served_cells_to_modify_item_ies
->
value
.
choice
.
Served_Cells_To_Modify_Item
;
/* - Configured_EPS_TAC */
if
(
1
)
{
asn1cCalloc
(
served_cell_information
->
configured_EPS_TAC
,
tmp2
);
OCTET_STRING_fromBuf
(
tmp2
,
"2"
,
2
);
}
asn1cSequenceAdd
(
served_cell_information
->
servedPLMNs
.
list
,
F1AP_ServedPLMNs_Item_t
,
servedPLMN_item
);
MCC_MNC_TO_PLMNID
(
cell
->
plmn
.
mcc
,
cell
->
plmn
.
mnc
,
cell
->
plmn
.
mnc_digit_length
,
&
servedPLMN_item
->
pLMN_Identity
);
// // /* - CHOICE NR-MODE-Info */
F1AP_NR_Mode_Info_t
*
nR_Mode_Info
=
&
served_cell_information
->
nR_Mode_Info
;
F1AP_NRCGI_t
*
oldNRCGI
=
&
served_cells_to_modify_item
->
oldNRCGI
;
const
f1ap_plmn_t
*
old_plmn
=
&
upd
->
cell_to_modify
[
i
].
old_plmn
;
MCC_MNC_TO_PLMNID
(
old_plmn
->
mcc
,
old_plmn
->
mnc
,
old_plmn
->
mnc_digit_length
,
&
oldNRCGI
->
pLMN_Identity
);
NR_CELL_ID_TO_BIT_STRING
(
upd
->
cell_to_modify
[
i
].
old_nr_cellid
,
&
oldNRCGI
->
nRCellIdentity
);
if
(
cell
->
mode
==
F1AP_MODE_FDD
)
{
nR_Mode_Info
->
present
=
F1AP_NR_Mode_Info_PR_fDD
;
/* > FDD >> FDD Info */
asn1cCalloc
(
nR_Mode_Info
->
choice
.
fDD
,
fDD_Info
);
/* >>> UL NRFreqInfo */
fDD_Info
->
uL_NRFreqInfo
.
nRARFCN
=
999L
;
asn1cSequenceAdd
(
fDD_Info
->
uL_NRFreqInfo
.
freqBandListNr
.
list
,
F1AP_FreqBandNrItem_t
,
ul_freqBandNrItem
);
ul_freqBandNrItem
->
freqBandIndicatorNr
=
888L
;
asn1cSequenceAdd
(
ul_freqBandNrItem
->
supportedSULBandList
.
list
,
F1AP_SupportedSULFreqBandItem_t
,
ul_supportedSULFreqBandItem
);
ul_supportedSULFreqBandItem
->
freqBandIndicatorNr
=
777L
;
/* >>> DL NRFreqInfo */
fDD_Info
->
dL_NRFreqInfo
.
nRARFCN
=
666L
;
asn1cSequenceAdd
(
dl_freqBandNrItem
->
supportedSULBandList
.
list
,
F1AP_FreqBandNrItem_t
,
dl_freqBandNrItem
);
dl_freqBandNrItem
->
freqBandIndicatorNr
=
555L
;
F1AP_SupportedSULFreqBandItem_t
dl_supportedSULFreqBandItem
;
memset
((
void
*
)
&
dl_supportedSULFreqBandItem
,
0
,
sizeof
(
F1AP_SupportedSULFreqBandItem_t
));
dl_supportedSULFreqBandItem
.
freqBandIndicatorNr
=
444L
;
/* >>> UL Transmission Bandwidth */
fDD_Info
->
uL_Transmission_Bandwidth
.
nRSCS
=
F1AP_NRSCS_scs15
;
fDD_Info
->
uL_Transmission_Bandwidth
.
nRNRB
=
F1AP_NRNRB_nrb11
;
/* >>> DL Transmission Bandwidth */
fDD_Info
->
dL_Transmission_Bandwidth
.
nRSCS
=
F1AP_NRSCS_scs15
;
fDD_Info
->
dL_Transmission_Bandwidth
.
nRNRB
=
F1AP_NRNRB_nrb11
;
}
else
if
(
cell
->
mode
==
F1AP_MODE_TDD
)
{
// TDD
nR_Mode_Info
->
present
=
F1AP_NR_Mode_Info_PR_tDD
;
/* > TDD >> TDD Info */
asn1cCalloc
(
nR_Mode_Info
->
choice
.
tDD
,
tDD_Info
);
/* >>> ARFCN */
tDD_Info
->
nRFreqInfo
.
nRARFCN
=
999L
;
// Integer
asn1cSequenceAdd
(
tDD_Info
->
nRFreqInfo
.
freqBandListNr
.
list
,
F1AP_FreqBandNrItem_t
,
nr_freqBandNrItem
);
nr_freqBandNrItem
->
freqBandIndicatorNr
=
555L
;
asn1cSequenceAdd
(
nr_freqBandNrItem
->
supportedSULBandList
.
list
,
F1AP_SupportedSULFreqBandItem_t
,
nr_supportedSULFreqBandItem
);
nr_supportedSULFreqBandItem
->
freqBandIndicatorNr
=
444L
;
tDD_Info
->
transmission_Bandwidth
.
nRSCS
=
F1AP_NRSCS_scs15
;
tDD_Info
->
transmission_Bandwidth
.
nRNRB
=
F1AP_NRNRB_nrb11
;
}
else
{
AssertFatal
(
false
,
"unknown mode %d
\n
"
,
cell
->
mode
);
served_cells_to_modify_item
->
served_Cell_Information
=
encode_served_cell_info
(
cell
);
served_cells_to_modify_item
->
gNB_DU_System_Information
=
encode_system_info
(
sys_info
);
}
/* - measurementTimingConfiguration */
char
*
measurementTimingConfiguration
=
"0"
;
// sept. 2018
OCTET_STRING_fromBuf
(
&
served_cell_information
->
measurementTimingConfiguration
,
measurementTimingConfiguration
,
strlen
(
measurementTimingConfiguration
));
/* 3.2.2 gNB-DU System Information */
asn1cCalloc
(
served_cells_to_modify_item
->
gNB_DU_System_Information
,
gNB_DU_System_Information
);
OCTET_STRING_fromBuf
(
&
gNB_DU_System_Information
->
mIB_message
,
// sept. 2018
"1"
,
sizeof
(
"1"
));
OCTET_STRING_fromBuf
(
&
gNB_DU_System_Information
->
sIB1_message
,
// sept. 2018
"1"
,
sizeof
(
"1"
));
}
/* mandatory */
/* c4. Served_Cells_To_Delete */
asn1cSequenceAdd
(
out
,
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie4
);
if
(
upd
->
num_cells_to_delete
>
0
)
{
asn1cSequenceAdd
(
out
->
protocolIEs
.
list
,
F1AP_GNBDUConfigurationUpdateIEs_t
,
ie4
);
ie4
->
id
=
F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_List
;
ie4
->
criticality
=
F1AP_Criticality_reject
;
ie4
->
value
.
present
=
F1AP_GNBDUConfigurationUpdateIEs__value_PR_Served_Cells_To_Delete_List
;
for
(
int
i
=
0
;
i
<
1
;
i
++
)
{
//
asn1cSequenceAdd
(
ie4
->
value
.
choice
.
Served_Cells_To_Delete_List
.
list
,
F1AP_Served_Cells_To_Delete_ItemIEs_t
,
served_cells_to_delete_item_ies
);
AssertFatal
(
upd
->
num_cells_to_delete
==
0
,
"code for deleting cells not tested
\n
"
);
for
(
int
i
=
0
;
i
<
upd
->
num_cells_to_delete
;
i
++
)
{
asn1cSequenceAdd
(
ie4
->
value
.
choice
.
Served_Cells_To_Delete_List
.
list
,
F1AP_Served_Cells_To_Delete_ItemIEs_t
,
served_cells_to_delete_item_ies
);
served_cells_to_delete_item_ies
->
id
=
F1AP_ProtocolIE_ID_id_Served_Cells_To_Delete_Item
;
served_cells_to_delete_item_ies
->
criticality
=
F1AP_Criticality_reject
;
served_cells_to_delete_item_ies
->
value
.
present
=
F1AP_Served_Cells_To_Delete_ItemIEs__value_PR_Served_Cells_To_Delete_Item
;
F1AP_Served_Cells_To_Delete_Item_t
*
served_cells_to_delete_item
=&
served_cells_to_delete_item_ies
->
value
.
choice
.
Served_Cells_To_Delete_Item
;
/* 3.1 oldNRCGI */
addnRCGI
(
served_cells_to_delete_item
->
oldNRCGI
,
&
f1ap_setup_req
->
cell
[
i
].
info
);
F1AP_Served_Cells_To_Delete_Item_t
*
served_cells_to_delete_item
=
&
served_cells_to_delete_item_ies
->
value
.
choice
.
Served_Cells_To_Delete_Item
;
addnRCGI
(
served_cells_to_delete_item
->
oldNRCGI
,
&
upd
->
cell_to_delete
[
i
]);
}
}
AssertFatal
(
upd
->
gNB_DU_ID
==
0
,
"encoding of gNB-DU Id not handled yet
\n
"
);
if
(
f1ap_encode_pdu
(
&
pdu
,
&
buffer
,
&
len
)
<
0
)
{
LOG_E
(
F1AP
,
"Failed to encode F1 gNB-DU CONFIGURATION UPDATE
\n
"
);
return
-
1
;
}
ASN_STRUCT_RESET
(
asn_DEF_F1AP_F1AP_PDU
,
&
pdu
);
f1ap_itti_send_sctp_data_req
(
assoc_id
,
buffer
,
len
);
return
0
;
}
...
...
openair2/F1AP/f1ap_du_interface_management.h
View file @
65d494fb
...
...
@@ -50,7 +50,7 @@ int DU_handle_ERROR_INDICATION(instance_t instance, sctp_assoc_t assoc_id, uint3
/*
* F1 Setup
*/
int
DU_send_F1_SETUP_REQUEST
(
sctp_assoc_t
assoc_id
,
f1ap_setup_req_t
*
setup_req
);
int
DU_send_F1_SETUP_REQUEST
(
sctp_assoc_t
assoc_id
,
const
f1ap_setup_req_t
*
setup_req
);
int
DU_handle_F1_SETUP_RESPONSE
(
instance_t
instance
,
sctp_assoc_t
assoc_id
,
uint32_t
stream
,
F1AP_F1AP_PDU_t
*
pdu
);
...
...
@@ -59,8 +59,7 @@ int DU_handle_F1_SETUP_FAILURE(instance_t instance, sctp_assoc_t assoc_id, uint3
/*
* gNB-DU Configuration Update
*/
int
DU_send_gNB_DU_CONFIGURATION_UPDATE
(
sctp_assoc_t
assoc_id
,
f1ap_setup_req_t
*
f1ap_du_data
);
int
DU_send_gNB_DU_CONFIGURATION_UPDATE
(
sctp_assoc_t
assoc_id
,
const
f1ap_gnb_du_configuration_update_t
*
upd
);
int
DU_handle_gNB_DU_CONFIGURATION_FAILURE
(
instance_t
instance
,
sctp_assoc_t
assoc_id
,
uint32_t
stream
,
F1AP_F1AP_PDU_t
*
pdu
);
...
...
openair2/F1AP/f1ap_du_task.c
View file @
65d494fb
...
...
@@ -186,6 +186,10 @@ void *F1AP_DU_task(void *arg) {
DU_send_UE_CONTEXT_MODIFICATION_REQUIRED
(
assoc_id
,
&
F1AP_UE_CONTEXT_MODIFICATION_REQUIRED
(
msg
));
break
;
case
F1AP_GNB_DU_CONFIGURATION_UPDATE
:
DU_send_gNB_DU_CONFIGURATION_UPDATE
(
assoc_id
,
&
F1AP_GNB_DU_CONFIGURATION_UPDATE
(
msg
));
break
;
case
TERMINATE_MESSAGE
:
LOG_W
(
F1AP
,
" *** Exiting F1AP thread
\n
"
);
itti_exit_task
();
...
...
openair2/F1AP/f1ap_handlers.c
View file @
65d494fb
...
...
@@ -45,7 +45,7 @@ static const f1ap_message_processing_t f1ap_messages_processing[][3] = {
{
0
,
0
,
0
},
/* Reset */
{
CU_handle_F1_SETUP_REQUEST
,
DU_handle_F1_SETUP_RESPONSE
,
DU_handle_F1_SETUP_FAILURE
},
/* F1Setup */
{
0
,
0
,
0
},
/* ErrorIndication */
{
0
,
0
,
0
},
/* gNBDUConfigurationUpdate */
{
CU_handle_gNB_DU_CONFIGURATION_UPDATE
,
0
,
0
},
/* gNBDUConfigurationUpdate */
{
DU_handle_gNB_CU_CONFIGURATION_UPDATE
,
CU_handle_gNB_CU_CONFIGURATION_UPDATE_ACKNOWLEDGE
,
CU_handle_gNB_CU_CONFIGURATION_UPDATE_FAILURE
},
/* gNBCUConfigurationUpdate */
...
...
openair2/GNB_APP/gnb_config.c
View file @
65d494fb
...
...
@@ -82,6 +82,7 @@
#include "NR_RateMatchPatternLTE-CRS.h"
#include "NR_SearchSpace.h"
#include "NR_ControlResourceSet.h"
#include "NR_MeasurementTimingConfiguration.h"
#include "NR_EUTRA-MBSFN-SubframeConfig.h"
#include "uper_decoder.h"
#include "uper_encoder.h"
...
...
@@ -1095,6 +1096,8 @@ static int read_du_cell_info(configmodule_interface_t *cfg,
PLMNParams
[
I
].
chkPptr
=
&
(
config_check_PLMNParams
[
I
]);
paramlist_def_t
PLMNParamList
=
{
GNB_CONFIG_STRING_PLMN_LIST
,
NULL
,
0
};
config_getlist
(
cfg
,
&
PLMNParamList
,
PLMNParams
,
sizeof
(
PLMNParams
)
/
sizeof
(
paramdef_t
),
aprefix
);
AssertFatal
(
PLMNParamList
.
numelt
>
0
,
"need to have a PLMN in PLMN section
\n
"
);
AssertFatal
(
PLMNParamList
.
numelt
==
1
,
"cannot have more than one PLMN
\n
"
);
// if fronthaul is F1, require gNB_DU_ID, else use gNB_ID
if
(
separate_du
)
{
...
...
@@ -1119,12 +1122,53 @@ static int read_du_cell_info(configmodule_interface_t *cfg,
info
->
plmn
.
mnc_digit_length
);
info
->
nr_cellid
=
(
uint64_t
)
*
(
GNBParamList
.
paramarray
[
0
][
GNB_NRCELLID_IDX
].
u64ptr
);
LOG_W
(
GNB_APP
,
"no slices transported via F1 Setup Request!
\n
"
);
info
->
num_ssi
=
0
;
paramdef_t
SNSSAIParams
[]
=
GNBSNSSAIPARAMS_DESC
;
paramlist_def_t
SNSSAIParamList
=
{
GNB_CONFIG_STRING_SNSSAI_LIST
,
NULL
,
0
};
checkedparam_t
config_check_SNSSAIParams
[]
=
SNSSAIPARAMS_CHECK
;
for
(
int
J
=
0
;
J
<
sizeofArray
(
SNSSAIParams
);
++
J
)
SNSSAIParams
[
J
].
chkPptr
=
&
(
config_check_SNSSAIParams
[
J
]);
char
snssaistr
[
MAX_OPTNAME_SIZE
*
2
+
8
];
sprintf
(
snssaistr
,
"%s.[0].%s.[0]"
,
GNB_CONFIG_STRING_GNB_LIST
,
GNB_CONFIG_STRING_PLMN_LIST
);
config_getlist
(
config_get_if
(),
&
SNSSAIParamList
,
SNSSAIParams
,
sizeofArray
(
SNSSAIParams
),
snssaistr
);
info
->
num_ssi
=
SNSSAIParamList
.
numelt
;
for
(
int
s
=
0
;
s
<
info
->
num_ssi
;
++
s
)
{
info
->
nssai
[
s
].
sst
=
*
SNSSAIParamList
.
paramarray
[
s
][
GNB_SLICE_SERVICE_TYPE_IDX
].
uptr
;
info
->
nssai
[
s
].
sd
=
*
SNSSAIParamList
.
paramarray
[
s
][
GNB_SLICE_DIFFERENTIATOR_IDX
].
uptr
;
AssertFatal
(
info
->
nssai
[
s
].
sd
<=
0xffffff
,
"SD cannot be bigger than 0xffffff, but is %d
\n
"
,
info
->
nssai
[
s
].
sd
);
}
return
1
;
}
static
f1ap_tdd_info_t
read_tdd_config
(
const
NR_ServingCellConfigCommon_t
*
scc
)
{
const
NR_FrequencyInfoDL_t
*
dl
=
scc
->
downlinkConfigCommon
->
frequencyInfoDL
;
f1ap_tdd_info_t
tdd
=
{
.
freqinfo
.
arfcn
=
dl
->
absoluteFrequencyPointA
,
.
freqinfo
.
band
=
*
dl
->
frequencyBandList
.
list
.
array
[
0
],
.
tbw
.
scs
=
dl
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
subcarrierSpacing
,
.
tbw
.
nrb
=
dl
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
carrierBandwidth
,
};
return
tdd
;
}
static
f1ap_fdd_info_t
read_fdd_config
(
const
NR_ServingCellConfigCommon_t
*
scc
)
{
const
NR_FrequencyInfoDL_t
*
dl
=
scc
->
downlinkConfigCommon
->
frequencyInfoDL
;
const
NR_FrequencyInfoUL_t
*
ul
=
scc
->
uplinkConfigCommon
->
frequencyInfoUL
;
f1ap_fdd_info_t
fdd
=
{
.
dl_freqinfo
.
arfcn
=
dl
->
absoluteFrequencyPointA
,
.
ul_freqinfo
.
arfcn
=
*
ul
->
absoluteFrequencyPointA
,
.
dl_tbw
.
scs
=
dl
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
subcarrierSpacing
,
.
ul_tbw
.
scs
=
ul
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
subcarrierSpacing
,
.
dl_tbw
.
nrb
=
dl
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
carrierBandwidth
,
.
ul_tbw
.
nrb
=
ul
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
carrierBandwidth
,
.
dl_freqinfo
.
band
=
*
dl
->
frequencyBandList
.
list
.
array
[
0
],
.
ul_freqinfo
.
band
=
*
ul
->
frequencyBandList
->
list
.
array
[
0
],
};
return
fdd
;
}
static
f1ap_setup_req_t
*
RC_read_F1Setup
(
uint64_t
id
,
const
char
*
name
,
const
f1ap_served_cell_info_t
*
info
,
...
...
@@ -1150,30 +1194,26 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
req
->
cell
[
0
].
info
.
nr_cellid
);
req
->
cell
[
0
].
info
.
nr_pci
=
*
scc
->
physCellId
;
struct
NR_FrequencyInfoDL
*
frequencyInfoDL
=
scc
->
downlinkConfigCommon
->
frequencyInfoDL
;
if
(
scc
->
tdd_UL_DL_ConfigurationCommon
)
{
LOG_I
(
GNB_APP
,
"ngran_DU: Configuring Cell %d for TDD
\n
"
,
0
);
req
->
cell
[
0
].
info
.
mode
=
F1AP_MODE_TDD
;
f1ap_tdd_info_t
*
tdd
=
&
req
->
cell
[
0
].
info
.
tdd
;
tdd
->
freqinfo
.
arfcn
=
frequencyInfoDL
->
absoluteFrequencyPointA
;
tdd
->
tbw
.
scs
=
frequencyInfoDL
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
subcarrierSpacing
;
tdd
->
tbw
.
nrb
=
frequencyInfoDL
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
carrierBandwidth
;
tdd
->
freqinfo
.
band
=
*
frequencyInfoDL
->
frequencyBandList
.
list
.
array
[
0
];
req
->
cell
[
0
].
info
.
tdd
=
read_tdd_config
(
scc
);
}
else
{
LOG_I
(
GNB_APP
,
"ngran_DU: Configuring Cell %d for FDD
\n
"
,
0
);
req
->
cell
[
0
].
info
.
mode
=
F1AP_MODE_FDD
;
f1ap_fdd_info_t
*
fdd
=
&
req
->
cell
[
0
].
info
.
fdd
;
fdd
->
dl_freqinfo
.
arfcn
=
frequencyInfoDL
->
absoluteFrequencyPointA
;
fdd
->
ul_freqinfo
.
arfcn
=
*
scc
->
uplinkConfigCommon
->
frequencyInfoUL
->
absoluteFrequencyPointA
;
fdd
->
dl_tbw
.
scs
=
frequencyInfoDL
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
subcarrierSpacing
;
fdd
->
ul_tbw
.
scs
=
scc
->
uplinkConfigCommon
->
frequencyInfoUL
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
subcarrierSpacing
;
fdd
->
dl_tbw
.
nrb
=
frequencyInfoDL
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
carrierBandwidth
;
fdd
->
ul_tbw
.
nrb
=
scc
->
uplinkConfigCommon
->
frequencyInfoUL
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
carrierBandwidth
;
fdd
->
dl_freqinfo
.
band
=
*
frequencyInfoDL
->
frequencyBandList
.
list
.
array
[
0
];
fdd
->
ul_freqinfo
.
band
=
*
scc
->
uplinkConfigCommon
->
frequencyInfoUL
->
frequencyBandList
->
list
.
array
[
0
];
req
->
cell
[
0
].
info
.
fdd
=
read_fdd_config
(
scc
);
}
req
->
cell
[
0
].
info
.
measurement_timing_information
=
"0"
;
NR_MeasurementTimingConfiguration_t
*
mtc
=
get_new_MeasurementTimingConfiguration
(
scc
);
uint8_t
buf
[
1024
];
int
len
=
encode_MeasurementTimingConfiguration
(
mtc
,
buf
,
sizeof
(
buf
));
DevAssert
(
len
<=
sizeof
(
buf
));
free_MeasurementTimingConfiguration
(
mtc
);
uint8_t
*
mtc_buf
=
calloc
(
len
,
sizeof
(
*
mtc_buf
));
AssertFatal
(
mtc_buf
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
mtc_buf
,
buf
,
len
);
req
->
cell
[
0
].
info
.
measurement_timing_config
=
mtc_buf
;
req
->
cell
[
0
].
info
.
measurement_timing_config_len
=
len
;
if
(
get_softmodem_params
()
->
sa
)
{
// in NSA we don't transmit SIB1, so cannot fill DU system information
...
...
@@ -1186,7 +1226,8 @@ static f1ap_setup_req_t *RC_read_F1Setup(uint64_t id,
sys_info
->
mib
=
calloc
(
buf_len
,
sizeof
(
*
sys_info
->
mib
));
DevAssert
(
sys_info
->
mib
!=
NULL
);
DevAssert
(
mib
!=
NULL
);
sys_info
->
mib_length
=
encode_MIB_NR
(
mib
,
0
,
sys_info
->
mib
,
buf_len
);
// encode only the mib message itself
sys_info
->
mib_length
=
encode_MIB_NR_setup
(
mib
->
message
.
choice
.
mib
,
0
,
sys_info
->
mib
,
buf_len
);
DevAssert
(
sys_info
->
mib_length
==
buf_len
);
DevAssert
(
sib1
!=
NULL
);
...
...
openair2/LAYER2/NR_MAC_gNB/config.c
View file @
65d494fb
...
...
@@ -540,13 +540,6 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
get_ssb_subcarrier_offset
(
*
scc
->
downlinkConfigCommon
->
frequencyInfoDL
->
absoluteFrequencySSB
,
scc
->
downlinkConfigCommon
->
frequencyInfoDL
->
absoluteFrequencyPointA
,
*
scc
->
ssbSubcarrierSpacing
);
AssertFatal
(
cfg
->
ssb_table
.
ssb_subcarrier_offset
.
value
<
16
,
"cannot handle ssb_subcarrier_offset %d resulting from Point A %ld SSB %ld: please increase dl_absoluteFrequencyPointA "
"in the config by 16
\n
"
,
cfg
->
ssb_table
.
ssb_subcarrier_offset
.
value
,
scc
->
downlinkConfigCommon
->
frequencyInfoDL
->
absoluteFrequencyPointA
,
*
scc
->
downlinkConfigCommon
->
frequencyInfoDL
->
absoluteFrequencySSB
);
cfg
->
ssb_table
.
ssb_subcarrier_offset
.
tl
.
tag
=
NFAPI_NR_CONFIG_SSB_SUBCARRIER_OFFSET_TAG
;
cfg
->
num_tlv
++
;
...
...
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
View file @
65d494fb
...
...
@@ -144,6 +144,12 @@ void f1_setup_failure(const f1ap_setup_failure_t *failure)
exit
(
1
);
}
void
gnb_du_configuration_update_acknowledge
(
const
f1ap_gnb_du_configuration_update_acknowledge_t
*
ack
)
{
(
void
)
ack
;
LOG_I
(
MAC
,
"received gNB-DU configuration update acknowledge
\n
"
);
}
static
NR_RLC_BearerConfig_t
*
get_bearerconfig_from_srb
(
const
f1ap_srb_to_be_setup_t
*
srb
)
{
long
priority
=
srb
->
srb_id
;
// high priority for SRB
...
...
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h
View file @
65d494fb
...
...
@@ -28,6 +28,7 @@
void
f1_setup_response
(
const
f1ap_setup_resp_t
*
resp
);
void
f1_setup_failure
(
const
f1ap_setup_failure_t
*
failure
);
void
gnb_du_configuration_update_acknowledge
(
const
f1ap_gnb_du_configuration_update_acknowledge_t
*
ack
);
NR_CellGroupConfig_t
*
clone_CellGroupConfig
(
const
NR_CellGroupConfig_t
*
orig
);
void
ue_context_setup_request
(
const
f1ap_ue_context_setup_t
*
req
);
void
ue_context_modification_request
(
const
f1ap_ue_context_modif_req_t
*
req
);
...
...
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul.h
View file @
65d494fb
...
...
@@ -26,6 +26,7 @@
#include "f1ap_messages_types.h"
typedef
void
(
*
f1_setup_request_func_t
)(
const
f1ap_setup_req_t
*
req
);
typedef
void
(
*
gnb_du_configuration_update_t
)(
const
f1ap_gnb_du_configuration_update_t
*
upd
);
typedef
void
(
*
ue_context_setup_response_func_t
)(
const
f1ap_ue_context_setup_t
*
req
,
const
f1ap_ue_context_setup_t
*
resp
);
typedef
void
(
*
ue_context_modification_response_func_t
)(
const
f1ap_ue_context_modif_req_t
*
req
,
...
...
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c
View file @
65d494fb
...
...
@@ -39,8 +39,14 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req)
AssertFatal
(
f1ap_msg
->
cell
[
n
].
info
.
tac
!=
NULL
,
"out of memory
\n
"
);
*
f1ap_msg
->
cell
[
n
].
info
.
tac
=
*
req
->
cell
[
n
].
info
.
tac
;
}
if
(
req
->
cell
[
n
].
info
.
measurement_timing_information
)
f1ap_msg
->
cell
[
n
].
info
.
measurement_timing_information
=
strdup
(
req
->
cell
[
n
].
info
.
measurement_timing_information
);
if
(
req
->
cell
[
n
].
info
.
measurement_timing_config_len
>
0
)
{
f1ap_msg
->
cell
[
n
].
info
.
measurement_timing_config
=
calloc
(
req
->
cell
[
n
].
info
.
measurement_timing_config_len
,
sizeof
(
uint8_t
));
AssertFatal
(
f1ap_msg
->
cell
[
n
].
info
.
measurement_timing_config
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
f1ap_msg
->
cell
[
n
].
info
.
measurement_timing_config
,
req
->
cell
[
n
].
info
.
measurement_timing_config
,
req
->
cell
[
n
].
info
.
measurement_timing_config_len
);
f1ap_msg
->
cell
[
n
].
info
.
measurement_timing_config_len
=
req
->
cell
[
n
].
info
.
measurement_timing_config_len
;
}
if
(
req
->
cell
[
n
].
sys_info
)
{
f1ap_gnb_du_system_info_t
*
orig_sys_info
=
req
->
cell
[
n
].
sys_info
;
...
...
@@ -66,6 +72,58 @@ static void f1_setup_request_direct(const f1ap_setup_req_t *req)
itti_send_msg_to_task
(
TASK_RRC_GNB
,
0
,
msg
);
}
static
void
gnb_du_configuration_update_direct
(
const
f1ap_gnb_du_configuration_update_t
*
upd
)
{
MessageDef
*
msg
=
itti_alloc_new_message
(
TASK_MAC_GNB
,
0
,
F1AP_GNB_DU_CONFIGURATION_UPDATE
);
msg
->
ittiMsgHeader
.
originInstance
=
-
1
;
// means monolithic
f1ap_gnb_du_configuration_update_t
*
f1ap_msg
=
&
F1AP_GNB_DU_CONFIGURATION_UPDATE
(
msg
);
DevAssert
(
upd
->
gNB_DU_ID
==
NULL
);
f1ap_msg
->
transaction_id
=
upd
->
transaction_id
;
DevAssert
(
upd
->
num_cells_to_add
==
0
);
DevAssert
(
upd
->
num_cells_to_delete
==
0
);
f1ap_msg
->
num_cells_to_modify
=
upd
->
num_cells_to_modify
;
for
(
int
n
=
0
;
n
<
upd
->
num_cells_to_modify
;
++
n
)
{
f1ap_msg
->
cell_to_modify
[
n
].
old_nr_cellid
=
upd
->
cell_to_modify
[
n
].
old_nr_cellid
;
f1ap_msg
->
cell_to_modify
[
n
].
info
=
upd
->
cell_to_modify
[
n
].
info
;
// copy most fields
if
(
upd
->
cell_to_modify
[
n
].
info
.
tac
)
{
f1ap_msg
->
cell_to_modify
[
n
].
info
.
tac
=
malloc
(
sizeof
(
*
f1ap_msg
->
cell_to_modify
[
n
].
info
.
tac
));
AssertFatal
(
f1ap_msg
->
cell_to_modify
[
n
].
info
.
tac
!=
NULL
,
"out of memory
\n
"
);
*
f1ap_msg
->
cell_to_modify
[
n
].
info
.
tac
=
*
upd
->
cell_to_modify
[
n
].
info
.
tac
;
}
if
(
upd
->
cell_to_modify
[
n
].
info
.
measurement_timing_config_len
>
0
)
{
f1ap_msg
->
cell_to_modify
[
n
].
info
.
measurement_timing_config
=
calloc
(
upd
->
cell_to_modify
[
n
].
info
.
measurement_timing_config_len
,
sizeof
(
uint8_t
));
AssertFatal
(
f1ap_msg
->
cell_to_modify
[
n
].
info
.
measurement_timing_config
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
f1ap_msg
->
cell_to_modify
[
n
].
info
.
measurement_timing_config
,
upd
->
cell_to_modify
[
n
].
info
.
measurement_timing_config
,
upd
->
cell_to_modify
[
n
].
info
.
measurement_timing_config_len
);
f1ap_msg
->
cell_to_modify
[
n
].
info
.
measurement_timing_config_len
=
upd
->
cell_to_modify
[
n
].
info
.
measurement_timing_config_len
;
}
if
(
upd
->
cell_to_modify
[
n
].
sys_info
)
{
f1ap_gnb_du_system_info_t
*
orig_sys_info
=
upd
->
cell_to_modify
[
n
].
sys_info
;
f1ap_gnb_du_system_info_t
*
copy_sys_info
=
calloc
(
1
,
sizeof
(
*
copy_sys_info
));
AssertFatal
(
copy_sys_info
!=
NULL
,
"out of memory
\n
"
);
f1ap_msg
->
cell_to_modify
[
n
].
sys_info
=
copy_sys_info
;
copy_sys_info
->
mib
=
calloc
(
orig_sys_info
->
mib_length
,
sizeof
(
uint8_t
));
AssertFatal
(
copy_sys_info
->
mib
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
copy_sys_info
->
mib
,
orig_sys_info
->
mib
,
orig_sys_info
->
mib_length
);
copy_sys_info
->
mib_length
=
orig_sys_info
->
mib_length
;
if
(
orig_sys_info
->
sib1_length
>
0
)
{
copy_sys_info
->
sib1
=
calloc
(
orig_sys_info
->
sib1_length
,
sizeof
(
uint8_t
));
AssertFatal
(
copy_sys_info
->
sib1
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
copy_sys_info
->
sib1
,
orig_sys_info
->
sib1
,
orig_sys_info
->
sib1_length
);
copy_sys_info
->
sib1_length
=
orig_sys_info
->
sib1_length
;
}
}
}
itti_send_msg_to_task
(
TASK_RRC_GNB
,
0
,
msg
);
}
static
void
ue_context_setup_response_direct
(
const
f1ap_ue_context_setup_t
*
req
,
const
f1ap_ue_context_setup_t
*
resp
)
{
DevAssert
(
req
->
drbs_to_be_setup_length
==
resp
->
drbs_to_be_setup_length
);
...
...
@@ -227,6 +285,7 @@ static void initial_ul_rrc_message_transfer_direct(module_id_t module_id, const
void
mac_rrc_ul_direct_init
(
struct
nr_mac_rrc_ul_if_s
*
mac_rrc
)
{
mac_rrc
->
f1_setup_request
=
f1_setup_request_direct
;
mac_rrc
->
gnb_du_configuration_update
=
gnb_du_configuration_update_direct
;
mac_rrc
->
ue_context_setup_response
=
ue_context_setup_response_direct
;
mac_rrc
->
ue_context_modification_response
=
ue_context_modification_response_direct
;
mac_rrc
->
ue_context_modification_required
=
ue_context_modification_required_direct
;
...
...
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c
View file @
65d494fb
...
...
@@ -69,8 +69,14 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
AssertFatal
(
f1ap_setup
->
cell
[
n
].
info
.
tac
!=
NULL
,
"out of memory
\n
"
);
*
f1ap_setup
->
cell
[
n
].
info
.
tac
=
*
req
->
cell
[
n
].
info
.
tac
;
}
if
(
req
->
cell
[
n
].
info
.
measurement_timing_information
)
f1ap_setup
->
cell
[
n
].
info
.
measurement_timing_information
=
strdup
(
req
->
cell
[
n
].
info
.
measurement_timing_information
);
if
(
req
->
cell
[
n
].
info
.
measurement_timing_config_len
>
0
)
{
f1ap_setup
->
cell
[
n
].
info
.
measurement_timing_config
=
calloc
(
req
->
cell
[
n
].
info
.
measurement_timing_config_len
,
sizeof
(
uint8_t
));
AssertFatal
(
f1ap_setup
->
cell
[
n
].
info
.
measurement_timing_config
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
f1ap_setup
->
cell
[
n
].
info
.
measurement_timing_config
,
req
->
cell
[
n
].
info
.
measurement_timing_config
,
req
->
cell
[
n
].
info
.
measurement_timing_config_len
);
f1ap_setup
->
cell
[
n
].
info
.
measurement_timing_config_len
=
req
->
cell
[
n
].
info
.
measurement_timing_config_len
;
}
if
(
req
->
cell
[
n
].
sys_info
)
{
f1ap_gnb_du_system_info_t
*
orig_sys_info
=
req
->
cell
[
n
].
sys_info
;
...
...
@@ -98,6 +104,39 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req)
itti_send_msg_to_task
(
TASK_DU_F1
,
0
,
msg
);
}
static
void
gnb_du_configuration_update_f1ap
(
const
f1ap_gnb_du_configuration_update_t
*
upd
)
{
MessageDef
*
msg
=
itti_alloc_new_message
(
TASK_MAC_GNB
,
0
,
F1AP_GNB_DU_CONFIGURATION_UPDATE
);
f1ap_gnb_du_configuration_update_t
*
f1_upd
=
&
F1AP_GNB_DU_CONFIGURATION_UPDATE
(
msg
);
f1_upd
->
transaction_id
=
upd
->
transaction_id
;
AssertFatal
(
upd
->
num_cells_to_add
==
0
,
"gNB-DU config update: cells to add not supported
\n
"
);
f1_upd
->
num_cells_to_modify
=
upd
->
num_cells_to_modify
;
for
(
int
n
=
0
;
n
<
upd
->
num_cells_to_modify
;
++
n
)
{
f1_upd
->
cell_to_modify
[
n
].
old_plmn
=
upd
->
cell_to_modify
[
n
].
old_plmn
;
f1_upd
->
cell_to_modify
[
n
].
old_nr_cellid
=
upd
->
cell_to_modify
[
n
].
old_nr_cellid
;
f1_upd
->
cell_to_modify
[
n
].
info
=
upd
->
cell_to_modify
[
n
].
info
;
if
(
upd
->
cell_to_modify
[
n
].
sys_info
)
{
f1ap_gnb_du_system_info_t
*
orig_sys_info
=
upd
->
cell_to_modify
[
n
].
sys_info
;
f1ap_gnb_du_system_info_t
*
copy_sys_info
=
calloc
(
1
,
sizeof
(
*
copy_sys_info
));
f1_upd
->
cell_to_modify
[
n
].
sys_info
=
copy_sys_info
;
copy_sys_info
->
mib
=
calloc
(
orig_sys_info
->
mib_length
,
sizeof
(
uint8_t
));
AssertFatal
(
copy_sys_info
->
mib
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
copy_sys_info
->
mib
,
orig_sys_info
->
mib
,
orig_sys_info
->
mib_length
);
copy_sys_info
->
mib_length
=
orig_sys_info
->
mib_length
;
if
(
orig_sys_info
->
sib1_length
>
0
)
{
copy_sys_info
->
sib1
=
calloc
(
orig_sys_info
->
sib1_length
,
sizeof
(
uint8_t
));
AssertFatal
(
copy_sys_info
->
sib1
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
copy_sys_info
->
sib1
,
orig_sys_info
->
sib1
,
orig_sys_info
->
sib1_length
);
copy_sys_info
->
sib1_length
=
orig_sys_info
->
sib1_length
;
}
}
}
AssertFatal
(
upd
->
num_cells_to_delete
==
0
,
"gNB-DU config update: cells to add not supported
\n
"
);
itti_send_msg_to_task
(
TASK_DU_F1
,
0
,
msg
);
}
static
void
ue_context_setup_response_f1ap
(
const
f1ap_ue_context_setup_t
*
req
,
const
f1ap_ue_context_setup_t
*
resp
)
{
DevAssert
(
req
->
drbs_to_be_setup_length
==
resp
->
drbs_to_be_setup_length
);
...
...
@@ -237,6 +276,7 @@ static void initial_ul_rrc_message_transfer_f1ap(module_id_t module_id, const f1
void
mac_rrc_ul_f1ap_init
(
struct
nr_mac_rrc_ul_if_s
*
mac_rrc
)
{
mac_rrc
->
f1_setup_request
=
f1_setup_request_f1ap
;
mac_rrc
->
gnb_du_configuration_update
=
gnb_du_configuration_update_f1ap
;
mac_rrc
->
ue_context_setup_response
=
ue_context_setup_response_f1ap
;
mac_rrc
->
ue_context_modification_response
=
ue_context_modification_response_f1ap
;
mac_rrc
->
ue_context_modification_required
=
ue_context_modification_required_f1ap
;
...
...
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
View file @
65d494fb
...
...
@@ -660,6 +660,7 @@ typedef struct NR_bler_options {
typedef
struct
nr_mac_rrc_ul_if_s
{
f1_setup_request_func_t
f1_setup_request
;
gnb_du_configuration_update_t
gnb_du_configuration_update
;
ue_context_setup_response_func_t
ue_context_setup_response
;
ue_context_modification_response_func_t
ue_context_modification_response
;
ue_context_modification_required_func_t
ue_context_modification_required
;
...
...
openair2/RRC/NR/MESSAGES/asn1_msg.c
View file @
65d494fb
...
...
@@ -1093,8 +1093,12 @@ int do_RRCReestablishmentComplete(uint8_t *buffer, size_t buffer_size, int64_t r
return
((
enc_rval
.
encoded
+
7
)
/
8
);
}
NR_MeasConfig_t
*
get_defaultMeasConfig
(
uint32_t
ssb_arfcn
,
int
band
,
int
scs
)
NR_MeasConfig_t
*
get_defaultMeasConfig
(
const
NR_MeasTiming_t
*
mt
,
int
band
,
int
scs
)
{
DevAssert
(
mt
!=
NULL
&&
mt
->
frequencyAndTiming
!=
NULL
);
const
struct
NR_MeasTiming__frequencyAndTiming
*
ft
=
mt
->
frequencyAndTiming
;
const
NR_SSB_MTC_t
*
ssb_mtc
=
&
ft
->
ssb_MeasurementTimingConfiguration
;
NR_MeasConfig_t
*
mc
=
calloc
(
1
,
sizeof
(
*
mc
));
mc
->
measObjectToAddModList
=
calloc
(
1
,
sizeof
(
*
mc
->
measObjectToAddModList
));
mc
->
reportConfigToAddModList
=
calloc
(
1
,
sizeof
(
*
mc
->
reportConfigToAddModList
));
...
...
@@ -1105,17 +1109,16 @@ NR_MeasConfig_t *get_defaultMeasConfig(uint32_t ssb_arfcn, int band, int scs)
mo1
->
measObjectId
=
1
;
mo1
->
measObject
.
present
=
NR_MeasObjectToAddMod__measObject_PR_measObjectNR
;
NR_MeasObjectNR_t
*
monr1
=
calloc
(
1
,
sizeof
(
*
monr1
));
asn1cCallocOne
(
monr1
->
ssbFrequency
,
ssb_arfcn
);
asn1cCallocOne
(
monr1
->
ssbSubcarrierSpacing
,
scs
);
asn1cCallocOne
(
monr1
->
ssbFrequency
,
ft
->
carrierFreq
);
asn1cCallocOne
(
monr1
->
ssbSubcarrierSpacing
,
ft
->
ssbSubcarrierSpacing
);
monr1
->
referenceSignalConfig
.
ssb_ConfigMobility
=
calloc
(
1
,
sizeof
(
*
monr1
->
referenceSignalConfig
.
ssb_ConfigMobility
));
monr1
->
referenceSignalConfig
.
ssb_ConfigMobility
->
deriveSSB_IndexFromCell
=
true
;
monr1
->
absThreshSS_BlocksConsolidation
=
calloc
(
1
,
sizeof
(
*
monr1
->
absThreshSS_BlocksConsolidation
));
asn1cCallocOne
(
monr1
->
absThreshSS_BlocksConsolidation
->
thresholdRSRP
,
36
);
asn1cCallocOne
(
monr1
->
nrofSS_BlocksToAverage
,
8
);
monr1
->
smtc1
=
calloc
(
1
,
sizeof
(
*
monr1
->
smtc1
));
monr1
->
smtc1
->
periodicityAndOffset
.
present
=
NR_SSB_MTC__periodicityAndOffset_PR_sf20
;
monr1
->
smtc1
->
periodicityAndOffset
.
choice
.
sf20
=
2
;
monr1
->
smtc1
->
duration
=
NR_SSB_MTC__duration_sf2
;
monr1
->
smtc1
->
periodicityAndOffset
=
ssb_mtc
->
periodicityAndOffset
;
monr1
->
smtc1
->
duration
=
ssb_mtc
->
duration
;
monr1
->
quantityConfigIndex
=
1
;
monr1
->
ext1
=
calloc
(
1
,
sizeof
(
*
monr1
->
ext1
));
asn1cCallocOne
(
monr1
->
ext1
->
freqBandIndicatorNR
,
band
);
...
...
openair2/RRC/NR/MESSAGES/asn1_msg.h
View file @
65d494fb
...
...
@@ -143,7 +143,7 @@ int do_RRCReestablishment(rrc_gNB_ue_context_t *const ue_context_pP,
int
do_RRCReestablishmentComplete
(
uint8_t
*
buffer
,
size_t
buffer_size
,
int64_t
rrc_TransactionIdentifier
);
NR_MeasConfig_t
*
get_defaultMeasConfig
(
uint32_t
absFreqSSB
,
int
band
,
int
scs
);
NR_MeasConfig_t
*
get_defaultMeasConfig
(
const
NR_MeasTiming_t
*
mt
,
int
band
,
int
scs
);
void
free_defaultMeasConfig
(
NR_MeasConfig_t
*
mc
);
uint8_t
do_NR_Paging
(
uint8_t
Mod_id
,
uint8_t
*
buffer
,
uint32_t
tmsi
);
...
...
openair2/RRC/NR/mac_rrc_dl.h
View file @
65d494fb
...
...
@@ -27,6 +27,8 @@
typedef
void
(
*
f1_setup_response_func_t
)(
sctp_assoc_t
assoc_id
,
const
f1ap_setup_resp_t
*
resp
);
typedef
void
(
*
f1_setup_failure_func_t
)(
sctp_assoc_t
assoc_id
,
const
f1ap_setup_failure_t
*
fail
);
typedef
void
(
*
gnb_du_configuration_update_ack_func_t
)(
sctp_assoc_t
assoc_id
,
const
f1ap_gnb_du_configuration_update_acknowledge_t
*
ack
);
typedef
void
(
*
ue_context_setup_request_func_t
)(
sctp_assoc_t
assoc_id
,
const
f1ap_ue_context_setup_t
*
req
);
typedef
void
(
*
ue_context_modification_request_func_t
)(
sctp_assoc_t
assoc_id
,
const
f1ap_ue_context_modif_req_t
*
req
);
...
...
openair2/RRC/NR/mac_rrc_dl_direct.c
View file @
65d494fb
...
...
@@ -36,6 +36,12 @@ static void f1_setup_failure_direct(sctp_assoc_t assoc_id, const f1ap_setup_fail
f1_setup_failure
(
fail
);
}
static
void
gnb_du_configuration_update_ack_direct
(
sctp_assoc_t
assoc_id
,
const
f1ap_gnb_du_configuration_update_acknowledge_t
*
ack
)
{
AssertFatal
(
assoc_id
==
-
1
,
"illegal assoc_id %d
\n
"
,
assoc_id
);
gnb_du_configuration_update_acknowledge
(
ack
);
}
static
void
ue_context_setup_request_direct
(
sctp_assoc_t
assoc_id
,
const
f1ap_ue_context_setup_t
*
req
)
{
AssertFatal
(
assoc_id
==
-
1
,
"illegal assoc_id %d
\n
"
,
assoc_id
);
...
...
@@ -76,6 +82,7 @@ void mac_rrc_dl_direct_init(nr_mac_rrc_dl_if_t *mac_rrc)
{
mac_rrc
->
f1_setup_response
=
f1_setup_response_direct
;
mac_rrc
->
f1_setup_failure
=
f1_setup_failure_direct
;
mac_rrc
->
gnb_du_configuration_update_acknowledge
=
gnb_du_configuration_update_ack_direct
;
mac_rrc
->
ue_context_setup_request
=
ue_context_setup_request_direct
;
mac_rrc
->
ue_context_modification_request
=
ue_context_modification_request_direct
;
mac_rrc
->
ue_context_modification_confirm
=
ue_context_modification_confirm_direct
;
...
...
openair2/RRC/NR/mac_rrc_dl_f1ap.c
View file @
65d494fb
...
...
@@ -44,6 +44,15 @@ static void f1_setup_failure_f1ap(sctp_assoc_t assoc_id, const f1ap_setup_failur
itti_send_msg_to_task
(
TASK_CU_F1
,
0
,
msg
);
}
static
void
gnb_du_configuration_update_ack_f1ap
(
sctp_assoc_t
assoc_id
,
const
f1ap_gnb_du_configuration_update_acknowledge_t
*
ack
)
{
MessageDef
*
msg
=
itti_alloc_new_message
(
TASK_RRC_GNB
,
0
,
F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
);
msg
->
ittiMsgHeader
.
originInstance
=
assoc_id
;
f1ap_gnb_du_configuration_update_acknowledge_t
*
f1ap_msg
=
&
F1AP_GNB_DU_CONFIGURATION_UPDATE_ACKNOWLEDGE
(
msg
);
*
f1ap_msg
=
*
ack
;
itti_send_msg_to_task
(
TASK_CU_F1
,
0
,
msg
);
}
static
void
ue_context_setup_request_f1ap
(
sctp_assoc_t
assoc_id
,
const
f1ap_ue_context_setup_t
*
req
)
{
MessageDef
*
msg
=
itti_alloc_new_message
(
TASK_RRC_GNB
,
0
,
F1AP_UE_CONTEXT_SETUP_REQ
);
...
...
@@ -208,6 +217,7 @@ void mac_rrc_dl_f1ap_init(nr_mac_rrc_dl_if_t *mac_rrc)
{
mac_rrc
->
f1_setup_response
=
f1_setup_response_f1ap
;
mac_rrc
->
f1_setup_failure
=
f1_setup_failure_f1ap
;
mac_rrc
->
gnb_du_configuration_update_acknowledge
=
gnb_du_configuration_update_ack_f1ap
;
mac_rrc
->
ue_context_setup_request
=
ue_context_setup_request_f1ap
;
mac_rrc
->
ue_context_modification_request
=
ue_context_modification_request_f1ap
;
mac_rrc
->
ue_context_modification_confirm
=
ue_context_modification_confirm_f1ap
;
...
...
openair2/RRC/NR/nr_rrc_config.c
View file @
65d494fb
...
...
@@ -36,6 +36,8 @@
#include "oai_asn1.h"
#include "SIMULATION/TOOLS/sim.h" // for taus();
#include "NR_MeasurementTimingConfiguration.h"
#include "uper_decoder.h"
#include "uper_encoder.h"
...
...
@@ -1875,6 +1877,95 @@ int encode_MIB_NR(NR_BCCH_BCH_Message_t *mib, int frame, uint8_t *buf, int buf_s
return
(
enc_rval
.
encoded
+
7
)
/
8
;
}
int
encode_MIB_NR_setup
(
NR_MIB_t
*
mib
,
int
frame
,
uint8_t
*
buf
,
int
buf_size
)
{
DevAssert
(
mib
!=
NULL
);
uint8_t
sfn_msb
=
(
uint8_t
)((
frame
>>
4
)
&
0x3f
);
*
mib
->
systemFrameNumber
.
buf
=
sfn_msb
<<
2
;
asn_enc_rval_t
enc_rval
=
uper_encode_to_buffer
(
&
asn_DEF_NR_MIB
,
NULL
,
mib
,
buf
,
buf_size
);
AssertFatal
(
enc_rval
.
encoded
>
0
,
"ASN1 message encoding failed (%s, %lu)!
\n
"
,
enc_rval
.
failed_type
->
name
,
enc_rval
.
encoded
);
LOG_D
(
NR_RRC
,
"Encoded MIB for frame %d sfn_msb %d, bits %lu
\n
"
,
frame
,
sfn_msb
,
enc_rval
.
encoded
);
return
(
enc_rval
.
encoded
+
7
)
/
8
;
}
static
struct
NR_SSB_MTC__periodicityAndOffset
get_SSB_MTC_periodicityAndOffset
(
long
ssb_periodicityServingCell
)
{
struct
NR_SSB_MTC__periodicityAndOffset
po
=
{
0
};
switch
(
ssb_periodicityServingCell
)
{
case
NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms5
:
po
.
present
=
NR_SSB_MTC__periodicityAndOffset_PR_sf5
;
po
.
choice
.
sf5
=
0
;
break
;
case
NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms10
:
po
.
present
=
NR_SSB_MTC__periodicityAndOffset_PR_sf10
;
po
.
choice
.
sf10
=
0
;
break
;
case
NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms20
:
po
.
present
=
NR_SSB_MTC__periodicityAndOffset_PR_sf20
;
po
.
choice
.
sf20
=
0
;
break
;
case
NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms40
:
po
.
present
=
NR_SSB_MTC__periodicityAndOffset_PR_sf40
;
po
.
choice
.
sf40
=
0
;
break
;
case
NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms80
:
po
.
present
=
NR_SSB_MTC__periodicityAndOffset_PR_sf80
;
po
.
choice
.
sf80
=
0
;
break
;
case
NR_ServingCellConfigCommon__ssb_periodicityServingCell_ms160
:
po
.
present
=
NR_SSB_MTC__periodicityAndOffset_PR_sf160
;
po
.
choice
.
sf160
=
0
;
break
;
default:
AssertFatal
(
false
,
"illegal ssb_periodicityServingCell %ld
\n
"
,
ssb_periodicityServingCell
);
break
;
}
return
po
;
}
NR_MeasurementTimingConfiguration_t
*
get_new_MeasurementTimingConfiguration
(
const
NR_ServingCellConfigCommon_t
*
scc
)
{
NR_MeasurementTimingConfiguration_t
*
mtc
=
calloc
(
1
,
sizeof
(
*
mtc
));
AssertFatal
(
mtc
!=
NULL
,
"out of memory
\n
"
);
mtc
->
criticalExtensions
.
present
=
NR_MeasurementTimingConfiguration__criticalExtensions_PR_c1
;
mtc
->
criticalExtensions
.
choice
.
c1
=
calloc
(
1
,
sizeof
(
*
mtc
->
criticalExtensions
.
choice
.
c1
));
AssertFatal
(
mtc
->
criticalExtensions
.
choice
.
c1
!=
NULL
,
"out of memory
\n
"
);
mtc
->
criticalExtensions
.
choice
.
c1
->
present
=
NR_MeasurementTimingConfiguration__criticalExtensions__c1_PR_measTimingConf
;
NR_MeasurementTimingConfiguration_IEs_t
*
mtc_ie
=
calloc
(
1
,
sizeof
(
*
mtc_ie
));
AssertFatal
(
mtc_ie
!=
NULL
,
"out of memory
\n
"
);
mtc
->
criticalExtensions
.
choice
.
c1
->
choice
.
measTimingConf
=
mtc_ie
;
mtc_ie
->
measTiming
=
calloc
(
1
,
sizeof
(
*
mtc_ie
->
measTiming
));
AssertFatal
(
mtc_ie
->
measTiming
!=
NULL
,
"out of memory
\n
"
);
asn1cSequenceAdd
(
mtc_ie
->
measTiming
->
list
,
NR_MeasTiming_t
,
mt
);
AssertFatal
(
mt
!=
NULL
,
"out of memory
\n
"
);
mt
->
frequencyAndTiming
=
calloc
(
1
,
sizeof
(
*
mt
->
frequencyAndTiming
));
AssertFatal
(
mt
->
frequencyAndTiming
!=
NULL
,
"out of memory
\n
"
);
mt
->
frequencyAndTiming
->
carrierFreq
=
*
scc
->
downlinkConfigCommon
->
frequencyInfoDL
->
absoluteFrequencySSB
;
mt
->
frequencyAndTiming
->
ssbSubcarrierSpacing
=
*
scc
->
ssbSubcarrierSpacing
;
NR_SSB_MTC_t
*
ssb_mtc
=
&
mt
->
frequencyAndTiming
->
ssb_MeasurementTimingConfiguration
;
ssb_mtc
->
duration
=
NR_SSB_MTC__duration_sf1
;
ssb_mtc
->
periodicityAndOffset
=
get_SSB_MTC_periodicityAndOffset
(
*
scc
->
ssb_periodicityServingCell
);
return
mtc
;
}
int
encode_MeasurementTimingConfiguration
(
const
struct
NR_MeasurementTimingConfiguration
*
mtc
,
uint8_t
*
buf
,
int
buf_len
)
{
DevAssert
(
mtc
!=
NULL
);
xer_fprint
(
stdout
,
&
asn_DEF_NR_MeasurementTimingConfiguration
,
mtc
);
asn_enc_rval_t
enc_rval
=
uper_encode_to_buffer
(
&
asn_DEF_NR_MeasurementTimingConfiguration
,
NULL
,
mtc
,
buf
,
buf_len
);
AssertFatal
(
enc_rval
.
encoded
>
0
,
"ASN1 message encoding failed (%s, %lu)!
\n
"
,
enc_rval
.
failed_type
->
name
,
enc_rval
.
encoded
);
return
(
enc_rval
.
encoded
+
7
)
/
8
;
}
void
free_MeasurementTimingConfiguration
(
NR_MeasurementTimingConfiguration_t
*
mtc
)
{
ASN_STRUCT_FREE
(
asn_DEF_NR_MeasurementTimingConfiguration
,
mtc
);
}
NR_BCCH_DL_SCH_Message_t
*
get_SIB1_NR
(
const
NR_ServingCellConfigCommon_t
*
scc
,
const
f1ap_plmn_t
*
plmn
,
uint64_t
cellID
,
int
tac
)
{
AssertFatal
(
cellID
<
(
1l
<<
36
),
"cellID must fit within 36 bits, but is %lu
\n
"
,
cellID
);
...
...
openair2/RRC/NR/nr_rrc_config.h
View file @
65d494fb
...
...
@@ -55,7 +55,12 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
NR_BCCH_BCH_Message_t
*
get_new_MIB_NR
(
const
NR_ServingCellConfigCommon_t
*
scc
);
void
free_MIB_NR
(
NR_BCCH_BCH_Message_t
*
mib
);
int
encode_MIB_NR
(
NR_BCCH_BCH_Message_t
*
mib
,
int
frame
,
uint8_t
*
buf
,
int
buf_size
);
int
encode_MIB_NR_setup
(
NR_MIB_t
*
mib
,
int
frame
,
uint8_t
*
buf
,
int
buf_size
);
struct
NR_MeasurementTimingConfiguration
;
struct
NR_MeasurementTimingConfiguration
*
get_new_MeasurementTimingConfiguration
(
const
NR_ServingCellConfigCommon_t
*
scc
);
int
encode_MeasurementTimingConfiguration
(
const
struct
NR_MeasurementTimingConfiguration
*
mtc
,
uint8_t
*
buf
,
int
buf_len
);
void
free_MeasurementTimingConfiguration
(
struct
NR_MeasurementTimingConfiguration
*
mtc
);
#define NR_MAX_SIB_LENGTH 2976 // 3GPP TS 38.331 section 5.2.1
NR_BCCH_DL_SCH_Message_t
*
get_SIB1_NR
(
const
NR_ServingCellConfigCommon_t
*
scc
,
const
f1ap_plmn_t
*
plmn
,
uint64_t
cellID
,
int
tac
);
...
...
openair2/RRC/NR/nr_rrc_defs.h
View file @
65d494fb
...
...
@@ -62,6 +62,7 @@
#include "NR_CellGroupConfig.h"
#include "NR_ServingCellConfigCommon.h"
#include "NR_EstablishmentCause.h"
#include "NR_MeasurementTimingConfiguration.h"
//-------------------
...
...
@@ -240,7 +241,6 @@ typedef enum {
RRC_SETUP_FOR_REESTABLISHMENT
,
RRC_REESTABLISH
,
RRC_REESTABLISH_COMPLETE
,
RRC_DEFAULT_RECONF
,
RRC_DEDICATED_RECONF
,
RRC_PDUSESSION_ESTABLISH
,
RRC_PDUSESSION_MODIFY
,
...
...
@@ -260,6 +260,7 @@ typedef struct gNB_RRC_UE_s {
NR_MeasResults_t
*
measResults
;
bool
as_security_active
;
bool
f1_ue_context_active
;
byte_array_t
ue_cap_buffer
;
NR_UE_NR_Capability_t
*
UE_Capability_nr
;
...
...
@@ -318,12 +319,14 @@ typedef struct gNB_RRC_UE_s {
uint32_t
ue_reconfiguration_counter
;
struct
NR_SpCellConfig
*
spCellConfig
;
/* NGUEContextSetup might come with PDU sessions, but setup needs to be
* delayed after security (and capability); PDU sessions are stored here */
int
n_initial_pdu
;
pdusession_t
*
initial_pdus
;
/* Nas Pdu */
ngap_pdu_t
nas_pdu
;
/* hack, see rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ() for more info */
int
max_delays_pdu_session
;
}
gNB_RRC_UE_t
;
typedef
struct
rrc_gNB_ue_context_s
{
...
...
@@ -359,6 +362,7 @@ typedef struct {
typedef
struct
nr_mac_rrc_dl_if_s
{
f1_setup_response_func_t
f1_setup_response
;
f1_setup_failure_func_t
f1_setup_failure
;
gnb_du_configuration_update_ack_func_t
gnb_du_configuration_update_acknowledge
;
ue_context_setup_request_func_t
ue_context_setup_request
;
ue_context_modification_request_func_t
ue_context_modification_request
;
ue_context_modification_confirm_func_t
ue_context_modification_confirm
;
...
...
@@ -381,6 +385,7 @@ typedef struct nr_rrc_du_container_t {
f1ap_setup_req_t
*
setup_req
;
NR_MIB_t
*
mib
;
NR_SIB1_t
*
sib1
;
NR_MeasurementTimingConfiguration_t
*
mtc
;
}
nr_rrc_du_container_t
;
typedef
struct
nr_rrc_cuup_container_t
{
...
...
openair2/RRC/NR/nr_rrc_proto.h
View file @
65d494fb
...
...
@@ -80,13 +80,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc,
int
parse_CG_ConfigInfo
(
gNB_RRC_INST
*
rrc
,
NR_CG_ConfigInfo_t
*
CG_ConfigInfo
,
x2ap_ENDC_sgnb_addition_req_t
*
m
);
void
rrc_gNB_generate_SecurityModeCommand
(
const
protocol_ctxt_t
*
const
ctxt_pP
,
rrc_gNB_ue_context_t
*
const
ue_context_pP
,
int
n_drbs
,
const
f1ap_drb_to_be_setup_t
*
drbs
);
void
rrc_gNB_generate_SecurityModeCommand
(
const
protocol_ctxt_t
*
const
ctxt_pP
,
rrc_gNB_ue_context_t
*
const
ue_context_pP
);
unsigned
int
rrc_gNB_get_next_transaction_identifier
(
module_id_t
gnb_mod_idP
);
...
...
@@ -165,8 +159,25 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag,
uint8_t
*
const
kUPenc
,
uint8_t
*
const
kUPint
);
void
trigger_bearer_setup
(
gNB_RRC_INST
*
rrc
,
gNB_RRC_UE_t
*
UE
,
int
n
,
pdusession_t
*
sessions
,
uint64_t
ueAggMaxBitRateDownlink
);
int
rrc_gNB_generate_pcch_msg
(
sctp_assoc_t
assoc_id
,
const
NR_SIB1_t
*
sib
,
uint32_t
tmsi
,
uint8_t
paging_drx
);
void
nr_rrc_transfer_protected_rrc_message
(
const
gNB_RRC_INST
*
rrc
,
const
gNB_RRC_UE_t
*
ue_p
,
uint8_t
srb_id
,
const
uint8_t
*
buffer
,
int
size
);
/** @}*/
/* UE Management Procedures */
void
rrc_gNB_generate_UeContextSetupRequest
(
const
gNB_RRC_INST
*
rrc
,
rrc_gNB_ue_context_t
*
const
ue_context_pP
,
int
n_drbs
,
const
f1ap_drb_to_be_setup_t
*
drbs
);
void
rrc_gNB_generate_UeContextModificationRequest
(
const
gNB_RRC_INST
*
rrc
,
rrc_gNB_ue_context_t
*
const
ue_context_pP
,
int
n_drbs
,
const
f1ap_drb_to_be_setup_t
*
drbs
,
int
n_rel_drbs
,
const
f1ap_drb_to_be_released_t
*
rel_drbs
);
#endif
openair2/RRC/NR/rrc_gNB.c
View file @
65d494fb
...
...
@@ -186,79 +186,12 @@ static int get_ssb_scs(const f1ap_served_cell_info_t *cell_info)
return
cell_info
->
mode
==
F1AP_MODE_TDD
?
cell_info
->
tdd
.
tbw
.
scs
:
cell_info
->
fdd
.
dl_tbw
.
scs
;
}
static
int
get_
dl_arfcn
(
const
f1ap_served_cell_info_t
*
cell_info
)
static
int
get_
ssb_arfcn
(
const
nr_rrc_du_container_t
*
du
)
{
return
cell_info
->
mode
==
F1AP_MODE_TDD
?
cell_info
->
tdd
.
freqinfo
.
arfcn
:
cell_info
->
fdd
.
dl_freqinfo
.
arfcn
;
}
static
int
get_dl_bw
(
const
f1ap_served_cell_info_t
*
cell_info
)
{
return
cell_info
->
mode
==
F1AP_MODE_TDD
?
cell_info
->
tdd
.
tbw
.
nrb
:
cell_info
->
fdd
.
dl_tbw
.
nrb
;
}
static
int
get_ssb_arfcn
(
const
f1ap_served_cell_info_t
*
cell_info
,
const
NR_MIB_t
*
mib
,
const
NR_SIB1_t
*
sib1
)
{
DevAssert
(
cell_info
!=
NULL
&&
sib1
!=
NULL
&&
mib
!=
NULL
);
const
NR_FrequencyInfoDL_SIB_t
*
freq_info
=
&
sib1
->
servingCellConfigCommon
->
downlinkConfigCommon
.
frequencyInfoDL
;
AssertFatal
(
freq_info
->
scs_SpecificCarrierList
.
list
.
count
==
1
,
"cannot handle more than one carrier, but has %d
\n
"
,
freq_info
->
scs_SpecificCarrierList
.
list
.
count
);
AssertFatal
(
freq_info
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
offsetToCarrier
==
0
,
"cannot handle offsetToCarrier != 0, but is %ld
\n
"
,
freq_info
->
scs_SpecificCarrierList
.
list
.
array
[
0
]
->
offsetToCarrier
);
long
offsetToPointA
=
freq_info
->
offsetToPointA
;
long
kssb
=
mib
->
ssb_SubcarrierOffset
;
uint32_t
dl_arfcn
=
get_dl_arfcn
(
cell_info
);
int
scs
=
get_ssb_scs
(
cell_info
);
int
band
=
get_dl_band
(
cell_info
);
uint64_t
freqpointa
=
from_nrarfcn
(
band
,
scs
,
dl_arfcn
);
uint64_t
freqssb
=
0
;
// 3GPP TS 38.211 sections 7.4.3.1 and 4.4.4.2
// for FR1 offsetToPointA and k_SSB are expressed in terms of 15 kHz SCS
// for FR2 offsetToPointA is expressed in terms of 60 kHz SCS and k_SSB expressed in terms of the subcarrier spacing provided
// by the higher-layer parameter subCarrierSpacingCommon
// FR1 includes frequency bands from 410 MHz (ARFCN 82000) to 7125 MHz (ARFCN 875000)
// FR2 includes frequency bands from 24.25 GHz (ARFCN 2016667) to 71.0 GHz (ARFCN 2795832)
if
(
dl_arfcn
>=
82000
&&
dl_arfcn
<
875000
)
freqssb
=
freqpointa
+
15000
*
(
offsetToPointA
*
12
+
kssb
)
+
10ll
*
12
*
(
1
<<
scs
)
*
15000
;
else
if
(
dl_arfcn
>=
2016667
&&
dl_arfcn
<
2795832
)
freqssb
=
freqpointa
+
60000
*
offsetToPointA
*
12
+
(
1
<<
scs
)
*
15000
*
(
kssb
+
10ll
*
12
);
else
AssertFatal
(
false
,
"Invalid absoluteFrequencyPointA: %u
\n
"
,
dl_arfcn
);
int
band_size_hz
=
get_supported_bw_mhz
(
band
>
256
?
FR2
:
FR1
,
scs
,
get_dl_bw
(
cell_info
))
*
1000
*
1000
;
uint32_t
ssb_arfcn
=
to_nrarfcn
(
band
,
freqssb
,
scs
,
band_size_hz
);
LOG_D
(
NR_RRC
,
"freqpointa %ld Hz/%d offsetToPointA %ld kssb %ld scs %d band %d band_size_hz %d freqssb %ld Hz/%d
\n
"
,
freqpointa
,
dl_arfcn
,
offsetToPointA
,
kssb
,
scs
,
band
,
band_size_hz
,
freqssb
,
ssb_arfcn
);
if
(
RC
.
nrmac
)
{
// debugging: let's test this is the correct ARFCN
// in the CU, we have no access to the SSB ARFCN and therefore need to
// compute it ourselves. If we are running in monolithic, though, we have
// access to the MAC structures and hence can read and compare to the
// original SSB ARFCN. If the below creates problems, it can safely be
// taken out (but the reestablishment will likely not work).
const
NR_ServingCellConfigCommon_t
*
scc
=
RC
.
nrmac
[
0
]
->
common_channels
[
0
].
ServingCellConfigCommon
;
uint32_t
scc_ssb_arfcn
=
*
scc
->
downlinkConfigCommon
->
frequencyInfoDL
->
absoluteFrequencySSB
;
AssertFatal
(
ssb_arfcn
==
scc_ssb_arfcn
,
"mismatch of SCC SSB ARFCN original %u vs. computed %u! Note: you can remove this Assert, the gNB might run but UE "
"connection instable
\n
"
,
scc_ssb_arfcn
,
ssb_arfcn
);
}
return
ssb_arfcn
;
DevAssert
(
du
!=
NULL
&&
du
->
mtc
!=
NULL
);
/* format has been verified when accepting MeasurementTimingConfiguration */
NR_MeasTimingList_t
*
mtlist
=
du
->
mtc
->
criticalExtensions
.
choice
.
c1
->
choice
.
measTimingConf
->
measTiming
;
return
mtlist
->
list
.
array
[
0
]
->
frequencyAndTiming
->
carrierFreq
;
}
///---------------------------------------------------------------------------------------------------------------///
...
...
@@ -542,91 +475,6 @@ static void rrc_gNB_process_RRCSetupComplete(const protocol_ctxt_t *const ctxt_p
#endif
}
//-----------------------------------------------------------------------------
static
void
rrc_gNB_generate_defaultRRCReconfiguration
(
const
protocol_ctxt_t
*
const
ctxt_pP
,
rrc_gNB_ue_context_t
*
ue_context_pP
)
//-----------------------------------------------------------------------------
{
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
ctxt_pP
->
module_id
];
gNB_RRC_UE_t
*
ue_p
=
&
ue_context_pP
->
ue_context
;
uint8_t
xid
=
rrc_gNB_get_next_transaction_identifier
(
ctxt_pP
->
module_id
);
ue_p
->
xids
[
xid
]
=
RRC_DEFAULT_RECONF
;
struct
NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
*
dedicatedNAS_MessageList
=
CALLOC
(
1
,
sizeof
(
*
dedicatedNAS_MessageList
));
/* Add all NAS PDUs to the list */
for
(
int
i
=
0
;
i
<
ue_p
->
nb_of_pdusessions
;
i
++
)
{
if
(
ue_p
->
pduSession
[
i
].
param
.
nas_pdu
.
buffer
!=
NULL
)
{
asn1cSequenceAdd
(
dedicatedNAS_MessageList
->
list
,
NR_DedicatedNAS_Message_t
,
msg
);
OCTET_STRING_fromBuf
(
msg
,
(
char
*
)
ue_p
->
pduSession
[
i
].
param
.
nas_pdu
.
buffer
,
ue_p
->
pduSession
[
i
].
param
.
nas_pdu
.
length
);
}
if
(
ue_p
->
pduSession
[
i
].
status
<
PDU_SESSION_STATUS_ESTABLISHED
)
{
ue_p
->
pduSession
[
i
].
status
=
PDU_SESSION_STATUS_DONE
;
LOG_D
(
NR_RRC
,
"setting the status for the default DRB (index %d) to (%d,%s)
\n
"
,
i
,
ue_p
->
pduSession
[
i
].
status
,
"PDU_SESSION_STATUS_DONE"
);
}
}
if
(
ue_p
->
nas_pdu
.
length
)
{
asn1cSequenceAdd
(
dedicatedNAS_MessageList
->
list
,
NR_DedicatedNAS_Message_t
,
msg
);
OCTET_STRING_fromBuf
(
msg
,
(
char
*
)
ue_p
->
nas_pdu
.
buffer
,
ue_p
->
nas_pdu
.
length
);
}
/* If list is empty free the list and reset the address */
if
(
dedicatedNAS_MessageList
->
list
.
count
==
0
)
{
free
(
dedicatedNAS_MessageList
);
dedicatedNAS_MessageList
=
NULL
;
}
const
nr_rrc_du_container_t
*
du
=
get_du_for_ue
(
rrc
,
ue_p
->
rrc_ue_id
);
DevAssert
(
du
!=
NULL
);
f1ap_served_cell_info_t
*
cell_info
=
&
du
->
setup_req
->
cell
[
0
].
info
;
int
scs
=
get_ssb_scs
(
cell_info
);
int
band
=
get_dl_band
(
cell_info
);
NR_MeasConfig_t
*
measconfig
=
NULL
;
if
(
du
->
mib
!=
NULL
&&
du
->
sib1
!=
NULL
)
{
/* we cannot calculate the default measurement config without MIB&SIB1, as
* we don't know the DU's SSB ARFCN */
uint32_t
ssb_arfcn
=
get_ssb_arfcn
(
cell_info
,
du
->
mib
,
du
->
sib1
);
measconfig
=
get_defaultMeasConfig
(
ssb_arfcn
,
band
,
scs
);
}
NR_SRB_ToAddModList_t
*
SRBs
=
createSRBlist
(
ue_p
,
false
);
NR_DRB_ToAddModList_t
*
DRBs
=
createDRBlist
(
ue_p
,
false
);
uint8_t
buffer
[
RRC_BUF_SIZE
]
=
{
0
};
int
size
=
do_RRCReconfiguration
(
ue_p
,
buffer
,
RRC_BUF_SIZE
,
xid
,
SRBs
,
DRBs
,
NULL
,
NULL
,
measconfig
,
dedicatedNAS_MessageList
,
ue_p
->
masterCellGroup
);
AssertFatal
(
size
>
0
,
"cannot encode RRCReconfiguration in %s()
\n
"
,
__func__
);
free_defaultMeasConfig
(
measconfig
);
freeSRBlist
(
SRBs
);
freeDRBlist
(
DRBs
);
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
{
xer_fprint
(
stdout
,
&
asn_DEF_NR_CellGroupConfig
,
ue_p
->
masterCellGroup
);
}
clear_nas_pdu
(
&
ue_p
->
nas_pdu
);
LOG_DUMPMSG
(
NR_RRC
,
DEBUG_RRC
,(
char
*
)
buffer
,
size
,
"[MSG] RRC Reconfiguration
\n
"
);
/* Free all NAS PDUs */
for
(
int
i
=
0
;
i
<
ue_p
->
nb_of_pdusessions
;
i
++
)
clear_nas_pdu
(
&
ue_p
->
pduSession
[
i
].
param
.
nas_pdu
);
LOG_I
(
NR_RRC
,
"UE %d: Generate RRCReconfiguration (bytes %d, xid %d)
\n
"
,
ue_p
->
rrc_ue_id
,
size
,
xid
);
AssertFatal
(
!
NODE_IS_DU
(
rrc
->
node_type
),
"illegal node type DU!
\n
"
);
nr_rrc_transfer_protected_rrc_message
(
rrc
,
ue_p
,
DCCH
,
buffer
,
size
);
}
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_dedicatedRRCReconfiguration
(
const
protocol_ctxt_t
*
const
ctxt_pP
,
rrc_gNB_ue_context_t
*
ue_context_pP
)
//-----------------------------------------------------------------------------
...
...
@@ -635,20 +483,7 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
uint8_t
xid
=
rrc_gNB_get_next_transaction_identifier
(
ctxt_pP
->
module_id
);
gNB_RRC_UE_t
*
ue_p
=
&
ue_context_pP
->
ue_context
;
/* hack: in many cases, we want to send a PDU session resource setup response
* after this dedicated RRC Reconfiguration (e.g., new PDU session). However,
* this is not always the case, e.g., when the PDU sessions came through the
* NG initial UE context setup, in which case all PDU sessions are
* established, and we end up here after a UE Capability Enquiry. So below,
* check if we are currently setting up any PDU sessions, and only then, set
* the xid to trigger a PDU session setup response. */
ue_p
->
xids
[
xid
]
=
RRC_DEDICATED_RECONF
;
for
(
int
i
=
0
;
i
<
ue_p
->
nb_of_pdusessions
;
++
i
)
{
if
(
ue_p
->
pduSession
[
i
].
status
<
PDU_SESSION_STATUS_ESTABLISHED
)
{
ue_p
->
xids
[
xid
]
=
RRC_PDUSESSION_ESTABLISH
;
break
;
}
}
struct
NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
*
dedicatedNAS_MessageList
=
CALLOC
(
1
,
sizeof
(
*
dedicatedNAS_MessageList
));
for
(
int
i
=
0
;
i
<
ue_p
->
nb_of_pdusessions
;
i
++
)
{
...
...
@@ -683,6 +518,18 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
NR_CellGroupConfig_t
*
cellGroupConfig
=
ue_p
->
masterCellGroup
;
const
nr_rrc_du_container_t
*
du
=
get_du_for_ue
(
rrc
,
ue_p
->
rrc_ue_id
);
DevAssert
(
du
!=
NULL
);
f1ap_served_cell_info_t
*
cell_info
=
&
du
->
setup_req
->
cell
[
0
].
info
;
NR_MeasConfig_t
*
measconfig
=
NULL
;
if
(
du
->
mtc
!=
NULL
)
{
int
scs
=
get_ssb_scs
(
cell_info
);
int
band
=
get_dl_band
(
cell_info
);
const
NR_MeasTimingList_t
*
mtlist
=
du
->
mtc
->
criticalExtensions
.
choice
.
c1
->
choice
.
measTimingConf
->
measTiming
;
const
NR_MeasTiming_t
*
mt
=
mtlist
->
list
.
array
[
0
];
measconfig
=
get_defaultMeasConfig
(
mt
,
band
,
scs
);
}
uint8_t
buffer
[
RRC_BUF_SIZE
]
=
{
0
};
NR_SRB_ToAddModList_t
*
SRBs
=
createSRBlist
(
ue_p
,
false
);
NR_DRB_ToAddModList_t
*
DRBs
=
createDRBlist
(
ue_p
,
false
);
...
...
@@ -695,10 +542,11 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
DRBs
,
ue_p
->
DRB_ReleaseList
,
NULL
,
NULL
,
measconfig
,
dedicatedNAS_MessageList
,
cellGroupConfig
);
LOG_DUMPMSG
(
NR_RRC
,
DEBUG_RRC
,(
char
*
)
buffer
,
size
,
"[MSG] RRC Reconfiguration
\n
"
);
free_defaultMeasConfig
(
measconfig
);
freeSRBlist
(
SRBs
);
freeDRBlist
(
DRBs
);
ASN_STRUCT_FREE
(
asn_DEF_NR_DRB_ToReleaseList
,
ue_p
->
DRB_ReleaseList
);
...
...
@@ -996,7 +844,7 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
uint8_t
xid
=
rrc_gNB_get_next_transaction_identifier
(
module_id
);
ue_p
->
xids
[
xid
]
=
RRC_REESTABLISH
;
const
f1ap_served_cell_info_t
*
cell_info
=
&
du
->
setup_req
->
cell
[
0
].
info
;
uint32_t
ssb_arfcn
=
get_ssb_arfcn
(
cell_info
,
du
->
mib
,
du
->
sib1
);
uint32_t
ssb_arfcn
=
get_ssb_arfcn
(
du
);
int
size
=
do_RRCReestablishment
(
ue_context_pP
,
buffer
,
RRC_BUF_SIZE
,
xid
,
cell_info
->
nr_pci
,
ssb_arfcn
);
LOG_I
(
NR_RRC
,
"[RAPROC] UE %04x Logical Channel DL-DCCH, Generating NR_RRCReestablishment (bytes %d)
\n
"
,
ue_p
->
rnti
,
size
);
...
...
@@ -1286,6 +1134,14 @@ static void rrc_handle_RRCReestablishmentRequest(gNB_RRC_INST *rrc,
goto
fallback_rrc_setup
;
}
if
(
du
->
mtc
==
NULL
)
{
// some UEs don't send MeasurementTimingConfiguration, so we don't know the
// SSB ARFCN and can't do reestablishment. handle it gracefully by doing
// RRC setup procedure instead
LOG_E
(
NR_RRC
,
"no MeasurementTimingConfiguration for this cell, cannot perform reestablishment
\n
"
);
goto
fallback_rrc_setup
;
}
/* TODO: start timer in ITTI and drop UE if it does not come back */
// update with new RNTI, and update secondary UE association
...
...
@@ -1345,6 +1201,22 @@ static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_p
return
0
;
}
static
void
rrc_forward_ue_nas_message
(
gNB_RRC_INST
*
rrc
,
gNB_RRC_UE_t
*
UE
)
{
if
(
UE
->
nas_pdu
.
buffer
==
NULL
||
UE
->
nas_pdu
.
length
==
0
)
return
;
// no problem: the UE will re-request a NAS PDU
uint8_t
buffer
[
4096
];
unsigned
int
xid
=
rrc_gNB_get_next_transaction_identifier
(
0
);
uint32_t
length
=
do_NR_DLInformationTransfer
(
buffer
,
sizeof
(
buffer
),
xid
,
UE
->
nas_pdu
.
length
,
UE
->
nas_pdu
.
buffer
);
LOG_DUMPMSG
(
NR_RRC
,
DEBUG_RRC
,
buffer
,
length
,
"[MSG] RRC DL Information Transfer
\n
"
);
rb_id_t
srb_id
=
UE
->
Srb
[
2
].
Active
?
DCCH1
:
DCCH
;
nr_rrc_transfer_protected_rrc_message
(
rrc
,
UE
,
srb_id
,
buffer
,
length
);
// no need to free UE->nas_pdu.buffer, do_NR_DLInformationTransfer() did that
UE
->
nas_pdu
.
buffer
=
NULL
;
UE
->
nas_pdu
.
length
=
0
;
}
static
int
handle_ueCapabilityInformation
(
const
protocol_ctxt_t
*
const
ctxt_pP
,
rrc_gNB_ue_context_t
*
ue_context_p
,
const
NR_UECapabilityInformation_t
*
ue_cap_info
)
...
...
@@ -1449,33 +1321,16 @@ static int handle_ueCapabilityInformation(const protocol_ctxt_t *const ctxt_pP,
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND
(
ctxt_pP
,
ue_context_p
,
ue_cap_info
);
/* if we already have DRBs setup (SRB2 exists if there is at least one DRB),
* there might not be a further reconfiguration on which we can rely, so send
* the UE capabilities to the DU to have it trigger a reconfiguration. */
if
(
UE
->
Srb
[
2
].
Active
&&
UE
->
ue_cap_buffer
.
len
>
0
&&
UE
->
ue_cap_buffer
.
buf
!=
NULL
)
{
cu_to_du_rrc_information_t
cu2du
=
{
0
};
if
(
UE
->
ue_cap_buffer
.
len
>
0
&&
UE
->
ue_cap_buffer
.
buf
!=
NULL
)
{
cu2du
.
uE_CapabilityRAT_ContainerList
=
UE
->
ue_cap_buffer
.
buf
;
cu2du
.
uE_CapabilityRAT_ContainerList_length
=
UE
->
ue_cap_buffer
.
len
;
}
f1_ue_data_t
ue_data
=
cu_get_f1_ue_data
(
UE
->
rrc_ue_id
);
if
(
ue_data
.
du_assoc_id
==
0
)
{
LOG_E
(
NR_RRC
,
"cannot send data: invalid assoc_id 0, DU offline
\n
"
);
return
-
1
;
}
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
0
];
f1ap_ue_context_modif_req_t
ue_context_modif_req
=
{
.
gNB_CU_ue_id
=
UE
->
rrc_ue_id
,
.
gNB_DU_ue_id
=
ue_data
.
secondary_ue
,
.
plmn
.
mcc
=
rrc
->
configuration
.
mcc
[
0
],
.
plmn
.
mnc
=
rrc
->
configuration
.
mnc
[
0
],
.
plmn
.
mnc_digit_length
=
rrc
->
configuration
.
mnc_digit_length
[
0
],
.
nr_cellid
=
rrc
->
nr_cellid
,
.
servCellId
=
0
,
/* TODO: correct value? */
.
cu_to_du_rrc_information
=
&
cu2du
,
};
rrc
->
mac_rrc
.
ue_context_modification_request
(
ue_data
.
du_assoc_id
,
&
ue_context_modif_req
);
if
(
UE
->
n_initial_pdu
>
0
)
{
/* there were PDU sessions with the NG UE Context setup, but we had to set
* up security and request capabilities, so trigger PDU sessions now. The
* UE NAS message will be forwarded in the corresponding reconfiguration,
* the Initial context setup response after reconfiguration complete. */
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
ctxt_pP
->
module_id
];
trigger_bearer_setup
(
rrc
,
UE
,
UE
->
n_initial_pdu
,
UE
->
initial_pdus
,
0
);
}
else
{
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP
(
ctxt_pP
,
ue_context_p
);
rrc_forward_ue_nas_message
(
RC
.
nrrrc
[
ctxt_pP
->
instance
],
UE
);
}
return
0
;
...
...
@@ -1561,7 +1416,6 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
UE
->
ue_reconfiguration_counter
++
;
LOG_I
(
NR_RRC
,
"UE %d: Receive RRC Reconfiguration Complete message (xid %d)
\n
"
,
UE
->
rrc_ue_id
,
xid
);
bool
successful_reconfig
=
true
;
switch
(
UE
->
xids
[
xid
])
{
case
RRC_PDUSESSION_RELEASE
:
{
gtpv1u_gnb_delete_tunnel_req_t
req
=
{
0
};
...
...
@@ -1570,26 +1424,27 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
rrc_gNB_send_NGAP_PDUSESSION_RELEASE_RESPONSE
(
ctxt_pP
,
ue_context_p
,
xid
);
}
break
;
case
RRC_PDUSESSION_ESTABLISH
:
if
(
UE
->
nb_of_pdusessions
>
0
)
if
(
UE
->
n_initial_pdu
>
0
)
{
/* PDU sessions through initial UE context setup */
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP
(
ctxt_pP
,
ue_context_p
);
UE
->
n_initial_pdu
=
0
;
free
(
UE
->
initial_pdus
);
UE
->
initial_pdus
=
NULL
;
}
else
if
(
UE
->
nb_of_pdusessions
>
0
)
rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP
(
ctxt_pP
,
ue_context_p
,
xid
);
break
;
case
RRC_PDUSESSION_MODIFY
:
rrc_gNB_send_NGAP_PDUSESSION_MODIFY_RESP
(
ctxt_pP
,
ue_context_p
,
xid
);
break
;
case
RRC_DEFAULT_RECONF
:
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP
(
ctxt_pP
,
ue_context_p
);
break
;
case
RRC_REESTABLISH_COMPLETE
:
case
RRC_DEDICATED_RECONF
:
/* do nothing */
break
;
case
RRC_ACTION_NONE
:
LOG_E
(
RRC
,
"UE %d: Received RRC Reconfiguration Complete with xid %d while no transaction is ongoing
\n
"
,
UE
->
rrc_ue_id
,
xid
);
successful_reconfig
=
false
;
break
;
default:
LOG_E
(
RRC
,
"UE %d: Received unexpected transaction type %d for xid %d
\n
"
,
UE
->
rrc_ue_id
,
UE
->
xids
[
xid
],
xid
);
successful_reconfig
=
false
;
break
;
}
UE
->
xids
[
xid
]
=
RRC_ACTION_NONE
;
...
...
@@ -1598,29 +1453,6 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_
LOG_I
(
RRC
,
"UE %d: transaction %d still ongoing for action %d
\n
"
,
UE
->
rrc_ue_id
,
i
,
UE
->
xids
[
i
]);
}
}
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
0
];
f1_ue_data_t
ue_data
=
cu_get_f1_ue_data
(
UE
->
rrc_ue_id
);
RETURN_IF_INVALID_ASSOC_ID
(
ue_data
);
f1ap_ue_context_modif_req_t
ue_context_modif_req
=
{
.
gNB_CU_ue_id
=
UE
->
rrc_ue_id
,
.
gNB_DU_ue_id
=
ue_data
.
secondary_ue
,
.
plmn
.
mcc
=
rrc
->
configuration
.
mcc
[
0
],
.
plmn
.
mnc
=
rrc
->
configuration
.
mnc
[
0
],
.
plmn
.
mnc_digit_length
=
rrc
->
configuration
.
mnc_digit_length
[
0
],
.
nr_cellid
=
rrc
->
nr_cellid
,
.
servCellId
=
0
,
/* TODO: correct value? */
.
ReconfigComplOutcome
=
successful_reconfig
?
RRCreconf_success
:
RRCreconf_failure
,
};
rrc
->
mac_rrc
.
ue_context_modification_request
(
ue_data
.
du_assoc_id
,
&
ue_context_modif_req
);
/* if we did not receive any UE Capabilities, let's do that now. It should
* only happen on the first time a reconfiguration arrives. Afterwards, we
* should have them. If the UE does not give us anything, we will re-request
* the capabilities after each reconfiguration, which is a finite number */
if
(
UE
->
ue_cap_buffer
.
len
==
0
)
{
rrc_gNB_generate_UECapabilityEnquiry
(
ctxt_pP
,
ue_context_p
);
}
}
//-----------------------------------------------------------------------------
int
rrc_gNB_decode_dcch
(
const
protocol_ctxt_t
*
const
ctxt_pP
,
...
...
@@ -1728,7 +1560,23 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
nr_rrc_pdcp_config_security
(
ctxt_pP
,
ue_context_p
,
1
);
ue_context_p
->
ue_context
.
as_security_active
=
true
;
rrc_gNB_generate_defaultRRCReconfiguration
(
ctxt_pP
,
ue_context_p
);
/* trigger UE capability enquiry if we don't have them yet */
if
(
ue_context_p
->
ue_context
.
ue_cap_buffer
.
len
==
0
)
{
rrc_gNB_generate_UECapabilityEnquiry
(
ctxt_pP
,
ue_context_p
);
/* else blocks are executed after receiving UE capability info */
}
else
if
(
ue_context_p
->
ue_context
.
n_initial_pdu
>
0
)
{
gNB_RRC_UE_t
*
UE
=
&
ue_context_p
->
ue_context
;
/* there were PDU sessions with the NG UE Context setup, but we had
* to set up security, so trigger PDU sessions now. The UE NAS
* message will be forwarded in the corresponding reconfiguration,
* the Initial context setup response after reconfiguration complete. */
trigger_bearer_setup
(
gnb_rrc_inst
,
UE
,
UE
->
n_initial_pdu
,
UE
->
initial_pdus
,
0
);
}
else
{
/* we already have capabilities, and no PDU sessions to setup, ack
* this UE */
rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP
(
ctxt_pP
,
ue_context_p
);
rrc_forward_ue_nas_message
(
RC
.
nrrrc
[
0
],
&
ue_context_p
->
ue_context
);
}
break
;
case
NR_UL_DCCH_MessageType__c1_PR_securityModeFailure
:
...
...
@@ -1900,6 +1748,7 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance
return
;
}
gNB_RRC_UE_t
*
UE
=
&
ue_context_p
->
ue_context
;
UE
->
f1_ue_context_active
=
true
;
NR_CellGroupConfig_t
*
cellGroupConfig
=
NULL
;
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
...
...
@@ -1918,13 +1767,14 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance
xer_fprint
(
stdout
,
&
asn_DEF_NR_CellGroupConfig
,
UE
->
masterCellGroup
);
if
(
resp
->
drbs_to_be_setup_length
>
0
)
{
AssertFatal
(
resp
->
srbs_to_be_setup_length
>
0
&&
resp
->
srbs_to_be_setup
[
0
].
srb_id
==
2
,
"logic bug: we set up DRBs, so need to have both SRB1&SRB2
\n
"
);
/* Note: we would ideally check that SRB2 is acked, but at least LiteOn DU
* seems buggy and does not ack, so simply check that locally we activated */
AssertFatal
(
UE
->
Srb
[
1
].
Active
&&
UE
->
Srb
[
2
].
Active
,
"SRBs 1 and 2 must be active during DRB Establishment"
);
e1_send_bearer_updates
(
rrc
,
UE
,
resp
->
drbs_to_be_setup_length
,
resp
->
drbs_to_be_setup
);
}
/* at this point, we don't have to do anything: the UE context setup request
* includes the Security Command, whose response will trigger the following
* messages (UE capability, to be specific) */
protocol_ctxt_t
ctxt
=
{.
rntiMaybeUEid
=
resp
->
gNB_CU_ue_id
,
.
module_id
=
instance
};
rrc_gNB_generate_dedicatedRRCReconfiguration
(
&
ctxt
,
ue_context_p
);
}
static
void
rrc_CU_process_ue_context_release_request
(
MessageDef
*
msg_p
)
...
...
@@ -1960,7 +1810,10 @@ void rrc_remove_ue(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p)
* are in E1, we also need to free the UE in the CU-CP, so call it twice to
* cover all cases */
nr_pdcp_remove_UE
(
UE
->
rrc_ue_id
);
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE
(
0
,
UE
->
rrc_ue_id
);
uint32_t
pdu_sessions
[
256
];
for
(
int
i
=
0
;
i
<
UE
->
nb_of_pdusessions
&&
i
<
256
;
++
i
)
pdu_sessions
[
i
]
=
UE
->
pduSession
[
i
].
param
.
pdusession_id
;
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE
(
0
,
UE
->
rrc_ue_id
,
UE
->
nb_of_pdusessions
,
pdu_sessions
);
LOG_I
(
NR_RRC
,
"removed UE CU UE ID %u/RNTI %04x
\n
"
,
UE
->
rrc_ue_id
,
UE
->
rnti
);
rrc_delete_ue_data
(
UE
);
rrc_gNB_remove_ue_context
(
rrc
,
ue_context_p
);
...
...
@@ -2069,7 +1922,6 @@ static void rrc_CU_process_ue_modification_required(MessageDef *msg_p)
/* trigger reconfiguration */
nr_rrc_reconfiguration_req
(
ue_context_p
,
&
ctxt
,
0
,
0
);
//rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p);
//rrc_gNB_generate_defaultRRCReconfiguration(&ctxt, ue_context_p);
return
;
}
LOG_W
(
RRC
,
...
...
@@ -2172,50 +2024,12 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
}
}
/* Instruction towards the DU for SRB2 configuration */
int
nb_srb
=
0
;
f1ap_srb_to_be_setup_t
srbs
[
1
]
=
{
0
};
if
(
UE
->
Srb
[
2
].
Active
==
0
)
{
activate_srb
(
UE
,
2
);
nb_srb
=
1
;
srbs
[
0
].
srb_id
=
2
;
srbs
[
0
].
lcid
=
2
;
}
if
(
!
UE
->
as_security_active
)
{
/* no AS security active, need to send UE context setup req with security
* command (and the bearers) */
protocol_ctxt_t
ctxt
=
{.
rntiMaybeUEid
=
UE
->
rrc_ue_id
};
rrc_gNB_generate_SecurityModeCommand
(
&
ctxt
,
ue_context_p
,
nb_drb
,
drbs
);
return
;
}
AssertFatal
(
UE
->
as_security_active
,
"logic bug: security should be active when activating DRBs
\n
"
);
/* Gather UE capability if present */
cu_to_du_rrc_information_t
cu2du
=
{
0
};
cu_to_du_rrc_information_t
*
cu2du_p
=
NULL
;
if
(
UE
->
ue_cap_buffer
.
len
>
0
&&
UE
->
ue_cap_buffer
.
buf
!=
NULL
)
{
cu2du_p
=
&
cu2du
;
cu2du
.
uE_CapabilityRAT_ContainerList
=
UE
->
ue_cap_buffer
.
buf
;
cu2du
.
uE_CapabilityRAT_ContainerList_length
=
UE
->
ue_cap_buffer
.
len
;
}
f1_ue_data_t
ue_data
=
cu_get_f1_ue_data
(
UE
->
rrc_ue_id
);
RETURN_IF_INVALID_ASSOC_ID
(
ue_data
);
f1ap_ue_context_modif_req_t
ue_context_modif_req
=
{
.
gNB_CU_ue_id
=
UE
->
rrc_ue_id
,
.
gNB_DU_ue_id
=
ue_data
.
secondary_ue
,
.
plmn
.
mcc
=
rrc
->
configuration
.
mcc
[
0
],
.
plmn
.
mnc
=
rrc
->
configuration
.
mnc
[
0
],
.
plmn
.
mnc_digit_length
=
rrc
->
configuration
.
mnc_digit_length
[
0
],
.
nr_cellid
=
rrc
->
nr_cellid
,
.
servCellId
=
0
,
/* TODO: correct value? */
.
srbs_to_be_setup_length
=
nb_srb
,
.
srbs_to_be_setup
=
srbs
,
.
drbs_to_be_setup_length
=
nb_drb
,
.
drbs_to_be_setup
=
drbs
,
.
cu_to_du_rrc_information
=
cu2du_p
,
};
rrc
->
mac_rrc
.
ue_context_modification_request
(
ue_data
.
du_assoc_id
,
&
ue_context_modif_req
);
if
(
!
UE
->
f1_ue_context_active
)
rrc_gNB_generate_UeContextSetupRequest
(
rrc
,
ue_context_p
,
nb_drb
,
drbs
);
else
rrc_gNB_generate_UeContextModificationRequest
(
rrc
,
ue_context_p
,
nb_drb
,
drbs
,
0
,
NULL
);
}
/**
...
...
@@ -2396,10 +2210,9 @@ void *rrc_gnb_task(void *args_p) {
break
;
case
TIMER_HAS_EXPIRED
:
if
(
TIMER_HAS_EXPIRED
(
msg_p
).
timer_id
==
stats_timer_id
)
/* only this one handled for now */
DevAssert
(
TIMER_HAS_EXPIRED
(
msg_p
).
timer_id
==
stats_timer_id
);
write_rrc_stats
(
RC
.
nrrrc
[
0
]);
else
itti_send_msg_to_task
(
TASK_RRC_GNB
,
0
,
TIMER_HAS_EXPIRED
(
msg_p
).
arg
);
/* see rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ() */
break
;
case
F1AP_INITIAL_UL_RRC_MESSAGE
:
...
...
@@ -2477,6 +2290,11 @@ void *rrc_gnb_task(void *args_p) {
rrc_CU_process_f1_lost_connection
(
RC
.
nrrrc
[
0
],
&
F1AP_LOST_CONNECTION
(
msg_p
),
msg_p
->
ittiMsgHeader
.
originInstance
);
break
;
case
F1AP_GNB_DU_CONFIGURATION_UPDATE
:
AssertFatal
(
!
NODE_IS_DU
(
RC
.
nrrrc
[
instance
]
->
node_type
),
"should not receive F1AP_SETUP_REQUEST in DU!
\n
"
);
rrc_gNB_process_f1_du_configuration_update
(
&
F1AP_GNB_DU_CONFIGURATION_UPDATE
(
msg_p
),
msg_p
->
ittiMsgHeader
.
originInstance
);
break
;
/* Messages from X2AP */
case
X2AP_ENDC_SGNB_ADDITION_REQ
:
LOG_I
(
NR_RRC
,
"Received ENDC sgNB addition request from X2AP
\n
"
);
...
...
@@ -2543,28 +2361,8 @@ void *rrc_gnb_task(void *args_p) {
}
}
typedef
struct
deliver_ue_ctxt_setup_data_t
{
gNB_RRC_INST
*
rrc
;
f1ap_ue_context_setup_t
*
setup_req
;
sctp_assoc_t
assoc_id
;
}
deliver_ue_ctxt_setup_data_t
;
static
void
rrc_deliver_ue_ctxt_setup_req
(
void
*
deliver_pdu_data
,
ue_id_t
ue_id
,
int
srb_id
,
char
*
buf
,
int
size
,
int
sdu_id
)
{
DevAssert
(
deliver_pdu_data
!=
NULL
);
deliver_ue_ctxt_setup_data_t
*
data
=
deliver_pdu_data
;
data
->
setup_req
->
rrc_container
=
(
uint8_t
*
)
buf
;
data
->
setup_req
->
rrc_container_length
=
size
;
data
->
rrc
->
mac_rrc
.
ue_context_setup_request
(
data
->
assoc_id
,
data
->
setup_req
);
}
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_SecurityModeCommand
(
const
protocol_ctxt_t
*
const
ctxt_pP
,
rrc_gNB_ue_context_t
*
const
ue_context_pP
,
int
n_drbs
,
const
f1ap_drb_to_be_setup_t
*
drbs
)
void
rrc_gNB_generate_SecurityModeCommand
(
const
protocol_ctxt_t
*
const
ctxt_pP
,
rrc_gNB_ue_context_t
*
const
ue_context_pP
)
//-----------------------------------------------------------------------------
{
uint8_t
buffer
[
100
];
...
...
@@ -2572,52 +2370,22 @@ rrc_gNB_generate_SecurityModeCommand(
gNB_RRC_UE_t
*
ue_p
=
&
ue_context_pP
->
ue_context
;
AssertFatal
(
!
ue_p
->
as_security_active
,
"logic error: security already active
\n
"
);
T
(
T_ENB_RRC_SECURITY_MODE_COMMAND
,
T_INT
(
ctxt_pP
->
module_id
),
T_INT
(
ctxt_pP
->
frame
),
T_INT
(
ctxt_pP
->
subframe
),
T_INT
(
ctxt_pP
->
rntiMaybeUEid
));
T
(
T_ENB_RRC_SECURITY_MODE_COMMAND
,
T_INT
(
ctxt_pP
->
module_id
),
T_INT
(
ctxt_pP
->
frame
),
T_INT
(
ctxt_pP
->
subframe
),
T_INT
(
ctxt_pP
->
rntiMaybeUEid
));
NR_IntegrityProtAlgorithm_t
integrity_algorithm
=
(
NR_IntegrityProtAlgorithm_t
)
ue_p
->
integrity_algorithm
;
size
=
do_NR_SecurityModeCommand
(
ctxt_pP
,
buffer
,
rrc_gNB_get_next_transaction_identifier
(
ctxt_pP
->
module_id
),
ue_p
->
ciphering_algorithm
,
integrity_algorithm
);
LOG_DUMPMSG
(
NR_RRC
,
DEBUG_RRC
,(
char
*
)
buffer
,
size
,
"[MSG] RRC Security Mode Command
\n
"
);
size
=
do_NR_SecurityModeCommand
(
ctxt_pP
,
buffer
,
rrc_gNB_get_next_transaction_identifier
(
ctxt_pP
->
module_id
),
ue_p
->
ciphering_algorithm
,
integrity_algorithm
);
LOG_DUMPMSG
(
NR_RRC
,
DEBUG_RRC
,
(
char
*
)
buffer
,
size
,
"[MSG] RRC Security Mode Command
\n
"
);
LOG_I
(
NR_RRC
,
"UE %u Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)
\n
"
,
ue_p
->
rrc_ue_id
,
size
);
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
ctxt_pP
->
module_id
];
AssertFatal
(
!
NODE_IS_DU
(
rrc
->
node_type
),
"illegal node type DU!
\n
"
);
cu_to_du_rrc_information_t
cu2du
=
{
0
};
cu_to_du_rrc_information_t
*
cu2du_p
=
NULL
;
if
(
ue_p
->
ue_cap_buffer
.
len
>
0
&&
ue_p
->
ue_cap_buffer
.
buf
!=
NULL
)
{
cu2du_p
=
&
cu2du
;
cu2du
.
uE_CapabilityRAT_ContainerList
=
ue_p
->
ue_cap_buffer
.
buf
;
cu2du
.
uE_CapabilityRAT_ContainerList_length
=
ue_p
->
ue_cap_buffer
.
len
;
}
int
nb_srb
=
0
;
f1ap_srb_to_be_setup_t
srb_buf
[
1
]
=
{
0
};
f1ap_srb_to_be_setup_t
*
srbs
=
0
;
if
(
n_drbs
>
0
)
{
nb_srb
=
1
;
srb_buf
[
0
].
srb_id
=
2
;
srb_buf
[
0
].
lcid
=
2
;
srbs
=
srb_buf
;
}
/* the callback will fill the UE context setup request and forward it */
f1_ue_data_t
ue_data
=
cu_get_f1_ue_data
(
ue_p
->
rrc_ue_id
);
RETURN_IF_INVALID_ASSOC_ID
(
ue_data
);
f1ap_ue_context_setup_t
ue_context_setup_req
=
{
.
gNB_CU_ue_id
=
ue_p
->
rrc_ue_id
,
.
gNB_DU_ue_id
=
ue_data
.
secondary_ue
,
.
plmn
.
mcc
=
rrc
->
configuration
.
mcc
[
0
],
.
plmn
.
mnc
=
rrc
->
configuration
.
mnc
[
0
],
.
plmn
.
mnc_digit_length
=
rrc
->
configuration
.
mnc_digit_length
[
0
],
.
nr_cellid
=
rrc
->
nr_cellid
,
.
servCellId
=
0
,
/* TODO: correct value? */
.
srbs_to_be_setup_length
=
nb_srb
,
.
srbs_to_be_setup
=
srbs
,
.
drbs_to_be_setup_length
=
n_drbs
,
.
drbs_to_be_setup
=
(
f1ap_drb_to_be_setup_t
*
)
drbs
,
.
cu_to_du_rrc_information
=
cu2du_p
,
};
deliver_ue_ctxt_setup_data_t
data
=
{.
rrc
=
rrc
,
.
setup_req
=
&
ue_context_setup_req
,
.
assoc_id
=
ue_data
.
du_assoc_id
};
nr_pdcp_data_req_srb
(
ctxt_pP
->
rntiMaybeUEid
,
DCCH
,
rrc_gNB_mui
++
,
size
,
buffer
,
rrc_deliver_ue_ctxt_setup_req
,
&
data
);
nr_rrc_transfer_protected_rrc_message
(
rrc
,
ue_p
,
DCCH
,
buffer
,
size
);
}
void
...
...
@@ -2780,3 +2548,94 @@ int rrc_gNB_generate_pcch_msg(sctp_assoc_t assoc_id, const NR_SIB1_t *sib1, uint
return
0
;
}
/* F1AP UE Context Management Procedures */
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_UeContextSetupRequest
(
const
gNB_RRC_INST
*
rrc
,
rrc_gNB_ue_context_t
*
const
ue_context_pP
,
int
n_drbs
,
const
f1ap_drb_to_be_setup_t
*
drbs
)
//-----------------------------------------------------------------------------
{
gNB_RRC_UE_t
*
ue_p
=
&
ue_context_pP
->
ue_context
;
AssertFatal
(
!
ue_p
->
f1_ue_context_active
,
"logic error: ue context already active
\n
"
);
AssertFatal
(
!
NODE_IS_DU
(
rrc
->
node_type
),
"illegal node type DU!
\n
"
);
cu_to_du_rrc_information_t
cu2du
=
{
0
};
cu_to_du_rrc_information_t
*
cu2du_p
=
NULL
;
if
(
ue_p
->
ue_cap_buffer
.
len
>
0
&&
ue_p
->
ue_cap_buffer
.
buf
!=
NULL
)
{
cu2du_p
=
&
cu2du
;
cu2du
.
uE_CapabilityRAT_ContainerList
=
ue_p
->
ue_cap_buffer
.
buf
;
cu2du
.
uE_CapabilityRAT_ContainerList_length
=
ue_p
->
ue_cap_buffer
.
len
;
}
int
nb_srb
=
1
;
f1ap_srb_to_be_setup_t
srbs
[
1
]
=
{{.
srb_id
=
2
,
.
lcid
=
2
}};
activate_srb
(
ue_p
,
2
);
/* the callback will fill the UE context setup request and forward it */
f1_ue_data_t
ue_data
=
cu_get_f1_ue_data
(
ue_p
->
rrc_ue_id
);
RETURN_IF_INVALID_ASSOC_ID
(
ue_data
);
f1ap_ue_context_setup_t
ue_context_setup_req
=
{
.
gNB_CU_ue_id
=
ue_p
->
rrc_ue_id
,
.
gNB_DU_ue_id
=
ue_data
.
secondary_ue
,
.
plmn
.
mcc
=
rrc
->
configuration
.
mcc
[
0
],
.
plmn
.
mnc
=
rrc
->
configuration
.
mnc
[
0
],
.
plmn
.
mnc_digit_length
=
rrc
->
configuration
.
mnc_digit_length
[
0
],
.
nr_cellid
=
rrc
->
nr_cellid
,
.
servCellId
=
0
,
/* TODO: correct value? */
.
srbs_to_be_setup_length
=
nb_srb
,
.
srbs_to_be_setup
=
srbs
,
.
drbs_to_be_setup_length
=
n_drbs
,
.
drbs_to_be_setup
=
(
f1ap_drb_to_be_setup_t
*
)
drbs
,
.
cu_to_du_rrc_information
=
cu2du_p
,
};
rrc
->
mac_rrc
.
ue_context_setup_request
(
ue_data
.
du_assoc_id
,
&
ue_context_setup_req
);
LOG_I
(
RRC
,
"UE %d trigger UE context setup request with %d DRBs
\n
"
,
ue_p
->
rrc_ue_id
,
n_drbs
);
}
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_UeContextModificationRequest
(
const
gNB_RRC_INST
*
rrc
,
rrc_gNB_ue_context_t
*
const
ue_context_pP
,
int
n_drbs
,
const
f1ap_drb_to_be_setup_t
*
drbs
,
int
n_rel_drbs
,
const
f1ap_drb_to_be_released_t
*
rel_drbs
)
//-----------------------------------------------------------------------------
{
gNB_RRC_UE_t
*
ue_p
=
&
ue_context_pP
->
ue_context
;
AssertFatal
(
ue_p
->
f1_ue_context_active
,
"logic error: calling ue context modification when context not established
\n
"
);
AssertFatal
(
ue_p
->
Srb
[
1
].
Active
&&
ue_p
->
Srb
[
2
].
Active
,
"SRBs should already be active
\n
"
);
AssertFatal
(
!
NODE_IS_DU
(
rrc
->
node_type
),
"illegal node type DU!
\n
"
);
cu_to_du_rrc_information_t
cu2du
=
{
0
};
cu_to_du_rrc_information_t
*
cu2du_p
=
NULL
;
if
(
ue_p
->
ue_cap_buffer
.
len
>
0
&&
ue_p
->
ue_cap_buffer
.
buf
!=
NULL
)
{
cu2du_p
=
&
cu2du
;
cu2du
.
uE_CapabilityRAT_ContainerList
=
ue_p
->
ue_cap_buffer
.
buf
;
cu2du
.
uE_CapabilityRAT_ContainerList_length
=
ue_p
->
ue_cap_buffer
.
len
;
}
f1_ue_data_t
ue_data
=
cu_get_f1_ue_data
(
ue_p
->
rrc_ue_id
);
RETURN_IF_INVALID_ASSOC_ID
(
ue_data
);
f1ap_ue_context_modif_req_t
ue_context_modif_req
=
{
.
gNB_CU_ue_id
=
ue_p
->
rrc_ue_id
,
.
gNB_DU_ue_id
=
ue_data
.
secondary_ue
,
.
plmn
.
mcc
=
rrc
->
configuration
.
mcc
[
0
],
.
plmn
.
mnc
=
rrc
->
configuration
.
mnc
[
0
],
.
plmn
.
mnc_digit_length
=
rrc
->
configuration
.
mnc_digit_length
[
0
],
.
nr_cellid
=
rrc
->
nr_cellid
,
.
servCellId
=
0
,
/* TODO: correct value? */
.
drbs_to_be_setup_length
=
n_drbs
,
.
drbs_to_be_setup
=
(
f1ap_drb_to_be_setup_t
*
)
drbs
,
.
drbs_to_be_released_length
=
n_rel_drbs
,
.
drbs_to_be_released
=
(
f1ap_drb_to_be_released_t
*
)
rel_drbs
,
.
cu_to_du_rrc_information
=
cu2du_p
,
};
rrc
->
mac_rrc
.
ue_context_modification_request
(
ue_data
.
du_assoc_id
,
&
ue_context_modif_req
);
LOG_I
(
RRC
,
"UE %d trigger UE context modification request with %d DRBs
\n
"
,
ue_p
->
rrc_ue_id
,
n_drbs
);
}
openair2/RRC/NR/rrc_gNB_NGAP.c
View file @
65d494fb
...
...
@@ -362,7 +362,7 @@ static int decodePDUSessionResourceSetup(pdusession_t *session)
return
0
;
}
static
void
trigger_bearer_setup
(
gNB_RRC_INST
*
rrc
,
gNB_RRC_UE_t
*
UE
,
int
n
,
pdusession_t
*
sessions
,
uint64_t
ueAggMaxBitRateDownlink
)
void
trigger_bearer_setup
(
gNB_RRC_INST
*
rrc
,
gNB_RRC_UE_t
*
UE
,
int
n
,
pdusession_t
*
sessions
,
uint64_t
ueAggMaxBitRateDownlink
)
{
e1ap_bearer_setup_req_t
bearer_req
=
{
0
};
...
...
@@ -493,18 +493,15 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
/* configure only integrity, ciphering comes after receiving SecurityModeComplete */
nr_rrc_pdcp_config_security
(
&
ctxt
,
ue_context_p
,
0
);
uint8_t
nb_pdusessions_tosetup
=
req
->
nb_of_pdusessions
;
/* if there are PDU sessions to setup, first send them to the CU-UP, then
* send the UE Context setup with Security commend. Else go to the security
* command directly. */
if
(
nb_pdusessions_tosetup
>
0
)
{
trigger_bearer_setup
(
RC
.
nrrrc
[
instance
],
UE
,
req
->
nb_of_pdusessions
,
req
->
pdusession_param
,
/*req->ueAggMaxBitRateDownlink*/
0
);
}
else
{
rrc_gNB_generate_SecurityModeCommand
(
&
ctxt
,
ue_context_p
,
0
,
NULL
);
rrc_gNB_generate_SecurityModeCommand
(
&
ctxt
,
ue_context_p
);
if
(
req
->
nb_of_pdusessions
>
0
)
{
/* if there are PDU sessions to setup, store them to be created once
* security (and UE capabilities) are received */
UE
->
n_initial_pdu
=
req
->
nb_of_pdusessions
;
UE
->
initial_pdus
=
calloc
(
UE
->
n_initial_pdu
,
sizeof
(
*
UE
->
initial_pdus
));
AssertFatal
(
UE
->
initial_pdus
!=
NULL
,
"out of memory
\n
"
);
for
(
int
i
=
0
;
i
<
UE
->
n_initial_pdu
;
++
i
)
UE
->
initial_pdus
[
i
]
=
req
->
pdusession_param
[
i
];
}
return
0
;
...
...
@@ -814,28 +811,6 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
return
;
}
/* \brief checks if any transaction is ongoing for any xid of this UE */
static
bool
transaction_ongoing
(
const
gNB_RRC_UE_t
*
UE
)
{
for
(
int
xid
=
0
;
xid
<
4
;
++
xid
)
if
(
UE
->
xids
[
xid
]
!=
RRC_ACTION_NONE
)
return
true
;
return
false
;
}
/* \brief delays the ongoing transaction (in msg_p) by setting a timer to wait
* 10ms; upon expiry, delivers to RRC, which sends the message to itself */
static
void
delay_transaction
(
MessageDef
*
msg_p
,
int
wait_us
)
{
MessageDef
*
new
=
itti_alloc_new_message
(
TASK_RRC_GNB
,
0
,
NGAP_PDUSESSION_SETUP_REQ
);
ngap_pdusession_setup_req_t
*
n
=
&
NGAP_PDUSESSION_SETUP_REQ
(
new
);
*
n
=
NGAP_PDUSESSION_SETUP_REQ
(
msg_p
);
int
instance
=
msg_p
->
ittiMsgHeader
.
originInstance
;
long
timer_id
;
timer_setup
(
0
,
wait_us
,
TASK_RRC_GNB
,
instance
,
TIMER_ONE_SHOT
,
new
,
&
timer_id
);
}
//------------------------------------------------------------------------------
void
rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ
(
MessageDef
*
msg_p
,
instance_t
instance
)
//------------------------------------------------------------------------------
...
...
@@ -861,24 +836,6 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
AssertFatal
(
UE
->
rrc_ue_id
==
msg
->
gNB_ue_ngap_id
,
"logic bug
\n
"
);
UE
->
amf_ue_ngap_id
=
msg
->
amf_ue_ngap_id
;
/* This is a hack. We observed that with some UEs, PDU session requests might
* come in quick succession, faster than the RRC reconfiguration for the PDU
* session requests can be carried out (UE is doing reconfig, and second PDU
* session request arrives). We don't have currently the means to "queue up"
* these transactions, which would probably involve some rework of the RRC.
* To still allow these requests to come in and succeed, we below check and delay transactions
* for 10ms. However, to not accidentally end up in infinite loops, the
* maximum number is capped on a per-UE basis as indicated in variable
* max_delays_pdu_session. */
if
(
UE
->
max_delays_pdu_session
>
0
&&
transaction_ongoing
(
UE
))
{
int
wait_us
=
10000
;
LOG_D
(
RRC
,
"UE %d: delay PDU session setup by %d us, pending %d retries
\n
"
,
UE
->
rrc_ue_id
,
wait_us
,
UE
->
max_delays_pdu_session
);
delay_transaction
(
msg_p
,
wait_us
);
UE
->
max_delays_pdu_session
--
;
return
;
}
trigger_bearer_setup
(
rrc
,
UE
,
msg
->
nb_pdusessions_tosetup
,
msg
->
pdusession_setup_params
,
msg
->
ueAggMaxBitRateDownlink
);
return
;
}
...
...
@@ -1207,13 +1164,10 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
if
(
ue_context_p
==
NULL
)
{
/* Can not associate this message to an UE index */
MessageDef
*
msg_complete_p
=
NULL
;
LOG_W
(
NR_RRC
,
"[gNB %ld] In NGAP_UE_CONTEXT_RELEASE_COMMAND: unknown UE from gNB_ue_ngap_id (%u)
\n
"
,
instance
,
gNB_ue_ngap_id
);
msg_complete_p
=
itti_alloc_new_message
(
TASK_RRC_GNB
,
0
,
NGAP_UE_CONTEXT_RELEASE_COMPLETE
);
NGAP_UE_CONTEXT_RELEASE_COMPLETE
(
msg_complete_p
).
gNB_ue_ngap_id
=
gNB_ue_ngap_id
;
itti_send_msg_to_task
(
TASK_NGAP
,
instance
,
msg_complete_p
);
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE
(
instance
,
gNB_ue_ngap_id
,
0
,
NULL
);
return
-
1
;
}
...
...
@@ -1249,11 +1203,17 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND(MessageDef *msg_p, instance_
return
0
;
}
void
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE
(
instance_t
instance
,
uint32_t
gNB_ue_ngap_id
)
{
void
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE
(
instance_t
instance
,
uint32_t
gNB_ue_ngap_id
,
int
num_pdu
,
uint32_t
pdu_session_id
[
256
])
{
MessageDef
*
msg
=
itti_alloc_new_message
(
TASK_RRC_GNB
,
0
,
NGAP_UE_CONTEXT_RELEASE_COMPLETE
);
NGAP_UE_CONTEXT_RELEASE_COMPLETE
(
msg
).
gNB_ue_ngap_id
=
gNB_ue_ngap_id
;
NGAP_UE_CONTEXT_RELEASE_COMPLETE
(
msg
).
num_pdu_sessions
=
num_pdu
;
for
(
int
i
=
0
;
i
<
num_pdu
;
++
i
)
NGAP_UE_CONTEXT_RELEASE_COMPLETE
(
msg
).
pdu_session_id
[
i
]
=
pdu_session_id
[
i
];
LOG_W
(
RRC
,
"trigger release with %d pdu
\n
"
,
num_pdu
);
itti_send_msg_to_task
(
TASK_NGAP
,
instance
,
msg
);
}
...
...
openair2/RRC/NR/rrc_gNB_NGAP.h
View file @
65d494fb
...
...
@@ -94,7 +94,10 @@ int rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_REQ(MessageDef *msg_p, instance_t in
int
rrc_gNB_process_NGAP_UE_CONTEXT_RELEASE_COMMAND
(
MessageDef
*
msg_p
,
instance_t
instance
);
void
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE
(
instance_t
instance
,
uint32_t
gNB_ue_ngap_id
);
void
rrc_gNB_send_NGAP_UE_CONTEXT_RELEASE_COMPLETE
(
instance_t
instance
,
uint32_t
gNB_ue_ngap_id
,
int
num_pdu
,
uint32_t
pdu_session_id
[
256
]);
void
rrc_gNB_send_NGAP_UE_CAPABILITIES_IND
(
const
protocol_ctxt_t
*
const
ctxt_pP
,
rrc_gNB_ue_context_t
*
const
ue_context_pP
,
...
...
openair2/RRC/NR/rrc_gNB_UE_context.c
View file @
65d494fb
...
...
@@ -202,7 +202,6 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(sctp_assoc_t assoc_id,
"UE F1 Context for ID %d already exists, logic bug
\n
"
,
ue
->
rrc_ue_id
);
cu_add_f1_ue_data
(
ue
->
rrc_ue_id
,
&
ue_data
);
ue
->
max_delays_pdu_session
=
20
;
/* see rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ() */
RB_INSERT
(
rrc_nr_ue_tree_s
,
&
rrc_instance_pP
->
rrc_ue_head
,
ue_context_p
);
LOG_I
(
NR_RRC
,
...
...
openair2/RRC/NR/rrc_gNB_du.c
View file @
65d494fb
...
...
@@ -49,6 +49,61 @@ static bool rrc_gNB_plmn_matches(const gNB_RRC_INST *rrc, const f1ap_served_cell
&&
conf
->
mnc
[
0
]
==
info
->
plmn
.
mnc
;
}
static
bool
extract_sys_info
(
const
f1ap_gnb_du_system_info_t
*
sys_info
,
NR_MIB_t
**
mib
,
NR_SIB1_t
**
sib1
)
{
DevAssert
(
sys_info
!=
NULL
);
DevAssert
(
mib
!=
NULL
);
DevAssert
(
sib1
!=
NULL
);
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
&
asn_DEF_NR_MIB
,
(
void
**
)
mib
,
sys_info
->
mib
,
sys_info
->
mib_length
);
if
(
dec_rval
.
code
!=
RC_OK
)
{
LOG_E
(
RRC
,
"Failed to decode NR_MIB (%zu bits) of DU
\n
"
,
dec_rval
.
consumed
);
ASN_STRUCT_FREE
(
asn_DEF_NR_MIB
,
*
mib
);
return
false
;
}
if
(
sys_info
->
sib1
)
{
dec_rval
=
uper_decode_complete
(
NULL
,
&
asn_DEF_NR_SIB1
,
(
void
**
)
sib1
,
sys_info
->
sib1
,
sys_info
->
sib1_length
);
if
(
dec_rval
.
code
!=
RC_OK
)
{
ASN_STRUCT_FREE
(
asn_DEF_NR_MIB
,
*
mib
);
ASN_STRUCT_FREE
(
asn_DEF_NR_SIB1
,
*
sib1
);
LOG_E
(
RRC
,
"Failed to decode NR_SIB1 (%zu bits), rejecting DU
\n
"
,
dec_rval
.
consumed
);
return
false
;
}
}
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
{
xer_fprint
(
stdout
,
&
asn_DEF_NR_MIB
,
*
mib
);
xer_fprint
(
stdout
,
&
asn_DEF_NR_SIB1
,
*
sib1
);
}
return
true
;
}
static
NR_MeasurementTimingConfiguration_t
*
extract_mtc
(
uint8_t
*
buf
,
int
buf_len
)
{
NR_MeasurementTimingConfiguration_t
*
mtc
=
NULL
;
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
&
asn_DEF_NR_MeasurementTimingConfiguration
,
(
void
**
)
&
mtc
,
buf
,
buf_len
);
if
(
dec_rval
.
code
!=
RC_OK
)
{
ASN_STRUCT_FREE
(
asn_DEF_NR_MeasurementTimingConfiguration
,
mtc
);
return
NULL
;
}
/* verify that it has the format we need */
if
(
mtc
->
criticalExtensions
.
present
!=
NR_MeasurementTimingConfiguration__criticalExtensions_PR_c1
||
mtc
->
criticalExtensions
.
choice
.
c1
==
NULL
||
mtc
->
criticalExtensions
.
choice
.
c1
->
present
!=
NR_MeasurementTimingConfiguration__criticalExtensions__c1_PR_measTimingConf
||
mtc
->
criticalExtensions
.
choice
.
c1
->
choice
.
measTimingConf
==
NULL
||
mtc
->
criticalExtensions
.
choice
.
c1
->
choice
.
measTimingConf
->
measTiming
==
NULL
||
mtc
->
criticalExtensions
.
choice
.
c1
->
choice
.
measTimingConf
->
measTiming
->
list
.
count
==
0
)
{
LOG_E
(
RRC
,
"error: measurementTimingConfiguration does not have expected format (at least one measTiming entry
\n
"
);
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
xer_fprint
(
stdout
,
&
asn_DEF_NR_MeasurementTimingConfiguration
,
mtc
);
ASN_STRUCT_FREE
(
asn_DEF_NR_MeasurementTimingConfiguration
,
mtc
);
return
NULL
;
}
return
mtc
;
}
void
rrc_gNB_process_f1_setup_req
(
f1ap_setup_req_t
*
req
,
sctp_assoc_t
assoc_id
)
{
AssertFatal
(
assoc_id
!=
0
,
"illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)
\n
"
);
...
...
@@ -111,35 +166,23 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
}
}
// if there is no system info or no SIB1 and we run in SA mode, we cannot handle it
// MTC is mandatory, but some DUs don't send it in the F1 Setup Request, so
// "tolerate" this behavior, despite it being mandatory
NR_MeasurementTimingConfiguration_t
*
mtc
=
extract_mtc
(
cell_info
->
measurement_timing_config
,
cell_info
->
measurement_timing_config_len
);
const
f1ap_gnb_du_system_info_t
*
sys_info
=
req
->
cell
[
0
].
sys_info
;
NR_
BCCH_BCH_Message
_t
*
mib
=
NULL
;
NR_
MIB
_t
*
mib
=
NULL
;
NR_SIB1_t
*
sib1
=
NULL
;
if
(
sys_info
!=
NULL
&&
sys_info
->
mib
!=
NULL
&&
!
(
sys_info
->
sib1
==
NULL
&&
get_softmodem_params
()
->
sa
))
{
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
&
asn_DEF_NR_BCCH_BCH_Message
,
(
void
**
)
&
mib
,
sys_info
->
mib
,
sys_info
->
mib_length
);
if
(
dec_rval
.
code
!=
RC_OK
||
mib
->
message
.
present
!=
NR_BCCH_BCH_MessageType_PR_mib
||
mib
->
message
.
choice
.
messageClassExtension
==
NULL
)
{
LOG_E
(
RRC
,
"Failed to decode NR_BCCH_BCH_MESSAGE (%zu bits) of DU, rejecting DU
\n
"
,
dec_rval
.
consumed
);
if
(
!
extract_sys_info
(
sys_info
,
&
mib
,
&
sib1
))
{
LOG_W
(
RRC
,
"rejecting DU ID %ld
\n
"
,
req
->
gNB_DU_id
);
f1ap_setup_failure_t
fail
=
{.
cause
=
F1AP_CauseProtocol_semantic_error
};
rrc
->
mac_rrc
.
f1_setup_failure
(
assoc_id
,
&
fail
);
ASN_STRUCT_FREE
(
asn_DEF_NR_
BCCH_BCH_Message
,
mib
);
ASN_STRUCT_FREE
(
asn_DEF_NR_
MeasurementTimingConfiguration
,
mtc
);
return
;
}
if
(
sys_info
->
sib1
)
{
dec_rval
=
uper_decode_complete
(
NULL
,
&
asn_DEF_NR_SIB1
,
(
void
**
)
&
sib1
,
sys_info
->
sib1
,
sys_info
->
sib1_length
);
if
(
dec_rval
.
code
!=
RC_OK
)
{
LOG_E
(
RRC
,
"Failed to decode NR_SIB1 (%zu bits) of DU, rejecting DU
\n
"
,
dec_rval
.
consumed
);
f1ap_setup_failure_t
fail
=
{.
cause
=
F1AP_CauseProtocol_semantic_error
};
rrc
->
mac_rrc
.
f1_setup_failure
(
assoc_id
,
&
fail
);
ASN_STRUCT_FREE
(
asn_DEF_NR_SIB1
,
sib1
);
return
;
}
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
xer_fprint
(
stdout
,
&
asn_DEF_NR_SIB1
,
sib1
);
}
}
LOG_I
(
RRC
,
"Accepting DU %ld (%s), sending F1 Setup Response
\n
"
,
req
->
gNB_DU_id
,
req
->
gNB_DU_name
);
LOG_I
(
RRC
,
"DU uses RRC version %u.%u.%u
\n
"
,
req
->
rrc_ver
[
0
],
req
->
rrc_ver
[
1
],
req
->
rrc_ver
[
2
]);
...
...
@@ -155,12 +198,10 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
du
->
setup_req
=
calloc
(
1
,
sizeof
(
*
du
->
setup_req
));
AssertFatal
(
du
->
setup_req
,
"out of memory
\n
"
);
*
du
->
setup_req
=
*
req
;
if
(
mib
!=
NULL
&&
sib1
!=
NULL
)
{
du
->
mib
=
mib
->
message
.
choice
.
mib
;
mib
->
message
.
choice
.
mib
=
NULL
;
ASN_STRUCT_FREE
(
asn_DEF_NR_BCCH_BCH_MessageType
,
mib
);
// MIB can be null and configured later via DU Configuration Update
du
->
mib
=
mib
;
du
->
sib1
=
sib1
;
}
du
->
mtc
=
mtc
;
RB_INSERT
(
rrc_du_tree
,
&
rrc
->
dus
,
du
);
rrc
->
num_dus
++
;
...
...
@@ -179,28 +220,6 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
if
(
rrc
->
node_name
!=
NULL
)
resp
.
gNB_CU_name
=
strdup
(
rrc
->
node_name
);
rrc
->
mac_rrc
.
f1_setup_response
(
assoc_id
,
&
resp
);
/*
MessageDef *msg_p2 = itti_alloc_new_message(TASK_RRC_GNB, 0, F1AP_GNB_CU_CONFIGURATION_UPDATE);
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).gNB_CU_name = rrc->node_name;
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mcc = rrc->configuration.mcc[0];
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc = rrc->configuration.mnc[0];
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0];
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nr_cellid = rrc->nr_cellid;
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].nrpci = req->cell[0].info.nr_pci;
int num_SI = 0;
if (rrc->carrier.SIB23) {
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container[2] = rrc->carrier.SIB23;
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].SI_container_length[2] = rrc->carrier.sizeof_SIB23;
num_SI++;
}
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).cells_to_activate[0].num_SI = num_SI;
F1AP_GNB_CU_CONFIGURATION_UPDATE(msg_p2).num_cells_to_activate = 1;
// send
itti_send_msg_to_task(TASK_CU_F1, 0, msg_p2);
*/
}
static
int
invalidate_du_connections
(
gNB_RRC_INST
*
rrc
,
sctp_assoc_t
assoc_id
)
...
...
@@ -226,6 +245,107 @@ static int invalidate_du_connections(gNB_RRC_INST *rrc, sctp_assoc_t assoc_id)
return
count
;
}
static
void
update_cell_info
(
nr_rrc_du_container_t
*
du
,
const
f1ap_served_cell_info_t
*
new_ci
)
{
DevAssert
(
du
!=
NULL
);
DevAssert
(
new_ci
!=
NULL
);
AssertFatal
(
du
->
setup_req
->
num_cells_available
==
1
,
"expected 1 cell for DU, but has %d
\n
"
,
du
->
setup_req
->
num_cells_available
);
f1ap_served_cell_info_t
*
ci
=
&
du
->
setup_req
->
cell
[
0
].
info
;
ci
->
nr_cellid
=
new_ci
->
nr_cellid
;
ci
->
nr_pci
=
new_ci
->
nr_pci
;
if
(
new_ci
->
tac
!=
NULL
)
*
ci
->
tac
=
*
new_ci
->
tac
;
ci
->
num_ssi
=
new_ci
->
num_ssi
;
for
(
int
s
=
0
;
s
<
new_ci
->
num_ssi
;
++
s
)
ci
->
nssai
[
s
]
=
new_ci
->
nssai
[
s
];
ci
->
mode
=
new_ci
->
mode
;
if
(
ci
->
mode
==
F1AP_MODE_TDD
)
ci
->
tdd
=
new_ci
->
tdd
;
else
ci
->
fdd
=
new_ci
->
fdd
;
NR_MeasurementTimingConfiguration_t
*
new_mtc
=
extract_mtc
(
new_ci
->
measurement_timing_config
,
new_ci
->
measurement_timing_config_len
);
if
(
new_mtc
!=
NULL
)
{
ASN_STRUCT_FREE
(
asn_DEF_NR_MeasurementTimingConfiguration
,
du
->
mtc
);
du
->
mtc
=
new_mtc
;
}
else
{
LOG_E
(
RRC
,
"error decoding MeasurementTimingConfiguration during cell update, ignoring new config
\n
"
);
ASN_STRUCT_FREE
(
asn_DEF_NR_MeasurementTimingConfiguration
,
new_mtc
);
}
}
void
rrc_gNB_process_f1_du_configuration_update
(
f1ap_gnb_du_configuration_update_t
*
conf_up
,
sctp_assoc_t
assoc_id
)
{
AssertFatal
(
assoc_id
!=
0
,
"illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)
\n
"
);
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
0
];
DevAssert
(
rrc
);
// check:
// - it is one cell
// - PLMN and Cell ID matches
// - no previous DU with the same ID
// else reject
nr_rrc_du_container_t
*
du
=
get_du_by_assoc_id
(
rrc
,
assoc_id
);
AssertError
(
du
!=
NULL
,
return
,
"no DU found for assoc_id %d
\n
"
,
assoc_id
);
const
f1ap_served_cell_info_t
*
info
=
&
du
->
setup_req
->
cell
[
0
].
info
;
if
(
conf_up
->
num_cells_to_add
>
0
)
{
// Here we check if the number of cell limit is respectet, otherwise send failure
LOG_W
(
RRC
,
"du_configuration_update->cells_to_add_list is not supported yet"
);
}
if
(
conf_up
->
num_cells_to_modify
>
0
)
{
// here the old nrcgi is used to find the cell information, if it exist then we modify consequently otherwise we fail
AssertFatal
(
conf_up
->
num_cells_to_modify
==
1
,
"cannot handle more than one cell!
\n
"
);
if
(
info
->
nr_cellid
!=
conf_up
->
cell_to_modify
[
0
].
old_nr_cellid
)
{
LOG_W
(
RRC
,
"no cell with ID %ld found, ignoring gNB-DU configuration update
\n
"
,
conf_up
->
cell_to_modify
[
0
].
old_nr_cellid
);
return
;
}
// verify the new plmn of the cell
if
(
!
rrc_gNB_plmn_matches
(
rrc
,
&
conf_up
->
cell_to_modify
[
0
].
info
))
{
LOG_W
(
RRC
,
"PLMN does not match, ignoring gNB-DU configuration update
\n
"
);
return
;
}
update_cell_info
(
du
,
&
conf_up
->
cell_to_modify
[
0
].
info
);
const
f1ap_gnb_du_system_info_t
*
sys_info
=
conf_up
->
cell_to_modify
[
0
].
sys_info
;
if
(
sys_info
!=
NULL
&&
sys_info
->
mib
!=
NULL
&&
!
(
sys_info
->
sib1
==
NULL
&&
get_softmodem_params
()
->
sa
))
{
// MIB is mandatory, so will be overwritten. SIB1 is optional, so will
// only be overwritten if present in sys_info
ASN_STRUCT_FREE
(
asn_DEF_NR_MIB
,
du
->
mib
);
if
(
sys_info
->
sib1
!=
NULL
)
ASN_STRUCT_FREE
(
asn_DEF_NR_SIB1
,
du
->
sib1
);
NR_MIB_t
*
mib
=
NULL
;
if
(
!
extract_sys_info
(
sys_info
,
&
mib
,
&
du
->
sib1
))
{
LOG_W
(
RRC
,
"cannot update sys_info for DU %ld
\n
"
,
du
->
setup_req
->
gNB_DU_id
);
}
else
{
DevAssert
(
mib
!=
NULL
);
du
->
mib
=
mib
;
LOG_I
(
RRC
,
"update system information of DU %ld
\n
"
,
du
->
setup_req
->
gNB_DU_id
);
}
}
}
if
(
conf_up
->
num_cells_to_delete
>
0
)
{
// delete the cell and send cell to desactive IE in the response.
LOG_W
(
RRC
,
"du_configuration_update->cells_to_delete_list is not supported yet"
);
}
/* Send DU Configuration Acknowledgement */
f1ap_gnb_du_configuration_update_acknowledge_t
ack
=
{.
transaction_id
=
conf_up
->
transaction_id
};
rrc
->
mac_rrc
.
gnb_du_configuration_update_acknowledge
(
assoc_id
,
&
ack
);
}
void
rrc_CU_process_f1_lost_connection
(
gNB_RRC_INST
*
rrc
,
f1ap_lost_connection_t
*
lc
,
sctp_assoc_t
assoc_id
)
{
AssertFatal
(
assoc_id
!=
0
,
"illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)
\n
"
);
...
...
@@ -242,6 +362,7 @@ void rrc_CU_process_f1_lost_connection(gNB_RRC_INST *rrc, f1ap_lost_connection_t
LOG_I
(
RRC
,
"releasing DU ID %ld (%s) on assoc_id %d
\n
"
,
req
->
gNB_DU_id
,
req
->
gNB_DU_name
,
assoc_id
);
ASN_STRUCT_FREE
(
asn_DEF_NR_MIB
,
du
->
mib
);
ASN_STRUCT_FREE
(
asn_DEF_NR_SIB1
,
du
->
sib1
);
ASN_STRUCT_FREE
(
asn_DEF_NR_MeasurementTimingConfiguration
,
du
->
mtc
);
/* TODO: free setup request */
nr_rrc_du_container_t
*
removed
=
RB_REMOVE
(
rrc_du_tree
,
&
rrc
->
dus
,
du
);
DevAssert
(
removed
!=
NULL
);
...
...
@@ -281,5 +402,18 @@ void dump_du_info(const gNB_RRC_INST *rrc, FILE *f)
}
const
f1ap_served_cell_info_t
*
info
=
&
sr
->
cell
[
0
].
info
;
fprintf
(
f
,
": nrCellID %ld, PCI %d
\n
"
,
info
->
nr_cellid
,
info
->
nr_pci
);
if
(
info
->
mode
==
F1AP_MODE_TDD
)
{
const
f1ap_nr_frequency_info_t
*
fi
=
&
info
->
tdd
.
freqinfo
;
const
f1ap_transmission_bandwidth_t
*
tb
=
&
info
->
tdd
.
tbw
;
fprintf
(
f
,
" TDD: band %d ARFCN %d SCS %d (kHz) PRB %d
\n
"
,
fi
->
band
,
fi
->
arfcn
,
15
*
(
1
<<
tb
->
scs
),
tb
->
nrb
);
}
else
{
const
f1ap_nr_frequency_info_t
*
dfi
=
&
info
->
fdd
.
dl_freqinfo
;
const
f1ap_transmission_bandwidth_t
*
dtb
=
&
info
->
fdd
.
dl_tbw
;
fprintf
(
f
,
" FDD: DL band %d ARFCN %d SCS %d (kHz) PRB %d
\n
"
,
dfi
->
band
,
dfi
->
arfcn
,
15
*
(
1
<<
dtb
->
scs
),
dtb
->
nrb
);
const
f1ap_nr_frequency_info_t
*
ufi
=
&
info
->
fdd
.
ul_freqinfo
;
const
f1ap_transmission_bandwidth_t
*
utb
=
&
info
->
fdd
.
ul_tbw
;
fprintf
(
f
,
" UL band %d ARFCN %d SCS %d (kHz) PRB %d
\n
"
,
ufi
->
band
,
ufi
->
arfcn
,
15
*
(
1
<<
utb
->
scs
),
utb
->
nrb
);
}
}
}
openair2/RRC/NR/rrc_gNB_du.h
View file @
65d494fb
...
...
@@ -31,9 +31,11 @@ struct f1ap_setup_req_s;
struct
f1ap_lost_connection_t
;
struct
gNB_RRC_INST_s
;
struct
nr_rrc_du_container_t
;
struct
f1ap_gnb_du_configuration_update_s
;
void
rrc_gNB_process_f1_setup_req
(
struct
f1ap_setup_req_s
*
req
,
sctp_assoc_t
assoc_id
);
void
rrc_CU_process_f1_lost_connection
(
struct
gNB_RRC_INST_s
*
rrc
,
struct
f1ap_lost_connection_t
*
lc
,
sctp_assoc_t
assoc_id
);
void
rrc_gNB_process_f1_du_configuration_update
(
struct
f1ap_gnb_du_configuration_update_s
*
conf_up
,
sctp_assoc_t
assoc_id
);
struct
nr_rrc_du_container_t
*
get_du_for_ue
(
struct
gNB_RRC_INST_s
*
rrc
,
uint32_t
ue_id
);
struct
nr_rrc_du_container_t
*
get_du_by_assoc_id
(
struct
gNB_RRC_INST_s
*
rrc
,
sctp_assoc_t
assoc_id
);
...
...
openair3/NGAP/ngap_gNB_context_management_procedures.c
View file @
65d494fb
...
...
@@ -50,7 +50,7 @@
#include "ngap_gNB_management_procedures.h"
#include "ngap_gNB_context_management_procedures.h"
#include "NGAP_PDUSessionResourceItemCxtRelReq.h"
#include "NGAP_PDUSessionResourceItemCxtRelCpl.h"
int
ngap_ue_context_release_complete
(
instance_t
instance
,
ngap_ue_release_complete_t
*
ue_release_complete_p
)
...
...
@@ -100,6 +100,20 @@ int ngap_ue_context_release_complete(instance_t instance,
ie
->
value
.
choice
.
RAN_UE_NGAP_ID
=
ue_release_complete_p
->
gNB_ue_ngap_id
;
}
/* number of PDU sessions */
if
(
ue_release_complete_p
->
num_pdu_sessions
>
0
)
{
asn1cSequenceAdd
(
out
->
protocolIEs
.
list
,
NGAP_UEContextReleaseComplete_IEs_t
,
ie
);
ie
->
id
=
NGAP_ProtocolIE_ID_id_PDUSessionResourceListCxtRelCpl
;
ie
->
criticality
=
NGAP_Criticality_reject
;
ie
->
value
.
present
=
NGAP_UEContextReleaseComplete_IEs__value_PR_PDUSessionResourceListCxtRelCpl
;
NGAP_PDUSessionResourceListCxtRelCpl_t
*
l
=
&
ie
->
value
.
choice
.
PDUSessionResourceListCxtRelCpl
;
DevAssert
(
ue_release_complete_p
->
num_pdu_sessions
<=
256
);
for
(
int
i
=
0
;
i
<
ue_release_complete_p
->
num_pdu_sessions
;
++
i
)
{
asn1cSequenceAdd
(
l
->
list
,
NGAP_PDUSessionResourceItemCxtRelCpl_t
,
pdu
);
pdu
->
pDUSessionID
=
ue_release_complete_p
->
pdu_session_id
[
i
];
}
}
if
(
ngap_gNB_encode_pdu
(
&
pdu
,
&
buffer
,
&
length
)
<
0
)
{
/* Encode procedure has failed... */
NGAP_ERROR
(
"Failed to encode UE context release complete
\n
"
);
...
...
openair3/UTILS/conversions.h
View file @
65d494fb
...
...
@@ -192,16 +192,20 @@ do { \
#define AMF_SETID_TO_BIT_STRING(x, aSN) \
do { \
INT16_TO_OCTET_STRING(x, aSN); \
(aSN)->buf = calloc(2, sizeof(uint8_t)); \
(aSN)->buf[0] = ((x) >> 2) & 0xff; \
(aSN)->buf[1] = ((x) & 0x03) << 6; \
(aSN)->size = 2; \
(aSN)->bits_unused = 6; \
} while
(0)
} while
(0)
#define AMF_POINTER_TO_BIT_STRING(x, aSN) \
do { \
INT8_TO_OCTET_STRING(x, aSN); \
(aSN)->buf = calloc(1, sizeof(uint8_t)); \
(aSN)->buf[0] = ((x) & 0x3f) << 2; \
(aSN)->size = 1; \
(aSN)->bits_unused = 2; \
} while(0)
} while (0)
#define ENCRALG_TO_BIT_STRING(encralg, bitstring) \
do { \
...
...
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