SL PSBCH: MAC->PHY cfg, PSBCH scheduler + supporting functions + enable system testing & scope

- Phy config update and Sidelink frame parameters initialisation
	- PSBCH scheduler to trigger TX PSBCH/RX PSBCH actions
	- Sidelink indication with rx ind to trigger send SL-MIB to MAC
	- Enable Scope for PSBCH use -d or --dqt
	- Enable system testing of PSBCH for example using RFSIMULATOR:

		- UE1 is a SYNCRONISATION SOURCE UE which transmits PSBCH

		  started using command -
		  sudo ./nr-uesoftmodem --sl-mode 2 --sync-ref 4 --rfsim --rfsimulator.serveraddr server

		- UE2 syncs onto UE1 during sidelink search, gets the timing and continues to receive PSBCH

		  started using command -
		  sudo ./nr-uesoftmodem --sl-mode 2 --rfsim --rfsimulator.serveraddr 127.0.0.1

		- In the default use case 2 Sidelink SSBs sent over 16 frames.

		- In case SL-SSB configuration needs to be changed use -O option in the above command like

		-O ../../../targets/PROJECTS/NR-SIDELINK/CONF/sidelink_preconfig_1txpool.conf
This commit is contained in:
Raghavendra Dinavahi
2024-06-21 09:40:16 +02:00
parent 9fab212441
commit 798ceeeef2
42 changed files with 1409 additions and 318 deletions
+8 -5
View File
@@ -23,11 +23,9 @@
#include "NR_SidelinkPreconfigNR-r16.h"
#include "mac_proto.h"
void sl_ue_mac_free(uint8_t module_id)
void sl_ue_mac_free(NR_UE_MAC_INST_t *mac)
{
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;
@@ -372,6 +370,9 @@ int nr_rrc_mac_config_req_sl_preconfig(module_id_t module_id,
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;
// Sync source is identified, timing needs to be adjusted.
sl_mac->timing_acquired = true;
}
//Do not copy TDD config yet as SYNC source is not yet found
@@ -474,12 +475,13 @@ void nr_rrc_mac_config_req_sl_mib(module_id_t module_id,
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) {
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->timing_acquired = true;
sl_mac->rx_sl_bch.status = 1;
sl_mac->rx_sl_bch.slss_id = rx_slss_id;
@@ -524,7 +526,8 @@ void nr_rrc_mac_config_req_sl_mib(module_id_t module_id,
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);
DevAssert(mac->if_module != NULL && mac->if_module->sl_phy_config_request != NULL);
mac->if_module->sl_phy_config_request(&sl_mac->sl_phy_config);
}
}
+32
View File
@@ -32,6 +32,10 @@
#define SL_NR_MAC_NUM_TX_RESOURCE_POOLS 1
#define SL_NUM_BYTES_TIMERESOURCEBITMAP 20
// every 16 frames, SSB is repeated.
#define SL_NR_SSB_REPETITION_IN_FRAMES 16
#define SL_FRAME_NUMBER_CYCLE 1024
// 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
@@ -127,6 +131,13 @@ typedef struct sl_bch_params {
} sl_bch_params_t;
typedef struct sl_stored_tti_req {
uint32_t sl_action;
int frame;
int slot;
} sl_stored_tti_req_t;
typedef struct sl_nr_ue_mac_params {
//Holds the RX resource pool from RRC and its related parameters
@@ -151,6 +162,27 @@ typedef struct sl_nr_ue_mac_params {
//Holds Broadcast params incase UE receives SL-SSB
sl_bch_params_t rx_sl_bch;
// SSB RSRP in dBm
int16_t ssb_rsrp_dBm;
// Bitmap indicating which slots belong to sidelink
// Right now supports 30Khz and 15Khz
uint32_t sl_slot_bitmap;
// adjust timing after new timing from sync is acquired.
bool timing_acquired;
// Sidelink slots per frame
uint16_t N_SL_SLOTS_perframe;
uint16_t decoded_DFN;
uint16_t decoded_slot;
uint32_t N_SL_SLOTS;
uint16_t N_SSB_16frames;
sl_stored_tti_req_t *future_ttis;
} sl_nr_ue_mac_params_t;
+21
View File
@@ -382,6 +382,7 @@ 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);
@@ -393,4 +394,24 @@ uint8_t sl_decode_sl_TDD_Config(NR_TDD_UL_DL_ConfigCommon_t *TDD_UL_DL_Config,
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);
/** \brief This function checks nr UE slot for Sidelink direction : Sidelink
* @param cfg : Sidelink config request
* @param nr_frame : frame number
* @param nr_slot : slot number
* @param frame duplex type : Frame type
@returns int : 0 or Sidelink slot type */
int sl_nr_ue_slot_select(sl_nr_phy_config_request_t *cfg, int nr_slot, uint8_t frame_duplex_type);
void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t *mac);
void nr_mac_rrc_sl_mib_ind(const module_id_t module_id,
const int CC_id,
const uint8_t gNB_index,
const frame_t frame,
const int slot,
const channel_t channel,
uint8_t *pduP,
const sdu_size_t pdu_len,
const uint16_t rx_slss_id);
#endif
+27 -23
View File
@@ -19,7 +19,8 @@
* contact@openairinterface.org
*/
#include "mac_defs_sl.h"
#include "mac_defs.h"
#include "mac_proto.h"
#define SL_DEBUG
@@ -348,35 +349,37 @@ uint32_t sl_prepare_MIB(NR_TDD_UL_DL_ConfigCommon_t *TDD_UL_DL_Config,
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);
//sl-NumSubchannel - Indicates the number of subchannels in the corresponding resource pool
//which consists of contiguous PRBs only.
uint16_t num_subch = (rpool->sl_NumSubchannel_r16) ? *rpool->sl_NumSubchannel_r16 : 0;
AssertFatal(num_subch,"NUM Subchannels cannot be 0. Resource Pool Configuration Error\n");
return num_subch;
}
uint16_t sl_get_subchannel_size(NR_SL_ResourcePool_r16_t *rpool)
{
uint16_t num_subch = sl_get_num_subch(rpool);
//sl-RB-Number - Indicates the number of PRBs in the corresponding resource pool.
//which consists of contiguous PRBs only.The remaining RB cannot be used
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;
uint16_t subch_size = 0;
subch_size = num_rbs/num_subch;
LOG_I(NR_MAC, "Subch_size:%d, numRBS:%d, num_subch:%d\n",
subch_size,num_rbs,num_subch);
return (num_subch);
return (subch_size);
}
//This function determines SCI 1A Len in bits based on the configuration in the resource pool.
@@ -474,10 +477,11 @@ uint8_t sl_determine_sci_1a_len(uint16_t *num_subchannels,
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);
LOG_D(NR_MAC,
"sci 1A - additional_table:%ld, sci 1a len:%d, additional table nbits:%d\n",
rpool->sl_Additional_MCS_Table_r16 ? *rpool->sl_Additional_MCS_Table_r16 : 0,
sci_1a_len,
sci_1a->additional_mcs_table_indicator.nbits);
uint8_t psfch_period = 0;
if (rpool->sl_PSFCH_Config_r16 &&
@@ -0,0 +1,426 @@
/*
* 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.h"
#include "mac_proto.h"
static uint16_t sl_adjust_ssb_indices(sl_ssb_timealloc_t *ssb_timealloc, uint32_t slot_in_16frames, uint16_t *ssb_slot_ptr)
{
uint16_t ssb_slot = ssb_timealloc->sl_TimeOffsetSSB;
uint16_t numssb = 0;
*ssb_slot_ptr = 0;
if (ssb_timealloc->sl_NumSSB_WithinPeriod == 0) {
*ssb_slot_ptr = 0;
return 0;
}
while (slot_in_16frames > ssb_slot) {
numssb = numssb + 1;
if (numssb < ssb_timealloc->sl_NumSSB_WithinPeriod)
ssb_slot = ssb_slot + ssb_timealloc->sl_TimeInterval;
else
break;
}
*ssb_slot_ptr = ssb_slot;
return numssb;
}
static uint8_t sl_get_elapsed_slots(uint32_t slot, uint32_t sl_slot_bitmap)
{
uint8_t elapsed_slots = 0;
for (int i = 0; i < slot; i++) {
if (sl_slot_bitmap & (1 << i))
elapsed_slots++;
}
return elapsed_slots;
}
static void sl_determine_slot_bitmap(sl_nr_ue_mac_params_t *sl_mac, int ue_id)
{
sl_nr_phy_config_request_t *sl_cfg = &sl_mac->sl_phy_config.sl_config_req;
uint8_t sl_scs = sl_cfg->sl_bwp_config.sl_scs;
uint8_t num_slots_per_frame = 10 * (1 << sl_scs);
uint8_t slot_type = 0;
for (int i = 0; i < num_slots_per_frame; i++) {
slot_type = sl_nr_ue_slot_select(sl_cfg, i, TDD);
if (slot_type == NR_SIDELINK_SLOT) {
sl_mac->N_SL_SLOTS_perframe += 1;
sl_mac->sl_slot_bitmap |= (1 << i);
}
}
sl_mac->future_ttis = calloc(num_slots_per_frame, sizeof(sl_stored_tti_req_t));
LOG_I(NR_MAC,
"[UE%d] SL-MAC: N_SL_SLOTS_perframe:%d, SL SLOT bitmap:%x\n",
ue_id,
sl_mac->N_SL_SLOTS_perframe,
sl_mac->sl_slot_bitmap);
}
/* This function determines the number of sidelink slots in 1024 frames - DFN cycle
* which can be used for determining reserved slots and REsource pool slots according to bitmap.
* Sidelink slots are the uplink and mixed slots with sidelink support except the SSB slots.
*/
static uint32_t sl_determine_num_sidelink_slots(sl_nr_ue_mac_params_t *sl_mac, int ue_id, uint16_t *N_SSB_16frames)
{
uint32_t N_SSB_1024frames = 0;
uint32_t N_SL_SLOTS = 0;
*N_SSB_16frames = 0;
if (sl_mac->rx_sl_bch.status) {
sl_ssb_timealloc_t *ssb_timealloc = &sl_mac->rx_sl_bch.ssb_time_alloc;
*N_SSB_16frames += ssb_timealloc->sl_NumSSB_WithinPeriod;
LOG_D(NR_MAC, "RX SSB Slots:%d\n", *N_SSB_16frames);
}
if (sl_mac->tx_sl_bch.status) {
sl_ssb_timealloc_t *ssb_timealloc = &sl_mac->tx_sl_bch.ssb_time_alloc;
*N_SSB_16frames += ssb_timealloc->sl_NumSSB_WithinPeriod;
LOG_D(NR_MAC, "TX SSB Slots:%d\n", *N_SSB_16frames);
}
// Total SSB slots in SFN cycle (1024 frames)
N_SSB_1024frames = SL_FRAME_NUMBER_CYCLE / SL_NR_SSB_REPETITION_IN_FRAMES * (*N_SSB_16frames);
// Determine total number of Valid Sidelink slots which can be used for Respool in a SFN cycle (1024 frames)
N_SL_SLOTS = (sl_mac->N_SL_SLOTS_perframe * SL_FRAME_NUMBER_CYCLE) - N_SSB_1024frames;
LOG_I(NR_MAC,
"[UE%d]SL-MAC:SSB slots in 1024 frames:%d, N_SL_SLOTS_perframe:%d, N_SL_SLOTs in 1024 frames:%d, SL SLOT bitmap:%x\n",
ue_id,
N_SSB_1024frames,
sl_mac->N_SL_SLOTS_perframe,
N_SL_SLOTS,
sl_mac->sl_slot_bitmap);
return N_SL_SLOTS;
}
/**
* DETERMINE IF SLOT IS MARKED AS SSB SLOT
* ACCORDING TO THE SSB TIME ALLOCATION PARAMETERS.
* sl_numSSB_withinPeriod - NUM SSBS in 16frames
* sl_timeoffset_SSB - time offset for first SSB at start of 16 frames cycle
* sl_timeinterval - distance in slots between 2 SSBs
*/
uint8_t sl_determine_if_SSB_slot(uint16_t frame, uint16_t slot, uint16_t slots_per_frame, sl_bch_params_t *sl_bch)
{
uint16_t frame_16 = frame % SL_NR_SSB_REPETITION_IN_FRAMES;
uint32_t slot_in_16frames = (frame_16 * slots_per_frame) + slot;
uint16_t sl_NumSSB_WithinPeriod = sl_bch->ssb_time_alloc.sl_NumSSB_WithinPeriod;
uint16_t sl_TimeOffsetSSB = sl_bch->ssb_time_alloc.sl_TimeOffsetSSB;
uint16_t sl_TimeInterval = sl_bch->ssb_time_alloc.sl_TimeInterval;
uint16_t num_ssb = sl_bch->num_ssb, ssb_slot = sl_bch->ssb_slot;
#ifdef SL_DEBUG
LOG_D(NR_MAC,
"%d:%d. num_ssb:%d,ssb_slot:%d, %d-%d-%d, status:%d\n",
frame,
slot,
sl_bch->num_ssb,
sl_bch->ssb_slot,
sl_NumSSB_WithinPeriod,
sl_TimeOffsetSSB,
sl_TimeInterval,
sl_bch->status);
#endif
if (sl_NumSSB_WithinPeriod && sl_bch->status) {
if (slot_in_16frames == sl_TimeOffsetSSB) {
num_ssb = 0;
ssb_slot = sl_TimeOffsetSSB;
}
if (num_ssb < sl_NumSSB_WithinPeriod && slot_in_16frames == ssb_slot) {
num_ssb += 1;
ssb_slot = (num_ssb < sl_NumSSB_WithinPeriod) ? (ssb_slot + sl_TimeInterval) : sl_TimeOffsetSSB;
sl_bch->ssb_slot = ssb_slot;
sl_bch->num_ssb = num_ssb;
LOG_D(NR_MAC, "%d:%d is a PSBCH SLOT. Next PSBCH Slot:%d, num_ssb:%d\n", frame, slot, sl_bch->ssb_slot, sl_bch->num_ssb);
return 1;
}
}
LOG_D(NR_MAC, "%d:%d is NOT a PSBCH SLOT. Next PSBCH Slot:%d, num_ssb:%d\n", frame, slot, sl_bch->ssb_slot, sl_bch->num_ssb);
return 0;
}
static uint8_t sl_psbch_scheduler(sl_nr_ue_mac_params_t *sl_mac_params, int ue_id, int frame, int slot)
{
uint8_t config_type = 0, is_psbch_rx_slot = 0, is_psbch_tx_slot = 0;
sl_nr_phy_config_request_t *sl_cfg = &sl_mac_params->sl_phy_config.sl_config_req;
uint16_t scs = sl_cfg->sl_bwp_config.sl_scs;
uint16_t slots_per_frame = nr_slots_per_frame[scs];
if (sl_mac_params->rx_sl_bch.status) {
is_psbch_rx_slot = sl_determine_if_SSB_slot(frame, slot, slots_per_frame, &sl_mac_params->rx_sl_bch);
if (is_psbch_rx_slot)
config_type = SL_NR_CONFIG_TYPE_RX_PSBCH;
} else if (sl_mac_params->tx_sl_bch.status) {
is_psbch_tx_slot = sl_determine_if_SSB_slot(frame, slot, slots_per_frame, &sl_mac_params->tx_sl_bch);
if (is_psbch_tx_slot)
config_type = SL_NR_CONFIG_TYPE_TX_PSBCH;
}
sl_mac_params->future_ttis[slot].frame = frame;
sl_mac_params->future_ttis[slot].slot = slot;
sl_mac_params->future_ttis[slot].sl_action = config_type;
LOG_D(NR_MAC, "[UE%d] SL-PSBCH SCHEDULER: %d:%d, config type:%d\n", ue_id, frame, slot, config_type);
return config_type;
}
/*
* This function calculates the indices based on the new timing (frame,slot)
* acquired by the UE.
* NUM SSB, SLOT_SSB needs to be calculated based on current timing
*/
static void sl_adjust_indices_based_on_timing(sl_nr_ue_mac_params_t *sl_mac,
int ue_id,
int frame, int slot,
int slots_per_frame)
{
uint8_t elapsed_slots = 0;
elapsed_slots = sl_get_elapsed_slots(slot, sl_mac->sl_slot_bitmap);
AssertFatal(elapsed_slots <= sl_mac->N_SL_SLOTS_perframe,
"Elapsed slots cannot be > N_SL_SLOTS_perframe %d,%d\n",
elapsed_slots,
sl_mac->N_SL_SLOTS_perframe);
uint16_t frame_16 = frame % SL_NR_SSB_REPETITION_IN_FRAMES;
uint32_t slot_in_16frames = (frame_16 * slots_per_frame) + slot;
LOG_I(NR_MAC,
"[UE%d]PSBCH params adjusted based on current timing %d:%d. frame_16:%d, slot_in_16frames:%d\n",
ue_id,
frame,
slot,
frame_16,
slot_in_16frames);
// Adjust PSBCH Indices based on current timing
if (sl_mac->rx_sl_bch.status) {
sl_ssb_timealloc_t *ssb_timealloc = &sl_mac->rx_sl_bch.ssb_time_alloc;
sl_mac->rx_sl_bch.num_ssb = sl_adjust_ssb_indices(ssb_timealloc, slot_in_16frames, &sl_mac->rx_sl_bch.ssb_slot);
LOG_I(NR_MAC,
"[UE%d]PSBCH RX params adjusted. NumSSB:%d, ssb_slot:%d\n",
ue_id,
sl_mac->rx_sl_bch.num_ssb,
sl_mac->rx_sl_bch.ssb_slot);
}
if (sl_mac->tx_sl_bch.status) {
sl_ssb_timealloc_t *ssb_timealloc = &sl_mac->tx_sl_bch.ssb_time_alloc;
sl_mac->tx_sl_bch.num_ssb = sl_adjust_ssb_indices(ssb_timealloc, slot_in_16frames, &sl_mac->tx_sl_bch.ssb_slot);
LOG_I(NR_MAC,
"[UE%d]PSBCH TX params adjusted. NumSSB:%d, ssb_slot:%d\n",
ue_id,
sl_mac->tx_sl_bch.num_ssb,
sl_mac->tx_sl_bch.ssb_slot);
}
}
// Adjust indices as new timing is acquired
static void sl_actions_after_new_timing(sl_nr_ue_mac_params_t *sl_mac,
int ue_id,
int frame, int slot)
{
uint8_t mu = sl_mac->sl_phy_config.sl_config_req.sl_bwp_config.sl_scs;
uint8_t slots_per_frame = nr_slots_per_frame[mu];
sl_determine_slot_bitmap(sl_mac, ue_id);
sl_mac->N_SL_SLOTS = sl_determine_num_sidelink_slots(sl_mac, ue_id, &sl_mac->N_SSB_16frames);
sl_adjust_indices_based_on_timing(sl_mac, ue_id, frame, slot, slots_per_frame);
}
static void sl_schedule_rx_actions(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t *mac)
{
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
int ue_id = mac->ue_id;
int rx_action = 0;
sl_nr_rx_config_request_t rx_config;
rx_config.number_pdus = 0;
rx_config.sfn = sl_ind->frame_rx;
rx_config.slot = sl_ind->slot_rx;
if (sl_ind->sci_ind != NULL) {
// TBD..
} else {
rx_action = sl_mac->future_ttis[sl_ind->slot_rx].sl_action;
}
if (rx_action == SL_NR_CONFIG_TYPE_RX_PSBCH) {
rx_config.number_pdus = 1;
rx_config.sl_rx_config_list[0].pdu_type = rx_action;
LOG_I(NR_MAC, "[UE%d] %d:%d CMD to PHY: RX PSBCH \n", ue_id, sl_ind->frame_rx, sl_ind->slot_rx);
} else if (rx_action >= SL_NR_CONFIG_TYPE_RX_PSCCH && rx_action <= SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH) {
// TBD..
} else if (rx_action == SL_NR_CONFIG_TYPE_RX_PSFCH) {
// TBD..
}
if (rx_config.number_pdus) {
AssertFatal(sl_ind->slot_type == SIDELINK_SLOT_TYPE_RX || sl_ind->slot_type == SIDELINK_SLOT_TYPE_BOTH,
"RX action cannot be scheduled in non Sidelink RX slot\n");
nr_scheduled_response_t scheduled_response = {.sl_rx_config = &rx_config,
.module_id = sl_ind->module_id,
.CC_id = sl_ind->cc_id,
.phy_data = sl_ind->phy_data,
.mac = mac};
sl_mac->future_ttis[sl_ind->slot_rx].sl_action = 0;
if ((mac->if_module != NULL) && (mac->if_module->scheduled_response != NULL))
mac->if_module->scheduled_response(&scheduled_response);
}
}
static void sl_schedule_tx_actions(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t *mac)
{
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
int ue_id = mac->ue_id;
int tx_action = 0;
sl_nr_tx_config_request_t tx_config;
tx_config.number_pdus = 0;
tx_config.sfn = sl_ind->frame_tx;
tx_config.slot = sl_ind->slot_tx;
tx_action = sl_mac->future_ttis[sl_ind->slot_tx].sl_action;
if (tx_action == SL_NR_CONFIG_TYPE_TX_PSBCH) {
tx_config.number_pdus = 1;
tx_config.tx_config_list[0].pdu_type = tx_action;
tx_config.tx_config_list[0].tx_psbch_config_pdu.tx_slss_id = sl_mac->tx_sl_bch.slss_id;
tx_config.tx_config_list[0].tx_psbch_config_pdu.psbch_tx_power = 0; // TBD...
memcpy(tx_config.tx_config_list[0].tx_psbch_config_pdu.psbch_payload, sl_mac->tx_sl_bch.sl_mib, 4);
LOG_I(NR_MAC, "[UE%d] %d:%d CMD to PHY: TX PSBCH \n", ue_id, sl_ind->frame_tx, sl_ind->slot_tx);
} else if (tx_action == SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH) {
// TBD....
} else if (tx_action == SL_NR_CONFIG_TYPE_TX_PSFCH) {
// TBD....
}
if (tx_config.number_pdus == 1) {
AssertFatal(sl_ind->slot_type == SIDELINK_SLOT_TYPE_TX || sl_ind->slot_type == SIDELINK_SLOT_TYPE_BOTH,
"TX action cannot be scheduled in non Sidelink TX slot\n");
nr_scheduled_response_t scheduled_response = {.sl_tx_config = &tx_config,
.module_id = sl_ind->module_id,
.CC_id = sl_ind->cc_id,
.phy_data = sl_ind->phy_data,
.mac = mac};
sl_mac->future_ttis[sl_ind->slot_tx].sl_action = 0;
if ((mac->if_module != NULL) && (mac->if_module->scheduled_response != NULL))
mac->if_module->scheduled_response(&scheduled_response);
}
}
void nr_ue_sidelink_scheduler(nr_sidelink_indication_t *sl_ind, NR_UE_MAC_INST_t *mac)
{
AssertFatal(sl_ind != NULL, "sl_indication cannot be NULL\n");
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
int ue_id = mac->ue_id;
LOG_D(NR_MAC,
"[UE%d]SL-SCHEDULER: RX %d-%d- TX %d-%d. slot_type:%d\n",
ue_id,
sl_ind->frame_rx,
sl_ind->slot_rx,
sl_ind->frame_tx,
sl_ind->slot_tx,
sl_ind->slot_type);
// Adjust indices as new timing is acquired
if (sl_mac->timing_acquired) {
sl_actions_after_new_timing(sl_mac, ue_id, sl_ind->frame_tx, sl_ind->slot_tx);
sl_mac->timing_acquired = false;
}
if (sl_ind->slot_type == SIDELINK_SLOT_TYPE_TX || sl_ind->slot_type == SIDELINK_SLOT_TYPE_BOTH) {
int frame = sl_ind->frame_tx;
int slot = sl_ind->slot_tx;
int is_sl_slot = 0;
is_sl_slot = sl_mac->sl_slot_bitmap & (1 << slot);
if (is_sl_slot) {
uint8_t tti_action = 0;
// Check if PSBCH slot and PSBCH should be transmitted or Received
tti_action = sl_psbch_scheduler(sl_mac, ue_id, frame, slot);
#if 0 // To be expanded later
// TBD .. Check for Actions coming out of TX resource pool
if (!tti_action && sl_mac->sl_TxPool[0])
tti_action = sl_tx_scheduler(ue_id, frame, slot, sl_mac, sl_mac->sl_TxPool[0]);
//TBD .. Check for Actions coming out of RX resource pool
if (!tti_action && sl_mac->sl_RxPool[0])
tti_action = sl_rx_scheduler(ue_id, frame, slot, sl_mac, sl_mac->sl_RxPool[0]);
#endif
LOG_D(NR_MAC, "[UE%d]SL-SCHED: TTI - %d:%d scheduled action:%d\n", ue_id, frame, slot, tti_action);
} else {
AssertFatal(1 == 0, "TX SLOT not a sidelink slot. Should not occur\n");
}
// Schedule the Tx actions if any
sl_schedule_tx_actions(sl_ind, mac);
}
if (sl_ind->slot_type == SIDELINK_SLOT_TYPE_RX || sl_ind->slot_type == SIDELINK_SLOT_TYPE_BOTH)
sl_schedule_rx_actions(sl_ind, mac);
}
+118
View File
@@ -1296,6 +1296,10 @@ nr_ue_if_module_t *nr_ue_if_module_init(uint32_t module_id)
nr_ue_if_module_inst[module_id]->current_slot = 0;
nr_ue_if_module_inst[module_id]->phy_config_request = nr_ue_phy_config_request;
nr_ue_if_module_inst[module_id]->synch_request = nr_ue_synch_request;
if (get_softmodem_params()->sl_mode) {
nr_ue_if_module_inst[module_id]->sl_phy_config_request = nr_ue_sl_phy_config_request;
nr_ue_if_module_inst[module_id]->sl_indication = nr_ue_sl_indication;
}
if (get_softmodem_params()->emulate_l1)
nr_ue_if_module_inst[module_id]->scheduled_response = nr_ue_scheduled_response_stub;
else
@@ -1335,3 +1339,117 @@ void RCconfig_nr_ue_macrlc(void) {
}
}
}
static void handle_sl_bch(int ue_id,
sl_nr_ue_mac_params_t *sl_mac,
uint8_t *const sl_mib,
const uint8_t len,
uint16_t frame_rx,
uint16_t slot_rx,
uint16_t rx_slss_id)
{
LOG_D(NR_MAC, " decode SL-MIB %d\n", rx_slss_id);
uint8_t sl_tdd_config[2] = {0, 0};
sl_tdd_config[0] = sl_mib[0];
sl_tdd_config[1] = sl_mib[1] & 0xF0;
uint8_t incov = sl_mib[1] & 0x08;
uint16_t frame_0 = (sl_mib[2] & 0xFE) >> 1;
uint16_t frame_1 = sl_mib[1] & 0x07;
frame_0 |= (frame_1 & 0x01) << 7;
frame_1 = ((frame_1 & 0x06) >> 1) << 8;
uint16_t frame = frame_1 | frame_0;
uint8_t slot = ((sl_mib[2] & 0x01) << 6) | ((sl_mib[3] & 0xFC) >> 2);
LOG_D(NR_MAC,
"[UE%d]In %d:%d Received SL-MIB:%x .Contents- SL-TDD config:%x, Incov:%d, FN:%d, Slot:%d\n",
ue_id,
frame_rx,
slot_rx,
*((uint32_t *)sl_mib),
*((uint16_t *)sl_tdd_config),
incov,
frame,
slot);
sl_mac->decoded_DFN = frame;
sl_mac->decoded_slot = slot;
nr_mac_rrc_data_ind_ue(ue_id, 0, 0, frame_rx, slot_rx, 0, rx_slss_id, 0, NR_SBCCH_SL_BCH, (uint8_t *)sl_mib, len);
return;
}
/*
if PSBCH rx - handle_psbch()
- Extract FN, Slot
- Extract TDD configuration from the 12 bits
- SEND THE SL-MIB to RRC
if PSSCH DATa rx - handle slsch()
*/
void sl_nr_process_rx_ind(int ue_id,
uint32_t frame,
uint32_t slot,
sl_nr_ue_mac_params_t *sl_mac,
sl_nr_rx_indication_t *rx_ind)
{
uint8_t num_pdus = rx_ind->number_pdus;
uint8_t pdu_type = rx_ind->rx_indication_body[num_pdus - 1].pdu_type;
switch (pdu_type) {
case SL_NR_RX_PDU_TYPE_SSB:
if (rx_ind->rx_indication_body[num_pdus - 1].ssb_pdu.decode_status) {
LOG_D(NR_MAC,
"[UE%d]SL-MAC Received SL-SSB: RSRP:%d dBm/RE, rx_psbch_payload:%x, rx_slss_id:%d\n",
ue_id,
rx_ind->rx_indication_body[num_pdus - 1].ssb_pdu.rsrp_dbm,
*((uint32_t *)rx_ind->rx_indication_body[num_pdus - 1].ssb_pdu.psbch_payload),
rx_ind->rx_indication_body[num_pdus - 1].ssb_pdu.rx_slss_id);
handle_sl_bch(ue_id,
sl_mac,
rx_ind->rx_indication_body[num_pdus - 1].ssb_pdu.psbch_payload,
4,
frame,
slot,
rx_ind->rx_indication_body[num_pdus - 1].ssb_pdu.rx_slss_id);
sl_mac->ssb_rsrp_dBm = rx_ind->rx_indication_body[num_pdus - 1].ssb_pdu.rsrp_dbm;
} else {
LOG_I(NR_MAC, "[UE%d]SL-MAC - NO SL-SSB Received\n", ue_id);
}
break;
case SL_NR_RX_PDU_TYPE_SLSCH:
break;
default:
AssertFatal(1 == 0, "Incorrect type received. %s\n", __FUNCTION__);
break;
}
}
/*
* Sidelink indication is sent from PHY->MAC.
* This interface function handles these
* - rx_ind (SSB on PSBCH/SLSCH on PSSCH).
* - sci_ind (received scis during rxpool reception/txpool sensing)
*/
void nr_ue_sl_indication(nr_sidelink_indication_t *sl_indication)
{
// NR_UE_L2_STATE_t ret;
int ue_id = sl_indication->module_id;
NR_UE_MAC_INST_t *mac = get_mac_inst(ue_id);
uint16_t slot = sl_indication->slot_rx;
uint16_t frame = sl_indication->frame_rx;
sl_nr_ue_mac_params_t *sl_mac = mac->SL_MAC_PARAMS;
if (sl_indication->rx_ind) {
sl_nr_process_rx_ind(ue_id, frame, slot, sl_mac, sl_indication->rx_ind);
} else {
nr_ue_sidelink_scheduler(sl_indication, mac);
}
}
+17 -3
View File
@@ -42,6 +42,15 @@
#include "NR_Packet_Drop.h"
#include "nfapi/open-nFAPI/nfapi/public_inc/sidelink_nr_ue_interface.h"
typedef enum sl_sidelink_slot_type {
SIDELINK_SLOT_TYPE_NONE = 0,
SIDELINK_SLOT_TYPE_RX,
SIDELINK_SLOT_TYPE_TX,
SIDELINK_SLOT_TYPE_BOTH
} sl_sidelink_slot_type_t;
extern slot_rnti_mcs_s slot_rnti_mcs[NUM_NFAPI_SLOT];
typedef struct NR_UL_TIME_ALIGNMENT NR_UL_TIME_ALIGNMENT_t;
@@ -106,6 +115,8 @@ typedef struct {
frame_t frame_tx;
/// slot tx
uint32_t slot_tx;
// slot type rx or tx
sl_sidelink_slot_type_t slot_type;
/// NR UE FAPI-like P7 message, direction: L1 to L2
/// data reception indication structure
@@ -199,7 +210,7 @@ typedef int8_t (nr_ue_scheduled_response_f)(nr_scheduled_response_t *scheduled_r
* -1: Failed to consume bytes. Abort the mission.
* Non-negative return values indicate success, and ignored.
*/
typedef int8_t (nr_sl_ue_scheduled_response_f)(nr_scheduled_response_t *sl_scheduled_response);
typedef void (nr_sl_ue_scheduled_response_f)(nr_scheduled_response_t *sl_scheduled_response);
/*
@@ -218,7 +229,7 @@ typedef int8_t (nr_ue_phy_config_request_f)(nr_phy_config_t *phy_config);
* -1: Failed to consume bytes. Abort the mission.
* Non-negative return values indicate success, and ignored.
*/
typedef int8_t (nr_sl_ue_phy_config_request_f)(nr_sl_phy_config_t *sl_phy_config);
typedef void(nr_ue_sl_phy_config_request_f)(nr_sl_phy_config_t *sl_phy_config);
/*
* Generic type of an application-defined callback to return various
@@ -254,12 +265,13 @@ typedef void (nr_ue_slot_indication_f)(uint8_t mod_id);
* -1: Failed to consume bytes. Abort the mission.
* Non-negative return values indicate success, and ignored.
*/
typedef int (nr_ue_sl_indication_f)(nr_sidelink_indication_t *sl_info);
typedef void (nr_ue_sl_indication_f)(nr_sidelink_indication_t *sl_info);
// TODO check this stuff can be reuse of need modification
typedef struct nr_ue_if_module_s {
nr_ue_scheduled_response_f *scheduled_response;
nr_ue_phy_config_request_f *phy_config_request;
nr_ue_sl_phy_config_request_f *sl_phy_config_request;
nr_ue_synch_request_f *synch_request;
nr_ue_dl_indication_f *dl_indication;
nr_ue_ul_indication_f *ul_indication;
@@ -304,5 +316,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info);
int nr_ue_ul_indication(nr_uplink_indication_t *ul_info);
void nr_ue_sl_indication(nr_sidelink_indication_t *sl_indication);
#endif
+1 -2
View File
@@ -113,8 +113,7 @@ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id,
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
NR_RRC_MAC_SBCCH_DATA_IND(message_p).rx_slss_id = cellid; // cellid is rx slss id
itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p);
}
break;
+1 -3
View File
@@ -462,9 +462,7 @@ static int8_t nr_sl_rrc_ue_decode_SL_MIB(const uint8_t gNB_index,
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, "%d:%d SL-RRC - Received MIB.\n", val_fn, 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)));