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
lizhongxiao
OpenXG-RAN
Commits
7337ae86
Commit
7337ae86
authored
Feb 23, 2024
by
Raphael Defosseux
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/NR_UE_RRC_improvements' into integration_2024_w08
parents
3972cd44
df867e53
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
233 additions
and
265 deletions
+233
-265
openair2/RRC/NR_UE/rrc_UE.c
openair2/RRC/NR_UE/rrc_UE.c
+228
-261
openair2/RRC/NR_UE/rrc_defs.h
openair2/RRC/NR_UE/rrc_defs.h
+4
-3
openair2/RRC/NR_UE/rrc_proto.h
openair2/RRC/NR_UE/rrc_proto.h
+1
-1
No files found.
openair2/RRC/NR_UE/rrc_UE.c
View file @
7337ae86
...
@@ -133,12 +133,10 @@ static const char nr_nas_attach_req_imsi_dummy_NSA_case[] = {
...
@@ -133,12 +133,10 @@ static const char nr_nas_attach_req_imsi_dummy_NSA_case[] = {
0x11
,
0x11
,
};
};
static
void
nr_rrc_manage_rlc_bearers
(
const
NR_UE_RRC_INST_t
*
rrc
,
static
void
nr_rrc_manage_rlc_bearers
(
NR_UE_RRC_INST_t
*
rrc
,
const
NR_CellGroupConfig_t
*
cellGroupConfig
,
const
NR_CellGroupConfig_t
*
cellGroupConfig
);
rrcPerNB_t
*
nb
);
static
void
nr_rrc_ue_process_RadioBearerConfig
(
NR_UE_RRC_INST_t
*
ue_rrc
,
static
void
nr_rrc_ue_process_RadioBearerConfig
(
NR_UE_RRC_INST_t
*
ue_rrc
,
rrcPerNB_t
*
rrcNB
,
NR_RadioBearerConfig_t
*
const
radioBearerConfig
);
NR_RadioBearerConfig_t
*
const
radioBearerConfig
);
static
void
nr_rrc_ue_generate_rrcReestablishmentComplete
(
NR_RRCReestablishment_t
*
rrcReestablishment
);
static
void
nr_rrc_ue_generate_rrcReestablishmentComplete
(
NR_RRCReestablishment_t
*
rrcReestablishment
);
static
void
process_lte_nsa_msg
(
NR_UE_RRC_INST_t
*
rrc
,
nsa_msg_t
*
msg
,
int
msg_len
);
static
void
process_lte_nsa_msg
(
NR_UE_RRC_INST_t
*
rrc
,
nsa_msg_t
*
msg
,
int
msg_len
);
...
@@ -148,7 +146,6 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
...
@@ -148,7 +146,6 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
static
void
nr_rrc_ue_process_ueCapabilityEnquiry
(
NR_UE_RRC_INST_t
*
rrc
,
NR_UECapabilityEnquiry_t
*
UECapabilityEnquiry
);
static
void
nr_rrc_ue_process_ueCapabilityEnquiry
(
NR_UE_RRC_INST_t
*
rrc
,
NR_UECapabilityEnquiry_t
*
UECapabilityEnquiry
);
static
void
nr_rrc_ue_process_masterCellGroup
(
NR_UE_RRC_INST_t
*
rrc
,
static
void
nr_rrc_ue_process_masterCellGroup
(
NR_UE_RRC_INST_t
*
rrc
,
rrcPerNB_t
*
rrcNB
,
OCTET_STRING_t
*
masterCellGroup
,
OCTET_STRING_t
*
masterCellGroup
,
long
*
fullConfig
);
long
*
fullConfig
);
...
@@ -166,7 +163,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
...
@@ -166,7 +163,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
if
(
ie
->
radioBearerConfig
!=
NULL
)
{
if
(
ie
->
radioBearerConfig
!=
NULL
)
{
LOG_I
(
NR_RRC
,
"radio Bearer Configuration is present
\n
"
);
LOG_I
(
NR_RRC
,
"radio Bearer Configuration is present
\n
"
);
nr_rrc_ue_process_RadioBearerConfig
(
rrc
,
rrcNB
,
ie
->
radioBearerConfig
);
nr_rrc_ue_process_RadioBearerConfig
(
rrc
,
ie
->
radioBearerConfig
);
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
xer_fprint
(
stdout
,
&
asn_DEF_NR_RadioBearerConfig
,
(
const
void
*
)
ie
->
radioBearerConfig
);
xer_fprint
(
stdout
,
&
asn_DEF_NR_RadioBearerConfig
,
(
const
void
*
)
ie
->
radioBearerConfig
);
}
}
...
@@ -174,7 +171,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
...
@@ -174,7 +171,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
if
(
ie
->
nonCriticalExtension
)
{
if
(
ie
->
nonCriticalExtension
)
{
NR_RRCReconfiguration_v1530_IEs_t
*
ext
=
ie
->
nonCriticalExtension
;
NR_RRCReconfiguration_v1530_IEs_t
*
ext
=
ie
->
nonCriticalExtension
;
if
(
ext
->
masterCellGroup
)
if
(
ext
->
masterCellGroup
)
nr_rrc_ue_process_masterCellGroup
(
rrc
,
rrcNB
,
ext
->
masterCellGroup
,
ext
->
fullConfig
);
nr_rrc_ue_process_masterCellGroup
(
rrc
,
ext
->
masterCellGroup
,
ext
->
fullConfig
);
/* Check if there is dedicated NAS information to forward to NAS */
/* Check if there is dedicated NAS information to forward to NAS */
if
(
ie
->
nonCriticalExtension
->
dedicatedNAS_MessageList
)
{
if
(
ie
->
nonCriticalExtension
->
dedicatedNAS_MessageList
)
{
struct
NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
*
tmp
=
ext
->
dedicatedNAS_MessageList
;
struct
NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList
*
tmp
=
ext
->
dedicatedNAS_MessageList
;
...
@@ -212,7 +209,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
...
@@ -212,7 +209,7 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
xer_fprint
(
stdout
,
&
asn_DEF_NR_CellGroupConfig
,
(
const
void
*
)
cellGroupConfig
);
xer_fprint
(
stdout
,
&
asn_DEF_NR_CellGroupConfig
,
(
const
void
*
)
cellGroupConfig
);
nr_rrc_cellgroup_configuration
(
rrc
NB
,
rrc
,
cellGroupConfig
);
nr_rrc_cellgroup_configuration
(
rrc
,
cellGroupConfig
);
AssertFatal
(
!
get_softmodem_params
()
->
sa
,
"secondaryCellGroup only used in NSA for now
\n
"
);
AssertFatal
(
!
get_softmodem_params
()
->
sa
,
"secondaryCellGroup only used in NSA for now
\n
"
);
nr_rrc_mac_config_req_cg
(
0
,
0
,
cellGroupConfig
,
rrc
->
UECap
.
UE_NR_Capability
);
nr_rrc_mac_config_req_cg
(
0
,
0
,
cellGroupConfig
,
rrc
->
UECap
.
UE_NR_Capability
);
...
@@ -239,15 +236,13 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
...
@@ -239,15 +236,13 @@ static void nr_rrc_ue_process_rrcReconfiguration(NR_UE_RRC_INST_t *rrc,
void
process_nsa_message
(
NR_UE_RRC_INST_t
*
rrc
,
nsa_message_t
nsa_message_type
,
void
*
message
,
int
msg_len
)
void
process_nsa_message
(
NR_UE_RRC_INST_t
*
rrc
,
nsa_message_t
nsa_message_type
,
void
*
message
,
int
msg_len
)
{
{
switch
(
nsa_message_type
)
{
switch
(
nsa_message_type
)
{
case
nr_SecondaryCellGroupConfig_r15
:
case
nr_SecondaryCellGroupConfig_r15
:
{
{
NR_RRCReconfiguration_t
*
RRCReconfiguration
=
NULL
;
NR_RRCReconfiguration_t
*
RRCReconfiguration
=
NULL
;
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
&
asn_DEF_NR_RRCReconfiguration
,
&
asn_DEF_NR_RRCReconfiguration
,
(
void
**
)
&
RRCReconfiguration
,
(
void
**
)
&
RRCReconfiguration
,
(
uint8_t
*
)
message
,
(
uint8_t
*
)
message
,
msg_len
);
msg_len
);
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
{
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
{
LOG_E
(
NR_RRC
,
"NR_RRCReconfiguration decode error
\n
"
);
LOG_E
(
NR_RRC
,
"NR_RRCReconfiguration decode error
\n
"
);
// free the memory
// free the memory
...
@@ -259,15 +254,13 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
...
@@ -259,15 +254,13 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
}
}
break
;
break
;
case
nr_RadioBearerConfigX_r15
:
case
nr_RadioBearerConfigX_r15
:
{
{
NR_RadioBearerConfig_t
*
RadioBearerConfig
=
NULL
;
NR_RadioBearerConfig_t
*
RadioBearerConfig
=
NULL
;
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
&
asn_DEF_NR_RadioBearerConfig
,
&
asn_DEF_NR_RadioBearerConfig
,
(
void
**
)
&
RadioBearerConfig
,
(
void
**
)
&
RadioBearerConfig
,
(
uint8_t
*
)
message
,
(
uint8_t
*
)
message
,
msg_len
);
msg_len
);
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
{
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
{
LOG_E
(
NR_RRC
,
"NR_RadioBearerConfig decode error
\n
"
);
LOG_E
(
NR_RRC
,
"NR_RadioBearerConfig decode error
\n
"
);
// free the memory
// free the memory
...
@@ -279,7 +272,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
...
@@ -279,7 +272,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
RadioBearerConfig
->
drb_ToAddModList
->
list
.
array
[
0
]
->
drb_Identity
,
RadioBearerConfig
->
drb_ToAddModList
->
list
.
array
[
0
]
->
drb_Identity
,
RadioBearerConfig
->
securityConfig
->
securityAlgorithmConfig
->
cipheringAlgorithm
,
RadioBearerConfig
->
securityConfig
->
securityAlgorithmConfig
->
cipheringAlgorithm
,
*
RadioBearerConfig
->
securityConfig
->
keyToUse
);
*
RadioBearerConfig
->
securityConfig
->
keyToUse
);
nr_rrc_ue_process_RadioBearerConfig
(
rrc
,
rrc
->
perNB
+
0
,
RadioBearerConfig
);
nr_rrc_ue_process_RadioBearerConfig
(
rrc
,
RadioBearerConfig
);
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
xer_fprint
(
stdout
,
&
asn_DEF_NR_RadioBearerConfig
,
(
const
void
*
)
RadioBearerConfig
);
xer_fprint
(
stdout
,
&
asn_DEF_NR_RadioBearerConfig
,
(
const
void
*
)
RadioBearerConfig
);
ASN_STRUCT_FREE
(
asn_DEF_NR_RadioBearerConfig
,
RadioBearerConfig
);
ASN_STRUCT_FREE
(
asn_DEF_NR_RadioBearerConfig
,
RadioBearerConfig
);
...
@@ -327,16 +320,19 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst)
...
@@ -327,16 +320,19 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst)
memset
(
&
rrc
->
timers_and_constants
,
0
,
sizeof
(
rrc
->
timers_and_constants
));
memset
(
&
rrc
->
timers_and_constants
,
0
,
sizeof
(
rrc
->
timers_and_constants
));
set_default_timers_and_constants
(
&
rrc
->
timers_and_constants
);
set_default_timers_and_constants
(
&
rrc
->
timers_and_constants
);
for
(
int
j
=
0
;
j
<
NR_NUM_SRB
;
j
++
)
rrc
->
Srb
[
j
]
=
RB_NOT_PRESENT
;
for
(
int
j
=
0
;
j
<
MAX_DRBS_PER_UE
;
j
++
)
rrc
->
status_DRBs
[
j
]
=
RB_NOT_PRESENT
;
// SRB0 activated by default
rrc
->
Srb
[
0
]
=
RB_ESTABLISHED
;
for
(
int
j
=
0
;
j
<
NR_MAX_NUM_LCID
;
j
++
)
rrc
->
active_RLC_entity
[
j
]
=
false
;
for
(
int
i
=
0
;
i
<
NB_CNX_UE
;
i
++
)
{
for
(
int
i
=
0
;
i
<
NB_CNX_UE
;
i
++
)
{
rrcPerNB_t
*
ptr
=
&
rrc
->
perNB
[
i
];
rrcPerNB_t
*
ptr
=
&
rrc
->
perNB
[
i
];
ptr
->
SInfo
=
(
NR_UE_RRC_SI_INFO
){
0
};
ptr
->
SInfo
=
(
NR_UE_RRC_SI_INFO
){
0
};
init_SI_timers
(
&
ptr
->
SInfo
);
init_SI_timers
(
&
ptr
->
SInfo
);
for
(
int
j
=
0
;
j
<
NR_NUM_SRB
;
j
++
)
ptr
->
Srb
[
j
]
=
RB_NOT_PRESENT
;
for
(
int
j
=
0
;
j
<
MAX_DRBS_PER_UE
;
j
++
)
ptr
->
status_DRBs
[
j
]
=
RB_NOT_PRESENT
;
// SRB0 activated by default
ptr
->
Srb
[
0
]
=
RB_ESTABLISHED
;
}
}
init_sidelink
(
rrc
);
init_sidelink
(
rrc
);
...
@@ -710,9 +706,8 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
...
@@ -710,9 +706,8 @@ static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(NR_UE_RRC_INST_t *rrc,
return
0
;
return
0
;
}
}
static
void
nr_rrc_manage_rlc_bearers
(
const
NR_UE_RRC_INST_t
*
rrc
,
static
void
nr_rrc_manage_rlc_bearers
(
NR_UE_RRC_INST_t
*
rrc
,
const
NR_CellGroupConfig_t
*
cellGroupConfig
,
const
NR_CellGroupConfig_t
*
cellGroupConfig
)
rrcPerNB_t
*
nb
)
{
{
if
(
cellGroupConfig
->
rlc_BearerToReleaseList
!=
NULL
)
{
if
(
cellGroupConfig
->
rlc_BearerToReleaseList
!=
NULL
)
{
for
(
int
i
=
0
;
i
<
cellGroupConfig
->
rlc_BearerToReleaseList
->
list
.
count
;
i
++
)
{
for
(
int
i
=
0
;
i
<
cellGroupConfig
->
rlc_BearerToReleaseList
->
list
.
count
;
i
++
)
{
...
@@ -726,12 +721,12 @@ static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
...
@@ -726,12 +721,12 @@ static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
for
(
int
i
=
0
;
i
<
cellGroupConfig
->
rlc_BearerToAddModList
->
list
.
count
;
i
++
)
{
for
(
int
i
=
0
;
i
<
cellGroupConfig
->
rlc_BearerToAddModList
->
list
.
count
;
i
++
)
{
NR_RLC_BearerConfig_t
*
rlc_bearer
=
cellGroupConfig
->
rlc_BearerToAddModList
->
list
.
array
[
i
];
NR_RLC_BearerConfig_t
*
rlc_bearer
=
cellGroupConfig
->
rlc_BearerToAddModList
->
list
.
array
[
i
];
NR_LogicalChannelIdentity_t
lcid
=
rlc_bearer
->
logicalChannelIdentity
;
NR_LogicalChannelIdentity_t
lcid
=
rlc_bearer
->
logicalChannelIdentity
;
if
(
nb
->
active_RLC_entity
[
lcid
])
{
if
(
rrc
->
active_RLC_entity
[
lcid
])
{
if
(
rlc_bearer
->
reestablishRLC
)
if
(
rlc_bearer
->
reestablishRLC
)
nr_rlc_reestablish_entity
(
rrc
->
ue_id
,
lcid
);
nr_rlc_reestablish_entity
(
rrc
->
ue_id
,
lcid
);
nr_rlc_reconfigure_entity
(
rrc
->
ue_id
,
lcid
,
rlc_bearer
->
rlc_Config
);
nr_rlc_reconfigure_entity
(
rrc
->
ue_id
,
lcid
,
rlc_bearer
->
rlc_Config
);
}
else
{
}
else
{
nb
->
active_RLC_entity
[
lcid
]
=
true
;
rrc
->
active_RLC_entity
[
lcid
]
=
true
;
AssertFatal
(
rlc_bearer
->
servedRadioBearer
,
"servedRadioBearer mandatory in case of setup
\n
"
);
AssertFatal
(
rlc_bearer
->
servedRadioBearer
,
"servedRadioBearer mandatory in case of setup
\n
"
);
AssertFatal
(
rlc_bearer
->
servedRadioBearer
->
present
!=
NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING
,
AssertFatal
(
rlc_bearer
->
servedRadioBearer
->
present
!=
NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING
,
"Invalid RB for RLC configuration
\n
"
);
"Invalid RB for RLC configuration
\n
"
);
...
@@ -747,7 +742,7 @@ static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
...
@@ -747,7 +742,7 @@ static void nr_rrc_manage_rlc_bearers(const NR_UE_RRC_INST_t *rrc,
}
}
}
}
void
nr_rrc_cellgroup_configuration
(
rrcPerNB_t
*
rrcNB
,
NR_UE_RRC_INST_t
*
rrc
,
NR_CellGroupConfig_t
*
cellGroupConfig
)
void
nr_rrc_cellgroup_configuration
(
NR_UE_RRC_INST_t
*
rrc
,
NR_CellGroupConfig_t
*
cellGroupConfig
)
{
{
NR_UE_Timers_Constants_t
*
tac
=
&
rrc
->
timers_and_constants
;
NR_UE_Timers_Constants_t
*
tac
=
&
rrc
->
timers_and_constants
;
...
@@ -768,12 +763,12 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
...
@@ -768,12 +763,12 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
rrc
->
rnti
=
reconfigurationWithSync
->
newUE_Identity
;
rrc
->
rnti
=
reconfigurationWithSync
->
newUE_Identity
;
// resume suspended radio bearers
// resume suspended radio bearers
for
(
int
i
=
0
;
i
<
NR_NUM_SRB
;
i
++
)
{
for
(
int
i
=
0
;
i
<
NR_NUM_SRB
;
i
++
)
{
if
(
rrc
NB
->
Srb
[
i
]
==
RB_SUSPENDED
)
if
(
rrc
->
Srb
[
i
]
==
RB_SUSPENDED
)
rrc
NB
->
Srb
[
i
]
=
RB_ESTABLISHED
;
rrc
->
Srb
[
i
]
=
RB_ESTABLISHED
;
}
}
for
(
int
i
=
0
;
i
<
MAX_DRBS_PER_UE
;
i
++
)
{
for
(
int
i
=
0
;
i
<
MAX_DRBS_PER_UE
;
i
++
)
{
if
(
rrc
NB
->
status_DRBs
[
i
]
==
RB_SUSPENDED
)
if
(
rrc
->
status_DRBs
[
i
]
==
RB_SUSPENDED
)
rrc
NB
->
status_DRBs
[
i
]
=
RB_ESTABLISHED
;
rrc
->
status_DRBs
[
i
]
=
RB_ESTABLISHED
;
}
}
// TODO reset MAC
// TODO reset MAC
}
}
...
@@ -787,7 +782,7 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
...
@@ -787,7 +782,7 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
}
}
}
}
nr_rrc_manage_rlc_bearers
(
rrc
,
cellGroupConfig
,
rrcNB
);
nr_rrc_manage_rlc_bearers
(
rrc
,
cellGroupConfig
);
AssertFatal
(
cellGroupConfig
->
sCellToReleaseList
==
NULL
,
AssertFatal
(
cellGroupConfig
->
sCellToReleaseList
==
NULL
,
"Secondary serving cell release not implemented
\n
"
);
"Secondary serving cell release not implemented
\n
"
);
...
@@ -798,7 +793,6 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
...
@@ -798,7 +793,6 @@ void nr_rrc_cellgroup_configuration(rrcPerNB_t *rrcNB, NR_UE_RRC_INST_t *rrc, NR
static
void
nr_rrc_ue_process_masterCellGroup
(
NR_UE_RRC_INST_t
*
rrc
,
static
void
nr_rrc_ue_process_masterCellGroup
(
NR_UE_RRC_INST_t
*
rrc
,
rrcPerNB_t
*
rrcNB
,
OCTET_STRING_t
*
masterCellGroup
,
OCTET_STRING_t
*
masterCellGroup
,
long
*
fullConfig
)
long
*
fullConfig
)
{
{
...
@@ -814,7 +808,7 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
...
@@ -814,7 +808,7 @@ static void nr_rrc_ue_process_masterCellGroup(NR_UE_RRC_INST_t *rrc,
xer_fprint
(
stdout
,
&
asn_DEF_NR_CellGroupConfig
,
(
const
void
*
)
cellGroupConfig
);
xer_fprint
(
stdout
,
&
asn_DEF_NR_CellGroupConfig
,
(
const
void
*
)
cellGroupConfig
);
}
}
nr_rrc_cellgroup_configuration
(
rrc
NB
,
rrc
,
cellGroupConfig
);
nr_rrc_cellgroup_configuration
(
rrc
,
cellGroupConfig
);
LOG_D
(
RRC
,
"Sending CellGroupConfig to MAC
\n
"
);
LOG_D
(
RRC
,
"Sending CellGroupConfig to MAC
\n
"
);
nr_rrc_mac_config_req_cg
(
rrc
->
ue_id
,
0
,
cellGroupConfig
,
rrc
->
UECap
.
UE_NR_Capability
);
nr_rrc_mac_config_req_cg
(
rrc
->
ue_id
,
0
,
cellGroupConfig
,
rrc
->
UECap
.
UE_NR_Capability
);
...
@@ -848,7 +842,6 @@ static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const
...
@@ -848,7 +842,6 @@ static void rrc_ue_generate_RRCSetupComplete(const NR_UE_RRC_INST_t *rrc, const
}
}
static
void
nr_rrc_process_rrcsetup
(
NR_UE_RRC_INST_t
*
rrc
,
static
void
nr_rrc_process_rrcsetup
(
NR_UE_RRC_INST_t
*
rrc
,
const
uint8_t
gNB_index
,
const
NR_RRCSetup_t
*
rrcSetup
)
const
NR_RRCSetup_t
*
rrcSetup
)
{
{
// if the RRCSetup is received in response to an RRCReestablishmentRequest
// if the RRCSetup is received in response to an RRCReestablishmentRequest
...
@@ -857,12 +850,10 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc,
...
@@ -857,12 +850,10 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc,
// perform the cell group configuration procedure in accordance with the received masterCellGroup
// perform the cell group configuration procedure in accordance with the received masterCellGroup
nr_rrc_ue_process_masterCellGroup
(
rrc
,
nr_rrc_ue_process_masterCellGroup
(
rrc
,
rrc
->
perNB
+
gNB_index
,
&
rrcSetup
->
criticalExtensions
.
choice
.
rrcSetup
->
masterCellGroup
,
&
rrcSetup
->
criticalExtensions
.
choice
.
rrcSetup
->
masterCellGroup
,
NULL
);
NULL
);
// perform the radio bearer configuration procedure in accordance with the received radioBearerConfig
// perform the radio bearer configuration procedure in accordance with the received radioBearerConfig
nr_rrc_ue_process_RadioBearerConfig
(
rrc
,
nr_rrc_ue_process_RadioBearerConfig
(
rrc
,
rrc
->
perNB
+
gNB_index
,
&
rrcSetup
->
criticalExtensions
.
choice
.
rrcSetup
->
radioBearerConfig
);
&
rrcSetup
->
criticalExtensions
.
choice
.
rrcSetup
->
radioBearerConfig
);
// TODO (not handled) if stored, discard the cell reselection priority information provided by
// TODO (not handled) if stored, discard the cell reselection priority information provided by
...
@@ -887,8 +878,7 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc,
...
@@ -887,8 +878,7 @@ static void nr_rrc_process_rrcsetup(NR_UE_RRC_INST_t *rrc,
}
}
static
int8_t
nr_rrc_ue_decode_ccch
(
NR_UE_RRC_INST_t
*
rrc
,
static
int8_t
nr_rrc_ue_decode_ccch
(
NR_UE_RRC_INST_t
*
rrc
,
const
NRRrcMacCcchDataInd
*
ind
,
const
NRRrcMacCcchDataInd
*
ind
)
const
uint8_t
gNB_index
)
{
{
NR_DL_CCCH_Message_t
*
dl_ccch_msg
=
NULL
;
NR_DL_CCCH_Message_t
*
dl_ccch_msg
=
NULL
;
asn_dec_rval_t
dec_rval
;
asn_dec_rval_t
dec_rval
;
...
@@ -921,7 +911,7 @@ static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc,
...
@@ -921,7 +911,7 @@ static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc,
case
NR_DL_CCCH_MessageType__c1_PR_rrcSetup
:
case
NR_DL_CCCH_MessageType__c1_PR_rrcSetup
:
LOG_I
(
NR_RRC
,
"[UE%ld][RAPROC] Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup
\n
"
,
rrc
->
ue_id
);
LOG_I
(
NR_RRC
,
"[UE%ld][RAPROC] Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup
\n
"
,
rrc
->
ue_id
);
nr_rrc_process_rrcsetup
(
rrc
,
gNB_index
,
dl_ccch_msg
->
message
.
choice
.
c1
->
choice
.
rrcSetup
);
nr_rrc_process_rrcsetup
(
rrc
,
dl_ccch_msg
->
message
.
choice
.
c1
->
choice
.
rrcSetup
);
rval
=
0
;
rval
=
0
;
break
;
break
;
...
@@ -938,11 +928,10 @@ static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc,
...
@@ -938,11 +928,10 @@ static int8_t nr_rrc_ue_decode_ccch(NR_UE_RRC_INST_t *rrc,
}
}
static
void
nr_rrc_ue_process_securityModeCommand
(
NR_UE_RRC_INST_t
*
ue_rrc
,
static
void
nr_rrc_ue_process_securityModeCommand
(
NR_UE_RRC_INST_t
*
ue_rrc
,
NR_SecurityModeCommand_t
*
const
securityModeCommand
,
NR_SecurityModeCommand_t
*
const
securityModeCommand
)
const
uint8_t
gNB_index
)
{
{
int
securityMode
=
0
;
int
securityMode
=
0
;
LOG_I
(
NR_RRC
,
"Receiving from SRB1 (DL-DCCH), Processing securityModeCommand
(eNB %d)
\n
"
,
gNB_index
);
LOG_I
(
NR_RRC
,
"Receiving from SRB1 (DL-DCCH), Processing securityModeCommand
\n
"
);
NR_SecurityConfigSMC_t
*
securityConfigSMC
=
NR_SecurityConfigSMC_t
*
securityConfigSMC
=
&
securityModeCommand
->
criticalExtensions
.
choice
.
securityModeCommand
->
securityConfigSMC
;
&
securityModeCommand
->
criticalExtensions
.
choice
.
securityModeCommand
->
securityConfigSMC
;
...
@@ -1011,7 +1000,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
...
@@ -1011,7 +1000,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
uint8_t
security_mode
=
ue_rrc
->
cipheringAlgorithm
|
(
ue_rrc
->
integrityProtAlgorithm
<<
4
);
uint8_t
security_mode
=
ue_rrc
->
cipheringAlgorithm
|
(
ue_rrc
->
integrityProtAlgorithm
<<
4
);
// configure lower layers to apply SRB integrity protection and ciphering
// configure lower layers to apply SRB integrity protection and ciphering
for
(
int
i
=
1
;
i
<
NR_NUM_SRB
;
i
++
)
{
for
(
int
i
=
1
;
i
<
NR_NUM_SRB
;
i
++
)
{
if
(
ue_rrc
->
perNB
[
gNB_index
].
Srb
[
i
]
==
RB_ESTABLISHED
)
if
(
ue_rrc
->
Srb
[
i
]
==
RB_ESTABLISHED
)
nr_pdcp_config_set_security
(
ue_rrc
->
ue_id
,
i
,
security_mode
,
kRRCenc
,
kRRCint
,
kUPenc
);
nr_pdcp_config_set_security
(
ue_rrc
->
ue_id
,
i
,
security_mode
,
kRRCenc
,
kRRCint
,
kUPenc
);
}
}
}
else
{
}
else
{
...
@@ -1025,8 +1014,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
...
@@ -1025,8 +1014,7 @@ static void nr_rrc_ue_process_securityModeCommand(NR_UE_RRC_INST_t *ue_rrc,
asn1cCalloc
(
modeComplete
->
criticalExtensions
.
choice
.
securityModeComplete
,
ext
);
asn1cCalloc
(
modeComplete
->
criticalExtensions
.
choice
.
securityModeComplete
,
ext
);
ext
->
nonCriticalExtension
=
NULL
;
ext
->
nonCriticalExtension
=
NULL
;
LOG_I
(
NR_RRC
,
LOG_I
(
NR_RRC
,
"Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (gNB %d), rrc_TransactionIdentifier: %ld
\n
"
,
"Receiving from SRB1 (DL-DCCH), encoding securityModeComplete, rrc_TransactionIdentifier: %ld
\n
"
,
gNB_index
,
securityModeCommand
->
rrc_TransactionIdentifier
);
securityModeCommand
->
rrc_TransactionIdentifier
);
uint8_t
buffer
[
200
];
uint8_t
buffer
[
200
];
asn_enc_rval_t
enc_rval
=
asn_enc_rval_t
enc_rval
=
...
@@ -1171,7 +1159,6 @@ void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measCo
...
@@ -1171,7 +1159,6 @@ void nr_rrc_ue_process_measConfig(rrcPerNB_t *rrc, NR_MeasConfig_t *const measCo
}
}
static
void
nr_rrc_ue_process_RadioBearerConfig
(
NR_UE_RRC_INST_t
*
ue_rrc
,
static
void
nr_rrc_ue_process_RadioBearerConfig
(
NR_UE_RRC_INST_t
*
ue_rrc
,
rrcPerNB_t
*
rrcNB
,
NR_RadioBearerConfig_t
*
const
radioBearerConfig
)
NR_RadioBearerConfig_t
*
const
radioBearerConfig
)
{
{
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
if
(
LOG_DEBUGFLAG
(
DEBUG_ASN1
))
...
@@ -1203,7 +1190,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
...
@@ -1203,7 +1190,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
if
(
radioBearerConfig
->
srb_ToAddModList
!=
NULL
)
{
if
(
radioBearerConfig
->
srb_ToAddModList
!=
NULL
)
{
for
(
int
cnt
=
0
;
cnt
<
radioBearerConfig
->
srb_ToAddModList
->
list
.
count
;
cnt
++
)
{
for
(
int
cnt
=
0
;
cnt
<
radioBearerConfig
->
srb_ToAddModList
->
list
.
count
;
cnt
++
)
{
struct
NR_SRB_ToAddMod
*
srb
=
radioBearerConfig
->
srb_ToAddModList
->
list
.
array
[
cnt
];
struct
NR_SRB_ToAddMod
*
srb
=
radioBearerConfig
->
srb_ToAddModList
->
list
.
array
[
cnt
];
if
(
rrcNB
->
Srb
[
srb
->
srb_Identity
]
==
RB_NOT_PRESENT
)
if
(
ue_rrc
->
Srb
[
srb
->
srb_Identity
]
==
RB_NOT_PRESENT
)
add_srb
(
false
,
add_srb
(
false
,
ue_rrc
->
ue_id
,
ue_rrc
->
ue_id
,
radioBearerConfig
->
srb_ToAddModList
->
list
.
array
[
cnt
],
radioBearerConfig
->
srb_ToAddModList
->
list
.
array
[
cnt
],
...
@@ -1217,7 +1204,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
...
@@ -1217,7 +1204,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
if
(
srb
->
pdcp_Config
&&
srb
->
pdcp_Config
->
t_Reordering
)
if
(
srb
->
pdcp_Config
&&
srb
->
pdcp_Config
->
t_Reordering
)
nr_pdcp_reconfigure_srb
(
ue_rrc
->
ue_id
,
srb
->
srb_Identity
,
*
srb
->
pdcp_Config
->
t_Reordering
);
nr_pdcp_reconfigure_srb
(
ue_rrc
->
ue_id
,
srb
->
srb_Identity
,
*
srb
->
pdcp_Config
->
t_Reordering
);
}
}
rrcNB
->
Srb
[
srb
->
srb_Identity
]
=
RB_ESTABLISHED
;
ue_rrc
->
Srb
[
srb
->
srb_Identity
]
=
RB_ESTABLISHED
;
}
}
}
}
...
@@ -1234,7 +1221,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
...
@@ -1234,7 +1221,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
for
(
int
cnt
=
0
;
cnt
<
radioBearerConfig
->
drb_ToAddModList
->
list
.
count
;
cnt
++
)
{
for
(
int
cnt
=
0
;
cnt
<
radioBearerConfig
->
drb_ToAddModList
->
list
.
count
;
cnt
++
)
{
struct
NR_DRB_ToAddMod
*
drb
=
radioBearerConfig
->
drb_ToAddModList
->
list
.
array
[
cnt
];
struct
NR_DRB_ToAddMod
*
drb
=
radioBearerConfig
->
drb_ToAddModList
->
list
.
array
[
cnt
];
int
DRB_id
=
drb
->
drb_Identity
;
int
DRB_id
=
drb
->
drb_Identity
;
if
(
rrcNB
->
status_DRBs
[
DRB_id
]
==
RB_ESTABLISHED
)
{
if
(
ue_rrc
->
status_DRBs
[
DRB_id
]
==
RB_ESTABLISHED
)
{
AssertFatal
(
drb
->
reestablishPDCP
==
NULL
,
"reestablishPDCP not yet implemented
\n
"
);
AssertFatal
(
drb
->
reestablishPDCP
==
NULL
,
"reestablishPDCP not yet implemented
\n
"
);
AssertFatal
(
drb
->
recoverPDCP
==
NULL
,
"recoverPDCP not yet implemented
\n
"
);
AssertFatal
(
drb
->
recoverPDCP
==
NULL
,
"recoverPDCP not yet implemented
\n
"
);
NR_SDAP_Config_t
*
sdap_Config
=
drb
->
cnAssociation
?
drb
->
cnAssociation
->
choice
.
sdap_Config
:
NULL
;
NR_SDAP_Config_t
*
sdap_Config
=
drb
->
cnAssociation
?
drb
->
cnAssociation
->
choice
.
sdap_Config
:
NULL
;
...
@@ -1243,7 +1230,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
...
@@ -1243,7 +1230,7 @@ static void nr_rrc_ue_process_RadioBearerConfig(NR_UE_RRC_INST_t *ue_rrc,
if
(
drb
->
cnAssociation
)
if
(
drb
->
cnAssociation
)
AssertFatal
(
drb
->
cnAssociation
->
choice
.
sdap_Config
==
NULL
,
"SDAP reconfiguration not yet implemented
\n
"
);
AssertFatal
(
drb
->
cnAssociation
->
choice
.
sdap_Config
==
NULL
,
"SDAP reconfiguration not yet implemented
\n
"
);
}
else
{
}
else
{
rrcNB
->
status_DRBs
[
DRB_id
]
=
RB_ESTABLISHED
;
ue_rrc
->
status_DRBs
[
DRB_id
]
=
RB_ESTABLISHED
;
add_drb
(
false
,
add_drb
(
false
,
ue_rrc
->
ue_id
,
ue_rrc
->
ue_id
,
radioBearerConfig
->
drb_ToAddModList
->
list
.
array
[
cnt
],
radioBearerConfig
->
drb_ToAddModList
->
list
.
array
[
cnt
],
...
@@ -1361,7 +1348,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
...
@@ -1361,7 +1348,7 @@ static int nr_rrc_ue_decode_dcch(NR_UE_RRC_INST_t *rrc,
break
;
break
;
case
NR_DL_DCCH_MessageType__c1_PR_securityModeCommand
:
case
NR_DL_DCCH_MessageType__c1_PR_securityModeCommand
:
LOG_I
(
NR_RRC
,
"Received securityModeCommand (gNB %d)
\n
"
,
gNB_indexP
);
LOG_I
(
NR_RRC
,
"Received securityModeCommand (gNB %d)
\n
"
,
gNB_indexP
);
nr_rrc_ue_process_securityModeCommand
(
rrc
,
c1
->
choice
.
securityModeCommand
,
gNB_indexP
);
nr_rrc_ue_process_securityModeCommand
(
rrc
,
c1
->
choice
.
securityModeCommand
);
break
;
break
;
}
}
}
break
;
}
break
;
...
@@ -1458,7 +1445,7 @@ void *rrc_nrue(void *notUsed)
...
@@ -1458,7 +1445,7 @@ void *rrc_nrue(void *notUsed)
case
NR_RRC_MAC_CCCH_DATA_IND
:
{
case
NR_RRC_MAC_CCCH_DATA_IND
:
{
NRRrcMacCcchDataInd
*
ind
=
&
NR_RRC_MAC_CCCH_DATA_IND
(
msg_p
);
NRRrcMacCcchDataInd
*
ind
=
&
NR_RRC_MAC_CCCH_DATA_IND
(
msg_p
);
nr_rrc_ue_decode_ccch
(
rrc
,
ind
,
0
);
nr_rrc_ue_decode_ccch
(
rrc
,
ind
);
}
break
;
}
break
;
case
NR_RRC_DCCH_DATA_IND
:
case
NR_RRC_DCCH_DATA_IND
:
...
@@ -1490,7 +1477,7 @@ void *rrc_nrue(void *notUsed)
...
@@ -1490,7 +1477,7 @@ void *rrc_nrue(void *notUsed)
/* Transfer data to PDCP */
/* Transfer data to PDCP */
// check if SRB2 is created, if yes request data_req on SRB2
// check if SRB2 is created, if yes request data_req on SRB2
// error: the remote gNB is hardcoded here
// error: the remote gNB is hardcoded here
rb_id_t
srb_id
=
rrc
->
perNB
[
0
].
Srb
[
2
]
==
RB_ESTABLISHED
?
2
:
1
;
rb_id_t
srb_id
=
rrc
->
Srb
[
2
]
==
RB_ESTABLISHED
?
2
:
1
;
nr_pdcp_data_req_srb
(
rrc
->
ue_id
,
srb_id
,
0
,
length
,
buffer
,
deliver_pdu_srb_rlc
,
NULL
);
nr_pdcp_data_req_srb
(
rrc
->
ue_id
,
srb_id
,
0
,
length
,
buffer
,
deliver_pdu_srb_rlc
,
NULL
);
break
;
break
;
}
}
...
@@ -1591,7 +1578,6 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa
...
@@ -1591,7 +1578,6 @@ static void nr_rrc_ue_process_ueCapabilityEnquiry(NR_UE_RRC_INST_t *rrc, NR_UECa
}
}
static
void
nr_rrc_ue_generate_rrcReestablishmentComplete
(
NR_RRCReestablishment_t
*
rrcReestablishment
)
static
void
nr_rrc_ue_generate_rrcReestablishmentComplete
(
NR_RRCReestablishment_t
*
rrcReestablishment
)
//-----------------------------------------------------------------------------
{
{
uint8_t
buffer
[
RRC_BUFFER_SIZE
]
=
{
0
};
uint8_t
buffer
[
RRC_BUFFER_SIZE
]
=
{
0
};
int
size
=
do_RRCReestablishmentComplete
(
buffer
,
RRC_BUFFER_SIZE
,
int
size
=
do_RRCReestablishmentComplete
(
buffer
,
RRC_BUFFER_SIZE
,
...
@@ -1603,18 +1589,14 @@ void *recv_msgs_from_lte_ue(void *args_p)
...
@@ -1603,18 +1589,14 @@ void *recv_msgs_from_lte_ue(void *args_p)
{
{
itti_mark_task_ready
(
TASK_RRC_NSA_NRUE
);
itti_mark_task_ready
(
TASK_RRC_NSA_NRUE
);
int
from_lte_ue_fd
=
get_from_lte_ue_fd
();
int
from_lte_ue_fd
=
get_from_lte_ue_fd
();
for
(;;)
for
(;;)
{
{
nsa_msg_t
msg
;
nsa_msg_t
msg
;
int
recvLen
=
recvfrom
(
from_lte_ue_fd
,
&
msg
,
sizeof
(
msg
),
int
recvLen
=
recvfrom
(
from_lte_ue_fd
,
&
msg
,
sizeof
(
msg
),
MSG_WAITALL
|
MSG_TRUNC
,
NULL
,
NULL
);
MSG_WAITALL
|
MSG_TRUNC
,
NULL
,
NULL
);
if
(
recvLen
==
-
1
)
{
if
(
recvLen
==
-
1
)
{
LOG_E
(
NR_RRC
,
"%s: recvfrom: %s
\n
"
,
__func__
,
strerror
(
errno
));
LOG_E
(
NR_RRC
,
"%s: recvfrom: %s
\n
"
,
__func__
,
strerror
(
errno
));
continue
;
continue
;
}
}
if
(
recvLen
>
sizeof
(
msg
))
if
(
recvLen
>
sizeof
(
msg
))
{
{
LOG_E
(
NR_RRC
,
"%s: Received truncated message %d
\n
"
,
__func__
,
recvLen
);
LOG_E
(
NR_RRC
,
"%s: Received truncated message %d
\n
"
,
__func__
,
recvLen
);
continue
;
continue
;
}
}
...
@@ -1623,9 +1605,9 @@ void *recv_msgs_from_lte_ue(void *args_p)
...
@@ -1623,9 +1605,9 @@ void *recv_msgs_from_lte_ue(void *args_p)
return
NULL
;
return
NULL
;
}
}
static
void
nsa_rrc_ue_process_ueCapabilityEnquiry
(
void
)
static
void
nsa_rrc_ue_process_ueCapabilityEnquiry
(
NR_UE_RRC_INST_t
*
rrc
)
{
{
NR_UE_NR_Capability_t
*
UE_Capability_nr
=
NR_UE_rrc_inst
[
0
].
UECap
.
UE_NR_Capability
=
CALLOC
(
1
,
sizeof
(
NR_UE_NR_Capability_t
));
NR_UE_NR_Capability_t
*
UE_Capability_nr
=
rrc
->
UECap
.
UE_NR_Capability
=
CALLOC
(
1
,
sizeof
(
NR_UE_NR_Capability_t
));
NR_BandNR_t
*
nr_bandnr
=
CALLOC
(
1
,
sizeof
(
NR_BandNR_t
));
NR_BandNR_t
*
nr_bandnr
=
CALLOC
(
1
,
sizeof
(
NR_BandNR_t
));
nr_bandnr
->
bandNR
=
78
;
nr_bandnr
->
bandNR
=
78
;
asn1cSeqAdd
(
&
UE_Capability_nr
->
rf_Parameters
.
supportedBandListNR
.
list
,
nr_bandnr
);
asn1cSeqAdd
(
&
UE_Capability_nr
->
rf_Parameters
.
supportedBandListNR
.
list
,
nr_bandnr
);
...
@@ -1647,8 +1629,8 @@ static void nsa_rrc_ue_process_ueCapabilityEnquiry(void)
...
@@ -1647,8 +1629,8 @@ static void nsa_rrc_ue_process_ueCapabilityEnquiry(void)
memset
(
&
ue_CapabilityRAT_Container
,
0
,
sizeof
(
NR_UE_CapabilityRAT_Container_t
));
memset
(
&
ue_CapabilityRAT_Container
,
0
,
sizeof
(
NR_UE_CapabilityRAT_Container_t
));
ue_CapabilityRAT_Container
.
rat_Type
=
NR_RAT_Type_nr
;
ue_CapabilityRAT_Container
.
rat_Type
=
NR_RAT_Type_nr
;
OCTET_STRING_fromBuf
(
&
ue_CapabilityRAT_Container
.
ue_CapabilityRAT_Container
,
OCTET_STRING_fromBuf
(
&
ue_CapabilityRAT_Container
.
ue_CapabilityRAT_Container
,
(
const
char
*
)
NR_UE_rrc_inst
[
0
].
UECap
.
sdu
,
(
const
char
*
)
rrc
->
UECap
.
sdu
,
NR_UE_rrc_inst
[
0
].
UECap
.
sdu_size
);
rrc
->
UECap
.
sdu_size
);
nsa_sendmsg_to_lte_ue
(
ue_CapabilityRAT_Container
.
ue_CapabilityRAT_Container
.
buf
,
nsa_sendmsg_to_lte_ue
(
ue_CapabilityRAT_Container
.
ue_CapabilityRAT_Container
.
buf
,
ue_CapabilityRAT_Container
.
ue_CapabilityRAT_Container
.
size
,
ue_CapabilityRAT_Container
.
ue_CapabilityRAT_Container
.
size
,
...
@@ -1657,8 +1639,7 @@ static void nsa_rrc_ue_process_ueCapabilityEnquiry(void)
...
@@ -1657,8 +1639,7 @@ static void nsa_rrc_ue_process_ueCapabilityEnquiry(void)
static
void
process_lte_nsa_msg
(
NR_UE_RRC_INST_t
*
rrc
,
nsa_msg_t
*
msg
,
int
msg_len
)
static
void
process_lte_nsa_msg
(
NR_UE_RRC_INST_t
*
rrc
,
nsa_msg_t
*
msg
,
int
msg_len
)
{
{
if
(
msg_len
<
sizeof
(
msg
->
msg_type
))
if
(
msg_len
<
sizeof
(
msg
->
msg_type
))
{
{
LOG_E
(
RRC
,
"Msg_len = %d
\n
"
,
msg_len
);
LOG_E
(
RRC
,
"Msg_len = %d
\n
"
,
msg_len
);
return
;
return
;
}
}
...
@@ -1666,10 +1647,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
...
@@ -1666,10 +1647,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
Rrc_Msg_Type_t
msg_type
=
msg
->
msg_type
;
Rrc_Msg_Type_t
msg_type
=
msg
->
msg_type
;
uint8_t
*
const
msg_buffer
=
msg
->
msg_buffer
;
uint8_t
*
const
msg_buffer
=
msg
->
msg_buffer
;
msg_len
-=
sizeof
(
msg
->
msg_type
);
msg_len
-=
sizeof
(
msg
->
msg_type
);
switch
(
msg_type
)
switch
(
msg_type
)
{
{
case
UE_CAPABILITY_ENQUIRY
:
{
case
UE_CAPABILITY_ENQUIRY
:
{
LOG_D
(
NR_RRC
,
"We are processing a %d message
\n
"
,
msg_type
);
LOG_D
(
NR_RRC
,
"We are processing a %d message
\n
"
,
msg_type
);
NR_FreqBandList_t
*
nr_freq_band_list
=
NULL
;
NR_FreqBandList_t
*
nr_freq_band_list
=
NULL
;
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
...
@@ -1677,14 +1656,12 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
...
@@ -1677,14 +1656,12 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
(
void
**
)
&
nr_freq_band_list
,
(
void
**
)
&
nr_freq_band_list
,
msg_buffer
,
msg_buffer
,
msg_len
);
msg_len
);
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
{
{
SEQUENCE_free
(
&
asn_DEF_NR_FreqBandList
,
nr_freq_band_list
,
ASFM_FREE_EVERYTHING
);
SEQUENCE_free
(
&
asn_DEF_NR_FreqBandList
,
nr_freq_band_list
,
ASFM_FREE_EVERYTHING
);
LOG_E
(
RRC
,
"Failed to decode UECapabilityInfo (%zu bits)
\n
"
,
dec_rval
.
consumed
);
LOG_E
(
RRC
,
"Failed to decode UECapabilityInfo (%zu bits)
\n
"
,
dec_rval
.
consumed
);
break
;
break
;
}
}
for
(
int
i
=
0
;
i
<
nr_freq_band_list
->
list
.
count
;
i
++
)
for
(
int
i
=
0
;
i
<
nr_freq_band_list
->
list
.
count
;
i
++
)
{
{
LOG_D
(
NR_RRC
,
"Received NR band information: %ld.
\n
"
,
LOG_D
(
NR_RRC
,
"Received NR band information: %ld.
\n
"
,
nr_freq_band_list
->
list
.
array
[
i
]
->
choice
.
bandInformationNR
->
bandNR
);
nr_freq_band_list
->
list
.
array
[
i
]
->
choice
.
bandInformationNR
->
bandNR
);
}
}
...
@@ -1695,8 +1672,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
...
@@ -1695,8 +1672,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
break
;
break
;
}
}
case
NRUE_CAPABILITY_ENQUIRY
:
case
NRUE_CAPABILITY_ENQUIRY
:
{
{
LOG_I
(
NR_RRC
,
"We are processing a %d message
\n
"
,
msg_type
);
LOG_I
(
NR_RRC
,
"We are processing a %d message
\n
"
,
msg_type
);
NR_FreqBandList_t
*
nr_freq_band_list
=
NULL
;
NR_FreqBandList_t
*
nr_freq_band_list
=
NULL
;
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
...
@@ -1704,19 +1680,17 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
...
@@ -1704,19 +1680,17 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
(
void
**
)
&
nr_freq_band_list
,
(
void
**
)
&
nr_freq_band_list
,
msg_buffer
,
msg_buffer
,
msg_len
);
msg_len
);
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
{
{
SEQUENCE_free
(
&
asn_DEF_NR_FreqBandList
,
nr_freq_band_list
,
ASFM_FREE_EVERYTHING
);
SEQUENCE_free
(
&
asn_DEF_NR_FreqBandList
,
nr_freq_band_list
,
ASFM_FREE_EVERYTHING
);
LOG_E
(
NR_RRC
,
"Failed to decode UECapabilityInfo (%zu bits)
\n
"
,
dec_rval
.
consumed
);
LOG_E
(
NR_RRC
,
"Failed to decode UECapabilityInfo (%zu bits)
\n
"
,
dec_rval
.
consumed
);
break
;
break
;
}
}
LOG_I
(
NR_RRC
,
"Calling nsa_rrc_ue_process_ueCapabilityEnquiry
\n
"
);
LOG_I
(
NR_RRC
,
"Calling nsa_rrc_ue_process_ueCapabilityEnquiry
\n
"
);
nsa_rrc_ue_process_ueCapabilityEnquiry
(
);
nsa_rrc_ue_process_ueCapabilityEnquiry
(
rrc
);
break
;
break
;
}
}
case
RRC_MEASUREMENT_PROCEDURE
:
case
RRC_MEASUREMENT_PROCEDURE
:
{
{
LOG_I
(
NR_RRC
,
"We are processing a %d message
\n
"
,
msg_type
);
LOG_I
(
NR_RRC
,
"We are processing a %d message
\n
"
,
msg_type
);
LTE_MeasObjectToAddMod_t
*
nr_meas_obj
=
NULL
;
LTE_MeasObjectToAddMod_t
*
nr_meas_obj
=
NULL
;
...
@@ -1725,8 +1699,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
...
@@ -1725,8 +1699,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
(
void
**
)
&
nr_meas_obj
,
(
void
**
)
&
nr_meas_obj
,
msg_buffer
,
msg_buffer
,
msg_len
);
msg_len
);
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
if
((
dec_rval
.
code
!=
RC_OK
)
&&
(
dec_rval
.
consumed
==
0
))
{
{
SEQUENCE_free
(
&
asn_DEF_NR_MeasObjectToAddMod
,
nr_meas_obj
,
ASFM_FREE_EVERYTHING
);
SEQUENCE_free
(
&
asn_DEF_NR_MeasObjectToAddMod
,
nr_meas_obj
,
ASFM_FREE_EVERYTHING
);
LOG_E
(
RRC
,
"Failed to decode measurement object (%zu bits) %d
\n
"
,
dec_rval
.
consumed
,
dec_rval
.
code
);
LOG_E
(
RRC
,
"Failed to decode measurement object (%zu bits) %d
\n
"
,
dec_rval
.
consumed
,
dec_rval
.
code
);
break
;
break
;
...
@@ -1737,8 +1710,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
...
@@ -1737,8 +1710,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
start_oai_nrue_threads
();
start_oai_nrue_threads
();
break
;
break
;
}
}
case
RRC_CONFIG_COMPLETE_REQ
:
{
case
RRC_CONFIG_COMPLETE_REQ
:
{
struct
msg
{
struct
msg
{
uint32_t
RadioBearer_size
;
uint32_t
RadioBearer_size
;
uint32_t
SecondaryCellGroup_size
;
uint32_t
SecondaryCellGroup_size
;
...
@@ -1755,7 +1728,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
...
@@ -1755,7 +1728,8 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
"nr_RadioBearerConfig1_r15 size %u nr_SecondaryCellGroupConfig_r15 size %u sizeof(hdr) %zu, msg_len = %d
\n
"
,
"nr_RadioBearerConfig1_r15 size %u nr_SecondaryCellGroupConfig_r15 size %u sizeof(hdr) %zu, msg_len = %d
\n
"
,
nr_RadioBearer_size
,
nr_RadioBearer_size
,
nr_SecondaryCellGroup_size
,
nr_SecondaryCellGroup_size
,
sizeof
(
hdr
),
msg_len
);
sizeof
(
hdr
),
msg_len
);
NR_RRC_TransactionIdentifier_t
t_id
=
hdr
.
trans_id
;
NR_RRC_TransactionIdentifier_t
t_id
=
hdr
.
trans_id
;
LOG_I
(
NR_RRC
,
"nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d t_id %ld
\n
"
,
LOG_I
(
NR_RRC
,
"nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d t_id %ld
\n
"
,
nr_RadioBearer_size
,
nr_RadioBearer_size
,
...
@@ -1764,8 +1738,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
...
@@ -1764,8 +1738,7 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
uint8_t
*
nr_RadioBearer_buffer
=
msg_buffer
+
offsetof
(
struct
msg
,
buffer
);
uint8_t
*
nr_RadioBearer_buffer
=
msg_buffer
+
offsetof
(
struct
msg
,
buffer
);
uint8_t
*
nr_SecondaryCellGroup_buffer
=
nr_RadioBearer_buffer
+
nr_RadioBearer_size
;
uint8_t
*
nr_SecondaryCellGroup_buffer
=
nr_RadioBearer_buffer
+
nr_RadioBearer_size
;
process_nsa_message
(
NR_UE_rrc_inst
,
nr_SecondaryCellGroupConfig_r15
,
nr_SecondaryCellGroup_buffer
,
process_nsa_message
(
NR_UE_rrc_inst
,
nr_SecondaryCellGroupConfig_r15
,
nr_SecondaryCellGroup_buffer
,
nr_SecondaryCellGroup_size
);
nr_SecondaryCellGroup_size
);
process_nsa_message
(
NR_UE_rrc_inst
,
nr_RadioBearerConfigX_r15
,
nr_RadioBearer_buffer
,
nr_RadioBearer_size
);
process_nsa_message
(
NR_UE_rrc_inst
,
nr_RadioBearerConfigX_r15
,
nr_RadioBearer_buffer
,
nr_RadioBearer_size
);
LOG_I
(
NR_RRC
,
"Calling do_NR_RRCReconfigurationComplete. t_id %ld
\n
"
,
t_id
);
LOG_I
(
NR_RRC
,
"Calling do_NR_RRCReconfigurationComplete. t_id %ld
\n
"
,
t_id
);
uint8_t
buffer
[
RRC_BUF_SIZE
];
uint8_t
buffer
[
RRC_BUF_SIZE
];
...
@@ -1774,16 +1747,13 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
...
@@ -1774,16 +1747,13 @@ static void process_lte_nsa_msg(NR_UE_RRC_INST_t *rrc, nsa_msg_t *msg, int msg_l
break
;
break
;
}
}
case
OAI_TUN_IFACE_NSA
:
case
OAI_TUN_IFACE_NSA
:
{
{
LOG_I
(
NR_RRC
,
"We got an OAI_TUN_IFACE_NSA!!
\n
"
);
LOG_I
(
NR_RRC
,
"We got an OAI_TUN_IFACE_NSA!!
\n
"
);
char
cmd_line
[
RRC_BUF_SIZE
];
char
cmd_line
[
RRC_BUF_SIZE
];
memcpy
(
cmd_line
,
msg_buffer
,
sizeof
(
cmd_line
));
memcpy
(
cmd_line
,
msg_buffer
,
sizeof
(
cmd_line
));
LOG_D
(
NR_RRC
,
"Command line: %s
\n
"
,
cmd_line
);
LOG_D
(
NR_RRC
,
"Command line: %s
\n
"
,
cmd_line
);
if
(
background_system
(
cmd_line
)
!=
0
)
if
(
background_system
(
cmd_line
)
!=
0
)
{
LOG_E
(
NR_RRC
,
"ESM-PROC - failed command '%s'"
,
cmd_line
);
LOG_E
(
NR_RRC
,
"ESM-PROC - failed command '%s'"
,
cmd_line
);
}
break
;
break
;
}
}
...
@@ -1857,27 +1827,24 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
...
@@ -1857,27 +1827,24 @@ void nr_rrc_going_to_IDLE(NR_UE_RRC_INST_t *rrc,
// release all radio resources, including release of the RLC entity,
// release all radio resources, including release of the RLC entity,
// the MAC configuration and the associated PDCP entity
// the MAC configuration and the associated PDCP entity
// and SDAP for all established RBs
// and SDAP for all established RBs
for
(
int
j
=
0
;
j
<
NB_CNX_UE
;
j
++
)
{
rrcPerNB_t
*
nb
=
&
rrc
->
perNB
[
j
];
for
(
int
i
=
0
;
i
<
MAX_DRBS_PER_UE
;
i
++
)
{
for
(
int
i
=
0
;
i
<
MAX_DRBS_PER_UE
;
i
++
)
{
if
(
nb
->
status_DRBs
[
i
]
!=
RB_NOT_PRESENT
)
{
if
(
rrc
->
status_DRBs
[
i
]
!=
RB_NOT_PRESENT
)
{
nb
->
status_DRBs
[
i
]
=
RB_NOT_PRESENT
;
rrc
->
status_DRBs
[
i
]
=
RB_NOT_PRESENT
;
nr_pdcp_release_drb
(
rrc
->
ue_id
,
i
);
nr_pdcp_release_drb
(
rrc
->
ue_id
,
i
);
}
}
}
}
for
(
int
i
=
1
;
i
<
NR_NUM_SRB
;
i
++
)
{
for
(
int
i
=
1
;
i
<
NR_NUM_SRB
;
i
++
)
{
if
(
nb
->
Srb
[
i
]
!=
RB_NOT_PRESENT
)
{
if
(
rrc
->
Srb
[
i
]
!=
RB_NOT_PRESENT
)
{
nb
->
Srb
[
i
]
=
RB_NOT_PRESENT
;
rrc
->
Srb
[
i
]
=
RB_NOT_PRESENT
;
nr_pdcp_release_srb
(
rrc
->
ue_id
,
i
);
nr_pdcp_release_srb
(
rrc
->
ue_id
,
i
);
}
}
}
}
for
(
int
i
=
0
;
i
<
NR_MAX_NUM_LCID
;
i
++
)
{
for
(
int
i
=
0
;
i
<
NR_MAX_NUM_LCID
;
i
++
)
{
if
(
nb
->
active_RLC_entity
[
i
])
{
if
(
rrc
->
active_RLC_entity
[
i
])
{
nb
->
active_RLC_entity
[
i
]
=
false
;
rrc
->
active_RLC_entity
[
i
]
=
false
;
nr_rlc_release_entity
(
rrc
->
ue_id
,
i
);
nr_rlc_release_entity
(
rrc
->
ue_id
,
i
);
}
}
}
}
}
for
(
int
i
=
0
;
i
<
NB_CNX_UE
;
i
++
)
{
for
(
int
i
=
0
;
i
<
NB_CNX_UE
;
i
++
)
{
rrcPerNB_t
*
nb
=
&
rrc
->
perNB
[
i
];
rrcPerNB_t
*
nb
=
&
rrc
->
perNB
[
i
];
...
...
openair2/RRC/NR_UE/rrc_defs.h
View file @
7337ae86
...
@@ -178,9 +178,6 @@ typedef struct rrcPerNB {
...
@@ -178,9 +178,6 @@ typedef struct rrcPerNB {
NR_QuantityConfig_t
*
QuantityConfig
;
NR_QuantityConfig_t
*
QuantityConfig
;
NR_MeasIdToAddMod_t
*
MeasId
[
MAX_MEAS_ID
];
NR_MeasIdToAddMod_t
*
MeasId
[
MAX_MEAS_ID
];
NR_MeasGapConfig_t
*
measGapConfig
;
NR_MeasGapConfig_t
*
measGapConfig
;
NR_RB_status_t
Srb
[
NR_NUM_SRB
];
NR_RB_status_t
status_DRBs
[
MAX_DRBS_PER_UE
];
bool
active_RLC_entity
[
NR_MAX_NUM_LCID
];
NR_UE_RRC_SI_INFO
SInfo
;
NR_UE_RRC_SI_INFO
SInfo
;
NR_RSRP_Range_t
s_measure
;
NR_RSRP_Range_t
s_measure
;
}
rrcPerNB_t
;
}
rrcPerNB_t
;
...
@@ -199,6 +196,10 @@ typedef struct NR_UE_RRC_INST_s {
...
@@ -199,6 +196,10 @@ typedef struct NR_UE_RRC_INST_s {
NR_BWP_Id_t
dl_bwp_id
;
NR_BWP_Id_t
dl_bwp_id
;
NR_BWP_Id_t
ul_bwp_id
;
NR_BWP_Id_t
ul_bwp_id
;
NR_RB_status_t
Srb
[
NR_NUM_SRB
];
NR_RB_status_t
status_DRBs
[
MAX_DRBS_PER_UE
];
bool
active_RLC_entity
[
NR_MAX_NUM_LCID
];
/* KgNB as computed from parameters within USIM card */
/* KgNB as computed from parameters within USIM card */
uint8_t
kgnb
[
32
];
uint8_t
kgnb
[
32
];
/* Used integrity/ciphering algorithms */
/* Used integrity/ciphering algorithms */
...
...
openair2/RRC/NR_UE/rrc_proto.h
View file @
7337ae86
...
@@ -58,7 +58,7 @@ void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfi
...
@@ -58,7 +58,7 @@ void init_nsa_message (NR_UE_RRC_INST_t *rrc, char* reconfig_file, char* rbconfi
void
process_nsa_message
(
NR_UE_RRC_INST_t
*
rrc
,
nsa_message_t
nsa_message_type
,
void
*
message
,
int
msg_len
);
void
process_nsa_message
(
NR_UE_RRC_INST_t
*
rrc
,
nsa_message_t
nsa_message_type
,
void
*
message
,
int
msg_len
);
void
nr_rrc_cellgroup_configuration
(
rrcPerNB_t
*
rrcNB
,
NR_UE_RRC_INST_t
*
rrc
,
NR_CellGroupConfig_t
*
cellGroupConfig
);
void
nr_rrc_cellgroup_configuration
(
NR_UE_RRC_INST_t
*
rrc
,
NR_CellGroupConfig_t
*
cellGroupConfig
);
/**\brief interface between MAC and RRC thru SRB0 (RLC TM/no PDCP)
/**\brief interface between MAC and RRC thru SRB0 (RLC TM/no PDCP)
\param module_id module id
\param module_id module id
...
...
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