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
zzha zzha
OpenXG-RAN
Commits
6ced3cd8
Commit
6ced3cd8
authored
Apr 12, 2023
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implementation for F1 UE Context Setup+Response in monolithic
parent
10b996f5
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
186 additions
and
346 deletions
+186
-346
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
+118
-8
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c
+26
-1
openair2/RRC/NR/rrc_gNB.c
openair2/RRC/NR/rrc_gNB.c
+42
-337
No files found.
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
View file @
6ced3cd8
...
...
@@ -19,22 +19,132 @@
* contact@openairinterface.org
*/
#include <stdlib.h>
#include "mac_rrc_dl_handler.h"
#include "mac_proto.h"
#include "openair2/RRC/NR/rrc_gNB_UE_context.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "openair2/RRC/NR/MESSAGES/asn1_msg.h"
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
e_NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration
bucket
=
NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5
;
return
get_SRB_RLC_BearerConfig
(
srb
->
srb_id
,
priority
,
bucket
);
}
static
void
handle_ue_context_srbs_setup
(
const
f1ap_ue_context_setup_t
*
req
,
f1ap_ue_context_setup_t
*
resp
,
NR_CellGroupConfig_t
*
cellGroupConfig
)
{
DevAssert
(
req
!=
NULL
&&
resp
!=
NULL
&&
cellGroupConfig
!=
NULL
);
resp
->
srbs_to_be_setup_length
=
req
->
srbs_to_be_setup_length
;
resp
->
srbs_to_be_setup
=
calloc
(
req
->
srbs_to_be_setup_length
,
sizeof
(
*
resp
->
srbs_to_be_setup
));
AssertFatal
(
resp
->
srbs_to_be_setup
!=
NULL
,
"out of memory
\n
"
);
for
(
int
i
=
0
;
i
<
req
->
srbs_to_be_setup_length
;
i
++
)
{
f1ap_srb_to_be_setup_t
*
srb
=
&
req
->
srbs_to_be_setup
[
i
];
NR_RLC_BearerConfig_t
*
rlc_BearerConfig
=
get_bearerconfig_from_srb
(
srb
);
nr_rlc_add_srb
(
req
->
rnti
,
srb
->
srb_id
,
rlc_BearerConfig
);
resp
->
srbs_to_be_setup
[
i
]
=
*
srb
;
int
ret
=
ASN_SEQUENCE_ADD
(
&
cellGroupConfig
->
rlc_BearerToAddModList
->
list
,
rlc_BearerConfig
);
DevAssert
(
ret
==
0
);
}
}
static
NR_RLC_BearerConfig_t
*
get_bearerconfig_from_drb
(
const
f1ap_drb_to_be_setup_t
*
drb
)
{
const
NR_RLC_Config_PR
rlc_conf
=
drb
->
rlc_mode
==
RLC_MODE_UM
?
NR_RLC_Config_PR_um_Bi_Directional
:
NR_RLC_Config_PR_am
;
long
priority
=
13
;
// hardcoded for the moment
return
get_DRB_RLC_BearerConfig
(
3
+
drb
->
drb_id
,
drb
->
drb_id
,
rlc_conf
,
priority
);
}
static
void
handle_ue_context_drbs_setup
(
const
f1ap_ue_context_setup_t
*
req
,
f1ap_ue_context_setup_t
*
resp
,
NR_CellGroupConfig_t
*
cellGroupConfig
)
{
DevAssert
(
req
!=
NULL
&&
resp
!=
NULL
&&
cellGroupConfig
!=
NULL
);
#include "NR_RRCSetup.h"
#include "NR_DL-CCCH-Message.h"
#include "NR_CellGroupConfig.h"
/* Note: the actual GTP tunnels are created in the F1AP breanch of
* ue_context_*_response() */
resp
->
drbs_to_be_setup_length
=
req
->
drbs_to_be_setup_length
;
resp
->
drbs_to_be_setup
=
calloc
(
req
->
drbs_to_be_setup_length
,
sizeof
(
*
resp
->
drbs_to_be_setup
));
AssertFatal
(
resp
->
drbs_to_be_setup
!=
NULL
,
"out of memory
\n
"
);
for
(
int
i
=
0
;
i
<
req
->
drbs_to_be_setup_length
;
i
++
)
{
f1ap_drb_to_be_setup_t
*
drb
=
&
req
->
drbs_to_be_setup
[
i
];
NR_RLC_BearerConfig_t
*
rlc_BearerConfig
=
get_bearerconfig_from_drb
(
drb
);
nr_rlc_add_drb
(
req
->
rnti
,
drb
->
drb_id
,
rlc_BearerConfig
);
resp
->
drbs_to_be_setup
[
i
]
=
*
drb
;
int
ret
=
ASN_SEQUENCE_ADD
(
&
cellGroupConfig
->
rlc_BearerToAddModList
->
list
,
rlc_BearerConfig
);
DevAssert
(
ret
==
0
);
}
}
void
ue_context_setup_request
(
const
f1ap_ue_context_setup_t
*
req
)
{
(
void
)
req
;
abort
();
gNB_MAC_INST
*
mac
=
RC
.
nrmac
[
0
];
/* response has same type as request... */
f1ap_ue_context_setup_t
resp
=
{
.
gNB_CU_ue_id
=
req
->
gNB_CU_ue_id
,
.
gNB_DU_ue_id
=
req
->
gNB_DU_ue_id
,
.
rnti
=
req
->
rnti
,
};
if
(
req
->
cu_to_du_rrc_information
!=
NULL
)
{
AssertFatal
(
req
->
cu_to_du_rrc_information
->
cG_ConfigInfo
==
NULL
,
"CG-ConfigInfo not handled
\n
"
);
AssertFatal
(
req
->
cu_to_du_rrc_information
->
uE_CapabilityRAT_ContainerList
==
NULL
,
"UE capabilities not handled yet
\n
"
);
AssertFatal
(
req
->
cu_to_du_rrc_information
->
measConfig
==
NULL
,
"MeasConfig not handled
\n
"
);
}
NR_SCHED_LOCK
(
&
mac
->
sched_lock
);
NR_UE_info_t
*
UE
=
find_nr_UE
(
&
RC
.
nrmac
[
0
]
->
UE_info
,
req
->
rnti
);
AssertFatal
(
UE
!=
NULL
,
"did not find UE with RNTI %04x, but UE Context Setup Failed not implemented
\n
"
,
UE
->
rnti
);
if
(
req
->
srbs_to_be_setup_length
>
0
)
handle_ue_context_srbs_setup
(
req
,
&
resp
,
UE
->
CellGroup
);
if
(
req
->
drbs_to_be_setup_length
>
0
)
{
handle_ue_context_drbs_setup
(
req
,
&
resp
,
NULL
);
}
if
(
req
->
rrc_container
!=
NULL
)
nr_rlc_srb_recv_sdu
(
req
->
rnti
,
DCCH
,
req
->
rrc_container
,
req
->
rrc_container_length
);
//nr_mac_update_cellgroup()
resp
.
du_to_cu_rrc_information
=
calloc
(
1
,
sizeof
(
du_to_cu_rrc_information_t
));
AssertFatal
(
resp
.
du_to_cu_rrc_information
!=
NULL
,
"out of memory
\n
"
);
resp
.
du_to_cu_rrc_information
->
cellGroupConfig
=
calloc
(
1
,
1024
);
AssertFatal
(
resp
.
du_to_cu_rrc_information
->
cellGroupConfig
!=
NULL
,
"out of memory
\n
"
);
asn_enc_rval_t
enc_rval
=
uper_encode_to_buffer
(
&
asn_DEF_NR_CellGroupConfig
,
NULL
,
UE
->
CellGroup
,
resp
.
du_to_cu_rrc_information
->
cellGroupConfig
,
1024
);
AssertFatal
(
enc_rval
.
encoded
>
0
,
"Could not encode CellGroup, failed element %s
\n
"
,
enc_rval
.
failed_type
->
name
);
resp
.
du_to_cu_rrc_information
->
cellGroupConfig_length
=
(
enc_rval
.
encoded
+
7
)
>>
3
;
/* TODO: need to apply after UE context reconfiguration confirmed? */
process_CellGroup
(
UE
->
CellGroup
,
&
UE
->
UE_sched_ctrl
);
NR_SCHED_UNLOCK
(
&
mac
->
sched_lock
);
/* some sanity checks, since we use the same type for request and response */
DevAssert
(
resp
.
cu_to_du_rrc_information
==
NULL
);
DevAssert
(
resp
.
du_to_cu_rrc_information
!=
NULL
);
DevAssert
(
resp
.
rrc_container
==
NULL
&&
resp
.
rrc_container_length
==
0
);
mac
->
mac_rrc
.
ue_context_setup_response
(
req
,
&
resp
);
/* free the memory we allocated above */
free
(
resp
.
srbs_to_be_setup
);
free
(
resp
.
drbs_to_be_setup
);
free
(
resp
.
du_to_cu_rrc_information
->
cellGroupConfig
);
free
(
resp
.
du_to_cu_rrc_information
);
}
int
dl_rrc_message
(
module_id_t
module_id
,
const
f1ap_dl_rrc_message_t
*
dl_rrc
)
...
...
openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_direct.c
View file @
6ced3cd8
...
...
@@ -26,8 +26,33 @@
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
);
AssertFatal
(
req
->
drbs_to_be_setup_length
==
0
,
"not implemented
\n
"
);
(
void
)
req
;
/* we don't need the request -- it is to set up GTP in F1 case */
AssertFatal
(
false
,
"not implemented
\n
"
);
MessageDef
*
msg
=
itti_alloc_new_message
(
TASK_MAC_GNB
,
0
,
F1AP_UE_CONTEXT_SETUP_RESP
);
f1ap_ue_context_setup_t
*
f1ap_msg
=
&
F1AP_UE_CONTEXT_SETUP_RESP
(
msg
);
/* copy all fields, but reallocate memory buffers! */
*
f1ap_msg
=
*
resp
;
if
(
resp
->
srbs_to_be_setup_length
>
0
)
{
DevAssert
(
resp
->
srbs_to_be_setup
!=
NULL
);
f1ap_msg
->
srbs_to_be_setup_length
=
resp
->
srbs_to_be_setup_length
;
f1ap_msg
->
srbs_to_be_setup
=
calloc
(
f1ap_msg
->
srbs_to_be_setup_length
,
sizeof
(
*
f1ap_msg
->
srbs_to_be_setup
));
for
(
int
i
=
0
;
i
<
f1ap_msg
->
srbs_to_be_setup_length
;
++
i
)
f1ap_msg
->
srbs_to_be_setup
[
i
]
=
resp
->
srbs_to_be_setup
[
i
];
}
f1ap_msg
->
du_to_cu_rrc_information
=
malloc
(
sizeof
(
*
resp
->
du_to_cu_rrc_information
));
AssertFatal
(
f1ap_msg
->
du_to_cu_rrc_information
!=
NULL
,
"out of memory
\n
"
);
f1ap_msg
->
du_to_cu_rrc_information_length
=
resp
->
du_to_cu_rrc_information_length
;
du_to_cu_rrc_information_t
*
du2cu
=
f1ap_msg
->
du_to_cu_rrc_information
;
du2cu
->
cellGroupConfig_length
=
resp
->
du_to_cu_rrc_information
->
cellGroupConfig_length
;
du2cu
->
cellGroupConfig
=
calloc
(
du2cu
->
cellGroupConfig_length
,
sizeof
(
*
du2cu
->
cellGroupConfig
));
AssertFatal
(
du2cu
->
cellGroupConfig
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
du2cu
->
cellGroupConfig
,
resp
->
du_to_cu_rrc_information
->
cellGroupConfig
,
du2cu
->
cellGroupConfig_length
);
itti_send_msg_to_task
(
TASK_RRC_GNB
,
0
,
msg
);
}
static
void
initial_ul_rrc_message_transfer_direct
(
module_id_t
module_id
,
const
f1ap_initial_ul_rrc_message_t
*
ul_rrc
)
...
...
openair2/RRC/NR/rrc_gNB.c
View file @
6ced3cd8
...
...
@@ -2284,71 +2284,10 @@ rrc_gNB_decode_dcch(
ul_dcch_msg
);
}
if
(
!
NODE_IS_CU
(
gnb_rrc_inst
->
node_type
))
{
if
(
UE
->
established_pdu_sessions_flag
==
1
)
{
rrc_gNB_generate_dedicatedRRCReconfiguration
(
ctxt_pP
,
ue_context_p
,
NULL
);
}
else
{
rrc_gNB_generate_defaultRRCReconfiguration
(
ctxt_pP
,
ue_context_p
);
}
if
(
UE
->
established_pdu_sessions_flag
==
1
)
{
rrc_gNB_generate_dedicatedRRCReconfiguration
(
ctxt_pP
,
ue_context_p
,
NULL
);
}
else
{
/*Generate a UE context setup request message towards the DU to provide the UE
*capability info and get the updates on master cell group config from the DU*/
MessageDef
*
message_p
;
message_p
=
itti_alloc_new_message
(
TASK_RRC_GNB
,
0
,
F1AP_UE_CONTEXT_SETUP_REQ
);
f1ap_ue_context_setup_t
*
req
=&
F1AP_UE_CONTEXT_SETUP_REQ
(
message_p
);
//UE_IDs will be extracted from F1AP layer
req
->
gNB_CU_ue_id
=
0
;
req
->
gNB_DU_ue_id
=
0
;
req
->
rnti
=
UE
->
rnti
;
req
->
mcc
=
gnb_rrc_inst
->
configuration
.
mcc
[
0
];
req
->
mnc
=
gnb_rrc_inst
->
configuration
.
mnc
[
0
];
req
->
mnc_digit_length
=
gnb_rrc_inst
->
configuration
.
mnc_digit_length
[
0
];
req
->
nr_cellid
=
gnb_rrc_inst
->
nr_cellid
;
if
(
UE
->
established_pdu_sessions_flag
==
1
)
{
/*Instruction towards the DU for SRB2 configuration*/
req
->
srbs_to_be_setup
=
malloc
(
1
*
sizeof
(
f1ap_srb_to_be_setup_t
));
req
->
srbs_to_be_setup_length
=
1
;
f1ap_srb_to_be_setup_t
*
SRBs
=
req
->
srbs_to_be_setup
;
SRBs
[
0
].
srb_id
=
2
;
SRBs
[
0
].
lcid
=
2
;
/*Instruction towards the DU for DRB configuration and tunnel creation*/
req
->
drbs_to_be_setup
=
malloc
(
1
*
sizeof
(
f1ap_drb_to_be_setup_t
));
req
->
drbs_to_be_setup_length
=
1
;
f1ap_drb_to_be_setup_t
*
DRBs
=
req
->
drbs_to_be_setup
;
LOG_I
(
RRC
,
"Length of DRB list:%d
\n
"
,
req
->
drbs_to_be_setup_length
);
DRBs
[
0
].
drb_id
=
1
;
DRBs
[
0
].
rlc_mode
=
RLC_MODE_AM
;
DRBs
[
0
].
up_ul_tnl
[
0
].
tl_address
=
inet_addr
(
gnb_rrc_inst
->
eth_params_s
.
my_addr
);
DRBs
[
0
].
up_ul_tnl
[
0
].
port
=
gnb_rrc_inst
->
eth_params_s
.
my_portd
;
DRBs
[
0
].
up_ul_tnl_length
=
1
;
DRBs
[
0
].
up_dl_tnl
[
0
].
tl_address
=
inet_addr
(
gnb_rrc_inst
->
eth_params_s
.
remote_addr
);
DRBs
[
0
].
up_dl_tnl
[
0
].
port
=
gnb_rrc_inst
->
eth_params_s
.
remote_portd
;
DRBs
[
0
].
up_dl_tnl_length
=
1
;
}
if
(
ul_dcch_msg
->
message
.
choice
.
c1
->
choice
.
ueCapabilityInformation
->
criticalExtensions
.
present
==
NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation
)
{
struct
NR_UE_CapabilityRAT_ContainerList
*
ue_CapabilityRAT_ContainerList
=
ul_dcch_msg
->
message
.
choice
.
c1
->
choice
.
ueCapabilityInformation
->
criticalExtensions
.
choice
.
ueCapabilityInformation
->
ue_CapabilityRAT_ContainerList
;
if
(
ue_CapabilityRAT_ContainerList
!=
NULL
){
LOG_I
(
NR_RRC
,
"ue_CapabilityRAT_ContainerList is present
\n
"
);
req
->
cu_to_du_rrc_information
=
calloc
(
1
,
sizeof
(
cu_to_du_rrc_information_t
));
req
->
cu_to_du_rrc_information
->
uE_CapabilityRAT_ContainerList
=
calloc
(
1
,
4096
);
asn_enc_rval_t
enc_rval
=
uper_encode_to_buffer
(
&
asn_DEF_NR_UE_CapabilityRAT_ContainerList
,
NULL
,
ue_CapabilityRAT_ContainerList
,
req
->
cu_to_du_rrc_information
->
uE_CapabilityRAT_ContainerList
,
4096
);
AssertFatal
(
enc_rval
.
encoded
>
0
,
"ASN1 ue_CapabilityRAT_ContainerList encoding failed (%s, %jd)!
\n
"
,
enc_rval
.
failed_type
->
name
,
enc_rval
.
encoded
);
req
->
cu_to_du_rrc_information
->
uE_CapabilityRAT_ContainerList_length
=
(
enc_rval
.
encoded
+
7
)
>>
3
;
}
else
{
LOG_I
(
NR_RRC
,
"ue_CapabilityRAT_ContainerList is not present
\n
"
);
}
}
itti_send_msg_to_task
(
TASK_CU_F1
,
ctxt_pP
->
module_id
,
message_p
);
rrc_gNB_generate_defaultRRCReconfiguration
(
ctxt_pP
,
ue_context_p
);
}
break
;
...
...
@@ -2524,233 +2463,6 @@ void rrc_gNB_process_dc_overall_timeout(const module_id_t gnb_mod_idP, x2ap_ENDC
rrc_remove_nsa_user
(
rrc
,
m
->
rnti
);
}
static
void
rrc_DU_process_ue_context_setup_request
(
MessageDef
*
msg_p
,
instance_t
instance
)
{
f1ap_ue_context_setup_t
*
req
=&
F1AP_UE_CONTEXT_SETUP_REQ
(
msg_p
);
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
instance
];
gNB_MAC_INST
*
mac
=
RC
.
nrmac
[
instance
];
rrc_gNB_ue_context_t
*
ue_context_p
=
rrc_gNB_get_ue_context_by_rnti
(
rrc
,
req
->
rnti
);
gNB_RRC_UE_t
*
UE
=
&
ue_context_p
->
ue_context
;
MessageDef
*
message_p
;
message_p
=
itti_alloc_new_message
(
TASK_RRC_GNB
,
0
,
F1AP_UE_CONTEXT_SETUP_RESP
);
f1ap_ue_context_setup_t
*
resp
=&
F1AP_UE_CONTEXT_SETUP_RESP
(
message_p
);
uint32_t
incoming_teid
=
0
;
if
(
req
->
cu_to_du_rrc_information
!=
NULL
){
if
(
req
->
cu_to_du_rrc_information
->
uE_CapabilityRAT_ContainerList
!=
NULL
){
LOG_I
(
NR_RRC
,
"Length of ue_CapabilityRAT_ContainerList is: %d
\n
"
,
(
int
)
req
->
cu_to_du_rrc_information
->
uE_CapabilityRAT_ContainerList_length
);
struct
NR_UE_CapabilityRAT_ContainerList
*
ue_CapabilityRAT_ContainerList
=
NULL
;
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
&
asn_DEF_NR_UE_CapabilityRAT_ContainerList
,
(
void
**
)
&
ue_CapabilityRAT_ContainerList
,
(
uint8_t
*
)
req
->
cu_to_du_rrc_information
->
uE_CapabilityRAT_ContainerList
,
(
int
)
req
->
cu_to_du_rrc_information
->
uE_CapabilityRAT_ContainerList_length
);
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
{
AssertFatal
(
1
==
0
,
"UE Capability RAT ContainerList decode error
\n
"
);
// free the memory
SEQUENCE_free
(
&
asn_DEF_NR_UE_CapabilityRAT_ContainerList
,
ue_CapabilityRAT_ContainerList
,
1
);
return
;
}
//To fill ue_context.UE_Capability_MRDC, ue_context.UE_Capability_nr ...
int
NR_index
=
-
1
;
for
(
int
i
=
0
;
i
<
ue_CapabilityRAT_ContainerList
->
list
.
count
;
i
++
){
if
(
ue_CapabilityRAT_ContainerList
->
list
.
array
[
i
]
->
rat_Type
==
NR_RAT_Type_nr
){
LOG_I
(
NR_RRC
,
"DU received NR_RAT_Type_nr UE capabilities Info through the UE Context Setup Request from the CU
\n
"
);
if
(
UE
->
UE_Capability_nr
)
{
ASN_STRUCT_FREE
(
asn_DEF_NR_UE_NR_Capability
,
UE
->
UE_Capability_nr
);
UE
->
UE_Capability_nr
=
0
;
}
dec_rval
=
uper_decode
(
NULL
,
&
asn_DEF_NR_UE_NR_Capability
,
(
void
**
)
&
UE
->
UE_Capability_nr
,
ue_CapabilityRAT_ContainerList
->
list
.
array
[
i
]
->
ue_CapabilityRAT_Container
.
buf
,
ue_CapabilityRAT_ContainerList
->
list
.
array
[
i
]
->
ue_CapabilityRAT_Container
.
size
,
0
,
0
);
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
)){
xer_fprint
(
stdout
,
&
asn_DEF_NR_UE_NR_Capability
,
UE
->
UE_Capability_nr
);
}
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
)){
LOG_E
(
NR_RRC
,
"UE %04x Failed to decode nr UE capabilities (%zu bytes)
\n
"
,
req
->
rnti
,
dec_rval
.
consumed
);
ASN_STRUCT_FREE
(
asn_DEF_NR_UE_NR_Capability
,
UE
->
UE_Capability_nr
);
UE
->
UE_Capability_nr
=
0
;
}
UE
->
UE_Capability_size
=
ue_CapabilityRAT_ContainerList
->
list
.
array
[
i
]
->
ue_CapabilityRAT_Container
.
size
;
if
(
NR_index
!=
-
1
){
LOG_E
(
NR_RRC
,
"fatal: more than 1 eutra capability
\n
"
);
exit
(
1
);
}
NR_index
=
i
;
}
if
(
ue_CapabilityRAT_ContainerList
->
list
.
array
[
i
]
->
rat_Type
==
NR_RAT_Type_eutra_nr
){
LOG_I
(
NR_RRC
,
"DU received NR_RAT_Type_eutra_nr UE capabilities Info through the UE Context Setup Request from the CU
\n
"
);
if
(
UE
->
UE_Capability_MRDC
)
{
ASN_STRUCT_FREE
(
asn_DEF_NR_UE_MRDC_Capability
,
UE
->
UE_Capability_MRDC
);
UE
->
UE_Capability_MRDC
=
0
;
}
dec_rval
=
uper_decode
(
NULL
,
&
asn_DEF_NR_UE_MRDC_Capability
,
(
void
**
)
&
UE
->
UE_Capability_MRDC
,
ue_CapabilityRAT_ContainerList
->
list
.
array
[
i
]
->
ue_CapabilityRAT_Container
.
buf
,
ue_CapabilityRAT_ContainerList
->
list
.
array
[
i
]
->
ue_CapabilityRAT_Container
.
size
,
0
,
0
);
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
)){
xer_fprint
(
stdout
,
&
asn_DEF_NR_UE_MRDC_Capability
,
UE
->
UE_Capability_MRDC
);
}
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
)){
LOG_E
(
NR_RRC
,
"UE %04x Failed to decode nr UE capabilities (%zu bytes)
\n
"
,
req
->
rnti
,
dec_rval
.
consumed
);
ASN_STRUCT_FREE
(
asn_DEF_NR_UE_MRDC_Capability
,
UE
->
UE_Capability_MRDC
);
UE
->
UE_Capability_MRDC
=
0
;
}
UE
->
UE_MRDC_Capability_size
=
ue_CapabilityRAT_ContainerList
->
list
.
array
[
i
]
->
ue_CapabilityRAT_Container
.
size
;
}
if
(
ue_CapabilityRAT_ContainerList
->
list
.
array
[
i
]
->
rat_Type
==
NR_RAT_Type_eutra
){
//TODO
}
}
}
}
/* Configure SRB2 */
NR_SRB_ToAddMod_t
*
SRB2_config
=
NULL
;
NR_SRB_ToAddModList_t
*
SRB_configList
=
NULL
;
uint8_t
SRBs_before_new_addition
=
0
;
if
(
req
->
srbs_to_be_setup_length
>
0
){
if
(
UE
->
SRB_configList
==
NULL
)
{
LOG_W
(
NR_RRC
,
"The SRB list of the UE context is empty before the addition of new SRB at the DU
\n
"
);
UE
->
SRB_configList
=
CALLOC
(
1
,
sizeof
(
*
UE
->
SRB_configList
));
}
SRB_configList
=
UE
->
SRB_configList
;
SRBs_before_new_addition
=
SRB_configList
->
list
.
count
;
for
(
int
i
=
0
;
i
<
req
->
srbs_to_be_setup_length
;
i
++
){
SRB2_config
=
CALLOC
(
1
,
sizeof
(
*
SRB2_config
));
SRB2_config
->
srb_Identity
=
req
->
srbs_to_be_setup
[
i
].
srb_id
;
asn1cSeqAdd
(
&
SRB_configList
->
list
,
SRB2_config
);
}
}
/* Configure DRB */
NR_DRB_ToAddMod_t
*
DRB_config
=
NULL
;
NR_DRB_ToAddModList_t
*
DRB_configList
=
NULL
;
uint8_t
drb_id_to_setup_start
=
0
;
uint8_t
nb_drb_to_setup
=
0
;
long
drb_priority
[
NGAP_MAX_DRBS_PER_UE
];
if
(
req
->
drbs_to_be_setup_length
>
0
){
if
(
UE
->
DRB_configList
==
NULL
)
{
UE
->
DRB_configList
=
CALLOC
(
1
,
sizeof
(
*
UE
->
DRB_configList
));
}
DRB_configList
=
UE
->
DRB_configList
;
nb_drb_to_setup
=
req
->
drbs_to_be_setup_length
;
for
(
int
i
=
0
;
i
<
req
->
drbs_to_be_setup_length
;
i
++
){
DRB_config
=
CALLOC
(
1
,
sizeof
(
*
DRB_config
));
DRB_config
->
drb_Identity
=
req
->
drbs_to_be_setup
[
i
].
drb_id
;
if
(
drb_id_to_setup_start
==
0
)
drb_id_to_setup_start
=
DRB_config
->
drb_Identity
;
asn1cSeqAdd
(
&
DRB_configList
->
list
,
DRB_config
);
f1ap_drb_to_be_setup_t
drb_p
=
req
->
drbs_to_be_setup
[
i
];
transport_layer_addr_t
addr
;
memcpy
(
addr
.
buffer
,
&
drb_p
.
up_ul_tnl
[
0
].
tl_address
,
sizeof
(
drb_p
.
up_ul_tnl
[
0
].
tl_address
));
addr
.
length
=
sizeof
(
drb_p
.
up_ul_tnl
[
0
].
tl_address
)
*
8
;
extern
instance_t
DUuniqInstance
;
incoming_teid
=
newGtpuCreateTunnel
(
DUuniqInstance
,
req
->
rnti
,
drb_p
.
drb_id
,
drb_p
.
drb_id
,
drb_p
.
up_ul_tnl
[
0
].
teid
,
-
1
,
// no qfi
addr
,
drb_p
.
up_ul_tnl
[
0
].
port
,
DURecvCb
,
NULL
);
/* TODO: hardcoded to 13 for the time being, to be changed? */
drb_priority
[
DRB_config
->
drb_Identity
-
1
]
=
13
;
}
}
NR_CellGroupConfig_t
*
cellGroupConfig
=
calloc
(
1
,
sizeof
(
NR_CellGroupConfig_t
));
if
(
req
->
srbs_to_be_setup_length
>
0
||
req
->
drbs_to_be_setup_length
>
0
)
// FIXME: fill_mastercellGroupConfig() won't fill the right priorities or
// bearer IDs for the DRBs
fill_mastercellGroupConfig
(
cellGroupConfig
,
UE
->
masterCellGroup
,
rrc
->
um_on_default_drb
,
SRB2_config
?
1
:
0
,
drb_id_to_setup_start
,
nb_drb_to_setup
,
drb_priority
);
protocol_ctxt_t
ctxt
=
{.
rntiMaybeUEid
=
req
->
rnti
,
.
module_id
=
instance
,
.
instance
=
instance
,
.
enb_flag
=
1
,
.
eNB_index
=
instance
};
apply_macrlc_config
(
rrc
,
ue_context_p
,
&
ctxt
);
if
(
req
->
rrc_container_length
>
0
){
mem_block_t
*
pdcp_pdu_p
=
get_free_mem_block
(
req
->
rrc_container_length
,
__func__
);
memcpy
(
&
pdcp_pdu_p
->
data
[
0
],
req
->
rrc_container
,
req
->
rrc_container_length
);
du_rlc_data_req
(
&
ctxt
,
1
,
0x00
,
1
,
1
,
0
,
req
->
rrc_container_length
,
pdcp_pdu_p
);
LOG_I
(
F1AP
,
"Printing RRC Container of UE context setup request:
\n
"
);
for
(
int
j
=
0
;
j
<
req
->
rrc_container_length
;
j
++
){
printf
(
"%02x "
,
pdcp_pdu_p
->
data
[
j
]);
}
printf
(
"
\n
"
);
}
/* Fill the UE context setup response ITTI message to send to F1AP */
resp
->
gNB_CU_ue_id
=
req
->
gNB_CU_ue_id
;
resp
->
rnti
=
req
->
rnti
;
if
(
DRB_configList
){
if
(
DRB_configList
->
list
.
count
>
0
){
resp
->
drbs_to_be_setup
=
calloc
(
1
,
DRB_configList
->
list
.
count
*
sizeof
(
f1ap_drb_to_be_setup_t
));
resp
->
drbs_to_be_setup_length
=
DRB_configList
->
list
.
count
;
for
(
int
i
=
0
;
i
<
DRB_configList
->
list
.
count
;
i
++
){
resp
->
drbs_to_be_setup
[
i
].
drb_id
=
DRB_configList
->
list
.
array
[
i
]
->
drb_Identity
;
resp
->
drbs_to_be_setup
[
i
].
rlc_mode
=
RLC_MODE_AM
;
resp
->
drbs_to_be_setup
[
i
].
up_dl_tnl
[
0
].
teid
=
incoming_teid
;
resp
->
drbs_to_be_setup
[
i
].
up_dl_tnl
[
0
].
tl_address
=
inet_addr
(
mac
->
eth_params_n
.
my_addr
);
resp
->
drbs_to_be_setup
[
i
].
up_dl_tnl_length
=
1
;
}
}
else
{
LOG_W
(
NR_RRC
,
"No DRB added upon reception of F1 UE context setup request with a DRB to setup list
\n
"
);
}
}
if
(
SRB_configList
){
if
(
SRB_configList
->
list
.
count
>
0
&&
SRBs_before_new_addition
<
SRB_configList
->
list
.
count
){
resp
->
srbs_to_be_setup
=
calloc
(
1
,
req
->
srbs_to_be_setup_length
*
sizeof
(
f1ap_srb_to_be_setup_t
));
resp
->
srbs_to_be_setup_length
=
req
->
srbs_to_be_setup_length
;
for
(
int
i
=
SRBs_before_new_addition
;
i
<
SRB_configList
->
list
.
count
;
i
++
){
resp
->
srbs_to_be_setup
[
i
-
SRBs_before_new_addition
].
srb_id
=
SRB_configList
->
list
.
array
[
i
]
->
srb_Identity
;
}
}
else
{
LOG_W
(
NR_RRC
,
"No SRB added upon reception of F1 UE Context setup request at the DU
\n
"
);
}
}
else
{
LOG_W
(
NR_RRC
,
"No SRB added upon reception of F1 UE Context setup request at the DU
\n
"
);
}
/* fixme:
* Here we should be encoding the updates on cellgroupconfig based on the content of UE capabilities
*/
resp
->
du_to_cu_rrc_information
=
calloc
(
1
,
sizeof
(
du_to_cu_rrc_information_t
));
resp
->
du_to_cu_rrc_information
->
cellGroupConfig
=
calloc
(
1
,
1024
);
asn_enc_rval_t
enc_rval
=
uper_encode_to_buffer
(
&
asn_DEF_NR_CellGroupConfig
,
NULL
,
UE
->
masterCellGroup
,
//(void *)cellGroupConfig,
resp
->
du_to_cu_rrc_information
->
cellGroupConfig
,
1024
);
if
(
enc_rval
.
encoded
==
-
1
)
{
LOG_E
(
F1AP
,
"Could not encode ue_context.masterCellGroup, failed element %s
\n
"
,
enc_rval
.
failed_type
->
name
);
exit
(
-
1
);
}
resp
->
du_to_cu_rrc_information
->
cellGroupConfig_length
=
(
enc_rval
.
encoded
+
7
)
>>
3
;
free
(
cellGroupConfig
);
itti_send_msg_to_task
(
TASK_DU_F1
,
instance
,
message_p
);
}
static
void
rrc_DU_process_ue_context_modification_request
(
MessageDef
*
msg_p
,
instance_t
instance
)
{
f1ap_ue_context_setup_t
*
req
=&
F1AP_UE_CONTEXT_MODIFICATION_REQ
(
msg_p
);
...
...
@@ -2898,54 +2610,29 @@ static void rrc_DU_process_ue_context_modification_request(MessageDef *msg_p, in
static
void
rrc_CU_process_ue_context_setup_response
(
MessageDef
*
msg_p
,
instance_t
instance
)
{
f1ap_ue_context_setup_t
*
resp
=&
F1AP_UE_CONTEXT_SETUP_RESP
(
msg_p
);
protocol_ctxt_t
ctxt
=
{.
rntiMaybeUEid
=
resp
->
rnti
,
.
module_id
=
instance
,
.
instance
=
instance
,
.
enb_flag
=
1
,
.
eNB_index
=
instance
};
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
ctxt
.
module_id
];
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
instance
];
rrc_gNB_ue_context_t
*
ue_context_p
=
rrc_gNB_get_ue_context_by_rnti
(
rrc
,
resp
->
rnti
);
gNB_RRC_UE_t
*
UE
=
&
ue_context_p
->
ue_context
;
NR_CellGroupConfig_t
*
cellGroupConfig
=
NULL
;
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
&
asn_DEF_NR_CellGroupConfig
,
(
void
**
)
&
cellGroupConfig
,
(
uint8_t
*
)
resp
->
du_to_cu_rrc_information
->
cellGroupConfig
,
(
int
)
resp
->
du_to_cu_rrc_information
->
cellGroupConfig_length
);
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
{
AssertFatal
(
1
==
0
,
"Cell group config decode error
\n
"
);
// free the memory
SEQUENCE_free
(
&
asn_DEF_NR_CellGroupConfig
,
cellGroupConfig
,
1
);
return
;
}
//xer_fprint(stdout,&asn_DEF_NR_CellGroupConfig, cellGroupConfig
);
NR_CellGroupConfig_t
*
cellGroupConfig
=
NULL
;
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
&
asn_DEF_NR_CellGroupConfig
,
(
void
**
)
&
cellGroupConfig
,
(
uint8_t
*
)
resp
->
du_to_cu_rrc_information
->
cellGroupConfig
,
resp
->
du_to_cu_rrc_information
->
cellGroupConfig_length
);
AssertFatal
(
dec_rval
.
code
==
RC_OK
&&
dec_rval
.
consumed
>
0
,
"Cell group config decode error
\n
"
);
if
(
UE
->
masterCellGroup
==
NULL
)
{
UE
->
masterCellGroup
=
calloc
(
1
,
sizeof
(
NR_CellGroupConfig_t
));
}
if
(
cellGroupConfig
->
rlc_BearerToAddModList
!=
NULL
){
if
(
UE
->
masterCellGroup
->
rlc_BearerToAddModList
!=
NULL
)
{
int
ue_ctxt_rlc_Bearers
=
UE
->
masterCellGroup
->
rlc_BearerToAddModList
->
list
.
count
;
for
(
int
i
=
ue_ctxt_rlc_Bearers
;
i
<
ue_ctxt_rlc_Bearers
+
cellGroupConfig
->
rlc_BearerToAddModList
->
list
.
count
;
i
++
){
asn1cSeqAdd
(
&
UE
->
masterCellGroup
->
rlc_BearerToAddModList
->
list
,
cellGroupConfig
->
rlc_BearerToAddModList
->
list
.
array
[
i
-
ue_ctxt_rlc_Bearers
]);
}
}
else
{
LOG_W
(
NR_RRC
,
"Empty rlc_BearerToAddModList at ue_context of the CU before filling the updates from UE context setup response
\n
"
);
UE
->
masterCellGroup
->
rlc_BearerToAddModList
=
calloc
(
1
,
sizeof
(
*
cellGroupConfig
->
rlc_BearerToAddModList
));
memcpy
(
UE
->
masterCellGroup
->
rlc_BearerToAddModList
,
cellGroupConfig
->
rlc_BearerToAddModList
,
sizeof
(
*
cellGroupConfig
->
rlc_BearerToAddModList
));
}
if
(
UE
->
masterCellGroup
)
{
ASN_STRUCT_FREE
(
asn_DEF_NR_CellGroupConfig
,
UE
->
masterCellGroup
);
LOG_I
(
RRC
,
"UE %04x replacing existing CellGroupConfig with new one received from DU
\n
"
,
UE
->
rnti
);
}
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
{
UE
->
masterCellGroup
=
cellGroupConfig
;
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
xer_fprint
(
stdout
,
&
asn_DEF_NR_CellGroupConfig
,
UE
->
masterCellGroup
);
}
if
(
UE
->
established_pdu_sessions_flag
==
1
)
{
fill_DRB_configList
(
&
ctxt
,
ue_context_p
);
rrc_gNB_generate_dedicatedRRCReconfiguration
(
&
ctxt
,
ue_context_p
,
cellGroupConfig
);
}
else
{
rrc_gNB_generate_defaultRRCReconfiguration
(
&
ctxt
,
ue_context_p
);
}
free
(
cellGroupConfig
->
rlc_BearerToAddModList
);
free
(
cellGroupConfig
);
/* 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) */
}
static
void
rrc_CU_process_ue_context_modification_response
(
MessageDef
*
msg_p
,
instance_t
instance
)
...
...
@@ -3507,10 +3194,6 @@ void *rrc_gnb_task(void *args_p) {
AssertFatal
(
NODE_IS_CU
(
RC
.
nrrrc
[
instance
]
->
node_type
),
"should not receive F1AP_SETUP_REQUEST, need call by CU!
\n
"
);
rrc_gNB_process_f1_setup_req
(
&
F1AP_SETUP_REQ
(
msg_p
));
break
;
case
F1AP_UE_CONTEXT_SETUP_REQ
:
rrc_DU_process_ue_context_setup_request
(
msg_p
,
instance
);
break
;
case
F1AP_UE_CONTEXT_SETUP_RESP
:
rrc_CU_process_ue_context_setup_response
(
msg_p
,
instance
);
...
...
@@ -3582,6 +3265,27 @@ void *rrc_gnb_task(void *args_p) {
}
}
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
);
gNB_RRC_INST
*
rrc
=
deliver_pdu_data
;
f1ap_ue_context_setup_t
ue_context_setup_req
=
{
.
gNB_CU_ue_id
=
0xffffffff
,
/* filled by F1 for the moment */
.
gNB_DU_ue_id
=
0xffffffff
,
/* filled by F1 for the moment */
.
rnti
=
ue_id
,
.
mcc
=
rrc
->
configuration
.
mcc
[
0
],
.
mnc
=
rrc
->
configuration
.
mnc
[
0
],
.
mnc_digit_length
=
rrc
->
configuration
.
mnc_digit_length
[
0
],
.
nr_cellid
=
rrc
->
nr_cellid
,
.
servCellId
=
0
,
/* TODO: correct value? */
.
srbs_to_be_setup
=
0
,
/* no new SRBs */
.
drbs_to_be_setup
=
0
,
/* no new DRBs */
.
rrc_container
=
(
uint8_t
*
)
buf
,
/* security mode command */
.
rrc_container_length
=
size
,
};
rrc
->
mac_rrc
.
ue_context_setup_request
(
&
ue_context_setup_req
);
}
//-----------------------------------------------------------------------------
void
rrc_gNB_generate_SecurityModeCommand
(
...
...
@@ -3603,7 +3307,8 @@ rrc_gNB_generate_SecurityModeCommand(
gNB_RRC_INST
*
rrc
=
RC
.
nrrrc
[
ctxt_pP
->
module_id
];
AssertFatal
(
!
NODE_IS_DU
(
rrc
->
node_type
),
"illegal node type DU!
\n
"
);
nr_pdcp_data_req_srb
(
ctxt_pP
->
rntiMaybeUEid
,
DCCH
,
rrc_gNB_mui
++
,
size
,
buffer
,
deliver_pdu_srb_f1
,
rrc
);
/* the callback will fill the UE context setup request and forward it */
nr_pdcp_data_req_srb
(
ctxt_pP
->
rntiMaybeUEid
,
DCCH
,
rrc_gNB_mui
++
,
size
,
buffer
,
rrc_deliver_ue_ctxt_setup_req
,
rrc
);
}
void
...
...
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