Commit e0e8bbcf authored by Guido Casati's avatar Guido Casati Committed by cig

RACH MAC procedure (RA initiation and Preamble selection)

- Updated PRACH procedures and general code formatting
- gNB msg1 handling and RAR generation
- general bug fixing
- formatting
- missing headers
- RAR handling.
parent 5aec9ab5
......@@ -1605,7 +1605,7 @@ add_library(PHY_MEX ${PHY_MEX_UE} ${CONFIG_LIB})
#Layer 2 library
#####################
set(MAC_DIR ${OPENAIR2_DIR}/LAYER2/MAC)
set(NR_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB)
set(NR_GNB_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB)
set(NR_UE_MAC_DIR ${OPENAIR2_DIR}/LAYER2/NR_MAC_UE)
set(PHY_INTERFACE_DIR ${OPENAIR2_DIR}/PHY_INTERFACE)
set(NR_PHY_INTERFACE_DIR ${OPENAIR2_DIR}/NR_PHY_INTERFACE)
......@@ -1757,14 +1757,17 @@ set (MAC_SRC
set (MAC_NR_SRC
${NR_PHY_INTERFACE_DIR}/NR_IF_Module.c
${NR_MAC_DIR}/main.c
${NR_MAC_DIR}/config.c
${NR_MAC_DIR}/gNB_scheduler.c
${NR_MAC_DIR}/gNB_scheduler_bch.c
${NR_MAC_DIR}/gNB_scheduler_dlsch.c
${NR_MAC_DIR}/gNB_scheduler_ulsch.c
${NR_MAC_DIR}/gNB_scheduler_primitives.c
${NR_MAC_DIR}/gNB_scheduler_phytest.c
${NR_GNB_MAC_DIR}/main.c
${NR_GNB_MAC_DIR}/config.c
${NR_GNB_MAC_DIR}/gNB_scheduler.c
${NR_GNB_MAC_DIR}/gNB_scheduler_bch.c
${NR_GNB_MAC_DIR}/gNB_scheduler_dlsch.c
${NR_GNB_MAC_DIR}/gNB_scheduler_ulsch.c
${NR_GNB_MAC_DIR}/gNB_scheduler_primitives.c
${NR_GNB_MAC_DIR}/gNB_scheduler_phytest.c
${NR_GNB_MAC_DIR}/gNB_scheduler_RA.c
${NR_UE_MAC_DIR}/nr_l1_helpers.c
${NR_UE_MAC_DIR}/nr_ra_procedures.c
)
......@@ -1776,7 +1779,6 @@ set (MAC_SRC_UE
${MAC_DIR}/l1_helpers.c
${MAC_DIR}/rar_tools_ue.c
${MAC_DIR}/config_ue.c
)
set (MAC_NR_SRC_UE
......@@ -1786,6 +1788,9 @@ set (MAC_NR_SRC_UE
${NR_UE_MAC_DIR}/main_ue_nr.c
${NR_UE_MAC_DIR}/nr_ue_procedures.c
${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c
${NR_UE_MAC_DIR}/nr_l1_helpers.c
${NR_UE_MAC_DIR}/nr_ra_procedures.c
${NR_UE_MAC_DIR}/rar_tools_nrUE.c
)
set (ENB_APP_SRC
......@@ -1849,7 +1854,7 @@ add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} )
add_library( MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c ${OPENAIR2_DIR}/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c)
include_directories("${OPENAIR2_DIR}/NR_UE_PHY_INTERFACE")
include_directories("${OPENAIR2_DIR}/LAYER2/NR_MAC_UE")
include_directories("${OPENAIR2_DIR}/LAYER2")
include_directories("${OPENAIR1_DIR}/SCHED_NR_UE")
#include_directories("${NFAPI_USER_DIR}"")
......@@ -2636,9 +2641,9 @@ add_executable(nr-uesoftmodem
target_link_libraries (nr-uesoftmodem
-Wl,--start-group
RRC_LIB NR_RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB
PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS NR_L2_UE L2_UE MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB
NFAPI_USER_LIB S1AP_LIB S1AP_ENB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
PHY_COMMON PHY_NR_COMMON PHY_UE PHY_NR_UE PHY_RU LFDS L2_UE NR_L2_UE MAC_NR_COMMON S1AP_LIB S1AP_ENB
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl)
target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES})
......
......@@ -63,7 +63,7 @@
#include "LAYER2/MAC/mac.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface.h"
......
......@@ -72,7 +72,7 @@
#include "SCHED_NR/sched_nr.h"
#include "LAYER2/MAC/mac.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface.h"
......
......@@ -21,7 +21,7 @@
#include "executables/thread-common.h"
#include "executables/nr-uesoftmodem.h"
#include "LAYER2/NR_MAC_UE/mac.h"
#include "NR_MAC_UE/mac.h"
//#include "RRC/LTE/rrc_extern.h"
#include "PHY_INTERFACE/phy_interface_extern.h"
......@@ -32,7 +32,7 @@
#include "PHY/phy_extern_nr_ue.h"
#include "PHY/INIT/phy_init.h"
#include "PHY/MODULATION/modulation_UE.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "NR_MAC_UE/mac_proto.h"
#include "RRC/NR_UE/rrc_proto.h"
//#ifndef NO_RAT_NR
......
......@@ -72,8 +72,8 @@ unsigned short config_frames[4] = {2,9,11,13};
#include "PHY/INIT/phy_init.h"
#include "system.h"
#include <openair2/RRC/NR_UE/rrc_proto.h>
#include <openair2/LAYER2/NR_MAC_UE/mac_defs.h>
#include <openair2/LAYER2/NR_MAC_UE/mac_proto.h>
#include "NR_MAC_UE/mac_defs.h"
#include "NR_MAC_UE/mac_proto.h"
#include <openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h>
#include <openair1/SCHED_NR_UE/fapi_nr_ue_l1.h>
......
......@@ -4,7 +4,7 @@
#include <executables/softmodem-common.h>
#include "PHY/defs_nr_UE.h"
#include "SIMULATION/ETH_TRANSPORT/proto.h"
#include <openair2/LAYER2/NR_MAC_gNB/mac_proto.h>
#include "NR_MAC_gNB/mac_proto.h"
/***************************************************************************************************************************************/
/* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument
......
......@@ -18,6 +18,7 @@
#define FAPI_NR_RX_PDU_TYPE_SIB 0x02
#define FAPI_NR_RX_PDU_TYPE_DLSCH 0x03
#define FAPI_NR_DCI_IND 0x04
#define FAPI_NR_RX_PDU_TYPE_RAR 0x05
#define FAPI_NR_SIBS_MASK_SIB1 0x1
......
......@@ -38,7 +38,6 @@
#include "PHY/NR_TRANSPORT/nr_ulsch.h"
#include "PHY/NR_REFSIG/nr_refsig.h"
#include "SCHED_NR/fapi_nr_l1.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "nfapi_nr_interface.h"
/*
......
......@@ -110,23 +110,25 @@ void nr_fill_du(uint8_t prach_fmt)
int is_nr_prach_subframe(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t subframe) {
uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex;
/*
// For FR1 paired
if (frame_parms->frame_type == FDD && frame_parms->freq_range == nr_FR1){
if (((frame%table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][2]) == table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][3]) &&
((table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][4]&(1<<subframe)) == 1)) {
// using table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink
return(1);
return 1;
} else {
return(0);
return 0;
}
*/
} else if (frame_parms->frame_type == TDD && frame_parms->freq_range == nr_FR1) {
// For FR1 unpaired
if (((frame%table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][2]) == table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][3]) &&
((table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4]&(1<<subframe)) == 1)) {
// using table 6.3.3.2-2: Random access configurations for FR1 and unpaired
return(1);
return 1;
} else {
return(0);
return 0;
}
}
/*
// For FR2: FIXME
......
......@@ -90,6 +90,6 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue,
uint32_t rx_power_fil_dB,
uint8_t eNB_id);
int16_t nr_get_PL(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index);
#endif
......@@ -41,9 +41,6 @@
#include "T.h"
extern uint16_t NCS_unrestricted_delta_f_RA_125[16];
extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15];
extern uint16_t NCS_restricted_TypeB_delta_f_RA_125[13];
......@@ -59,13 +56,6 @@ extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10];
extern uint16_t nr_du[838];
extern int16_t nr_ru[2*839];
int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf )
{
......
......@@ -26,7 +26,7 @@
#include <simple_executable.h>
#include <common/utils/system.h>
#include <openairinterface5g_limits.h>
#include <openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h>
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "common/ran_context.h"
#include <openair1/PHY/defs_gNB.h>
#include <forms.h>
......
......@@ -930,7 +930,7 @@ typedef struct {
uint8_t pucch_sel[10];
uint8_t pucch_payload[22];
UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_eNB_MAX];
UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_gNB_MAX];
/// cell-specific reference symbols
uint32_t lte_gold_table[7][20][2][14];
......@@ -967,10 +967,10 @@ typedef struct {
unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX];
uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX];
unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX];
PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_eNB_MAX];
unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_gNB_MAX];
uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_gNB_MAX];
unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_gNB_MAX];
NR_PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_gNB_MAX];
int turbo_iterations, turbo_cntl_iterations;
/// \brief ?.
/// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
......
......@@ -223,6 +223,29 @@ typedef struct {
NR_PRACH_CONFIG_INFO prach_ConfigInfo;
} NR_PRACH_CONFIG_COMMON;
typedef struct {
/// Preamble index for PRACH (0-63)
uint8_t ra_PreambleIndex;
/// RACH MaskIndex
uint8_t ra_RACH_MaskIndex;
/// Target received power at eNB (-120 ... -82 dBm)
uint32_t ra_PREAMBLE_RECEIVED_TARGET_POWER;
/// PRACH index for TDD (0 ... 6) depending on TDD configuration and prachConfigIndex
uint8_t ra_TDD_map_index;
/// RA Preamble Power Ramping Step in dB
uint32_t RA_PREAMBLE_POWER_RAMPING_STEP;
///
uint8_t RA_PREAMBLE_BACKOFF;
///
uint8_t RA_SCALING_FACTOR_BI;
///
uint8_t RA_PCMAX;
/// Corresponding RA-RNTI for UL-grant
uint16_t ra_RNTI;
/// Pointer to Msg3 payload for UL-grant
uint8_t *Msg3;
} NR_PRACH_RESOURCES_t;
typedef struct NR_DL_FRAME_PARMS {
/// frequency range
nr_frequency_range_e freq_range;
......
......@@ -218,6 +218,15 @@ void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
*/
void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
/*! \brief UE PRACH procedures.
@param
@param
@param
*/
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t mode);
int is_nr_prach_subframe(NR_DL_FRAME_PARMS *frame_parms, uint32_t frame, uint8_t subframe);
#if 0
/*! \brief Compute ACK/NACK information for PUSCH/PUCCH for UE transmission in subframe n. This function implements table 10.1-1 of 36.213, p. 69.
@param frame_parms Pointer to DL frame parameter descriptor
......@@ -322,13 +331,14 @@ uint16_t nr_get_n1_pucch(PHY_VARS_NR_UE *phy_vars_ue,
uint8_t SR);
#endif
/*! \brief This function retrieves the PHY UE mode. It is used as a helper function for the UE MAC.
@param Mod_id Local UE index on which to act
@param CC_id Component Carrier Index
@param eNB_index ID of eNB
@param gNB_index ID of gNB
@returns UE mode
*/
UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index);
UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_index);
/*! \brief This function implements the power control mechanism for PUCCH from 36.213.
@param phy_vars_ue PHY variables
......
......@@ -58,7 +58,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response)
NR_UE_DLSCH_t *dlsch0 = PHY_vars_UE_g[module_id][cc_id]->dlsch[thread_id][0][0];
NR_UE_ULSCH_t *ulsch0 = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0][0];
//NR_DL_FRAME_PARMS frame_parms = PHY_vars_UE_g[module_id][cc_id]->frame_parms;
PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0];
NR_PRACH_RESOURCES_t *prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[0];
// PUCCH_ConfigCommon_nr_t *pucch_config_common = PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0];
// PUCCH_Config_t *pucch_config_dedicated = PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0];
......
......@@ -66,6 +66,7 @@
#endif
#include "LAYER2/NR_MAC_UE/mac_defs.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "common/utils/LOG/log.h"
#ifdef EMOS
......@@ -308,51 +309,6 @@ void nr_dump_dlsch_ra(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,
write_output("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1);
}
void phy_reset_ue(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
// This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later
// for more flexibility
uint8_t i,j,k,s;
PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
//[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2];
for(int l=0; l<RX_NB_TH; l++) {
for(i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
for(j=0; j<2; j++) {
//DL HARQ
if(ue->dlsch[l][i][j]) {
for(k=0; k<NR_MAX_DLSCH_HARQ_PROCESSES && ue->dlsch[l][i][j]->harq_processes[k]; k++) {
ue->dlsch[l][i][j]->harq_processes[k]->status = SCH_IDLE;
for (s=0; s<10; s++) {
// reset ACK/NACK bit to DTX for all nr_tti_rxs s = 0..9
ue->dlsch[l][i][j]->harq_ack[s].ack = 2;
ue->dlsch[l][i][j]->harq_ack[s].send_harq_status = 0;
ue->dlsch[l][i][j]->harq_ack[s].vDAI_UL = 0xff;
ue->dlsch[l][i][j]->harq_ack[s].vDAI_DL = 0xff;
}
}
}
}
//UL HARQ
if(ue->ulsch[i]) {
for(k=0; k<NR_MAX_ULSCH_HARQ_PROCESSES && ue->ulsch[i]->harq_processes[k]; k++) {
ue->ulsch[i]->harq_processes[k]->status = SCH_IDLE;
//Set NDIs for all UL HARQs to 0
// ue->ulsch[i]->harq_processes[k]->Ndi = 0;
}
}
// flush Msg3 buffer
ue->ulsch_Msg3_active[i] = 0;
}
}
}
void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
......@@ -388,25 +344,6 @@ void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
}
}
UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index)
{
return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]);
}
void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance) {
ue->timing_advance = timing_advance*4;
#ifdef DEBUG_PHY_PROC
/* TODO: fix this log, what is 'HW timing advance'? */
/*LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx_rx, ue->timing_advance);*/
LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx, ue->timing_advance);
#endif
}
uint8_t nr_is_SR_TXOp(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id)
......@@ -1399,6 +1336,9 @@ void ulsch_common_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_
#endif
UE_MODE_t get_nrUE_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t gNB_id){ // TBR generate enum for NR
return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[gNB_id]);
}
void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_command, uint8_t mu, uint16_t bwp_ul_NB_RB){
......@@ -1421,7 +1361,23 @@ void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_com
LOG_D(PHY, "[UE %d] Got timing advance command %u from MAC, new value is %u\n", Mod_id, ta_command, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance);
}
void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint16_t timing_advance) {
/* TODO TBR FIX THIS
ue->timing_advance = timing_advance*4;
#ifdef DEBUG_PHY_PROC
// TODO: fix this log, what is 'HW timing advance'?
//LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx_rx, ue->timing_advance);
LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->nr_tti_rx, ue->timing_advance);
#endif
*/
}
#if 0
void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t eNB_id,
......@@ -2329,11 +2285,12 @@ void ue_pucch_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_
void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
uint8_t gNB_id,
uint8_t thread_id)
{
uint8_t thread_id){
//int32_t ulsch_start=0;
int slot_tx = proc->nr_tti_tx;
int frame_tx = proc->frame_tx;
uint8_t harq_pid = 0; // TBR
runmode_t mode = normal_txrx; // TBR set proper mode
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN);
......@@ -2343,15 +2300,12 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
start_meas(&ue->phy_proc_tx);
#endif
uint8_t harq_pid = 0; //temporary implementation
nr_ue_ulsch_procedures(ue,
harq_pid,
slot_tx,
thread_id,
gNB_id);
/*
if (ue->UE_mode[eNB_id] == PUSCH) {
// check if we need to use PUCCH 1a/1b
......@@ -2361,7 +2315,6 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
} // UE_mode==PUSCH
*/
nr_ue_pusch_common_procedures(ue,
harq_pid,
slot_tx,
......@@ -2369,23 +2322,20 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
gNB_id,
&ue->frame_parms);
//LOG_M("txdata.m","txs",ue->common_vars.txdata[0],1228800,1,1);
/*
if ((ue->UE_mode[eNB_id] == PRACH) &&
(ue->frame_parms.prach_config_common.prach_Config_enabled==1)) {
/* RACH */
if ((ue->UE_mode[gNB_id] == PRACH) && (ue->frame_parms.prach_config_common.prach_Config_enabled == 1)) {
// check if we have PRACH opportunity
if (is_prach_subframe(&ue->frame_parms,frame_tx,nr_tti_tx)) {
ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode);
if (is_nr_prach_subframe(&ue->frame_parms, frame_tx, slot_tx)) {
// TBR TODO FIX this works only for TDD but it enters phy_procedures_nrUE_TX only when mode is FDD
printf("the value of is_nr_prach subframe is %d\n", is_nr_prach_subframe(&ue->frame_parms, frame_tx, slot_tx)); // TBR debug
nr_ue_prach_procedures(ue, proc, gNB_id, mode);
}
}
} // mode is PRACH
else {
ue->generate_prach=0;
ue->generate_nr_prach = 0;
}
*/
/* RACH */
LOG_I(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx);
......@@ -2396,139 +2346,6 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue,
}
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) {
int frame_tx = proc->frame_tx;
int nr_tti_tx = proc->nr_tti_tx;
int prach_power;
uint16_t preamble_tx=ue->prach_resources[0]->ra_PreambleIndex;
PRACH_RESOURCES_t prach_resources;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
ue->generate_nr_prach=0;
if (ue->mac_enabled==0){
ue->prach_resources[eNB_id] = &prach_resources;
ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
ue->prach_resources[eNB_id]->ra_TDD_map_index = 0;
ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10;
ue->prach_resources[eNB_id]->ra_RNTI = 93;
}
if (ue->mac_enabled==1){
// ask L2 for RACH transport
if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
LOG_D(PHY,"Getting PRACH resources\n");
//ue->prach_resources[eNB_id] = mac_xface->ue_get_rach(ue->Mod_id,ue->CC_id,frame_tx,eNB_id,nr_tti_tx);
// LOG_D(PHY,"Got prach_resources for eNB %d address %p, RRCCommon %p\n",eNB_id,ue->prach_resources[eNB_id],UE_mac_inst[ue->Mod_id].radioResourceConfigCommon);
// LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]);
}
}
if (ue->prach_resources[eNB_id]!=NULL) {
ue->generate_nr_prach=1;
ue->prach_cnt=0;
#ifdef SMBV
ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
#endif
#ifdef OAI_EMU
ue->prach_PreambleIndex=ue->prach_resources[eNB_id]->ra_PreambleIndex;
#endif
if (abstraction_flag == 0) {
LOG_I(PHY,"mode %d\n",mode);
if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id);
}
else {
ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm;
ue->prach_resources[eNB_id]->ra_PreambleIndex = preamble_tx;
}
LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n",
ue->Mod_id,
frame_tx,
nr_tti_tx,
ue->prach_resources[eNB_id]->ra_PreambleIndex,
get_nr_PL(ue,eNB_id),
ue->tx_power_dBm[nr_tti_tx],
ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
ue->prach_resources[eNB_id]->ra_TDD_map_index,
ue->prach_resources[eNB_id]->ra_RNTI);
ue->tx_total_RE[nr_tti_tx] = 96;
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx],
ue->tx_power_max_dBm,
ue->frame_parms.N_RB_UL,
6);
#else
ue->prach_vars[eNB_id]->amp = AMP;
#endif
if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0))
LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n",
ue->Mod_id,
proc->frame_rx,
proc->nr_tti_tx,
ue->tx_power_dBm[nr_tti_tx],
ue->prach_vars[eNB_id]->amp);
// start_meas(&ue->tx_prach);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
// prach_power = generate_nr_prach(ue,eNB_id,nr_tti_tx,frame_tx);
prach_power = generate_nr_prach(ue,0,9,0); //subframe number hardcoded according to the simulator
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
// stop_meas(&ue->tx_prach);
LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
ue->Mod_id,
get_nr_PL(ue,eNB_id),
ue->tx_power_dBm[nr_tti_tx],
dB_fixed(prach_power),
ue->prach_vars[eNB_id]->amp);
}/* else {
UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1;
UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
}*/ // commented for compiling as abstraction flag is 0
if (ue->mac_enabled==1){
//mac_xface->Msg1_transmitted(ue->Mod_id,ue->CC_id,frame_tx,eNB_id);
}
LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
ue->Mod_id,frame_tx,nr_tti_tx,eNB_id,
ue->prach_resources[eNB_id]->ra_PreambleIndex,
ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,eNB_id),
get_nr_PL(ue,eNB_id));
}
// if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
if (mode == calib_prach_tx)
ue->prach_resources[eNB_id]=NULL;
LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n",
ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_nr_prach,ue->prach_cnt);
ue->prach_cnt++;
if (ue->prach_cnt==3)
ue->generate_nr_prach=0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
}
/*
void phy_procedures_UE_S_TX(PHY_VARS_NR_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag,relaying_type_t r_type)
{
......@@ -3349,19 +3166,17 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB
} // CRNTI active
}
}
#if 0
void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) {
/*void nr_process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) { // TBR todo
int frame_rx = proc->frame_rx;
int nr_tti_rx = proc->nr_tti_rx;
int timing_advance;
NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[eNB_id];
int harq_pid = 0;
uint8_t *rar;
/*
uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
*/
// uint8_t next1_thread_id = ue->current_thread_id[nr_tti_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[nr_tti_rx]+1);
// uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1);
LOG_D(PHY,"[UE %d][RAPROC] Frame %d nr_tti_rx %d Received RAR mode %d\n",
ue->Mod_id,
......@@ -3377,28 +3192,24 @@ void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmod
nr_tti_rx,
ue->prach_resources[eNB_id]->ra_PreambleIndex);
/* timing_advance = mac_xface->ue_process_rar(ue->Mod_id,
ue->CC_id,
frame_rx,
ue->prach_resources[eNB_id]->ra_RNTI,
dlsch0->harq_processes[0]->b,
&ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
ue->prach_resources[eNB_id]->ra_PreambleIndex,
dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
*/
/*
ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
*/
// TBR restore
// timing_advance = nr_ue_process_rar(ue->Mod_id, ue->CC_id, frame_rx,
// ue->prach_resources[eNB_id]->ra_RNTI, dlsch0->harq_processes[0]->b,
// &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
// ue->prach_resources[eNB_id]->ra_PreambleIndex, dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload
// ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
// ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti;
if (timing_advance!=0xffff) {
LOG_D(PHY,"[UE %d][RAPROC] Frame %d nr_tti_rx %d Got rnti %x and timing advance %d from RAR\n",
ue->Mod_id,
frame_rx,
nr_tti_rx,
ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
timing_advance);
// TBR restore
// LOG_D(PHY,"[UE %d][RAPROC] Frame %d nr_tti_rx %d Got rnti %x and timing advance %d from RAR\n",
// ue->Mod_id,
// frame_rx,
// nr_tti_rx,
// ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti,
// timing_advance);
// remember this c-rnti is still a tc-rnti
......@@ -3409,11 +3220,12 @@ void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmod
if (mode!=debug_prach) {
ue->ulsch_Msg3_active[eNB_id]=1;
nr_get_Msg3_alloc(&ue->frame_parms,
nr_tti_rx,
frame_rx,
&ue->ulsch_Msg3_frame[eNB_id],
&ue->ulsch_Msg3_subframe[eNB_id]);
// TBR nr_get_Msg3_alloc has to be fixed
// nr_get_Msg3_alloc(&ue->frame_parms,
// nr_tti_rx,
// frame_rx,
// &ue->ulsch_Msg3_frame[eNB_id],
// &ue->ulsch_Msg3_subframe[eNB_id]);
LOG_D(PHY,"[UE %d][RAPROC] Got Msg3_alloc Frame %d nr_tti_rx %d: Msg3_frame %d, Msg3_subframe %d\n",
ue->Mod_id,
......@@ -3424,11 +3236,11 @@ void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmod
harq_pid = nr_subframe2harq_pid(&ue->frame_parms,
ue->ulsch_Msg3_frame[eNB_id],
ue->ulsch_Msg3_subframe[eNB_id]);
ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0;
//ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0; // TODO TBR fix this when HARQ is ready
ue->UE_mode[eNB_id] = RA_RESPONSE;
// ue->Msg3_timer[eNB_id] = 10;
ue->ulsch[eNB_id]->power_offset = 6;
//ue->ulsch[eNB_id]->power_offset = 6; // TODO TBR fix this
ue->ulsch_no_allocation_counter[eNB_id] = 0;
}
} else { // PRACH preamble doesn't match RAR
......@@ -3443,9 +3255,7 @@ void process_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB_id, runmod
timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4));
nr_process_timing_advance_rar(ue,proc,timing_advance);
}
}
#endif
}*/
void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
UE_nr_rxtx_proc_t *proc,
......@@ -3540,11 +3350,11 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
if (frame_rx < *dlsch_errors)
*dlsch_errors=0;
if (pdsch==RA_PDSCH) {
if (pdsch == RA_PDSCH) {
if (ue->prach_resources[eNB_id]!=NULL)
dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI;
else {
LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,nr_tti_rx);
LOG_E(PHY,"[UE %d] Frame %d, nr_tti_rx %d: FATAL, prach_resources is NULL\n", ue->Mod_id, frame_rx, nr_tti_rx);
//mac_xface->macphy_exit("prach_resources is NULL");
return;
}
......@@ -3734,7 +3544,15 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue,
dl_indication.proc=proc;
//dl_indication.rx_ind->number_pdus
switch (pdsch) {
case RA_PDSCH:
rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_RAR;
break;
case PDSCH:
rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH;
break;
}
rx_ind.rx_indication_body[0].pdsch_pdu.pdu = dlsch0->harq_processes[harq_pid]->b;
rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length = dlsch0->harq_processes[harq_pid]->TBS>>3;
LOG_D(PHY, "PDU length in bits: %d, in bytes: %d \n", dlsch0->harq_processes[harq_pid]->TBS, rx_ind.rx_indication_body[0].pdsch_pdu.pdu_length);
......@@ -4399,6 +4217,30 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
ue->dlsch_ra[eNB_id],
NULL);
// #if UE_TIMING_TRACE
// start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
// #endif
nr_ue_dlsch_procedures(ue,
proc,
eNB_id,
RA_PDSCH,
ue->dlsch_ra[eNB_id],
NULL,
&ue->dlsch_ra_errors[eNB_id],
mode);
// #if UE_TIMING_TRACE
// stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]);
#if DISABLE_LOG_X
printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0));
printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
#else
LOG_D(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0));
#endif
// #endif
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT);
}
......@@ -4639,3 +4481,134 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue,
return(0);
}
void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t mode) {
/* TBR
// here params are hardcoded */
int frame_tx = proc->frame_tx, nr_tti_tx = proc->nr_tti_tx, prach_power;
uint16_t preamble_tx=ue->prach_resources[0]->ra_PreambleIndex; //uint16_t preamble_tx=50; // TBR
NR_PRACH_RESOURCES_t prach_resources;
uint8_t mod_id = ue->Mod_id;
NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
UE_MODE_t UE_mode = get_nrUE_mode(mod_id, ue->CC_id, gNB_id);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN);
ue->generate_nr_prach = 0;
if (ue->mac_enabled == 0){
ue->prach_resources[gNB_id] = &prach_resources; // TBR double check pointer
ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx;
ue->prach_resources[gNB_id]->ra_TDD_map_index = 0;
// ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10; // TBR
// ue->prach_resources[gNB_id]->ra_RNTI = 93; // TBR
} else {
// ask L2 for RACH transport
/* TBR
// check if these modes are active */
if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) {
LOG_D(PHY,"Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_tti_tx);
ue->prach_resources[gNB_id] = nr_ue_get_rach(mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_tti_tx);
// LOG_D(PHY,"Got prach_resources for gNB %d address %p, RRCCommon %p\n", gNB_id, ue->prach_resources[gNB_id], UE_mac_inst[ue->Mod_id].radioResourceConfigCommon); // TBR update this
}
}
if (ue->prach_resources[gNB_id]!=NULL) {
ue->generate_nr_prach = 1;
ue->prach_cnt = 0;
#ifdef SMBV // TBR
ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx;
#endif
#ifdef OAI_EMU // TBR
ue->prach_PreambleIndex=ue->prach_resources[gNB_id]->ra_PreambleIndex;
#endif
// if (abstraction_flag == 0) { // TBR
LOG_I(PHY,"mode %d\n",mode);
if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) {
/* TODO TBR
// check if ra_PREAMBLE_RECEIVED_TARGET_POWER is filled id */
ue->tx_power_dBm[nr_tti_tx] = ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER + get_nr_PL(ue,gNB_id);
/* TODO TBR
DEBUG ONLY */
printf("ue->tx_power_dBm[nr_tti_tx] %d ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER %d get_nr_PL(ue,gNB_id) %d\n", ue->tx_power_dBm[nr_tti_tx], ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, get_nr_PL(ue,gNB_id));
} else {
ue->tx_power_dBm[nr_tti_tx] = ue->tx_power_max_dBm;
ue->prach_resources[gNB_id]->ra_PreambleIndex = preamble_tx; /* TODO TBR this is hardcoded */
}
LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n", ue->Mod_id,
frame_tx,
nr_tti_tx,
ue->prach_resources[gNB_id]->ra_PreambleIndex,
get_nr_PL(ue,gNB_id),
ue->tx_power_dBm[nr_tti_tx],
ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER,
ue->prach_resources[gNB_id]->ra_TDD_map_index,
ue->prach_resources[gNB_id]->ra_RNTI);
ue->tx_total_RE[nr_tti_tx] = 96; /* TODO TBR this is hardcoded */
#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706)
ue->prach_vars[gNB_id]->amp = get_tx_amp(ue->tx_power_dBm[nr_tti_tx], /* TODO TBR get_tx_amp is still valid for NR ? */
ue->tx_power_max_dBm,
ue->frame_parms.N_RB_UL,
6); /* TODO TBR why 6 ? */
#else
ue->prach_vars[gNB_id]->amp = AMP; /* TODO TBR where does this come from ? */
#endif
if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) /* TODO TBR double check where calibration prach tx is handled */
LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d : PRACH TX power %d dBm, amp %d\n",
ue->Mod_id,
proc->frame_rx,
proc->nr_tti_tx,
ue->tx_power_dBm[nr_tti_tx],
ue->prach_vars[gNB_id]->amp);
// start_meas(&ue->tx_prach);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN);
// prach_power = generate_nr_prach(ue,gNB_id,nr_tti_tx,frame_tx);
prach_power = generate_nr_prach(ue,0,9,0); //subframe number hardcoded according to the simulator /* TODO TBR this is hardcoded */
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT);
// stop_meas(&ue->tx_prach);
LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n",
ue->Mod_id,
get_nr_PL(ue,gNB_id),
ue->tx_power_dBm[nr_tti_tx],
dB_fixed(prach_power),
ue->prach_vars[gNB_id]->amp);
// } else {
// UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_flag=1;
// UE_transport_info[ue->Mod_id][ue->CC_id].cntl.prach_id=ue->prach_resources[eNB_id]->ra_PreambleIndex;
// } // commented for compiling as abstraction flag is 0
if (ue->mac_enabled == 1)
// nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id); TBR
LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_rx %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n",
ue->Mod_id,frame_tx,nr_tti_tx,gNB_id,
ue->prach_resources[gNB_id]->ra_PreambleIndex,
ue->prach_resources[gNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_nr_PL(ue,gNB_id),
get_nr_PL(ue,gNB_id));
}
// if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue
if (mode == calib_prach_tx)
ue->prach_resources[gNB_id]=NULL;
LOG_D(PHY,"[UE %d] frame %d nr_tti_rx %d : generate_nr_prach %d, prach_cnt %d\n", ue->Mod_id,frame_tx,nr_tti_tx,ue->generate_nr_prach,ue->prach_cnt);
ue->prach_cnt++;
if (ue->prach_cnt == 3)
ue->generate_nr_prach = 0;
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT);
}
\ No newline at end of file
......@@ -37,7 +37,7 @@
#include "PHY/defs_nr_UE.h"
#include <openair1/SCHED/sched_common.h>
#include <openair1/PHY/NR_UE_TRANSPORT/pucch_nr.h>
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#ifndef NO_RAT_NR
......
......@@ -28,11 +28,9 @@
#include "common/ran_context.h"
#include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "openair2/LAYER2/NR_MAC_UE/mac_defs.h"
#include "openair2/LAYER2/NR_MAC_UE/mac_extern.h"
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/NR_MAC_UE/mac_defs.h"
#include "LAYER2/NR_MAC_UE/mac_extern.h"
#include "PHY/defs_gNB.h"
#include "PHY/defs_nr_common.h"
#include "PHY/defs_nr_UE.h"
......@@ -55,7 +53,7 @@
#include "LAYER2/NR_MAC_UE/mac_proto.h"
//#include "LAYER2/NR_MAC_gNB/mac_proto.h"
//#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "NR_asn_constant.h"
#include "RRC/NR/MESSAGES/asn1_msg.h"
#include "openair1/SIMULATION/RF/rf.h"
......
......@@ -114,7 +114,7 @@ int main(int argc, char **argv)
uint8_t subframe=9;
uint16_t preamble_energy, preamble_tx=50, preamble_delay;
uint16_t preamble_max,preamble_energy_max;
PRACH_RESOURCES_t prach_resources;
NR_PRACH_RESOURCES_t prach_resources;
//uint8_t prach_fmt;
//int N_ZC;
int delay = 0;
......@@ -518,8 +518,7 @@ int main(int argc, char **argv)
0); //Nf */ //commented for testing purpose
UE_nr_rxtx_proc_t proc={0};
nr_ue_prach_procedures(UE,&proc,0,0,0);
nr_ue_prach_procedures(UE,&proc,0,0);
/* tx_lev_dB not used later, no need to set */
//tx_lev_dB = (unsigned int) dB_fixed(tx_lev);
......
......@@ -52,8 +52,9 @@
#include "openair1/SIMULATION/TOOLS/sim.h"
#include "openair1/SIMULATION/RF/rf.h"
#include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h"
#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h"
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
//#define DEBUG_ULSIM
......
......@@ -54,7 +54,8 @@
#include "common/config/config_userapi.h"
//#include "RRC_config_tools.h"
#include "gnb_paramdef.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "NR_asn_constant.h"
#include "executables/thread-common.h"
#include "NR_SCS-SpecificCarrier.h"
......
......@@ -35,7 +35,7 @@
#include "LAYER2/MAC/mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h"
#include "nfapi/oai_integration/vendor_ext.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
......
......@@ -41,6 +41,10 @@
#define NR_BCCH_BCH 5 // MIB
#define CCCH_PAYLOAD_SIZE_MAX 128
#define RAR_PAYLOAD_SIZE_MAX 128
// For both DL/UL-SCH
// Except:
// - UL/DL-SCH: fixed-size MAC CE(known by LCID)
......@@ -66,6 +70,12 @@
// F: lenght of L is 0:8 or 1:16 bits wide
// R: Reserved bit, set to zero.
typedef enum {
RA_IDLE = 0,
WAIT_RAR = 1,
WAIT_CONTENTION_RESOLUTION = 2
} RA_state_t;
typedef struct {
uint8_t LCID:6; // octet 1 [5:0]
uint8_t F:1; // octet 1 [6]
......@@ -92,6 +102,31 @@ typedef struct {
uint8_t TAGID:2; // octet 1 [7:6]
} __attribute__ ((__packed__)) NR_MAC_CE_TA;
// /*! \brief CCCH payload */ // TBR
// typedef struct {
// uint8_t payload[CCCH_PAYLOAD_SIZE_MAX];
// } __attribute__ ((__packed__)) CCCH_PDU;
//
// /*! \brief RAR payload */ // TBR
// typedef struct {
// uint8_t payload[RAR_PAYLOAD_SIZE_MAX];
// } __attribute__ ((__packed__)) RAR_PDU;
/*!\brief MAC header of Random Access Response for Random access preamble identifier (RAPID) */
typedef struct {
uint8_t RAPID:6;
uint8_t T:1;
uint8_t E:1;
} __attribute__ ((__packed__)) NR_RA_HEADER_RAPID;
/*!\brief MAC header of Random Access Response for backoff indicator (BI)*/
typedef struct {
uint8_t BI:4;
uint8_t R:2;
uint8_t T:1;
uint8_t E:1;
} __attribute__ ((__packed__)) NR_RA_HEADER_BI;
// 38.321 ch6.2.1, 38.331
#define DL_SCH_LCID_CCCH 0x00
#define DL_SCH_LCID_DCCH 0x01
......
......@@ -32,6 +32,8 @@
#ifndef __LAYER2_NR_MAC_COMMON_H__
#define __LAYER2_NR_MAC_COMMON_H__
#include "NR_PDSCH-Config.h"
uint16_t config_bandwidth(int mu, int nb_rb, int nr_band);
uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn);
......
......@@ -19,12 +19,12 @@
* contact@openairinterface.org
*/
/*! \file extern.h
/*! \file nr_mac_extern.h
* \brief NR mac externs
* \author G. Casati
* \author Navid Nikaein, Raymond Knopp, Guido Casati
* \date 2019
* \version 1.0
* \email guido.casati@iis.fraunhofer.de
* \email navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
* @ingroup _mac
*/
......@@ -32,10 +32,11 @@
#ifndef __NR_MAC_EXTERN_H__
#define __NR_MAC_EXTERN_H__
//#include "PHY/defs_common.h"
#include "nr_mac.h"
#include "RRC/LTE/rrc_defs.h"
#include "RRC/LTE/rrc_defs.h" // TBR
#include "common/ran_context.h"
#include "nr_mac.h"
/*#include "PHY/defs_common.h"*/
/* extern const uint32_t BSR_TABLE[BSR_TABLE_SIZE];
extern const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE];
......@@ -43,8 +44,6 @@ extern const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
extern const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
extern const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE];
extern UE_RRC_INST *UE_rrc_inst;
extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8
extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8
extern int cqi_to_mcs[16];
extern uint32_t RRC_CONNECTION_FLAG;
extern uint8_t rb_table[34];
......@@ -52,6 +51,9 @@ extern mac_rlc_am_muilist_t rlc_am_mui;
extern SCHEDULER_MODES global_scheduler_mode;
extern unsigned char NB_UE_INST;*/
extern eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8
extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_ENB]; // eNBxUE = 8x8
extern unsigned char NB_INST;
extern unsigned char NB_eNB_INST;
extern unsigned char NB_RN_INST;
......@@ -61,8 +63,15 @@ extern unsigned short NODE_ID[1];
extern RAN_CONTEXT_t RC;
extern int phy_test;
extern uint8_t nfapi_mode;
extern mac_rlc_am_muilist_t rlc_am_mui;
extern SCHEDULER_MODES global_scheduler_mode;
/*#if defined(PRE_SCD_THREAD)
extern int cqi_to_mcs[16];
extern uint32_t RRC_CONNECTION_FLAG;
extern uint8_t rb_table[34];
#if defined(PRE_SCD_THREAD)
extern uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX];
extern uint8_t dlsch_ue_select_tbl_in_use;
extern uint8_t new_dlsch_ue_select_tbl_in_use;
......@@ -70,4 +79,5 @@ extern boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX];
extern eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
#endif*/
#endif //DEF_H
......@@ -31,11 +31,11 @@
*/
//#include "mac_defs.h"
#include "mac_proto.h"
#include "NR_MAC_UE/mac_proto.h"
#include "NR_MAC-CellGroupConfig.h"
#include "../NR_MAC_gNB/nr_mac_common.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "SCHED_NR/phy_frame_config_nr.h"
int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg,
......
......@@ -37,6 +37,20 @@
#include <stdlib.h>
#include <string.h>
#include "platform_types.h"
/* PHY */
#include "PHY/defs_nr_common.h"
/* IF */
#include "NR_IF_Module.h"
#include "fapi_nr_ue_interface.h"
/* MAC */
#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "LAYER2/MAC/mac.h" // TBR
/* RRC */
#include "NR_DRX-Config.h"
#include "NR_SchedulingRequestConfig.h"
#include "NR_BSR-Config.h"
......@@ -48,12 +62,11 @@
#include "NR_PhysicalCellGroupConfig.h"
#include "NR_SpCellConfig.h"
#include "NR_ServingCellConfig.h"
#include "fapi_nr_ue_interface.h"
#include "NR_IF_Module.h"
#include "../NR_MAC_gNB/nr_mac_common.h"
#include "PHY/defs_nr_common.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#define NB_NR_UE_MAC_INST 1
#define MAX_NUM_BWP 2
typedef enum {
SFN_C_MOD_2_EQ_0,
......@@ -61,14 +74,6 @@ typedef enum {
SFN_C_IMPOSSIBLE
} SFN_C_TYPE;
#define MAX_NUM_BWP 2
typedef enum {
RA_IDLE=0,
WAIT_RAR=1,
WAIT_CONTENTION_RESOLUTION=2
} RA_state_t;
/*!\brief Top level UE MAC structure */
typedef struct {
......@@ -95,15 +100,67 @@ typedef struct {
SFN_C_TYPE type0_pdcch_ss_sfn_c;
uint32_t type0_pdcch_ss_n_c;
uint32_t type0_pdcch_consecutive_slots;
/* PDUs */
/// Outgoing CCCH pdu for PHY
CCCH_PDU CCCH_pdu;
/* Random Access parameters */
/// state of RA procedure
RA_state_t ra_state;
RA_state_t ra_state; // TBR
/// RACH ConfigCommon
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon;
/// RA-rnti
uint16_t ra_rnti;
uint16_t ra_rnti; // TBR
/// Temporary CRNTI
uint16_t t_crnti;
uint16_t t_crnti; // TBR
/// CRNTI
uint16_t crnti;
uint16_t crnti; // TBR
/// number of attempt for rach
uint8_t RA_attempt_number;
/// Random-access procedure flag
uint8_t RA_active;
/// Random-access window counter
int8_t RA_window_cnt;
/// Random-access Msg3 size in bytes
uint8_t RA_Msg3_size;
/// Random-access prachMaskIndex
uint8_t RA_prachMaskIndex;
/// Flag indicating Preamble set (A,B) used for first Msg3 transmission
uint8_t RA_usedGroupA;
/// Random-access Resources
NR_PRACH_RESOURCES_t RA_prach_resources;
/// BeamfailurerecoveryConfig
NR_BeamFailureRecoveryConfig_t RA_BeamFailureRecoveryConfig;
/// Preamble Tx Counter
uint8_t RA_PREAMBLE_TRANSMISSION_COUNTER;
/// Preamble Power Ramping Counter
uint8_t RA_PREAMBLE_POWER_RAMPING_COUNTER;
/// Random-access backoff counter
int16_t RA_backoff_cnt;
/// Random-access variable for window calculation (frame of last change in window counter)
uint32_t RA_tx_frame;
/// Random-access variable for window calculation (subframe of last change in window counter)
uint8_t RA_tx_subframe;
/// Random-access Group B maximum path-loss
/// Random-access variable for backoff (frame of last change in backoff counter)
uint32_t RA_backoff_frame;
/// Random-access variable for backoff (subframe of last change in backoff counter)
uint8_t RA_backoff_subframe;
/// Random-access Group B maximum path-loss
uint16_t RA_maxPL;
/// Random-access Contention Resolution Timer active flag
uint8_t RA_contention_resolution_timer_active;
/// Random-access Contention Resolution Timer count value
uint8_t RA_contention_resolution_cnt;
/// Msg3 Delta Preamble
int8_t deltaPreamble_Msg3;
/// Flag to monitor if matching RAPID was received in RAR
uint8_t RA_RAPID_found;
/// UE_Mode variable should be used in the case of Phy_stub operation since we won't have access to PHY_VARS_UE
/// where the UE_mode originally is for the full stack operation mode. The transitions between the states of the UE_Mode
/// will be triggered within phy_stub_ue.c in this case
UE_MODE_t UE_mode[NUMBER_OF_CONNECTED_gNB_MAX];
//// FAPI-like interface message
fapi_nr_tx_request_t tx_request;
......
......@@ -124,8 +124,6 @@ uint32_t get_ssb_slot(uint32_t ssb_index);
uint32_t mr_ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, uint8_t eNB_id, uint16_t rnti, sub_frame_t subframe);
/* \brief Get payload (MAC PDU) from UE PHY
@param module_idP Instance id of UE in machine
@param CC_id Component Carrier index
......@@ -170,5 +168,39 @@ int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu,
int nrofDownlinkSlots, int nrofDownlinkSymbols,
int nrofUplinkSlots, int nrofUplinkSymbols);
/** \brief Function for UE/PHY to compute PUSCH transmit power in power-control procedure.
@param Mod_id Module id of UE
@returns Po_NOMINAL_PUSCH (PREAMBLE_RECEIVED_TARGET_POWER+DELTA_PREAMBLE
*/
int8_t nr_get_Po_NOMINAL_PUSCH(module_id_t module_idP, uint8_t CC_id);
/** \brief Function to compute DELTA_PREAMBLE from 38.321 subclause 7.3
(for RA power ramping procedure and Msg3 PUSCH power control policy)
@param Mod_id Module id of UE
@returns DELTA_PREAMBLE
*/
int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id);
/* \brief Function called by PHY to process the received RAR and check that the preamble matches what was sent by the gNB. It provides the timing advance and t-CRNTI.
@param Mod_id Index of UE instance
@param CC_id Index to a component carrier
@param frame Frame index
@param ra_rnti RA_RNTI value
@param dlsch_buffer Pointer to dlsch_buffer containing RAR PDU
@param t_crnti Pointer to PHY variable containing the T_CRNTI
@param preamble_index Preamble Index used by PHY to transmit the PRACH. This should match the received RAR to trigger the rest of
random-access procedure
@param selected_rar_buffer the output buffer for storing the selected RAR header and RAR payload
@returns timing advance or 0xffff if preamble doesn't match
*/
uint16_t nr_ue_process_rar(const module_id_t mod_id,
const int CC_id,
const frame_t frameP,
const rnti_t ra_rnti,
uint8_t * const dlsch_buffer,
rnti_t * const t_crnti,
const uint8_t preamble_index,
uint8_t * selected_rar_buffer);
#endif
/** @}*/
......@@ -31,8 +31,8 @@
*/
//#include "defs.h"
#include "mac_proto.h"
#include "executables/nr-softmodem.h"
#include "NR_MAC_UE/mac_proto.h"
static NR_UE_MAC_INST_t *nr_ue_mac_inst;
......
/*
* 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
*/
/*! \file nr_l1_helper.c
* \brief PHY helper function adapted to NR
* \author Guido Casati
* \date 2019
* \version 1.0
* \email guido.casati@iis.fraunhofer.de
* @ingroup _mac
*/
#include "PHY/defs_common.h" // TBR
#include "PHY/defs_nr_common.h"
#include "mac_defs.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
/* 38.321 subclause 7.3 - return values are in dB */
int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id){
NR_UE_MAC_INST_t *nrUE_mac_inst = get_mac_inst(mod_id);
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = nrUE_mac_inst->nr_rach_ConfigCommon;
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
NR_SubcarrierSpacing_t scs = nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
uint8_t preambleFormat, prachConfigIndex;
lte_frame_type_t frame_type = TDD; // TODO TBR retrieve frame type. Currently hardcoded to TDD.
// was nr_UE_mac_inst[mod_id].tdd_Config
nr_frequency_range_e fr = nr_FR1; // TODO TBR retrieve frame type. Currently hardcoded to FR1.
int mu;
switch (scs){
case NR_SubcarrierSpacing_kHz15:
mu = 0;
break;
case NR_SubcarrierSpacing_kHz30:
mu = 1;
break;
case NR_SubcarrierSpacing_kHz60:
mu = 2;
break;
case NR_SubcarrierSpacing_kHz120:
mu = 3;
break;
case NR_SubcarrierSpacing_kHz240:
mu = 4;
break;
case NR_SubcarrierSpacing_spare3:
mu = 5;
break;
case NR_SubcarrierSpacing_spare2:
mu = 6;
break;
case NR_SubcarrierSpacing_spare1:
mu = 7;
break;
default:
AssertFatal(1 == 0,"Unknown msg1_SubcarrierSpacing %d\n", scs);
}
prachConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
preambleFormat = get_nr_prach_fmt(prachConfigIndex,frame_type,fr);
switch (preambleFormat) {
// long preamble formats
case 0:
case 3:
return 0;
case 1:
return -3;
case 2:
return -6;
// short preamble formats
case 0xa1:
case 0xb1:
return 8 + 3*mu;
case 0xa2:
case 0xb2:
case 0xc2:
return 5 + 3*mu;
case 0xa3:
case 0xb3:
return 3 + 3*mu;
case 0xb4:
return 3*mu;
case 0xc0:
return 5 + 3*mu;
default:
AssertFatal(1 == 0, "[UE %d] ue_procedures.c: FATAL, Illegal preambleFormat %d, prachConfigIndex %d\n", mod_id, preambleFormat, prachConfigIndex);
}
return;
}
int8_t nr_get_Po_NOMINAL_PUSCH(module_id_t mod_id, uint8_t CC_id){
NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon;
NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources;
//AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
AssertFatal(nr_rach_ConfigCommon != NULL, "[UE %d] CCid %d FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id, CC_id);
int8_t receivedTargerPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower + nr_get_DELTA_PREAMBLE(mod_id, CC_id) + (nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP;
return receivedTargerPower;
//return (-120 + (nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower << 1) + nr_get_DELTA_PREAMBLE(mod_id, CC_id) );
}
/*int8_t get_deltaP_rampup(module_id_t module_idP, uint8_t CC_id){ // TBR
AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n");
LOG_D(MAC, "[PUSCH]%d dB\n",
nrUE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER << 1);
return ((int8_t)
(nrUE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER << 1));
}*/
\ No newline at end of file
/*
* 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
*/
/*! \file ra_procedures.c
* \brief Routines for UE MAC-layer Random Access procedures (TS 38.321, Release 15)
* \author R. Knopp, Navid Nikaein, Guido Casati
* \date 2019
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr navid.nikaein@eurecom.fr, guido.casati@iis.fraunhofer.de
* \note
* \warning
*/
#include "mac.h"
// TBR missing NR_nr_UE_mac_inst in mac.h
/*
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "PHY_INTERFACE/phy_interface_extern.h"
#include "SCHED_UE/sched_UE.h"
#include "COMMON/mac_rrc_primitives.h"
#include "RRC/LTE/rrc_extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "common/utils/LOG/log.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "PHY/LTE_ESTIMATION/lte_estimation.h"*/
/* Tools */
#include "SIMULATION/TOOLS/sim.h" // for taus
/* RRC */
#include "NR_RACH-ConfigCommon.h"
/* PHY */
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
#include "PHY/defs_common.h"
#include "PHY/defs_nr_common.h"
/* MAC */
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
extern UE_MODE_t get_nrUE_mode(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_id);
extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9];
extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9];
//extern uint8_t nfapi_mode; // TBR
// This routine implements Section 5.1.2 (UE Random Access Resource Selection)
// and Section 5.1.3 (Random Access Preamble Transmission) from 3GPP TS 38.321
void nr_get_prach_resources(module_id_t mod_id,
int CC_id,
uint8_t gNB_id,
uint8_t t_id,
uint8_t first_Msg3,
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){
NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources;
NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &nr_UE_mac_inst->RA_BeamFailureRecoveryConfig;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon;
int messagePowerOffsetGroupB, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, frequencyStart, i, deltaPreamble_Msg3;
uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, msg1_FDM, prach_ConfigIndex, SFN_nbr, Msg3_size;
NR_RSRP_Range_t rsrp_ThresholdSSB;
/* TBR retrieve following params
// currently hardcoded */
prach_resources->ra_PreambleIndex = 51;
/*uint8_t Msg3_size = nr_UE_mac_inst->RA_Msg3_size;
uint8_t f_id = 0, num_prach = 0;*/
/*AssertFatal(CC_id == 0,
"Transmission on secondary CCs is not supported yet\n");
AssertFatal(nr_UE_mac_inst->nr_rach_ConfigCommon != NULL,
"[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n",
mod_id);*/
///////////////////////////////////////////////////////////
//////////* UE Random Access Resource Selection *//////////
///////////////////////////////////////////////////////////
//numberOfRA_Preambles = (1 + nr_rach_ConfigCommon->preambleInfo.numberOfRA_Preambles) << 2;
numberOfRA_Preambles = nr_rach_ConfigCommon->totalNumberOfRA_Preambles;
rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB;
nr_UE_mac_inst->nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
/* TBR switch initialisation cases
- RA initiated by beam failure recovery operation (subclause 5.17 TS 38.321)
- SSB selection, set prach_resources->ra_PreambleIndex
- RA initiated by PDCCH: ra_PreambleIndex provided by PDCCH && ra_PreambleIndex != 0b000000
- set REAMBLE_INDEX to ra_PreambleIndex
- select the SSB signalled by PDCCH
- RA initiated for SI request:
- SSB selection, set prach_resources->ra_PreambleIndex */
// if (rach_ConfigDedicated) { // This is for network controlled Mobility
// // TBR operation for contention-free RA resources when:
// // - available SSB with SS-RSRP above rsrp-ThresholdSSB: SSB selection
// // - availalbe CSI-RS with CSI-RSRP above rsrp-ThresholdCSI-RS: CSI-RS selection
// prach_resources->ra_PreambleIndex = rach_ConfigDedicated->ra_PreambleIndex;
// return;
// }
/* Contention-based RA preamble selection:
- TBR selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB */
if (!nr_rach_ConfigCommon->groupBconfigured) {
noGroupB = 1;
} else {
/* RA preambles group B is configured
// - Defining the number of RA preambles in RA Preamble Group A for each SSB */
//sizeOfRA_PreamblesGroupA = (nr_rach_ConfigCommon->preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA + 1) << 2;
sizeOfRA_PreamblesGroupA = nr_rach_ConfigCommon->groupBconfigured->numberOfRA_PreamblesGroupA;
switch (nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA){
/* - Threshold to determine the groups of RA preambles */
case 0:
messageSizeGroupA = 56;
break;
case 1:
messageSizeGroupA = 144;
break;
case 2:
messageSizeGroupA = 208;
break;
case 3:
messageSizeGroupA = 256;
break;
case 4:
messageSizeGroupA = 282;
break;
case 5:
messageSizeGroupA = 480;
break;
case 6:
messageSizeGroupA = 640;
break;
case 7:
messageSizeGroupA = 800;
break;
case 8:
messageSizeGroupA = 1000;
break;
case 9:
messageSizeGroupA = 72;
break;
default:
AssertFatal(1 == 0,"Unknown ra_Msg3SizeGroupA %d\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA);
/* TBR cases 10 -15*/
}
/* - Power offset for preamble selection */
/* TBR: what value to use as default? */
messagePowerOffsetGroupB = -9999;
switch (nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB){
case 0:
messagePowerOffsetGroupB = -9999;
break;
case 1:
messagePowerOffsetGroupB = 0;
break;
case 2:
messagePowerOffsetGroupB = 5;
break;
case 3:
messagePowerOffsetGroupB = 8;
break;
case 4:
messagePowerOffsetGroupB = 10;
break;
case 5:
messagePowerOffsetGroupB = 12;
break;
case 6:
messagePowerOffsetGroupB = 15;
break;
case 7:
messagePowerOffsetGroupB = 18;
break;
default:
AssertFatal(1 == 0,"Unknown messagePowerOffsetGroupB %d\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB);
}
// TBR Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0
nr_UE_mac_inst->deltaPreamble_Msg3 = 0;
deltaPreamble_Msg3 = nr_UE_mac_inst->deltaPreamble_Msg3;
}
PLThreshold = prach_resources->RA_PCMAX - nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB;
// PLThreshold = prach_resources->RA_PCMAX - nr_get_DELTA_PREAMBLE(mod_id, CC_id) - nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id) - messagePowerOffsetGroupB;
// TBR Note Pcmax is set to 0 here, we have to fix this
/* Msg3 has not been transmitted yet */
if (first_Msg3 == 1) {
if (noGroupB == 1) {
// use Group A preamble
prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles;
prach_resources->ra_RACH_MaskIndex = 0;
nr_UE_mac_inst->RA_usedGroupA = 1;
} else if ((Msg3_size < messageSizeGroupA) && (get_PL(mod_id, 0, gNB_id) > PLThreshold)) {
// TBR update get_PL to NR
// TBR add condition for initiation by CCCH
// Group B is configured and RA preamble Group A is used
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
prach_resources->ra_RACH_MaskIndex = 0;
nr_UE_mac_inst->RA_usedGroupA = 1;
} else {
// Group B preamble is configured and used
// the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
// the remaining belong to RA Preambles Group B
prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA
+ (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
prach_resources->ra_RACH_MaskIndex = 0;
nr_UE_mac_inst->RA_usedGroupA = 0;
}
//TBR check why this is here
// prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id);
} else {
// Msg3 is being retransmitted
if (nr_UE_mac_inst->RA_usedGroupA == 1) {
if (nr_rach_ConfigCommon->groupBconfigured){
prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA;
} else {
prach_resources->ra_PreambleIndex = (taus()) & 0x3f; // TBR check this
prach_resources->ra_RACH_MaskIndex = 0;
}
} else {
// TBR FIXME nr_rach_ConfigCommon->preambleInfo.preamblesGroupAConfig may be zero
prach_resources->ra_PreambleIndex =
sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA);
prach_resources->ra_RACH_MaskIndex = 0;
}
}
// TBR determine next available PRACH occasion
// - if RA initiated for SI request and ra_AssociationPeriodIndex and si-RequestPeriod are configured
// - else if SSB is selected above
// - else if CSI-RS is selected above
/* // choose random PRACH resource in TDD
if (nr_UE_mac_inst->tdd_Config) {
num_prach = get_num_prach_tdd(mod_id);
if ((num_prach > 0) && (num_prach < 6))
prach_resources->ra_TDD_map_index = (taus() % num_prach);
f_id = get_fid_prach_tdd(mod_id, nr_UE_mac_inst [mod_id].RA_prach_resources->ra_TDD_map_index);
}*/
/////////////////////////////////////////////////////////////////////////////
//////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *//////////
/////////////////////////////////////////////////////////////////////////////
// TBR condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321)
// TBR check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission
if (nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER >1)
nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER++;
//prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower +
// nr_get_DELTA_PREAMBLE(mod_id, CC_id) + (nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; // TBR
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id);
/* RA-RNTI computation (associated to PRACH occasion in which the RA Preamble is transmitted)
// 1) this does not apply to contention-free RA Preamble for beam failure recovery request
// 2) getting star_symb, SFN_nbr from table 6.3.3.2-3 (TDD and FR1 scenario)
// 3) TBR extend this (e.g. f_id selection, ul_carrier_id are hardcoded) */
ul_carrier_id = 0; // UL carrier used for RA preamble transmission, hardcoded for NUL carrier
f_id = 0;
//frequencyStart = nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart;
switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){
case 0:
msg1_FDM = 1;
break;
case 1:
msg1_FDM = 2;
break;
case 2:
msg1_FDM = 4;
break;
case 3:
msg1_FDM = 8;
break;
default:
AssertFatal(1 == 0,"Unknown msg1_FDM %d\n", nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM);
}
prach_ConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex;
// TBR this is for TDD FR1 only
SFN_nbr = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][4];
s_id = table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][5]; // starting symbol of the PRACH occasion
// pick the first slot of the PRACH occasion in a system frame (0 <= t_id <= 80)
for (i = 0; i < 10; i++){
if (((SFN_nbr & (1 << i)) >> i) == 1){
t_id = 2*i;
break;
}
}
prach_resources->ra_RNTI = 1 + s_id + 14 * t_id + 1120 * f_id + 8960 * ul_carrier_id;
}
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
#if 0 //TBR
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
// start contention resolution timer
nr_UE_mac_inst->RA_attempt_number++;
if (opt_enabled) {
trace_pdu(DIRECTION_UPLINK, NULL, 0, mod_id, WS_NO_RNTI, nr_UE_mac_inst->RA_prach_resources->ra_PreambleIndex, nr_UE_mac_inst->txFrame, nr_UE_mac_inst->txSubframe, 0, nr_UE_mac_inst->RA_attempt_number);
LOG_D(OPT, "[UE %d][RAPROC] TX MSG1 Frame %d trace pdu for rnti %x with size %d\n", mod_id, frameP, 1, nr_UE_mac_inst->RA_Msg3_size);
}
#endif
}
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){
#if 0 // TBR
AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n");
LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Setting contention resolution timer\n", mod_id, frameP);
// start contention resolution timer
nr_UE_mac_inst->RA_contention_resolution_cnt = 0;
nr_UE_mac_inst->RA_contention_resolution_timer_active = 1;
if (opt_enabled) {
trace_pdu(DIRECTION_UPLINK, &nr_UE_mac_inst->CCCH_pdu.payload[0], nr_UE_mac_inst->RA_Msg3_size, mod_id, WS_C_RNTI, nr_UE_mac_inst->crnti, nr_UE_mac_inst->txFrame, nr_UE_mac_inst->txSubframe, 0, 0);
LOG_D(OPT, "[UE %d][RAPROC] MSG3 Frame %d trace pdu Preamble %d with size %d\n", mod_id, frameP, nr_UE_mac_inst->crnti /*nr_UE_mac_inst->RA_prach_resources->ra_PreambleIndex */, nr_UE_mac_inst->RA_Msg3_size);
}
#endif
}
/////////////////////////////////////////////////////////////////////////
///////* Random Access Preamble Initialization (5.1.1 TS 38.321) *///////
/////////////////////////////////////////////////////////////////////////
/// Handling inizialization by PDCCH order, MAC entity or RRC (TS 38.300)
/// Only one RA procedure is ongoing at any point in time in a MAC entity
/// the RA procedure on a SCell shall only be initiated by PDCCH order
NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id,
int CC_id,
UE_MODE_t UE_mode,
frame_t frame,
uint8_t gNB_id,
int nr_tti_tx){
NR_UE_MAC_INST_t *nr_UE_mac_inst = get_mac_inst(mod_id);
uint8_t size_sdu = 0, Nb_tb = 1, lcid = CCCH, dcch_header_len = 0, ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES];
// UE_MODE_t UE_mode;
uint16_t Size16, sdu_lengths;
NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = (struct NR_RACH_ConfigCommon_t *) NULL;
NR_PRACH_RESOURCES_t *prach_resources = &nr_UE_mac_inst->RA_prach_resources;
int32_t frame_diff = 0;
// Modification for phy_stub_ue operation // TBR
// if(nfapi_mode == 3) { // phy_stub_ue mode
// UE_mode = nr_UE_mac_inst->UE_mode[CC_id];
// LOG_D(MAC, "ue_get_rach, UE_mode: %d", UE_mode);
// }
// else // Full stack mode
// UE_mode = get_nrUE_mode(mod_id, CC_id, gNB_id); // TBR
AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n");
if (UE_mode == PRACH) {
LOG_D(MAC, "ue_get_rach, RA_active value: %d", nr_UE_mac_inst->RA_active);
if (nr_UE_mac_inst->nr_rach_ConfigCommon) {
nr_rach_ConfigCommon = nr_UE_mac_inst->nr_rach_ConfigCommon;
printf("nr_rach_ConfigCommon from MAC nr_UE_mac_inst\n"); /* TBR DEBUG only */
} else return NULL;
/* TBR moved below
size_sdu = mac_rrc_nr_data_req(mod_id,
CC_id,
frame,
CCCH,
1,
&nr_UE_mac_inst->CCCH_pdu.payload[sizeof(SCH_SUBHEADER_SHORT) + 1], gNB_id, 0);*/
if (nr_UE_mac_inst->RA_active == 0) {
/* RA not active - checking if RRC is ready to initiate the RA procedure */
LOG_I(MAC, "RA not active\n");
/* TBR flush Msg3 Buffer
this was done like this but at PHY level
for(i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
// flush Msg3 buffer
PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
ue->ulsch_Msg3_active[i] = 0;
}
*/
nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
nr_UE_mac_inst->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1;
prach_resources->RA_PREAMBLE_BACKOFF = 0;
/* TBR: if carrier to use is explicitly signalled do RA CARRIER SELECTION (SUL, NUL) this will set PCMAX */
prach_resources->RA_PCMAX = 0;
/* TBR: BWP operation (subclause 5.15 TS 38.321) */
/* Set RA_PREAMBLE_POWER_RAMPING_STEP */
switch (nr_rach_ConfigCommon->rach_ConfigGeneric.powerRampingStep){ // in dB
case 0:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 0;
break;
case 1:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 2;
break;
case 2:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 4;
break;
case 3:
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP = 6;
break;
}
prach_resources->RA_SCALING_FACTOR_BI = 1;
/* TBR: initialization by beam failure recovery */
/* TBR: initialization by handover */
/* size_sdu = mac_rrc_nr_data_req(mod_id,
CC_id,
frame,
CCCH,
Nb_tb,
&nr_UE_mac_inst->CCCH_pdu.payload[sizeof(NR_MAC_SUBHEADER_SHORT) + 1]); */
// TBR mac_rrc_nr_data_req is a GNB func
// use nr_mac_rrc_data_ind_ue instead
// TBR fix CCCH PDU payload
Size16 = (uint16_t) size_sdu;
/* TBR FIX THIS
// LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",mod_id,frame,size_sdu);
LOG_I(RRC,
"[MSC_MSG][FRAME %05d][RRC_UE][MOD %02d][][--- MAC_DATA_REQ (RRCConnectionRequest gNB %d) --->][MAC_UE][MOD %02d][]\n",
frame, mod_id, gNB_id, mod_id);
LOG_I(MAC,
"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n",
mod_id, frame, size_sdu);
nr_UE_mac_inst->RA_RAPID_found = 0;
// TBR which frame and slot ?
nr_UE_mac_inst->RA_tx_frame = frame;
nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx;
nr_UE_mac_inst->RA_backoff_frame = frame;
nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx;*/
/*if (size_sdu > 0) { */
/* TBR initialisation by RRC
// PDU from CCCH */
LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame);
// TBR
/*nr_UE_mac_inst->RA_Msg3_size = size_sdu + sizeof(SCH_SUBHEADER_SHORT) + sizeof(SCH_SUBHEADER_SHORT);
nr_UE_mac_inst->RA_prachMaskIndex = 0;
prach_resources->Msg3 = nr_UE_mac_inst->CCCH_pdu.payload;
nr_UE_mac_inst->RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
AssertFatal(nr_rach_ConfigCommon != NULL,
"[UE %d] FATAL Frame %d: nr_rach_ConfigCommon is NULL !!!\n",
mod_id, frame);
nr_UE_mac_inst->RA_window_cnt = 2 + nr_rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
if (nr_UE_mac_inst->RA_window_cnt == 9) {
nr_UE_mac_inst->RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
}*/
// Fill in preamble and PRACH resources
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, NULL);
/*generate_ulsch_header((uint8_t *) & nr_UE_mac_inst->CCCH_pdu.payload[0], // mac header
1, // num sdus
0, // short pading
&Size16, // sdu length
&lcid, // sdu lcid
NULL, // power headroom
NULL, // crnti
NULL, // truncated bsr
NULL, // short bsr
NULL, // long_bsr
1); //post_padding*/
return (&nr_UE_mac_inst->RA_prach_resources);
/*} else if (nr_UE_mac_inst->scheduling_info.
BSR_bytes[nr_UE_mac_inst->scheduling_info.LCGID[DCCH]] > 0) {
// This is for triggering a transmission on DCCH using PRACH (during handover,
// or sending SR for example)
dcch_header_len = 2 + 2; /// SHORT Subheader + C-RNTI control element
LOG_USEDINLOG_VAR(mac_rlc_status_resp_t,rlc_status)=mac_rlc_status_ind(mod_id,
nr_UE_mac_inst->crnti,
gNB_id, frame, nr_tti_tx,
ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,0, 0
#endif
);
if (nr_UE_mac_inst->crnti_before_ho)
LOG_D(MAC,
"[UE %d] Frame %d : UL-DCCH -> ULSCH, HO RRCConnectionReconfigurationComplete (%x, %x), RRC message has %d bytes to send throug PRACH (mac header len %d)\n",
mod_id, frame,
nr_UE_mac_inst->crnti,
nr_UE_mac_inst->crnti_before_ho,
rlc_status.bytes_in_buffer, dcch_header_len);
else
LOG_D(MAC,
"[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to send through PRACH(mac header len %d)\n",
mod_id, frame, rlc_status.bytes_in_buffer,
dcch_header_len);
sdu_lengths = mac_rlc_data_req(mod_id, nr_UE_mac_inst->crnti,
gNB_id, frame, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6, //not used
(char *) &ulsch_buff[0]
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,0,0
#endif
);
if(sdu_lengths > 0)
LOG_D(MAC, "[UE %d] TX Got %d bytes for DCCH\n", mod_id, sdu_lengths);
else
LOG_E(MAC, "[UE %d] TX DCCH error\n", mod_id );
update_bsr(mod_id, frame, nr_tti_tx, gNB_id);
nr_UE_mac_inst->scheduling_info.BSR[nr_UE_mac_inst->
scheduling_info.LCGID[DCCH]] = locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE,
nr_UE_mac_inst
[mod_id].scheduling_info.BSR_bytes
[nr_UE_mac_inst
[mod_id].scheduling_info.LCGID
[DCCH]]);
//TBR: fill BSR infos in UL TBS
//header_len +=2;
nr_UE_mac_inst->RA_active = 1;
nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER =
1;
nr_UE_mac_inst->RA_Msg3_size =
size_sdu + dcch_header_len;
nr_UE_mac_inst->RA_prachMaskIndex = 0;
prach_resources->Msg3 =
ulsch_buff;
nr_UE_mac_inst->RA_backoff_cnt = 0; // add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator)
AssertFatal(nr_rach_ConfigCommon != NULL,
"[UE %d] FATAL Frame %d: nr_rach_ConfigCommon is NULL !!!\n",
mod_id, frame);
nr_UE_mac_inst->RA_window_cnt =
2 +
nr_rach_ConfigCommon->ra_SupervisionInfo.
ra_ResponseWindowSize;
if (nr_UE_mac_inst->RA_window_cnt == 9) {
nr_UE_mac_inst->RA_window_cnt = 10; // Note: 9 subframe window doesn't exist, after 8 is 10!
}
nr_UE_mac_inst->RA_tx_frame = frame;
nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx;
nr_UE_mac_inst->RA_backoff_frame = frame;
nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx;
// Fill in preamble and PRACH resource
nr_get_prach_resources(mod_id, CC_id, gNB_id,
nr_tti_tx, 1, NULL);
generate_ulsch_header((uint8_t *) ulsch_buff, // mac header
1, // num sdus
0, // short pading
&Size16, // sdu length
&lcid, // sdu lcid
NULL, // power headroom
&nr_UE_mac_inst->crnti, // crnti
NULL, // truncated bsr
NULL, // short bsr
NULL, // long_bsr
0); //post_padding
return (&nr_UE_mac_inst->RA_prach_resources);
}*/
} else { // RACH is active
////////////////////////////////////////////////////////////////
/////* Random Access Response reception (5.1.4 TS 38.321) */////
////////////////////////////////////////////////////////////////
/// Handling ra_responseWindow, RA_PREAMBLE_TRANSMISSION_COUNTER
/// and RA_backoff_cnt
LOG_D(MAC, "[MAC][UE %d][RAPROC] frame %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n",
mod_id, frame, nr_tti_tx, nr_UE_mac_inst->RA_window_cnt, nr_UE_mac_inst->RA_tx_frame, nr_UE_mac_inst->RA_tx_subframe);
// - TBR check
// compute backoff parameters
if (nr_UE_mac_inst->RA_backoff_cnt > 0){
frame_diff = (sframe_t) frame - nr_UE_mac_inst->RA_backoff_frame;
if (frame_diff < 0) frame_diff = -frame_diff;
nr_UE_mac_inst->RA_backoff_cnt -= ((10 * frame_diff) + (nr_tti_tx - nr_UE_mac_inst->RA_backoff_subframe));
nr_UE_mac_inst->RA_backoff_frame = frame;
nr_UE_mac_inst->RA_backoff_subframe = nr_tti_tx;
}
// - TBR check
// - TBR check
// compute RA window parameters
if (nr_UE_mac_inst->RA_window_cnt > 0){
frame_diff = (frame_t) frame - nr_UE_mac_inst->RA_tx_frame;
if (frame_diff < 0) frame_diff = -frame_diff;
nr_UE_mac_inst->RA_window_cnt -= ((10 * frame_diff) + (nr_tti_tx - nr_UE_mac_inst->RA_tx_subframe));
LOG_D(MAC, "[MAC][UE %d][RAPROC] Frame %d, subframe %d: RA Active, adjusted window cnt %d\n", mod_id, frame, nr_tti_tx, nr_UE_mac_inst->RA_window_cnt);
}
// - TBR check
//if ((nr_UE_mac_inst->RA_window_cnt <= 0) && (nr_UE_mac_inst->RA_backoff_cnt <= 0)){
if ((nr_UE_mac_inst->RA_window_cnt <= 0) && (nr_UE_mac_inst->RA_RAPID_found == 0)){ // TODO TBR double check the condition
LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception not successful, (RA window count %d) \n", mod_id, frame, nr_tti_tx, nr_UE_mac_inst->RA_window_cnt);
nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER++;
// - TBR check RA_tx_frame RA_tx_subframe
nr_UE_mac_inst->RA_tx_frame = frame;
nr_UE_mac_inst->RA_tx_subframe = nr_tti_tx;
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER += (prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP << 1); // 2dB increments in ASN.1 definition
// - TBR check ra_PREAMBLE_RECEIVED_TARGET_POWER increment
int preambleTransMax = -1;
switch (nr_rach_ConfigCommon->rach_ConfigGeneric.preambleTransMax) {
case NR_RACH_ConfigGeneric__preambleTransMax_n3:
preambleTransMax = 3;
break;
case NR_RACH_ConfigGeneric__preambleTransMax_n4:
preambleTransMax = 4;
break;
case NR_RACH_ConfigGeneric__preambleTransMax_n5:
preambleTransMax = 5;
break;
case NR_RACH_ConfigGeneric__preambleTransMax_n6:
preambleTransMax = 6;
break;
case NR_RACH_ConfigGeneric__preambleTransMax_n7:
preambleTransMax = 7;
break;
case NR_RACH_ConfigGeneric__preambleTransMax_n8:
preambleTransMax = 8;
break;
case NR_RACH_ConfigGeneric__preambleTransMax_n10:
preambleTransMax = 10;
break;
case NR_RACH_ConfigGeneric__preambleTransMax_n20:
preambleTransMax = 20;
break;
case NR_RACH_ConfigGeneric__preambleTransMax_n50:
preambleTransMax = 50;
break;
case NR_RACH_ConfigGeneric__preambleTransMax_n100:
preambleTransMax = 100;
break;
case NR_RACH_ConfigGeneric__preambleTransMax_n200:
preambleTransMax = 200;
break;
}
if (nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){
LOG_D(MAC, "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", mod_id, frame, preambleTransMax);
// TBR select random backoff according to a uniform distribution between 0 and PREAMBLE_BACKOFF
// (rand() % prach_resources->RA_PREAMBLE_BACKOFF
// TODO TBR send message to RRC
nr_UE_mac_inst->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(mod_id, CC_id); // TBR check if this is necessary
}
// TBR ra_SupervisionInfo.ra_ResponseWindowSize is missing
// nr_UE_mac_inst->RA_window_cnt = 2 + nr_rach_ConfigCommon->ra_SupervisionInfo.ra_ResponseWindowSize;
nr_UE_mac_inst->RA_backoff_cnt = 0;
// Fill in preamble and PRACH resources
nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, NULL);
return (&nr_UE_mac_inst->RA_prach_resources);
}
}
} else if (UE_mode == PUSCH) {
LOG_D(MAC, "[UE %d] FATAL: Should not have checked for RACH in PUSCH yet ...", mod_id);
AssertFatal(1 == 0, "");
}
return NULL;
}
\ No newline at end of file
......@@ -30,36 +30,36 @@
* \warning
*/
#include <stdio.h>
#include <math.h>
/* exe */
#include "executables/nr-softmodem.h"
/* MAC related headers */
#include "mac_proto.h"
/* MAC */
#include "mac_defs.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
#include "mac_extern.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "NR_MAC_UE/mac_proto.h"
#include "NR_MAC_UE/mac_extern.h"
#include "common/utils/nr/nr_common.h"
//#include "LAYER2/MAC/mac_vars.h" // TODO Note that mac_vars.h is not NR specific and this should be updated
//#include "LAYER2/MAC/mac_vars.h" // TBR Note that mac_vars.h is not NR specific and this should be updated
// also, the use of the same should be updated in nr-softmodem and nr-uesoftmodem
/* PHY UE related headers*/
/* PHY UE */
#include "SCHED_NR_UE/defs.h"
#include "RRC/NR_UE/rrc_proto.h"
#include "assertions.h"
#include "PHY/defs_nr_UE.h"
/*Openair Packet Tracer */
#include "UTIL/OPT/opt.h"
#include "OCG.h"
/* log utils */
/* utils */
#include "assertions.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include <stdio.h>
#include <math.h>
//#define ENABLE_MAC_PAYLOAD_DEBUG 1
#define DEBUG_EXTRACT_DCI 1
......
/*
* 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
*/
/*! \file rar_tools_nrUE.c
* \brief RA tools for NR UE
* \author Guido Casati
* \date 2019
* \version 1.0
* @ingroup _mac
*/
/* Sim */
#include "SIMULATION/TOOLS/sim.h"
/* Utils */
#include "common/utils/LOG/log.h"
#include "OCG.h"
#include "OCG_extern.h"
#include "UTIL/OPT/opt.h"
/* Common */
#include "common/ran_context.h"
/* MAC */
#include "NR_MAC_UE/mac.h"
#include "NR_MAC_UE/mac_proto.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#define DEBUG_RAR
uint16_t nr_ue_process_rar(const module_id_t mod_id,
const int CC_id,
const frame_t frameP,
const rnti_t ra_rnti,
uint8_t * const dlsch_buffer,
rnti_t * const t_crnti,
const uint8_t preamble_index,
uint8_t * selected_rar_buffer/*output argument for storing the selected RAR header and RAR payload*/){
NR_UE_MAC_INST_t *nrUE_mac_inst = get_mac_inst(mod_id);
uint16_t ret = 0; // return value
NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer;
// TODO TBR
// NR_RAR_PDU *rar = (RAR_PDU *)(dlsch_buffer+1);
uint8_t *rar = (uint8_t *) (dlsch_buffer + 1);
// get the last RAR payload for working with CMW500
uint8_t n_rarpy = 0; // number of RAR payloads
uint8_t n_rarh = 0; // number of MAC RAR subheaders
uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs
while (1) {
n_rarh++;
if (rarh->T == 1) {
n_rarpy++;
LOG_D(MAC, "RAPID %d\n", rarh->RAPID);
}
if (rarh->RAPID == preamble_index) {
LOG_D(PHY, "Found RAR with the intended RAPID %d\n",
rarh->RAPID);
rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
nrUE_mac_inst->RA_RAPID_found = 1;
break;
}
if (abs((int) rarh->RAPID - (int) preamble_index) <
abs((int) best_rx_rapid - (int) preamble_index)) {
best_rx_rapid = rarh->RAPID;
rar = (uint8_t *) (dlsch_buffer + n_rarh + (n_rarpy - 1) * 6);
}
if (rarh->E == 0) {
LOG_I(PHY, "No RAR found with the intended RAPID. The closest RAPID in all RARs is %d\n", best_rx_rapid);
break;
} else {
rarh++;
}
};
LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n",
n_rarh, n_rarpy);
if (CC_id > 0) {
LOG_W(MAC, "Should not have received RAR on secondary CCs! \n");
return (0xffff);
}
LOG_I(MAC,
"[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n",
mod_id, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2],
rar[3], rar[4], rar[5], rarh->RAPID, preamble_index);
#ifdef DEBUG_RAR
LOG_D(MAC, "[UE %d][RAPROC] rarh->E %d\n", mod_id, rarh->E);
LOG_D(MAC, "[UE %d][RAPROC] rarh->T %d\n", mod_id, rarh->T);
LOG_D(MAC, "[UE %d][RAPROC] rarh->RAPID %d\n", mod_id,
rarh->RAPID);
// LOG_I(MAC,"[UE %d][RAPROC] rar->R %d\n",mod_id,rar->R);
LOG_D(MAC, "[UE %d][RAPROC] rar->Timing_Advance_Command %d\n",
mod_id, (((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
// LOG_I(MAC,"[UE %d][RAPROC] rar->hopping_flag %d\n",mod_id,rar->hopping_flag);
// LOG_I(MAC,"[UE %d][RAPROC] rar->rb_alloc %d\n",mod_id,rar->rb_alloc);
// LOG_I(MAC,"[UE %d][RAPROC] rar->mcs %d\n",mod_id,rar->mcs);
// LOG_I(MAC,"[UE %d][RAPROC] rar->TPC %d\n",mod_id,rar->TPC);
// LOG_I(MAC,"[UE %d][RAPROC] rar->UL_delay %d\n",mod_id,rar->UL_delay);
// LOG_I(MAC,"[UE %d][RAPROC] rar->cqi_req %d\n",mod_id,rar->cqi_req);
LOG_D(MAC, "[UE %d][RAPROC] rar->t_crnti %x\n", mod_id,
(uint16_t) rar[5] + (rar[4] << 8));
#endif
if (opt_enabled) {
LOG_D(OPT,
"[UE %d][RAPROC] CC_id %d RAR Frame %d trace pdu for ra-RNTI %x\n",
mod_id, CC_id, frameP, ra_rnti);
/*trace_pdu(DIRECTION_DOWNLINK, (uint8_t *) dlsch_buffer, n_rarh + n_rarpy * 6,
mod_id, WS_RA_RNTI, ra_rnti, nrUE_mac_inst->rxFrame,
nrUE_mac_inst->rxSubframe, 0, 0);*/ // TODO TBR fix rxframe and subframe
}
if (preamble_index == rarh->RAPID) { // TBR double check this
*t_crnti = (uint16_t) rar[5] + (rar[4] << 8); //rar->t_crnti;
nrUE_mac_inst->crnti = *t_crnti; //rar->t_crnti;
//return(rar->Timing_Advance_Command);
ret = ((((uint16_t) (rar[0] & 0x7f)) << 4) + (rar[1] >> 4));
} else {
nrUE_mac_inst->crnti = 0;
ret = (0xffff);
}
// move the selected RAR to the front of the RA_PDSCH buffer
memcpy(selected_rar_buffer + 0, (uint8_t *) rarh, 1);
memcpy(selected_rar_buffer + 1, (uint8_t *) rar, 6);
return ret;
}
......@@ -44,7 +44,7 @@
#include "SCHED_NR/phy_frame_config_nr.h"
#include "NR_MIB.h"
#include "nr_mac_common.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
extern RAN_CONTEXT_t RC;
//extern int l2_init_gNB(void);
......
......@@ -33,9 +33,9 @@
#include "assertions.h"
#include "LAYER2/MAC/mac.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
......@@ -365,10 +365,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
schedule_nr_mib(module_idP, frame_txP, slot_txP);
}
// TbD once RACH is available, start ta_timer when UE is connected
// TBR once RACH is available, start ta_timer when UE is connected
if (ue_sched_ctl->ta_timer) ue_sched_ctl->ta_timer--;
if (ue_sched_ctl->ta_timer == 0) {
if (ue_sched_ctl->ta_timer == 0) { // TBR check phy_test (see below)
gNB->ta_command = ue_sched_ctl->ta_update;
/* if time is up, then set the timer to not send it for 5 frames
// regardless of the TA value */
......@@ -380,8 +380,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
}
// Phytest scheduling
if (phy_test && slot_txP==1){
if (phy_test && slot_txP==1){ // TBR check phy_test
nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP,NULL);
// This schedules Random-Access for NR starting in subframeP
nr_schedule_RA(module_idP, frame_txP, slot_txP);
// resetting ta flag
gNB->ta_len = 0;
}
......
......@@ -21,42 +21,539 @@
/*! \file gNB_scheduler_RA.c
* \brief primitives used for random access
* \author
* \date
* \email:
* \author Guido Casati
* \date 2019
* \email: guido.casati@iis.fraunhofer.de
* \version
*/
#include nr_mac_gNB.h
#include "platform_types.h"
#include "nr_mac_gNB.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
void
schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)
{
/* Openair Packet Tracer */
#include "UTIL/OPT/opt.h"
eNB_MAC_INST *mac = RC.mac[module_idP];
COMMON_channels_t *cc = mac->common_channels;
RA_t *ra;
// void nr_add_subframe(uint16_t *frameP, uint16_t *slotP, int offset){
// *frameP = (*frameP + ((*slotP + offset) / 10)) % 1024;
// *slotP = ((*slotP + offset) % 10);
// } // TBR fix
// handles the event of MSG1 reception
// TBR remove sub_frame_t
void nr_initiate_ra_proc(module_id_t module_idP,
int CC_id,
frame_t frameP,
sub_frame_t slotP,
uint16_t preamble_index,
int16_t timing_offset,
uint16_t ra_rnti
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // TBR
, uint8_t rach_resource_type
#endif
){
uint8_t i;
uint16_t msg2_frame = frameP, msg2_slot = slotP;
int offset;
NR_COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id];
NR_RA_t *ra = &cc->ra[0];
static uint8_t failure_cnt = 0;
start_meas(&mac->schedule_ra);
/*#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
struct PRACH_ConfigSIB_v1310 *ext4_prach = NULL;
PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL;
static uint8_t failure_cnt = 0;
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
if (cc->radioResourceConfigCommon_BR
&& cc->radioResourceConfigCommon_BR->ext4) {
ext4_prach = cc->radioResourceConfigCommon_BR->ext4->prach_ConfigCommon_v1310;
prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13;
}
#endif // #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */
for (i = 0; i < NB_RA_PROC_MAX; i++) {
LOG_D(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Subframe %d Initiating RA procedure for preamble index %d\n",
module_idP, CC_id, frameP, slotP, preamble_index);
/*#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
LOG_D(MAC,
"[gNB %d][RAPROC] CC_id %d Frame %d, Subframe %d PRACH resource type %d\n",
module_idP, CC_id, frameP, slotP, rach_resource_type);
#endif*/
ra = (RA_t *) & cc[CC_id].ra[i];
//LOG_D(MAC,"RA[state:%d]\n",ra->state);
if (ra->state == MSG2)
generate_Msg2(module_idP, CC_id, frameP, subframeP, ra);
else if (ra->state == MSG4)
generate_Msg4(module_idP, CC_id, frameP, subframeP, ra);
else if (ra->state == WAITMSG4ACK)
check_Msg4_retransmission(module_idP, CC_id, frameP, subframeP, ra);
} // for i=0 .. N_RA_PROC-1
} // CC_id
/*#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0))
if (prach_ParametersListCE_r13 && prach_ParametersListCE_r13->list.count < rach_resource_type) {
LOG_E(MAC,"[gNB %d][RAPROC] CC_id %d Received impossible PRACH resource type %d,
only %d CE levels configured\n",
module_idP, CC_id, rach_resource_type,
(int) prach_ParametersListCE_r13->list.count);
return;
}
#endif // #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */
/*VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0);*/
for (i = 0; i < NR_NB_RA_PROC_MAX; i++) {
if (ra[i].state == IDLE) {
int loop = 0;
LOG_D(MAC, "Frame %d, Subframe %d: Activating RA process %d\n", frameP, slotP, i);
ra[i].state = MSG2;
ra[i].timing_offset = timing_offset;
ra[i].preamble_subframe = slotP;
/*#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
ra[i].rach_resource_type = rach_resource_type;
ra[i].msg2_mpdcch_repetition_cnt = 0;
ra[i].msg4_mpdcch_repetition_cnt = 0;
#endif*/
/* TBR CHECK Fill in other TDD config. What about nfapi_mode? */
// if(cc->tdd_Config!=NULL){
// // switch(cc->tdd_Config->subframeAssignment){ // TBR missing tdd_Config
// // default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort();
// // case 1 :
// // offset = 6;
// // break;
// // }
// }else{//FDD
// // DJP - this is because VNF is 2 subframes ahead of PNF and TX needs 4 subframes
// if (nfapi_mode)
// offset = 7;
// else
// offset = 5;
// }
// nr_add_subframe(&msg2_frame, &msg2_slot, offset); // TBR
ra[i].Msg2_frame = msg2_frame;
ra[i].Msg2_subframe = msg2_slot;
LOG_D(MAC,"%s() Msg2[%04d%d] SFN/SF:%04d%d offset:%d\n", __FUNCTION__,ra[i].Msg2_frame,ra[i].Msg2_subframe,frameP,slotP,offset);
ra[i].Msg2_subframe = (slotP + offset) % 10;
/* TBR: find better procedure to allocate RNTI */
do {
#if defined(USRP_REC_PLAY) // deterministic rnti in usrp record/playback mode
static int drnti[MAX_MOBILES_PER_GNB] = { 0xbda7, 0x71da, 0x9c40, 0xc350, 0x2710, 0x4e20, 0x7530, 0x1388, 0x3a98, 0x61a8, 0x88b8, 0xafc8, 0xd6d8, 0x1b58, 0x4268, 0x6978 };
int j = 0;
int nb_ue = 0;
for (j = 0; j < MAX_MOBILES_PER_GNB; j++) {
if (UE_RNTI(module_idP, j) > 0) {
nb_ue++;
} else {
break;
}
}
if (nb_ue >= MAX_MOBILES_PER_GNB) {
printf("No more free RNTI available, increase MAX_MOBILES_PER_GNB\n");
abort();
}
ra[i].rnti = drnti[nb_ue];
#else
ra[i].rnti = taus();
#endif
loop++;
}
/* While loop
** TBR: second condition is not correct, the rnti may be in use without
* being in the MAC yet. To be refined.
** 1024 and 60000 arbirarily chosen, not coming from standard */
while (loop != 100 /*&& !(find_nrUE_id(module_idP, ra[i].rnti) == -1 && ra[i].rnti >= 1024 && ra[i].rnti < 60000)*/);
// TBR nr_find_ue
if (loop == 100) {
printf("%s:%d:%s: FATAL ERROR! contact the authors\n",__FILE__, __LINE__, __FUNCTION__);
abort();
}
ra[i].RA_rnti = ra_rnti;
ra[i].preamble_index = preamble_index;
failure_cnt = 0;
LOG_D(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d Activating RAR generation in Frame %d, subframe %d for process %d, rnti %x, state %d\n", module_idP, CC_id, frameP, ra[i].Msg2_frame, ra[i].Msg2_subframe, i, ra[i].rnti, ra[i].state);
return;
}
}
LOG_E(MAC,
"[gNB %d][RAPROC] FAILURE: CC_id %d Frame %d Initiating RA procedure for preamble index %d\n",
module_idP, CC_id, frameP, preamble_index);
failure_cnt++;
if(failure_cnt > 20) {
LOG_E(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information\n", module_idP, CC_id, frameP);
nr_clear_ra_proc(module_idP, CC_id, frameP);
}
}
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){
gNB_MAC_INST *mac = RC.mac[module_idP];
NR_COMMON_channels_t *cc = mac->common_channels;
NR_RA_t *ra;
uint8_t i, CC_id = 0;
start_meas(&mac->schedule_ra);
// for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
for (i = 0; i < NR_NB_RA_PROC_MAX; i++) {
ra = (NR_RA_t *) & cc[CC_id].ra[i];
LOG_D(MAC,"RA[state:%d]\n",ra->state);
switch (ra->state){
case MSG2:
nr_generate_Msg2(module_idP, CC_id, frameP, slotP, ra);
break;
case MSG4:
generate_Msg4(module_idP, CC_id, frameP, slotP, ra);
break;
case WAITMSG4ACK:
check_Msg4_retransmission(module_idP, CC_id, frameP, slotP, ra);
break;
}
} // for i=0 .. N_RA_PROC-1
// } // CC_id
stop_meas(&mac->schedule_ra);
}
void nr_generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP,
sub_frame_t slotP, NR_RA_t * ra){
int first_rb, N_RB_DL;
gNB_MAC_INST *mac = RC.mac[module_idP];
NR_COMMON_channels_t *cc = mac->common_channels;
uint8_t *vrb_map = cc[CC_idP].vrb_map;
// /* TBR - MIGRATE TO THE NEW NFAPI */
// nfapi_nr_dl_tti_request_body_t *dl_req = &mac->DL_req[CC_idP].dl_config_request_body;
// nfapi_nr_dl_tti_request_pdu_t *dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
// nfapi_tx_request_pdu_t *TX_req;
//
// /* TBR: BW should be retrieved from
// // NR_ServingCellConfigCommonSIB_t -> NR_BWP_DownlinkCommon_t -> NR_BWP_t
// N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth);
// // Temporary hardcoded
// */
// N_RB_DL = 106;
//
// if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == slotP)) {
//
// LOG_D(MAC,"[gNB %d] CC_id %d Frame %d, slotP %d:
// Generating RAR DCI, state %d\n",
// module_idP, CC_idP, frameP, slotP, ra->state);
//
// // Allocate 4 PRBS starting in RB 0
// // commented out because preprocessor is missing
// /*first_rb = 0;
// vrb_map[first_rb] = 1;
// vrb_map[first_rb + 1] = 1;
// vrb_map[first_rb + 2] = 1;
// vrb_map[first_rb + 3] = 1;*/
//
// memset((void *) dl_config_pdu, 0, sizeof(nfapi_nr_dl_config_request_pdu_t));
//
// dl_config_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE;
// dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1A;
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4;
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = ra->RA_rnti;
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 2; // RA-RNTI : see Table 4-10 from SCF082 - nFAPI specifications
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power
//
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0;
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // no TPC
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1;
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = 0;
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0;
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.virtual_resource_block_assignment_flag = 0;
//
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4);
//
// // This checks if the above DCI allocation is feasible in current subframe
// if (!nr_CCE_allocation_infeasible(module_idP, CC_idP, 0, slotP,
// dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, ra->RA_rnti)) {
//
// LOG_D(MAC, "Frame %d: Subframe %d : Adding common DCI for RA_RNTI %x\n", frameP, slotP, ra->RA_rnti);
// dl_req->number_dci++;
// dl_req->number_pdu++;
//
// dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
// memset((void *) dl_config_pdu, 0, sizeof(nfapi_nr_dl_config_request_pdu_t));
// dl_config_pdu->pdu_type = NFAPI_NR_DL_CONFIG_DCI_DL_PDU_TYPE;
// dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_nr_dl_config_dlsch_pdu));
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.tl.tag = NFAPI_NR_DL_CONFIG_REQUEST_DLSCH_PDU_REL15_TAG;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = mac->pdu_index[CC_idP];
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = ra->RA_rnti;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 2; // format 1A/1B/1D
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(N_RB_DL, first_rb, 4);
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 0;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1; // first block
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB == 1) ? 0 : 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1;
// // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB == 1) ? 1 : 2;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1;
// dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1;
// // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ;
// dl_req->number_pdu++;
// mac->DL_req[CC_idP].sfn_sf = frameP<<4 | slotP;
//
// // Program UL processing for Msg3
// nr_get_Msg3alloc(&cc[CC_idP], slotP, frameP,&ra->Msg3_frame, &ra->Msg3_subframe);
//
// LOG_D(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n",
// frameP, slotP, ra->Msg3_frame,
// ra->Msg3_subframe);
//
// nr_fill_rar(module_idP, CC_idP, ra, frameP, cc[CC_idP].RAR_pdu.payload, N_RB_DL, 7);
// nr_add_msg3(module_idP, CC_idP, ra, frameP, slotP);
// ra->state = WAITMSG3;
// LOG_D(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, slotP);
//
// // DL request
// mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + slotP;
// TX_req = &mac->TX_req[CC_idP].tx_request_body.tx_pdu_list[mac->TX_req[CC_idP].tx_request_body.number_of_pdus];
// TX_req->pdu_length = 7; // This should be changed if we have more than 1 preamble
// TX_req->pdu_index = mac->pdu_index[CC_idP]++;
// TX_req->num_segments = 1;
// TX_req->segments[0].segment_length = 7;
// TX_req->segments[0].segment_data = cc[CC_idP].RAR_pdu.payload;
// mac->TX_req[CC_idP].tx_request_body.number_of_pdus++;
//
// /*if(RC.mac[module_idP]->scheduler_mode == SCHED_MODE_FAIR_RR){
// set_dl_ue_select_msg2(CC_idP, 4, -1, ra->rnti);
// }*/
// } // PDCCH CCE allocation is feasible
// } // Msg2 frame/subframe condition
}
void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){
unsigned char i;
NR_RA_t *ra = (NR_RA_t *) &RC.mac[module_idP]->common_channels[CC_id].ra[0];
for (i = 0; i < NR_NB_RA_PROC_MAX; i++){
LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra[i].rnti);
ra[i].state = IDLE;
ra[i].timing_offset = 0;
ra[i].RRC_timer = 20;
ra[i].rnti = 0;
ra[i].msg3_round = 0;
}
}
unsigned short nr_fill_rar(const module_id_t mod_id,
const int CC_id,
NR_RA_t * ra,
const frame_t frameP,
uint8_t * const dlsch_buffer,
const uint16_t N_RB_UL,
const uint8_t input_buffer_length){
RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer;
uint8_t *rar = (uint8_t *) (dlsch_buffer + 1);
/* E/T/RAPID subheader
- E = 0, one only RAR, first and last
- T = 1, E/T/RAPID subheader */
rarh->E = 0;
rarh->T = 1;
rarh->RAPID = ra->preamble_index; // TBR Respond to Preamble 0 only for the moment
/* TBR handle MAC RAR BI subheader*/
/* TC-RNTI */
// TBR double check
rar[5] = (uint8_t) (ra->rnti >> 8);
rar[6] = (uint8_t) (ra->rnti & 0xff);
// TBR double check
/* Timing Advance Command */
// TBR double check
//ra->timing_offset = 0;
//printf("ra->timing_offset %d\n", ra->timing_offset); // TBR remove
ra->timing_offset /= 16; //T_A = N_TA/16, where N_TA should be on a 30.72Msps
rar[0] = (uint8_t) (ra->timing_offset >> (2 + 4)); // 7 MSBs of timing advance + divide by 4
rar[1] = (uint8_t) (ra->timing_offset << (4 - 2)) & 0xf0; // 4 LSBs of timing advance + divide by 4
// TBR double check
// TBR double check
COMMON_channels_t *cc = &RC.mac[mod_id]->common_channels[CC_id];
if(N_RB_UL == 25){
ra->msg3_first_rb = 1;
}else{
// if (cc->tdd_Config && N_RB_UL == 100) { // TBR missing tdd_Config
// ra->msg3_first_rb = 3;
// } else {
// ra->msg3_first_rb = 2;
// }
}
ra->msg3_nb_rb = 1;
// TBR double check
/* UL Grant */
// TBR fix this
uint16_t rballoc = nr_mac_compute_RIV(N_RB_UL, ra->msg3_first_rb, ra->msg3_nb_rb); // first PRB only for UL Grant
rar[1] |= (rballoc >> 7) & 7; // Hopping = 0 (bit 3), 3 MSBs of rballoc
rar[2] = ((uint8_t) (rballoc & 0xff)) << 1; // 7 LSBs of rballoc
ra->msg3_mcs = 10;
ra->msg3_TPC = 3;
ra->msg3_ULdelay = 0;
ra->msg3_cqireq = 0;
ra->msg3_round = 0;
rar[2] |= ((ra->msg3_mcs & 0x8) >> 3); // mcs 10
rar[3] = (((ra->msg3_mcs & 0x7) << 5)) | ((ra->msg3_TPC & 7) << 2) | ((ra->msg3_ULdelay & 1) << 1) | (ra->msg3_cqireq & 1);
// TBR double check
return ra->rnti;
}
void nr_add_msg3(module_id_t module_idP, int CC_id, NR_RA_t *ra, frame_t frameP, sub_frame_t subframeP){
#if 0
eNB_MAC_INST *mac = RC.mac[module_idP];
COMMON_channels_t *cc = &mac->common_channels[CC_id];
uint8_t j;
nfapi_ul_config_request_t *ul_req;
nfapi_ul_config_request_body_t *ul_req_body;
nfapi_ul_config_request_pdu_t *ul_config_pdu;
nfapi_hi_dci0_request_t *hi_dci0_req;
nfapi_hi_dci0_request_body_t *hi_dci0_req_body;
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu;
uint8_t sf_ahead_dl;
uint8_t rvseq[4] = {0, 2, 3, 1};
ul_req = &mac->UL_req_tmp[CC_id][ra->Msg3_subframe];
ul_req_body = &ul_req->ul_config_request_body;
AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n",
ra->rnti);
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
if (ra->rach_resource_type > 0) {
LOG_D (MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n",
module_idP, frameP, subframeP, CC_id, ra->rach_resource_type - 1, ra->Msg3_frame, ra->Msg3_subframe);
LOG_D (MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d)\n",
frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe, ra->msg3_nb_rb, ra->msg3_round);
ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus];
memset ((void *) ul_config_pdu, 0, sizeof (nfapi_ul_config_request_pdu_t));
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE;
ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_ul_config_ulsch_pdu));
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = narrowband_to_first_rb (cc, ra->msg34_narrowband) + ra->msg3_first_rb;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round];
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL (ra->msg3_mcs, ra->msg3_nb_rb);
// Re13 fields
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.ue_type = ra->rach_resource_type > 2 ? 2 : 1;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions = 1;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number = 1;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.initial_transmission_sf_io = (ra->Msg3_frame * 10) + ra->Msg3_subframe;
ul_req_body->number_of_pdus++;
} // if (ra->rach_resource_type>0) {
else
#endif
{
LOG_D(MAC,
"[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n",
module_idP, frameP, subframeP, CC_id, ra->Msg3_frame,
ra->Msg3_subframe);
LOG_D(MAC,
"Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n",
frameP, subframeP, ra->Msg3_frame, ra->Msg3_subframe,
ra->msg3_nb_rb, ra->msg3_first_rb, ra->msg3_round, ra->rnti);
ul_config_pdu = &ul_req_body->ul_config_pdu_list[ul_req_body->number_of_pdus];
memset((void *) ul_config_pdu, 0, sizeof(nfapi_ul_config_request_pdu_t));
ul_config_pdu->pdu_type = NFAPI_UL_CONFIG_ULSCH_PDU_TYPE;
ul_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_ul_config_ulsch_pdu));
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_PDU_REL8_TAG;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.handle = mac->ul_handle++;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.rnti = ra->rnti;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.resource_block_start = ra->msg3_first_rb;
AssertFatal(ra->msg3_nb_rb > 0, "nb_rb = 0\n");
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.number_of_resource_blocks = ra->msg3_nb_rb;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.modulation_type = 2;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.cyclic_shift_2_for_drms = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_enabled_flag = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.frequency_hopping_bits = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.new_data_indication = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.redundancy_version = rvseq[ra->msg3_round];
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.harq_process_number = subframe2harqpid(cc, ra->Msg3_frame, ra->Msg3_subframe);
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.ul_tx_mode = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.current_tx_nb = 0;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.n_srs = 1;
ul_config_pdu->ulsch_pdu.ulsch_pdu_rel8.size = get_TBS_UL(10, ra->msg3_nb_rb);
ul_req_body->number_of_pdus++;
ul_req_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
ul_req->sfn_sf = ra->Msg3_frame<<4|ra->Msg3_subframe;
ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST;
// save UL scheduling information for preprocessor
for (j = 0; j < ra->msg3_nb_rb; j++)
cc->vrb_map_UL[ra->msg3_first_rb + j] = 1;
LOG_D(MAC, "MSG3: UL_CONFIG SFN/SF:%d number_of_pdus:%d ra->msg3_round:%d\n", NFAPI_SFNSF2DEC(ul_req->sfn_sf), ul_req_body->number_of_pdus, ra->msg3_round);
if (ra->msg3_round != 0) { // program HI too
sf_ahead_dl = ul_subframe2_k_phich(cc, subframeP);
hi_dci0_req = &mac->HI_DCI0_req[CC_id][(subframeP+sf_ahead_dl)%10];
hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
memset((void *) hi_dci0_pdu, 0,
sizeof(nfapi_hi_dci0_request_pdu_t));
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE;
hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu);
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = ra->msg3_first_rb;
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0;
hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0;
hi_dci0_req_body->number_of_hi++;
hi_dci0_req_body->sfnsf = sfnsf_add_subframe(ra->Msg3_frame, ra->Msg3_subframe, 0);
hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl);
hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
if (NFAPI_MODE != NFAPI_MONOLITHIC) {
oai_nfapi_hi_dci0_req(hi_dci0_req);
hi_dci0_req_body->number_of_hi=0;
}
LOG_D(MAC, "MSG3: HI_DCI0 SFN/SF:%d number_of_dci:%d number_of_hi:%d\n", NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req_body->number_of_dci, hi_dci0_req_body->number_of_hi);
// save UL scheduling information for preprocessor
for (j = 0; j < ra->msg3_nb_rb; j++)
cc->vrb_map_UL[ra->msg3_first_rb + j] = 1;
LOG_D(MAC,
"[eNB %d][PUSCH-RA %x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) RA (mcs %d, first rb %d, nb_rb %d,round %d)\n",
module_idP, ra->rnti, CC_id, frameP, subframeP, 10, 1, 1,
ra->msg3_round - 1);
} // if (ra->msg3_round != 0) { // program HI too
} // non-BL/CE UE case
#endif
}
\ No newline at end of file
......@@ -31,9 +31,9 @@
*/
#include "assertions.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
......
......@@ -34,9 +34,9 @@
#include "PHY/defs_nr_common.h"
#include "PHY/NR_TRANSPORT/nr_transport_common_proto.h"
/*MAC*/
#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/MAC/mac.h"
/*NFAPI*/
......@@ -97,6 +97,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP,
}
LOG_D(MAC, "NR MAC CE timing advance command = %d (%d) TAG ID = %d\n", timing_advance_cmd, ((NR_MAC_CE_TA *) ce_ptr)->TA_COMMAND, tag_id);
mac_ce_size = sizeof(NR_MAC_CE_TA);
// Copying bytes for MAC CEs to the mac pdu pointer
......
......@@ -30,8 +30,8 @@
#include "nr_mac_gNB.h"
#include "SCHED_NR/sched_nr.h"
#include "mac_proto.h"
#include "nr_mac_common.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "PHY/NR_TRANSPORT/nr_dlsch.h"
#include "PHY/NR_TRANSPORT/nr_dci.h"
#include "executables/nr-softmodem.h"
......
......@@ -33,10 +33,10 @@
#include "assertions.h"
#include "LAYER2/MAC/mac.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/nr/nr_common.h"
......@@ -1364,3 +1364,176 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){
}
}
*/
/* TBR fix this
boolean_t nr_CCE_allocation_infeasible(int module_idP, int CC_idP, int format_flag, int slot, int aggregation, int rnti){
nfapi_dl_config_request_body_t *DL_req = &RC.mac[module_idP]->DL_req[CC_idP].dl_config_request_body;
nfapi_dl_config_request_pdu_t *dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu];
nfapi_hi_dci0_request_body_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][slot].hi_dci0_request_body;
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi];
int ret;
boolean_t res = FALSE;
if (format_flag != 2) { // DL DCI
if (DL_req->number_pdu == MAX_NUM_DL_PDU) {
LOG_W(MAC,
"Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n",
slot, rnti);
} else {
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (format_flag == 0) ? 2 : 1;
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation;
DL_req->number_pdu++;
LOG_D(MAC, "Subframe %d: Checking CCE feasibility format %d : (%x,%d) (%x,%d,%d)\n",
slot, format_flag, rnti, aggregation,
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti,
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.
aggregation_level,
dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type);
// ret = nr_allocate_CCEs(module_idP, CC_idP, 0, slot, 0); // TBR
if (ret == -1) res = TRUE;
DL_req->number_pdu--;
}
} else { // ue-specific UL DCI
if (HI_DCI0_req->number_of_dci + HI_DCI0_req->number_of_hi == MAX_NUM_HI_DCI0_PDU) {
LOG_W(MAC, "Subframe %d: FAPI UL structure is full, skip scheduling UE %d\n", slot, rnti);
} else {
hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti;
hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
HI_DCI0_req->number_of_dci++;
// ret = nr_allocate_CCEs(module_idP, CC_idP, 0, slot, 0); // TBR
if (ret == -1) res = TRUE;
HI_DCI0_req->number_of_dci--;
}
}
return res;
}*/
/* // TBR fix this
void nr_get_Msg3alloc(NR_COMMON_channels_t *cc,
sub_frame_t current_subframe, // TBR sub_frame_t
frame_t current_frame,
frame_t *frame,
sub_frame_t *subframe){
// Fill in other TDD Configuration!!!!
// TBR missing ‘tdd_Config’ in NR_COMMON_channels_t
if (cc->tdd_Config == NULL) { // FDD
*subframe = current_subframe + 6;
if (*subframe > 9) {
*subframe = *subframe - 10;
*frame = (current_frame + 1) & 1023;
} else {
*frame = current_frame;
}
} else { // TDD
if (cc->tdd_Config->subframeAssignment == 1) {
switch (current_subframe) {
case 0:
*subframe = 7;
*frame = current_frame;
break;
case 4:
*subframe = 2;
*frame = (current_frame + 1) & 1023;
break;
case 5:
*subframe = 2;
*frame = (current_frame + 1) & 1023;
break;
case 9:
*subframe = 7;
*frame = (current_frame + 1) & 1023;
break;
}
} else if (cc->tdd_Config->subframeAssignment == 3) {
switch (current_subframe) {
case 0:
case 5:
case 6:
*subframe = 2;
*frame = (current_frame + 1) & 1023;
break;
case 7:
*subframe = 3;
*frame = (current_frame + 1) & 1023;
break;
case 8:
*subframe = 4;
*frame = (current_frame + 1) & 1023;
break;
case 9:
*subframe = 2;
*frame = (current_frame + 2) & 1023;
break;
}
} else if (cc->tdd_Config->subframeAssignment == 4) {
switch (current_subframe) {
case 0:
case 4:
case 5:
case 6:
*subframe = 2;
*frame = (current_frame + 1) & 1023;
break;
case 7:
*subframe = 3;
*frame = (current_frame + 1) & 1023;
break;
case 8:
case 9:
*subframe = 2;
*frame = (current_frame + 2) & 1023;
break;
}
} else if (cc->tdd_Config->subframeAssignment == 5) {
switch (current_subframe){
case 0:
case 4:
case 5:
case 6:
*subframe = 2;
*frame = (current_frame + 1) & 1023;
break;
case 7:
case 8:
case 9:
*subframe = 2;
*frame = (current_frame + 2) & 1023;
break;
}
}
} // else TDD
}*/
uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs){ // TBR this is outdated
uint16_t RIV;
if (Lcrbs <= (1 + (N_RB_DL >> 1))) RIV = (N_RB_DL * (Lcrbs - 1)) + RBstart;
else RIV = (N_RB_DL * (N_RB_DL + 1 - Lcrbs)) + (N_RB_DL - 1 - RBstart);
return RIV;
}
\ No newline at end of file
......@@ -28,7 +28,7 @@
* @ingroup _mac
*/
#include "LAYER2/NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_gNB/mac_proto.h"
/*
* When data are received on PHY and transmitted to MAC
......
......@@ -31,8 +31,9 @@
#ifndef __LAYER2_NR_MAC_PROTO_H__
#define __LAYER2_NR_MAC_PROTO_H__
#include "nr_mac_gNB.h"
#include "PHY/defs_gNB.h"
#include "LAYER2/NR_MAC_gNB/nr_mac_gNB.h"
#include "NR_TAG-Id.h"
void set_cset_offset(uint16_t);
......@@ -76,6 +77,61 @@ void nr_schedule_ue_spec(module_id_t module_idP, frame_t frameP, sub_frame_t slo
void schedule_nr_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP);
/////// Random Access MAC-PHY interface functions and primitives ///////
void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP);
/* \brief Function to indicate a received preamble on PRACH. It initiates the RA procedure.
@param module_idP Instance ID of gNB
@param preamble_index index of the received RA request
@param slotP Slot number on which to act
@param timing_offset Offset in samples of the received PRACH w.r.t. eNB timing. This is used to
@param rnti RA rnti corresponding to this PRACH preamble
@param rach_resource type (0=non BL/CE,1 CE level 0,2 CE level 1, 3 CE level 2,4 CE level 3)
*/
void nr_initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP,
uint16_t preamble_index, int16_t timing_offset, uint16_t rnti
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
, uint8_t rach_resource_type
#endif
);
void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP);
boolean_t nr_CCE_allocation_infeasible(int module_idP,
int CC_idP,
int common_flag,
int slot,
int aggregation,
int rnti);
int nr_allocate_CCEs(int module_idP, int CC_idP, frame_t frameP, sub_frame_t slotP, int test_only);
void nr_get_Msg3alloc(NR_COMMON_channels_t *cc,
sub_frame_t current_subframe,
frame_t current_frame,
frame_t *frame,
sub_frame_t *subframe);
/* \brief Function in gNB to fill RAR pdu when requested by PHY. This provides a single RAR SDU for the moment and returns the t-CRNTI.
@param Mod_id Instance ID of gNB
@param dlsch_buffer Pointer to DLSCH input buffer
@param N_RB_UL Number of UL resource blocks
@returns t_CRNTI
*/
unsigned short nr_fill_rar(const module_id_t module_idP,
const int CC_id,
NR_RA_t *ra,
const frame_t frameP,
uint8_t * const dlsch_buffer,
const uint16_t N_RB_UL,
const uint8_t input_buffer_length);
uint16_t nr_mac_compute_RIV(uint16_t N_RB_DL, uint16_t RBstart, uint16_t Lcrbs);
/////// Phy test scheduler ///////
void nr_schedule_css_dlsch_phytest(module_id_t module_idP,
frame_t frameP,
sub_frame_t subframeP);
......@@ -215,4 +271,42 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP,
const uint16_t sdu_lenP,
const uint16_t timing_advance, const uint8_t ul_cqi);
/* Random Access */
/* \brief Function called by PHY to retrieve information to be transmitted using the RA procedure.
If the UE is not in PUSCH mode for a particular eNB index, this is assumed to be an Msg3 and MAC
attempts to retrieves the CCCH message from RRC. If the UE is in PUSCH mode for a particular eNB
index and PUCCH format 0 (Scheduling Request) is not activated, the MAC may use this resource for
andom-access to transmit a BSR along with the C-RNTI control element (see 5.1.4 from 36.321)
@param mod_id Index of UE instance
@param CC_id Component Carrier Index
@param frame
@param gNB_id gNB index
@param nr_tti_tx slot for PRACH transmission
@returns A pointer to a PRACH_RESOURCES_t */
NR_PRACH_RESOURCES_t *nr_ue_get_rach(module_id_t mod_id,
int CC_id,
UE_MODE_t UE_mode,
frame_t frame,
uint8_t gNB_id,
int nr_tti_tx);
/* \brief Function implementing the routine for the selection of Random Access resources (5.1.2 TS 38.321).
@param module_idP Index of UE instance
@param CC_id Component Carrier Index
@param gNB_index gNB index
@param t_id
@param rach_ConfigDedicated
@returns A pointer to a PRACH_RESOURCES_t */
void nr_get_prach_resources(module_id_t mod_id,
int CC_id,
uint8_t gNB_id,
uint8_t t_id,
uint8_t first_Msg3,
NR_RACH_ConfigDedicated_t * rach_ConfigDedicated);
void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id);
#endif /*__LAYER2_NR_MAC_PROTO_H__*/
......@@ -30,8 +30,8 @@
*/
#include "mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "NR_MAC_gNB/mac_proto.h"
#include "NR_MAC_COMMON/nr_mac_extern.h"
#include "assertions.h"
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
......
......@@ -42,30 +42,95 @@
#include <stdlib.h>
#include <string.h>
/* Commmon */
#include "targets/ARCH/COMMON/common_lib.h"
#include "COMMON/platform_constants.h"
#include "common/ran_context.h"
/* RRC */
#include "NR_BCCH-BCH-Message.h"
#include "NR_CellGroupConfig.h"
#include "NR_ServingCellConfigCommon.h"
#include "NR_MeasConfig.h"
/* PHY */
#include "PHY/defs_gNB.h"
#include "PHY/TOOLS/time_meas.h"
/* Interface */
#include "nfapi_nr_interface_scf.h"
#include "NR_PHY_INTERFACE/NR_IF_Module.h"
#include "COMMON/platform_constants.h"
#include "common/ran_context.h"
/* MAC */
#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h"
#include "PHY/defs_gNB.h"
#include "PHY/TOOLS/time_meas.h"
#include "targets/ARCH/COMMON/common_lib.h"
#include "nr_mac_common.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac_common.h"
#include "NR_TAG.h"
/* Defs */
#define MAX_NUM_BWP 2
#define MAX_NUM_CORESET 2
#define MAX_NUM_CCE 90
/*!\brief Maximum number of random access process */
#define NR_NB_RA_PROC_MAX 4
#include "NR_TAG.h"
/*! \brief gNB template for the Random access information */
typedef struct {
/// Flag to indicate this process is active
RA_state_t state;
/// Subframe where preamble was received
uint8_t preamble_subframe;
/// Subframe where Msg2 is to be sent
uint8_t Msg2_subframe;
/// Frame where Msg2 is to be sent
frame_t Msg2_frame;
/// Subframe where Msg3 is to be sent
sub_frame_t Msg3_subframe;
/// Frame where Msg3 is to be sent
frame_t Msg3_frame;
/// Subframe where Msg4 is to be sent
sub_frame_t Msg4_subframe;
/// Frame where Msg4 is to be sent
frame_t Msg4_frame;
/// harq_pid used for Msg4 transmission
uint8_t harq_pid;
/// UE RNTI allocated during RAR
rnti_t rnti;
/// RA RNTI allocated from received PRACH
uint16_t RA_rnti;
/// Received preamble_index
uint8_t preamble_index;
/// Received UE Contention Resolution Identifier
uint8_t cont_res_id[6];
/// Timing offset indicated by PHY
int16_t timing_offset;
/// Timeout for RRC connection
int16_t RRC_timer;
/// Msg3 first RB
uint8_t msg3_first_rb;
/// Msg3 number of RB
uint8_t msg3_nb_rb;
/// Msg3 MCS
uint8_t msg3_mcs;
/// Msg3 TPC command
uint8_t msg3_TPC;
/// Msg3 ULdelay command
uint8_t msg3_ULdelay;
/// Msg3 cqireq command
uint8_t msg3_cqireq;
/// Round of Msg3 HARQ
uint8_t msg3_round;
/// TBS used for Msg4
int msg4_TBsize;
/// MCS used for Msg4
int msg4_mcs;
///
int32_t crnti_rrc_mui; // TBR
///
int8_t crnti_harq_pid; // TBR
} NR_RA_t;
/*! \brief gNB common channels */
typedef struct {
......@@ -93,7 +158,7 @@ typedef struct {
/// Outgoing RAR pdu for PHY
RAR_PDU RAR_pdu;
/// Template for RA computations
RA_t ra[NB_RA_PROC_MAX];
NR_RA_t ra[NR_NB_RA_PROC_MAX];
/// VRB map for common channels
uint8_t vrb_map[100];
/// VRB map for common channels and retransmissions by PHICH
......@@ -107,9 +172,8 @@ typedef struct {
int dummy;
} NR_UE_sched_ctrl_t;
/*! \brief UE list used by eNB to order UEs/CC for scheduling*/
/*! \brief UE list used by gNB to order UEs/CC for scheduling*/
typedef struct {
DLSCH_PDU DLSCH_pdu[4][MAX_MOBILES_PER_GNB];
/// scheduling control info
UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB];
......@@ -192,66 +256,63 @@ typedef struct gNB_MAC_INST_s {
typedef struct {
uint8_t format_indicator; //1 bit
uint16_t frequency_domain_assignment; //up to 16 bits
uint8_t time_domain_assignment; // 4 bits
uint8_t frequency_hopping_flag; //1 bit
uint8_t ra_preamble_index; //6 bits
uint8_t ss_pbch_index; //6 bits
uint8_t prach_mask_index; //4 bits
uint8_t vrb_to_prb_mapping; //0 or 1 bit
uint8_t mcs; //5 bits
uint8_t ndi; //1 bit
uint8_t rv; //2 bits
uint8_t harq_pid; //4 bits
uint8_t dai; //0, 2 or 4 bits
uint8_t dai1; //1 or 2 bits
uint8_t dai2; //0 or 2 bits
uint8_t tpc; //2 bits
uint8_t pucch_resource_indicator; //3 bits
uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits
uint8_t short_messages_indicator; //2 bits
uint8_t short_messages; //8 bits
uint8_t tb_scaling; //2 bits
uint8_t carrier_indicator; //0 or 3 bits
uint8_t bwp_indicator; //0, 1 or 2 bits
uint8_t prb_bundling_size_indicator; //0 or 1 bits
uint8_t rate_matching_indicator; //0, 1 or 2 bits
uint8_t zp_csi_rs_trigger; //0, 1 or 2 bits
uint8_t transmission_configuration_indication; //0 or 3 bits
uint8_t srs_request; //2 bits
uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits
uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit
uint8_t dmrs_sequence_initialization; //0 or 1 bit
uint8_t srs_resource_indicator;
uint8_t precoding_information;
uint8_t csi_request;
uint8_t ptrs_dmrs_association;
uint8_t beta_offset_indicator; //0 or 2 bits
uint8_t slot_format_indicator_count;
uint8_t *slot_format_indicators;
uint8_t pre_emption_indication_count;
uint16_t *pre_emption_indications; //14 bit
uint8_t block_number_count;
uint8_t *block_numbers;
uint8_t ul_sul_indicator; //0 or 1 bit
uint8_t antenna_ports;
uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
uint16_t padding;
uint8_t format_indicator; //1 bit
uint16_t frequency_domain_assignment; //up to 16 bits
uint8_t time_domain_assignment; // 4 bits
uint8_t frequency_hopping_flag; //1 bit
uint8_t ra_preamble_index; //6 bits
uint8_t ss_pbch_index; //6 bits
uint8_t prach_mask_index; //4 bits
uint8_t vrb_to_prb_mapping; //0 or 1 bit
uint8_t mcs; //5 bits
uint8_t ndi; //1 bit
uint8_t rv; //2 bits
uint8_t harq_pid; //4 bits
uint8_t dai; //0, 2 or 4 bits
uint8_t dai1; //1 or 2 bits
uint8_t dai2; //0 or 2 bits
uint8_t tpc; //2 bits
uint8_t pucch_resource_indicator; //3 bits
uint8_t pdsch_to_harq_feedback_timing_indicator; //0, 1, 2 or 3 bits
uint8_t short_messages_indicator; //2 bits
uint8_t short_messages; //8 bits
uint8_t tb_scaling; //2 bits
uint8_t carrier_indicator; //0 or 3 bits
uint8_t bwp_indicator; //0, 1 or 2 bits
uint8_t prb_bundling_size_indicator; //0 or 1 bits
uint8_t rate_matching_indicator; //0, 1 or 2 bits
uint8_t zp_csi_rs_trigger; //0, 1 or 2 bits
uint8_t transmission_configuration_indication; //0 or 3 bits
uint8_t srs_request; //2 bits
uint8_t cbgti; //CBG Transmission Information: 0, 2, 4, 6 or 8 bits
uint8_t cbgfi; //CBG Flushing Out Information: 0 or 1 bit
uint8_t dmrs_sequence_initialization; //0 or 1 bit
uint8_t srs_resource_indicator;
uint8_t precoding_information;
uint8_t csi_request;
uint8_t ptrs_dmrs_association;
uint8_t beta_offset_indicator; //0 or 2 bits
uint8_t slot_format_indicator_count;
uint8_t *slot_format_indicators;
uint8_t pre_emption_indication_count;
uint16_t *pre_emption_indications; //14 bit
uint8_t block_number_count;
uint8_t *block_numbers;
uint8_t ul_sul_indicator; //0 or 1 bit
uint8_t antenna_ports;
uint16_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits
uint16_t padding;
} dci_pdu_rel15_t;
#endif /*__LAYER2_NR_MAC_GNB_H__ */
......@@ -57,24 +57,19 @@ void handle_nr_rach(NR_UL_IND_t *UL_info) {
AssertFatal(UL_info->rach_ind.rach_indication_body.number_of_preambles==1,"More than 1 preamble not supported\n");
UL_info->rach_ind.rach_indication_body.number_of_preambles=0;
LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SF:%d\n",UL_info->frame,UL_info->slot, NFAPI_SFNSF2DEC(UL_info->rach_ind.sfn_sf));
/*
initiate_ra_proc(UL_info->module_id,
nr_initiate_ra_proc(UL_info->module_id,
UL_info->CC_id,
NFAPI_SFNSF2SFN(UL_info->rach_ind.sfn_sf),
NFAPI_SFNSF2SF(UL_info->rach_ind.sfn_sf),
UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble,
UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance,
UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti
#if (NR_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) || (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
//#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // TBR
,0
#endif
#endif
);
*/
}
}
void handle_nr_sr(NR_UL_IND_t *UL_info) {
......
......@@ -32,9 +32,9 @@
#include "PHY/defs_nr_UE.h"
#include "NR_IF_Module.h"
#include "mac_proto.h"
#include "NR_MAC_UE/mac_proto.h"
#include "assertions.h"
#include "LAYER2/NR_MAC_UE/mac_extern.h"
#include "NR_MAC_UE/mac_extern.h"
#include "SCHED_NR_UE/fapi_nr_ue_l1.h"
#include "executables/nr-softmodem.h"
......@@ -93,6 +93,14 @@ int8_t handle_dlsch (module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_n
*/
}
int8_t handle_rar (module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, uint8_t *pduP, uint32_t pdu_len, frame_t frame, int slot, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment){
if (IS_SOFTMODEM_NOS1 || IS_SOFTMODEM_RFSIM)
//nr_process_rar(ue,proc, gNB_index, mode); TBR
return 0;
}
int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){
NR_UE_L2_STATE_t ret;
......@@ -249,17 +257,17 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_
dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH;
dl_config->number_pdus = dl_config->number_pdus + 1;
*/
/*ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind,
dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu,
dl_info->rx_ind->rx_indication_body[i].pdsch_pdu.pdu_length, dl_info->frame, dl_info->slot)) << FAPI_NR_RX_PDU_TYPE_DLSCH;
*/
break;
default:
case FAPI_NR_RX_PDU_TYPE_RAR:
/*ret_mask |= (handle_rar(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind,
(dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu,
(dl_info->rx_ind->rx_indication_body+i)->pdsch_pdu.pdu_length,
dl_info->frame, dl_info->slot,ul_time_alignment)) << FAPI_NR_RX_PDU_TYPE_RAR;*/ //TODO TBR
break;
default:
break;
}
}
}
......
......@@ -53,8 +53,7 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
uint8_t *const buffer_pP ){
asn_enc_rval_t enc_rval;
//SRB_INFO *Srb_info;
//uint8_t Sdu_size = 0;
uint8_t Sdu_size = 0;
uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f);
#ifdef DEBUG_RRC
......@@ -64,11 +63,15 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
gNB_RRC_INST *rrc;
rrc_gNB_carrier_data_t *carrier;
NR_BCCH_BCH_Message_t *mib;
NR_SRB_INFO * srb_info;
char payload_size, payload_pP;
rrc = RC.nrrrc[Mod_idP];
carrier = &rrc->carrier;
mib = &carrier->mib;
srb_info = &carrier->Srb0;
/* MIBCH */
if( (Srb_id & RAB_OFFSET ) == MIBCH) {
mib->message.choice.mib->systemFrameNumber.buf[0] = sfn_msb << 2;
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_BCCH_BCH_Message,
......@@ -86,9 +89,30 @@ int8_t mac_rrc_nr_data_req(const module_id_t Mod_idP,
return(3);
}
//BCCH SIB1 SIBs
/* TODO BCCH SIB1 SIBs */
//CCCH
/* CCCH */ // TBR lte code
if( (Srb_id & RAB_OFFSET ) == CCCH) {
//struct rrc_eNB_ue_context_s *ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP],rnti);
//if (ue_context_p == NULL) return(0);
//eNB_RRC_UE_t *ue_p = &ue_context_p->ue_context;
LOG_D(RRC,"[gNB %d] Frame %d CCCH request (Srb_id %d)\n", Mod_idP, frameP, Srb_id);
// srb_info=&ue_p->Srb0;
payload_size = srb_info->Tx_buffer.payload_size;
// check if data is there for MAC
if (payload_size > 0) {
payload_pP = srb_info->Tx_buffer.Payload;
LOG_D(RRC,"[gNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n", Mod_idP, srb_info, payload_size, buffer_pP, payload_pP);
// Fill buffer
memcpy(buffer_pP, payload_pP, payload_size);
Sdu_size = payload_size;
srb_info->Tx_buffer.payload_size = 0;
}
return Sdu_size;
}
return(0);
......
......@@ -42,7 +42,7 @@
#include "rrc_defs.h"
#include "rrc_proto.h"
#include "rrc_vars.h"
#include "mac_proto.h"
#include "LAYER2/NR_MAC_UE/mac_proto.h"
extern int phy_test;
......
......@@ -39,8 +39,8 @@
#include "platform_types.h"
#include "LAYER2/NR_MAC_UE/mac.h"
#include "LAYER2/NR_MAC_COMMON/nr_mac.h"
#include "NR_MAC_UE/mac.h"
#include "NR_MAC_COMMON/nr_mac.h"
#include "rrc_list.h"
#include "NR_asn_constant.h"
#include "NR_MeasConfig.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment