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
d01c1470
Commit
d01c1470
authored
Feb 13, 2024
by
Robert Schmidt
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/NR_PSBCH_MERGE2' into integration_2024_w06
parents
0e531b44
4d411dbc
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
1475 additions
and
21 deletions
+1475
-21
CMakeLists.txt
CMakeLists.txt
+2
-0
executables/nr-ue.c
executables/nr-ue.c
+2
-0
executables/softmodem-common.h
executables/softmodem-common.h
+3
-10
nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h
nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h
+2
-2
openair2/COMMON/mac_messages_def.h
openair2/COMMON/mac_messages_def.h
+1
-0
openair2/COMMON/mac_messages_types.h
openair2/COMMON/mac_messages_types.h
+12
-0
openair2/LAYER2/NR_MAC_UE/config_ue_sl.c
openair2/LAYER2/NR_MAC_UE/config_ue_sl.c
+533
-0
openair2/LAYER2/NR_MAC_UE/mac_defs.h
openair2/LAYER2/NR_MAC_UE/mac_defs.h
+4
-0
openair2/LAYER2/NR_MAC_UE/mac_defs_sl.h
openair2/LAYER2/NR_MAC_UE/mac_defs_sl.h
+157
-0
openair2/LAYER2/NR_MAC_UE/mac_proto.h
openair2/LAYER2/NR_MAC_UE/mac_proto.h
+24
-0
openair2/LAYER2/NR_MAC_UE/nr_ue_procedures_sl.c
openair2/LAYER2/NR_MAC_UE/nr_ue_procedures_sl.c
+524
-0
openair2/RRC/NR_UE/L2_interface_ue.c
openair2/RRC/NR_UE/L2_interface_ue.c
+26
-0
openair2/RRC/NR_UE/rrc_UE.c
openair2/RRC/NR_UE/rrc_UE.c
+23
-3
openair2/RRC/NR_UE/rrc_defs.h
openair2/RRC/NR_UE/rrc_defs.h
+6
-0
openair2/RRC/NR_UE/rrc_proto.h
openair2/RRC/NR_UE/rrc_proto.h
+14
-1
openair2/RRC/NR_UE/rrc_sl_preconfig.c
openair2/RRC/NR_UE/rrc_sl_preconfig.c
+142
-5
No files found.
CMakeLists.txt
View file @
d01c1470
...
...
@@ -1384,9 +1384,11 @@ set (MAC_NR_SRC_UE
${
NR_UE_PHY_INTERFACE_DIR
}
/NR_IF_Module.c
${
NR_UE_PHY_INTERFACE_DIR
}
/NR_Packet_Drop.c
${
NR_UE_MAC_DIR
}
/config_ue.c
${
NR_UE_MAC_DIR
}
/config_ue_sl.c
${
NR_UE_MAC_DIR
}
/mac_vars.c
${
NR_UE_MAC_DIR
}
/main_ue_nr.c
${
NR_UE_MAC_DIR
}
/nr_ue_procedures.c
${
NR_UE_MAC_DIR
}
/nr_ue_procedures_sl.c
${
NR_UE_MAC_DIR
}
/nr_ue_scheduler.c
${
NR_UE_MAC_DIR
}
/nr_ue_dci_configuration.c
${
NR_UE_MAC_DIR
}
/nr_ra_procedures.c
...
...
executables/nr-ue.c
View file @
d01c1470
...
...
@@ -987,6 +987,8 @@ void init_NR_UE(int nb_inst, char *uecap_file, char *reconfig_file, char *rbconf
init_nsa_message
(
rrc_inst
,
reconfig_file
,
rbconfig_file
);
nr_rlc_activate_srb0
(
mac_inst
->
crnti
,
NULL
,
send_srb0_rrc
);
}
//TODO: Move this call to RRC
start_sidelink
((
&
rrc_inst
[
i
])
->
ue_id
);
}
}
...
...
executables/softmodem-common.h
View file @
d01c1470
...
...
@@ -106,11 +106,9 @@ extern "C"
#define CONFIG_L1_EMULATOR "Run in L1 emulated mode (disable PHY layer)\n"
#define CONFIG_HLP_CONTINUOUS_TX "perform continuous transmission, even in TDD mode (to work around USRP issues)\n"
#define CONFIG_HLP_STATS_DISABLE "disable globally the stats generation and persistence"
#define CONFIG_HLP_SYNC_REF "Sync Reference in Sidelink\n"
#define CONFIG_HLP_NID1 "Set NID1 value in Sidelink\n"
#define CONFIG_HLP_NID2 "Set NID2 value in Sidelink\n"
#define CONFIG_HLP_NOITTI "Do not start itti threads, call queue processing in place, inside the caller thread"
#define CONFIG_HLP_LDPC_OFFLOAD "Enable LDPC offload to AMD Xilinx T2 telco card\n"
#define CONFIG_HLP_SYNC_REF "UE acts a Sync Reference in Sidelink. 0-none 1-GNB 2-GNSS 4-localtiming\n"
/*-----------------------------------------------------------------------------------------------------------------------------------------------------*/
/* command line parameters common to eNodeB and UE */
...
...
@@ -143,8 +141,6 @@ extern "C"
#define EMULATE_L1 softmodem_params.emulate_l1
#define CONTINUOUS_TX softmodem_params.continuous_tx
#define SYNC_REF softmodem_params.sync_ref
#define NID1 softmodem_params.nid1
#define NID2 softmodem_params.nid2
#define LDPC_OFFLOAD_FLAG softmodem_params.ldpc_offload_flag
#define REORDER_THREAD_DISABLE softmodem_params.reorder_thread_disable
...
...
@@ -191,10 +187,9 @@ extern int usrp_tx_thread;
{"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, .iptr=&EMULATE_L1, .defintval=0, TYPE_INT, 0}, \
{"continuous-tx", CONFIG_HLP_CONTINUOUS_TX, PARAMFLAG_BOOL, .iptr=&CONTINUOUS_TX, .defintval=0, TYPE_INT, 0}, \
{"disable-stats", CONFIG_HLP_STATS_DISABLE, PARAMFLAG_BOOL, .iptr=&stats_disabled, .defintval=0, TYPE_INT, 0}, \
{"nid1", CONFIG_HLP_NID1, 0, .iptr=&NID1, .defintval=10, TYPE_INT, 0}, \
{"nid2", CONFIG_HLP_NID2, 0, .iptr=&NID2, .defintval=1, TYPE_INT, 0}, \
{"no-itti-threads", CONFIG_HLP_NOITTI, PARAMFLAG_BOOL, .iptr=&softmodem_params.no_itti, .defintval=0, TYPE_INT, 0}, \
{"ldpc-offload-enable", CONFIG_HLP_LDPC_OFFLOAD, PARAMFLAG_BOOL, .iptr=&LDPC_OFFLOAD_FLAG, .defstrval=0, TYPE_INT, 0}, \
{"sync-ref", CONFIG_HLP_SYNC_REF, 0, .uptr=&SYNC_REF, .defintval=0, TYPE_UINT, 0}, \
}
// clang-format on
...
...
@@ -353,9 +348,7 @@ typedef struct {
int
non_stop
;
int
emulate_l1
;
int
continuous_tx
;
int
sync_ref
;
int
nid1
;
int
nid2
;
uint32_t
sync_ref
;
int
no_itti
;
int
ldpc_offload_flag
;
}
softmodem_params_t
;
...
...
nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h
View file @
d01c1470
...
...
@@ -351,7 +351,7 @@ typedef struct
uint16_t
sl_bandwidth
;
//Absolute frequency of SL point A in KHz
//n38 (2570-2620 Mhz), n47 (5855-5925 Mhz) are defined.
uint
32
_t
sl_frequency
;
uint
64
_t
sl_frequency
;
//Only 1 SCS-SpecificCarrier allowed for NR-SL communication
uint16_t
sl_grid_size
;
// bandwidth for each numerology
...
...
@@ -363,7 +363,7 @@ typedef struct
uint8_t
sl_frequency_shift_7p5khz
;
//Indicates presence of +/-5Khz shift wrt FREF for V2X reference frequencies.
//Possible values: {-1,0,1}
u
int8_t
sl_value_N
;
int8_t
sl_value_N
;
}
sl_nr_carrier_config_t
;
...
...
openair2/COMMON/mac_messages_def.h
View file @
d01c1470
...
...
@@ -57,4 +57,5 @@ MESSAGE_DEF(RRC_MAC_DRX_CONFIG_REQ, MESSAGE_PRIORITY_MED, rrc_mac_drx_config_req
// gNB
MESSAGE_DEF
(
NR_RRC_MAC_CCCH_DATA_IND
,
MESSAGE_PRIORITY_MED_PLUS
,
NRRrcMacCcchDataInd
,
nr_rrc_mac_ccch_data_ind
)
MESSAGE_DEF
(
NR_RRC_MAC_BCCH_DATA_IND
,
MESSAGE_PRIORITY_MED_PLUS
,
NRRrcMacBcchDataInd
,
nr_rrc_mac_bcch_data_ind
)
MESSAGE_DEF
(
NR_RRC_MAC_SBCCH_DATA_IND
,
MESSAGE_PRIORITY_MED_PLUS
,
NRRrcMacSBcchDataInd
,
nr_rrc_mac_sbcch_data_ind
)
openair2/COMMON/mac_messages_types.h
View file @
d01c1470
...
...
@@ -41,6 +41,7 @@
#define RRC_MAC_BCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_data_req
#define RRC_MAC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_data_ind
#define NR_RRC_MAC_BCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_mac_bcch_data_ind
#define NR_RRC_MAC_SBCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nr_rrc_mac_sbcch_data_ind
#define RRC_MAC_BCCH_MBMS_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_req
#define RRC_MAC_BCCH_MBMS_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_bcch_mbms_data_ind
...
...
@@ -119,6 +120,17 @@ typedef struct NRRrcMacBcchDataInd_s {
uint8_t
rsrp
;
}
NRRrcMacBcchDataInd
;
typedef
struct
NRRrcMacSBcchDataInd_s
{
uint32_t
frame
;
uint8_t
slot
;
uint32_t
sdu_size
;
uint8_t
sdu
[
BCCH_SDU_SIZE
];
uint8_t
gnb_index
;
uint16_t
rx_slss_id
;
uint8_t
rsrq
;
uint8_t
rsrp
;
}
NRRrcMacSBcchDataInd
;
typedef
struct
RrcMacBcchMbmsDataReq_s
{
uint32_t
frame
;
uint32_t
sdu_size
;
...
...
openair2/LAYER2/NR_MAC_UE/config_ue_sl.c
0 → 100644
View file @
d01c1470
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h"
#include "NR_SidelinkPreconfigNR-r16.h"
#include "mac_proto.h"
void
sl_ue_mac_free
(
uint8_t
module_id
)
{
NR_UE_MAC_INST_t
*
mac
=
get_mac_inst
(
module_id
);
sl_nr_phy_config_request_t
*
sl_config
=
&
mac
->
SL_MAC_PARAMS
->
sl_phy_config
.
sl_config_req
;
uint8_t
syncsource
=
sl_config
->
sl_sync_source
.
sync_source
;
//Allocated by MAC only in case of SYNC_REF_UE
//else it is freed as part of RRC pre-config structure
if
(
syncsource
==
SL_SYNC_SOURCE_SYNC_REF_UE
)
{
ASN_STRUCT_FREE
(
asn_DEF_NR_TDD_UL_DL_Pattern
,
mac
->
SL_MAC_PARAMS
->
sl_TDD_config
);
}
fapi_nr_max_tdd_periodicity_t
*
tdd_list
=
sl_config
->
tdd_table
.
max_tdd_periodicity_list
;
// @todo: maybe this should be done by phy
if
(
tdd_list
)
{
int
mu
=
sl_config
->
sl_bwp_config
.
sl_scs
;
int
nb_slots_to_set
=
TDD_CONFIG_NB_FRAMES
*
(
1
<<
mu
)
*
NR_NUMBER_OF_SUBFRAMES_PER_FRAME
;
for
(
int
i
=
0
;
i
<
nb_slots_to_set
;
i
++
)
{
free_and_zero
(
tdd_list
[
i
].
max_num_of_symbol_per_slot_list
);
}
free_and_zero
(
sl_config
->
tdd_table
.
max_tdd_periodicity_list
);
}
for
(
int
i
=
0
;
i
<
SL_NR_MAC_NUM_RX_RESOURCE_POOLS
;
i
++
)
{
free_and_zero
(
mac
->
SL_MAC_PARAMS
->
sl_RxPool
[
i
]);
}
for
(
int
i
=
0
;
i
<
SL_NR_MAC_NUM_TX_RESOURCE_POOLS
;
i
++
)
{
free_and_zero
(
mac
->
SL_MAC_PARAMS
->
sl_TxPool
[
i
]);
}
free_and_zero
(
mac
->
SL_MAC_PARAMS
);
}
void
sl_set_tdd_config_nr_ue
(
fapi_nr_tdd_table_t
*
tdd_table
,
int
mu
,
NR_TDD_UL_DL_Pattern_t
*
pattern
)
{
const
int
nrofUplinkSlots
=
pattern
->
nrofUplinkSlots
;
const
int
nrofUplinkSymbols
=
pattern
->
nrofUplinkSymbols
;
const
int
nb_periods_per_frame
=
get_nb_periods_per_frame
(
pattern
->
dl_UL_TransmissionPeriodicity
);
const
int
nb_slots_per_period
=
((
1
<<
mu
)
*
NR_NUMBER_OF_SUBFRAMES_PER_FRAME
)
/
nb_periods_per_frame
;
tdd_table
->
tdd_period_in_slots
=
nb_slots_per_period
;
LOG_I
(
PHY
,
"UL slots:%d, symbols:%d, slots_per_period:%d
\n
"
,
nrofUplinkSlots
,
nrofUplinkSymbols
,
nb_slots_per_period
);
tdd_table
->
max_tdd_periodicity_list
=
(
fapi_nr_max_tdd_periodicity_t
*
)
malloc
(
nb_slots_per_period
*
sizeof
(
fapi_nr_max_tdd_periodicity_t
));
for
(
int
memory_alloc
=
0
;
memory_alloc
<
nb_slots_per_period
;
memory_alloc
++
)
tdd_table
->
max_tdd_periodicity_list
[
memory_alloc
].
max_num_of_symbol_per_slot_list
=
(
fapi_nr_max_num_of_symbol_per_slot_t
*
)
malloc
(
NR_NUMBER_OF_SYMBOLS_PER_SLOT
*
sizeof
(
fapi_nr_max_num_of_symbol_per_slot_t
));
int
slot_number
=
(
nb_slots_per_period
-
nrofUplinkSlots
)
-
(
nrofUplinkSymbols
?
1
:
0
);
if
(
nrofUplinkSymbols
!=
0
)
{
for
(
int
number_of_symbol
=
NR_NUMBER_OF_SYMBOLS_PER_SLOT
-
nrofUplinkSymbols
;
number_of_symbol
<
NR_NUMBER_OF_SYMBOLS_PER_SLOT
;
number_of_symbol
++
)
{
tdd_table
->
max_tdd_periodicity_list
[
slot_number
].
max_num_of_symbol_per_slot_list
[
number_of_symbol
].
slot_config
=
1
;
}
slot_number
++
;
}
while
(
slot_number
<
nb_slots_per_period
)
{
for
(
int
number_of_symbol
=
0
;
number_of_symbol
<
nrofUplinkSlots
*
NR_NUMBER_OF_SYMBOLS_PER_SLOT
;
number_of_symbol
++
)
{
tdd_table
->
max_tdd_periodicity_list
[
slot_number
].
max_num_of_symbol_per_slot_list
[
number_of_symbol
%
NR_NUMBER_OF_SYMBOLS_PER_SLOT
].
slot_config
=
1
;
if
((
number_of_symbol
+
1
)
%
NR_NUMBER_OF_SYMBOLS_PER_SLOT
==
0
)
slot_number
++
;
}
}
}
//Prepares the PHY config to be sent to PHY. Prepares from the Valus from MAC context.
static
void
sl_prepare_phy_config
(
int
module_id
,
sl_nr_phy_config_request_t
*
phycfg
,
NR_SL_FreqConfigCommon_r16_t
*
freqcfg
,
uint8_t
sync_source
,
uint32_t
sl_OffsetDFN
,
NR_TDD_UL_DL_ConfigCommon_t
*
sl_TDD_config
)
{
phycfg
->
sl_sync_source
.
sync_source
=
sync_source
;
LOG_I
(
NR_MAC
,
"Sidelink CFG: sync source:%d
\n
"
,
phycfg
->
sl_sync_source
.
sync_source
);
uint32_t
pointA_ARFCN
=
freqcfg
->
sl_AbsoluteFrequencyPointA_r16
;
AssertFatal
(
pointA_ARFCN
,
"sl_AbsoluteFrequencyPointA_r16 cannot be 0
\n
"
);
int
sl_band
=
0
;
//REL 16 3GPP spec 38.101 section 5.2E.1 specifies 2 bands for operation on PC5 interface.
//Band 47, Band 38
if
(
pointA_ARFCN
>=
790334
&&
pointA_ARFCN
<=
795000
)
sl_band
=
47
;
else
if
(
pointA_ARFCN
>=
514000
&&
pointA_ARFCN
<=
524000
)
sl_band
=
38
;
AssertFatal
(
sl_band
,
"not valid band for Sidelink operation
\n
"
);
uint32_t
SSB_ARFCN
=
(
freqcfg
->
sl_AbsoluteFrequencySSB_r16
)
?
*
freqcfg
->
sl_AbsoluteFrequencySSB_r16
:
0
;
AssertFatal
(
SSB_ARFCN
,
"sl_AbsoluteFrequencySSB cannot be 0
\n
"
);
LOG_I
(
NR_MAC
,
"SIDELINK CONFIGs: AbsFreqSSB:%d, AbsFreqPointA:%d, SL band:%d
\n
"
,
SSB_ARFCN
,
pointA_ARFCN
,
sl_band
);
//FREQSHIFT_7P5KHZ is DISABLED
phycfg
->
sl_carrier_config
.
sl_frequency_shift_7p5khz
=
0
;
phycfg
->
sl_carrier_config
.
sl_value_N
=
freqcfg
->
valueN_r16
;
NR_SCS_SpecificCarrier_t
*
carriercfg
=
freqcfg
->
sl_SCS_SpecificCarrierList_r16
.
list
.
array
[
0
];
AssertFatal
(
carriercfg
,
"SCS_SpecificCarrier cannot be NULL"
);
int
bw_index
=
get_supported_band_index
(
carriercfg
->
subcarrierSpacing
,
sl_band
,
carriercfg
->
carrierBandwidth
);
phycfg
->
sl_carrier_config
.
sl_bandwidth
=
get_supported_bw_mhz
(
FR1
,
bw_index
);
phycfg
->
sl_carrier_config
.
sl_frequency
=
from_nrarfcn
(
sl_band
,
carriercfg
->
subcarrierSpacing
,
pointA_ARFCN
);
// freq in kHz
phycfg
->
sl_carrier_config
.
sl_grid_size
=
carriercfg
->
carrierBandwidth
;
//For sidelink offset to carrier is 0. hence not used
//phycfg->sl_carrier_config.sl_k0 = carriercfg->offsetToCarrier;
NR_SL_BWP_Generic_r16_t
*
bwp_generic
=
NULL
;
if
(
freqcfg
->
sl_BWP_List_r16
&&
freqcfg
->
sl_BWP_List_r16
->
list
.
array
[
0
]
&&
freqcfg
->
sl_BWP_List_r16
->
list
.
array
[
0
]
->
sl_BWP_Generic_r16
)
bwp_generic
=
freqcfg
->
sl_BWP_List_r16
->
list
.
array
[
0
]
->
sl_BWP_Generic_r16
;
AssertFatal
(
bwp_generic
,
"SL-BWP Generic cannot be NULL"
);
NR_BWP_t
*
sl_bwp
=
bwp_generic
->
sl_BWP_r16
;
AssertFatal
(
sl_bwp
,
"SL-BWP cannot be NULL"
);
int
locbw
=
bwp_generic
->
sl_BWP_r16
->
locationAndBandwidth
;
phycfg
->
sl_bwp_config
.
sl_bwp_size
=
NRRIV2BW
(
locbw
,
MAX_BWP_SIZE
);
phycfg
->
sl_bwp_config
.
sl_bwp_start
=
NRRIV2PRBOFFSET
(
locbw
,
MAX_BWP_SIZE
);
phycfg
->
sl_bwp_config
.
sl_scs
=
sl_bwp
->
subcarrierSpacing
;
int
scs_scaling
=
1
<<
(
phycfg
->
sl_bwp_config
.
sl_scs
);
if
(
pointA_ARFCN
<
600000
)
scs_scaling
=
scs_scaling
*
3
;
if
(
pointA_ARFCN
>
2016666
)
scs_scaling
=
scs_scaling
>>
2
;
//SSB arfcn points to middle RE of PSBCH 11 RBs
uint32_t
diff
=
(
SSB_ARFCN
-
66
*
scs_scaling
)
-
pointA_ARFCN
;
//the RE offset from pointA where SSB starts
phycfg
->
sl_bwp_config
.
sl_ssb_offset_point_a
=
diff
/
scs_scaling
;
#ifdef SL_DEBUG
printf
(
"diff:%d, scaling:%d, pointa:%d, ssb:%d
\n
"
,
diff
,
scs_scaling
,
pointA_ARFCN
,
SSB_ARFCN
);
#endif
phycfg
->
sl_bwp_config
.
sl_dc_location
=
(
bwp_generic
->
sl_TxDirectCurrentLocation_r16
)
?
*
bwp_generic
->
sl_TxDirectCurrentLocation_r16
:
0
;
const
uint8_t
values
[]
=
{
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
};
phycfg
->
sl_bwp_config
.
sl_num_symbols
=
(
bwp_generic
->
sl_LengthSymbols_r16
)
?
values
[
*
bwp_generic
->
sl_LengthSymbols_r16
]
:
0
;
phycfg
->
sl_bwp_config
.
sl_start_symbol
=
(
bwp_generic
->
sl_StartSymbol_r16
)
?
*
bwp_generic
->
sl_StartSymbol_r16
:
0
;
//0-EXTENDED, 1-NORMAL CP
phycfg
->
sl_bwp_config
.
sl_cyclic_prefix
=
(
sl_bwp
->
cyclicPrefix
)
?
EXTENDED
:
NORMAL
;
AssertFatal
(
phycfg
->
sl_bwp_config
.
sl_cyclic_prefix
==
NORMAL
,
"Only NORMAL-CP Supported. Ext CP not yet supported
\n
"
);
AssertFatal
(
phycfg
->
sl_bwp_config
.
sl_start_symbol
>=
0
&&
phycfg
->
sl_bwp_config
.
sl_start_symbol
<=
7
,
"Sidelink Start symbol should be in range 0-7
\n
"
);
AssertFatal
(
phycfg
->
sl_bwp_config
.
sl_num_symbols
>=
7
&&
phycfg
->
sl_bwp_config
.
sl_num_symbols
<=
14
,
"Num Sidelink symbols should be in range 7-14
\n
"
);
AssertFatal
((
phycfg
->
sl_bwp_config
.
sl_start_symbol
+
phycfg
->
sl_bwp_config
.
sl_num_symbols
)
<=
14
,
"Incorrect configuration of Start and num SL symbols
\n
"
);
//Configure PHY with TDD config only if the sync source is known.
if
(
sync_source
==
SL_SYNC_SOURCE_LOCAL_TIMING
||
sync_source
==
SL_SYNC_SOURCE_GNSS
)
{
phycfg
->
config_mask
=
0xF
;
//Total config is sent
phycfg
->
sl_sync_source
.
gnss_dfn_offset
=
sl_OffsetDFN
;
// TDD Table Configuration
sl_set_tdd_config_nr_ue
(
&
phycfg
->
tdd_table
,
phycfg
->
sl_bwp_config
.
sl_scs
,
&
sl_TDD_config
->
pattern1
);
LOG_I
(
NR_MAC
,
"SIDELINK CONFIGs: tdd config period:%ld, mu:%ld, DLslots:%ld,ULslots:%ld Mixedslotsym DL:UL %ld:%ld
\n
"
,
sl_TDD_config
->
pattern1
.
dl_UL_TransmissionPeriodicity
,
sl_TDD_config
->
referenceSubcarrierSpacing
,
sl_TDD_config
->
pattern1
.
nrofDownlinkSlots
,
sl_TDD_config
->
pattern1
.
nrofUplinkSlots
,
sl_TDD_config
->
pattern1
.
nrofDownlinkSymbols
,
sl_TDD_config
->
pattern1
.
nrofUplinkSymbols
);
}
else
if
(
sync_source
==
SL_SYNC_SOURCE_NONE
)
{
//Only Carrier config, BWP config sent
phycfg
->
config_mask
=
0x9
;
//partial config is sent
}
//#ifdef SL_DEBUG
char
str
[
5
][
20
]
=
{
"NONE"
,
"GNBENB"
,
"GNSS"
,
"SYNC_REF_UE"
,
"LOCAL_TIMING"
};
LOG_I
(
NR_MAC
,
"UE[%d] Function %s - Phy config preparation:
\n
"
,
module_id
,
__FUNCTION__
);
LOG_I
(
NR_MAC
,
"UE[%d] Sync source params: sync_source :%d-%s, gnss_dfn_offset:%d, rx_slss_id:%d
\n
"
,
module_id
,
phycfg
->
sl_sync_source
.
sync_source
,
str
[
phycfg
->
sl_sync_source
.
sync_source
],
phycfg
->
sl_sync_source
.
gnss_dfn_offset
,
phycfg
->
sl_sync_source
.
rx_slss_id
);
LOG_I
(
NR_MAC
,
"UE[%d] Carrier CFG Params: freq:%ld, bw:%d, gridsize:%d, valueN:%d
\n
"
,
module_id
,
phycfg
->
sl_carrier_config
.
sl_frequency
,
phycfg
->
sl_carrier_config
.
sl_bandwidth
,
phycfg
->
sl_carrier_config
.
sl_grid_size
,
phycfg
->
sl_carrier_config
.
sl_value_N
);
LOG_I
(
NR_MAC
,
"UE[%d] SL-BWP Params: start:%d, size:%d, scs:%d, Ncp:%d, startsym:%d, numsym:%d,ssb_offset:%d,dcloc:%d
\n
"
,
module_id
,
phycfg
->
sl_bwp_config
.
sl_bwp_start
,
phycfg
->
sl_bwp_config
.
sl_bwp_size
,
phycfg
->
sl_bwp_config
.
sl_scs
,
phycfg
->
sl_bwp_config
.
sl_cyclic_prefix
,
phycfg
->
sl_bwp_config
.
sl_start_symbol
,
phycfg
->
sl_bwp_config
.
sl_num_symbols
,
phycfg
->
sl_bwp_config
.
sl_ssb_offset_point_a
,
phycfg
->
sl_bwp_config
.
sl_dc_location
);
//#endif
return
;
}
// RRC calls this API when RRC is configured with Sidelink PRE-configuration I.E
int
nr_rrc_mac_config_req_sl_preconfig
(
module_id_t
module_id
,
NR_SL_PreconfigurationNR_r16_t
*
sl_preconfiguration
,
uint8_t
sync_source
)
{
LOG_I
(
NR_MAC
,
"[UE%d] SL RRC->MAC CONFIG RECEIVED. Syncsource:%d
\n
"
,
module_id
,
sync_source
);
NR_UE_MAC_INST_t
*
mac
=
get_mac_inst
(
module_id
);
AssertFatal
(
sl_preconfiguration
!=
NULL
,
"SL-Preconfig Cannot be NULL"
);
AssertFatal
(
mac
,
"mac should have an instance"
);
if
(
!
mac
->
SL_MAC_PARAMS
)
mac
->
SL_MAC_PARAMS
=
CALLOC
(
1
,
sizeof
(
sl_nr_ue_mac_params_t
));
sl_nr_ue_mac_params_t
*
sl_mac
=
mac
->
SL_MAC_PARAMS
;
NR_SidelinkPreconfigNR_r16_t
*
sl_preconfig
=
&
sl_preconfiguration
->
sidelinkPreconfigNR_r16
;
//Only one entry supported in rel16.
//Carrier freq config used for Sidelink
NR_SL_FreqConfigCommon_r16_t
*
freqcfg
=
(
sl_preconfig
->
sl_PreconfigFreqInfoList_r16
)
?
sl_preconfig
->
sl_PreconfigFreqInfoList_r16
->
list
.
array
[
0
]
:
NULL
;
AssertFatal
(
freqcfg
!=
NULL
,
"SL fcfg Cannot be NULL"
);
//MAx num of consecutive HARQ DTX before triggering RLF.
const
uint8_t
MaxNumConsecutiveDTX
[]
=
{
1
,
2
,
3
,
4
,
6
,
8
,
16
,
32
};
sl_mac
->
sl_MaxNumConsecutiveDTX
=
(
sl_preconfig
->
sl_MaxNumConsecutiveDTX_r16
)
?
MaxNumConsecutiveDTX
[
*
sl_preconfig
->
sl_MaxNumConsecutiveDTX_r16
]
:
0
;
//priority of SL-SSB tx and rx
sl_mac
->
sl_SSB_PriorityNR
=
(
sl_preconfig
->
sl_SSB_PriorityNR_r16
)
?
*
sl_preconfig
->
sl_SSB_PriorityNR_r16
:
0
;
//Indicates if CSI Reporting is enabled in UNICAST. is 0-ENABLED, 1-DISABLED
sl_mac
->
sl_CSI_Acquisition
=
(
sl_preconfig
->
sl_CSI_Acquisition_r16
)
?
0
:
1
;
//Used for DFN calculation in case Sync source = GNSS.
uint32_t
sl_OffsetDFN
=
(
sl_preconfig
->
sl_OffsetDFN_r16
)
?
*
sl_preconfig
->
sl_OffsetDFN_r16
:
0
;
NR_SL_BWP_ConfigCommon_r16_t
*
bwp
=
NULL
;
if
(
freqcfg
->
sl_BWP_List_r16
&&
freqcfg
->
sl_BWP_List_r16
->
list
.
array
[
0
])
bwp
=
freqcfg
->
sl_BWP_List_r16
->
list
.
array
[
0
];
AssertFatal
(
bwp
!=
NULL
,
"BWP config common cannot be NULL
\n
"
);
if
(
bwp
->
sl_BWP_PoolConfigCommon_r16
)
{
if
(
bwp
->
sl_BWP_PoolConfigCommon_r16
->
sl_RxPool_r16
)
{
for
(
int
i
=
0
;
i
<
bwp
->
sl_BWP_PoolConfigCommon_r16
->
sl_RxPool_r16
->
list
.
count
;
i
++
)
{
NR_SL_ResourcePool_r16_t
*
rxpool
=
bwp
->
sl_BWP_PoolConfigCommon_r16
->
sl_RxPool_r16
->
list
.
array
[
i
];
if
(
rxpool
)
{
if
(
sl_mac
->
sl_RxPool
[
i
]
==
NULL
)
sl_mac
->
sl_RxPool
[
i
]
=
malloc16_clear
(
sizeof
(
SL_ResourcePool_params_t
));
sl_mac
->
sl_RxPool
[
i
]
->
respool
=
rxpool
;
uint16_t
sci_1a_len
=
0
,
num_subch
=
0
;
sci_1a_len
=
sl_determine_sci_1a_len
(
&
num_subch
,
sl_mac
->
sl_RxPool
[
i
]
->
respool
,
&
sl_mac
->
sl_RxPool
[
i
]
->
sci_1a
);
sl_mac
->
sl_RxPool
[
i
]
->
num_subch
=
num_subch
;
sl_mac
->
sl_RxPool
[
i
]
->
sci_1a_len
=
sci_1a_len
;
LOG_I
(
NR_MAC
,
"Rxpool[%d] - num subchannels:%d, sci_1a_len:%d
\n
"
,
i
,
sl_mac
->
sl_RxPool
[
i
]
->
num_subch
,
sl_mac
->
sl_RxPool
[
i
]
->
sci_1a_len
);
}
}
}
if
(
bwp
->
sl_BWP_PoolConfigCommon_r16
->
sl_TxPoolSelectedNormal_r16
)
{
for
(
int
i
=
0
;
i
<
bwp
->
sl_BWP_PoolConfigCommon_r16
->
sl_TxPoolSelectedNormal_r16
->
list
.
count
;
i
++
)
{
NR_SL_ResourcePool_r16_t
*
txpool
=
bwp
->
sl_BWP_PoolConfigCommon_r16
->
sl_TxPoolSelectedNormal_r16
->
list
.
array
[
0
]
->
sl_ResourcePool_r16
;
if
(
txpool
)
{
if
(
sl_mac
->
sl_TxPool
[
i
]
==
NULL
)
sl_mac
->
sl_TxPool
[
i
]
=
malloc16_clear
(
sizeof
(
SL_ResourcePool_params_t
));
sl_mac
->
sl_TxPool
[
i
]
->
respool
=
txpool
;
uint16_t
sci_1a_len
=
0
,
num_subch
=
0
;
sci_1a_len
=
sl_determine_sci_1a_len
(
&
num_subch
,
sl_mac
->
sl_TxPool
[
i
]
->
respool
,
&
sl_mac
->
sl_TxPool
[
i
]
->
sci_1a
);
sl_mac
->
sl_TxPool
[
i
]
->
num_subch
=
num_subch
;
sl_mac
->
sl_TxPool
[
i
]
->
sci_1a_len
=
sci_1a_len
;
LOG_I
(
NR_MAC
,
"Txpool[%d] - num subchannels:%d, sci_1a_len:%d
\n
"
,
i
,
sl_mac
->
sl_TxPool
[
i
]
->
num_subch
,
sl_mac
->
sl_TxPool
[
i
]
->
sci_1a_len
);
}
}
}
}
if
(
sync_source
==
SL_SYNC_SOURCE_GNSS
||
sync_source
==
SL_SYNC_SOURCE_LOCAL_TIMING
)
{
NR_TDD_UL_DL_ConfigCommon_t
*
tdd_uldl_config
=
NULL
;
if
(
sl_preconfig
->
sl_PreconfigGeneral_r16
&&
sl_preconfig
->
sl_PreconfigGeneral_r16
->
sl_TDD_Configuration_r16
)
tdd_uldl_config
=
sl_preconfig
->
sl_PreconfigGeneral_r16
->
sl_TDD_Configuration_r16
;
AssertFatal
((
tdd_uldl_config
!=
NULL
),
"Sidelink MAC CFG: TDD Config cannot be NULL"
);
AssertFatal
((
tdd_uldl_config
->
pattern2
==
NULL
),
"Sidelink MAC CFG: pattern2 not yet supported"
);
sl_mac
->
sl_TDD_config
=
sl_preconfig
->
sl_PreconfigGeneral_r16
->
sl_TDD_Configuration_r16
;
}
//Do not copy TDD config yet as SYNC source is not yet found
if
(
sync_source
==
SL_SYNC_SOURCE_NONE
)
{
if
(
sl_mac
->
sl_TDD_config
)
ASN_STRUCT_FREE
(
asn_DEF_NR_TDD_UL_DL_ConfigCommon
,
sl_mac
->
sl_TDD_config
);
sl_mac
->
sl_TDD_config
=
NULL
;
}
nr_sl_phy_config_t
*
sl_phy_cfg
=
&
sl_mac
->
sl_phy_config
;
sl_phy_cfg
->
Mod_id
=
module_id
;
sl_phy_cfg
->
CC_id
=
0
;
sl_prepare_phy_config
(
module_id
,
&
sl_phy_cfg
->
sl_config_req
,
freqcfg
,
sync_source
,
sl_OffsetDFN
,
sl_mac
->
sl_TDD_config
);
return
0
;
}
//Copies the values of SSB time allocation from ASN format to MAC context
static
void
sl_mac_config_ssb_time_alloc
(
uint8_t
module_id
,
NR_SL_SSB_TimeAllocation_r16_t
*
sl_SSB_TimeAllocation_r16
,
sl_ssb_timealloc_t
*
ssb_time_alloc
)
{
const
uint8_t
values
[]
=
{
1
,
2
,
4
,
8
,
16
,
32
,
64
};
ssb_time_alloc
->
sl_NumSSB_WithinPeriod
=
(
sl_SSB_TimeAllocation_r16
->
sl_NumSSB_WithinPeriod_r16
!=
NULL
)
?
values
[
*
sl_SSB_TimeAllocation_r16
->
sl_NumSSB_WithinPeriod_r16
]
:
0
;
ssb_time_alloc
->
sl_TimeOffsetSSB
=
(
sl_SSB_TimeAllocation_r16
->
sl_TimeOffsetSSB_r16
!=
NULL
)
?
*
sl_SSB_TimeAllocation_r16
->
sl_TimeOffsetSSB_r16
:
0
;
ssb_time_alloc
->
sl_TimeInterval
=
(
sl_SSB_TimeAllocation_r16
->
sl_TimeInterval_r16
!=
NULL
)
?
*
sl_SSB_TimeAllocation_r16
->
sl_TimeInterval_r16
:
0
;
}
//This API is called by RRC after it determines that UE needs to transmit SL-SSB
// SLSS id and SL-MIB is given to MAC by RRC
void
nr_rrc_mac_transmit_slss_req
(
module_id_t
module_id
,
uint8_t
*
sl_mib_payload
,
uint16_t
tx_slss_id
,
NR_SL_SSB_TimeAllocation_r16_t
*
ssb_ta
)
{
sl_nr_ue_mac_params_t
*
sl_mac
=
get_mac_inst
(
module_id
)
->
SL_MAC_PARAMS
;
AssertFatal
(
sl_mac
,
"sidelink MAC cannot be NULL"
);
AssertFatal
(
tx_slss_id
<
672
,
"SLSS id cannot be >= 672. id:%d"
,
tx_slss_id
);
AssertFatal
(
ssb_ta
,
"ssb_ta cannot be NULL"
);
sl_mac
->
tx_sl_bch
.
slss_id
=
tx_slss_id
;
sl_mac
->
tx_sl_bch
.
status
=
1
;
memcpy
(
sl_mac
->
tx_sl_bch
.
sl_mib
,
sl_mib_payload
,
4
);
sl_mac
->
tx_sl_bch
.
num_ssb
=
0
;
sl_mac
->
tx_sl_bch
.
ssb_slot
=
0
;
sl_mac_config_ssb_time_alloc
(
module_id
,
ssb_ta
,
&
sl_mac
->
tx_sl_bch
.
ssb_time_alloc
);
LOG_I
(
NR_MAC
,
"[UE%d]SL RRC->MAC: TX SLSS REQ SLSS-id:%d, SL-MIB:%x, numssb:%d, offset:%d, interval:%d
\n
"
,
module_id
,
sl_mac
->
tx_sl_bch
.
slss_id
,
*
((
uint32_t
*
)
sl_mib_payload
),
sl_mac
->
tx_sl_bch
.
ssb_time_alloc
.
sl_NumSSB_WithinPeriod
,
sl_mac
->
tx_sl_bch
.
ssb_time_alloc
.
sl_TimeOffsetSSB
,
sl_mac
->
tx_sl_bch
.
ssb_time_alloc
.
sl_TimeInterval
);
uint8_t
byte0
=
0
;
uint8_t
byte1
=
0
;
sl_nr_bwp_config_t
*
cfg
=
&
sl_mac
->
sl_phy_config
.
sl_config_req
.
sl_bwp_config
;
sl_prepare_psbch_payload
(
sl_mac
->
sl_TDD_config
,
&
byte0
,
&
byte1
,
cfg
->
sl_scs
,
cfg
->
sl_num_symbols
,
cfg
->
sl_start_symbol
);
sl_mac
->
tx_sl_bch
.
sl_mib
[
0
]
=
byte0
;
sl_mac
->
tx_sl_bch
.
sl_mib
[
1
]
=
byte1
|
sl_mac
->
tx_sl_bch
.
sl_mib
[
1
];
LOG_I
(
NR_MAC
,
"[UE%d]SL RRC->MAC: TX SLSS REQ - TDD CONFIG STUFFED INSIDE - SL-MIB :%x
\n
"
,
module_id
,
*
((
uint32_t
*
)
sl_mac
->
tx_sl_bch
.
sl_mib
));
}
//This API is called by RRC after it determines that UE needs to keep
// receiving SL-SSB from the sync ref UE
void
nr_rrc_mac_config_req_sl_mib
(
module_id_t
module_id
,
NR_SL_SSB_TimeAllocation_r16_t
*
ssb_ta
,
uint16_t
rx_slss_id
,
uint8_t
*
sl_mib
)
{
NR_UE_MAC_INST_t
*
mac
=
get_mac_inst
(
module_id
);
sl_nr_ue_mac_params_t
*
sl_mac
=
mac
->
SL_MAC_PARAMS
;
AssertFatal
(
sl_mac
,
"Sidelink MAC instance cannot be NULL"
);
AssertFatal
(
ssb_ta
,
"ssb_ta cannot be NULL"
);
AssertFatal
(
rx_slss_id
<
672
,
"SLSS id cannot be >= 672. id:%d"
,
rx_slss_id
);
AssertFatal
(
sl_mib
,
"sl_mib cannot be NULL"
);
sl_nr_phy_config_request_t
*
sl_config
=
&
sl_mac
->
sl_phy_config
.
sl_config_req
;
//Update configs if Sync source is not set else nothing to be done
if
(
sl_config
->
sl_sync_source
.
sync_source
==
SL_SYNC_SOURCE_NONE
)
{
//Set SYNC source as SYNC REF UE and send the remaining config to PHY
sl_config
->
config_mask
=
0xF
;
//all configs done.
sl_config
->
sl_sync_source
.
sync_source
=
SL_SYNC_SOURCE_SYNC_REF_UE
;
sl_config
->
sl_sync_source
.
rx_slss_id
=
rx_slss_id
;
sl_mac
->
rx_sl_bch
.
status
=
1
;
sl_mac
->
rx_sl_bch
.
slss_id
=
rx_slss_id
;
sl_mac
->
rx_sl_bch
.
num_ssb
=
0
;
sl_mac
->
rx_sl_bch
.
ssb_slot
=
0
;
sl_mac_config_ssb_time_alloc
(
module_id
,
ssb_ta
,
&
sl_mac
->
rx_sl_bch
.
ssb_time_alloc
);
LOG_I
(
NR_MAC
,
"[UE%d]SL RRC->MAC: RX SLSS REQ SLSS-id:%d, SL-MIB:%x, numssb:%d, offset:%d, interval:%d
\n
"
,
module_id
,
sl_mac
->
rx_sl_bch
.
slss_id
,
*
((
uint32_t
*
)
sl_mib
),
sl_mac
->
rx_sl_bch
.
ssb_time_alloc
.
sl_NumSSB_WithinPeriod
,
sl_mac
->
rx_sl_bch
.
ssb_time_alloc
.
sl_TimeOffsetSSB
,
sl_mac
->
rx_sl_bch
.
ssb_time_alloc
.
sl_TimeInterval
);
if
(
sl_mac
->
sl_TDD_config
==
NULL
)
sl_mac
->
sl_TDD_config
=
CALLOC
(
sizeof
(
NR_TDD_UL_DL_ConfigCommon_t
),
1
);
sl_nr_phy_config_request_t
*
cfg
=
&
sl_mac
->
sl_phy_config
.
sl_config_req
;
int
ret
=
1
;
ret
=
sl_decode_sl_TDD_Config
(
sl_mac
->
sl_TDD_config
,
sl_mib
[
0
],
sl_mib
[
1
]
&
0xF0
,
cfg
->
sl_bwp_config
.
sl_scs
,
cfg
->
sl_bwp_config
.
sl_num_symbols
,
cfg
->
sl_bwp_config
.
sl_start_symbol
);
if
(
ret
==
0
)
{
//sl_tdd_config bytes are all 1's - no TDD config present use all slots for sidelink.
//Spec not clear -- TBD...
sl_mac
->
sl_TDD_config
->
pattern1
.
nrofUplinkSlots
=
NR_NUMBER_OF_SUBFRAMES_PER_FRAME
*
(
1
<<
cfg
->
sl_bwp_config
.
sl_scs
);
}
sl_set_tdd_config_nr_ue
(
&
cfg
->
tdd_table
,
cfg
->
sl_bwp_config
.
sl_scs
,
&
sl_mac
->
sl_TDD_config
->
pattern1
);
LOG_I
(
MAC
,
"SIDELINK CONFIGs: tdd config period:%ld, mu:%ld, DLslots:%ld,ULslots:%ld Mixedslotsym DL:UL %ld:%ld
\n
"
,
sl_mac
->
sl_TDD_config
->
pattern1
.
dl_UL_TransmissionPeriodicity
,
sl_mac
->
sl_TDD_config
->
referenceSubcarrierSpacing
,
sl_mac
->
sl_TDD_config
->
pattern1
.
nrofDownlinkSlots
,
sl_mac
->
sl_TDD_config
->
pattern1
.
nrofUplinkSlots
,
sl_mac
->
sl_TDD_config
->
pattern1
.
nrofDownlinkSymbols
,
sl_mac
->
sl_TDD_config
->
pattern1
.
nrofUplinkSymbols
);
}
}
openair2/LAYER2/NR_MAC_UE/mac_defs.h
View file @
d01c1470
...
...
@@ -47,6 +47,7 @@
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "LAYER2/MAC/mac.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "mac_defs_sl.h"
/* RRC */
#include "NR_DRX-Config.h"
...
...
@@ -543,6 +544,9 @@ typedef struct NR_UE_MAC_INST_s {
pthread_mutex_t
mutex_dl_info
;
//SIDELINK MAC PARAMETERS
sl_nr_ue_mac_params_t
*
SL_MAC_PARAMS
;
}
NR_UE_MAC_INST_t
;
/*@}*/
...
...
openair2/LAYER2/NR_MAC_UE/mac_defs_sl.h
0 → 100644
View file @
d01c1470
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __MAC_DEFS_SL_H__
#define __MAC_DEFS_SL_H__
#include "sidelink_nr_ue_interface.h"
#include "NR_SL-ResourcePool-r16.h"
#include "NR_TDD-UL-DL-ConfigCommon.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "NR_UE_PHY_INTERFACE/NR_IF_Module.h"
#define SL_NR_MAC_NUM_RX_RESOURCE_POOLS 1
#define SL_NR_MAC_NUM_TX_RESOURCE_POOLS 1
#define SL_NUM_BYTES_TIMERESOURCEBITMAP 20
// Size of Fixed fields prio (3), sci_2ndstage(2),
// betaoffsetindicator(2), num dmrs ports (1), mcs (5bits)
#define SL_SCI_FORMAT_1A_LEN_IN_BITS_FIXED_FIELDS 13
#define NR_SBCCH_SL_BCH 0xFF
#define sci_field_t dci_field_t
typedef
struct
sidelink_sci_format_1a_fields
{
// Priority of this transmission
uint8_t
priority
;
//3 bits
//Indicates the format to be used in 2nd stage i.e SCI format 2 sent on PSSCH
//00 - SCI FORMAT 2A, 01 - SCI FORMAT 2B, 10, 11 - Reserved
//Spec 38.212 Table 8.3.1.1-1
uint8_t
sci_format_2nd_stage
;
//2 bits
//Num modulated symbols for stage 2 SCI - TBD:
// Spec 38.212 Table 8.3.1.1-2
uint8_t
beta_offset_indicator
;
//2 bits
//determine the number of layers for data on PSSCH
// Spec 38.212 Table 8.3.1.1-3
uint8_t
num_dmrs_ports
;
//1 bit
//Modulation and coding scheme to be used for data on PSSCH
uint8_t
mcs
;
//5 bits
//Identifies the frequence resource (subchannels) to be used for PSSCH/PSCCH
//sl-MaxNumPerReserve is 2 - ceil(log2(N_subch*(N_subch+1)/2)) bits
//sl-MaxNumPerReserve is 3 - ceil(log2(N_subch*(N_subch+1)(2*N_subch+1)/6)) bits
sci_field_t
frequency_resource_assignment
;
//variable
//Identifies the Time resource (slots) to be used for PSSCH/PSCCH
//sl-MaxNumPerReserve is 2 - 5 bits
//sl-MaxNumPerReserve is 3 - 9 bits
sci_field_t
time_resource_assignment
;
//variable
//TBD:
//sl-MultiReserveResource is not configured - 0 bits
//sl-MultiReserveResource is configured - ceil(log2(number of entries in sl-ResourceReservePeriodList)) bits
sci_field_t
resource_reservation_period
;
//variable
//Identifies the DMRS Pattern to be used on PSSCH
//ceil(log2(number of dmrs patterns in sl-PSSCH-DMRS-TimePatternList)) bits
sci_field_t
dmrs_pattern
;
//variable
//Identifies the TABLE to be used to determine MCS on PSSCH
//1 table configured in sl-Additional-MCS-Table - 1 bit
//2 tables configured in sl-Additional-MCS-Table - 2 bits
//Not configured- 0 bits
sci_field_t
additional_mcs_table_indicator
;
//variable
//Identifies the number of symbols for PSFCH
//sl-PSFCH-Period Not configured- 0 bits
//if sl-PSFCH-Period configured and value 2 or 4 - 1 bit
sci_field_t
psfch_overhead_indication
;
//variable
//number of bits determined by sl-NumReservedbits
//Value encoded is 0
sci_field_t
reserved_bits
;
}
sidelink_sci_format_1a_fields_t
;
typedef
struct
SL_ResourcePool_params
{
//This holds the structure from RRC
NR_SL_ResourcePool_r16_t
*
respool
;
//NUM Subchannels in this resource pool
uint16_t
num_subch
;
//SCI-1A length is the same for this resource pool.
uint16_t
sci_1a_len
;
//SCI-1A configuration according to RESPOOL configured.
sidelink_sci_format_1a_fields_t
sci_1a
;
}
SL_ResourcePool_params_t
;
typedef
struct
sl_ssb_timealloc
{
uint32_t
sl_NumSSB_WithinPeriod
;
uint32_t
sl_TimeOffsetSSB
;
uint32_t
sl_TimeInterval
;
}
sl_ssb_timealloc_t
;
typedef
struct
sl_bch_params
{
//configured from RRC
//Parameters used to determine PSBCH slot
sl_ssb_timealloc_t
ssb_time_alloc
;
uint16_t
slss_id
;
bool
status
;
uint8_t
sl_mib
[
4
];
//Parameters incremented by MAC PSBCH scheduler
//after every SSB txn/reception
uint16_t
num_ssb
;
uint16_t
ssb_slot
;
}
sl_bch_params_t
;
typedef
struct
sl_nr_ue_mac_params
{
//Holds the RX resource pool from RRC and its related parameters
SL_ResourcePool_params_t
*
sl_RxPool
[
SL_NR_MAC_NUM_RX_RESOURCE_POOLS
];
//Holds the TX resource pool from RRC and its related parameters
SL_ResourcePool_params_t
*
sl_TxPool
[
SL_NR_MAC_NUM_TX_RESOURCE_POOLS
];
//Holds either the TDD config from RRC
//or TDD config decoded from SL-MIB
NR_TDD_UL_DL_ConfigCommon_t
*
sl_TDD_config
;
//Configured from RRC
uint32_t
sl_MaxNumConsecutiveDTX
;
uint32_t
sl_SSB_PriorityNR
;
uint8_t
sl_CSI_Acquisition
;
//MAC prepares this and sends it to PHY
nr_sl_phy_config_t
sl_phy_config
;
//Holds Broadcast params incase UE sends Sidelink SSB
sl_bch_params_t
tx_sl_bch
;
//Holds Broadcast params incase UE receives SL-SSB
sl_bch_params_t
rx_sl_bch
;
}
sl_nr_ue_mac_params_t
;
#endif
openair2/LAYER2/NR_MAC_UE/mac_proto.h
View file @
d01c1470
...
...
@@ -515,4 +515,28 @@ int nr_config_pusch_pdu(NR_UE_MAC_INST_t *mac,
RAR_grant_t
*
rar_grant
,
uint16_t
rnti
,
const
nr_dci_format_t
dci_format
);
int
nr_rrc_mac_config_req_sl_preconfig
(
module_id_t
module_id
,
NR_SL_PreconfigurationNR_r16_t
*
sl_preconfiguration
,
uint8_t
sync_source
);
void
nr_rrc_mac_transmit_slss_req
(
module_id_t
module_id
,
uint8_t
*
sl_mib_payload
,
uint16_t
tx_slss_id
,
NR_SL_SSB_TimeAllocation_r16_t
*
ssb_ta
);
void
nr_rrc_mac_config_req_sl_mib
(
module_id_t
module_id
,
NR_SL_SSB_TimeAllocation_r16_t
*
ssb_ta
,
uint16_t
rx_slss_id
,
uint8_t
*
sl_mib
);
void
sl_prepare_psbch_payload
(
NR_TDD_UL_DL_ConfigCommon_t
*
TDD_UL_DL_Config
,
uint8_t
*
bits_0_to_7
,
uint8_t
*
bits_8_to_11
,
uint8_t
mu
,
uint8_t
L
,
uint8_t
Y
);
uint8_t
sl_decode_sl_TDD_Config
(
NR_TDD_UL_DL_ConfigCommon_t
*
TDD_UL_DL_Config
,
uint8_t
bits_0_to_7
,
uint8_t
bits_8_to_11
,
uint8_t
mu
,
uint8_t
L
,
uint8_t
Y
);
uint8_t
sl_determine_sci_1a_len
(
uint16_t
*
num_subchannels
,
NR_SL_ResourcePool_r16_t
*
rpool
,
sidelink_sci_format_1a_fields_t
*
sci_1a
);
#endif
openair2/LAYER2/NR_MAC_UE/nr_ue_procedures_sl.c
0 → 100644
View file @
d01c1470
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "mac_defs_sl.h"
#define SL_DEBUG
uint8_t
sl_process_TDD_UL_DL_config_patterns
(
NR_TDD_UL_DL_ConfigCommon_t
*
TDD_UL_DL_Config
,
uint8_t
mu
,
double
*
slot_period_P
,
uint8_t
*
w
)
{
uint8_t
return_value
=
255
;
*
w
=
0
;
int
pattern1_dlul_period
=
TDD_UL_DL_Config
->
pattern1
.
dl_UL_TransmissionPeriodicity
;
#ifdef SL_DEBUG
printf
(
"INPUT VALUES: function: %s
\n
"
,
__func__
);
printf
(
"pattern1 periodicity:%d
\n
"
,
pattern1_dlul_period
);
if
(
TDD_UL_DL_Config
->
pattern1
.
ext1
!=
NULL
&&
TDD_UL_DL_Config
->
pattern1
.
ext1
->
dl_UL_TransmissionPeriodicity_v1530
!=
NULL
)
printf
(
"pattern1 periodicity_v1530:%ld
\n
"
,
*
TDD_UL_DL_Config
->
pattern1
.
ext1
->
dl_UL_TransmissionPeriodicity_v1530
);
if
(
TDD_UL_DL_Config
->
pattern2
!=
NULL
)
{
printf
(
"mu:%d, pattern2 periodicity:%d
\n
"
,
mu
,
pattern1_dlul_period
);
if
(
TDD_UL_DL_Config
->
pattern2
->
ext1
!=
NULL
&&
TDD_UL_DL_Config
->
pattern2
->
ext1
->
dl_UL_TransmissionPeriodicity_v1530
!=
NULL
)
printf
(
"pattern2 periodicity_v1530:%ld
\n
"
,
*
TDD_UL_DL_Config
->
pattern2
->
ext1
->
dl_UL_TransmissionPeriodicity_v1530
);
}
#endif
return_value
=
pattern1_dlul_period
;
switch
(
pattern1_dlul_period
)
{
case
0
:
*
slot_period_P
=
0
.
5
;
break
;
case
1
:
*
slot_period_P
=
0
.
625
;
break
;
case
2
:
*
slot_period_P
=
1
.
0
;
break
;
case
3
:
*
slot_period_P
=
1
.
25
;
break
;
case
4
:
*
slot_period_P
=
2
.
0
;
break
;
case
5
:
*
slot_period_P
=
2
.
5
;
break
;
case
6
:
*
slot_period_P
=
5
.
0
;
return_value
=
7
;
break
;
case
7
:
*
slot_period_P
=
10
.
0
;
return_value
=
8
;
break
;
default:
AssertFatal
(
1
==
0
,
"Incorrect value of dl_UL_TransmissionPeriodicity
\n
"
);
break
;
}
if
(
TDD_UL_DL_Config
->
pattern1
.
ext1
!=
NULL
&&
TDD_UL_DL_Config
->
pattern1
.
ext1
->
dl_UL_TransmissionPeriodicity_v1530
!=
NULL
)
{
if
(
*
TDD_UL_DL_Config
->
pattern1
.
ext1
->
dl_UL_TransmissionPeriodicity_v1530
==
1
)
{
*
slot_period_P
=
4
.
0
;
return_value
=
6
;
}
else
{
*
slot_period_P
=
3
.
0
;
return_value
=
255
;
}
}
if
(
TDD_UL_DL_Config
->
pattern2
!=
NULL
)
{
return_value
=
255
;
*
w
=
1
;
if
((
*
slot_period_P
==
4
.
0
)
&&
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
1
))
{
return_value
=
13
;
*
w
=
(
mu
==
3
)
?
2
:
1
;
}
else
if
((
*
slot_period_P
==
3
.
0
)
&&
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
4
))
{
return_value
=
12
;
*
w
=
(
mu
==
3
)
?
2
:
1
;
}
else
if
((
*
slot_period_P
==
3
.
0
)
&&
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
2
))
{
return_value
=
8
;
*
w
=
(
mu
==
3
)
?
2
:
1
;
}
else
{
switch
(
pattern1_dlul_period
)
{
case
7
:
if
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
7
)
{
return_value
=
15
;
*
w
=
1
<<
mu
;
}
break
;
case
6
:
if
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
6
)
{
return_value
=
14
;
*
w
=
(
mu
==
0
)
?
1
:
1
<<
(
mu
-
1
);
}
break
;
case
5
:
if
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
5
)
{
return_value
=
11
;
*
w
=
(
mu
==
3
)
?
2
:
1
;
}
break
;
case
4
:
if
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
0
)
{
return_value
=
5
;
}
else
if
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
4
)
{
return_value
=
7
;
}
else
if
(
TDD_UL_DL_Config
->
pattern2
->
ext1
!=
NULL
&&
*
TDD_UL_DL_Config
->
pattern2
->
ext1
->
dl_UL_TransmissionPeriodicity_v1530
==
0
)
{
return_value
=
10
;
*
w
=
(
mu
==
3
)
?
2
:
1
;
}
break
;
case
3
:
if
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
3
)
{
return_value
=
4
;
}
break
;
case
2
:
if
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
2
)
{
return_value
=
2
;
}
else
if
(
TDD_UL_DL_Config
->
pattern2
->
ext1
!=
NULL
&&
*
TDD_UL_DL_Config
->
pattern2
->
ext1
->
dl_UL_TransmissionPeriodicity_v1530
==
0
)
{
return_value
=
6
;
*
w
=
(
mu
==
3
)
?
2
:
1
;
}
else
if
(
TDD_UL_DL_Config
->
pattern2
->
ext1
!=
NULL
&&
*
TDD_UL_DL_Config
->
pattern2
->
ext1
->
dl_UL_TransmissionPeriodicity_v1530
==
1
)
{
return_value
=
9
;
*
w
=
(
mu
==
3
)
?
2
:
1
;
}
break
;
case
1
:
if
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
1
)
{
return_value
=
1
;
}
break
;
case
0
:
if
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
0
)
{
return_value
=
0
;
}
else
if
(
TDD_UL_DL_Config
->
pattern2
->
dl_UL_TransmissionPeriodicity
==
4
)
{
return_value
=
3
;
}
break
;
default:
AssertFatal
(
1
==
0
,
"Incorrect value of dl_UL_TransmissionPeriodicity"
);
}
}
}
#ifdef SL_DEBUG
printf
(
"OUTPUT VALUES: function %s
\n
"
,
__func__
);
printf
(
"return_value:%d, *w:%d, slot_period_P:%f
\n
"
,
return_value
,
*
w
,
*
slot_period_P
);
#endif
return
return_value
;
}
/*
This procedures prepares the psbch payload of tdd configuration according
to section 16.1 in 38.213
*/
void
sl_prepare_psbch_payload
(
NR_TDD_UL_DL_ConfigCommon_t
*
TDD_UL_DL_Config
,
uint8_t
*
bits_0_to_7
,
uint8_t
*
bits_8_to_11
,
uint8_t
mu
,
uint8_t
L
,
uint8_t
Y
)
{
uint8_t
w
=
0
,
a1_to_a4
=
0
;
uint8_t
mu_ref
=
0
,
diff
=
0
;
uint8_t
u_slots
=
0
,
u_sym
=
0
,
I1
=
0
;
uint8_t
u_sl_slots
=
0
,
u_sl_slots_2
=
0
;
double
slot_period_P
=
0
.
0
;
*
bits_0_to_7
=
0xFF
;
// If TDD_UL_DL_Config = NULL all 12 bits are set to 1
*
bits_8_to_11
=
0xF0
;
if
(
TDD_UL_DL_Config
!=
NULL
)
{
mu_ref
=
TDD_UL_DL_Config
->
referenceSubcarrierSpacing
;
diff
=
1
<<
(
mu
-
mu_ref
);
u_slots
=
TDD_UL_DL_Config
->
pattern1
.
nrofUplinkSlots
;
u_sym
=
TDD_UL_DL_Config
->
pattern1
.
nrofUplinkSymbols
;
I1
=
((
u_sym
*
diff
)
%
L
>=
(
L
-
Y
))
?
1
:
0
;
#ifdef SL_DEBUG
printf
(
"INPUT VALUES: function %s
\n
"
,
__func__
);
printf
(
"numerology:%d, number of symbols:%d, sl-startSymbol:%d
\n
"
,
mu
,
L
,
Y
);
printf
(
"mu_ref:%d, u_slots:%d, u_sym:%d
\n
"
,
mu_ref
,
u_slots
,
u_sym
);
if
(
TDD_UL_DL_Config
->
pattern2
!=
NULL
)
printf
(
"u_slots_2:%ld, u_sym_2:%ld
\n
"
,
TDD_UL_DL_Config
->
pattern2
->
nrofUplinkSlots
,
TDD_UL_DL_Config
->
pattern2
->
nrofUplinkSymbols
);
#endif
u_sl_slots
=
(
u_slots
*
diff
)
+
floor
((
u_sym
*
diff
)
/
L
)
+
I1
;
a1_to_a4
=
sl_process_TDD_UL_DL_config_patterns
(
TDD_UL_DL_Config
,
mu
,
&
slot_period_P
,
&
w
);
AssertFatal
(
a1_to_a4
!=
255
,
"Incorrect return value, wrong configuration.
\n
"
);
#ifdef SL_DEBUG
printf
(
"I1:%d, a1_to_a2:%d, u_sl_slots:%d
\n
"
,
I1
,
a1_to_a4
,
u_sl_slots
);
#endif
if
(
TDD_UL_DL_Config
->
pattern2
!=
NULL
)
{
uint8_t
u_slots_2
=
TDD_UL_DL_Config
->
pattern2
->
nrofUplinkSlots
;
uint8_t
u_sym_2
=
TDD_UL_DL_Config
->
pattern2
->
nrofUplinkSymbols
;
uint8_t
I2
=
((
u_sym_2
*
diff
)
%
L
>=
(
L
-
Y
))
?
1
:
0
;
uint16_t
val
=
floor
(((
u_slots_2
*
diff
)
+
floor
((
u_sym_2
*
diff
)
/
L
)
+
I2
)
/
w
);
u_sl_slots_2
=
val
*
ceil
((
slot_period_P
*
(
1
<<
mu
)
+
1
)
/
w
)
+
floor
(
u_sl_slots
/
w
);
*
bits_0_to_7
=
0x80
|
(
a1_to_a4
<<
3
)
|
((
u_sl_slots_2
&
0x70
)
>>
4
);
*
bits_8_to_11
=
(
u_sl_slots_2
&
0x0F
)
<<
4
;
#ifdef SL_DEBUG
printf
(
"I2:%d, val:%d, u_sl_slots_2:%d
\n
"
,
I2
,
val
,
u_sl_slots_2
);
#endif
}
else
{
*
bits_0_to_7
=
0x00
|
(
a1_to_a4
<<
3
)
|
((
u_sl_slots
&
0x70
)
>>
4
);
*
bits_8_to_11
=
(
u_sl_slots
&
0x0F
)
<<
4
;
}
}
#ifdef SL_DEBUG
printf
(
"OUTPUT VALUES: function %s
\n
"
,
__func__
);
printf
(
"12 bits payload buf[0]:%x, buf[1]:%x
\n
"
,
*
bits_0_to_7
,
*
bits_8_to_11
);
#endif
}
/*
This procedures prepares the psbch payload of tdd configuration according
to section 16.1 in 38.213
*/
uint8_t
sl_decode_sl_TDD_Config
(
NR_TDD_UL_DL_ConfigCommon_t
*
TDD_UL_DL_Config
,
uint8_t
bits_0_to_7
,
uint8_t
bits_8_to_11
,
uint8_t
mu
,
uint8_t
L
,
uint8_t
Y
)
{
AssertFatal
(
TDD_UL_DL_Config
,
"TDD_UL_DL_Config cannot be null"
);
uint16_t
num_SL_slots
=
0
,
mixed_slot_numsym
=
0
;
TDD_UL_DL_Config
->
pattern1
.
nrofDownlinkSlots
=
0
;
TDD_UL_DL_Config
->
pattern1
.
nrofDownlinkSymbols
=
0
;
TDD_UL_DL_Config
->
pattern1
.
nrofUplinkSlots
=
0
;
TDD_UL_DL_Config
->
pattern1
.
nrofUplinkSymbols
=
0
;
TDD_UL_DL_Config
->
referenceSubcarrierSpacing
=
mu
;
TDD_UL_DL_Config
->
pattern1
.
ext1
=
NULL
;
LOG_D
(
MAC
,
"bits_0_to_7:%x, bits_8_to_11:%x, mu:%d, L:%d, Y:%d
\n
"
,
bits_0_to_7
,
bits_8_to_11
,
mu
,
L
,
Y
);
//If all bits are 1 - indicates that no TDD config was present.
if
((
bits_0_to_7
==
0xFF
)
&&
((
bits_8_to_11
&
0xF0
)
==
0xF0
))
{
//If no TDD config present - use all slots for Sidelink.
//Spec not clear -- TBD....
return
0
;
}
//Bit A0 if 1 indicates pattern2 as present.
if
(
bits_0_to_7
&
0x80
)
{
//Pattern1 and Pattern2 Present.
TDD_UL_DL_Config
->
pattern2
=
malloc16_clear
(
sizeof
(
*
TDD_UL_DL_Config
->
pattern2
));
AssertFatal
(
1
==
0
,
"Decoding Pattern2 - NOT YET IMPLEMENTED
\n
"
);
}
else
{
//Only Pattern1 Present. bits a1..a4 identify the periodicity.
uint8_t
val
=
(
bits_0_to_7
&
0x78
)
>>
3
;
if
(
val
>=
7
)
TDD_UL_DL_Config
->
pattern1
.
dl_UL_TransmissionPeriodicity
=
val
-
1
;
if
(
val
==
6
)
{
if
(
TDD_UL_DL_Config
->
pattern1
.
ext1
==
NULL
)
TDD_UL_DL_Config
->
pattern1
.
ext1
=
calloc
(
1
,
sizeof
(
*
TDD_UL_DL_Config
->
pattern1
.
ext1
));
if
(
TDD_UL_DL_Config
->
pattern1
.
ext1
->
dl_UL_TransmissionPeriodicity_v1530
==
NULL
)
TDD_UL_DL_Config
->
pattern1
.
ext1
->
dl_UL_TransmissionPeriodicity_v1530
=
calloc
(
1
,
sizeof
(
long
));
*
TDD_UL_DL_Config
->
pattern1
.
ext1
->
dl_UL_TransmissionPeriodicity_v1530
=
1
;
}
//a5,a6..a11 bits from the 7th to 1st LSB of num SL slots
num_SL_slots
=
((
bits_0_to_7
&
0x07
)
<<
4
)
|
((
bits_8_to_11
&
0xF0
)
>>
4
);
TDD_UL_DL_Config
->
pattern1
.
nrofUplinkSlots
=
num_SL_slots
;
TDD_UL_DL_Config
->
pattern1
.
nrofUplinkSymbols
=
mixed_slot_numsym
;
LOG_D
(
MAC
,
"SIDELINK: EXtracted TDD config from 12 bits - Sidelink Slots:%ld, Mixed_slot_symbols:%ld,dl_UL_TransmissionPeriodicity:%ld
\n
"
,
TDD_UL_DL_Config
->
pattern1
.
nrofUplinkSlots
,
TDD_UL_DL_Config
->
pattern1
.
nrofUplinkSymbols
,
TDD_UL_DL_Config
->
pattern1
.
dl_UL_TransmissionPeriodicity
);
}
return
1
;
}
/*Function used to prepare Sidelink MIB*/
uint32_t
sl_prepare_MIB
(
NR_TDD_UL_DL_ConfigCommon_t
*
TDD_UL_DL_Config
,
uint8_t
incoverage
,
uint8_t
mu
,
uint8_t
start_symbol
,
uint8_t
L
)
{
uint8_t
sl_mib_payload
[
4
]
=
{
0
,
0
,
0
,
0
};
//int mu = UE->sl_frame_params.numerology_index, start_symbol = UE->start_symbol;
uint8_t
byte0
,
byte1
;
//int L = (UE->sl_frame_params.Ncp == 0) ? 14 : 12;
uint32_t
sl_mib
=
0
;
sl_prepare_psbch_payload
(
TDD_UL_DL_Config
,
&
byte0
,
&
byte1
,
mu
,
L
,
start_symbol
);
sl_mib_payload
[
0
]
=
byte0
;
sl_mib_payload
[
1
]
=
byte1
;
AssertFatal
(
incoverage
<=
1
,
"Invalid value for incoverage paramter for SL-MIB. Accepted values 0 or 1
\n
"
);
sl_mib_payload
[
1
]
|=
(
incoverage
<<
3
);
sl_mib
=
sl_mib_payload
[
1
]
<<
8
|
sl_mib_payload
[
0
];
#ifdef SL_DEBUG
printf
(
"SIDELINK PSBCH SIM: NUM SYMBOLS:%d, mu:%d, start_symbol:%d incoverage:%d
\n
"
,
L
,
mu
,
start_symbol
,
incoverage
);
printf
(
"SIDELINK PSBCH PAYLOAD: psbch_a:%x, sl_mib_payload:%x %x %x %x
\n
"
,
sl_mib
,
sl_mib_payload
[
0
],
sl_mib_payload
[
1
],
sl_mib_payload
[
2
],
sl_mib_payload
[
3
]);
#endif
return
sl_mib
;
}
uint16_t
sl_get_subchannel_size
(
NR_SL_ResourcePool_r16_t
*
rpool
)
{
uint16_t
subch_size
=
0
;
const
uint8_t
subchsizes
[
8
]
=
{
10
,
12
,
15
,
20
,
25
,
50
,
75
,
100
};
subch_size
=
(
rpool
->
sl_SubchannelSize_r16
)
?
subchsizes
[
*
rpool
->
sl_SubchannelSize_r16
]
:
0
;
AssertFatal
(
subch_size
,
"Subch Size cannot be 0.Resource Pool Configuration Error
\n
"
);
return
subch_size
;
}
uint16_t
sl_get_num_subch
(
NR_SL_ResourcePool_r16_t
*
rpool
)
{
uint16_t
num_subch
=
0
;
uint16_t
subch_size
=
sl_get_subchannel_size
(
rpool
);
uint16_t
num_rbs
=
(
rpool
->
sl_RB_Number_r16
)
?
*
rpool
->
sl_RB_Number_r16
:
0
;
AssertFatal
(
num_rbs
,
"NumRbs in rpool cannot be 0.Resource Pool Configuration Error
\n
"
);
num_subch
=
num_rbs
/
subch_size
;
LOG_I
(
NR_MAC
,
"Subch_size:%d, numRBS:%d, num_subch:%d
\n
"
,
subch_size
,
num_rbs
,
num_subch
);
return
(
num_subch
);
}
//This function determines SCI 1A Len in bits based on the configuration in the resource pool.
uint8_t
sl_determine_sci_1a_len
(
uint16_t
*
num_subchannels
,
NR_SL_ResourcePool_r16_t
*
rpool
,
sidelink_sci_format_1a_fields_t
*
sci_1a
)
{
uint8_t
num_bits
=
0
;
//Size of Fixed fields prio (3), sci_2ndstage(2),
//betaoffsetindicator(2), num dmrs ports (1), mcs (5bits)
uint8_t
sci_1a_len
=
SL_SCI_FORMAT_1A_LEN_IN_BITS_FIXED_FIELDS
;
*
num_subchannels
=
sl_get_num_subch
(
rpool
);
uint16_t
n_subch
=
*
num_subchannels
;
LOG_D
(
NR_MAC
,
"Determine SCI-1A len - Num Subch:%d, sci 1A len fixed fields:%d
\n
"
,
*
num_subchannels
,
sci_1a_len
);
NR_SL_UE_SelectedConfigRP_r16_t
*
selectedconfigRP
=
rpool
->
sl_UE_SelectedConfigRP_r16
;
const
uint8_t
maxnum_values
[]
=
{
2
,
3
};
uint8_t
sl_MaxNumPerReserve
=
(
selectedconfigRP
&&
selectedconfigRP
->
sl_MaxNumPerReserve_r16
)
?
maxnum_values
[
*
selectedconfigRP
->
sl_MaxNumPerReserve_r16
]
:
0
;
//Determine bits for Freq and Time Resource assignment
if
(
sl_MaxNumPerReserve
==
3
)
{
num_bits
=
ceil
(
log2
(
n_subch
*
(
n_subch
+
1
)
*
(
2
*
n_subch
+
1
)
/
6
));
sci_1a_len
+=
num_bits
;
sci_1a
->
frequency_resource_assignment
.
nbits
=
num_bits
;
sci_1a_len
+=
9
;
sci_1a
->
time_resource_assignment
.
nbits
=
9
;
}
else
{
num_bits
=
ceil
(
log2
((
n_subch
*
(
n_subch
+
1
))
>>
1
));
sci_1a_len
+=
num_bits
;
sci_1a
->
frequency_resource_assignment
.
nbits
=
num_bits
;
sci_1a_len
+=
5
;
sci_1a
->
time_resource_assignment
.
nbits
=
5
;
}
LOG_D
(
NR_MAC
,
"sci 1A - sl_MaxNumPerReserve:%d, sci 1a len:%d, FRA nbits:%d, TRA nbits:%d
\n
"
,
sl_MaxNumPerReserve
,
sci_1a_len
,
sci_1a
->
frequency_resource_assignment
.
nbits
,
sci_1a
->
time_resource_assignment
.
nbits
);
//Determine bits for res reservation period
uint8_t
n_rsvperiod
=
(
selectedconfigRP
&&
selectedconfigRP
->
sl_ResourceReservePeriodList_r16
)
?
selectedconfigRP
->
sl_ResourceReservePeriodList_r16
->
list
.
count
:
0
;
#define SL_IE_ENABLED 0
if
(
selectedconfigRP
&&
selectedconfigRP
->
sl_MultiReserveResource_r16
==
SL_IE_ENABLED
)
{
num_bits
=
ceil
(
log2
(
n_rsvperiod
));
sci_1a_len
+=
num_bits
;
sci_1a
->
resource_reservation_period
.
nbits
=
num_bits
;
}
else
sci_1a
->
resource_reservation_period
.
nbits
=
0
;
LOG_D
(
NR_MAC
,
"sci 1A - n_rsvperiod:%d, sci 1a len:%d, res reserve period.nbits:%d
\n
"
,
n_rsvperiod
,
sci_1a_len
,
sci_1a
->
resource_reservation_period
.
nbits
);
uint8_t
n_dmrspatterns
=
0
;
if
(
rpool
->
sl_PSSCH_Config_r16
&&
rpool
->
sl_PSSCH_Config_r16
->
present
==
NR_SetupRelease_SL_PSSCH_Config_r16_PR_setup
)
{
NR_SL_PSSCH_Config_r16_t
*
pssch_cfg
=
rpool
->
sl_PSSCH_Config_r16
->
choice
.
setup
;
//Determine bits for DMRS PATTERNS
n_dmrspatterns
=
(
pssch_cfg
&&
pssch_cfg
->
sl_PSSCH_DMRS_TimePatternList_r16
)
?
pssch_cfg
->
sl_PSSCH_DMRS_TimePatternList_r16
->
list
.
count
:
0
;
}
AssertFatal
((
n_dmrspatterns
>=
1
)
&&
(
n_dmrspatterns
<=
3
),
"Number of DMRS Patterns should be 1or2or3. Resource Pool Configuration Error.
\n
"
);
if
(
n_dmrspatterns
)
{
num_bits
=
ceil
(
log2
(
n_dmrspatterns
));
sci_1a_len
+=
num_bits
;
sci_1a
->
dmrs_pattern
.
nbits
=
num_bits
;
}
LOG_D
(
NR_MAC
,
"sci 1A - n_dmrspatterns:%d, sci 1a len:%d, dmrs_pattern.nbits:%d
\n
"
,
n_dmrspatterns
,
sci_1a_len
,
sci_1a
->
dmrs_pattern
.
nbits
);
//Determine bits for Additional MCS table
if
(
rpool
->
sl_Additional_MCS_Table_r16
)
{
int
numbits
=
(
*
rpool
->
sl_Additional_MCS_Table_r16
>
1
)
?
2
:
1
;
sci_1a_len
+=
numbits
;
sci_1a
->
additional_mcs_table_indicator
.
nbits
=
numbits
;
AssertFatal
(
*
rpool
->
sl_Additional_MCS_Table_r16
<=
2
,
"additional table value cannot be > 2. Resource Pool Configuration Error.
\n
"
);
}
LOG_D
(
NR_MAC
,
"sci 1A - additional_table:%ld, sci 1a len:%d, additional table nbits:%d
\n
"
,
*
rpool
->
sl_Additional_MCS_Table_r16
,
sci_1a_len
,
sci_1a
->
additional_mcs_table_indicator
.
nbits
);
uint8_t
psfch_period
=
0
;
if
(
rpool
->
sl_PSFCH_Config_r16
&&
rpool
->
sl_PSFCH_Config_r16
->
present
==
NR_SetupRelease_SL_PSFCH_Config_r16_PR_setup
)
{
NR_SL_PSFCH_Config_r16_t
*
psfch_config
=
rpool
->
sl_PSFCH_Config_r16
->
choice
.
setup
;
//Determine bits for PSFCH overhead indication
const
uint8_t
psfch_periods
[]
=
{
0
,
1
,
2
,
4
};
psfch_period
=
(
psfch_config
->
sl_PSFCH_Period_r16
)
?
psfch_periods
[
*
psfch_config
->
sl_PSFCH_Period_r16
]
:
0
;
}
if
((
psfch_period
==
2
)
||
(
psfch_period
==
4
))
{
sci_1a_len
+=
1
;
sci_1a
->
psfch_overhead_indication
.
nbits
=
1
;
}
else
sci_1a
->
psfch_overhead_indication
.
nbits
=
0
;
LOG_D
(
NR_MAC
,
"sci 1A - psfch_period:%d, sci 1a len:%d, psfch overhead nbits:%d
\n
"
,
psfch_period
,
sci_1a_len
,
sci_1a
->
psfch_overhead_indication
.
nbits
);
//Determine number of reserved bits
uint8_t
num_reservedbits
=
0
;
if
(
rpool
->
sl_PSCCH_Config_r16
&&
rpool
->
sl_PSCCH_Config_r16
->
present
==
NR_SetupRelease_SL_PSCCH_Config_r16_PR_setup
)
{
NR_SL_PSCCH_Config_r16_t
*
pscch_config
=
rpool
->
sl_PSCCH_Config_r16
->
choice
.
setup
;
num_reservedbits
=
(
pscch_config
->
sl_NumReservedBits_r16
)
?
*
pscch_config
->
sl_NumReservedBits_r16
:
0
;
}
AssertFatal
((
num_reservedbits
>=
2
)
||
(
num_reservedbits
<=
4
)
,
"Num Reserved bits can only be 2or3or4. Resource Pool Configuration Error.
\n
"
);
sci_1a_len
+=
num_reservedbits
;
sci_1a
->
reserved_bits
.
nbits
=
num_reservedbits
;
LOG_D
(
NR_MAC
,
"sci 1A - reserved_bits:%d, sci 1a len:%d, sci_1a->reserved_bits.nbits:%d
\n
"
,
num_reservedbits
,
sci_1a_len
,
sci_1a
->
reserved_bits
.
nbits
);
LOG_D
(
NR_MAC
,
"sci 1A Length in bits: %d
\n
"
,
sci_1a_len
);
return
sci_1a_len
;
}
openair2/RRC/NR_UE/L2_interface_ue.c
View file @
d01c1470
...
...
@@ -94,6 +94,32 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
AssertFatal
(
false
,
"use RLC instead
\n
"
);
break
;
case
NR_SBCCH_SL_BCH
:
if
(
pdu_len
>
0
)
{
LOG_T
(
NR_RRC
,
"[UE %d] Received SL-MIB for NR_SBCCH_SL_BCH.
\n
"
,
module_id
);
MessageDef
*
message_p
;
int
msg_sdu_size
=
BCCH_SDU_SIZE
;
if
(
pdu_len
>
msg_sdu_size
)
{
LOG_E
(
NR_RRC
,
"SDU larger than NR_SBCCH_SL_BCH SDU buffer size (%d, %d)"
,
sdu_size
,
msg_sdu_size
);
sdu_size
=
msg_sdu_size
;
}
else
{
sdu_size
=
pdu_len
;
}
message_p
=
itti_alloc_new_message
(
TASK_MAC_UE
,
0
,
NR_RRC_MAC_SBCCH_DATA_IND
);
memset
(
NR_RRC_MAC_SBCCH_DATA_IND
(
message_p
).
sdu
,
0
,
BCCH_SDU_SIZE
);
memcpy
(
NR_RRC_MAC_SBCCH_DATA_IND
(
message_p
).
sdu
,
pduP
,
sdu_size
);
NR_RRC_MAC_SBCCH_DATA_IND
(
message_p
).
frame
=
frame
;
//frameP
NR_RRC_MAC_SBCCH_DATA_IND
(
message_p
).
slot
=
slot
;
NR_RRC_MAC_SBCCH_DATA_IND
(
message_p
).
sdu_size
=
sdu_size
;
NR_RRC_MAC_SBCCH_DATA_IND
(
message_p
).
gnb_index
=
gNB_index
;
NR_RRC_MAC_SBCCH_DATA_IND
(
message_p
).
rx_slss_id
=
rnti
;
//rx_slss_id is rnti
itti_send_msg_to_task
(
TASK_RRC_NRUE
,
GNB_MODULE_ID_TO_INSTANCE
(
module_id
),
message_p
);
}
break
;
default:
break
;
}
...
...
openair2/RRC/NR_UE/rrc_UE.c
View file @
d01c1470
...
...
@@ -324,10 +324,8 @@ NR_UE_RRC_INST_t* nr_rrc_init_ue(char* uecap_file, int nb_inst)
// SRB0 activated by default
ptr
->
Srb
[
0
]
=
RB_ESTABLISHED
;
}
}
if
(
get_softmodem_params
()
->
sl_mode
)
{
configure_NR_SL_Preconfig
(
get_softmodem_params
()
->
sync_ref
);
init_sidelink
(
rrc
);
}
return
NR_UE_rrc_inst
;
...
...
@@ -1437,6 +1435,14 @@ void *rrc_nrue(void *notUsed)
nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message
(
rrc
,
bcch
->
gnb_index
,
bcch
->
sdu
,
bcch
->
sdu_size
,
bcch
->
rsrq
,
bcch
->
rsrp
);
break
;
case
NR_RRC_MAC_SBCCH_DATA_IND
:
LOG_D
(
NR_RRC
,
"[UE %ld] Received %s: gNB %d
\n
"
,
instance
,
ITTI_MSG_NAME
(
msg_p
),
NR_RRC_MAC_SBCCH_DATA_IND
(
msg_p
).
gnb_index
);
NRRrcMacSBcchDataInd
*
sbcch
=
&
NR_RRC_MAC_SBCCH_DATA_IND
(
msg_p
);
nr_rrc_ue_decode_NR_SBCCH_SL_BCH_Message
(
rrc
,
sbcch
->
gnb_index
,
sbcch
->
frame
,
sbcch
->
slot
,
sbcch
->
sdu
,
sbcch
->
sdu_size
,
sbcch
->
rx_slss_id
);
break
;
case
NR_RRC_MAC_CCCH_DATA_IND
:
{
NRRrcMacCcchDataInd
*
ind
=
&
NR_RRC_MAC_CCCH_DATA_IND
(
msg_p
);
nr_rrc_ue_decode_ccch
(
rrc
,
ind
,
0
);
...
...
@@ -1921,3 +1927,17 @@ void handle_t300_expiry(NR_UE_RRC_INST_t *rrc)
// TODO handle connEstFailureControl
// TODO inform upper layers about the failure to establish the RRC connection
}
//This calls the sidelink preconf message after RRC, MAC instances are created.
void
start_sidelink
(
int
instance
)
{
NR_UE_RRC_INST_t
*
rrc
=
&
NR_UE_rrc_inst
[
instance
];
if
(
get_softmodem_params
()
->
sl_mode
==
2
)
{
//Process the Sidelink Preconfiguration
rrc_ue_process_sidelink_Preconfiguration
(
rrc
,
get_softmodem_params
()
->
sync_ref
);
}
}
openair2/RRC/NR_UE/rrc_defs.h
View file @
d01c1470
...
...
@@ -54,6 +54,8 @@
#include "NR_DL-DCCH-Message.h"
#include "NR_SystemInformation.h"
#include "NR_UE-NR-Capability.h"
#include "NR_SL-PreconfigurationNR-r16.h"
#include "NR_MasterInformationBlockSidelink.h"
#include "RRC/NR/nr_rrc_common.h"
#include "as_message.h"
...
...
@@ -210,6 +212,10 @@ typedef struct NR_UE_RRC_INST_s {
long
selected_plmn_identity
;
Rrc_State_NR_t
nrRrcState
;
as_nas_info_t
initialNasMsg
;
//Sidelink params
NR_SL_PreconfigurationNR_r16_t
*
sl_preconfig
;
}
NR_UE_RRC_INST_t
;
#endif
openair2/RRC/NR_UE/rrc_proto.h
View file @
d01c1470
...
...
@@ -121,7 +121,20 @@ void handle_rlf_sync(NR_UE_Timers_Constants_t *tac, nr_sync_msg_t sync_msg);
void
nr_rrc_handle_SetupRelease_RLF_TimersAndConstants
(
NR_UE_RRC_INST_t
*
rrc
,
struct
NR_SetupRelease_RLF_TimersAndConstants
*
rlf_TimersAndConstants
);
int
configure_NR_SL_Preconfig
(
int
sync_source
);
int
configure_NR_SL_Preconfig
(
NR_UE_RRC_INST_t
*
rrc
,
int
sync_source
);
void
init_sidelink
(
NR_UE_RRC_INST_t
*
rrc
);
void
start_sidelink
(
int
instance
);
void
rrc_ue_process_sidelink_Preconfiguration
(
NR_UE_RRC_INST_t
*
rrc_inst
,
int
sync_ref
);
void
nr_rrc_ue_decode_NR_SBCCH_SL_BCH_Message
(
NR_UE_RRC_INST_t
*
rrc
,
const
uint8_t
gNB_index
,
const
frame_t
frame
,
const
int
slot
,
uint8_t
*
pduP
,
const
sdu_size_t
pdu_len
,
const
uint16_t
rx_slss_id
);
/** @}*/
#endif
...
...
openair2/RRC/NR_UE/rrc_sl_preconfig.c
View file @
d01c1470
...
...
@@ -27,6 +27,17 @@
#include "common/utils/LOG/log.h"
#include "sl_preconfig_paramvalues.h"
#include "common/config/config_userapi.h"
#include "rrc_defs.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "nr-uesoftmodem.h"
void
free_sl_rrc
(
NR_UE_RRC_INST_t
*
rrc
)
{
if
(
rrc
->
sl_preconfig
)
{
ASN_STRUCT_FREE
(
asn_DEF_NR_SL_PreconfigurationNR_r16
,
rrc
->
sl_preconfig
);
}
}
static
void
prepare_NR_SL_SyncConfig
(
NR_SL_SyncConfig_r16_t
*
sl_syncconfig
)
{
...
...
@@ -399,8 +410,7 @@ NR_SL_PreconfigurationNR_r16_t *prepare_NR_SL_PRECONFIGURATION(uint16_t num_tx_p
return
sl_preconfiguration
;
}
int
configure_NR_SL_Preconfig
(
int
sync_source
)
int
configure_NR_SL_Preconfig
(
NR_UE_RRC_INST_t
*
rrc
,
int
sync_source
)
{
NR_SL_PreconfigurationNR_r16_t
*
sl_preconfig
=
NULL
;
...
...
@@ -424,9 +434,136 @@ int configure_NR_SL_Preconfig(int sync_source)
}
}
ASN_STRUCT_FREE
(
asn_DEF_NR_SL_PreconfigurationNR_r16
,
sl_preconfig
);
sl_preconfig
=
NULL
;
//END.......
rrc
->
sl_preconfig
=
sl_preconfig
;
return
0
;
}
/*decode SL-BCH (SL-MIB) message*/
static
int8_t
nr_sl_rrc_ue_decode_SL_MIB
(
const
uint8_t
gNB_index
,
uint8_t
*
const
bufferP
,
const
uint8_t
buffer_len
)
{
NR_MasterInformationBlockSidelink_t
*
sl_mib
=
NULL
;
asn_dec_rval_t
dec_rval
=
uper_decode_complete
(
NULL
,
&
asn_DEF_NR_MasterInformationBlockSidelink
,
(
void
**
)
&
sl_mib
,
(
const
void
*
)
bufferP
,
buffer_len
);
int
ret
=
0
;
if
((
dec_rval
.
code
!=
RC_OK
)
||
(
dec_rval
.
consumed
==
0
))
{
LOG_E
(
NR_RRC
,
"SL-MIB decode error
\n
"
);
ret
=
-
1
;
}
else
{
int
bits_unused
=
sl_mib
->
directFrameNumber_r16
.
bits_unused
;
uint16_t
val_fn
=
sl_mib
->
directFrameNumber_r16
.
buf
[
0
];
val_fn
=
(
val_fn
<<
(
8
-
bits_unused
))
+
(
sl_mib
->
directFrameNumber_r16
.
buf
[
1
]
>>
bits_unused
);
uint8_t
val_slot
=
sl_mib
->
slotIndex_r16
.
buf
[
0
];
LOG_D
(
NR_RRC
,
"SL-RRC - Received MIB
\n
"
);
LOG_D
(
NR_RRC
,
"SL-MIB Contents - DFN:%d
\n
"
,
val_fn
);
LOG_D
(
NR_RRC
,
"SL-MIB Contents - SLOT:%d
\n
"
,
val_slot
>>
1
);
LOG_D
(
NR_RRC
,
"SL-MIB Contents - Incoverage:%d
\n
"
,
sl_mib
->
inCoverage_r16
);
LOG_D
(
NR_RRC
,
"SL-MIB Contents - sl-TDD-Config:%x
\n
"
,
*
((
uint16_t
*
)(
sl_mib
->
sl_TDD_Config_r16
.
buf
)));
ASN_STRUCT_FREE
(
asn_DEF_NR_MasterInformationBlockSidelink
,
sl_mib
);
}
return
ret
;
}
void
nr_rrc_ue_decode_NR_SBCCH_SL_BCH_Message
(
NR_UE_RRC_INST_t
*
rrc
,
const
uint8_t
gNB_index
,
const
frame_t
frame
,
const
int
slot
,
uint8_t
*
pduP
,
const
sdu_size_t
pdu_len
,
const
uint16_t
rx_slss_id
)
{
nr_sl_rrc_ue_decode_SL_MIB
(
gNB_index
,
(
uint8_t
*
)
pduP
,
pdu_len
);
DevAssert
(
rrc
->
sl_preconfig
);
NR_SL_FreqConfigCommon_r16_t
*
fcfg
=
NULL
;
if
(
rrc
->
sl_preconfig
->
sidelinkPreconfigNR_r16
.
sl_PreconfigFreqInfoList_r16
)
fcfg
=
rrc
->
sl_preconfig
->
sidelinkPreconfigNR_r16
.
sl_PreconfigFreqInfoList_r16
->
list
.
array
[
0
];
DevAssert
(
fcfg
);
NR_SL_SSB_TimeAllocation_r16_t
*
sl_SSB_TimeAllocation
=
NULL
;
//Current implementation only supports one SSB Timeallocation
//Extend RRC to use multiple SSB Time allocations TBD....
if
(
fcfg
->
sl_SyncConfigList_r16
)
sl_SSB_TimeAllocation
=
fcfg
->
sl_SyncConfigList_r16
->
list
.
array
[
0
]
->
sl_SSB_TimeAllocation1_r16
;
DevAssert
(
sl_SSB_TimeAllocation
);
nr_rrc_mac_config_req_sl_mib
(
rrc
->
ue_id
,
sl_SSB_TimeAllocation
,
rx_slss_id
,
pduP
);
return
;
}
void
rrc_ue_process_sidelink_Preconfiguration
(
NR_UE_RRC_INST_t
*
rrc_inst
,
sl_sync_source_enum_t
sync_source
)
{
AssertFatal
(
rrc_inst
,
"RRC instance not created.
\n
"
);
NR_SL_PreconfigurationNR_r16_t
*
sl_preconfig
=
rrc_inst
->
sl_preconfig
;
AssertFatal
(
rrc_inst
->
sl_preconfig
,
"Check if SL-preconfig was created"
);
AssertFatal
(
sync_source
!=
SL_SYNC_SOURCE_GNBENB
,
"Sync source GNB not supported
\n
"
);
nr_rrc_mac_config_req_sl_preconfig
(
rrc_inst
->
ue_id
,
sl_preconfig
,
sync_source
);
//TBD.. These should be chosen by RRC according to 3GPP 38.331 RRC specification.
//Currently hardcoding the values to these
uint16_t
slss_id
=
671
,
ssb_ta_index
=
1
;
//12 bits -sl-TDD-config will be filled by MAC
//Incoverage 1bit is FALSE as this is mode 2
//DFN, sfn will be filled by PHY
uint8_t
sl_mib_payload
[
4
]
=
{
0
,
0
,
0
,
0
};
NR_SL_SSB_TimeAllocation_r16_t
*
ssb_ta
=
NULL
;
NR_SL_FreqConfigCommon_r16_t
*
fcfg
=
NULL
;
NR_SL_SyncConfig_r16_t
*
synccfg
=
NULL
;
if
(
sl_preconfig
->
sidelinkPreconfigNR_r16
.
sl_PreconfigFreqInfoList_r16
)
fcfg
=
sl_preconfig
->
sidelinkPreconfigNR_r16
.
sl_PreconfigFreqInfoList_r16
->
list
.
array
[
0
];
AssertFatal
(
fcfg
,
"Fcfg cannot be NULL
\n
"
);
if
(
fcfg
->
sl_SyncConfigList_r16
)
synccfg
=
fcfg
->
sl_SyncConfigList_r16
->
list
.
array
[
0
];
AssertFatal
(
synccfg
,
"Synccfg cannot be NULL
\n
"
);
if
(
ssb_ta_index
==
1
)
ssb_ta
=
synccfg
->
sl_SSB_TimeAllocation1_r16
;
else
if
(
ssb_ta_index
==
2
)
ssb_ta
=
synccfg
->
sl_SSB_TimeAllocation2_r16
;
else
if
(
ssb_ta_index
==
3
)
ssb_ta
=
synccfg
->
sl_SSB_TimeAllocation3_r16
;
else
DevAssert
(
0
);
AssertFatal
(
ssb_ta
,
"SSB_timeallocation cannot be NULL
\n
"
);
if
(
sync_source
==
SL_SYNC_SOURCE_LOCAL_TIMING
||
sync_source
==
SL_SYNC_SOURCE_GNSS
)
nr_rrc_mac_transmit_slss_req
(
rrc_inst
->
ue_id
,
sl_mib_payload
,
slss_id
,
ssb_ta
);
}
//For Sidelink mode 2 operation this prepares the sidelink preconfiguration
void
init_sidelink
(
NR_UE_RRC_INST_t
*
rrc
)
{
int
sync_ref
=
get_softmodem_params
()
->
sync_ref
;
if
(
get_softmodem_params
()
->
sl_mode
==
2
)
{
//Preparation of the Sidelink PRE-Configuration message
configure_NR_SL_Preconfig
(
rrc
,
sync_ref
);
}
}
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