diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index b84ffd38a0a18f6729e9299e9ea8d0bd590f017f..76f2a485eab0ec00e54371ed1870537cec32ab60 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -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}) diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 0302697e5b7d70350128368ae8b30b3ee6349f94..dedee9b651a46641eb5953ff91bc78e8314d6915 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -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" diff --git a/executables/nr-ru.c b/executables/nr-ru.c index 42d7a2a48a094e85a4de018e97519504be900043..1e6ae12e0957a4d5e64414d57d7546141576c99b 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -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" diff --git a/executables/nr-ue.c b/executables/nr-ue.c index d8eda68d05fd15d08fa8c50e814a28addcbd0595..bbdcd0c29c62928a6187862e86f1771f8ad8b9b1 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -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 diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index fb0f18f2f50134bc2978e1e83617fdb019da7d08..e2f32529a174c34f3dc8c17d13122ae933f72a38 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -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> diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 891b97514c2bc51e51c0369e6df1916b0eee576b..3438f31373f193117ee53f5dac00773577a78a3a 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.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 diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h index cbcd26c3e352ba2c9679dbbf4c2f55319577a3ab..4b0720078a8b3d399db718ffb9111f238f0c02ab 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_constants.h @@ -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 diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index df9747104a196f1b0b6829c5e78ce3334cf2030e..3c93442c8d691430240c7318bb54943e8db96e4a 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -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" /* diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c index e1b80a87a2f16e0d279997e3d512c4caa92366db..82ad498c2a62a64a49118bf074b0c40c83869796 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c @@ -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%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); - } else { - return(0); - } - */ + 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; + } else { + 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); - } else { - return(0); + 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; + } else { + return 0; + } } /* // For FR2: FIXME diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index 68b9e44d63b21af50aa36dceae69a02b116d05db..af06f9a98f3d69eea929221af3aac45852b4575b 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -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 diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index a98820b69cb4c6d940f8252b9756da8b06b90024..1e46cde82eec1ef2019fc519995a99cb6d0f7c8d 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -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 ) { diff --git a/openair1/PHY/TOOLS/nr_phy_scope.h b/openair1/PHY/TOOLS/nr_phy_scope.h index aaee08a554bf9fe27c8ce5742531f3d4c29e1bd6..4877b93007ccc6a10f1be9e07f7a303daeb1b8f8 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.h +++ b/openair1/PHY/TOOLS/nr_phy_scope.h @@ -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> diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 1ad0c7529e28129617409a9a9494c4ade586ea60..e88bfd77689d55ad5e085d4610d7a98cb74ebf3e 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.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) diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index 487b28473ffc497c96a9cfd35a47902444333e2d..5241f5736d53a71751752d873c271f9df6cc5749 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -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; diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index e34ce2b6debc06071e09fc363ce3ea274160c45b..c6aea2ec08d317645a51d379d86a5494acbf0d8c 100644 --- a/openair1/SCHED_NR_UE/defs.h +++ b/openair1/SCHED_NR_UE/defs.h @@ -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 diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index c6a830a8da9f1ec365a4a49cfe528a45b05e9cf9..7dbb68cf3183dac930e16ac9df0a381854e95cea 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -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]; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index e8e3ac66eefddcb927ef53f847cecd3b7a267e90..5a292661fde14021abbcc348ec6ae938487b04ec 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -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,13 +3350,13 @@ 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; + 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); - //mac_xface->macphy_exit("prach_resources is NULL"); - return; + 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 - rx_ind.rx_indication_body[0].pdu_type = FAPI_NR_RX_PDU_TYPE_DLSCH; + 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); @@ -4367,11 +4185,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); nr_ue_pdsch_procedures(ue, - proc, - eNB_id, - SI_PDSCH, - ue->dlsch_SI[eNB_id], - NULL); + proc, + eNB_id, + SI_PDSCH, + ue->dlsch_SI[eNB_id], + NULL); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT); } @@ -4380,11 +4198,11 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN); nr_ue_pdsch_procedures(ue, - proc, - eNB_id, - P_PDSCH, - ue->dlsch_p[eNB_id], - NULL); + proc, + eNB_id, + P_PDSCH, + ue->dlsch_p[eNB_id], + NULL); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT); } @@ -4393,13 +4211,37 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue, if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN); nr_ue_pdsch_procedures(ue, - proc, - eNB_id, - RA_PDSCH, - ue->dlsch_ra[eNB_id], - NULL); + proc, + eNB_id, + RA_PDSCH, + ue->dlsch_ra[eNB_id], + NULL); + + // #if UE_TIMING_TRACE + // start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); + // #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); + 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); } // do procedures for C-RNTI @@ -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 diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 326c617dfb5413cffabd52a6b957a2c9574f1aa7..eb2ce3598f2589eeddff6e96763884daf37db758 100644 --- a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c @@ -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 diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 473c86bed02d530011a56a73b695d45da10f129f..cc3517215e7ab75a31a10a770198e157e1c4e957 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -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" diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 33c00e82f4786cab2d21153d7de0e67ef3f418de..fac5d599c8a46e2de03d84e908e0e9f572bd731d 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -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); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 2c397090bae1493c0487b577fe0e3af65d2d4d18..e53e28860253a2bb4e2216b7dd3f41a3bb52f93f 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -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 diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 9845adbeaa59844ce2da1faeaab8a9c9ea432b8b..1c8657aec10b8c48d98ce3fc31fcce1a79c4fd5c 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -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" diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 8d497c80d36505c7fb87b5e2ccc840b360163580..433a490c195fa49e71bc2989e123dc463d7a7294 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -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" diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 7202f2e5203bfd6a3af5e21b80df0416e4ca2648..bbccb9f707728bc04ec866e9b54970509772a65a 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.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 diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h similarity index 98% rename from openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h rename to openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 6b043963b01816d9e710fa50522814bea7081fbc..1891bd0ee98287579a1ed3500b9054f79247de06 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -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); diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h index 10df4567c41608f09c12820805872a27f630b595..4bc462f759ffc7b2a9de6ee5bd8e237ebfed3114 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h @@ -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 diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index c98302303496300fc9921f44b30f21c76c279124..6250b53dd3032fe630a67d2c39aa0b6a2d965a3f 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -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, diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 37d1b1216dc766e96a02e3b37143f069b9dd42f4..ef733020e00d26d09f5e17e4ae628af8ab6cee29 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -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 { @@ -76,13 +81,13 @@ typedef struct { NR_ServingCellConfig_t *scd; int servCellIndex; //// MAC config - NR_DRX_Config_t *drx_Config; + NR_DRX_Config_t *drx_Config; NR_SchedulingRequestConfig_t *schedulingRequestConfig; - NR_BSR_Config_t *bsr_Config; - NR_TAG_Config_t *tag_Config; - NR_PHR_Config_t *phr_Config; - NR_RNTI_Value_t *cs_RNTI; - NR_MIB_t *mib; + NR_BSR_Config_t *bsr_Config; + NR_TAG_Config_t *tag_Config; + NR_PHR_Config_t *phr_Config; + NR_RNTI_Value_t *cs_RNTI; + NR_MIB_t *mib; NR_BWP_Downlink_t *DLbwp[MAX_NUM_BWP]; NR_BWP_Uplink_t *ULbwp[MAX_NUM_BWP]; @@ -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; - /// state of RA procedure - RA_state_t ra_state; - /// RA-rnti - uint16_t ra_rnti; - /// Temporary CRNTI - uint16_t t_crnti; - /// CRNTI - uint16_t crnti; + /* PDUs */ + /// Outgoing CCCH pdu for PHY + CCCH_PDU CCCH_pdu; + + /* Random Access parameters */ + /// state of RA procedure + RA_state_t ra_state; // TBR + /// RACH ConfigCommon + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon; + /// RA-rnti + uint16_t ra_rnti; // TBR + /// Temporary CRNTI + uint16_t t_crnti; // TBR + /// 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; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index 36d285e320e416c7f14d3f0694e01322d6ddc6c7..061b1fa3995600c22e0bf37ea40901dc90fe6f79 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -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 /** @}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index be1e85236087a4a84e3827dcba529f345480fc52..c057f5ee022bf69e4d82fa5b94d2bd98c058188d 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -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; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c new file mode 100644 index 0000000000000000000000000000000000000000..85c8cf893522b1084afe7ee8ba84b610c2f18b15 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c @@ -0,0 +1,155 @@ +/* + * 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 diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c new file mode 100644 index 0000000000000000000000000000000000000000..501f96b7717f0db69ed4e6140a6839fb248aede4 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -0,0 +1,726 @@ +/* + * 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 diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 55ac0953989d135b687447dc5ecd142d9fe7f93f..e192bfb232d8bbd10206d2b6b2d93bde84290de0 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -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 diff --git a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c new file mode 100644 index 0000000000000000000000000000000000000000..bd7e96eda5989e640b08415e89f1a6f615094f68 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c @@ -0,0 +1,157 @@ +/* + * 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; +} diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index c911fbd56a6c6aa5d53048131067815e014b4d0b..6f9f04c108211619b25db474df0697a221a5c6fe 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -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); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index ace9551d2f4ba603053b4086d4007b1bba3f42d6..5e7ad3848e94aa86c8082f8ac08f48419ce2056c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -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; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index d74df15eac813bb1137cf299a3c06c25d307684d..f98aebfb0d1ec3205cb7bfd8f88c92bf3bf62323 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -19,44 +19,541 @@ * contact@openairinterface.org */ -/*! \file gNB_scheduler_RA.c - * \brief primitives used for random access - * \author - * \date - * \email: +/*! \file gNB_scheduler_RA.c + * \brief primitives used for random access + * \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; + + /*#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; + + 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)) */ + + 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*/ + + + + /*#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); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + 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 - for (i = 0; i < NB_RA_PROC_MAX; i++) { + /* Timing Advance Command */ + // TBR double check + //ra->timing_offset = 0; + //printf("ra->timing_offset %d\n", ra->timing_offset); // TBR remove - ra = (RA_t *) & cc[CC_id].ra[i]; - //LOG_D(MAC,"RA[state:%d]\n",ra->state); + 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 - 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); + // 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 - } // for i=0 .. N_RA_PROC-1 - } // CC_id + /* 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 - stop_meas(&mac->schedule_ra); + 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 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 9555e1d046abf25ead70053a7eb6fc11d24f0e29..024496c3d07410ad6e04f0a9ba105ee248921e6c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c @@ -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" diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c index 52332701499d2868dc5c7c5cd13298439eb634d4..2999f4d8eeb6d4136c2be2fa36d570f18c4395ee 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c @@ -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 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 55a73851438876408e184ec048871dbd00758c67..68f1021c68160ce07ef5f2a602fda2c03630bd72 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -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" diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index 9a9bfa0164c21d787c79008459e9ad0ac121f8fb..a94934c4329bfb4cc042963eb361fc43d2c472da 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -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" @@ -1363,4 +1363,177 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ } } } -*/ \ No newline at end of file +*/ + +/* 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 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 4ae679b8f564173e3954d29e2aa09d921731345b..604664f3efd1aa6a7be6bd515309970a1b092ee9 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -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 diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index e0932e28e1bbfa69aa9cdbd4057dbcbf4fef8c68..c2ca2dc1fe914c6b847c1ce520c9ba4224ca3a5d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -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__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index ff552d0bfd597a96b02f4fd3eeb0518857be5bd5..775116faf684188e785736296851fc3346bdff34 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -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" diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 5bc320d5e2ee67ec8d0e76e12fb5f07d3b4b716f..ad92fdb979a8359d0ce8969b24771bf38a6dfaa7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.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__ */ diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 770e27dd608b5c4063c514e0f20400e3e332c2c6..60629958415e8e5d914ccb883dac392eb50e416b 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -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, - - 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)) - ,0 -#endif - ); - */ + 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 (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // TBR + ,0 + #endif + ); } - } void handle_nr_sr(NR_UL_IND_t *UL_info) { diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 4e6c0d8979b2980604f692967bfd4672807d6491..3ac9a8a43ffc7ff805f67124b0e938da148e902b 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -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; @@ -231,11 +239,11 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ dl_info->rx_ind->rx_indication_body[i].mib_pdu.cell_id )) << FAPI_NR_RX_PDU_TYPE_MIB;*/ break; case FAPI_NR_RX_PDU_TYPE_SIB: - ret_mask |= (handle_bcch_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, - (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.sibs_mask, - (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu, - (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu_length )) << FAPI_NR_RX_PDU_TYPE_SIB; - break; + ret_mask |= (handle_bcch_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, + (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.sibs_mask, + (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu, + (dl_info->rx_ind->rx_indication_body+i)->sib_pdu.pdu_length )) << FAPI_NR_RX_PDU_TYPE_SIB; + break; case FAPI_NR_RX_PDU_TYPE_DLSCH: // ret_mask |= (0) << FAPI_NR_RX_PDU_TYPE_DLSCH; ret_mask |= (handle_dlsch(dl_info->module_id, dl_info->cc_id, dl_info->gNB_index, dl_info->dci_ind, @@ -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; */ + break; - /*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; + 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; - */ - break; default: - - break; - + break; } } } diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index fb1ed160cb8b674e46a0656da07080c2dcbec59f..8b2966e0c5059d8b815f1262b58bd7aae72cc7ef 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -53,9 +53,8 @@ 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 sfn_msb = (uint8_t)((frameP>>4)&0x3f); + uint8_t Sdu_size = 0; + uint8_t sfn_msb = (uint8_t)((frameP>>4)&0x3f); #ifdef DEBUG_RRC LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%ld\n",Mod_idP,Srb_id); @@ -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,10 +89,31 @@ 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); -} +} \ No newline at end of file diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index 38163a68b81512457931c755f6f22ab978fdd2b4..862cf48cec6259a8fa635fc15dde7b3005d4aab6 100755 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -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; diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index cb1207757dc5618ebc14779a8d6bfd62c18bd026..6481fb0cea266492f0d35ef86f40f0e7769feb05 100644 --- a/openair2/RRC/NR_UE/rrc_defs.h +++ b/openair2/RRC/NR_UE/rrc_defs.h @@ -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"