diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index 9d6349077f..3fa91b862c 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -186,7 +186,7 @@ function variant__v3__phy_sim { BUILD_OPTIONS="--phy_simulators" VM_MEMORY=8192 VM_DISK=20 - RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111\" -q -np -b" + RUN_OPTIONS="./run_exec_autotests.bash -g \"01510* 015111 015112\" -q -np -b" } function variant__v4__cppcheck { diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index f6fcabf82e..ebd6f88fc2 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1624,7 +1624,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) @@ -1775,14 +1775,15 @@ 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 ) @@ -1794,7 +1795,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 @@ -1804,6 +1804,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 @@ -1867,7 +1870,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}"") @@ -1895,6 +1898,19 @@ set (GTPV1U_SRC add_library(GTPV1U ${GTPV1U_SRC}) add_dependencies(GTPV1U rrc_flag) +#NR case +set (NR_GTPV1U_SRC + ${NR_RRC_DIR}/rrc_gNB_GTPV1U.c + ${RRC_DIR}/rrc_eNB_GTPV1U.c + ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTunnelEndPoint.c + ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uTrxn.c + ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1uMsg.c + ${GTPV1U_DIR}/nw-gtpv1u/src/NwGtpv1u.c + ${GTPV1U_DIR}/gtpv1u_teid_pool.c +) +add_library(NR_GTPV1U ${NR_GTPV1U_SRC}) +add_dependencies(NR_GTPV1U rrc_flag) + set (MME_APP_SRC ${OPENAIR3_DIR}/MME_APP/mme_app.c ${OPENAIR3_DIR}/MME_APP/mme_config.c @@ -2605,6 +2621,7 @@ add_executable(nr-softmodem ${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c ${OPENAIR2_DIR}/RRC/NAS/nas_config.c ${OPENAIR2_DIR}/RRC/NAS/rb_config.c + ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_gNB.c ${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c @@ -2618,7 +2635,7 @@ add_executable(nr-softmodem target_link_libraries (nr-softmodem -Wl,--start-group - UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA + UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS NR_GTPV1U SECU_CN SECU_OSA ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} LFDS7 ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB L2 L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB ${PROTO_AGENT_LIB} ${FSPT_MSG_LIB} @@ -2662,9 +2679,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}) @@ -2821,7 +2838,7 @@ add_executable(nr_prachsim ${T_SOURCE} ${SHLIB_LOADER_SOURCES}) target_link_libraries(nr_prachsim - -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) + -Wl,--start-group UTIL SIMU PHY_COMMON PHY_NR_COMMON PHY_NR PHY_RU PHY_NR_UE MAC_NR_COMMON SCHED_NR_LIB MAC_UE_NR SCHED_NR_UE_LIB RRC_LIB NR_RRC_LIB L2_NR CONFIG_LIB -Wl,--end-group m pthread ${ATLAS_LIBRARIES} ${T_LIB} ${ITTI_LIB} dl) add_executable(nr_ulschsim ${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c diff --git a/cmake_targets/autotests/README.txt b/cmake_targets/autotests/README.txt index 10c14fd59a..19a333c626 100644 --- a/cmake_targets/autotests/README.txt +++ b/cmake_targets/autotests/README.txt @@ -142,10 +142,14 @@ Obj.# Case# Test# Description (Test 11: 10 MHz, R7.FDD (MCS 25), EVA5, 17.7dB (70%)) (TM2 Test 1 10 MHz, R.11 FDD (MCS 14), EVA5, 6.8 dB (70%)), (TM2 Test 1b 20 MHz, R.11-2 FDD (MCS 13), EVA5, 5.9 dB (70%)), -01 51 11 nr_ulsim Test cases. (Test1: MCS 9), - (Test2: MCS 16), - (Test3: MCS 28) - +01 51 11 nr_ulsim Test cases. (Test1: MCS 9 106 PRBs), + (Test2: MCS 16 50 PRBs), + (Test3: MCS 28 50 PRBs), + (Test4: MCS 9 217 PRBs), + (Test5: MCS 9 273 PRBs) +01 51 12 nr_prachsim Test cases.(Test1: 106 PRBs), + (Test2: 217 PRBs), + (Test3: 273 PRBs) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index 7908772bb6..d5c20ffdc6 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -1104,9 +1104,8 @@ -n100 -R217 -a80 -s5 -n100 -R217 -a110 -s5 -b100 -n100 -e27 -s30 - -n100 -e16 -s10 - - nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 + -n100 -e16 -s10 + nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 PDSCH test OK segmentation fault|assertion|exiting|fatal 3 @@ -1245,17 +1244,37 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash $OPENAIR_DIR/targets/bin/nr_ulsim.Rel15 - -n100 -m9 -r106 -s0 + -n100 -m9 -r106 -s5 -n100 -m16 -s10 -n100 -m28 -s20 - -n100 -m9 -R217 -r217 -s0 - -n100 -m9 -R273 -r273 -s0 + -n100 -m9 -R217 -r217 -s5 + -n100 -m9 -R273 -r273 -s5 nr_ulsim.test1 nr_ulsim.test2 nr_ulsim.test3 nr_ulsim.test4 nr_ulsim.test5 PUSCH test OK segmentation fault|assertion|exiting|fatal 3 + + execution + nr_prachsim Test cases. (Test1: 106 PRBs), + (Test2: 217 PRBs), + (Test3: 273 PRBs) + + $OPENAIR_DIR/cmake_targets/build_oai + --phy_simulators -c + $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash + + $OPENAIR_DIR/targets/bin/nr_prachsim.Rel15 + -a -s -30 -n 100 -p 16 -R 106 + -a -s -30 -n 100 -p 16 -R 217 + -a -s -30 -n 100 -p 16 -R 273 + nr_prachsim.test1 nr_prachsim.test2 nr_prachsim.test3 + PRACH test OK + segmentation fault|assertion|exiting|fatal + 3 + + lte-softmodem diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index 8a236c49f9..5f07fc00aa 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -52,6 +52,7 @@ int NRRIV2PRBOFFSET(int locationAndBandwidth,int N_RB) { else return(N_RB-1-tmp2); } +/* TS 38.214 ch. 6.1.2.2.2 - Resource allocation type 1 for DL and UL */ int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize) { AssertFatal(NPRB>0 && (NPRB + RBstart <= BWPsize),"Illegal NPRB/RBstart Configuration (%d,%d) for BWPsize %d\n",NPRB,RBstart,BWPsize); @@ -62,14 +63,21 @@ int PRBalloc_to_locationandbandwidth0(int NPRB,int RBstart,int BWPsize) { int PRBalloc_to_locationandbandwidth(int NPRB,int RBstart) { return(PRBalloc_to_locationandbandwidth0(NPRB,RBstart,275)); } + /// Target code rate tables indexed by Imcs +/* TS 38.214 table 5.1.3.1-1 - MCS index table 1 for PDSCH */ uint16_t nr_target_code_rate_table1[29] = {120, 157, 193, 251, 308, 379, 449, 526, 602, 679, 340, 378, 434, 490, 553, \ 616, 658, 438, 466, 517, 567, 616, 666, 719, 772, 822, 873, 910, 948}; - // Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point + +/* TS 38.214 table 5.1.3.1-2 - MCS index table 2 for PDSCH */ +// Imcs values 20 and 26 have been multiplied by 2 to avoid the floating point uint16_t nr_target_code_rate_table2[28] = {120, 193, 308, 449, 602, 378, 434, 490, 553, 616, 658, 466, 517, 567, \ 616, 666, 719, 772, 822, 873, 1365, 711, 754, 797, 841, 885, 1833, 948}; + +/* TS 38.214 table 5.1.3.1-3 - MCS index table 3 for PDSCH */ uint16_t nr_target_code_rate_table3[29] = {30, 40, 50, 64, 78, 99, 120, 157, 193, 251, 308, 379, 449, 526, 602, 340, \ 378, 434, 490, 553, 616, 438, 466, 517, 567, 616, 666, 719, 772}; + uint16_t nr_tbs_table[93] = {24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 160, 168, 176, 184, 192, 208, 224, 240, 256, 272, 288, 304, 320, \ 336, 352, 368, 384, 408, 432, 456, 480, 504, 528, 552, 576, 608, 640, 672, 704, 736, 768, 808, 848, 888, 928, 984, 1032, 1064, 1128, 1160, 1192, 1224, 1256, \ 1288, 1320, 1352, 1416, 1480, 1544, 1608, 1672, 1736, 1800, 1864, 1928, 2024, 2088, 2152, 2216, 2280, 2408, 2472, 2536, 2600, 2664, 2728, 2792, 2856, 2976, \ diff --git a/common/utils/ocp_itti/intertask_interface.h b/common/utils/ocp_itti/intertask_interface.h index 52c733752d..ae51f7ff42 100644 --- a/common/utils/ocp_itti/intertask_interface.h +++ b/common/utils/ocp_itti/intertask_interface.h @@ -237,6 +237,7 @@ typedef struct IttiMsgText_s { //#include #include +#include void *rrc_enb_process_itti_msg(void *); #include #include diff --git a/doc/RUNMODEM.md b/doc/RUNMODEM.md index 0c66b58547..70074c65ed 100644 --- a/doc/RUNMODEM.md +++ b/doc/RUNMODEM.md @@ -56,9 +56,48 @@ oai supports [number of deployment](FEATURE_SET.md) model, the following are tes 1. [Monolithic eNodeB](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/HowToConnectCOTSUEwithOAIeNBNew) where the whole signal processing is performed in a single process 2. if4p5 mode, where frequency domain samples are carried over ethernet, from the RRU which implement part of L1(FFT,IFFT,part of PRACH), to a RAU +# 5G NR + +As of February 2020, all 5G NR development is part of the develop branch (the branch develop-nr is no longer maintained). This also means that all new development will be merged into there once it passes all the CI. + +## NSA setup with COTS UE + +This setup requires an EPC, an OAI eNB and gNB, and a COTS Phone. A dedicated page describe the setup can be found [here](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home/gNB-COTS-UE-testing). + +### Launch gNB + +```bash sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf``` + +### Launch eNB + +```bash sudo ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf +## phy-test setup with OAI UE + +The OAI UE can also be used in front of a OAI gNB without the support of eNB or EPC. In this case both gNB and eNB need to be run with the --phy-test flag. At the gNB this flag does the following + - it reads the RRC configuration from the configuration file + - it encodes the RRCConfiguration and the RBconfig message and stores them in the binary files rbconfig.raw and reconfig.raw + - the MAC uses a pre-configured allocation of PDSCH and PUSCH with randomly generated payload + +At the UE the --phy-test flag will + - read the binary files rbconfig.raw and reconfig.raw from the current directory (a different directory can be specified with the flag --rrc_config_path) and process them. + + +### Launch gNB + +```bash sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --phy-test``` + +### Launch UE in another window + +```bash sudo ./nr-uesoftmodem --phy-test [--rrc_config_path ../../../ci-scripts/rrc-files]``` + +## noS1 setup with OAI UE + +Instead of randomly generated payload, in the phy-test mode we can also inject/receive user-plane traffic over a TUN interface. This is the so-called noS1 mode. + +This setup is described in the [rfsimulator page](../targets/ARCH/rfsimulator/README.md#5g-case). In theory this should also work with the real hardware target although this has yet to be tested. diff --git a/executables/nr-gnb.c b/executables/nr-gnb.c index 984aa56cc9..5c45d83ad7 100644 --- a/executables/nr-gnb.c +++ b/executables/nr-gnb.c @@ -47,7 +47,7 @@ #include "SCHED/sched_eNB.h" #include "SCHED_NR/sched_nr.h" #include "SCHED_NR/fapi_nr_l1.h" -#include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "PHY/NR_TRANSPORT/nr_transport.h" #undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all //#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all @@ -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" @@ -164,14 +164,14 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t if (gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus|| gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs || gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs || - gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles || + gNB->UL_INFO.rach_ind.number_of_pdus || gNB->UL_INFO.cqi_ind.number_of_cqis ) { - LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d \n", + LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d rach_pdus:%0d.%d:%d cqis:%d] RX:%04d%d TX:%04d%d \n", NFAPI_SFNSF2DEC(gNB->UL_INFO.rx_ind.sfn_sf), gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(gNB->UL_INFO.harq_ind.sfn_sf), gNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, NFAPI_SFNSF2DEC(gNB->UL_INFO.crc_ind.sfn_sf), gNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, - NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles, + gNB->UL_INFO.rach_ind.sfn, gNB->UL_INFO.rach_ind.slot,gNB->UL_INFO.rach_ind.number_of_pdus, gNB->UL_INFO.cqi_ind.number_of_cqis, frame_rx, slot_rx, frame_tx, slot_tx); @@ -204,6 +204,13 @@ static inline int rxtx(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int frame_t if (rx_slot_type == NR_UPLINK_SLOT || rx_slot_type == NR_MIXED_SLOT) { // UE-specific RX processing for subframe n // TODO: check if this is correct for PARALLEL_RU_L1_TRX_SPLIT + + // Do PRACH RU processing + int prach_id=find_nr_prach(gNB,frame_rx,slot_rx,0,SEARCH_EXIST); + if (prach_id>=0) { + L1_nr_prach_procedures(gNB,frame_rx,slot_rx,&gNB->prach_vars.list[prach_id].pdu); + gNB->prach_vars.list[prach_id].frame=-1; + } phy_procedures_gNB_uespec_RX(gNB, frame_rx, slot_rx); } diff --git a/executables/nr-ru.c b/executables/nr-ru.c index fe10988462..da1e241b7a 100644 --- a/executables/nr-ru.c +++ b/executables/nr-ru.c @@ -68,12 +68,13 @@ #include "PHY/defs_nr_common.h" #include "PHY/phy_extern.h" #include "PHY/LTE_TRANSPORT/transport_proto.h" +#include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/INIT/phy_init.h" #include "SCHED/sched_eNB.h" #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" @@ -308,7 +309,7 @@ void fh_if5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) // southbound IF4p5 fronthaul void fh_if4p5_south_out(RU_t *ru, int frame, int slot, uint64_t timestamp) { - nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &ru->config; if (ru == RC.ru[0]) VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, ru->proc.timestamp_tx&0xffffffff ); LOG_D(PHY,"Sending IF4p5 for frame %d subframe %d\n",ru->proc.frame_tx,ru->proc.tti_tx); @@ -519,7 +520,7 @@ void fh_if5_north_asynch_in(RU_t *ru,int *frame,int *slot) { void fh_if4p5_north_asynch_in(RU_t *ru,int *frame,int *slot) { NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &ru->config; RU_proc_t *proc = &ru->proc; uint16_t packet_type; uint32_t symbol_number,symbol_mask,symbol_mask_full=0; @@ -716,7 +717,7 @@ void rx_rf(RU_t *ru,int *frame,int *slot) { void tx_rf(RU_t *ru,int frame,int slot, uint64_t timestamp) { RU_proc_t *proc = &ru->proc; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &ru->config; void *txp[ru->nb_tx]; unsigned int txs; int i,txsymb; @@ -808,7 +809,7 @@ void *ru_thread_asynch_rxtx( void *param ) { static int ru_thread_asynch_rxtx_status; RU_t *ru = (RU_t *)param; RU_proc_t *proc = &ru->proc; - nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &ru->config; int slot=0, frame=0; // wait for top-level synchronization and do one acquisition to get timestamp for setting frame/subframe wait_sync("ru_thread_asynch_rxtx"); @@ -1053,10 +1054,10 @@ int wakeup_prach_ru(RU_t *ru) { void fill_rf_config(RU_t *ru, char *rf_config_file) { int i; NR_DL_FRAME_PARMS *fp = ru->nr_frame_parms; - nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; //tmp index + nfapi_nr_config_request_scf_t *config = &ru->config; //tmp index openair0_config_t *cfg = &ru->openair0_cfg; - int mu = gNB_config->ssb_config.scs_common.value; - int N_RB = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value; + int mu = config->ssb_config.scs_common.value; + int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; if (mu == NR_MU_0) { //or if LTE if(N_RB == 100) { @@ -1141,7 +1142,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { AssertFatal(0 == 1,"Numerology %d not supported for the moment\n",mu); } - if (gNB_config->cell_config.frame_duplex_type.value==TDD) + if (config->cell_config.frame_duplex_type.value==TDD) cfg->duplex_mode = duplex_mode_TDD; else //FDD cfg->duplex_mode = duplex_mode_FDD; @@ -1180,7 +1181,7 @@ int setup_RU_buffers(RU_t *ru) { int card,ant; //uint16_t N_TA_offset = 0; NR_DL_FRAME_PARMS *frame_parms; - //nfapi_nr_config_request_t *gNB_config = ru->gNB_list[0]->gNB_config; //tmp index + nfapi_nr_config_request_scf_t *config = &ru->config; if (ru) { frame_parms = ru->nr_frame_parms; @@ -1189,12 +1190,54 @@ int setup_RU_buffers(RU_t *ru) { printf("ru pointer is NULL\n"); return(-1); } + int mu = config->ssb_config.scs_common.value; + int N_RB = config->carrier_config.dl_grid_size[config->ssb_config.scs_common.value].value; - /* if (frame_parms->frame_type == TDD) { - if (frame_parms->N_RB_DL == 100) ru->N_TA_offset = 624; - else if (frame_parms->N_RB_DL == 50) ru->N_TA_offset = 624/2; - else if (frame_parms->N_RB_DL == 25) ru->N_TA_offset = 624/4; - } */ + + if (config->cell_config.frame_duplex_type.value == TDD) { + int N_TA_offset = config->carrier_config.uplink_frequency.value < 6000000 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 + + double factor=1; + + switch (mu) { + case 0: //15 kHz scs + AssertFatal(N_TA_offset == 400,"scs_common 15kHz only for FR1\n"); + if (N_RB <= 25) factor = .25; // 7.68 Ms/s + else if (N_RB <=50) factor = .5; // 15.36 Ms/s + else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s + else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s + else AssertFatal(1==0,"Too many PRBS for mu=0\n"); + break; + case 1: //30 kHz sc + AssertFatal(N_TA_offset == 400,"scs_common 30kHz only for FR1\n"); + if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s + else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s + break; + case 2: //60 kHz scs + AssertFatal(1==0,"scs_common should not be 60 kHz\n"); + break; + case 3: //120 kHz scs + AssertFatal(N_TA_offset == 431,"scs_common 120kHz only for FR2\n"); + break; + case 4: //240 kHz scs + AssertFatal(1==0,"scs_common should not be 60 kHz\n"); + if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s + else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s + else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB); + break; + + if (N_RB == 100) ru->N_TA_offset = 624; + else if (N_RB == 50) ru->N_TA_offset = 624/2; + else if (N_RB == 25) ru->N_TA_offset = 624/4; + } + if (frame_parms->threequarter_fs == 1) factor = factor*.75; + ru->N_TA_offset = (int)(N_TA_offset * factor); + LOG_I(PHY,"RU %d Setting N_TA_offset to %d samples (factor %f, UL Freq %d, N_RB %d)\n",ru->idx,ru->N_TA_offset,factor, + config->carrier_config.uplink_frequency.value, N_RB); + } + else ru->N_TA_offset = 0; + + if (ru->openair0_cfg.mmapped_dma == 1) { // replace RX signal buffers with mmaped HW versions for (i=0; inb_rx; i++) { @@ -1407,7 +1450,7 @@ void *ru_thread( void *param ) { int i = 0; int aa; - nfapi_nr_config_request_scf_t *cfg = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &ru->config; // set default return value ru_thread_status = 0; @@ -1419,7 +1462,7 @@ void *ru_thread( void *param ) { if(emulate_rf) { fill_rf_config(ru,ru->rf_config_file); - nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp); + nr_init_frame_parms(&ru->config, fp); nr_dump_frame_parms(fp); nr_phy_init_RU(ru); @@ -1439,8 +1482,10 @@ void *ru_thread( void *param ) { AssertFatal(ret==0,"Cannot connect to remote radio\n"); } + memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config)); + if (ru->if_south == LOCAL_RF) { // configure RF parameters only - nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, fp); + nr_init_frame_parms(&ru->config, fp); nr_dump_frame_parms(fp); fill_rf_config(ru,ru->rf_config_file); nr_phy_init_RU(ru); @@ -1541,6 +1586,17 @@ void *ru_thread( void *param ) { for (aa=0;aanb_rx;aa++) memcpy((void*)RC.gNB[0]->common_vars.rxdataF[aa], (void*)ru->common.rxdataF[aa], fp->symbols_per_slot*fp->ofdm_symbol_size*sizeof(int32_t)); + + // Do PRACH RU processing + int prach_id=find_nr_prach_ru(ru,proc->frame_rx,proc->tti_rx,SEARCH_EXIST); + if (prach_id>=0) { + rx_nr_prach_ru(ru, + ru->prach_list[prach_id].fmt, + ru->prach_list[prach_id].numRA, + ru->prach_list[prach_id].prachStartSymbol, + proc->frame_rx,proc->tti_rx); + free_nr_ru_prach_entry(ru,prach_id); + } } // At this point, all information for subframe has been received on FH interface @@ -1911,7 +1967,7 @@ void configure_ru(int idx, RU_t *ru = RC.ru[idx]; RRU_config_t *config = (RRU_config_t *)arg; RRU_capabilities_t *capabilities = (RRU_capabilities_t *)arg; - nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &ru->config; int ret; LOG_I(PHY, "Received capabilities from RRU %d\n",idx); @@ -1934,15 +1990,15 @@ void configure_ru(int idx, //config->tdd_config_S[0] = ru->nr_frame_parms->tdd_config_S; config->att_tx[0] = ru->att_tx; config->att_rx[0] = ru->att_rx; - config->N_RB_DL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value; - config->N_RB_UL[0] = gNB_config->carrier_config.dl_grid_size[gNB_config->ssb_config.scs_common.value].value; + config->N_RB_DL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value; + config->N_RB_UL[0] = cfg->carrier_config.dl_grid_size[cfg->ssb_config.scs_common.value].value; config->threequarter_fs[0] = ru->nr_frame_parms->threequarter_fs; /* if (ru->if_south==REMOTE_IF4p5) { config->prach_FreqOffset[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset; config->prach_ConfigIndex[0] = ru->nr_frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; LOG_I(PHY,"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d\n", config->prach_FreqOffset[0],config->prach_ConfigIndex[0]);*/ - nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, ru->nr_frame_parms); + nr_init_frame_parms(&ru->config, ru->nr_frame_parms); nr_phy_init_RU(ru); } @@ -1950,23 +2006,23 @@ void configure_rru(int idx, void *arg) { RRU_config_t *config = (RRU_config_t *)arg; RU_t *ru = RC.ru[idx]; - nfapi_nr_config_request_scf_t *gNB_config = &ru->gNB_list[0]->gNB_config; + nfapi_nr_config_request_scf_t *cfg = &ru->config; ru->nr_frame_parms->nr_band = config->band_list[0]; ru->nr_frame_parms->dl_CarrierFreq = config->tx_freq[0]; ru->nr_frame_parms->ul_CarrierFreq = config->rx_freq[0]; if (ru->nr_frame_parms->dl_CarrierFreq == ru->nr_frame_parms->ul_CarrierFreq) { - gNB_config->cell_config.frame_duplex_type.value = TDD; + cfg->cell_config.frame_duplex_type.value = TDD; //ru->nr_frame_parms->tdd_config = config->tdd_config[0]; //ru->nr_frame_parms->tdd_config_S = config->tdd_config_S[0]; } else - gNB_config->cell_config.frame_duplex_type.value = FDD; + cfg->cell_config.frame_duplex_type.value = FDD; ru->att_tx = config->att_tx[0]; ru->att_rx = config->att_rx[0]; - int mu = gNB_config->ssb_config.scs_common.value; - gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0]; - gNB_config->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0]; + int mu = cfg->ssb_config.scs_common.value; + cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_DL[0]; + cfg->carrier_config.dl_grid_size[mu].value = config->N_RB_UL[0]; ru->nr_frame_parms->threequarter_fs = config->threequarter_fs[0]; //ru->nr_frame_parms->pdsch_config_common.referenceSignalPower = ru->max_pdschReferenceSignalPower-config->att_tx[0]; @@ -1981,7 +2037,7 @@ void configure_rru(int idx, } fill_rf_config(ru,ru->rf_config_file); - nr_init_frame_parms(&ru->gNB_list[0]->gNB_config, ru->nr_frame_parms); + nr_init_frame_parms(&ru->config, ru->nr_frame_parms); nr_phy_init_RU(ru); } @@ -2166,7 +2222,6 @@ void init_NR_RU(char *rf_config_file) PHY_VARS_gNB *gNB0= (PHY_VARS_gNB *)NULL; NR_DL_FRAME_PARMS *fp = (NR_DL_FRAME_PARMS *)NULL; int i; - int CC_id; // create status mask RC.ru_mask = 0; pthread_mutex_init(&RC.ru_mutex,NULL); diff --git a/executables/nr-softmodem-common.h b/executables/nr-softmodem-common.h index ccb3f28d98..305e4c4fc8 100644 --- a/executables/nr-softmodem-common.h +++ b/executables/nr-softmodem-common.h @@ -57,6 +57,7 @@ #define CONFIG_HLP_DLSHIFT "dynamic shift for LLR compuation for TM3/4 (default 0)\n" #define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n" #define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" +#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n" #define CONFIG_HLP_DMAMAP "sets flag for improved EXMIMO UE performance\n" #define CONFIG_HLP_EXCCLK "tells hardware to use a clock reference (0:internal(default), 1:external, 2:gpsdo)\n" #define CONFIG_HLP_USIM "use XOR autentication algo in case of test usim mode\n" diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 04c515e556..59aa229b1a 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -176,6 +176,7 @@ extern void reset_opp_meas(void); extern void print_opp_meas(void); extern void init_eNB_afterRU(void); +extern void *udp_eNB_task(void *args_p); int transmission_mode=1; int emulate_rf = 0; @@ -382,10 +383,10 @@ int create_gNB_tasks(uint32_t gnb_nb) { if (gnb_nb > 0) { /* Last task to create, others task must be ready before its start */ - if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { + /*if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { LOG_E(GNB_APP, "Create task for gNB APP failed\n"); return -1; - } + }*/ if(itti_create_task(TASK_SCTP, sctp_eNB_task, NULL) < 0){ LOG_E(SCTP, "Create task for SCTP failed\n"); return -1; @@ -400,35 +401,39 @@ int create_gNB_tasks(uint32_t gnb_nb) { } } - /* - if (EPC_MODE_ENABLED) { - if (gnb_nb > 0) { - if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { - LOG_E(SCTP, "Create task for SCTP failed\n"); - return -1; - } + if (EPC_MODE_ENABLED && (get_softmodem_params()->phy_test==0 && get_softmodem_params()->do_ra==0)) { + if (gnb_nb > 0) { + /*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { + LOG_E(SCTP, "Create task for SCTP failed\n"); + return -1; + } - if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) { - LOG_E(S1AP, "Create task for S1AP failed\n"); - return -1; - } - if(!emulate_rf){ - if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { - LOG_E(UDP_, "Create task for UDP failed\n"); - return -1; - } - } + if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) { + LOG_E(S1AP, "Create task for S1AP failed\n"); + return -1; + }*/ - if (itti_create_task (TASK_GTPV1_U, >pv1u_eNB_task, NULL) < 0) { - LOG_E(GTPU, "Create task for GTPV1U failed\n"); - return -1; - } + + if(!emulate_rf){ + if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { + LOG_E(UDP_, "Create task for UDP failed\n"); + return -1; } + } + if (itti_create_task (TASK_GTPV1_U, >pv1u_gNB_task, NULL) < 0) { + LOG_E(GTPU, "Create task for GTPV1U failed\n"); + return -1; + } } - */ + } + if (gnb_nb > 0) { + if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { + LOG_E(GNB_APP, "Create task for gNB APP failed\n"); + return -1; + } LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); if (itti_create_task (TASK_RRC_GNB, rrc_gnb_task, NULL) < 0) { @@ -706,7 +711,6 @@ int stop_L1L2(module_id_t gnb_id) { */ int restart_L1L2(module_id_t gnb_id) { RU_t *ru = RC.ru[gnb_id]; - int cc_id; MessageDef *msg_p = NULL; LOG_W(GNB_APP, "restarting nr-softmodem\n"); /* block threads */ @@ -822,6 +826,10 @@ int main( int argc, char **argv ) } openair0_cfg[0].threequarter_fs = threequarter_fs; + EPC_MODE_ENABLED = !IS_SOFTMODEM_NOS1; //!get_softmodem_params()->phy_test; + + if (get_softmodem_params()->do_ra) + AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n"); #if T_TRACER T_Config_Init(); diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 131710ee02..514d5f0239 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 @@ -142,15 +142,23 @@ void init_nr_ue_vars(PHY_VARS_NR_UE *ue, uint8_t abstraction_flag) { + int nb_connected_gNB = 1, gNB_id; + memcpy(&(ue->frame_parms), frame_parms, sizeof(NR_DL_FRAME_PARMS)); ue->Mod_id = UE_id; ue->mac_enabled = 1; + // Setting UE mode to NOT_SYNCHED by default + for (gNB_id = 0; gNB_id < nb_connected_gNB; gNB_id++){ + ue->UE_mode[gNB_id] = NOT_SYNCHED; + ue->prach_resources[gNB_id] = (NR_PRACH_RESOURCES_t *)malloc16_clear(sizeof(NR_PRACH_RESOURCES_t)); + } + // initialize all signal buffers - init_nr_ue_signal(ue,1,abstraction_flag); + init_nr_ue_signal(ue, nb_connected_gNB, abstraction_flag); // intialize transport - init_nr_ue_transport(ue,abstraction_flag); + init_nr_ue_transport(ue, abstraction_flag); } /*! @@ -360,14 +368,17 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { uint32_t nb_rb, start_rb; uint8_t nb_symb_sch, start_symbol, mcs, precod_nbr_layers, harq_pid, rvidx; uint16_t n_rnti; + module_id_t mod_id; nr_dcireq_t dcireq; nr_scheduled_response_t scheduled_response; // program PUSCH. this should actually be done by the MAC upon reception of an UL DCI - if (proc->nr_tti_tx == 8 || UE->frame_parms.frame_type == FDD){ + if (proc->nr_tti_tx == 8 || proc->nr_tti_tx == 19 || UE->frame_parms.frame_type == FDD){ - dcireq.module_id = UE->Mod_id; + mod_id = UE->Mod_id; + + dcireq.module_id = mod_id; dcireq.gNB_index = 0; dcireq.cc_id = 0; dcireq.frame = proc->frame_rx; @@ -376,7 +387,7 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { scheduled_response.dl_config = NULL; scheduled_response.ul_config = &dcireq.ul_config_req; scheduled_response.tx_request = NULL; - scheduled_response.module_id = UE->Mod_id; + scheduled_response.module_id = mod_id; scheduled_response.CC_id = 0; scheduled_response.frame = proc->frame_rx; scheduled_response.slot = proc->nr_tti_rx; @@ -407,9 +418,9 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.ulsch_pdu_rel15.harq_process_nbr = harq_pid; nr_ue_scheduled_response(&scheduled_response); - + if (UE->mode != loop_through_memory) { - uint8_t thread_id = PHY_vars_UE_g[UE->Mod_id][0]->current_thread_id[proc->nr_tti_tx]; + uint8_t thread_id = PHY_vars_UE_g[mod_id][0]->current_thread_id[proc->nr_tti_tx]; phy_procedures_nrUE_TX(UE,proc,0,thread_id); } } @@ -470,23 +481,6 @@ void processSlotRX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { pdcp_run(&ctxt); } } - - - // no UL for now - /* - if (UE->mac_enabled==1) { - // trigger L2 to run ue_scheduler thru IF module - // [TODO] mapping right after NR initial sync - if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) { - UE->ul_indication.module_id = 0; - UE->ul_indication.gNB_index = 0; - UE->ul_indication.cc_id = 0; - UE->ul_indication.frame = proc->frame_rx; - UE->ul_indication.slot = proc->nr_tti_rx; - UE->if_inst->ul_indication(&UE->ul_indication); - } - } - */ } /*! @@ -503,11 +497,15 @@ typedef struct processingData_s { } processingData_t; void UE_processing(void *arg) { - processingData_t *rxtxD=(processingData_t *) arg; + processingData_t *rxtxD = (processingData_t *) arg; UE_nr_rxtx_proc_t *proc = &rxtxD->proc; PHY_VARS_NR_UE *UE = rxtxD->UE; - uint8_t gNB_id = 0; + uint8_t gNB_id = 0, CC_id = 0; + module_id_t mod_id = 0; + + nr_uplink_indication_t ul_indication; + memset((void*)&ul_indication, 0, sizeof(ul_indication)); // params for UL time alignment procedure NR_UL_TIME_ALIGNMENT_t *ul_time_alignment = &UE->ul_time_alignment[gNB_id]; @@ -534,6 +532,21 @@ void UE_processing(void *arg) { processSlotRX(UE, proc); + if (UE->mac_enabled == 1) { + // trigger L2 to run ue_scheduler thru IF module + // [TODO] mapping right after NR initial sync + if(UE->if_inst != NULL && UE->if_inst->ul_indication != NULL) { + ul_indication.module_id = mod_id; + ul_indication.gNB_index = gNB_id; + ul_indication.cc_id = CC_id; + ul_indication.frame_rx = proc->frame_rx; + ul_indication.slot_rx = proc->nr_tti_rx; + ul_indication.frame_tx = proc->frame_tx; + ul_indication.slot_tx = proc->nr_tti_tx; + UE->if_inst->ul_indication(&ul_indication); + } + } + processSlotTX(UE, proc); } @@ -611,11 +624,6 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { } int computeSamplesShift(PHY_VARS_NR_UE *UE) { - if (IS_SOFTMODEM_RFSIM) { - LOG_E(PHY,"SET rx_offset %d \n",UE->rx_offset); - //UE->rx_offset_diff=0; - return 0; - } // compute TO compensation that should be applied for this frame if ( UE->rx_offset < UE->frame_parms.samples_per_frame/2 && diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 53e407923f..d5c34fc728 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 -#include -#include +#include "NR_MAC_UE/mac_defs.h" +#include "NR_MAC_UE/mac_proto.h" #include #include @@ -716,6 +716,9 @@ int main( int argc, char **argv ) { PHY_vars_UE_g = malloc(sizeof(PHY_VARS_NR_UE **)); PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_NR_UE *)*MAX_NUM_CCs); + if (get_softmodem_params()->do_ra) + AssertFatal(get_softmodem_params()->phy_test == 0,"RA and phy_test are mutually exclusive\n"); + for (int CC_id=0; CC_idofdm_symbol_size); frame_parms[CC_id]->nb_antennas_tx = nb_antenna_tx; @@ -742,11 +745,6 @@ int main( int argc, char **argv ) { init_nr_ue_vars(UE[CC_id],frame_parms[CC_id],0,abstraction_flag); - if (get_softmodem_params()->phy_test==1) - UE[CC_id]->mac_enabled = 0; - else - UE[CC_id]->mac_enabled = 1; - UE[CC_id]->mac_enabled = 1; UE[CC_id]->if_inst = nr_ue_if_module_init(0); UE[CC_id]->UE_scan = UE_scan; @@ -759,15 +757,49 @@ int main( int argc, char **argv ) { UE[CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0] + rx_gain_off; UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id]; - if (frame_parms[CC_id]->frame_type==FDD) { + if (UE[CC_id]->frame_parms.frame_type == FDD) { UE[CC_id]->N_TA_offset = 0; } else { - if (frame_parms[CC_id]->N_RB_DL == 100) - UE[CC_id]->N_TA_offset = 624; - else if (frame_parms[CC_id]->N_RB_DL == 50) - UE[CC_id]->N_TA_offset = 624/2; - else if (frame_parms[CC_id]->N_RB_DL == 25) - UE[CC_id]->N_TA_offset = 624/4; + int N_RB = UE[CC_id]->frame_parms.N_RB_DL; + int N_TA_offset = UE[CC_id]->frame_parms.ul_CarrierFreq < 6e9 ? 400 : 431; // reference samples for 25600Tc @ 30.72 Ms/s for FR1, same @ 61.44 Ms/s for FR2 + double factor=1; + switch (UE[CC_id]->frame_parms.numerology_index) { + case 0: //15 kHz scs + AssertFatal(N_TA_offset == 400, "scs_common 15kHz only for FR1\n"); + if (N_RB <= 25) factor = .25; // 7.68 Ms/s + else if (N_RB <=50) factor = .5; // 15.36 Ms/s + else if (N_RB <=75) factor = 1.0; // 30.72 Ms/s + else if (N_RB <=100) factor = 1.0; // 30.72 Ms/s + else AssertFatal(1==0,"Too many PRBS for mu=0\n"); + break; + case 1: //30 kHz sc + AssertFatal(N_TA_offset == 400, "scs_common 30kHz only for FR1\n"); + if (N_RB <= 106) factor = 2.0; // 61.44 Ms/s + else if (N_RB <= 275) factor = 4.0; // 122.88 Ms/s + break; + case 2: //60 kHz scs + AssertFatal(1==0,"scs_common should not be 60 kHz\n"); + break; + case 3: //120 kHz scs + AssertFatal(N_TA_offset == 431, "scs_common 120kHz only for FR2\n"); + break; + case 4: //240 kHz scs + AssertFatal(1==0,"scs_common should not be 60 kHz\n"); + if (N_RB <= 32) factor = 1.0; // 61.44 Ms/s + else if (N_RB <= 66) factor = 2.0; // 122.88 Ms/s + else AssertFatal(1==0,"N_RB %d is too big for curretn FR2 implementation\n",N_RB); + break; + + if (N_RB == 100) + UE[CC_id]->N_TA_offset = 624; + else if (N_RB == 50) + UE[CC_id]->N_TA_offset = 624/2; + else if (N_RB == 25) + UE[CC_id]->N_TA_offset = 624/4; + } + if (UE[CC_id]->frame_parms.threequarter_fs == 1) factor = factor*.75; + UE[CC_id]->N_TA_offset = (int)(N_TA_offset * factor); + LOG_I(PHY,"UE %d Setting N_TA_offset to %d samples (factor %f, UL Freq %lu, N_RB %d)\n", UE[CC_id]->Mod_id, UE[CC_id]->N_TA_offset, factor, UE[CC_id]->frame_parms.ul_CarrierFreq, N_RB); } } diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 7fad43e897..a5de840258 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -4,7 +4,6 @@ #include #include "PHY/defs_nr_UE.h" #include "SIMULATION/ETH_TRANSPORT/proto.h" -#include /***************************************************************************************************************************************/ /* command line options definitions, CMDLINE_XXXX_DESC macros are used to initialize paramdef_t arrays which are then used as argument diff --git a/executables/softmodem-common.h b/executables/softmodem-common.h index cfed951469..7684dad948 100644 --- a/executables/softmodem-common.h +++ b/executables/softmodem-common.h @@ -50,6 +50,7 @@ extern "C" #define CONFIG_HLP_DUMPFRAME "dump UE received frame to rxsig_frame0.dat and exit\n" #define CONFIG_HLP_UELOOP "get softmodem (UE) to loop through memory instead of acquiring from HW\n" #define CONFIG_HLP_PHYTST "test UE phy layer, mac disabled\n" +#define CONFIG_HLP_DORA "test gNB and UE with RA procedures\n" #define CONFIG_HLP_EXTS "tells hardware to use an external timing reference\n" #define CONFIG_HLP_DMRSSYNC "tells RU to insert DMRS in subframe 1 slot 0" #define CONFIG_HLP_CLK "tells hardware to use a clock reference (0:internal, 1:external, 2:gpsdo)\n" @@ -89,6 +90,7 @@ extern "C" /*-----------------------------------------------------------------------------------------------------------------------------------------------------*/ #define RF_CONFIG_FILE softmodem_params.rf_config_file #define PHY_TEST softmodem_params.phy_test +#define DO_RA softmodem_params.do_ra #define WAIT_FOR_SYNC softmodem_params.wait_for_sync #define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag #define CHAIN_OFFSET softmodem_params.chain_offset @@ -104,6 +106,7 @@ extern "C" #define CMDLINE_PARAMS_DESC { \ {"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)},\ {"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \ + {"do-ra", CONFIG_HLP_DORA, PARAMFLAG_BOOL, iptr:&DO_RA, defintval:0, TYPE_INT, 0}, \ {"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \ {"clock", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \ {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \ @@ -192,6 +195,7 @@ typedef struct { //THREAD_STRUCT thread_struct; char rf_config_file[1024]; int phy_test; + int do_ra; uint8_t usim_test; int emulate_rf; int wait_for_sync; //eNodeB only 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 cbcd26c3e3..4b0720078a 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/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h index 576144e1df..610a798292 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h @@ -156,22 +156,29 @@ typedef struct { fapi_nr_tx_request_body_t *tx_request_body; } fapi_nr_tx_request_t; - typedef struct { - uint8_t preamble_index; - uint8_t prach_configuration_index; - uint16_t preamble_length; - uint8_t power_ramping_step; - uint16_t preamble_received_target_power; - uint8_t msg1_fdm; - uint8_t msg1_frequency_start; - uint8_t zero_correlation_zone_config; - uint8_t subcarrier_spacing; - uint8_t restrictedset_config; - uint16_t root_sequence_index; - uint16_t rsrp_threshold_ssb; - uint16_t rsrp_threshold_sul; - uint16_t prach_freq_offset; - } fapi_nr_ul_config_prach_pdu; +/// This struct replaces: +/// PRACH-ConfigInfo from 38.331 RRC spec +/// PRACH-ConfigSIB or PRACH-Config +typedef struct { + /// PHY cell ID + uint16_t phys_cell_id; + /// Num PRACH occasions + uint8_t num_prach_ocas; + /// PRACH format + uint8_t prach_format; + /// Num RA + uint8_t num_ra; + uint8_t prach_start_symbol; + /// 38.211 (NCS 38.211 6.3.3.1). + uint16_t num_cs; + /// Parameter: prach-rootSequenceIndex, see TS 38.211 (6.3.3.2). + uint16_t root_seq_id; + /// Parameter: High-speed-flag, see TS 38.211 (6.3.3.1). 1 corresponds to Restricted set and 0 to Unrestricted set. + uint8_t restricted_set; + /// see TS 38.211 (6.3.3.2). + uint16_t freq_msg1; + // nfapi_nr_ul_beamforming_t beamforming; +} fapi_nr_ul_config_prach_pdu; typedef struct { diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index 33951a2751..eadd05c52c 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -86,7 +86,7 @@ typedef enum { NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION= 0X86, NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION= 0X87, NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION= 0X88, - NFAPI_NR_PHY_MSG_TYPE_PACH_INDICATION= 0X89 + NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION= 0X89 //RESERVED 0X8a ~ 0xff } nfapi_nr_phy_msg_type_e; @@ -623,22 +623,35 @@ typedef struct { //table 3-37 -#define DCI_PAYLOAD_BTYE_LEN 12 //? TS38.212 sec 7.3.1 +#define DCI_PAYLOAD_BYTE_LEN 8 // 12 ? TS38.212 sec 7.3.1 +#define MAX_DCI_CORESET 8 -typedef struct -{ - uint16_t rnti;// - uint16_t scrambling_id;// - uint16_t scrambling_rnti;/* */ - uint8_t cce_index;// - uint8_t aggregation_level;// - nfapi_nr_tx_precoding_and_beamforming_t* precoding_and_beamforming_list; - //tx power info - uint8_t beta_pdcch_1_0;/*PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of -SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 */ - uint8_t power_control_offset_ss;//PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB - uint16_t payload_size_bits;//The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0-> DCI_PAYLOAD_BTYE_LEN*8 - uint8_t payload[DCI_PAYLOAD_BTYE_LEN];//DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB +typedef struct { + // The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535. + uint16_t RNTI[MAX_DCI_CORESET]; + // For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured, + // otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535 + uint16_t ScramblingId[MAX_DCI_CORESET]; + // For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI. + // Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535 + uint16_t ScramblingRNTI[MAX_DCI_CORESET]; + // CCE start Index used to send the DCI Value: 0->135 + uint8_t CceIndex[MAX_DCI_CORESET]; + // Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16 + uint8_t AggregationLevel[MAX_DCI_CORESET]; + // Precoding and Beamforming structure See Table 3-43 + nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET]; + // PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. + // This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] + // Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps + uint8_t beta_PDCCH_1_0[MAX_DCI_CORESET]; + // PDCCH power value used for all other PDCCH Formats. + // This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB + uint8_t powerControlOffsetSS[MAX_DCI_CORESET]; + // The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BYTE_LEN*8 + uint16_t PayloadSizeBits[MAX_DCI_CORESET]; + // DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB + uint8_t Payload[MAX_DCI_CORESET][DCI_PAYLOAD_BYTE_LEN]; } nfapi_nr_dl_dci_pdu_t; @@ -653,9 +666,6 @@ typedef struct { uint16_t *beamIdx[275]; } nr_beamforming_t; -#define MAX_DCI_CORESET 8 -#define DCI_PAYLOAD_BYTE_LEN 8 - typedef struct { ///Bandwidth part size [TS38.213 sec12]. Number of contiguous PRBs allocated to the BWP,Value: 1->275 uint16_t BWPSize; @@ -685,26 +695,8 @@ typedef struct { uint8_t precoderGranularity; ///Number of DCIs in this CORESET.Value: 0->MaxDciPerSlot uint16_t numDlDci; - ///The RNTI used for identifying the UE when receiving the PDU Value: 1 -> 65535. - uint16_t RNTI[MAX_DCI_CORESET]; - ///For a UE-specific search space it equals the higher-layer parameter PDCCH-DMRSScrambling-ID if configured, otherwise it should be set to the phy cell ID. [TS38.211, sec 7.3.2.3] Value: 0->65535 - uint16_t ScramblingId[MAX_DCI_CORESET]; - ///For a UE-specific search space where PDCCH-DMRSScrambling- ID is configured This param equals the CRNTI. Otherwise, it should be set to 0. [TS38.211, sec 7.3.2.3] Value: 0 -> 65535 - uint16_t ScramblingRNTI[MAX_DCI_CORESET]; - ///CCE start Index used to send the DCI Value: 0->135 - uint8_t CceIndex[MAX_DCI_CORESET]; - ///Aggregation level used [TS38.211, sec 7.3.2.1] Value: 1,2,4,8,16 - uint8_t AggregationLevel[MAX_DCI_CORESET]; - ///Precoding and Beamforming structure See Table 3-43 - nfapi_nr_tx_precoding_and_beamforming_t precodingAndBeamforming[MAX_DCI_CORESET]; - ///PDCCH power value used for PDCCH Format 1_0 with CRC scrambled by SI-RNTI, PI-RNTI or RA-RNTI. This is ratio of SSB/PBCH EPRE to PDCCH and PDCCH DMRS EPRE [TS38.213, sec 4.1] Value :0->17 Report title: 5G FAPI: PHY API Specification Issue date: 29 June 2019 Version: 222.10.17 68 Field Type Description representing -8 to 8 dB in 1dB steps - uint8_t beta_PDCCH_1_0[MAX_DCI_CORESET]; - ///PDCCH power value used for all other PDCCH Formats. This is ratio of SSB/PBCH block EPRE to PDCCH and PDCCH DMRS EPRE [TS38.214, sec 4.1] Values: 0: -3dB,1: 0dB,2: 3dB,3: 6dB - uint8_t powerControlOffsetSS[MAX_DCI_CORESET]; -///The total DCI length (in bits) including padding bits [TS38.212 sec 7.3.1] Range 0->DCI_PAYLOAD_BTYE_LEN*8 - uint16_t PayloadSizeBits[MAX_DCI_CORESET]; - ///DCI payload, where the actual size is defined by PayloadSizeBits. The bit order is as following bit0-bit7 are mapped to first byte of MSB - LSB - uint8_t Payload[MAX_DCI_CORESET][DCI_PAYLOAD_BYTE_LEN]; + ///DL DCI PDU + nfapi_nr_dl_dci_pdu_t dci_pdu; } nfapi_nr_dl_tti_pdcch_pdu_rel15_t; typedef struct { @@ -1037,10 +1029,12 @@ typedef struct { uint16_t phys_cell_id; uint8_t num_prach_ocas; + // SCF PRACH PDU format field does not consider A1/B1 etc. possibilities + // We added 9 = A1/B1 10 = A2/B2 11 A3/B3 uint8_t prach_format; uint8_t num_ra; uint8_t prach_start_symbol; - uint16_t num_cs;// + uint16_t num_cs; nfapi_nr_ul_beamforming_t beamforming; } nfapi_nr_prach_pdu_t; diff --git a/openair1/PHY/CODING/coding_defs.h b/openair1/PHY/CODING/coding_defs.h index 9b111309cd..da19ec40e2 100644 --- a/openair1/PHY/CODING/coding_defs.h +++ b/openair1/PHY/CODING/coding_defs.h @@ -463,6 +463,7 @@ uint32_t nr_compute_tbs(uint16_t Qm, uint16_t nb_symb_sch, uint16_t nb_dmrs_prb, uint16_t nb_rb_oh, + uint8_t tb_scaling, uint8_t Nl); uint32_t nr_compute_tbslbrm(uint16_t table, diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 1c0d5a6aca..a74b90749a 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -26,6 +26,7 @@ #include "PHY/INIT/phy_init.h" #include "PHY/CODING/nrPolar_tools/nr_polar_pbch_defs.h" #include "PHY/NR_TRANSPORT/nr_transport.h" +#include "PHY/NR_TRANSPORT/nr_transport_proto_common.h" /*#include "RadioResourceConfigCommonSIB.h" #include "RadioResourceConfigDedicated.h" #include "TDD-Config.h" @@ -39,7 +40,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" /* @@ -152,11 +152,11 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, } } - nr_init_pdsch_dmrs(gNB, cfg->cell_config.phy_cell_id.value); //PUSCH DMRS init gNB->nr_gold_pusch_dmrs = (uint32_t ****)malloc16(2*sizeof(uint32_t ***)); + uint32_t ****pusch_dmrs = gNB->nr_gold_pusch_dmrs; for(int nscid=0; nscid<2; nscid++) { @@ -231,6 +231,8 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB, */ prach_vars->prach_ifft = (int32_t *)malloc16_clear(1024*2*sizeof(int32_t)); + init_prach_list(gNB); + int N_RB_UL = cfg->carrier_config.ul_grid_size[cfg->ssb_config.scs_common.value].value; printf("Before ULSCH init : %p\n",gNB->dlsch[0][0]->harq_processes[0]); @@ -404,7 +406,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, fp->dl_CarrierFreq = 3500000000;//from_nrarfcn(gNB_config->nfapi_config.rf_bands.rf_band[0],gNB_config->nfapi_config.nrarfcn.value); fp->ul_CarrierFreq = 3500000000;//fp->dl_CarrierFreq - (get_uldl_offset(gNB_config->nfapi_config.rf_bands.rf_band[0])*100000); fp->nr_band = 78; - fp->threequarter_fs= 0; +// fp->threequarter_fs= 0; gNB_config->carrier_config.dl_bandwidth.value = config_bandwidth(mu, N_RB_DL, fp->nr_band); @@ -416,6 +418,7 @@ void nr_phy_config_request_sim(PHY_VARS_gNB *gNB, void nr_phy_config_request(NR_PHY_Config_t *phy_config) { uint8_t Mod_id = phy_config->Mod_id; + uint8_t short_sequence, num_sequences, rootSequenceIndex, fd_occasion; NR_DL_FRAME_PARMS *fp = &RC.gNB[Mod_id]->frame_parms; nfapi_nr_config_request_scf_t *gNB_config = &RC.gNB[Mod_id]->gNB_config; @@ -479,6 +482,14 @@ void nr_phy_config_request(NR_PHY_Config_t *phy_config) { return; } + fd_occasion = 0; + nfapi_nr_prach_config_t *prach_config = &gNB_config->prach_config; + short_sequence = prach_config->prach_sequence_length.value; + num_sequences = prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value; + rootSequenceIndex = prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value; + + compute_nr_prach_seq(short_sequence, num_sequences, rootSequenceIndex, RC.gNB[Mod_id]->X_u); + RC.gNB[Mod_id]->configured = 1; LOG_I(PHY,"gNB %d configured\n",Mod_id); } diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 2dcf035866..60921da1cb 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -22,6 +22,7 @@ #include "phy_init.h" #include "SCHED/sched_common.h" #include "PHY/phy_extern.h" +#include "PHY/NR_TRANSPORT/nr_transport.h" #include "SIMULATION/TOOLS/sim.h" /*#include "RadioResourceConfigCommonSIB.h" #include "RadioResourceConfigDedicated.h" @@ -39,14 +40,19 @@ int nr_phy_init_RU(RU_t *ru) { int p; int re; + // For memory allocation of ru->prach_rxsigF + int mu = fp->numerology_index; + LOG_I(PHY,"Initializing RU signal buffers (if_south %s) nb_tx %d\n",ru_if_types[ru->if_south],ru->nb_tx); nfapi_nr_config_request_scf_t *cfg; ru->nb_log_antennas=0; for (int n=0;ngNB_config; + cfg = &ru->config; if (cfg->carrier_config.num_tx_ant.value > ru->nb_log_antennas) ru->nb_log_antennas = cfg->carrier_config.num_tx_ant.value; } + // copy configuration from gNB[0] in to RU, assume that all gNB instances sharing RU use the same configuration (at least the parts that are needed by the RU, numerology and PRACH) + AssertFatal(ru->nb_log_antennas > 0 && ru->nb_log_antennas < 13, "ru->nb_log_antennas %d ! \n",ru->nb_log_antennas); if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so allocate memory for time-domain signals // Time-domain signals @@ -107,7 +113,8 @@ int nr_phy_init_RU(RU_t *ru) { ru->prach_rxsigF = (int16_t**)malloc(ru->nb_rx * sizeof(int16_t*)); for (i=0; inb_rx; i++) { - ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); + // for preamble format 1 and 2, more memory should be allocated + ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*(1<rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]); } @@ -144,6 +151,8 @@ int nr_phy_init_RU(RU_t *ru) { ru->common.sync_corr = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_subframe_wCP ); + init_prach_ru_list(ru); + return(0); } diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c index 4ed5be2119..b88f9aa0f2 100644 --- a/openair1/PHY/INIT/nr_init_ue.c +++ b/openair1/PHY/INIT/nr_init_ue.c @@ -77,19 +77,19 @@ void phy_config_sib2_ue(uint8_t Mod_id,int CC_id, LOG_I(PHY,"[UE%d] Applying radioResourceConfigCommon from eNB%d\n",Mod_id,eNB_id); - fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex; + ue->prach_vars[eNB_id]->prach_pdu.root_seq_id =radioResourceConfigCommon->prach_Config.rootSequenceIndex; - fp->prach_config_common.prach_Config_enabled=1; - fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex; - fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.highSpeedFlag; - fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; - fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset; + ue->prach_vars[eNB_id]->prach_Config_enabled=1; + //ue->prach_vars[eNB_id]->prach_pdu.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_ConfigIndex; + ue->prach_vars[eNB_id]->prach_pdu.restricted_set =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.highSpeedFlag; + ue->prach_vars[eNB_id]->prach_pdu.num_cs =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig; + //ue->prach_vars[eNB_id]->prach_pdu.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo.prach_FreqOffset; - compute_prach_seq(fp->prach_config_common.rootSequenceIndex, - fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - fp->prach_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type,ue->X_u); + //compute_prach_seq(fp->prach_config_common.rootSequenceIndex, + // fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + // fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + // fp->prach_config_common.prach_ConfigInfo.highSpeedFlag, + // fp->frame_type,ue->X_u); @@ -226,12 +226,12 @@ void phy_config_sib13_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_ LOG_I(PHY,"[UE%d] Handover triggered: Applying radioResourceConfigCommon from eNB %d\n", Mod_id,eNB_id); - fp->prach_config_common.rootSequenceIndex =radioResourceConfigCommon->prach_Config.rootSequenceIndex; - fp->prach_config_common.prach_Config_enabled=1; - fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex; - fp->prach_config_common.prach_ConfigInfo.highSpeedFlag =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->highSpeedFlag; - fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->zeroCorrelationZoneConfig; - fp->prach_config_common.prach_ConfigInfo.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_FreqOffset; + ue->prach_vars[eNB_id]->prach_pdu.root_seq_id =radioResourceConfigCommon->prach_Config.rootSequenceIndex; + ue->prach_vars[eNB_id]->prach_Config_enabled=1; + //ue->prach_vars[eNB_id]->prach_pdu.prach_ConfigIndex =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex; + ue->prach_vars[eNB_id]->prach_pdu.restricted_set =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->highSpeedFlag; + ue->prach_vars[eNB_id]->prach_pdu.num_cs =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->zeroCorrelationZoneConfig; + //ue->prach_vars[eNB_id]->prach_pdu.prach_FreqOffset =radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_FreqOffset; // prach_fmt = get_prach_fmt(radioResourceConfigCommon->prach_Config.prach_ConfigInfo->prach_ConfigIndex,fp->frame_type); // N_ZC = (prach_fmt <4)?839:139; @@ -239,12 +239,12 @@ void phy_config_sib13_ue(uint8_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_ // prach_root_sequence_map4[fp->prach_config_common.rootSequenceIndex]; //compute_prach_seq(u,N_ZC, PHY_vars_UE_g[Mod_id]->X_u); - compute_prach_seq(PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.rootSequenceIndex, - PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag, - fp->frame_type, - PHY_vars_UE_g[Mod_id][CC_id]->X_u); + //compute_prach_seq(PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.rootSequenceIndex, + // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, + // PHY_vars_UE_g[Mod_id][CC_id]->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag, + // fp->frame_type, + // PHY_vars_UE_g[Mod_id][CC_id]->X_u); fp->pucch_config_common.deltaPUCCH_Shift = 1+radioResourceConfigCommon->pucch_ConfigCommon->deltaPUCCH_Shift; @@ -960,7 +960,9 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, // enable MIB/SIB decoding by default ue->decode_MIB = 1; ue->decode_SIB = 1; - init_prach_tables(839); + + init_nr_prach_tables(839); + return 0; } diff --git a/openair1/PHY/MODULATION/slot_fep_nr.c b/openair1/PHY/MODULATION/slot_fep_nr.c index f2e5d24bad..8feb5f13b9 100644 --- a/openair1/PHY/MODULATION/slot_fep_nr.c +++ b/openair1/PHY/MODULATION/slot_fep_nr.c @@ -211,10 +211,10 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue, } int nr_slot_fep_init_sync(PHY_VARS_NR_UE *ue, - unsigned char symbol, - unsigned char Ns, - int sample_offset, - int no_prefix) + unsigned char symbol, + unsigned char Ns, + int sample_offset, + int no_prefix) { NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; NR_UE_COMMON *common_vars = &ue->common_vars; @@ -394,12 +394,13 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, int sample_offset, int no_prefix) { - uint32_t slot_offset; - uint32_t rxdata_offset; + int32_t slot_offset, rxdata_offset; unsigned int nb_prefix_samples = (no_prefix ? 0 : frame_parms->nb_prefix_samples); unsigned int nb_prefix_samples0 = (no_prefix ? 0 : frame_parms->nb_prefix_samples0); + int tmp_dft_in[8192] __attribute__ ((aligned (32))); + void (*dft)(int16_t *,int16_t *, int); switch (frame_parms->ofdm_symbol_size) { @@ -442,14 +443,26 @@ int nr_slot_fep_ul(NR_DL_FRAME_PARMS *frame_parms, slot_offset = frame_parms->get_samples_slot_timestamp(Ns,frame_parms,0); - if(symbol == 0) rxdata_offset = slot_offset + nb_prefix_samples0 - SOFFSET; else rxdata_offset = slot_offset + nb_prefix_samples0 + (symbol * (frame_parms->ofdm_symbol_size + nb_prefix_samples)) - SOFFSET; - dft((int16_t *)&rxdata[rxdata_offset], - (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); + if(sample_offset>rxdata_offset) { + memcpy((void *)tmp_dft_in, + (void *) &rxdata[frame_parms->samples_per_frame-sample_offset+rxdata_offset], + (sample_offset-rxdata_offset)*sizeof(int)); + + memcpy((void *)&tmp_dft_in[sample_offset-rxdata_offset], + (void *) &rxdata[0], + (frame_parms->ofdm_symbol_size-sample_offset+rxdata_offset)*sizeof(int)); + + dft((int16_t *)&tmp_dft_in, + (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); + } + else + dft((int16_t *)&rxdata[rxdata_offset-sample_offset], + (int16_t *)&rxdataF[symbol * frame_parms->ofdm_symbol_size], 1); return(0); } diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index 0d7732599f..94da06dd8b 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -116,7 +116,10 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, //------------------generate DMRS------------------// - nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->dmrs_config_type); + if (pusch_pdu->transform_precoding) // if transform precoding is disabled + nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, pusch_pdu->rb_start*NR_NB_SC_PER_RB, pusch_pdu->dmrs_config_type); + else + nr_pusch_dmrs_rx(gNB, Ns, gNB->nr_gold_pusch_dmrs[pusch_pdu->scid][Ns][symbol], &pilot[0], 1000, 0, nb_rb_pusch, 0, pusch_pdu->dmrs_config_type); //------------------------------------------------// @@ -275,70 +278,69 @@ int nr_pusch_channel_estimation(PHY_VARS_gNB *gNB, 8); - // check if PRB crosses DC and improve estimates around DC - if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) { - ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; - uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); - uint16_t idxPil = idxDC/2; - re_offset = k; - pil = (int16_t *)&pilot[0]; - pil += (idxPil-2); - ul_ch += (idxDC-4); - ul_ch = memset(ul_ch, 0, sizeof(int16_t)*10); - re_offset = (re_offset+idxDC/2-2) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - - // for proper allignment of SIMD vectors - if((gNB->frame_parms.N_RB_UL&1)==0) { + // check if PRB crosses DC and improve estimates around DC + if ((bwp_start_subcarrier < gNB->frame_parms.ofdm_symbol_size) && (bwp_start_subcarrier+nb_rb_pusch*12 >= gNB->frame_parms.ofdm_symbol_size)) { + ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; + uint16_t idxDC = 2*(gNB->frame_parms.ofdm_symbol_size - bwp_start_subcarrier); + uint16_t idxPil = idxDC/2; + re_offset = k; + pil = (int16_t *)&pilot[0]; + pil += (idxPil-2); + ul_ch += (idxDC-4); + ul_ch = memset(ul_ch, 0, sizeof(int16_t)*10); + re_offset = (re_offset+idxDC/2-2) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(fdcl, - ch, - ul_ch-4, - 8); + // for proper allignment of SIMD vectors + if((gNB->frame_parms.N_RB_UL&1)==0) { + + multadd_real_vector_complex_scalar(fdcl, + ch, + ul_ch-4, + 8); - pil += 4; - re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); + pil += 4; + re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - multadd_real_vector_complex_scalar(fdcr, - ch, - ul_ch-4, - 8); - } else { + multadd_real_vector_complex_scalar(fdcr, + ch, + ul_ch-4, + 8); + } + else { + multadd_real_vector_complex_scalar(fdclh, + ch, + ul_ch, + 8); - multadd_real_vector_complex_scalar(fdclh, - ch, - ul_ch, - 8); + pil += 4; + re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; + rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; + ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); + ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - pil += 4; - re_offset = (re_offset+4) % gNB->frame_parms.ofdm_symbol_size; - rxF = (int16_t *)&rxdataF[aarx][(symbol_offset+nushift+re_offset)]; - ch[0] = (int16_t)(((int32_t)pil[0]*rxF[0] - (int32_t)pil[1]*rxF[1])>>15); - ch[1] = (int16_t)(((int32_t)pil[0]*rxF[1] + (int32_t)pil[1]*rxF[0])>>15); - - multadd_real_vector_complex_scalar(fdcrh, - ch, - ul_ch, - 8); + multadd_real_vector_complex_scalar(fdcrh, + ch, + ul_ch, + 8); + } } - - } #ifdef DEBUG_PDSCH - ul_ch = (int16_t *)&ul_ch_estimates[aarx][ch_offset]; - for(uint16_t idxP=0; idxPframe_parms.ofdm_symbol_size) { + switch (gNB->frame_parms.ofdm_symbol_size) { case 128: idft128((int16_t*) &ul_ch_estimates[aarx][symbol_offset], (int16_t*) ul_ch_estimates_time[aarx], diff --git a/openair1/PHY/NR_REFSIG/dmrs_nr.c b/openair1/PHY/NR_REFSIG/dmrs_nr.c index ed37a79d0f..34c887be30 100644 --- a/openair1/PHY/NR_REFSIG/dmrs_nr.c +++ b/openair1/PHY/NR_REFSIG/dmrs_nr.c @@ -111,6 +111,7 @@ int32_t get_l_prime(uint8_t duration_in_symbols, uint8_t mapping_type, pusch_dmr * n index starting 0,1,... * delta see Table 6.4.1.1.3 * duration_in_symbols number of scheduled PUSCH ofdm symbols +* start_symbol first symbol index in PUSCH allocation * dmrs_UplinkConfig DMRS uplink configuration * mapping_type PUSCH mapping type (A or B) * ofdm_symbol_size IFFT size @@ -140,6 +141,8 @@ uint8_t is_dmrs_symbol(uint8_t l, is_dmrs_freq = 0; is_dmrs_time = 0; + AssertFatal(l >= 0,"Check DMRS configuration (start_symbol) !\n"); + l0 = get_l0_ul(mapping_type, 2); l_prime_mask = get_l_prime(duration_in_symbols, mapping_type, additional_pos, pusch_maxLength); @@ -166,6 +169,7 @@ uint8_t is_dmrs_symbol(uint8_t l, } + if (is_dmrs_time && is_dmrs_freq) return 1; else @@ -368,7 +372,7 @@ void lte_gold_new(LTE_DL_FRAME_PARMS *frame_parms, uint32_t lte_gold_table[20][2 * * NAME : get_l0_ul * -* PARAMETERS : mapping_type : PUSCH mapping type +* PARAMETERS : mapping_type : PUSCH mapping type * dmrs_typeA_position : higher layer parameter * * RETURN : demodulation reference signal for PUSCH diff --git a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c index f933a8c7ab..b1b038e918 100644 --- a/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c +++ b/openair1/PHY/NR_REFSIG/nr_dmrs_rx.c @@ -45,7 +45,7 @@ int wt1[8][2] = {{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1}}; int wf2[12][2] = {{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,-1},{1,1},{1,1},{1,1},{1,-1},{1,1},{1,1}}; int wt2[12][2] = {{1,1},{1,1},{1,1},{1,1},{1,1},{1,1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1},{1,-1}}; - +// complex conjugate of mod table short nr_rx_mod_table[14] = {0,0,23170,-23170,-23170,23170,23170,-23170,23170,23170,-23170,-23170,-23170,23170}; short nr_rx_nmod_table[14] = {0,0,-23170,23170,23170,-23170,-23170,23170,-23170,-23170,23170,23170,23170,-23170}; @@ -57,39 +57,40 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, unsigned short p, unsigned char lp, unsigned short nb_pusch_rb, + uint32_t re_offset, uint8_t dmrs_type) { - int8_t w; + int8_t w, nb_dmrs; short *mod_table; unsigned char idx=0; typedef int array_of_w[2]; array_of_w *wf; array_of_w *wt; - wf = (dmrs_type==pusch_dmrs_type1) ? wf1 : wf2; wt = (dmrs_type==pusch_dmrs_type1) ? wt1 : wt2; if (dmrs_type > 2) - LOG_E(PHY,"Bad PUSCH DMRS config type %d\n", dmrs_type); + LOG_E(PHY,"PUSCH DMRS config type %d not valid\n", dmrs_type+1); if ((p>=1000) && (p<((dmrs_type==pusch_dmrs_type1) ? 1008 : 1012))) { if (gNB->frame_parms.Ncp == NORMAL) { - - for (int i=0; i>5])>>((i<<1)&0x1f))&1)<<1) ^ (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1); - ((int16_t*)output)[i<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; - ((int16_t*)output)[(i<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; + ((int16_t*)output)[i<<1] = mod_table[(NR_MOD_TABLE_QPSK_OFFSET + idx)<<1]; + ((int16_t*)output)[(i<<1)+1] = mod_table[((NR_MOD_TABLE_QPSK_OFFSET + idx)<<1) + 1]; #ifdef DEBUG_PUSCH - printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb); - printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]); - printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1), - (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1]); + printf("nr_pusch_dmrs_rx dmrs config type %d port %d nb_pusch_rb %d\n", dmrs_type, p, nb_pusch_rb); + printf("wf[%d] = %d wt[%d]= %d\n", i&1, wf[p-1000][i&1], lp, wt[p-1000][lp]); + printf("i %d idx %d pusch gold %u b0-b1 %d-%d mod_dmrs %d %d\n", i, idx, nr_gold_pusch[(i<<1)>>5], (((nr_gold_pusch[(i<<1)>>5])>>((i<<1)&0x1f))&1), + (((nr_gold_pusch[((i<<1)+1)>>5])>>(((i<<1)+1)&0x1f))&1), ((int16_t*)output)[i<<1], ((int16_t*)output)[(i<<1)+1]); #endif + } } else { LOG_E(PHY,"extended cp not supported for PUSCH DMRS yet\n"); diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c index 472d03e649..4b007f1292 100644 --- a/openair1/PHY/NR_REFSIG/nr_gold.c +++ b/openair1/PHY/NR_REFSIG/nr_gold.c @@ -88,6 +88,7 @@ void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid) uint16_t N_n_scid[NR_MAX_NB_CODEWORDS]={Nid, Nid}; // Not correct, appropriate scrambling IDs have to be updated to support DCI 1_1 uint8_t n_scid=0; // again works only for 1_0 for (uint8_t slot=0; slotslots_per_frame; slot++) { + for (uint8_t symb=0; symbsymbols_per_slot; symb++) { reset = 1; x2 = ((1<<17) * (fp->symbols_per_slot*slot+symb+1) * ((N_n_scid[n_scid]<<1)+1) +((N_n_scid[n_scid]<<1)+n_scid)); diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h index 5af0e88099..9934b2163e 100644 --- a/openair1/PHY/NR_REFSIG/nr_refsig.h +++ b/openair1/PHY/NR_REFSIG/nr_refsig.h @@ -48,5 +48,6 @@ int nr_pusch_dmrs_rx(PHY_VARS_gNB *gNB, unsigned short p, unsigned char lp, unsigned short nb_pusch_rb, + uint32_t re_offset, uint8_t dmrs_type); #endif diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci.c b/openair1/PHY/NR_TRANSPORT/nr_dci.c index 5c4df1b4ed..fbb982b973 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci.c @@ -137,6 +137,7 @@ void nr_pdcch_scrambling(uint32_t *in, uint32_t x1, x2, s=0; reset = 1; x2 = (n_RNTI<<16) + Nid; + LOG_D(PHY,"PDCCH Scrambling x2 %x : n_RNTI %x\n",x2,n_RNTI); for (int i=0; iCceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED, "Interleaved CCE REG MAPPING not supported\n"); uint32_t dmrs_length = (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED)? - (n_rb*6) : (pdcch_pdu_rel15->AggregationLevel[d]*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE) - uint32_t encoded_length = pdcch_pdu_rel15->AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE) + (n_rb*6) : (pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*36/cset_nsymb); //2(QPSK)*3(per RB)*6(REG per CCE) + uint32_t encoded_length = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*108; //2(QPSK)*9(per RB)*6(REG per CCE) LOG_D(PHY, "DMRS length per symbol %d\t DCI encoded length %d (precoder_granularity %d,reg_mapping %d)\n", dmrs_length, encoded_length,pdcch_pdu_rel15->precoderGranularity,pdcch_pdu_rel15->CceRegMappingType); dmrs_length += rb_offset*6; // To accommodate more DMRS symbols in case of rb offset @@ -228,17 +229,20 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, /// DCI payload processing // CRC attachment + Scrambling + Channel coding + Rate matching uint32_t encoder_output[NR_MAX_DCI_SIZE_DWORD]; - uint16_t n_RNTI = pdcch_pdu_rel15->RNTI[d]; - uint16_t Nid = pdcch_pdu_rel15->ScramblingId[d]; + + uint16_t n_RNTI = pdcch_pdu_rel15->dci_pdu.RNTI[d]; + uint16_t Nid = pdcch_pdu_rel15->dci_pdu.ScramblingId[d]; + uint16_t scrambling_RNTI = pdcch_pdu_rel15->dci_pdu.ScramblingRNTI[d]; + t_nrPolar_params *currentPtr = nr_polar_params(NR_POLAR_DCI_MESSAGE_TYPE, - pdcch_pdu_rel15->PayloadSizeBits[d], - pdcch_pdu_rel15->AggregationLevel[d], + pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d], + pdcch_pdu_rel15->dci_pdu.AggregationLevel[d], 0,NULL); - polar_encoder_fast((uint64_t*)pdcch_pdu_rel15->Payload[d], encoder_output, n_RNTI,1,currentPtr); + polar_encoder_fast((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d], encoder_output, n_RNTI,1,currentPtr); #ifdef DEBUG_CHANNEL_CODING - printf("polar rnti %x,length %d, L %d\n",n_RNTI, pdcch_pdu_rel15->PayloadSizeBits[d],pdcch_pdu_rel15->AggregationLevel[d]); + printf("polar rnti %x,length %d, L %d\n",n_RNTI, pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d],pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]); printf("DCI PDU: [0]->0x%lx \t [1]->0x%lx\n", - ((uint64_t*)pdcch_pdu_rel15->Payload[d])[0], ((uint64_t*)pdcch_pdu_rel15->Payload[d])[1]); + ((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d])[0], ((uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[d])[1]); printf("Encoded Payload (length:%d dwords):\n", encoded_length>>5); for (int i=0; i>5; i++) @@ -248,7 +252,7 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, #endif /// Scrambling uint32_t scrambled_output[NR_MAX_DCI_SIZE_DWORD]= {0}; - nr_pdcch_scrambling(encoder_output, encoded_length, Nid, n_RNTI, scrambled_output); + nr_pdcch_scrambling(encoder_output, encoded_length, Nid, scrambling_RNTI, scrambled_output); #ifdef DEBUG_CHANNEL_CODING printf("scrambled output: [0]->0x%08x \t [1]->0x%08x \t [2]->0x%08x \t [3]->0x%08x\t [4]->0x%08x\t [5]->0x%08x\t \ [6]->0x%08x \t [7]->0x%08x \t [8]->0x%08x \t [9]->0x%08x\t [10]->0x%08x\t [11]->0x%08x\n", @@ -271,8 +275,8 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, cset_start_sc -= frame_parms.ofdm_symbol_size; /*Reorder REG list for a freq first mapping*/ - uint8_t nb_regs = pdcch_pdu_rel15->AggregationLevel[d]*NR_NB_REG_PER_CCE; - uint8_t reg_idx0 = pdcch_pdu_rel15->CceIndex[d]*NR_NB_REG_PER_CCE; + uint8_t reg_idx0 = pdcch_pdu_rel15->dci_pdu.CceIndex[d]*NR_NB_REG_PER_CCE; + uint8_t nb_regs = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]*NR_NB_REG_PER_CCE; /*Mapping the encoded DCI along with the DMRS */ for (int reg_idx=reg_idx0; reg_idx<(nb_regs+reg_idx0); reg_idx++) { @@ -294,8 +298,8 @@ uint8_t nr_generate_dci_top(nfapi_nr_dl_tti_pdcch_pdu *pdcch_pdu, for (int m=0; mCceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED) { - ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (2*amp * mod_dmrs[l][dmrs_idx<<1]) >> 15; - ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (2*amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; + ((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1] = (amp * mod_dmrs[l][dmrs_idx<<1]) >> 15; + ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1) + 1] = (amp * mod_dmrs[l][(dmrs_idx<<1) + 1]) >> 15; #ifdef DEBUG_PDCCH_DMRS printf("PDCCH DMRS: l %d position %d => (%d,%d)\n",l,k,((int16_t *)txdataF)[(l*frame_parms.ofdm_symbol_size + k)<<1], ((int16_t *)txdataF)[((l*frame_parms.ofdm_symbol_size + k)<<1)+1]); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c index ccec73d40e..c0fe5e8f3a 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dci_tools.c @@ -140,7 +140,7 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) { int C; for (int d=0;dnumDlDci;d++) { - int L = pdcch_pdu_rel15->AggregationLevel[d]; + int L = pdcch_pdu_rel15->dci_pdu.AggregationLevel[d]; if (pdcch_pdu_rel15->CoreSetType == NFAPI_NR_CSET_CONFIG_MIB_SIB1) AssertFatal(L>=4, "Invalid aggregation level for SIB1 configured PDCCH %d\n", L); @@ -151,10 +151,10 @@ void nr_fill_cce_list(PHY_VARS_gNB *gNB, uint8_t m) { C = N_reg/(bsize*R); } - LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->CceIndex[d]); + LOG_D(PHY, "CCE list generation for candidate %d: bundle size %d ilv size %d CceIndex %d\n", m, bsize, R, pdcch_pdu_rel15->dci_pdu.CceIndex[d]); for (uint8_t cce_idx=0; cce_idxcce_list[d][cce_idx]; - cce->cce_idx = pdcch_pdu_rel15->CceIndex[d] + cce_idx; + cce->cce_idx = pdcch_pdu_rel15->dci_pdu.CceIndex[d] + cce_idx; LOG_D(PHY, "cce_idx %d\n", cce->cce_idx); if (pdcch_pdu_rel15->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { @@ -210,12 +210,12 @@ void nr_fill_dci(PHY_VARS_gNB *gNB, for (int i=0;inumDlDci;i++) { - uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i]; + uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i]; - int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->RNTI[i],gNB,SEARCH_EXIST_OR_FREE); + int dlsch_id = find_nr_dlsch(pdcch_pdu_rel15->dci_pdu.RNTI[i],gNB,SEARCH_EXIST_OR_FREE); if( (dlsch_id<0) || (dlsch_id>=NUMBER_OF_NR_DLSCH_MAX) ){ - LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->RNTI[i],dlsch_id); + LOG_E(PHY,"illegal dlsch_id found!!! rnti %04x dlsch_id %d\n",(unsigned int)pdcch_pdu_rel15->dci_pdu.RNTI[i],dlsch_id); return; } @@ -228,7 +228,7 @@ void nr_fill_dci(PHY_VARS_gNB *gNB, "illegal harq_pid %d\n",harq_pid); dlsch->harq_mask |= (1<rnti = pdcch_pdu_rel15->RNTI[i]; + dlsch->rnti = pdcch_pdu_rel15->dci_pdu.RNTI[i]; nr_fill_cce_list(gNB,0); /* @@ -248,7 +248,7 @@ void nr_fill_ul_dci(PHY_VARS_gNB *gNB, for (int i=0;inumDlDci;i++) { - uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->Payload[i]; + uint64_t *dci_pdu = (uint64_t*)pdcch_pdu_rel15->dci_pdu.Payload[i]; // if there's no DL DCI then generate CCE list if (gNB->pdcch_pdu) nr_fill_cce_list(gNB,0); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c index 4518280f6b..b8d9fdea18 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c @@ -133,13 +133,17 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, int16_t **mod_symbs = (int16_t**)dlsch->mod_symbs; int16_t **tx_layers = (int16_t**)dlsch->txdataF; int8_t Wf[2], Wt[2], l0, l_prime[2], delta; - + uint8_t nodata_dmrs = 1; uint8_t dmrs_Type = rel15->dmrsConfigType; int nb_re_dmrs = (dmrs_Type== NFAPI_NR_DMRS_TYPE1) ? 6:4; uint16_t n_dmrs = ((rel15->rbSize+rel15->rbStart)*nb_re_dmrs)<<1; int16_t mod_dmrs[n_dmrs<<1]; - uint16_t nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords; + uint16_t nb_re; + if (nodata_dmrs) // no data in dmrs symbol + nb_re = ((12*rel15->NrOfSymbols)-12-xOverhead)*rel15->rbSize*rel15->NrOfCodewords; + else + nb_re = ((12*rel15->NrOfSymbols)-nb_re_dmrs-xOverhead)*rel15->rbSize*rel15->NrOfCodewords; uint8_t Qm = rel15->qamModOrder[0]; uint32_t encoded_length = nb_re*Qm; @@ -297,15 +301,16 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, } else { - - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; + if( (l != dmrs_symbol) || !nodata_dmrs) { + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)] = (amp * tx_layers[ap][m<<1]) >> 15; + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)] = (amp * tx_layers[ap][(m<<1) + 1]) >> 15; #ifdef DEBUG_DLSCH_MAPPING - printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", -m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], - ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); + printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", + m, l, k, ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + (2*txdataF_offset)], + ((int16_t*)txdataF[ap])[((l*frame_parms->ofdm_symbol_size + k)<<1) + 1 + (2*txdataF_offset)]); #endif - m++; + m++; + } } if (++k >= frame_parms->ofdm_symbol_size) k -= frame_parms->ofdm_symbol_size; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h index f48905b68c..3a6851ee8f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.h +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.h @@ -90,7 +90,7 @@ uint8_t nr_generate_pdsch(NR_gNB_DLSCH_t *dlsch, -void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB); +void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB); void clean_gNB_dlsch(NR_gNB_DLSCH_t *dlsch); diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 856a7863f4..065e62a2cb 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -49,7 +49,7 @@ //#define DEBUG_DLSCH_FREE 1 -void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB) +void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr, uint16_t N_RB) { int i; int r; @@ -131,7 +131,7 @@ void free_gNB_dlsch(NR_gNB_DLSCH_t **dlschptr,uint16_t N_RB) } free16(dlsch,sizeof(NR_gNB_DLSCH_t)); - dlsch = NULL; + *dlschptr = NULL; } } @@ -336,7 +336,12 @@ int nr_dlsch_encoding(unsigned char *a, uint32_t E; uint8_t Ilbrm = 1; uint32_t Tbslbrm = 950984; //max tbs - uint8_t nb_re_dmrs = rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1 ? 6:4; + uint8_t nodata_dmrs = 1; + uint8_t nb_re_dmrs; + if (nodata_dmrs) + nb_re_dmrs = 12; + else + nb_re_dmrs = rel15->dmrsConfigType==NFAPI_NR_DMRS_TYPE1 ? 6:4; uint16_t length_dmrs = get_num_dmrs(rel15->dlDmrsSymbPos); uint16_t R=rel15->targetCodeRate[0]; float Coderate = 0.0; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index 2e6fc707bd..7702d770ee 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -274,25 +274,7 @@ int16_t find_nr_dlsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { return first_free_index; } -int16_t find_nr_ulsch(uint16_t rnti, PHY_VARS_gNB *gNB,find_type_t type) { - uint16_t i; - int16_t first_free_index=-1; - - AssertFatal(gNB!=NULL,"gNB is null\n"); - for (i=0; iulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i); - AssertFatal(gNB->ulsch[i][0]!=NULL,"gNB->ulsch[%d][0] is null\n",i); - LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i][0]->harq_mask,gNB->ulsch[i][0]->rnti,first_free_index); - if ((gNB->ulsch[i][0]->harq_mask >0) && - (gNB->ulsch[i][0]->rnti==rnti)) return i; - else if ((gNB->ulsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i; - } - if (type == SEARCH_EXIST) return -1; - if (first_free_index != -1) - gNB->ulsch[first_free_index][0]->rnti = 0; - return first_free_index; -} void nr_fill_dlsch(PHY_VARS_gNB *gNB, int frame, @@ -316,26 +298,3 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB, } -void nr_fill_ulsch(PHY_VARS_gNB *gNB, - int frame, - int slot, - nfapi_nr_pusch_pdu_t *ulsch_pdu) { - - - int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE); - AssertFatal( (ulsch_id>=0) && (ulsch_idrnti,ulsch_id); - - NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id][0]; - int harq_pid = ulsch_pdu->pusch_data.harq_process_id; - ulsch->rnti = ulsch_pdu->rnti; - //ulsch->rnti_type; - ulsch->harq_mask |= 1<harq_process_id[slot] = harq_pid; - - memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t)); - - LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid); - -} - diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 5710499e1a..2f0ea46ecd 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -34,38 +34,133 @@ #include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/NR_TRANSPORT/nr_transport_proto_common.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]; -extern uint16_t NCS_unrestricted_delta_f_RA_5[16]; -extern uint16_t NCS_restricted_TypeA_delta_f_RA_5[16]; -extern uint16_t NCS_restricted_TypeB_delta_f_RA_5[14]; -extern uint16_t NCS_unrestricted_delta_f_RA_15[16]; extern uint16_t prach_root_sequence_map_0_3[838]; extern uint16_t prach_root_sequence_map_abc[138]; -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 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]; +extern const char *prachfmt[9]; + +void init_prach_list(PHY_VARS_gNB *gNB) { + + AssertFatal(gNB!=NULL,"gNB is null\n"); + for (int i=0; iprach_vars.list[i].frame=-1; +} + +int16_t find_nr_prach(PHY_VARS_gNB *gNB,int frame,int slot, int numRA, find_type_t type) { + + uint16_t i; + int16_t first_free_index=-1; + + AssertFatal(gNB!=NULL,"gNB is null\n"); + for (i=0; i %d.%d numRA %d\n", frame,slot,numRA,i, + gNB->prach_vars.list[i].frame,gNB->prach_vars.list[i].slot,gNB->prach_vars.list[i].pdu.num_ra); + if ((gNB->prach_vars.list[i].frame == frame) && + (gNB->prach_vars.list[i].slot == slot) && + (gNB->prach_vars.list[i].pdu.num_ra == numRA)) return i; + else if ((gNB->prach_vars.list[i].frame == -1) && (first_free_index==-1)) first_free_index=i; + } + if (type == SEARCH_EXIST) return -1; + + return first_free_index; +} + +void nr_fill_prach(PHY_VARS_gNB *gNB, + int SFN, + int Slot, + nfapi_nr_prach_pdu_t *prach_pdu) { + + int prach_id = find_nr_prach(gNB,SFN,Slot,prach_pdu->num_ra,SEARCH_EXIST_OR_FREE); + AssertFatal( (prach_id>=0) && (prach_idnum_ra,prach_id); + + gNB->prach_vars.list[prach_id].frame=SFN; + gNB->prach_vars.list[prach_id].slot=Slot; + memcpy((void*)&gNB->prach_vars.list[prach_id].pdu,(void*)prach_pdu,sizeof(*prach_pdu)); + +} + +void init_prach_ru_list(RU_t *ru) { + + AssertFatal(ru!=NULL,"ruis null\n"); + for (int i=0; iprach_list[i].frame=-1; + pthread_mutex_init(&ru->prach_list_mutex,NULL); +} + +int16_t find_nr_prach_ru(RU_t *ru,int frame,int slot, find_type_t type) { + + uint16_t i; + int16_t first_free_index=-1; + + AssertFatal(ru!=NULL,"ru is null\n"); + pthread_mutex_lock(&ru->prach_list_mutex); + for (i=0; i %d.%d\n", frame,slot,i, + ru->prach_list[i].frame,ru->prach_list[i].slot); + if ((ru->prach_list[i].frame == frame) && + (ru->prach_list[i].slot == slot)) { + pthread_mutex_unlock(&ru->prach_list_mutex); + return i; + } + else if ((ru->prach_list[i].frame == -1) && (first_free_index==-1)) first_free_index=i; + } + pthread_mutex_unlock(&ru->prach_list_mutex); + if (type == SEARCH_EXIST) return -1; + + return first_free_index; +} + +void nr_fill_prach_ru(RU_t *ru, + int SFN, + int Slot, + nfapi_nr_prach_pdu_t *prach_pdu) { + + int prach_id = find_nr_prach_ru(ru,SFN,Slot,SEARCH_EXIST_OR_FREE); + AssertFatal( (prach_id>=0) && (prach_idprach_list_mutex); + ru->prach_list[prach_id].frame = SFN; + ru->prach_list[prach_id].slot = Slot; + ru->prach_list[prach_id].fmt = prach_pdu->prach_format; + ru->prach_list[prach_id].numRA = prach_pdu->num_ra; + ru->prach_list[prach_id].prachStartSymbol = prach_pdu->prach_start_symbol; + pthread_mutex_unlock(&ru->prach_list_mutex); + +} + +void free_nr_ru_prach_entry(RU_t *ru, + int prach_id) { + + pthread_mutex_lock(&ru->prach_list_mutex); + ru->prach_list[prach_id].frame=-1; + pthread_mutex_unlock(&ru->prach_list_mutex); + +} + void rx_nr_prach_ru(RU_t *ru, + int prachFormat, + int numRA, + int prachStartSymbol, int frame, - int subframe) { + int slot) { AssertFatal(ru!=NULL,"ru is null\n"); int16_t **rxsigF=NULL; NR_DL_FRAME_PARMS *fp=ru->nr_frame_parms; - int16_t prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; + int16_t *prach[ru->nb_rx]; - uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,fp->frame_type,fp->freq_range); + int prach_sequence_length = ru->config.prach_config.prach_sequence_length.value; + + int msg1_frequencystart = ru->config.prach_config.num_prach_fd_occasions_list[numRA].k1.value; rxsigF = ru->prach_rxsigF; AssertFatal(ru->if_south == LOCAL_RF,"we shouldn't call this if if_south != LOCAL_RF\n"); for (int aa=0; aanb_rx; aa++) - prach[aa] = (int16_t*)&ru->common.rxdata[aa][(subframe*fp->samples_per_subframe)-ru->N_TA_offset]; + prach[aa] = (int16_t*)&ru->common.rxdata[aa][(slot*fp->get_samples_per_slot(slot,fp))-ru->N_TA_offset]; @@ -73,87 +168,97 @@ void rx_nr_prach_ru(RU_t *ru, int Ncp; int16_t *prach2; - - switch (prach_fmt) { - case 0: - Ncp = 3168; - break; - - case 1: - Ncp = 21024; - break; - - case 2: - Ncp = 4688; - break; - - case 3: - Ncp = 3168; - break; - - case 0xa1: - Ncp = 288/(1<idx,frame,slot,prachFormat,msg1_frequencystart); + AssertFatal(prachFormat<4,"Illegal prach format %d for length 839\n",prachFormat); + switch (prachFormat) { + case 0: + Ncp = 3168; + break; + + case 1: + Ncp = 21024; + break; + + case 2: + Ncp = 4688; + break; + + case 3: + Ncp = 3168; + break; + + } } + else { + LOG_D(PHY,"PRACH (ru %d) in %d.%d, format %s, msg1_frequencyStart %d,startSymbol %d\n", + ru->idx,frame,slot,prachfmt[prachFormat],msg1_frequencystart,prachStartSymbol); + switch (prachFormat) { + case 0: //A1 + Ncp = 288/(1<N_RB_UL, ru->nb_rx, Ncp); + LOG_D(PHY,"rx_prach: Doing PRACH FFT for nb_rx:%d Ncp:%d\n",ru->nb_rx, Ncp); } AssertFatal(mu==1,"only 30 kHz SCS handled for now\n"); // Note: Assumes PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below int kbar = 1; int K = 24; - if (prach_fmt == 3) { + if (prach_sequence_length == 0 && prachFormat == 3) { K=4; kbar=10; } - else if (prach_fmt > 3) { + else if (prach_sequence_length == 1) { // Note: Assumes that PRACH SCS is same as PUSCH SCS K=1; kbar=2; } - int n_ra_prb = fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart; + int n_ra_prb = msg1_frequencystart; int k = (12*n_ra_prb) - 6*fp->N_RB_UL; - int N_ZC = (prach_fmt<4)?839:139; + int N_ZC = (prach_sequence_length==0)?839:139; if (k<0) k+=(fp->ofdm_symbol_size); @@ -173,170 +278,226 @@ void rx_nr_prach_ru(RU_t *ru, if (fp->threequarter_fs==0) { //40 MHz @ 61.44 Ms/s //50 MHz @ 61.44 Ms/s - prach2 = prach[aa] + (Ncp<<2); - if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) - dft49152(prach2,rxsigF[aa],1); - if (prach_fmt == 1 || prach_fmt == 2) { - dft49152(prach2+98304,rxsigF[aa]+98304,1); - reps++; - } - if (prach_fmt == 2) { - dft49152(prach2+(98304*2),rxsigF[aa]+(98304*2),1); - dft49152(prach2+(98304*3),rxsigF[aa]+(98304*3),1); - reps+=2; - } - if (prach_fmt == 3) { - for (int i=0;i<4;i++) dft12288(prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1); - reps=4; - } - if (prach_fmt >3) { - dft2048(prach2,rxsigF[aa],1); - if (prach_fmt != 0xc0) { - dft2048(prach2+4096,rxsigF[aa]+4096,1); + prach2 = prach[aa] + (Ncp<<2); // Ncp is for 30.72 Ms/s, so multiply by 2 for I/Q, and 2 to bring to 61.44 Ms/s + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=49152; + dft49152(prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft49152(prach2+98304,rxsigF[aa]+98304,1); reps++; } - } - if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) { - dft2048(prach2+4096*2,rxsigF[aa]+4096*2,1); - dft2048(prach2+4096*3,rxsigF[aa]+4096*3,1); - reps+=2; - } - if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) { - dft2048(prach2+4096*4,rxsigF[aa]+4096*4,1); - dft2048(prach2+4096*5,rxsigF[aa]+4096*5,1); - reps+=2; - } - if (prach_fmt == 0xc2) { - for (int i=6;i<11;i++) dft2048(prach2+(3072*i),rxsigF[aa]+(3072*i),1); - reps+=6; + if (prachFormat == 2) { + dft49152(prach2+(98304*2),rxsigF[aa]+(98304*2),1); + dft49152(prach2+(98304*3),rxsigF[aa]+(98304*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=12288; + for (int i=0;i<4;i++) dft12288(prach2+(i*12288*2),rxsigF[aa]+(i*12288*2),1); + reps=4; + } + }// 839 sequence + else { + if ((mu==0 && + (prachStartSymbol == 0 || prachStartSymbol == 7)) || + (mu==1 && prachStartSymbol == 0)) prach2+=64; // 32 samples @ 61.44 Ms/s in first symbol of each half subframe (15/30 kHz only) + + if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==1) { + dftlen=2048; + dft2048(prach2,rxsigF[aa],1); + if (prachFormat != 7) { // !=C0 + dft2048(prach2+4096,rxsigF[aa]+4096,1); + reps++; + } + if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) { + dft2048(prach2+4096*2,rxsigF[aa]+4096*2,1); + dft2048(prach2+4096*3,rxsigF[aa]+4096*3,1); + reps+=2; + } + if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) { + dft2048(prach2+4096*4,rxsigF[aa]+4096*4,1); + dft2048(prach2+4096*5,rxsigF[aa]+4096*5,1); + reps+=2; + } + if (prachFormat == 6) { + for (int i=6;i<12;i++) dft2048(prach2+(4096*i),rxsigF[aa]+(4096*i),1); + reps+=6; + } + } + else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); } - } else { + } else { // threequarter sampling // 40 MHz @ 46.08 Ms/s - prach2 = prach[aa] + (3*Ncp); - AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n"); - if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) { - dft36864(prach2,rxsigF[aa],1); - reps++; - } - if (prach_fmt == 1 || prach_fmt == 2) { - dft36864(prach2+73728,rxsigF[aa]+73728,1); - reps++; - } - if (prach_fmt == 2) { - dft36864(prach2+(98304*2),rxsigF[aa]+(98304*2),1); - dft36864(prach2+(98304*3),rxsigF[aa]+(98304*3),1); - reps+=2; - } - if (prach_fmt == 3) { - for (int i=0;i<4;i++) dft9216(prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1); - reps=4; - } - if (prach_fmt >3) { - dft1536(prach2,rxsigF[aa],1); - if (prach_fmt != 0xc0) { - dft1536(prach2+3072,rxsigF[aa]+3072,1); + prach2 = prach[aa] + (3*Ncp); // 46.08 is 1.5 * 30.72, times 2 for I/Q + if (prach_sequence_length == 0) { + AssertFatal(fp->N_RB_UL <= 107,"cannot do 108..136 PRBs with 3/4 sampling\n"); + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=36864; + dft36864(prach2,rxsigF[aa],1); reps++; } - } - if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) { - dft1536(prach2+3072*2,rxsigF[aa]+3072*2,1); - dft1536(prach2+3072*3,rxsigF[aa]+3072*3,1); - reps+=2; - } - if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) { - dft1536(prach2+3072*4,rxsigF[aa]+3072*4,1); - dft1536(prach2+3072*5,rxsigF[aa]+3072*5,1); - reps+=2; - } - if (prach_fmt == 0xc2) { - for (int i=6;i<11;i++) dft1536(prach2+(3072*i),rxsigF[aa]+(3072*i),1); - reps+=6; - } - } - } + if (prachFormat == 1 || prachFormat == 2) { + dft36864(prach2+73728,rxsigF[aa]+73728,1); + reps++; + } + if (prachFormat == 2) { + dft36864(prach2+(73728*2),rxsigF[aa]+(73728*2),1); + dft36864(prach2+(73728*3),rxsigF[aa]+(73728*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=9216; + for (int i=0;i<4;i++) dft9216(prach2+(i*9216*2),rxsigF[aa]+(i*9216*2),1); + reps=4; + } + } else { + if ((mu==0 && + (prachStartSymbol == 0 || prachStartSymbol == 7)) || + (mu==1 && prachStartSymbol == 0)) prach2+=48; // 24 samples @ 46.08 Ms/s in first symbol of each half subframe (15/30 kHz only) + if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==1) { + dftlen=1536; + dft1536(prach2,rxsigF[aa],1); + if (prachFormat != 7) { + dft1536(prach2+3072,rxsigF[aa]+3072,1); + reps++; + } + + if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) { + dft1536(prach2+3072*2,rxsigF[aa]+3072*2,1); + dft1536(prach2+3072*3,rxsigF[aa]+3072*3,1); + reps+=2; + } + if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) { + dft1536(prach2+3072*4,rxsigF[aa]+3072*4,1); + dft1536(prach2+3072*5,rxsigF[aa]+3072*5,1); + reps+=2; + } + if (prachFormat == 6) { + for (int i=6;i<12;i++) dft1536(prach2+(3072*i),rxsigF[aa]+(3072*i),1); + reps+=6; + } + }// mu==1 + else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); + } // short format + } // 3/4 sampling + } // <=50 MHz BW else if (fp->N_RB_UL <= 273) { if (fp->threequarter_fs==0) { prach2 = prach[aa] + (Ncp<<3); - dftlen=98304; - //80,90,100 MHz @ 61.44 Ms/s - if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) - dft98304(prach2,rxsigF[aa],1); - if (prach_fmt == 1 || prach_fmt == 2) { - dft98304(prach2+196608,rxsigF[aa]+196608,1); - reps++; - } - if (prach_fmt == 1 || prach_fmt == 2) { - dft98304(prach2+196608,rxsigF[aa]+196608,1); - dft98304(prach2+(196608*2),rxsigF[aa]+(196608*2),1); - reps+=2; - } - if (prach_fmt == 3) { - dft24576(prach2+(2*49152),rxsigF[aa]+(2*49152),1); - reps=4; - dftlen=24576; - } - if (prach_fmt >3) { - dftlen=4096; - dft4096(prach2,rxsigF[aa],1); - if (prach_fmt != 0xc0) { - dft4096(prach2+8192,rxsigF[aa]+8192,1); + //80,90,100 MHz @ 122.88 Ms/s + + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=98304; + dft98304(prach2,rxsigF[aa],1); + } + if (prachFormat == 1 || prachFormat == 2) { + dft98304(prach2+196608,rxsigF[aa]+196608,1); reps++; } - } - if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) { - dft4096(prach2+8192*2,rxsigF[aa]+8192*2,1); - dft4096(prach2+8192*3,rxsigF[aa]+8192*3,1); - reps+=2; - } - if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) { - dft4096(prach2+8192*4,rxsigF[aa]+8192*4,1); - dft4096(prach2+8192*5,rxsigF[aa]+8192*5,1); - reps+=2; - } - if (prach_fmt == 0xc2) { - for (int i=6;i<11;i++) dft4096(prach2+(8192*i),rxsigF[aa]+(8192*i),1); - reps+=6; + if (prachFormat == 2) { + dft98304(prach2+196608*2,rxsigF[aa]+196608*2,1); + dft98304(prach2+(196608*3),rxsigF[aa]+(196608*3),1); + reps+=2; + } + if (prachFormat == 3) { + dftlen=24576; + for (int i=0;i<4;i++) dft24576(prach2+(i*2*24576),rxsigF[aa]+(i*2*24576),1); + reps=4; + } + } + else { + if ((mu==0 && + (prachStartSymbol == 0 || prachStartSymbol == 7)) || + (mu==1 && prachStartSymbol == 0)) prach2+=128; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + + if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==1) { + dftlen=4096; + dft4096(prach2,rxsigF[aa],1); + if (prachFormat != 7) { //!=C0 + dft4096(prach2+8192,rxsigF[aa]+8192,1); + reps++; + } + + if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) { + dft4096(prach2+8192*2,rxsigF[aa]+8192*2,1); + dft4096(prach2+8192*3,rxsigF[aa]+8192*3,1); + reps+=2; + } + if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) { + dft4096(prach2+8192*4,rxsigF[aa]+8192*4,1); + dft4096(prach2+8192*5,rxsigF[aa]+8192*5,1); + reps+=2; + } + if (prachFormat == 6) { + for (int i=6;i<12;i++) dft4096(prach2+(8192*i),rxsigF[aa]+(8192*i),1); + reps+=6; + } + } + else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); } } else { AssertFatal(fp->N_RB_UL <= 217,"cannot do more than 217 PRBs with 3/4 sampling\n"); prach2 = prach[aa] + (6*Ncp); - // 80 MHz @ 46.08 Ms/s - dftlen=73728; - if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) { - dft73728(prach2,rxsigF[aa],1); - reps++; - } - if (prach_fmt == 1 || prach_fmt == 2) { - dft73728(prach2+(2*73728),rxsigF[aa]+(2*73728),1); - reps++; - } - if (prach_fmt == 3) { - dft73728(prach2+(4*73728),rxsigF[aa]+(4*73728),1); - reps=4; - dftlen=18432; - } - - if (prach_fmt >3) { - dftlen=3072; - dft3072(prach2,rxsigF[aa],1); - if (prach_fmt != 0xc0) { - dft3072(prach2+6144,rxsigF[aa]+6144,1); + // 80 MHz @ 92.16 Ms/s + if (prach_sequence_length == 0) { + if (prachFormat == 0 || prachFormat == 1 || prachFormat == 2) { + dftlen=73728; + dft73728(prach2,rxsigF[aa],1); reps++; } - } - if (prach_fmt == 0xa2 || prach_fmt == 0xa3 || prach_fmt == 0xb2 || prach_fmt == 0xb3 || prach_fmt == 0xb4 || prach_fmt == 0xc2) { - dft3072(prach2+6144*2,rxsigF[aa]+6144*2,1); - dft3072(prach2+6144*3,rxsigF[aa]+6144*3,1); - reps+=2; - } - if (prach_fmt == 0xa3 || prach_fmt == 0xb3 || prach_fmt == 0xc2) { - dft3072(prach2+6144*4,rxsigF[aa]+6144*4,1); - dft3072(prach2+6144*5,rxsigF[aa]+6144*5,1); - reps+=2; - } - if (prach_fmt == 0xc2) { - for (int i=6;i<11;i++) dft3072(prach2+(6144*i),rxsigF[aa]+(6144*i),1); - reps+=6; + if (prachFormat == 1 || prachFormat == 2) { + dft73728(prach2+(2*73728),rxsigF[aa]+(2*73728),1); + reps++; + } + if (prachFormat == 3) { + dftlen=18432; + for (int i=0;i<4;i++) dft18432(prach2+(i*2*18432),rxsigF[aa]+(i*2*18432),1); + reps=4; + } + } else { + if ((mu==0 && + (prachStartSymbol == 0 || prachStartSymbol == 7)) || + (mu==1 && prachStartSymbol == 0)) prach2+=96; // 64 samples @ 122.88 Ms/s in first symbol of each half subframe (15/30 kHz only) + + if (mu==0) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==1) { + dftlen=3072; + dft3072(prach2,rxsigF[aa],1); + if (prachFormat != 7) { //!=C0 + dft3072(prach2+6144,rxsigF[aa]+6144,1); + reps++; + } + + if (prachFormat == 1 || prachFormat == 2 || prachFormat == 4 || prachFormat == 5 || prachFormat == 6 || prachFormat == 8) { + dft3072(prach2+6144*2,rxsigF[aa]+6144*2,1); + dft3072(prach2+6144*3,rxsigF[aa]+6144*3,1); + reps+=2; + } + if (prachFormat == 2 || prachFormat == 5 || prachFormat == 6) { + dft3072(prach2+6144*4,rxsigF[aa]+6144*4,1); + dft3072(prach2+6144*5,rxsigF[aa]+6144*5,1); + reps+=2; + } + if (prachFormat == 6) { + for (int i=6;i<12;i++) dft3072(prach2+(6144*i),rxsigF[aa]+(6144*i),1); + reps+=6; + } + } + else if (mu==2) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==3) AssertFatal(1==0,"Shouldn't get here\n"); + else if (mu==4) AssertFatal(1==0,"Shouldn't get here\n"); } } } @@ -350,7 +511,7 @@ void rx_nr_prach_ru(RU_t *ru, for (int j=0;jgNB_config.prach_config; NR_DL_FRAME_PARMS *fp; - lte_frame_type_t frame_type; + uint16_t rootSequenceIndex; - uint8_t prach_ConfigIndex; - uint8_t Ncs_config; + int numrootSequenceIndex; uint8_t restricted_set; uint8_t n_ra_prb; int16_t *prachF=NULL; @@ -403,63 +565,46 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, int16_t prach_ifft_tmp[2048*2] __attribute__((aligned(32))); int32_t *prach_ifft=(int32_t*)NULL; - nr_frequency_range_e freq_range; - - AssertFatal(gNB!=NULL,"Can only be called from gNB\n"); - fp = &gNB->frame_parms; - nb_rx = fp->nb_antennas_rx; - - frame_type = fp->frame_type; - freq_range = fp->freq_range; - rootSequenceIndex = fp->prach_config_common.rootSequenceIndex; - prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; - Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig; - restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag; - - - uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,frame_type,freq_range); - uint16_t N_ZC = (prach_fmt <4)?839:139; AssertFatal(gNB!=NULL,"gNB is null\n"); + fp = &gNB->frame_parms; + + nb_rx = gNB->gNB_config.carrier_config.num_rx_ant.value; + + rootSequenceIndex = cfg->num_prach_fd_occasions_list[0].prach_root_sequence_index.value; + numrootSequenceIndex = cfg->num_prach_fd_occasions_list[0].num_root_sequences.value; + NCS = prach_pdu->num_cs;//cfg->num_prach_fd_occasions_list[0].prach_zero_corr_conf.value; + int prach_sequence_length = cfg->prach_sequence_length.value; + + int msg1_frequencystart = cfg->num_prach_fd_occasions_list[0].k1.value; + // int num_unused_root_sequences = cfg->num_prach_fd_occasions_list[0].num_unused_root_sequences.value; + // cfg->num_prach_fd_occasions_list[0].unused_root_sequences_list + + restricted_set = cfg->restricted_set_config.value; + + AssertFatal(prach_sequence_length == 1, "no support yet for long prachSequenceLength\n"); + + + uint8_t prach_fmt = prach_pdu->prach_format; + uint16_t N_ZC = (prach_sequence_length==0)?839:139; + + LOG_D(PHY,"L1 PRACH RX: rooSequenceIndex %d, numRootSeqeuences %d, NCS %d, N_ZC %d \n", rootSequenceIndex,numrootSequenceIndex,NCS,N_ZC); + prach_ifft = gNB->prach_vars.prach_ifft; prachF = gNB->prach_vars.prachF; if (LOG_DEBUGFLAG(PRACH)){ - if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for subframe %d, msg1_frequencystart %d, prach_ConfigIndex %d , rootSequenceIndex %d\n", subframe,fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart,prach_ConfigIndex,rootSequenceIndex); + if ((frame&1023) < 20) LOG_D(PHY,"PRACH (gNB) : running rx_prach for subframe %d, msg1_frequencystart %d, rootSequenceIndex %d\n", subframe,msg1_frequencystart,rootSequenceIndex); } - - int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME - if (prach_fmt<3){ - if (restricted_set == 0) { - NCS = NCS_unrestricted_delta_f_RA_125[Ncs_config]; - } else { - if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[Ncs_config]; // for TypeA, this is hardcoded. FIXME - if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[Ncs_config]; // for TypeB, this is hardcoded. FIXME - } - } - if (prach_fmt==3){ - if (restricted_set == 0) { - NCS = NCS_unrestricted_delta_f_RA_5[Ncs_config]; - } else { - if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[Ncs_config]; // for TypeA, this is hardcoded. FIXME - if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[Ncs_config]; // for TypeB, this is hardcoded. FIXME - } - } - if (prach_fmt>3){ - NCS = NCS_unrestricted_delta_f_RA_15[Ncs_config]; - } - - AssertFatal(NCS!=99,"NCS has not been set\n"); - - if (gNB) start_meas(&gNB->rx_prach); + start_meas(&gNB->rx_prach); - prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc; + prach_root_sequence_map = (cfg->prach_sequence_length.value==0) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc; // PDP is oversampled, e.g. 1024 sample instead of 839 // Adapt the NCS (zero-correlation zones) with oversampling factor e.g. 1024/839 @@ -472,6 +617,9 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, *max_preamble_energy=0; + *max_preamble_delay=0; + *max_preamble=0; + for (preamble_index=0 ; preamble_index<64 ; preamble_index++) { if (LOG_DEBUGFLAG(PRACH)){ @@ -481,7 +629,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, if (restricted_set == 0) { // This is the relative offset in the root sequence table (5.7.2-4 from 36.211) for the given preamble index preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS))); - + if (preamble_offset != preamble_offset_old) { preamble_offset_old = preamble_offset; new_dft = 1; @@ -511,13 +659,6 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, // current root depending on rootSequenceIndex int index = (rootSequenceIndex + preamble_offset) % N_ZC; - if (prach_fmt<4) { - // prach_root_sequence_map points to prach_root_sequence_map0_3 - DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) ); - } else { - // prach_root_sequence_map points to prach_root_sequence_map4 - DevAssert( index < sizeof(prach_root_sequence_map_abc) / sizeof(prach_root_sequence_map_abc[0]) ); - } u = prach_root_sequence_map[index]; uint16_t n_group_ra = 0; @@ -562,14 +703,21 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, // Compute DFT of RX signal (conjugate input, results in conjugate output) for each new rootSequenceIndex if (LOG_DEBUGFLAG(PRACH)) { int en = dB_fixed(signal_energy((int32_t*)&rxsigF[0][0],840)); - if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d, NCS %d, NCS_config %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n", - frame,subframe,preamble_index,NCS,Ncs_config,N_ZC/NCS,preamble_offset,preamble_shift,en); + if (en>60) LOG_I(PHY,"frame %d, subframe %d : preamble index %d, NCS %d, N_ZC/NCS %d: offset %d, preamble shift %d , en %d)\n", + frame,subframe,preamble_index,NCS,N_ZC/NCS,preamble_offset,preamble_shift,en); } + LOG_D(PHY,"PRACH RX preamble_index %d, preamble_offset %d\n",preamble_index,preamble_offset); + + if (new_dft == 1) { new_dft = 0; Xu=(int16_t*)gNB->X_u[preamble_offset-first_nonzero_root_idx]; + + LOG_D(PHY,"PRACH RX new dft preamble_offset-first_nonzero_root_idx %d\n",preamble_offset-first_nonzero_root_idx); + + memset(prach_ifft,0,((N_ZC==839) ? 2048 : 256)*sizeof(int32_t)); @@ -593,13 +741,13 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, idft1024(prachF,prach_ifft_tmp,1); // compute energy and accumulate over receive antennas for (i=0;i<2048;i++) - prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[i<<1] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>10; + prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[i<<1] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10; } else { idft256(prachF,prach_ifft_tmp,1); log2_ifft_size = 8; // compute energy and accumulate over receive antennas and repetitions for BR for (i=0;i<256;i++) - prach_ifft[i] += (prach_ifft_tmp[i<<1]*prach_ifft_tmp[(i<<1)] + prach_ifft_tmp[1+(i<<1)]*prach_ifft_tmp[1+(i<<1)])>>10; + prach_ifft[i] += ((int32_t)prach_ifft_tmp[i<<1]*(int32_t)prach_ifft_tmp[(i<<1)] + (int32_t)prach_ifft_tmp[1+(i<<1)]*(int32_t)prach_ifft_tmp[1+(i<<1)])>>10; } if (LOG_DUMPFLAG(PRACH)) { @@ -617,7 +765,6 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, for (i=0; i*max_preamble_energy) { *max_preamble_energy = levdB; *max_preamble_delay = i; // Note: This has to be normalized to the 30.72 Ms/s sampling rate @@ -626,6 +773,31 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, } }// preamble_index + + // The conversion from *max_preamble_delay from TA value is done here. + // It is normalized to the 30.72 Ms/s, considering the numerology, N_RB and the sampling rate + // See table 6.3.3.1 -1 and -2 in 38211. + + // Format 0, 1, 2: 24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s + // By solving: + // max_preamble_delay * ( (24576*(fs/30.72M)) / 1024 ) / fs = TA * 16 * 64 / 2^mu * Tc + + // Format 3: 6144 samples @ 30.72 Ms/s, 24576 samples @ 122.88 Ms/s + // By solving: + // max_preamble_delay * ( (6144*(fs/30.72M)) / 1024 ) / fs = TA * 16 * 64 / 2^mu * Tc + + // Format >3: 2048/2^mu samples @ 30.72 Ms/s, 2048/2^mu * 4 samples @ 122.88 Ms/s + // By solving: + // max_preamble_delay * ( (2048/2^mu*(fs/30.72M)) / 256 ) / fs = TA * 16 * 64 / 2^mu * Tc + uint16_t *TA = max_preamble_delay; + int mu = fp->numerology_index; + if (cfg->prach_sequence_length.value==0) { + if (prach_fmt == 0 || prach_fmt == 1 || prach_fmt == 2) *TA = *TA*3*(1<60) { @@ -644,7 +816,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, LOG_M("prach_ifft0.m","prach_t0",prach_ifft,1024,1,1); } } /* LOG_DUMPFLAG(PRACH) */ - if (gNB) stop_meas(&gNB->rx_prach); + stop_meas(&gNB->rx_prach); } diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.h b/openair1/PHY/NR_TRANSPORT/nr_prach.h index 1e2b758035..d158e04c79 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.h +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.h @@ -37,18 +37,6 @@ uint16_t nr_du[838]; /************************************* * The following tables defined for NR **************************************/ -// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz -uint16_t NCS_unrestricted_delta_f_RA_125[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419}; -uint16_t NCS_restricted_TypeA_delta_f_RA_125[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case set Type A -uint16_t NCS_restricted_TypeB_delta_f_RA_125[13] = {15,18,22,26,32,38,46,55,68,82,100,118,137}; // high-speed case set Type B - -// Table 6.3.3.1-6 (38.211) NCS for preamble formats with delta_f_RA = 5 KHz -uint16_t NCS_unrestricted_delta_f_RA_5[16] = {0,13,26,33,38,41,49,55,64,76,93,119,139,209,279,419}; -uint16_t NCS_restricted_TypeA_delta_f_RA_5[16] = {36,57,72,81,89,94,103,112,121,132,137,152,173,195,216,237}; // high-speed case set Type A -uint16_t NCS_restricted_TypeB_delta_f_RA_5[14] = {36,57,60,63,65,68,71,77,81,85,97,109,122,137}; // high-speed case set Type B - -// Table 6.3.3.1-7 (38.211) NCS for preamble formats with delta_f_RA = 15 * 2mu KHz where mu = {0,1,2,3} -uint16_t NCS_unrestricted_delta_f_RA_15[16] = {0,2,4,6,8,10,12,13,15,17,19,23,27,34,46,69}; //Table 6.3.3.1-3: Mapping from logical index i to sequence number u for preamble formats with L_RA = 839 uint16_t prach_root_sequence_map_0_3[838] = { @@ -105,787 +93,3 @@ uint16_t prach_root_sequence_map_abc[138] = { 51, 88 , 52, 87 , 53, 86 , 54, 85 , 55, 84 , 56, 83 , 57, 82 , 58, 81 , 59, 80 , 60, 79 , 61, 78 , 62, 77 , 63, 76 , 64, 75 , 65, 74 , 66, 73 , 67, 72 , 68, 71 , 69, 70 }; - -// Table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink -// the column 5, (SFN_nbr is a bitmap where we set bit to '1' in the position of the subframe where the RACH can be sent. -// E.g. in row 4, and column 5 we have set value 512 ('1000000000') which means RACH can be sent at subframe 9. -// E.g. in row 20 and column 5 we have set value 66 ('0001000010') which means RACH can be sent at subframe 1 or 6 -int64_t table_6_3_3_2_2_prachConfig_Index [256][9] = { -//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration -{0, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{0, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 -{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 -{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 -{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 -{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 -{0, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 -{0, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 -{0, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9 -{0, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8 -{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9 -{0, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{1, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{1, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{1, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 -{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 -{1, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 -{1, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 -{1, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 -{1, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 -{1, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 -{1, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3,6,9 -{2, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 4, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 2, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 2, 0, 32, 0, -1, -1, 0}, // (subframe number) 5 -{2, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{2, -1, 1, 0, 32, 0, -1, -1, 0}, // (subframe number) 5 -{3, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{3, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{3, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 -{3, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 -{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 -{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 -{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 -{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 -{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 -{3, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 -{3, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 -{3, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9 -{3, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8 -{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9 -{3, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{0xa1, -1, 16, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 -{0xa1, -1, 16, 1, 16, 0, 2, 6, 2}, // (subframe number) 4 -{0xa1, -1, 8, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 -{0xa1, -1, 8, 1, 16, 0, 2, 6, 2}, // (subframe number) 4 -{0xa1, -1, 4, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 -{0xa1, -1, 4, 1, 528, 0, 1, 6, 2}, // (subframe number) 4,9 -{0xa1, -1, 4, 0, 16, 0, 2, 6, 2}, // (subframe number) 4 -{0xa1, -1, 2, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 -{0xa1, -1, 2, 0, 2, 0, 2, 6, 2}, // (subframe number) 1 -{0xa1, -1, 2, 0, 16, 0, 2, 6, 2}, // (subframe number) 4 -{0xa1, -1, 2, 0, 128, 0, 2, 6, 2}, // (subframe number) 7 -{0xa1, -1, 1, 0, 16, 0, 1, 6, 2}, // (subframe number) 4 -{0xa1, -1, 1, 0, 66, 0, 1, 6, 2}, // (subframe number) 1,6 -{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 -{0xa1, -1, 1, 0, 2, 0, 2, 6, 2}, // (subframe number) 1 -{0xa1, -1, 1, 0, 128, 0, 2, 6, 2}, // (subframe number) 7 -{0xa1, -1, 1, 0, 132, 0, 2, 6, 2}, // (subframe number) 2,7 -{0xa1, -1, 1, 0, 146, 0, 2, 6, 2}, // (subframe number) 1,4,7 -{0xa1, -1, 1, 0, 341, 0, 2, 6, 2}, // (subframe number) 0,2,4,6,8 -{0xa1, -1, 1, 0, 1023, 0, 2, 6, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{0xa1, -1, 1, 0, 682, 0, 2, 6, 2}, // (subframe number) 1,3,5,7,9 -{0xa1, 0xb1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 -{0xa1, 0xb1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4 -{0xa1, 0xb1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4 -{0xa1, 0xb1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6 -{0xa1, 0xb1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 -{0xa1, 0xb1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1 -{0xa1, 0xb1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7 -{0xa1, 0xb1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7 -{0xa1, 0xb1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8 -{0xa2, -1, 16, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9 -{0xa2, -1, 16, 1, 16, 0, 2, 3, 4}, // (subframe number) 4 -{0xa2, -1, 8, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9 -{0xa2, -1, 8, 1, 16, 0, 2, 3, 4}, // (subframe number) 4 -{0xa2, -1, 4, 0, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9 -{0xa2, -1, 4, 0, 16, 0, 2, 3, 4}, // (subframe number) 4 -{0xa2, -1, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9 -{0xa2, -1, 2, 0, 2, 0, 2, 3, 4}, // (subframe number) 1 -{0xa2, -1, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4 -{0xa2, -1, 2, 0, 128, 0, 2, 3, 4}, // (subframe number) 7 -{0xa2, -1, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4 -{0xa2, -1, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6 -{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9 -{0xa2, -1, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1 -{0xa2, -1, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7 -{0xa2, -1, 1, 0, 132, 0, 2, 3, 4}, // (subframe number) 2,7 -{0xa2, -1, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7 -{0xa2, -1, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8 -{0xa2, -1, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{0xa2, -1, 1, 0, 682, 0, 2, 3, 4}, // (subframe number) 1,3,5,7,9 -{0xa2, 0xb2, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9 -{0xa2, 0xb2, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4 -{0xa2, 0xb2, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4 -{0xa2, 0xb2, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6 -{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9 -{0xa2, 0xb2, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1 -{0xa2, 0xb2, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7 -{0xa2, 0xb2, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7 -{0xa2, 0xb2, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8 -{0xa2, 0xb2, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{0xa3, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9 -{0xa3, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4 -{0xa3, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9 -{0xa3, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4 -{0xa3, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9 -{0xa3, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4 -{0xa3, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9 -{0xa3, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1 -{0xa3, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4 -{0xa3, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7 -{0xa3, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4 -{0xa3, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6 -{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9 -{0xa3, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1 -{0xa3, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7 -{0xa3, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7 -{0xa3, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7 -{0xa3, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8 -{0xa3, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{0xa3, -1, 1, 0, 682, 0, 2, 2, 6}, // (subframe number) 1,3,5,7,9 -{0xa3, 0xb3, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9 -{0xa3, 0xb3, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4 -{0xa3, 0xb3, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4 -{0xa3, 0xb3, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6 -{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9 -{0xa3, 0xb3, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1 -{0xa3, 0xb3, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7 -{0xa3, 0xb3, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7 -{0xa3, 0xb3, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8 -{0xa3, 0xb3, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{0xb1, -1, 16, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 -{0xb1, -1, 16, 1, 16, 0, 2, 7, 2}, // (subframe number) 4 -{0xb1, -1, 8, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 -{0xb1, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4 -{0xb1, -1, 4, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 -{0xb1, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9 -{0xb1, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4 -{0xb1, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 -{0xb1, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1 -{0xb1, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4 -{0xb1, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7 -{0xb1, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4 -{0xb1, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6 -{0xb1, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 -{0xb1, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1 -{0xb1, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7 -{0xb1, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7 -{0xb1, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7 -{0xb1, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8 -{0xb1, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{0xb1, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9 -{0xb4, -1, 16, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9 -{0xb4, -1, 16, 1, 16, 0, 2, 1, 12}, // (subframe number) 4 -{0xb4, -1, 8, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9 -{0xb4, -1, 8, 1, 16, 0, 2, 1, 12}, // (subframe number) 4 -{0xb4, -1, 4, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9 -{0xb4, -1, 4, 0, 16, 0, 2, 1, 12}, // (subframe number) 4 -{0xb4, -1, 4, 1, 528, 0, 2, 1, 12}, // (subframe number) 4,9 -{0xb4, -1, 2, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9 -{0xb4, -1, 2, 0, 2, 0, 2, 1, 12}, // (subframe number) 1 -{0xb4, -1, 2, 0, 16, 0, 2, 1, 12}, // (subframe number) 4 -{0xb4, -1, 2, 0, 128, 0, 2, 1, 12}, // (subframe number) 7 -{0xb4, -1, 1, 0, 2, 0, 2, 1, 12}, // (subframe number) 1 -{0xb4, -1, 1, 0, 16, 0, 2, 1, 12}, // (subframe number) 4 -{0xb4, -1, 1, 0, 128, 0, 2, 1, 12}, // (subframe number) 7 -{0xb4, -1, 1, 0, 66, 0, 2, 1, 12}, // (subframe number) 1,6 -{0xb4, -1, 1, 0, 132, 0, 2, 1, 12}, // (subframe number) 2,7 -{0xb4, -1, 1, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9 -{0xb4, -1, 1, 0, 146, 0, 2, 1, 12}, // (subframe number) 1,4,7 -{0xb4, -1, 1, 0, 341, 0, 2, 1, 12}, // (subframe number) 0,2,4,6,8 -{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{0xb4, -1, 1, 0, 682, 0, 2, 1, 12}, // (subframe number) 1,3,5,7,9 -{0xc0, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4 -{0xc0, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9 -{0xc0, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4 -{0xc0, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 -{0xc0, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1 -{0xc0, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4 -{0xc0, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7 -{0xc0, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4 -{0xc0, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6 -{0xc0, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 -{0xc0, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1 -{0xc0, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7 -{0xc0, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7 -{0xc0, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7 -{0xc0, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8 -{0xc0, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{0xc0, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9 -{0xc2, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9 -{0xc2, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4 -{0xc2, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9 -{0xc2, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4 -{0xc2, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9 -{0xc2, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4 -{0xc2, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9 -{0xc2, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1 -{0xc2, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4 -{0xc2, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7 -{0xc2, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4 -{0xc2, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6 -{0xc2, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9 -{0xc2, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1 -{0xc2, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7 -{0xc2, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7 -{0xc2, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7 -{0xc2, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8 -{0xc2, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 -{0xc2, -1, 1, 0, 682, 0, 2, 2, 6} // (subframe number) 1,3,5,7,9 -}; -// Table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum -int64_t table_6_3_3_2_3_prachConfig_Index [256][9] = { -//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration -{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4) -{0, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{0, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8) -{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{0, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6) -{0, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5) -{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{0, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3) -{0, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2) -{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6) -{0, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6) -{0, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9) -{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8) -{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7) -{0, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9) -{0, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9) -{0, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9) -{0, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9) -{0, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9) -{0, -1, 1, 0, 960, 0, -1, -1, 0}, // (subrame number 6,7,8,9) -{0, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9) -{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9) -{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 2, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subrame number 7) -{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{2, -1, 16, 1, 64, 0, -1, -1, 0}, // (subrame number 6) -{2, -1, 8, 1, 64, 0, -1, -1, 0}, // (subrame number 6) -{2, -1, 4, 1, 64, 0, -1, -1, 0}, // (subrame number 6) -{2, -1, 2, 0, 64, 7, -1, -1, 0}, // (subrame number 6) -{2, -1, 2, 1, 64, 7, -1, -1, 0}, // (subrame number 6) -{2, -1, 1, 0, 64, 7, -1, -1, 0}, // (subrame number 6) -{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4) -{3, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9) -{3, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8) -{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) -{3, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6) -{3, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5) -{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4) -{3, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3) -{3, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2) -{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6) -{3, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6) -{3, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9) -{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8) -{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7) -{3, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9) -{3, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9) -{3, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9) -{3, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9) -{3, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9) -{3, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9) -{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9) -{0xa1, -1, 16, 1, 512, 0, 2, 6, 2}, // (subrame number 9) -{0xa1, -1, 8, 1, 512, 0, 2, 6, 2}, // (subrame number 9) -{0xa1, -1, 4, 1, 512, 0, 1, 6, 2}, // (subrame number 9) -{0xa1, -1, 2, 1, 512, 0, 1, 6, 2}, // (subrame number 9) -{0xa1, -1, 2, 1, 528, 7, 1, 3, 2}, // (subrame number 4,9) -{0xa1, -1, 2, 1, 640, 7, 1, 3, 2}, // (subrame number 7,9) -{0xa1, -1, 2, 1, 640, 0, 1, 6, 2}, // (subrame number 7,9) -{0xa1, -1, 2, 1, 768, 0, 2, 6, 2}, // (subrame number 8,9) -{0xa1, -1, 2, 1, 528, 0, 2, 6, 2}, // (subrame number 4,9) -{0xa1, -1, 2, 1, 924, 0, 1, 6, 2}, // (subrame number 2,3,4,7,8,9) -{0xa1, -1, 1, 0, 512, 0, 2, 6, 2}, // (subrame number 9) -{0xa1, -1, 1, 0, 512, 7, 1, 3, 2}, // (subrame number 9) -{0xa1, -1, 1, 0, 512, 0, 1, 6, 2}, // (subrame number 9) -{0xa1, -1, 1, 0, 768, 0, 2, 6, 2}, // (subrame number 8,9) -{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subrame number 4,9) -{0xa1, -1, 1, 0, 640, 7, 1, 3, 2}, // (subrame number 7,9) -{0xa1, -1, 1, 0, 792, 0, 1, 6, 2}, // (subrame number 3,4,8,9) -{0xa1, -1, 1, 0, 792, 0, 2, 6, 2}, // (subrame number 3,4,8,9) -{0xa1, -1, 1, 0, 682, 0, 1, 6, 2}, // (subrame number 1,3,5,7,9) -{0xa1, -1, 1, 0, 1023, 7, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9) -{0xa2, -1, 16, 1, 512, 0, 2, 3, 4}, // (subrame number 9) -{0xa2, -1, 8, 1, 512, 0, 2, 3, 4}, // (subrame number 9) -{0xa2, -1, 4, 1, 512, 0, 1, 3, 4}, // (subrame number 9) -{0xa2, -1, 2, 1, 640, 0, 1, 3, 4}, // (subrame number 7,9) -{0xa2, -1, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9) -{0xa2, -1, 2, 1, 640, 9, 1, 1, 4}, // (subrame number 7,9) -{0xa2, -1, 2, 1, 528, 9, 1, 1, 4}, // (subrame number 4,9) -{0xa2, -1, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9) -{0xa2, -1, 16, 1, 924, 0, 1, 3, 4}, // (subrame number 2,3,4,7,8,9) -{0xa2, -1, 1, 0, 4, 0, 1, 3, 4}, // (subrame number 2) -{0xa2, -1, 1, 0, 128, 0, 1, 3, 4}, // (subrame number 7) -{0xa2, -1, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9) -{0xa2, -1, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9) -{0xa2, -1, 1, 0, 512, 9, 1, 1, 4}, // (subrame number 9) -{0xa2, -1, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9) -{0xa2, -1, 1, 0, 132, 0, 1, 3, 4}, // (subrame number 2,7) -{0xa2, -1, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9) -{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9) -{0xa2, -1, 1, 0, 640, 9, 1, 1, 4}, // (subrame number 7,9) -{0xa2, -1, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9) -{0xa2, -1, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9) -{0xa2, -1, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9) -{0xa2, -1, 1, 0, 1023, 9, 1, 1, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9) -{0xa3, -1, 16, 1, 512, 0, 2, 2, 6}, // (subrame number 9) -{0xa3, -1, 8, 1, 512, 0, 2, 2, 6}, // (subrame number 9) -{0xa3, -1, 4, 1, 512, 0, 1, 2, 6}, // (subrame number 9) -{0xa3, -1, 2, 1, 528, 7, 1, 1, 6}, // (subrame number 4,9) -{0xa3, -1, 2, 1, 640, 7, 1, 1, 6}, // (subrame number 7,9) -{0xa3, -1, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9) -{0xa3, -1, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9) -{0xa3, -1, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9) -{0xa3, -1, 2, 1, 924, 0, 1, 2, 6}, // (subrame number 2,3,4,7,8,9) -{0xa3, -1, 1, 0, 4, 0, 1, 2, 6}, // (subrame number 2) -{0xa3, -1, 1, 0, 128, 0, 1, 2, 6}, // (subrame number 7) -{0xa3, -1, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9) -{0xa3, -1, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9) -{0xa3, -1, 1, 0, 512, 7, 1, 1, 6}, // (subrame number 9) -{0xa3, -1, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9) -{0xa3, -1, 1, 0, 132, 0, 1, 2, 6}, // (subrame number 2,7) -{0xa3, -1, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9) -{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9) -{0xa3, -1, 1, 0, 640, 7, 1, 1, 6}, // (subrame number 7,9) -{0xa3, -1, 1, 0, 792, 0, 1, 2, 6}, // (subrame number 3,4,8,9) -{0xa3, -1, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9) -{0xa3, -1, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9) -{0xa3, -1, 1, 0, 1023, 7, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9) -{0xb1, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9) -{0xb1, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9) -{0xb1, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9) -{0xb1, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9) -{0xb1, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9) -{0xb1, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9) -{0xb1, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9) -{0xb1, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9) -{0xb1, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9) -{0xb1, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9) -{0xb1, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9) -{0xb1, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9) -{0xb4, -1, 16, 1, 512, 0, 2, 1, 12}, // (subrame number 9) -{0xb4, -1, 8, 1, 512, 0, 2, 1, 12}, // (subrame number 9) -{0xb4, -1, 4, 1, 512, 2, 1, 1, 12}, // (subrame number 9) -{0xb4, -1, 2, 1, 512, 0, 1, 1, 12}, // (subrame number 9) -{0xb4, -1, 2, 1, 512, 2, 1, 1, 12}, // (subrame number 9) -{0xb4, -1, 2, 1, 640, 2, 1, 1, 12}, // (subrame number 7,9) -{0xb4, -1, 2, 1, 528, 2, 1, 1, 12}, // (subrame number 4,9) -{0xb4, -1, 2, 1, 528, 0, 2, 1, 12}, // (subrame number 4,9) -{0xb4, -1, 2, 1, 768, 0, 2, 1, 12}, // (subrame number 8,9) -{0xb4, -1, 2, 1, 924, 0, 1, 1, 12}, // (subrame number 2,3,4,7,8,9) -{0xb4, -1, 1, 0, 2, 0, 1, 1, 12}, // (subrame number 1) -{0xb4, -1, 1, 0, 4, 0, 1, 1, 12}, // (subrame number 2) -{0xb4, -1, 1, 0, 16, 0, 1, 1, 12}, // (subrame number 4) -{0xb4, -1, 1, 0, 128, 0, 1, 1, 12}, // (subrame number 7) -{0xb4, -1, 1, 0, 512, 0, 1, 1, 12}, // (subrame number 9) -{0xb4, -1, 1, 0, 512, 2, 1, 1, 12}, // (subrame number 9) -{0xb4, -1, 1, 0, 512, 0, 2, 1, 12}, // (subrame number 9) -{0xb4, -1, 1, 0, 528, 2, 1, 1, 12}, // (subrame number 4,9) -{0xb4, -1, 1, 0, 640, 2, 1, 1, 12}, // (subrame number 7,9) -{0xb4, -1, 1, 0, 768, 0, 2, 1, 12}, // (subrame number 8,9) -{0xb4, -1, 1, 0, 792, 2, 1, 1, 12}, // (subrame number 3,4,8,9) -{0xb4, -1, 1, 0, 682, 2, 1, 1, 12}, // (subrame number 1,3,5,7,9) -{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9) -{0xb4, -1, 1, 0, 1023, 2, 1, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9) -{0xc0, -1, 16, 1, 512, 2, 2, 6, 2}, // (subrame number 9) -{0xc0, -1, 8, 1, 512, 2, 2, 6, 2}, // (subrame number 9) -{0xc0, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9) -{0xc0, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9) -{0xc0, -1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9) -{0xc0, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9) -{0xc0, -1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9) -{0xc0, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9) -{0xc0, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9) -{0xc0, -1, 2, 1, 924, 2, 1, 6, 2}, // (subrame number 2,3,4,7,8,9) -{0xc0, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9) -{0xc0, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9) -{0xc0, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9) -{0xc0, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9) -{0xc0, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9) -{0xc0, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9) -{0xc0, -1, 1, 0, 792, 2, 1, 6, 2}, // (subrame number 3,4,8,9) -{0xc0, -1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9) -{0xc0, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9) -{0xc0, -1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9) -{0xc2, -1, 16, 1, 512, 2, 2, 2, 6}, // (subrame number 9) -{0xc2, -1, 8, 1, 512, 2, 2, 2, 6}, // (subrame number 9) -{0xc2, -1, 4, 1, 512, 2, 1, 2, 6}, // (subrame number 9) -{0xc2, -1, 2, 1, 512, 2, 1, 2, 6}, // (subrame number 9) -{0xc2, -1, 2, 1, 768, 2, 2, 2, 6}, // (subrame number 8,9) -{0xc2, -1, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9) -{0xc2, -1, 2, 1, 640, 8, 1, 1, 6}, // (subrame number 7,9) -{0xc2, -1, 2, 1, 528, 8, 1, 1, 6}, // (subrame number 4,9) -{0xc2, -1, 2, 1, 528, 2, 2, 2, 6}, // (subrame number 4,9) -{0xc2, -1, 2, 1, 924, 2, 1, 2, 6}, // (subrame number 2,3,4,7,8,9) -{0xc2, -1, 8, 1, 512, 8, 2, 1, 6}, // (subrame number 9) -{0xc2, -1, 4, 1, 512, 8, 1, 1, 6}, // (subrame number 9) -{0xc2, -1, 1, 0, 512, 2, 2, 2, 6}, // (subrame number 9) -{0xc2, -1, 1, 0, 512, 8, 1, 1, 6}, // (subrame number 9) -{0xc2, -1, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9) -{0xc2, -1, 1, 0, 768, 2, 2, 2, 6}, // (subrame number 8,9) -{0xc2, -1, 1, 0, 528, 2, 1, 2, 6}, // (subrame number 4,9) -{0xc2, -1, 1, 0, 640, 8, 1, 1, 6}, // (subrame number 7,9) -{0xc2, -1, 1, 0, 792, 2, 1, 2, 6}, // (subrame number 3,4,8,9) -{0xc2, -1, 1, 0, 792, 2, 2, 2, 6}, // (subrame number 3,4,8,9) -{0xc2, -1, 1, 0, 682, 2, 1, 2, 6}, // (subrame number 1,3,5,7,9) -{0xc2, -1, 1, 0, 1023, 8, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9) -{0xa1, 0xb1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9) -{0xa1, 0xb1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9) -{0xa1, 0xb1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9) -{0xa1, 0xb1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9) -{0xa1, 0xb1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9) -{0xa1, 0xb1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9) -{0xa1, 0xb1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9) -{0xa1, 0xb1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9) -{0xa1, 0xb1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9) -{0xa1, 0xb1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9) -{0xa1, 0xb1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9) -{0xa1, 0xb1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9) -{0xa1, 0xb1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9) -{0xa1, 0xb1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9) -{0xa1, 0xb1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9) -{0xa2, 0xb2, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9) -{0xa2, 0xb2, 2, 1, 528, 6, 1, 2, 4}, // (subrame number 4,9) -{0xa2, 0xb2, 2, 1, 640, 6, 1, 2, 4}, // (subrame number 7,9) -{0xa2, 0xb2, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9) -{0xa2, 0xb2, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9) -{0xa2, 0xb2, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9) -{0xa2, 0xb2, 1, 0, 512, 6, 1, 2, 4}, // (subrame number 9) -{0xa2, 0xb2, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9) -{0xa2, 0xb2, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9) -{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9) -{0xa2, 0xb2, 1, 0, 640, 6, 1, 2, 4}, // (subrame number 7,9) -{0xa2, 0xb2, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9) -{0xa2, 0xb2, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9) -{0xa2, 0xb2, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9) -{0xa2, 0xb2, 1, 0, 1023, 6, 1, 2, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9) -{0xa3, 0xb3, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9) -{0xa3, 0xb3, 2, 1, 528, 2, 1, 2, 6}, // (subrame number 4,9) -{0xa3, 0xb3, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9) -{0xa3, 0xb3, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9) -{0xa3, 0xb3, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9) -{0xa3, 0xb3, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9) -{0xa3, 0xb3, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9) -{0xa3, 0xb3, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9) -{0xa3, 0xb3, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9) -{0xa3, 0xb3, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9) -{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9) -{0xa3, 0xb3, 1, 0, 640, 2, 1, 2, 6}, // (subrame number 7,9) -{0xa3, 0xb3, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9) -{0xa3, 0xb3, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9) -{0xa3, 0xb3, 1, 0, 1023, 2, 1, 2, 6} // (subrame number 0,1,2,3,4,5,6,7,8,9) -}; -// Table 6.3.3.2-4: Random access configurations for FR2 and unpaired spectrum -int64_t table_6_3_3_2_4_prachConfig_Index [256][10] = { -//format, format, x, y, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration -{0xa1, -1, 16, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, -1, 16, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa1, -1, 8, 1, 2, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39) -{0xa1, -1, 8, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, -1, 8, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa1, -1, 4, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, -1, 4, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, -1, 4, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa1, -1, 2, 1, -1, 551911719040, 0, 2, 6, 2}, // (subframe number :7,15,23,31,39) -{0xa1, -1, 2, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, -1, 2, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, -1, 2, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa1, -1, 1, 0, -1, 549756338176, 7, 1, 3, 2}, // (subframe number :19,39) -{0xa1, -1, 1, 0, -1, 168, 0, 1, 6, 2}, // (subframe number :3,5,7) -{0xa1, -1, 1, 0, -1, 567489331200, 7, 1, 3, 2}, // (subframe number :24,29,34,39) -{0xa1, -1, 1, 0, -1, 550293209600, 7, 2, 3, 2}, // (subframe number :9,19,29,39) -{0xa1, -1, 1, 0, -1, 687195422720, 0, 1, 6, 2}, // (subframe number :17,19,37,39) -{0xa1, -1, 1, 0, -1, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39) -{0xa1, -1, 1, 0, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, -1, 1, 0, -1, 567489872400, 7, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, -1, 1, 0, -1, 10920, 7, 1, 3, 2}, // (subframe number :3,5,7,9,11,13) -{0xa1, -1, 1, 0, -1, 586405642240, 7, 1, 3, 2}, // (subframe number :23,27,31,35,39) -{0xa1, -1, 1, 0, -1, 551911719040, 0, 1, 6, 2}, // (subframe number :7,15,23,31,39) -{0xa1, -1, 1, 0, -1, 586405642240, 0, 1, 6, 2}, // (subframe number :23,27,31,35,39) -{0xa1, -1, 1, 0, -1, 965830828032, 7, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39) -{0xa1, -1, 1, 0, -1, 586406201480, 7, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa1, -1, 1, 0, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa1, -1, 1, 0, -1, 733007751850, 0, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39) -{0xa1, -1, 1, 0, -1, 1099511627775, 7, 1, 3, 2}, // (subframe number :0,1,2,…,39) -{0xa2, -1, 16, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, -1, 16, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa2, -1, 8, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, -1, 8, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa2, -1, 8, 1, 2, 550293209600, 0, 2, 3, 4}, // (subframe number :9,19,29,39) -{0xa2, -1, 4, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, -1, 4, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, -1, 4, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa2, -1, 2, 1, -1, 551911719040, 0, 2, 3, 4}, // (subframe number :7,15,23,31,39) -{0xa2, -1, 2, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, -1, 2, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, -1, 2, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa2, -1, 1, 0, -1, 549756338176, 5, 1, 2, 4}, // (subframe number :19,39) -{0xa2, -1, 1, 0, -1, 168, 0, 1, 3, 4}, // (subframe number :3,5,7) -{0xa2, -1, 1, 0, -1, 567489331200, 5, 1, 2, 4}, // (subframe number :24,29,34,39) -{0xa2, -1, 1, 0, -1, 550293209600, 5, 2, 2, 4}, // (subframe number :9,19,29,39) -{0xa2, -1, 1, 0, -1, 687195422720, 0, 1, 3, 4}, // (subframe number :17,19,37,39) -{0xa2, -1, 1, 0, -1, 550293209600, 0, 2, 3, 4}, // (subframe number :9, 19, 29, 39) -{0xa2, -1, 1, 0, -1, 551911719040, 0, 1, 3, 4}, // (subframe number :7,15,23,31,39) -{0xa2, -1, 1, 0, -1, 586405642240, 5, 1, 2, 4}, // (subframe number :23,27,31,35,39) -{0xa2, -1, 1, 0, -1, 586405642240, 0, 1, 3, 4}, // (subframe number :23,27,31,35,39) -{0xa2, -1, 1, 0, -1, 10920, 5, 1, 2, 4}, // (subframe number :3,5,7,9,11,13) -{0xa2, -1, 1, 0, -1, 10920, 0, 1, 3, 4}, // (subframe number :3,5,7,9,11,13) -{0xa2, -1, 1, 0, -1, 567489872400, 5, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, -1, 1, 0, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, -1, 1, 0, -1, 965830828032, 5, 2, 2, 4}, // (subframe number :13,14,15, 29,30,31,37,38,39) -{0xa2, -1, 1, 0, -1, 586406201480, 5, 1, 2, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa2, -1, 1, 0, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa2, -1, 1, 0, -1, 733007751850, 0, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39) -{0xa2, -1, 1, 0, -1, 1099511627775, 5, 1, 2, 4}, // (subframe number :0,1,2,…,39) -{0xa3, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa3, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa3, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39) -{0xa3, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa3, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa3, -1, 1, 0, -1, 549756338176, 7, 1, 1, 6}, // (subframe number :19,39) -{0xa3, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7) -{0xa3, -1, 1, 0, -1, 10752, 2, 1, 2, 6}, // (subframe number :9,11,13) -{0xa3, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39) -{0xa3, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39) -{0xa3, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39) -{0xa3, -1, 1, 0, -1, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39) -{0xa3, -1, 1, 0, -1, 551911719040, 0, 1, 2, 6}, // (subframe number :7,15,23,31,39) -{0xa3, -1, 1, 0, -1, 586405642240, 7, 1, 1, 6}, // (subframe number :23,27,31,35,39) -{0xa3, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39) -{0xa3, -1, 1, 0, -1, 10920, 0, 1, 2, 6}, // (subframe number :3,5,7,9,11,13) -{0xa3, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13) -{0xa3, -1, 1, 0, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, -1, 1, 0, -1, 567489872400, 7, 1, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39) -{0xa3, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa3, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa3, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39) -{0xa3, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39) -{0xb1, -1, 16, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb1, -1, 8, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb1, -1, 8, 1, 2, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39) -{0xb1, -1, 4, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb1, -1, 2, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb1, -1, 2, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xb1, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39) -{0xb1, -1, 1, 0, -1, 168, 2, 1, 6, 2}, // (subframe number :3,5,7) -{0xb1, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39) -{0xb1, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39) -{0xb1, -1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39) -{0xb1, -1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39) -{0xb1, -1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39) -{0xb1, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39) -{0xb1, -1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39) -{0xb1, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13) -{0xb1, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb1, -1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb1, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xb1, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39) -{0xb1, -1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xb1, -1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39) -{0xb1, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39) -{0xb4, -1, 16, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb4, -1, 16, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xb4, -1, 8, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb4, -1, 8, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xb4, -1, 8, 1, 2, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39) -{0xb4, -1, 4, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb4, -1, 4, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb4, -1, 4, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xb4, -1, 2, 1, -1, 551911719040, 2, 2, 1, 12}, // (subframe number :7,15,23,31,39) -{0xb4, -1, 2, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb4, -1, 2, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb4, -1, 2, 1, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xb4, -1, 1, 0, -1, 549756338176, 2, 2, 1, 12}, // (subframe number :19, 39) -{0xb4, -1, 1, 0, -1, 687195422720, 0, 1, 1, 12}, // (subframe number :17, 19, 37, 39) -{0xb4, -1, 1, 0, -1, 567489331200, 2, 1, 1, 12}, // (subframe number :24,29,34,39) -{0xb4, -1, 1, 0, -1, 550293209600, 2, 2, 1, 12}, // (subframe number :9,19,29,39) -{0xb4, -1, 1, 0, -1, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39) -{0xb4, -1, 1, 0, -1, 551911719040, 0, 1, 1, 12}, // (subframe number :7,15,23,31,39) -{0xb4, -1, 1, 0, -1, 551911719040, 0, 2, 1, 12}, // (subframe number :7,15,23,31,39) -{0xb4, -1, 1, 0, -1, 586405642240, 0, 1, 1, 12}, // (subframe number :23,27,31,35,39) -{0xb4, -1, 1, 0, -1, 586405642240, 2, 2, 1, 12}, // (subframe number :23,27,31,35,39) -{0xb4, -1, 1, 0, -1, 698880, 0, 1, 1, 12}, // (subframe number :9,11,13,15,17,19) -{0xb4, -1, 1, 0, -1, 10920, 2, 1, 1, 12}, // (subframe number :3,5,7,9,11,13) -{0xb4, -1, 1, 0, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb4, -1, 1, 0, -1, 567489872400, 2, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) -{0xb4, -1, 1, 0, -1, 965830828032, 2, 2, 1, 12}, // (subframe number :13,14,15, 29,30,31,37,38,39) -{0xb4, -1, 1, 0, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xb4, -1, 1, 0, -1, 586406201480, 2, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xb4, -1, 1, 0, -1, 44739240, 2, 1, 1, 12}, // (subframe number :3, 5, 7, …, 23,25) -{0xb4, -1, 1, 0, -1, 44739240, 0, 2, 1, 12}, // (subframe number :3, 5, 7, …, 23,25) -{0xb4, -1, 1, 0, -1, 733007751850, 0, 1, 1, 12}, // (subframe number :1,3,5,7,…,37,39) -{0xb4, -1, 1, 0, -1, 1099511627775, 2, 1, 1, 12}, // (subframe number :0, 1, 2,…, 39) -{0xc0, -1, 16, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc0, -1, 16, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc0, -1, 8, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc0, -1, 8, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc0, -1, 8, 1, 2, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39) -{0xc0, -1, 4, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc0, -1, 4, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc0, -1, 4, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc0, -1, 2, 1, -1, 551911719040, 0, 2, 7, 2}, // (subframe number :7,15,23,31,39) -{0xc0, -1, 2, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc0, -1, 2, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc0, -1, 2, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc0, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39) -{0xc0, -1, 1, 0, -1, 168, 0, 1, 7, 2}, // (subframe number :3,5,7) -{0xc0, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39) -{0xc0, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39) -{0xc0, -1, 1, 0, -1, 687195422720, 0, 1, 7, 2}, // (subframe number :17,19,37,39) -{0xc0, -1, 1, 0, -1, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39) -{0xc0, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39) -{0xc0, -1, 1, 0, -1, 551911719040, 0, 1, 7, 2}, // (subframe number :7,15,23,31,39) -{0xc0, -1, 1, 0, -1, 586405642240, 0, 1, 7, 2}, // (subframe number :23,27,31,35,39) -{0xc0, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13) -{0xc0, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc0, -1, 1, 0, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc0, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39) -{0xc0, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc0, -1, 1, 0, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc0, -1, 1, 0, -1, 733007751850, 0, 1, 7, 2}, // (subframe number :1,3,5,7,…,37,39) -{0xc0, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39) -{0xc2, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc2, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc2, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc2, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc2, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39) -{0xc2, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc2, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc2, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc2, -1, 2, 1, -1, 551911719040, 2, 2, 2, 6}, // (subframe number :7,15,23,31,39) -{0xc2, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc2, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc2, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc2, -1, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39) -{0xc2, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7) -{0xc2, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39) -{0xc2, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39) -{0xc2, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39) -{0xc2, -1, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39) -{0xc2, -1, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39) -{0xc2, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13) -{0xc2, -1, 1, 0, -1, 586405642240, 7, 2, 1, 6}, // (subframe number :23,27,31,35,39) -{0xc2, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39) -{0xc2, -1, 1, 0, -1, 567489872400, 7, 2, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc2, -1, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xc2, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39) -{0xc2, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc2, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xc2, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39) -{0xc2, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39) -{0xa1, 0xb1, 16, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, 0xb1, 16, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa1, 0xb1, 8, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, 0xb1, 8, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa1, 0xb1, 4, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, 0xb1, 4, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa1, 0xb1, 2, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, 0xb1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39) -{0xa1, 0xb1, 1, 0, -1, 550293209600, 8, 1, 3, 2}, // (subframe number :9,19,29,39) -{0xa1, 0xb1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39) -{0xa1, 0xb1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39) -{0xa1, 0xb1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39) -{0xa1, 0xb1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39) -{0xa1, 0xb1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39) -{0xa1, 0xb1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, 0xb1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa1, 0xb1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa1, 0xb1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39) -{0xa2, 0xb2, 16, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, 0xb2, 16, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa2, 0xb2, 8, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, 0xb2, 8, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa2, 0xb2, 4, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, 0xb2, 4, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa2, 0xb2, 2, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, 0xb2, 1, 0, -1, 549756338176, 6, 1, 2, 4}, // (subframe number :19,39) -{0xa2, 0xb2, 1, 0, -1, 550293209600, 6, 1, 2, 4}, // (subframe number :9,19,29,39) -{0xa2, 0xb2, 1, 0, -1, 687195422720, 2, 1, 3, 4}, // (subframe number :17,19,37,39) -{0xa2, 0xb2, 1, 0, -1, 550293209600, 2, 2, 3, 4}, // (subframe number :9,19,29,39) -{0xa2, 0xb2, 1, 0, -1, 586405642240, 6, 1, 2, 4}, // (subframe number :23,27,31,35,39) -{0xa2, 0xb2, 1, 0, -1, 551911719040, 2, 1, 3, 4}, // (subframe number :7,15,23,31,39) -{0xa2, 0xb2, 1, 0, -1, 586405642240, 2, 1, 3, 4}, // (subframe number :23,27,31,35,39) -{0xa2, 0xb2, 1, 0, -1, 567489872400, 6, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, 0xb2, 1, 0, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa2, 0xb2, 1, 0, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa2, 0xb2, 1, 0, -1, 733007751850, 2, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39) -{0xa3, 0xb3, 16, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, 0xb3, 16, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa3, 0xb3, 8, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, 0xb3, 8, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa3, 0xb3, 4, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, 0xb3, 4, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa3, 0xb3, 2, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, 0xb3, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39) -{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 1, 2, 6}, // (subframe number :9,19,29,39) -{0xa3, 0xb3, 1, 0, -1, 687195422720, 2, 1, 2, 6}, // (subframe number :17,19,37,39) -{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39) -{0xa3, 0xb3, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39) -{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 1, 2, 6}, // (subframe number :23,27,31,35,39) -{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 2, 2, 6}, // (subframe number :23,27,31,35,39) -{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) -{0xa3, 0xb3, 1, 0, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) -{0xa3, 0xb3, 1, 0, -1, 733007751850, 2, 1, 2, 6} // (subframe number :1,3,5,7,…,37,39) -}; diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c index e1b80a87a2..8373e775bd 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach_common.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach_common.c @@ -37,12 +37,12 @@ #include "PHY/NR_TRANSPORT/nr_transport_proto_common.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" - +#include "openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h" #include "T.h" -void init_nr_prach_tables(int N_ZC); -void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe) { + +/*void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe) { FILE *fd; @@ -76,23 +76,13 @@ void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe) { fprintf(fd,"prach_config: n_ra_prboffset = %d\n",frame_parms->prach_config_common.prach_ConfigInfo.msg1_frequencystart); fclose(fd); -} +}*/ // This function computes the du -void nr_fill_du(uint8_t prach_fmt) +void nr_fill_du(uint16_t N_ZC,uint16_t *prach_root_sequence_map) { uint16_t iu,u,p; - uint16_t N_ZC; - uint16_t *prach_root_sequence_map; - - if (prach_fmt<4) { - N_ZC = 839; - prach_root_sequence_map = prach_root_sequence_map_0_3; - } else { - N_ZC = 139; - prach_root_sequence_map = prach_root_sequence_map_abc; - } for (iu=0; iu<(N_ZC-1); iu++) { @@ -107,210 +97,45 @@ 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<slots_per_subframe; - // when were in the last slot of the subframe and this is a PRACH subframe ,return 1 - if (((slot%fp->slots_per_subframe) == fp->slots_per_subframe-1)&& - (is_nr_prach_subframe(fp,frame,subframe))) return (1); - else return(0); -} - -uint16_t get_nr_prach_fmt(int prach_ConfigIndex,lte_frame_type_t frame_type, nr_frequency_range_e fr) -{ - - if (frame_type==FDD) return (table_6_3_3_2_2_prachConfig_Index[prach_ConfigIndex][0]); // if using table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink - else if (fr==nr_FR1) return (table_6_3_3_2_3_prachConfig_Index[prach_ConfigIndex][0]); // if using table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum - else AssertFatal(1==0,"FR2 prach configuration not supported yet\n"); - // For FR2 not implemented. FIXME -} - -void compute_nr_prach_seq(uint16_t rootSequenceIndex, - uint8_t prach_ConfigIndex, - uint8_t zeroCorrelationZoneConfig, - uint8_t highSpeedFlag, - lte_frame_type_t frame_type, - nr_frequency_range_e fr, - uint32_t X_u[64][839]) -{ +void compute_nr_prach_seq(uint8_t short_sequence, + uint8_t num_sequences, + uint8_t rootSequenceIndex, + uint32_t X_u[64][839]){ // Compute DFT of x_u => X_u[k] = x_u(inv(u)*k)^* X_u[k] = exp(j\pi u*inv(u)*k*(inv(u)*k+1)/N_ZC) - unsigned int k,inv_u,i,NCS=0,num_preambles; + unsigned int k,inv_u,i; int N_ZC; - uint8_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,frame_type,fr); + uint16_t *prach_root_sequence_map; - uint16_t u, preamble_offset; - uint16_t n_shift_ra,n_shift_ra_bar, d_start,numshift; - uint8_t not_found; + uint16_t u; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_COMPUTE_PRACH, VCD_FUNCTION_IN); -#ifdef NR_PRACH_DEBUG - LOG_I(PHY,"compute_prach_seq: NCS_config %d, prach_fmt %x\n",zeroCorrelationZoneConfig, prach_fmt); -#endif + LOG_D(PHY,"compute_prach_seq: prach short sequence %x, num_sequences %d, rootSequenceIndex %d\n", short_sequence, num_sequences, rootSequenceIndex); - - N_ZC = (prach_fmt < 4) ? 839 : 139; + N_ZC = (short_sequence) ? 139 : 839; //init_prach_tables(N_ZC); //moved to phy_init_lte_ue/eNB, since it takes to long in real-time init_nr_prach_tables(N_ZC); - if (prach_fmt < 4) { - prach_root_sequence_map = prach_root_sequence_map_0_3; - } else { + if (short_sequence) { // FIXME cannot be reached prach_root_sequence_map = prach_root_sequence_map_abc; - } - - -#ifdef PRACH_DEBUG - LOG_I( PHY, "compute_prach_seq: done init prach_tables\n" ); -#endif - - - - - int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME - - if (highSpeedFlag== 0) { - -#ifdef PRACH_DEBUG - LOG_I(PHY,"Low speed prach : NCS_config %d\n",zeroCorrelationZoneConfig); -#endif - - AssertFatal(zeroCorrelationZoneConfig<=15, - "FATAL, Illegal Ncs_config for unrestricted format %"PRIu8"\n", zeroCorrelationZoneConfig ); - if (prach_fmt<3) NCS = NCS_unrestricted_delta_f_RA_125[zeroCorrelationZoneConfig]; - if (prach_fmt==3) NCS = NCS_unrestricted_delta_f_RA_5[zeroCorrelationZoneConfig]; - if (prach_fmt>3) NCS = NCS_unrestricted_delta_f_RA_15[zeroCorrelationZoneConfig]; - - num_preambles = (NCS==0) ? 64 : ((64*NCS)/N_ZC); - - if (NCS>0) num_preambles++; - - preamble_offset = 0; } else { - -#ifdef PRACH_DEBUG - LOG_I( PHY, "high speed prach : NCS_config %"PRIu8"\n", zeroCorrelationZoneConfig ); -#endif - - AssertFatal(zeroCorrelationZoneConfig<=14, - "FATAL, Illegal Ncs_config for restricted format %"PRIu8"\n", zeroCorrelationZoneConfig ); - if (prach_fmt<3){ - if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[zeroCorrelationZoneConfig]; // for TypeA, this is hardcoded. FIXME - if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[zeroCorrelationZoneConfig]; // for TypeB, this is hardcoded. FIXME - } - if (prach_fmt==3){ - if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[zeroCorrelationZoneConfig]; // for TypeA, this is hardcoded. FIXME - if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[zeroCorrelationZoneConfig]; // for TypeB, this is hardcoded. FIXME - } - if (prach_fmt>3){ - - } - - nr_fill_du(prach_fmt); - - num_preambles = 64; // compute ZC sequence for 64 possible roots - // find first non-zero shift root (stored in preamble_offset) - not_found = 1; - preamble_offset = 0; - - while (not_found == 1) { - // current root depending on rootSequenceIndex - int index = (rootSequenceIndex + preamble_offset) % N_ZC; - - if (prach_fmt<4) { - // prach_root_sequence_map points to prach_root_sequence_map0_3 - DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) ); - } else { - // prach_root_sequence_map points to prach_root_sequence_map4 - DevAssert( index < sizeof(prach_root_sequence_map_abc) / sizeof(prach_root_sequence_map_abc[0]) ); - } - - u = prach_root_sequence_map[index]; - - uint16_t n_group_ra = 0; - - if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) { - n_shift_ra = nr_du[u]/NCS; - d_start = (nr_du[u]<<1) + (n_shift_ra * NCS); - n_group_ra = N_ZC/d_start; - n_shift_ra_bar = max(0,(N_ZC-(nr_du[u]<<1)-(n_group_ra*d_start))/N_ZC); - } else if ( (nr_du[u]>=(N_ZC/3)) && (nr_du[u]<=((N_ZC - NCS)>>1)) ) { - n_shift_ra = (N_ZC - (nr_du[u]<<1))/NCS; - d_start = N_ZC - (nr_du[u]<<1) + (n_shift_ra * NCS); - n_group_ra = nr_du[u]/d_start; - n_shift_ra_bar = min(n_shift_ra,max(0,(nr_du[u]- (n_group_ra*d_start))/NCS)); - } else { - n_shift_ra = 0; - n_shift_ra_bar = 0; - } - - // This is the number of cyclic shifts for the current root u - numshift = (n_shift_ra*n_group_ra) + n_shift_ra_bar; - - // skip to next root and recompute parameters if numshift==0 - if (numshift>0) - not_found = 0; - else - preamble_offset++; - } + prach_root_sequence_map = prach_root_sequence_map_0_3; } -#ifdef PRACH_DEBUG + LOG_D( PHY, "compute_prach_seq: done init prach_tables\n" ); - if (NCS>0) - LOG_I( PHY, "Initializing %u preambles for PRACH (NCS_config %"PRIu8", NCS %u, N_ZC/NCS %u)\n", - num_preambles, zeroCorrelationZoneConfig, NCS, N_ZC/NCS ); + for (i=0; iulsch[i]!=NULL,"gNB->ulsch[%d] is null\n",i); + AssertFatal(gNB->ulsch[i][0]!=NULL,"gNB->ulsch[%d][0] is null\n",i); + LOG_D(PHY,"searching for rnti %x : ulsch_index %d=> harq_mask %x, rnti %x, first_free_index %d\n", rnti,i,gNB->ulsch[i][0]->harq_mask,gNB->ulsch[i][0]->rnti,first_free_index); + if ((gNB->ulsch[i][0]->harq_mask >0) && + (gNB->ulsch[i][0]->rnti==rnti)) return i; + else if ((gNB->ulsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i; + } + if (type == SEARCH_EXIST) return -1; + if (first_free_index != -1) + gNB->ulsch[first_free_index][0]->rnti = 0; + return first_free_index; +} + +void nr_fill_ulsch(PHY_VARS_gNB *gNB, + int frame, + int slot, + nfapi_nr_pusch_pdu_t *ulsch_pdu) { + + + int ulsch_id = find_nr_ulsch(ulsch_pdu->rnti,gNB,SEARCH_EXIST_OR_FREE); + AssertFatal( (ulsch_id>=0) && (ulsch_idrnti,ulsch_id); + + NR_gNB_ULSCH_t *ulsch = gNB->ulsch[ulsch_id][0]; + int harq_pid = ulsch_pdu->pusch_data.harq_process_id; + ulsch->rnti = ulsch_pdu->rnti; + //ulsch->rnti_type; + ulsch->harq_mask |= 1<harq_process_id[slot] = harq_pid; + + ulsch->harq_processes[harq_pid]->frame=frame; + ulsch->harq_processes[harq_pid]->slot=slot; + ulsch->harq_processes[harq_pid]->handled= 0; + ulsch->harq_processes[harq_pid]->status= NR_ACTIVE; + memcpy((void*)&ulsch->harq_processes[harq_pid]->ulsch_pdu, (void*)ulsch_pdu, sizeof(nfapi_nr_pusch_pdu_t)); + + LOG_D(PHY,"Initializing nFAPI for ULSCH, UE %d, harq_pid %d\n",ulsch_id,harq_pid); + +} + void nr_ulsch_unscrambling(int16_t* llr, - uint32_t size, - uint8_t q, - uint32_t Nid, - uint32_t n_RNTI) -{ + uint32_t size, + uint8_t q, + uint32_t Nid, + uint32_t n_RNTI) { + uint8_t reset; uint32_t x1, x2, s=0; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index e8a961360f..769fd16065 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -219,13 +219,13 @@ void clean_gNB_ulsch(NR_gNB_ULSCH_t *ulsch) /// Nfapi ULSCH PDU //nfapi_nr_ul_config_ulsch_pdu ulsch_pdu; ulsch->harq_processes[i]->frame=0; - ulsch->harq_processes[i]->subframe=0; + ulsch->harq_processes[i]->slot=0; ulsch->harq_processes[i]->round=0; ulsch->harq_processes[i]->TPC=0; ulsch->harq_processes[i]->mimo_mode=0; ulsch->harq_processes[i]->dci_alloc=0; ulsch->harq_processes[i]->rar_alloc=0; - ulsch->harq_processes[i]->status=0; + ulsch->harq_processes[i]->status=NR_SCH_IDLE; ulsch->harq_processes[i]->subframe_scheduling_flag=0; ulsch->harq_processes[i]->subframe_cba_scheduling_flag=0; ulsch->harq_processes[i]->phich_active=0; @@ -421,7 +421,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, #ifdef DEBUG_ULSCH_DECODING printf("ulsch decoding nr segmentation Z %d\n", harq_process->Z); if (!frame%100) - printf("K %d C %d Z %d\n", harq_process->K, harq_process->C, harq_process->Z); + printf("K %d C %d Z %d \n", harq_process->K, harq_process->C, harq_process->Z); #endif } p_decParams->Z = harq_process->Z; @@ -677,8 +677,8 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, ulsch->harq_mask &= ~(1 << harq_pid); } - // LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", - // phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS); + // LOG_D(PHY,"[gNB %d] ULSCH: Setting NACK for nr_tti_rx %d (pid %d, pid status %d, round %d/Max %d, TBS %d)\n", + // phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->status,harq_process->round,ulsch->Mlimit,harq_process->TBS); harq_process->handled = 1; ret = ulsch->max_ldpc_iterations + 1; @@ -700,6 +700,7 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, // LOG_D(PHY,"[gNB %d] ULSCH: Setting ACK for nr_tti_rx %d (pid %d, round %d, TBS %d)\n",phy_vars_gNB->Mod_id,nr_tti_rx,harq_pid,harq_process->round,harq_process->TBS); + // Reassembly of Transport block here offset = 0; Kr = harq_process->K; diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c index bce8ddcc29..d304f26d02 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c @@ -222,7 +222,6 @@ void nr_idft(uint32_t *z, uint32_t Msc_PUSCH) } - void nr_ulsch_extract_rbs_single(int32_t **rxdataF, NR_gNB_PUSCH *pusch_vars, unsigned char symbol, @@ -230,6 +229,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, nfapi_nr_pusch_pdu_t *pusch_pdu, NR_DL_FRAME_PARMS *frame_parms) { + unsigned short start_re, re, nb_re_pusch; unsigned char aarx; uint8_t K_ptrs; @@ -259,8 +259,6 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, is_ptrs_symbol_flag = 0; num_ptrs_symbols = 0; - K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2; - for (aarx = 0; aarx < frame_parms->nb_antennas_rx; aarx++) { rxF = (int16_t *)&rxdataF[aarx][symbol * frame_parms->ofdm_symbol_size]; @@ -285,6 +283,8 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, is_dmrs_re = 0; if ( ((pusch_pdu->pdu_bit_map)>>2)& 0x01 ) { + + K_ptrs = (pusch_pdu->pusch_ptrs.ptrs_freq_density)?4:2; is_ptrs_symbol_flag = is_ptrs_symbol(symbol, (start_re + re)%frame_parms->ofdm_symbol_size, n_rnti, @@ -304,7 +304,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, } #ifdef DEBUG_RB_EXT - printf("re = %d, is_dmrs_symbol_flag = %d, symbol = %d\n", re, is_dmrs_symbol_flag, symbol); + printf("re = %d, symbol = %d\n", re, symbol); #endif if ( is_dmrs_re == 0 && is_ptrs_symbol_flag == 0) { @@ -315,8 +315,7 @@ void nr_ulsch_extract_rbs_single(int32_t **rxdataF, ul_ch0_ptrs_ext[ul_ch0_ptrs_ext_index] = ul_ch0_ptrs[ul_ch0_ptrs_index]; #ifdef DEBUG_RB_EXT - printf("rxF_ext[%d] = %d\n", rxF_ext_index, rxF_ext[rxF_ext_index]); - printf("rxF_ext[%d] = %d\n", rxF_ext_index+1, rxF_ext[rxF_ext_index+1]); + printf("rxF_ext[%d] = (%d,%d)\n", rxF_ext_index>>1, rxF_ext[rxF_ext_index],rxF_ext[rxF_ext_index+1]); #endif ul_ch0_ext_index++; @@ -372,7 +371,6 @@ void nr_ulsch_scale_channel(int **ul_ch_estimates_ext, nb_rb = (2*nb_rb)/3; } - for (rb=0;rb=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; - for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) + for (aatx=0; aatxnb_antenna_ports_gNB; aatx++) { for (aarx=0; aarxnb_antennas_rx; aarx++) { //clear average level avg128U = vdupq_n_s32(0); @@ -489,8 +487,7 @@ void nr_ulsch_channel_level(int **ul_ch_estimates_ext, ((int32_t*)&avg128U)[2] + ((int32_t*)&avg128U)[3] ) / (nb_rb*nre); } - - + } #endif } @@ -516,12 +513,12 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, ul_ch = (int16_t *)&ul_ch_estimates_ext[0][symbol*nb_rb*12]; printf("--------------------symbol = %d, mod_order = %d, output_shift = %d-----------------------\n", symbol, mod_order, output_shift); - printf("----------------Before compansation------------------\n"); + printf("----------------Before compensation------------------\n"); - for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx++){ + for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx+=2){ - printf("rxF[%d] = %d\n", prnt_idx, rxF[prnt_idx]); - printf("ul_ch[%d] = %d\n", prnt_idx, ul_ch[prnt_idx]); + printf("rxF[%d] = (%d,%d)\n", prnt_idx>>1, rxF[prnt_idx],rxF[prnt_idx+1]); + printf("ul_ch[%d] = (%d,%d)\n", prnt_idx>>1, ul_ch[prnt_idx],ul_ch[prnt_idx+1]); } @@ -709,7 +706,6 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, if (rho) { - for (aarx=0; aarxnb_antennas_rx; aarx++) { rho128 = (__m128i *)&rho[aarx][symbol*frame_parms->N_RB_UL*12]; ul_ch128 = (__m128i *)&ul_ch_estimates_ext[aarx][symbol*frame_parms->N_RB_UL*12]; @@ -791,7 +787,6 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, #elif defined(__arm__) - unsigned short rb; unsigned char aatx,aarx,symbol_mod,is_dmrs_symbol=0; @@ -993,9 +988,9 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, printf("----------------After compansation------------------\n"); - for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx++){ + for (prnt_idx=0;prnt_idx<12*nb_rb*2;prnt_idx+=2){ - printf("rxF[%d] = %d\n", prnt_idx, rxF[prnt_idx]); + printf("rxF[%d] = (%d,%d)\n", prnt_idx>>1, rxF[prnt_idx],rxF[prnt_idx+1]); } @@ -1008,9 +1003,9 @@ void nr_ulsch_channel_compensation(int **rxdataF_ext, printf("----------------After computation------------------\n"); - for (print_idx=0;print_idx<12*nb_rb*2;print_idx++){ + for (print_idx=0;print_idx<12*nb_rb*2;print_idx+=2){ - printf("ch_mag[%d] = %d\n", print_idx, ch_mag[print_idx]); + printf("ch_mag[%d] = (%d,%d)\n", print_idx>>1, ch_mag[print_idx],ch_mag[print_idx+1]); } @@ -1026,17 +1021,17 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, unsigned char harq_pid) { - uint8_t first_symbol_flag, aarx, aatx, dmrs_symbol_flag, ptrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol + uint8_t aarx, aatx, dmrs_symbol_flag, ptrs_symbol_flag; // dmrs_symbol_flag, a flag to indicate DMRS REs in current symbol uint32_t nb_re_pusch, bwp_start_subcarrier; uint8_t L_ptrs = 0; // PTRS parameter int avgs; int avg[4]; NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; nfapi_nr_pusch_pdu_t *rel15_ul = &gNB->ulsch[UE_id][0]->harq_processes[harq_pid]->ulsch_pdu; + uint8_t nodata_dmrs = 1; // FIXME to be properly configured from fapi dmrs_symbol_flag = 0; ptrs_symbol_flag = 0; - first_symbol_flag = 0; gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol = 0; if(symbol == rel15_ul->start_symbol_index){ @@ -1044,7 +1039,6 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, gNB->pusch_vars[UE_id]->dmrs_symbol = 0; gNB->pusch_vars[UE_id]->cl_done = 0; gNB->pusch_vars[UE_id]->ptrs_symbols = 0; - first_symbol_flag = 1; if ( ((rel15_ul->pdu_bit_map)>>2)& 0x01 ) { // if there is ptrs pdu L_ptrs = 1<<(rel15_ul->pusch_ptrs.ptrs_time_density); @@ -1064,7 +1058,12 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, dmrs_symbol_flag = ((rel15_ul->ul_dmrs_symb_pos)>>symbol)&0x01; if (dmrs_symbol_flag == 1){ - nb_re_pusch = rel15_ul->rb_size * ((rel15_ul->dmrs_config_type==pusch_dmrs_type1)?6:8); + if (((rel15_ul->ul_dmrs_symb_pos)>>((symbol+1)%frame_parms->symbols_per_slot))&0x01) + AssertFatal(1==0,"Double DMRS configuration is not yet supported\n"); + if (nodata_dmrs) + nb_re_pusch = 0; + else + nb_re_pusch = rel15_ul->rb_size * ((rel15_ul->dmrs_config_type==pusch_dmrs_type1)?6:8); gNB->pusch_vars[UE_id]->dmrs_symbol = symbol; } else { nb_re_pusch = rel15_ul->rb_size * NR_NB_SC_PER_RB; @@ -1106,70 +1105,75 @@ void nr_rx_pusch(PHY_VARS_gNB *gNB, //--------------------- RBs extraction --------------------- //---------------------------------------------------------- - nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF, - gNB->pusch_vars[UE_id], - symbol, - dmrs_symbol_flag, - rel15_ul, - frame_parms); + if (nb_re_pusch > 0) { - nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, - frame_parms, - gNB->ulsch[UE_id], - symbol, - dmrs_symbol_flag, - rel15_ul->rb_size, - rel15_ul->dmrs_config_type); - - - if (first_symbol_flag==1) { - - nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, - frame_parms, - avg, - symbol, - nb_re_pusch, - rel15_ul->rb_size); - avgs = 0; - - for (aatx=0;aatxnb_antennas_tx;aatx++) - for (aarx=0;aarxnb_antennas_rx;aarx++) - avgs = cmax(avgs,avg[(aatx<<1)+aarx]); - - gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1; - - } - - nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext, - gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, - gNB->pusch_vars[UE_id]->ul_ch_mag0, - gNB->pusch_vars[UE_id]->ul_ch_magb0, - gNB->pusch_vars[UE_id]->rxdataF_comp, - (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL, - frame_parms, + nr_ulsch_extract_rbs_single(gNB->common_vars.rxdataF, + gNB->pusch_vars[UE_id], symbol, dmrs_symbol_flag, - rel15_ul->qam_mod_order, - rel15_ul->rb_size, - gNB->pusch_vars[UE_id]->log2_maxh); + rel15_ul, + frame_parms); + + nr_ulsch_scale_channel(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + frame_parms, + gNB->ulsch[UE_id], + symbol, + dmrs_symbol_flag, + rel15_ul->rb_size, + rel15_ul->dmrs_config_type); + + + if (gNB->pusch_vars[UE_id]->cl_done==0) { + + nr_ulsch_channel_level(gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + frame_parms, + avg, + symbol, + nb_re_pusch, + rel15_ul->rb_size); + + avgs = 0; + + for (aatx=0;aatxnb_antennas_tx;aatx++) + for (aarx=0;aarxnb_antennas_rx;aarx++) + avgs = cmax(avgs,avg[(aatx<<1)+aarx]); + + gNB->pusch_vars[UE_id]->log2_maxh = (log2_approx(avgs)/2)+1; + gNB->pusch_vars[UE_id]->cl_done = 1; + } + + nr_ulsch_channel_compensation(gNB->pusch_vars[UE_id]->rxdataF_ext, + gNB->pusch_vars[UE_id]->ul_ch_estimates_ext, + gNB->pusch_vars[UE_id]->ul_ch_mag0, + gNB->pusch_vars[UE_id]->ul_ch_magb0, + gNB->pusch_vars[UE_id]->rxdataF_comp, + (frame_parms->nb_antennas_tx>1) ? gNB->pusch_vars[UE_id]->rho : NULL, + frame_parms, + symbol, + dmrs_symbol_flag, + rel15_ul->qam_mod_order, + rel15_ul->rb_size, + gNB->pusch_vars[UE_id]->log2_maxh); #ifdef NR_SC_FDMA - nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch); + nr_idft(&((uint32_t*)gNB->pusch_vars[UE_id]->rxdataF_ext[0])[symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], nb_re_pusch); #endif //---------------------------------------------------------- //-------------------- LLRs computation -------------------- //---------------------------------------------------------- - nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], - gNB->pusch_vars[UE_id]->ul_ch_mag0, - gNB->pusch_vars[UE_id]->ul_ch_magb0, - &gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order], - rel15_ul->rb_size, - nb_re_pusch, - symbol, - rel15_ul->qam_mod_order); + nr_ulsch_compute_llr(&gNB->pusch_vars[UE_id]->rxdataF_comp[0][symbol * rel15_ul->rb_size * NR_NB_SC_PER_RB], + gNB->pusch_vars[UE_id]->ul_ch_mag0, + gNB->pusch_vars[UE_id]->ul_ch_magb0, + &gNB->pusch_vars[UE_id]->llr[gNB->pusch_vars[UE_id]->rxdataF_ext_offset * rel15_ul->qam_mod_order], + rel15_ul->rb_size, + nb_re_pusch, + symbol, + rel15_ul->qam_mod_order); - gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch - gNB->pusch_vars[UE_id]->ptrs_sc_per_ofdm_symbol; + } + + gNB->pusch_vars[UE_id]->rxdataF_ext_offset = gNB->pusch_vars[UE_id]->rxdataF_ext_offset + nb_re_pusch; } diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c index cc22e5f7d7..24fcbf2e5b 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_adjust_synch_ue.c @@ -35,8 +35,8 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, PHY_VARS_NR_UE *ue, - module_id_t eNB_id, - uint8_t subframe, + module_id_t gNB_id, + uint8_t subframe, unsigned char clear, short coef) { @@ -60,8 +60,8 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, temp = 0; for (aa=0; aanb_antennas_rx; aa++) { - Re = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; - Im = ((int16_t*)ue->pbch_vars[eNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; + Re = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[(i<<1)]; + Im = ((int16_t*)ue->pbch_vars[gNB_id]->dl_ch_estimates_time[aa])[1+(i<<1)]; temp += (Re*Re/2) + (Im*Im/2); } @@ -111,11 +111,11 @@ void nr_adjust_synch_ue(NR_DL_FRAME_PARMS *frame_parms, } } - if ( ue->rx_offset < 0 ) - ue->rx_offset += frame_parms->samples_per_frame; + if (ue->rx_offset < 0) + ue->rx_offset += frame_parms->samples_per_frame; - if ( ue->rx_offset >= frame_parms->samples_per_frame ) - ue->rx_offset -= frame_parms->samples_per_frame; + if (ue->rx_offset >= frame_parms->samples_per_frame) + ue->rx_offset -= frame_parms->samples_per_frame; diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h index af06f9a98f..6326ed9446 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_estimation.h @@ -90,6 +90,7 @@ void phy_adjust_gain_nr(PHY_VARS_NR_UE *ue, uint32_t rx_power_fil_dB, uint8_t eNB_id); -int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index); +int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index); + #endif diff --git a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c index aa1e2b5ade..860ca11d8c 100644 --- a/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c +++ b/openair1/PHY/NR_UE_ESTIMATION/nr_ue_measurements.c @@ -55,8 +55,9 @@ void print_ints(char *s,int *x) } #endif -int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index) -{ +int16_t get_nr_PL(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index){ + + PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; /* if (ue->frame_parms.mode1_flag == 1) @@ -75,9 +76,6 @@ int16_t get_nr_PL(PHY_VARS_NR_UE *ue,uint8_t gNB_index) //(ue->frame_parms.pdsch_config_common.referenceSignalPower*10))/10)); } - - - void nr_ue_measurements(PHY_VARS_NR_UE *ue, unsigned int subframe_offset, unsigned char N0_symbol, diff --git a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c index ef22b61260..6d98031843 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/dci_nr.c @@ -814,6 +814,8 @@ void nr_pdcch_unscrambling(uint16_t crnti, NR_DL_FRAME_PARMS *frame_parms, uint8 x2 = (((1<<16)*n_rnti)+n_id); //mod 2^31 is implicit //this is c_init in 38.211 v15.1.0 Section 7.3.2.3 + LOG_D(PHY,"PDCCH Unscrambling x2 %x : n_RNTI %x\n",x2,n_rnti); + for (i = 0; i < length; i++) { if ((i & 0x1f) == 0) { s = lte_gold_generic(&x1, &x2, reset); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 00167507ce..6aa9ab9d4b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -215,16 +215,16 @@ void nr_dlsch_unscrambling(int16_t* llr, } uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, - short *dlsch_llr, - NR_DL_FRAME_PARMS *frame_parms, - NR_UE_DLSCH_t *dlsch, - NR_DL_UE_HARQ_t *harq_process, - uint32_t frame, - uint16_t nb_symb_sch, - uint8_t nr_tti_rx, - uint8_t harq_pid, - uint8_t is_crnti, - uint8_t llr8_flag) + short *dlsch_llr, + NR_DL_FRAME_PARMS *frame_parms, + NR_UE_DLSCH_t *dlsch, + NR_DL_UE_HARQ_t *harq_process, + uint32_t frame, + uint16_t nb_symb_sch, + uint8_t nr_tti_rx, + uint8_t harq_pid, + uint8_t is_crnti, + uint8_t llr8_flag) { #if UE_TIMING_TRACE @@ -264,7 +264,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t dmrs_Type = harq_process->dmrsConfigType; AssertFatal(dmrs_Type == 1 || dmrs_Type == 2,"Illegal dmrs_type %d\n",dmrs_Type); - uint8_t nb_re_dmrs = (dmrs_Type==1)?6:4; + uint8_t nb_re_dmrs = 12;//(dmrs_Type==1)?6:4; uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos); AssertFatal(dmrs_length == 1 || dmrs_length == 2,"Illegal dmrs_length %d\n",dmrs_length); @@ -318,7 +318,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs - harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, harq_process->Nl); + harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*dmrs_length, nb_rb_oh, 0, harq_process->Nl); A = harq_process->TBS; ret = dlsch->max_ldpc_iterations + 1; @@ -327,7 +327,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, harq_process->G = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, dmrs_length, harq_process->Qm,harq_process->Nl); G = harq_process->G; - LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d G %d nb_re_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,G, nb_re_dmrs,harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); + LOG_D(PHY,"DLSCH Decoding, harq_pid %d TBS %d (%d) G %d nb_re_dmrs %d mcs %d Nl %d nb_symb_sch %d nb_rb %d\n",harq_pid,A,A/8,G, nb_re_dmrs,harq_process->mcs, harq_process->Nl, nb_symb_sch,nb_rb); if ((harq_process->R)<1024) Coderate = (float) (harq_process->R) /(float) 1024; @@ -802,8 +802,8 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, //nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config; //uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value; - uint8_t nb_re_dmrs = (dmrs_type==1)?6:4; - uint16_t length_dmrs = get_num_dmrs(harq_process->dlDmrsSymbPos); + uint8_t nb_re_dmrs = 12;//(dmrs_type==1)?6:4; + uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos); uint32_t i,j; // int nbDlProcessing =0; @@ -855,7 +855,7 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs - harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl); + harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, 0, harq_process->Nl); A = harq_process->TBS; @@ -1432,7 +1432,7 @@ void nr_dlsch_decoding_process(void *arg) uint16_t nb_rb_oh = 0; // it was not computed at UE side even before and set to 0 in nr_compute_tbs - harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, harq_process->Nl); + harq_process->TBS = nr_compute_tbs(harq_process->Qm,harq_process->R,nb_rb,nb_symb_sch,nb_re_dmrs*length_dmrs, nb_rb_oh, 0, harq_process->Nl); A = harq_process->TBS; //2072 for QPSK 1/3 @@ -1698,10 +1698,10 @@ void nr_dlsch_decoding_process(void *arg) } no_iteration_ldpc = nrLDPC_decoder(p_decParams, - (int8_t*)&pl[0], - llrProcBuf, - p_nrLDPC_procBuf, - p_procTime); + (int8_t*)&pl[0], + llrProcBuf, + p_nrLDPC_procBuf, + p_procTime); // Fixme: correct type is unsigned, but nrLDPC_decoder and all called behind use signed int if (check_crc((uint8_t*)llrProcBuf,length_dec,harq_process->F,crc_type)) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index c704efdb1f..43545bada2 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -155,17 +155,18 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, uint16_t n_tx=1, n_rx=1; int32_t median[16]; uint32_t len; - + + switch (type) { case SI_PDSCH: - pdsch_vars = &ue->pdsch_vars_SI[eNB_id]; + pdsch_vars = ue->pdsch_vars_SI; dlsch = &ue->dlsch_SI[eNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; beamforming_mode = 0; break; case RA_PDSCH: - pdsch_vars = &ue->pdsch_vars_ra[eNB_id]; + pdsch_vars = ue->pdsch_vars_ra; dlsch = &ue->dlsch_ra[eNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; beamforming_mode = 0; @@ -174,17 +175,15 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, case PDSCH: pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]]; dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id]; - - - dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); - dlsch[0]->harq_processes[harq_pid]->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); - - //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status); + dlsch[0]->harq_processes[harq_pid]->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); + dlsch[0]->harq_processes[harq_pid]->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); + + //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status); LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", - frame,nr_tti_rx,symbol,harq_pid, - dlsch[0]->harq_processes[harq_pid]->status, - dlsch[1]->harq_processes[harq_pid]->status); - + frame,nr_tti_rx,symbol,harq_pid, + dlsch[0]->harq_processes[harq_pid]->status, + dlsch[1]->harq_processes[harq_pid]->status); + if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) && (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE)){ codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword; @@ -195,8 +194,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, printf("[DEMOD] I am assuming both TBs are active\n"); #endif } - else if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) && - (dlsch[1]->harq_processes[harq_pid]->status != ACTIVE) ) { + else if ((dlsch[0]->harq_processes[harq_pid]->status == ACTIVE) && + (dlsch[1]->harq_processes[harq_pid]->status != ACTIVE) ) { codeword_TB0 = dlsch[0]->harq_processes[harq_pid]->codeword; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; dlsch1_harq = NULL; @@ -205,8 +204,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, printf("[DEMOD] I am assuming only TB0 is active\n"); #endif } - else if ((dlsch[0]->harq_processes[harq_pid]->status != ACTIVE) && - (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE) ){ + else if ((dlsch[0]->harq_processes[harq_pid]->status != ACTIVE) && + (dlsch[1]->harq_processes[harq_pid]->status == ACTIVE) ){ codeword_TB1 = dlsch[1]->harq_processes[harq_pid]->codeword; dlsch0_harq = dlsch[1]->harq_processes[harq_pid]; dlsch1_harq = NULL; @@ -221,17 +220,18 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, } beamforming_mode = ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]; break; - + default: - LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n",nr_tti_rx,type); + AssertFatal(1==0,"[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n",nr_tti_rx,type); return(-1); break; } + #ifdef DEBUG_HARQ printf("[DEMOD] MIMO mode = %d\n", dlsch0_harq->mimo_mode); printf("[DEMOD] cw for TB0 = %d, cw for TB1 = %d\n", codeword_TB0, codeword_TB1); #endif - + start_rb = dlsch0_harq->start_rb; nb_rb_pdsch = dlsch0_harq->nb_rb; @@ -363,7 +363,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, nr_tti_rx, ue->high_speed_flag, frame_parms); - + } /*else if(beamforming_mode>7) { LOG_W(PHY,"dlsch_demodulation: beamforming mode not supported yet.\n"); }*/ @@ -624,7 +624,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, write_output("rho2_mrc.m","rho2_0",&pdsch_vars[eNB_id]->dl_ch_rho2_ext[0][symbol*frame_parms->N_RB_DL*12],frame_parms->N_RB_DL*12,1,1);//should be almost 0 } */ } - } + } //printf("start compute LLR\n"); if (dlsch0_harq->mimo_mode == NR_DUALSTREAM) { @@ -655,19 +655,19 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, // -> // compute @pointer where llrs should filled for this ofdm-symbol if (first_symbol_flag==1) pdsch_vars[eNB_id]->llr_offset[symbol-1] = 0; - llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol-1]; - //pllr_symbol_cw0_deint = (int8_t*)pdsch_vars[eNB_id]->llr[0]; - //pllr_symbol_cw1_deint = (int8_t*)pdsch_vars[eNB_id]->llr[1]; - pllr_symbol_layer0 = pdsch_vars[eNB_id]->layer_llr[0]; - pllr_symbol_layer1 = pdsch_vars[eNB_id]->layer_llr[1]; - pllr_symbol_layer0 += llr_offset_symbol; - pllr_symbol_layer1 += llr_offset_symbol; - pllr_symbol_cw0 = pdsch_vars[eNB_id]->llr[0]; - pllr_symbol_cw1 = pdsch_vars[eNB_id]->llr[1]; - pllr_symbol_cw0 += llr_offset_symbol; - pllr_symbol_cw1 += llr_offset_symbol; - - pdsch_vars[eNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol; + llr_offset_symbol = pdsch_vars[eNB_id]->llr_offset[symbol-1]; + //pllr_symbol_cw0_deint = (int8_t*)pdsch_vars[eNB_id]->llr[0]; + //pllr_symbol_cw1_deint = (int8_t*)pdsch_vars[eNB_id]->llr[1]; + pllr_symbol_layer0 = pdsch_vars[eNB_id]->layer_llr[0]; + pllr_symbol_layer1 = pdsch_vars[eNB_id]->layer_llr[1]; + pllr_symbol_layer0 += llr_offset_symbol; + pllr_symbol_layer1 += llr_offset_symbol; + pllr_symbol_cw0 = pdsch_vars[eNB_id]->llr[0]; + pllr_symbol_cw1 = pdsch_vars[eNB_id]->llr[1]; + pllr_symbol_cw0 += llr_offset_symbol; + pllr_symbol_cw1 += llr_offset_symbol; + + pdsch_vars[eNB_id]->llr_offset[symbol] = len*dlsch0_harq->Qm + llr_offset_symbol; /*LOG_I(PHY,"compute LLRs [symbol %d] NbRB %d Qm %d LLRs-Length %d LLR-Offset %d @LLR Buff %x @LLR Buff(symb) %x\n", symbol, @@ -689,13 +689,13 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, case 2 : if ((rx_type==rx_standard) || (codeword_TB1 == -1)) { nr_dlsch_qpsk_llr(frame_parms, - pdsch_vars[eNB_id]->rxdataF_comp0, - pllr_symbol_cw0, - symbol, - len, - first_symbol_flag, - nb_rb, - beamforming_mode); + pdsch_vars[eNB_id]->rxdataF_comp0, + pllr_symbol_cw0, + symbol, + len, + first_symbol_flag, + nb_rb, + beamforming_mode); } else if (codeword_TB0 == -1){ @@ -1003,7 +1003,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, return(-1); break; } - } + } //nr_dlsch_deinterleaving(symbol,bundle_L,(int16_t*)pllr_symbol_cw0,(int16_t*)pllr_symbol_cw0_deint, nb_rb_pdsch); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index f407119024..e7d930b34a 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -19,13 +19,13 @@ * contact@openairinterface.org */ -/*! \file PHY/LTE_TRANSPORT/prach_common.c - * \brief Common routines for UE/eNB PRACH physical channel V8.6 2009-03 - * \author R. Knopp - * \date 2011 - * \version 0.1 - * \company Eurecom - * \email: knopp@eurecom.fr +/*! \file PHY/NR_TRANSPORT/nr_prach.c + * \brief Routines for UE PRACH physical channel + * \author R. Knopp, G. Casati + * \date 2019 + * \version 0.2 + * \company Eurecom, Fraunhofer IIS + * \email: knopp@eurecom.fr, guido.casati@iis.fraunhofer.de * \note * \warning */ @@ -35,14 +35,14 @@ #include "PHY/impl_defs_nr.h" #include "PHY/defs_nr_UE.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" +#include "PHY/NR_TRANSPORT/nr_transport_proto_common.h" #include "common/utils/LOG/log.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "T.h" - - +#define NR_PRACH_DEBUG 1 extern uint16_t NCS_unrestricted_delta_f_RA_125[16]; extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15]; @@ -58,77 +58,75 @@ extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9]; 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]; +extern const char *prachfmt[9]; +// Note: +// - prach_fmt_id is an ID used to map to the corresponding PRACH format value in prachfmt +// WIP todo: +// - take prach start symbol into account +// - idft for short sequence assumes we are transmitting starting in symbol 0 of a PRACH slot +// - Assumes that PRACH SCS is same as PUSCH SCS @ 30 kHz, take values for formats 0-2 and adjust for others below +// - Preamble index different from 0 is not detected by gNB +int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ - - - - - - -int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf ) -{ - - //lte_frame_type_t frame_type = ue->frame_parms.frame_type; - //uint8_t tdd_config = ue->frame_parms.tdd_config; NR_DL_FRAME_PARMS *fp=&ue->frame_parms; - uint16_t rootSequenceIndex = fp->prach_config_common.rootSequenceIndex; - uint8_t prach_ConfigIndex = fp->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; - uint8_t Ncs_config = fp->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig; - uint8_t restricted_set = fp->prach_config_common.prach_ConfigInfo.highSpeedFlag; - uint8_t preamble_index = ue->prach_resources[eNB_id]->ra_PreambleIndex; - //uint8_t tdd_mapindex = ue->prach_resources[eNB_id]->ra_TDD_map_index; - int16_t *prachF = ue->prach_vars[eNB_id]->prachF; + fapi_nr_config_request_t *nrUE_config = &ue->nrUE_config; + NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_id]; + fapi_nr_ul_config_prach_pdu *prach_pdu = &ue->prach_vars[gNB_id]->prach_pdu; + + uint8_t Mod_id, fd_occasion, preamble_index, restricted_set, not_found; + uint16_t rootSequenceIndex, prach_fmt_id, NCS, *prach_root_sequence_map, preamble_offset = 0; + uint16_t preamble_shift = 0, preamble_index0, n_shift_ra, n_shift_ra_bar, d_start, numshift, N_ZC, u, offset, offset2, first_nonzero_root_idx; int16_t prach_tmp[98304*2*4] __attribute__((aligned(32))); - int16_t *prach = prach_tmp; - int16_t *prach2; - int16_t amp = ue->prach_vars[eNB_id]->amp; - int16_t Ncp; - uint16_t NCS=0; - uint16_t *prach_root_sequence_map; - uint16_t preamble_offset,preamble_shift; - uint16_t preamble_index0,n_shift_ra,n_shift_ra_bar; - uint16_t d_start,numshift; + int16_t Ncp, amp, *prach, *prach2, *prachF, *Xu; + int32_t Xu_re, Xu_im, samp_count; + int prach_start, prach_sequence_length, i, prach_len, dftlen, mu, kbar, K, n_ra_prb, k; + //int restricted_Type; - uint16_t prach_fmt = get_nr_prach_fmt(prach_ConfigIndex,fp->frame_type,fp->freq_range); - //uint8_t Nsp=2; - //uint8_t f_ra,t1_ra; - uint16_t N_ZC = (prach_fmt<4)?839:139; - uint8_t not_found; - int16_t *Xu; - uint16_t u; - int32_t Xu_re,Xu_im; - uint16_t offset,offset2; - int prach_start; - int i, prach_len=0; - uint16_t first_nonzero_root_idx=0; + prach = prach_tmp; + prachF = ue->prach_vars[gNB_id]->prachF; + amp = ue->prach_vars[gNB_id]->amp; + Mod_id = ue->Mod_id; + prach_sequence_length = nrUE_config->prach_config.prach_sequence_length; + N_ZC = (prach_sequence_length == 0) ? 839:139; + mu = nrUE_config->prach_config.prach_sub_c_spacing; + restricted_set = prach_pdu->restricted_set; + rootSequenceIndex = prach_pdu->root_seq_id; + n_ra_prb = prach_pdu->freq_msg1; + NCS = prach_pdu->num_cs; + prach_fmt_id = prach_pdu->prach_format; + preamble_index = prach_resources->ra_PreambleIndex; + fd_occasion = 0; + prach_len = 0; + dftlen = 0; + first_nonzero_root_idx = 0; + kbar = 1; + K = 24; + k = 12*n_ra_prb - 6*fp->N_RB_UL; + //prachStartSymbol = prach_config_pdu->prach_start_symbol + //restricted_Type = 0; -#if defined(OAI_USRP) - prach_start = (ue->rx_offset+subframe*fp->samples_per_subframe-ue->hw_timing_advance-ue->N_TA_offset); -#ifdef NR_PRACH_DEBUG - LOG_I(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id, - prach_start, - ue->rx_offset, - ue->hw_timing_advance, - ue->N_TA_offset); -#endif + compute_nr_prach_seq(nrUE_config->prach_config.prach_sequence_length, + nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].num_root_sequences, + nrUE_config->prach_config.num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index, + ue->X_u); + + if (mu == 0) + samp_count = fp->samples_per_subframe; + else + samp_count = (slot%(fp->slots_per_subframe/2)) ? fp->samples_per_slotN0 : fp->samples_per_slot0; + + #if defined (OAI_USRP) + prach_start = (ue->rx_offset + slot*samp_count - ue->hw_timing_advance - ue->N_TA_offset); + #else //normal case (simulation) + prach_start = slot*samp_count - ue->N_TA_offset; + #endif if (prach_start<0) - prach_start+=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - - if (prach_start>=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)) - prach_start-=(fp->samples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME); - -#else //normal case (simulation) - prach_start = subframe*fp->samples_per_subframe-ue->N_TA_offset; - LOG_D(PHY,"[UE %d] prach_start %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", ue->Mod_id, - prach_start, - ue->rx_offset, - ue->hw_timing_advance, - ue->N_TA_offset); - -#endif + prach_start += (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME); + if (prach_start >= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME)) + prach_start -= (fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME); // First compute physical root sequence /************************************************************************ @@ -138,41 +136,19 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, * NOTE: Restricted set type B is not implemented *************************************************************************/ - int restricted_Type = 0; //this is hardcoded ('0' for restricted_TypeA; and '1' for restricted_TypeB). FIXME - if (prach_fmt<3){ - if (restricted_set == 0) { - NCS = NCS_unrestricted_delta_f_RA_125[Ncs_config]; - } else { - if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_125[Ncs_config]; // for TypeA, this is hardcoded. FIXME - if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_125[Ncs_config]; // for TypeB, this is hardcoded. FIXME - } - } - if (prach_fmt==3){ - if (restricted_set == 0) { - NCS = NCS_unrestricted_delta_f_RA_5[Ncs_config]; - } else { - if (restricted_Type == 0) NCS = NCS_restricted_TypeA_delta_f_RA_5[Ncs_config]; // for TypeA, this is hardcoded. FIXME - if (restricted_Type == 1) NCS = NCS_restricted_TypeB_delta_f_RA_5[Ncs_config]; // for TypeB, this is hardcoded. FIXME - } - } - if (prach_fmt>3){ - NCS = NCS_unrestricted_delta_f_RA_15[Ncs_config]; - } - - prach_root_sequence_map = (prach_fmt<4) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc; - - // This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index - preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS))); + prach_root_sequence_map = (prach_sequence_length == 0) ? prach_root_sequence_map_0_3 : prach_root_sequence_map_abc; if (restricted_set == 0) { + // This is the relative offset (for unrestricted case) in the root sequence table (5.7.2-4 from 36.211) for the given preamble index + preamble_offset = ((NCS==0)? preamble_index : (preamble_index/(N_ZC/NCS))); // This is the \nu corresponding to the preamble index preamble_shift = (NCS==0)? 0 : (preamble_index % (N_ZC/NCS)); preamble_shift *= NCS; } else { // This is the high-speed case -#ifdef NR_PRACH_DEBUG - LOG_I(PHY,"[UE %d] High-speed mode, NCS_config %d\n",ue->Mod_id,Ncs_config); -#endif + #ifdef NR_PRACH_DEBUG + LOG_I(PHY, "PRACH [UE %d] High-speed mode, NCS %d\n", Mod_id, NCS); + #endif not_found = 1; preamble_index0 = preamble_index; @@ -183,8 +159,9 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, while (not_found == 1) { // current root depending on rootSequenceIndex and preamble_offset int index = (rootSequenceIndex + preamble_offset) % N_ZC; + uint16_t n_group_ra = 0; - if (prach_fmt<4) { + if (prach_fmt_id<4) { // prach_root_sequence_map points to prach_root_sequence_map0_3 DevAssert( index < sizeof(prach_root_sequence_map_0_3) / sizeof(prach_root_sequence_map_0_3[0]) ); } else { @@ -194,8 +171,6 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, u = prach_root_sequence_map[index]; - uint16_t n_group_ra = 0; - if ( (nr_du[u]<(N_ZC/3)) && (nr_du[u]>=NCS) ) { n_shift_ra = nr_du[u]/NCS; d_start = (nr_du[u]<<1) + (n_shift_ra * NCS); @@ -229,43 +204,49 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, } // now generate PRACH signal -#ifdef NR_PRACH_DEBUG - - if (NCS>0) - LOG_D(PHY,"Generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %x, prach_ConfigIndex %d, NCS %d (NCS_config %d, N_ZC/NCS %d): Preamble_offset %d, Preamble_shift %d\n", - rootSequenceIndex,preamble_index,prach_fmt,prach_ConfigIndex,NCS,Ncs_config,N_ZC/NCS, - preamble_offset,preamble_shift); - -#endif + #ifdef NR_PRACH_DEBUG + if (NCS>0) + LOG_I(PHY, "PRACH [UE %d] generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d\n", Mod_id, + rootSequenceIndex, + preamble_index, + prachfmt[prach_fmt_id], + NCS, + N_ZC, + preamble_offset, + preamble_shift); + #endif // nsymb = (frame_parms->Ncp==0) ? 14:12; - // subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*subframe*nsymb; - int kbar = 1; - int K = 24; - if (prach_fmt == 3) { - K=4; - kbar=10; + // subframe_offset = (unsigned int)frame_parms->ofdm_symbol_size*slot*nsymb; + + if (prach_sequence_length == 0 && prach_fmt_id == 3) { + K = 4; + kbar = 10; + } else if (prach_sequence_length == 1) { + K = 1; + kbar = 2; } - else if (prach_fmt > 3) { - // Note: Assumes that PRACH SCS is same as PUSCH SCS - K=1; - kbar=2; - } - int n_ra_prb = fp->prach_config_common.prach_ConfigInfo.msg1_frequencystart; - int k = (12*n_ra_prb) - 6*fp->N_RB_UL; - k = (12*n_ra_prb) - 6*fp->N_RB_UL; + if (k<0) + k += fp->ofdm_symbol_size; - if (k<0) k+=fp->ofdm_symbol_size; + k *= K; + k += kbar; + k *= 2; - k*=K; - k+=kbar; - - LOG_D(PHY,"placing prach in position %d\n",k); - k*=2; + LOG_I(PHY, "PRACH [UE %d] in slot %d, placing PRACH in position %d, msg1 frequency start %d, preamble_offset %d, first_nonzero_root_idx %d\n", Mod_id, + slot, + k, + n_ra_prb, + preamble_offset, + first_nonzero_root_idx); Xu = (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx]; + #if defined (PRACH_WRITE_OUTPUT_DEBUG) + LOG_M("X_u.m", "X_u", (int16_t*)ue->X_u[preamble_offset-first_nonzero_root_idx], N_ZC, 1, 1); + #endif + /******************************************************** * * In function init_prach_tables: @@ -280,10 +261,86 @@ int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, * *********************************************************/ - AssertFatal(prach_fmt>3,"prach_fmt<=3: Fix this for other formats\n"); - int dftlen=2048; - if (fp->N_RB_UL >= 137) dftlen=4096; - if (fp->threequarter_fs==1) dftlen=(3*dftlen)/4; + if (fp->N_RB_UL <= 100) + AssertFatal(1 == 0, "N_RB_UL %d not support for NR PRACH yet\n", fp->N_RB_UL); + else if (fp->N_RB_UL < 137) { + if (fp->threequarter_fs == 0) { + //40 MHz @ 61.44 Ms/s + //50 MHz @ 61.44 Ms/s + if (prach_sequence_length == 0) { + if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) + dftlen = 49152; + if (prach_fmt_id == 3) + dftlen = 12288; + } // 839 sequence + else { + switch (mu){ + case 1: + dftlen = 2048; + break; + default: + AssertFatal(1 == 0, "Shouldn't get here\n"); + break; + } + } + } else { // threequarter sampling + // 40 MHz @ 46.08 Ms/s + if (prach_sequence_length == 0) { + AssertFatal(fp->N_RB_UL <= 107, "cannot do 108..136 PRBs with 3/4 sampling\n"); + if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) + dftlen = 36864; + if (prach_fmt_id == 3) + dftlen = 9216; + } else { + switch (mu){ + case 1: + dftlen = 1536; + break; + default: + AssertFatal(1 == 0, "Shouldn't get here\n"); + break; + } + } // short format + } // 3/4 sampling + } // <=50 MHz BW + else if (fp->N_RB_UL <= 273) { + if (fp->threequarter_fs == 0) { + //80,90,100 MHz @ 122.88 Ms/s + if (prach_sequence_length == 0) { + if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) + dftlen = 98304; + if (prach_fmt_id == 3) + dftlen = 24576; + } + } else { // threequarter sampling + switch (mu){ + case 1: + dftlen = 4096; + break; + default: + AssertFatal(1 == 0, "Shouldn't get here\n"); + break; + } + } + } else { + AssertFatal(fp->N_RB_UL <= 217, "cannot do more than 217 PRBs with 3/4 sampling\n"); + // 80 MHz @ 92.16 Ms/s + if (prach_sequence_length == 0) { + if (prach_fmt_id == 0 || prach_fmt_id == 1 || prach_fmt_id == 2) + dftlen = 73728; + if (prach_fmt_id == 3) + dftlen = 18432; + } else { + switch (mu){ + case 1: + dftlen = 3072; + break; + default: + AssertFatal(1 == 0, "Shouldn't get here\n"); + break; + } + } + } for (offset=0,offset2=0; offset>15); prachF[k++]= ((Xu_re*nr_ru[offset2<<1]) - (Xu_im*nr_ru[1+(offset2<<1)]))>>15; prachF[k++]= ((Xu_im*nr_ru[offset2<<1]) + (Xu_re*nr_ru[1+(offset2<<1)]))>>15; + if (k==dftlen) k=0; } - switch (fp->N_RB_UL) { - case 6: - memset((void*)prachF,0,4*1536); - break; + #if defined (PRACH_WRITE_OUTPUT_DEBUG) + LOG_M("prachF.m", "prachF", &prachF[1804], 1024, 1, 1); + LOG_M("Xu.m", "Xu", Xu, N_ZC, 1, 1); + #endif - case 15: - memset((void*)prachF,0,4*3072); - break; + if (prach_sequence_length == 0) { - case 25: - memset((void*)prachF,0,4*6144); - break; + AssertFatal(prach_fmt_id < 4, "Illegal PRACH format %d for sequence length 839\n", prach_fmt_id); - case 50: - memset((void*)prachF,0,4*12288); - break; + switch (prach_fmt_id) { + case 0: + Ncp = 3168; + break; + case 1: + Ncp = 21024; + break; + case 2: + Ncp = 4688; + break; + case 3: + Ncp = 3168; + break; + } - case 75: - memset((void*)prachF,0,4*18432); - break; + } else { - case 100: - if (fp->threequarter_fs == 0) - memset((void*)prachF,0,4*24576); - else - memset((void*)prachF,0,4*18432); - break; + //LOG_D(PHY, "PRACH [UE %d] in slot %d, format %d, msg1 frequency start %d startSymbol %d \n", Mod_id, slot, prachfmt[prach_fmt_id], n_ra_prb, prachStartSymbol); - case 106: - memset((void*)prachF,0,4*24576); - break; -} - - int mu = 1; // numerology is hardcoded. FIXME!!! - switch (prach_fmt) { - case 0: - Ncp = 3168; - break; - - case 1: - Ncp = 2*21024; - break; - - case 2: - Ncp = 4688; - break; - - case 3: - Ncp = 3168; - break; - - case 0xa1: - Ncp = 288/(1<N_RB_UL <= 100) AssertFatal(1==0,"N_RB_UL %d not supported for NR PRACH yet\n",fp->N_RB_UL); else if (fp->N_RB_UL < 137) { // 46.08 or 61.44 Ms/s - if (fp->threequarter_fs==0) { //61.44 Ms/s + if (fp->threequarter_fs == 0) { // full sampling @ 61.44 Ms/s Ncp<<=1; // This is after cyclic prefix (Ncp<<1 samples for 30.72 Ms/s, Ncp<<2 samples for 61.44 Ms/s prach2 = prach+(Ncp<<1); - if (prach_fmt == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s - idft49152(prachF,prach2,1); - // here we have |empty | Prach49152| - memmove(prach,prach+(49152<<1),(Ncp<<3)); - // here we have |Prefix | Prach49152| - prach_len = 49152+Ncp; - dftlen=49152; + if (prach_sequence_length == 0){ + if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s + idft49152(prachF,prach2,1); + // here we have |empty | Prach49152| + memmove(prach,prach+(49152<<1),(Ncp<<2)); + // here we have |Prefix | Prach49152| + prach_len = 49152+Ncp; + } else if (prach_fmt_id == 1) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s + idft49152(prachF,prach2,1); + memmove(prach2+(49152<<1),prach2,(49152<<2)); + // here we have |empty | Prach49152 | Prach49152| + memmove(prach,prach+(49152<<2),(Ncp<<2)); + // here we have |Prefix | Prach49152 | Prach49152| + prach_len = (49152*2)+Ncp; + } else if (prach_fmt_id == 2) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s + idft49152(prachF,prach2,1); + memmove(prach2+(49152<<1),prach2,(49152<<2)); + // here we have |empty | Prach49152 | Prach49152| empty49152 | empty49152 + memmove(prach2+(49152<<2),prach2,(49152<<3)); + // here we have |empty | Prach49152 | Prach49152| Prach49152 | Prach49152 + memmove(prach,prach+(49152<<3),(Ncp<<2)); + // here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152 + prach_len = (49152*4)+Ncp; + } else if (prach_fmt_id == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s + idft12288(prachF,prach2,1); + memmove(prach2+(12288<<1),prach2,(12288<<2)); + // here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288 + memmove(prach2+(12288<<2),prach2,(12288<<3)); + // here we have |empty | Prach12288 | Prach12288| Prach12288 | Prach12288 + memmove(prach,prach+(12288<<3),(Ncp<<2)); + // here we have |Prefix | Prach12288 | Prach12288| Prach12288 | Prach12288 + prach_len = (12288*4)+Ncp; + } + } else { // short PRACH sequence + if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) { + Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft2048(prachF,prach2,1); + // here we have |empty | Prach2048 | + if (prach_fmt_id != 7) { + memmove(prach2+(2048<<1),prach2,(2048<<2)); + prach_len = (2048*2)+Ncp; + } + else prach_len = (2048*1)+Ncp; + memmove(prach,prach+(2048<<1),(Ncp<<2)); + // here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) | + } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x2048 + Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft2048(prachF,prach2,1); + // here we have |empty | Prach2048 | + memmove(prach2+(2048<<1),prach2,(2048<<2)); + // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | + memmove(prach2+(2048<<2),prach2,(2048<<3)); + // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | + memmove(prach,prach+(2048<<1),(Ncp<<2)); + // here we have |Prefix | Prach2048 | + prach_len = (2048*4)+Ncp; + } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x2048 + Ncp+=32; + prach2 = prach+(Ncp<<1); + idft2048(prachF,prach2,1); + // here we have |empty | Prach2048 | + memmove(prach2+(2048<<1),prach2,(2048<<2)); + // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048 + memmove(prach2+(2048<<2),prach2,(2048<<3)); + // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048 + memmove(prach2+(2048<<3),prach2,(2048<<3)); + // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 + memmove(prach,prach+(2048<<1),(Ncp<<2)); + // here we have |Prefix | Prach2048 | + prach_len = (2048*6)+Ncp; + } else if (prach_fmt_id == 6) { // 12x2048 + Ncp+=32; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft2048(prachF,prach2,1); + // here we have |empty | Prach2048 | + memmove(prach2+(2048<<1),prach2,(2048<<2)); + // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048 + memmove(prach2+(2048<<2),prach2,(2048<<3)); + // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048 + memmove(prach2+(2048<<3),prach2,(2048<<3)); + // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 + memmove(prach2+(2048<<1)*6,prach2,(2048<<2)*6); + // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048| + memmove(prach,prach+(2048<<1),(Ncp<<2)); + // here we have |Prefix | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048| + prach_len = (2048*12)+Ncp; + } } - else if (prach_fmt == 1) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s - idft49152(prachF,prach2,1); - memmove(prach2+(49152<<1),prach2,(49152<<2)); - // here we have |empty | Prach49152 | Prach49152| - memmove(prach,prach+(49152<<2),(Ncp<<3)); - // here we have |Prefix | Prach49152 | Prach49152| - prach_len = (49152*2)+Ncp; - dftlen=49152; - } - else if (prach_fmt == 2) { //24576 samples @ 30.72 Ms/s, 49152 samples @ 61.44 Ms/s - idft49152(prachF,prach2,1); - memmove(prach2+(49152<<1),prach2,(49152<<2)); - // here we have |empty | Prach49152 | Prach49152| empty49152 | empty49152 - memmove(prach2+(49152<<2),prach2,(49152<<3)); - // here we have |empty | Prach49152 | Prach49152| Prach49152 | Prach49152 - memmove(prach,prach+(49152<<3),(Ncp<<3)); - // here we have |Prefix | Prach49152 | Prach49152| Prach49152 | Prach49152 - prach_len = (49152*4)+Ncp; - dftlen=49152; - } - else if (prach_fmt == 3) { // //6144 samples @ 30.72 Ms/s, 12288 samples @ 61.44 Ms/s - idft12288(prachF,prach2,1); - memmove(prach2+(12288<<1),prach2,(12288<<2)); - // here we have |empty | Prach12288 | Prach12288| empty12288 | empty12288 - memmove(prach2+(12288<<2),prach2,(12288<<3)); - // here we have |empty | Prach12288 | Prach12288| Prach12288 | Prach12288 - memmove(prach,prach+(12288<<3),(Ncp<<3)); - // here we have |Prefix | Prach12288 | Prach12288| Prach12288 | Prach12288 - prach_len = (12288*4)+Ncp; - dftlen=12288; - } - else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) { - prach2 = prach+(Ncp<<1); - idft2048(prachF,prach2,1); - dftlen=2048; - // here we have |empty | Prach2048 | - if (prach_fmt != 0xc0) { - memmove(prach2+(2048<<1),prach2,(2048<<2)); - prach_len = (2048*2)+Ncp; - } - else prach_len = (2048*1)+Ncp; - memmove(prach,prach+(2048<<1),(Ncp<<2)); - // here we have |Prefix | Prach2048 | Prach2048 (if ! 0xc0) | - } - else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x2048 - idft2048(prachF,prach2,1); - dftlen=2048; - // here we have |empty | Prach2048 | - memmove(prach2+(2048<<1),prach2,(2048<<2)); - // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | - memmove(prach2+(2048<<2),prach2,(2048<<3)); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | - memmove(prach,prach+(2048<<1),(Ncp<<2)); - // here we have |Prefix | Prach2048 | - prach_len = (2048*4)+Ncp; - } - else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x2048 - prach2 = prach+(Ncp<<1); - idft2048(prachF,prach2,1); - dftlen=2048; - // here we have |empty | Prach2048 | - memmove(prach2+(2048<<1),prach2,(2048<<2)); - // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048 - memmove(prach2+(2048<<2),prach2,(2048<<3)); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048 - memmove(prach2+((2048<<1)*3),prach2,(2048<<3)); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 - memmove(prach,prach+(2048<<1),(Ncp<<2)); - // here we have |Prefix | Prach2048 | - prach_len = (2048*6)+Ncp; - } - else if (prach_fmt == 0xb4) { // 12x2048 - idft2048(prachF,prach2,1); - dftlen=2048; - // here we have |empty | Prach2048 | - memmove(prach2+(2048<<1),prach2,(2048<<2)); - // here we have |empty | Prach2048 | Prach2048| empty2048 | empty2048 | empty2048 | empty2048 - memmove(prach2+(2048<<2),prach2,(2048<<3)); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | empty2048 | empty2048 - memmove(prach2+(2048<<3),prach2,(2048<<3)); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 - memmove(prach2+(2048<<1)*6,prach2,(2048<<2)*6); - // here we have |empty | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048| - memmove(prach,prach+(2048<<1),(Ncp<<2)); - // here we have |Prefix | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048 | Prach2048| Prach2048 | Prach2048 | Prach2048 | Prach2048| - prach_len = (2048*12)+Ncp; - } - - } - else { // 46.08 Ms/s + } else { // threequarter sampling @ 46.08 Ms/s Ncp = (Ncp*3)/2; prach2 = prach+(Ncp<<1); - if (prach_fmt == 0) { - idft36864(prachF,prach2,1); - dftlen=36864; - // here we have |empty | Prach73728| - memmove(prach,prach+(36864<<1),(Ncp<<2)); - // here we have |Prefix | Prach73728| - prach_len = (36864*1)+Ncp; + if (prach_sequence_length == 0){ + if (prach_fmt_id == 0) { + idft36864(prachF,prach2,1); + // here we have |empty | Prach73728| + memmove(prach,prach+(36864<<1),(Ncp<<2)); + // here we have |Prefix | Prach73728| + prach_len = (36864*1)+Ncp; + } else if (prach_fmt_id == 1) { + idft36864(prachF,prach2,1); + memmove(prach2+(36864<<1),prach2,(36864<<2)); + // here we have |empty | Prach73728 | Prach73728| + memmove(prach,prach+(36864<<2),(Ncp<<2)); + // here we have |Prefix | Prach73728 | Prach73728| + prach_len = (36864*2)+Ncp; + } else if (prach_fmt_id == 2) { + idft36864(prachF,prach2,1); + memmove(prach2+(36864<<1),prach2,(36864<<2)); + // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728 + memmove(prach2+(36864<<2),prach2,(36864<<3)); + // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728 + memmove(prach,prach+(36864<<3),(Ncp<<2)); + // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728 + prach_len = (36864*4)+Ncp; + } else if (prach_fmt_id == 3) { + idft9216(prachF,prach2,1); + memmove(prach2+(9216<<1),prach2,(9216<<2)); + // here we have |empty | Prach9216 | Prach9216| empty9216 | empty9216 + memmove(prach2+(9216<<2),prach2,(9216<<3)); + // here we have |empty | Prach9216 | Prach9216| Prach9216 | Prach9216 + memmove(prach,prach+(9216<<3),(Ncp<<2)); + // here we have |Prefix | Prach9216 | Prach9216| Prach9216 | Prach9216 + prach_len = (9216*4)+Ncp; + } + } else { // short sequence + if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) { + Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft1536(prachF,prach2,1); + + // here we have |empty | Prach1536 | + if (prach_fmt_id != 7) { + memmove(prach2+(1536<<1),prach2,(1536<<2)); + prach_len = (1536*2)+Ncp; + } else prach_len = (1536*1)+Ncp; + + memmove(prach,prach+(1536<<1),(Ncp<<2)); + // here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) | + + } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 6x1536 + + Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft1536(prachF,prach2,1); + // here we have |empty | Prach1536 | + memmove(prach2+(1536<<1),prach2,(1536<<2)); + // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | + memmove(prach2+(1536<<2),prach2,(1536<<3)); + // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | + memmove(prach,prach+(1536<<1),(Ncp<<2)); + // here we have |Prefix | Prach1536 | + prach_len = (1536*4)+Ncp; + } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x1536 + Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft1536(prachF,prach2,1); + // here we have |empty | Prach1536 | + memmove(prach2+(1536<<1),prach2,(1536<<2)); + // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536 + memmove(prach2+(1536<<2),prach2,(1536<<3)); + // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536 + memmove(prach2+(1536<<3),prach2,(1536<<3)); + // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 + memmove(prach,prach+(1536<<1),(Ncp<<2)); + // here we have |Prefix | Prach1536 | + prach_len = (1536*6)+Ncp; + } else if (prach_fmt_id == 6) { // 12x1536 + Ncp+=24; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft1536(prachF,prach2,1); + // here we have |empty | Prach1536 | + memmove(prach2+(1536<<1),prach2,(1536<<2)); + // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536 + memmove(prach2+(1536<<2),prach2,(1536<<3)); + // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536 + memmove(prach2+(1536<<3),prach2,(1536<<3)); + // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 + memmove(prach2+(1536<<1)*6,prach2,(1536<<2)*6); + // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536| + memmove(prach,prach+(1536<<1),(Ncp<<2)); + // here we have |Prefix | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536| + prach_len = (1536*12)+Ncp; + } } - else if (prach_fmt == 1) { - idft36864(prachF,prach2,1); - dftlen=36864; - memmove(prach2+(36864<<1),prach2,(36864<<2)); - // here we have |empty | Prach73728 | Prach73728| - memmove(prach,prach+(36864<<2),(Ncp<<2)); - // here we have |Prefix | Prach73728 | Prach73728| - prach_len = (36864*2)+Ncp; - } - if (prach_fmt == 2) { - idft36864(prachF,prach2,1); - dftlen=36864; - memmove(prach2+(36864<<1),prach2,(36864<<2)); - // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728 - memmove(prach2+(36864<<2),prach2,(36864<<3)); - // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728 - memmove(prach,prach+(36864<<3),(Ncp<<2)); - // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728 - prach_len = (36864*4)+Ncp; - } - else if (prach_fmt == 3) { - idft9216(prachF,prach2,1); - dftlen=36864; - memmove(prach2+(9216<<1),prach2,(9216<<2)); - // here we have |empty | Prach9216 | Prach9216| empty9216 | empty9216 - memmove(prach2+(9216<<2),prach2,(9216<<3)); - // here we have |empty | Prach9216 | Prach9216| Prach9216 | Prach9216 - memmove(prach,prach+(9216<<3),(Ncp<<2)); - // here we have |Prefix | Prach9216 | Prach9216| Prach9216 | Prach9216 - prach_len = (9216*4)+Ncp; - } - else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) { - idft1536(prachF,prach2,1); - dftlen=1536; - // here we have |empty | Prach1536 | - if (prach_fmt != 0xc0) - memmove(prach2+(1536<<1),prach2,(1536<<2)); - memmove(prach,prach+(1536<<1),(Ncp<<2)); - // here we have |Prefix | Prach1536 | Prach1536 (if ! 0xc0) | - prach_len = (1536*2)+Ncp; - } - else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 6x1536 - idft1536(prachF,prach2,1); - dftlen=1536; - // here we have |empty | Prach1536 | - memmove(prach2+(1536<<1),prach2,(1536<<2)); - // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | - memmove(prach2+(1536<<2),prach2,(1536<<3)); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | - memmove(prach,prach+(1536<<1),(Ncp<<2)); - // here we have |Prefix | Prach1536 | - prach_len = (1536*4)+Ncp; - } - else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x1536 - idft1536(prachF,prach2,1); - dftlen=1536; - // here we have |empty | Prach1536 | - memmove(prach2+(1536<<1),prach2,(1536<<2)); - // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536 - memmove(prach2+(1536<<2),prach2,(1536<<3)); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536 - memmove(prach2+((1536<<1)*3),prach2,(1536<<3)); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 - memmove(prach,prach+(1536<<1),(Ncp<<2)); - // here we have |Prefix | Prach1536 | - prach_len = (1536*6)+Ncp; - } - else if (prach_fmt == 0xb4) { // 12x1536 - idft1536(prachF,prach2,1); - dftlen=1536; - // here we have |empty | Prach1536 | - memmove(prach2+(1536<<1),prach2,(1536<<2)); - // here we have |empty | Prach1536 | Prach1536| empty1536 | empty1536 | empty1536 | empty1536 - memmove(prach2+(1536<<2),prach2,(1536<<3)); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | empty1536 | empty1536 - memmove(prach2+(1536<<3),prach2,(1536<<3)); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 - memmove(prach2+(1536<<1)*6,prach2,(1536<<2)*6); - // here we have |empty | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536| - memmove(prach,prach+(1536<<1),(Ncp<<2)); - // here we have |Prefix | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536 | Prach1536| Prach1536 | Prach1536 | Prach1536 | Prach1536| - prach_len = (1536*12)+Ncp; - } } - } - else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s - if (fp->threequarter_fs==0) { //122.88 Ms/s + } else if (fp->N_RB_UL <= 273) {// 92.16 or 122.88 Ms/s + if (fp->threequarter_fs == 0) { // full sampling @ 122.88 Ms/s Ncp<<=2; prach2 = prach+(Ncp<<1); - if (prach_fmt == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s - idft98304(prachF,prach2,1); - dftlen=98304; - // here we have |empty | Prach98304| - memmove(prach,prach+(98304<<1),(Ncp<<2)); - // here we have |Prefix | Prach98304| - prach_len = (98304*1)+Ncp; + if (prach_sequence_length == 0){ + if (prach_fmt_id == 0) { //24576 samples @ 30.72 Ms/s, 98304 samples @ 122.88 Ms/s + idft98304(prachF,prach2,1); + // here we have |empty | Prach98304| + memmove(prach,prach+(98304<<1),(Ncp<<2)); + // here we have |Prefix | Prach98304| + prach_len = (98304*1)+Ncp; + } else if (prach_fmt_id == 1) { + idft98304(prachF,prach2,1); + memmove(prach2+(98304<<1),prach2,(98304<<2)); + // here we have |empty | Prach98304 | Prach98304| + memmove(prach,prach+(98304<<2),(Ncp<<2)); + // here we have |Prefix | Prach98304 | Prach98304| + prach_len = (98304*2)+Ncp; + } else if (prach_fmt_id == 2) { + idft98304(prachF,prach2,1); + memmove(prach2+(98304<<1),prach2,(98304<<2)); + // here we have |empty | Prach98304 | Prach98304| empty98304 | empty98304 + memmove(prach2+(98304<<2),prach2,(98304<<3)); + // here we have |empty | Prach98304 | Prach98304| Prach98304 | Prach98304 + memmove(prach,prach+(98304<<3),(Ncp<<2)); + // here we have |Prefix | Prach98304 | Prach98304| Prach98304 | Prach98304 + prach_len = (98304*4)+Ncp; + } else if (prach_fmt_id == 3) { // 4x6144, Ncp 3168 + idft24576(prachF,prach2,1); + memmove(prach2+(24576<<1),prach2,(24576<<2)); + // here we have |empty | Prach24576 | Prach24576| empty24576 | empty24576 + memmove(prach2+(24576<<2),prach2,(24576<<3)); + // here we have |empty | Prach24576 | Prach24576| Prach24576 | Prach24576 + memmove(prach,prach+(24576<<3),(Ncp<<2)); + // here we have |Prefix | Prach24576 | Prach24576| Prach24576 | Prach24576 + prach_len = (24576*4)+Ncp; + } + } else { // short sequence + if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) { + Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft4096(prachF,prach2,1); + // here we have |empty | Prach4096 | + if (prach_fmt_id != 7) { + memmove(prach2+(4096<<1),prach2,(4096<<2)); + prach_len = (4096*2)+Ncp; + } else prach_len = (4096*1)+Ncp; + memmove(prach,prach+(4096<<1),(Ncp<<2)); + // here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) | + } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x4096 + Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft4096(prachF,prach2,1); + // here we have |empty | Prach4096 | + memmove(prach2+(4096<<1),prach2,(4096<<2)); + // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | + memmove(prach2+(4096<<2),prach2,(4096<<3)); + // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | + memmove(prach,prach+(4096<<1),(Ncp<<2)); + // here we have |Prefix | Prach4096 | + prach_len = (4096*4)+Ncp; + } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x4096 + Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft4096(prachF,prach2,1); + // here we have |empty | Prach4096 | + memmove(prach2+(4096<<1),prach2,(4096<<2)); + // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096 + memmove(prach2+(4096<<2),prach2,(4096<<3)); + // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096 + memmove(prach2+(4096<<3),prach2,(4096<<3)); + // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 + memmove(prach,prach+(4096<<1),(Ncp<<2)); + // here we have |Prefix | Prach4096 | + prach_len = (4096*6)+Ncp; + } else if (prach_fmt_id == 6) { // 12x4096 + Ncp+=64; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft4096(prachF,prach2,1); + // here we have |empty | Prach4096 | + memmove(prach2+(4096<<1),prach2,(4096<<2)); + // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096 + memmove(prach2+(4096<<2),prach2,(4096<<3)); + // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096 + memmove(prach2+(4096<<3),prach2,(4096<<3)); + // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 + memmove(prach2+(4096<<1)*6,prach2,(4096<<2)*6); + // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096| + memmove(prach,prach+(4096<<1),(Ncp<<2)); + // here we have |Prefix | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096| + prach_len = (4096*12)+Ncp; + } } - else if (prach_fmt == 1) { - idft98304(prachF,prach2,1); - dftlen=98304; - memmove(prach2+(98304<<1),prach2,(98304<<2)); - // here we have |empty | Prach98304 | Prach98304| - memmove(prach,prach+(98304<<2),(Ncp<<2)); - // here we have |Prefix | Prach98304 | Prach98304| - prach_len = (98304*2)+Ncp; - } - else if (prach_fmt == 2) { - idft98304(prachF,prach2,1); - dftlen=98304; - memmove(prach2+(98304<<1),prach2,(98304<<2)); - // here we have |empty | Prach98304 | Prach98304| empty98304 | empty98304 - memmove(prach2+(98304<<2),prach2,(98304<<3)); - // here we have |empty | Prach98304 | Prach98304| Prach98304 | Prach98304 - memmove(prach,prach+(98304<<3),(Ncp<<2)); - // here we have |Prefix | Prach98304 | Prach98304| Prach98304 | Prach98304 - prach_len = (98304*4)+Ncp; - } - else if (prach_fmt == 3) { // 4x6144, Ncp 3168 - idft24576(prachF,prach2,1); - dftlen=24576; - memmove(prach2+(24576<<1),prach2,(24576<<2)); - // here we have |empty | Prach24576 | Prach24576| empty24576 | empty24576 - memmove(prach2+(24576<<2),prach2,(24576<<3)); - // here we have |empty | Prach24576 | Prach24576| Prach24576 | Prach24576 - memmove(prach,prach+(24576<<3),(Ncp<<2)); - // here we have |Prefix | Prach24576 | Prach24576| Prach24576 | Prach24576 - prach_len = (24576*4)+(Ncp<<1); - } - else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) { - idft4096(prachF,prach2,1); - dftlen=4096; - // here we have |empty | Prach4096 | - if (prach_fmt != 0xc0) { - memmove(prach2+(4096<<1),prach2,(4096<<2)); - prach_len = (4096*2)+Ncp; - } - else prach_len = (4096*1)+Ncp; - memmove(prach,prach+(4096<<1),(Ncp<<2)); - // here we have |Prefix | Prach4096 | Prach4096 (if ! 0xc0) | - - } - else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x4096 - idft4096(prachF,prach2,1); - dftlen=4096; - // here we have |empty | Prach4096 | - memmove(prach2+(4096<<1),prach2,(4096<<2)); - // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | - memmove(prach2+(4096<<2),prach2,(4096<<3)); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | - memmove(prach,prach+(4096<<1),(Ncp<<2)); - // here we have |Prefix | Prach4096 | - prach_len = (4096*4)+Ncp; - } - else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x4096 - idft4096(prachF,prach2,1); - dftlen=4096; - // here we have |empty | Prach4096 | - memmove(prach2+(4096<<1),prach2,(4096<<2)); - // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096 - memmove(prach2+(4096<<2),prach2,(4096<<3)); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096 - memmove(prach2+((4096<<1)*3),prach2,(4096<<3)); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 - memmove(prach,prach+(4096<<1),(Ncp<<2)); - // here we have |Prefix | Prach4096 | - prach_len = (4096*6)+Ncp; - } - else if (prach_fmt == 0xb4) { // 12x4096 - idft4096(prachF,prach2,1); - dftlen=4096; - // here we have |empty | Prach4096 | - memmove(prach2+(4096<<1),prach2,(4096<<2)); - // here we have |empty | Prach4096 | Prach4096| empty4096 | empty4096 | empty4096 | empty4096 - memmove(prach2+(4096<<2),prach2,(4096<<3)); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | empty4096 | empty4096 - memmove(prach2+(4096<<3),prach2,(4096<<3)); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 - memmove(prach2+(4096<<1)*6,prach2,(4096<<2)*6); - // here we have |empty | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096| - memmove(prach,prach+(4096<<1),(Ncp<<2)); - // here we have |Prefix | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096 | Prach4096| Prach4096 | Prach4096 | Prach4096 | Prach4096| - prach_len = (4096*12)+Ncp; - } - } - else { // 92.16 Ms/s + } else { // three quarter sampling @ 92.16 Ms/s Ncp = (Ncp*3); prach2 = prach+(Ncp<<1); - if (prach_fmt == 0) { - idft73728(prachF,prach2,1); - dftlen=73728; - // here we have |empty | Prach73728| - memmove(prach,prach+(73728<<1),(Ncp<<4)); - // here we have |Prefix | Prach73728| - prach_len = (73728*1)+Ncp; - } - else if (prach_fmt == 1) { - idft73728(prachF,prach2,1); - dftlen=73728; - memmove(prach2+(73728<<1),prach2,(73728<<2)); - // here we have |empty | Prach73728 | Prach73728| - memmove(prach,prach+(73728<<2),(Ncp<<4)); - // here we have |Prefix | Prach73728 | Prach73728| - prach_len = (73728*2)+Ncp; - } - if (prach_fmt == 2) { - idft73728(prachF,prach2,1); - dftlen=73728; - memmove(prach2+(73728<<1),prach2,(73728<<2)); - // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728 - memmove(prach2+(73728<<2),prach2,(73728<<3)); - // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728 - memmove(prach,prach+(73728<<3),(Ncp<<4)); - // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728 - prach_len = (73728*4)+Ncp; - } - else if (prach_fmt == 3) { - idft18432(prachF,prach2,1); - dftlen=18432; - memmove(prach2+(18432<<1),prach2,(18432<<2)); - // here we have |empty | Prach18432 | Prach18432| empty18432 | empty18432 - memmove(prach2+(18432<<2),prach2,(18432<<3)); - // here we have |empty | Prach18432 | Prach18432| Prach18432 | Prach18432 - memmove(prach,prach+(18432<<3),(Ncp<<4)); - // here we have |Prefix | Prach18432 | Prach18432| Prach18432 | Prach18432 - prach_len = (18432*4)+Ncp; - } - else if (prach_fmt == 0xa1 || prach_fmt == 0xb1 || prach_fmt == 0xc0) { - idft3072(prachF,prach2,1); - dftlen=3072; - // here we have |empty | Prach3072 | - if (prach_fmt != 0xc0) { - memmove(prach2+(3072<<1),prach2,(3072<<2)); - prach_len = (3072*2)+Ncp; - } - else prach_len = (3072*1)+Ncp; - memmove(prach,prach+(3072<<1),(Ncp<<2)); - // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) | - } - else if (prach_fmt == 0xa3 || prach_fmt == 0xb3) { // 6x3072 - idft3072(prachF,prach2,1); - dftlen=3072; - // here we have |empty | Prach3072 | - memmove(prach2+(3072<<1),prach2,(3072<<2)); - // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072 - memmove(prach2+(3072<<2),prach2,(3072<<3)); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072 - memmove(prach2+((3072<<1)*3),prach2,(3072<<3)); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 - memmove(prach,prach+(3072<<1),(Ncp<<2)); - // here we have |Prefix | Prach3072 | - prach_len = (3072*6)+Ncp; - } - else if (prach_fmt == 0xa2 || prach_fmt == 0xb2) { // 4x3072 - idft3072(prachF,prach2,1); - dftlen=3072; - // here we have |empty | Prach3072 | - memmove(prach2+(3072<<1),prach2,(3072<<2)); - // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | - memmove(prach2+(3072<<2),prach2,(3072<<3)); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | - memmove(prach,prach+(3072<<1),(Ncp<<2)); - // here we have |Prefix | Prach3072 | - prach_len = (3072*4)+Ncp; - } - else if (prach_fmt == 0xb4) { // 12x3072 - idft3072(prachF,prach2,1); - dftlen=3072; - // here we have |empty | Prach3072 | - memmove(prach2+(3072<<1),prach2,(3072<<2)); - // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072 - memmove(prach2+(3072<<2),prach2,(3072<<3)); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072 - memmove(prach2+(3072<<3),prach2,(3072<<3)); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 - memmove(prach2+(3072<<1)*6,prach2,(3072<<2)*6); - // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072| - memmove(prach,prach+(3072<<1),(Ncp<<2)); - // here we have |Prefix | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072| - prach_len = (3072*12)+Ncp; + if (prach_sequence_length == 0){ + if (prach_fmt_id == 0) { + idft73728(prachF,prach2,1); + // here we have |empty | Prach73728| + memmove(prach,prach+(73728<<1),(Ncp<<2)); + // here we have |Prefix | Prach73728| + prach_len = (73728*1)+Ncp; + } else if (prach_fmt_id == 1) { + idft73728(prachF,prach2,1); + memmove(prach2+(73728<<1),prach2,(73728<<2)); + // here we have |empty | Prach73728 | Prach73728| + memmove(prach,prach+(73728<<2),(Ncp<<2)); + // here we have |Prefix | Prach73728 | Prach73728| + prach_len = (73728*2)+Ncp; + } if (prach_fmt_id == 2) { + idft73728(prachF,prach2,1); + memmove(prach2+(73728<<1),prach2,(73728<<2)); + // here we have |empty | Prach73728 | Prach73728| empty73728 | empty73728 + memmove(prach2+(73728<<2),prach2,(73728<<3)); + // here we have |empty | Prach73728 | Prach73728| Prach73728 | Prach73728 + memmove(prach,prach+(73728<<3),(Ncp<<2)); + // here we have |Prefix | Prach73728 | Prach73728| Prach73728 | Prach73728 + prach_len = (73728*4)+Ncp; + } else if (prach_fmt_id == 3) { + idft18432(prachF,prach2,1); + memmove(prach2+(18432<<1),prach2,(18432<<2)); + // here we have |empty | Prach18432 | Prach18432| empty18432 | empty18432 + memmove(prach2+(18432<<2),prach2,(18432<<3)); + // here we have |empty | Prach18432 | Prach18432| Prach18432 | Prach18432 + memmove(prach,prach+(18432<<3),(Ncp<<2)); + // here we have |Prefix | Prach18432 | Prach18432| Prach18432 | Prach18432 + prach_len = (18432*4)+Ncp; + } + } else { // short sequence + if (prach_fmt_id == 0 || prach_fmt_id == 3 || prach_fmt_id == 7) { + Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft3072(prachF,prach2,1); + // here we have |empty | Prach3072 | + if (prach_fmt_id != 7) { + memmove(prach2+(3072<<1),prach2,(3072<<2)); + prach_len = (3072*2)+Ncp; + } else prach_len = (3072*1)+Ncp; + memmove(prach,prach+(3072<<1),(Ncp<<2)); + // here we have |Prefix | Prach3072 | Prach3072 (if ! 0xc0) | + } else if (prach_fmt_id == 2 || prach_fmt_id == 5) { // 6x3072 + Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft3072(prachF,prach2,1); + // here we have |empty | Prach3072 | + memmove(prach2+(3072<<1),prach2,(3072<<2)); + // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072 + memmove(prach2+(3072<<2),prach2,(3072<<3)); + // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072 + memmove(prach2+(3072<<3),prach2,(3072<<3)); + // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 + memmove(prach,prach+(3072<<1),(Ncp<<2)); + // here we have |Prefix | Prach3072 | + prach_len = (3072*6)+Ncp; + } else if (prach_fmt_id == 1 || prach_fmt_id == 4) { // 4x3072 + Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft3072(prachF,prach2,1); + // here we have |empty | Prach3072 | + memmove(prach2+(3072<<1),prach2,(3072<<2)); + // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | + memmove(prach2+(3072<<2),prach2,(3072<<3)); + // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | + memmove(prach,prach+(3072<<1),(Ncp<<2)); + // here we have |Prefix | Prach3072 | + prach_len = (3072*4)+Ncp; + } else if (prach_fmt_id == 6) { // 12x3072 + Ncp+=48; // This assumes we are transmitting starting in symbol 0 of a PRACH slot, 30 kHz, full sampling + prach2 = prach+(Ncp<<1); + idft3072(prachF,prach2,1); + // here we have |empty | Prach3072 | + memmove(prach2+(3072<<1),prach2,(3072<<2)); + // here we have |empty | Prach3072 | Prach3072| empty3072 | empty3072 | empty3072 | empty3072 + memmove(prach2+(3072<<2),prach2,(3072<<3)); + // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | empty3072 | empty3072 + memmove(prach2+(3072<<3),prach2,(3072<<3)); + // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 + memmove(prach2+(3072<<1)*6,prach2,(3072<<2)*6); + // here we have |empty | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072| + memmove(prach,prach+(3072<<1),(Ncp<<2)); + // here we have |Prefix | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072 | Prach3072| Prach3072 | Prach3072 | Prach3072 | Prach3072| + prach_len = (3072*12)+Ncp; + } } } - } - - - - -#if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - int j; - int overflow = prach_start + prach_len - LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe; - LOG_D( PHY, "prach_start=%d, overflow=%d\n", prach_start, overflow ); - - for (i=prach_start,j=0; isamples_per_subframe*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,prach_start+prach_len); i++,j++) { - ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]; - ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]; } - for (i=0; icommon_vars.txdata[0])[2*i] = prach[2*j]; - ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]; - } -#else + #ifdef NR_PRACH_DEBUG + LOG_I(PHY, "PRACH [UE %d] N_RB_UL %d prach_start %d, prach_len %d, rx_offset %d, hw_timing_advance %d, N_TA_offset %d\n", Mod_id, + fp->N_RB_UL, + prach_start, + prach_len, + ue->rx_offset, + ue->hw_timing_advance, + ue->N_TA_offset); + #endif - LOG_D( PHY, "prach_start=%d\n", prach_start); + #if defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) + int j, overflow = prach_start + prach_len - NR_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_subframe; - for (i=0; icommon_vars.txdata[0][prach_start]))[2*i] = prach[2*i]; - ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1]; - } -#endif + #ifdef NR_PRACH_DEBUG + LOG_I( PHY, "PRACH [UE %d] overflow = %d\n", Mod_id, overflow); + #endif + // prach_start=414.730, overflow=-39470 prach_len=6600 fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME 460.800 prach_start+prach_len 421.330 fp->samples_per_subframe 46080 + // from prach_start=414.730 to prach_start+prach_len 421.330 + for (i = prach_start, j = 0; i < min(fp->samples_per_subframe*NR_NUMBER_OF_SUBFRAMES_PER_FRAME, prach_start + prach_len); i++, j++) { + ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]; + ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]; + } -#if defined(PRACH_WRITE_OUTPUT_DEBUG) - LOG_M("prach_txF0.m","prachtxF0",prachF,prach_len-Ncp,1,1); - LOG_M("prach_tx0.m","prachtx0",prach+(Ncp<<1),prach_len-Ncp,1,1); - LOG_M("txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]),fp->samples_per_subframe,1,1); - exit(-1); -#endif + for (i = 0; i < overflow; i++,j++) { + ((int16_t*)ue->common_vars.txdata[0])[2*i] = prach[2*j]; + ((int16_t*)ue->common_vars.txdata[0])[2*i+1] = prach[2*j+1]; + } + #else // simulators + for (i=0; icommon_vars.txdata[0][prach_start]))[2*i] = prach[2*i]; + ((int16_t*)(&ue->common_vars.txdata[0][prach_start]))[2*i+1] = prach[2*i+1]; + } + #endif - return signal_energy( (int*)prach, 256 ); + //printf("----------------------\n"); + //for(int ii = prach_start; ii<2*(prach_start + prach_len); ii++){ + // printf("PRACH rx data[%d] = %d\n", ii, ue->common_vars.txdata[0][ii]); + //} + //printf(" \n"); + + #if defined(PRACH_WRITE_OUTPUT_DEBUG) + LOG_M("prach_tx0.m", "prachtx0", prach+(Ncp<<1), prach_len-Ncp, 1, 1); + LOG_M("Prach_txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]), 2*(prach_start+prach_len), 1, 1) + #endif + + return signal_energy((int*)prach, 256); } diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h index 35fe8bc899..d20457de06 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h @@ -1756,9 +1756,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t is_crnti, uint8_t llr8_flag); - - -int32_t generate_nr_prach( PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t subframe, uint16_t Nf ); +int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t subframe); void *dlsch_thread(void *arg); /**@}*/ diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index fb560f229d..643e70c442 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -42,8 +42,6 @@ #include "UTIL/LISTS/list.h" #endif -#include "LAYER2/NR_MAC_gNB/mac_proto.h" - //#include "../LTE_TRANSPORT/transport_common.h" // structures below implement 36-211 and 36-212 diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c index 55bac90520..6eba390449 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_coding.c @@ -292,6 +292,7 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, printf("%02x.",a[i]); printf("\n"); */ + if (A > 3824) { // Add 24-bit crc (polynomial A) to payload crc = crc24a(harq_process->a,A)>>8; @@ -321,7 +322,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch, memcpy(harq_process->b,harq_process->a,(A/8)+3); // using 3 bytes to mimic the case of 24 bit crc } - /////////// /////////////////////////////////////////////////////////////////////////// diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index f1d4a304f9..14c70e6582 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -129,6 +129,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, number_dmrs_symbols = 0; uint8_t mapping_type = UE->pusch_config.pusch_TimeDomainResourceAllocation[0]->mappingType; + for (cwd_index = 0;cwd_index < num_of_codewords; cwd_index++) { ulsch_ue = UE->ulsch[thread_id][gNB_id][cwd_index]; @@ -147,11 +148,13 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type, frame_parms->ofdm_symbol_size); + ulsch_ue->length_dmrs = number_dmrs_symbols; // pusch.MaxLenght is redundant here as number_dmrs_symbols // contains all dmrs symbols even for double symbol dmrs ulsch_ue->rnti = n_rnti; ulsch_ue->Nid_cell = Nid_cell; - ulsch_ue->nb_re_dmrs = ((UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4); + ulsch_ue->nb_re_dmrs = 12; //FIXME temprary for no data in dmrs symbol +//((UE->dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; N_RE_prime = NR_NB_SC_PER_RB*harq_process_ul_ue->number_of_symbols - ulsch_ue->nb_re_dmrs*number_dmrs_symbols - N_PRB_oh; @@ -166,8 +169,10 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, harq_process_ul_ue->number_of_symbols, ulsch_ue->nb_re_dmrs*ulsch_ue->length_dmrs, 0, + 0, harq_process_ul_ue->Nl); + uint8_t access_mode = SCHEDULED_ACCESS; //-----------------------------------------------------// @@ -175,23 +180,14 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if (harq_process_ul_ue != NULL){ data_existing = 0; - - if (IS_SOFTMODEM_NOS1){ - data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame, - slot, 0, ulsch_input_buffer, harq_process_ul_ue->TBS/8, &access_mode); - //IP traffic to be transmitted - if(data_existing){ - //harq_process_ul_ue->a = (unsigned char*)calloc(harq_process_ul_ue->TBS/8, sizeof(unsigned char)); - memcpy(harq_process_ul_ue->a, ulsch_input_buffer, harq_process_ul_ue->TBS/8); - - #ifdef DEBUG_MAC_PDU - LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", harq_process_ul_ue->TBS/8); - for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { - printf("0x%02x",harq_process_ul_ue->a[i]); - } - printf("\n"); - #endif - } + if (IS_SOFTMODEM_NOS1){ + data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame, + slot, 0, ulsch_input_buffer, harq_process_ul_ue->TBS/8, &access_mode); + //IP traffic to be transmitted + if(data_existing){ + //harq_process_ul_ue->a = (unsigned char*)calloc(harq_process_ul_ue->TBS/8, sizeof(unsigned char)); + memcpy(harq_process_ul_ue->a, ulsch_input_buffer, harq_process_ul_ue->TBS/8); + } } //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity if (!IS_SOFTMODEM_NOS1 || !data_existing) { @@ -199,15 +195,24 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, //and block this traffic from being forwarded to the upper layers at the gNB uint16_t payload_offset = 5; LOG_D(PHY, "Random data to be tranmsitted: \n"); - //Give the header bytes some dummy value in order to block the random packet at the MAC layer of the receiver + + //Give the header bytes a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) + //in order to block the random packet at the MAC layer of the receiver for (i = 0; ia[i] = 0; + harq_process_ul_ue->a[i] = 64; for (i = payload_offset; i < harq_process_ul_ue->TBS / 8; i++) { harq_process_ul_ue->a[i] = (unsigned char) rand(); //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); } } + #ifdef DEBUG_MAC_PDU + LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", harq_process_ul_ue->TBS/8); + for (i = 0; i < harq_process_ul_ue->TBS / 8; i++) { + printf("%02x",harq_process_ul_ue->a[i]); + } + printf("\n"); + #endif } else { LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n"); return; @@ -268,6 +273,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////////////////////DMRS Modulation///////////////////////// /////////// + ulsch_ue->nb_re_dmrs = ((UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1)?6:4)*number_dmrs_symbols; //FIXME temprary here for no data in dmrs symbol pusch_dmrs = UE->nr_gold_pusch_dmrs[slot]; n_dmrs = (harq_process_ul_ue->nb_rb*ulsch_ue->nb_re_dmrs*ulsch_ue->length_dmrs); int16_t mod_dmrs[n_dmrs<<1]; @@ -310,9 +316,9 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, tx_layers = (int16_t **)pusch_ue->txdataF_layers; nr_ue_layer_mapping(UE->ulsch[thread_id][gNB_id], - harq_process_ul_ue->Nl, - available_bits/mod_order, - tx_layers); + harq_process_ul_ue->Nl, + available_bits/mod_order, + tx_layers); /////////// //////////////////////////////////////////////////////////////////////// @@ -338,7 +344,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, harq_process_ul_ue->number_of_symbols, dmrs_type, frame_parms->ofdm_symbol_size); - + if (is_dmrs == 1) nb_re_dmrs_per_rb = ulsch_ue->nb_re_dmrs; else @@ -383,7 +389,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t l_ref; uint16_t m=0, n=0, dmrs_idx=0, ptrs_idx = 0; - for (l=start_symbol; lnumber_of_symbols; l++) { + for (l=start_symbol; lnumber_of_symbols; l++) { k = start_sc; n = 0; @@ -456,8 +462,18 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, } else { - ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; - ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; + if (!is_dmrs_symbol((mapping_type)?l-start_symbol:l, + 0, + 0, + 0, + 0, + 0, + harq_process_ul_ue->number_of_symbols, + UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type, + frame_parms->ofdm_symbol_size)) + { + ((int16_t*)txdataF[ap])[(sample_offsetF)<<1] = ((int16_t *) ulsch_ue->y)[m<<1]; + ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1] = ((int16_t *) ulsch_ue->y)[(m<<1) + 1]; #ifdef DEBUG_PUSCH_MAPPING printf("m %d\t l %d \t k %d \t txdataF: %d %d\n", @@ -465,7 +481,8 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, ((int16_t*)txdataF[ap])[((sample_offsetF)<<1) + 1]); #endif - m++; + m++; + } } if (++k >= frame_parms->ofdm_symbol_size) diff --git a/openair1/PHY/TOOLS/lte_dfts.c b/openair1/PHY/TOOLS/lte_dfts.c index 4147ba6dc6..4baf996f7c 100644 --- a/openair1/PHY/TOOLS/lte_dfts.c +++ b/openair1/PHY/TOOLS/lte_dfts.c @@ -6059,25 +6059,126 @@ void idft24576(int16_t *input, int16_t *output,int scale) } int16_t twa36864[24576] __attribute__((aligned(32))); -int16_t twb36884[24576] __attribute__((aligned(32))); +int16_t twb36864[24576] __attribute__((aligned(32))); + // 12288 x 3 void dft36864(int16_t *input, int16_t *output,int scale) { - AssertFatal(1==0,"Need to do this ..\n"); + int i,i2,j; + uint32_t tmp[3][12288] __attribute__((aligned(32))); + uint32_t tmpo[3][12288] __attribute__((aligned(32))); + simd_q15_t *y128p=(simd_q15_t*)output; + simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15); + + for (i=0,j=0; i<12288; i++) { + tmp[0][i] = ((uint32_t *)input)[j++]; + tmp[1][i] = ((uint32_t *)input)[j++]; + tmp[2][i] = ((uint32_t *)input)[j++]; + } + + dft12288((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1); + dft12288((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1); + dft12288((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1); + + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("dft36864out0.m","o0",tmpo[0],12288,1,1); + LOG_M("dft36864out1.m","o1",tmpo[1],12288,1,1); + LOG_M("dft36864out2.m","o2",tmpo[2],12288,1,1); + } + + for (i=0,i2=0; i<24576; i+=8,i2+=4) { + bfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),(simd_q15_t*)(&tmpo[2][i2]), + (simd_q15_t*)(output+i),(simd_q15_t*)(output+24576+i),(simd_q15_t*)(output+49152+i), + (simd_q15_t*)(twa36864+i),(simd_q15_t*)(twb36864+i)); + } + + if (scale==1) { + for (i=0; i<576; i++) { + y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128); + y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128); + y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128); + y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128); + y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128); + y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128); + y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128); + y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128); + y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128); + y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128); + y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128); + y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128); + y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128); + y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128); + y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128); + y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128); + y128p+=16; + } + } + _mm_empty(); + _m_empty(); + if (LOG_DUMPFLAG(DEBUG_DFT)) { + LOG_M("out.m","out",output,36864,1,1); + } } + void idft36864(int16_t *input, int16_t *output,int scale) { - AssertFatal(1==0,"Need to do this ..\n"); + int i,i2,j; + uint32_t tmp[3][12288] __attribute__((aligned(32))); + uint32_t tmpo[3][12288] __attribute__((aligned(32))); + simd_q15_t *y128p=(simd_q15_t*)output; + simd_q15_t ONE_OVER_SQRT3_Q15_128 = set1_int16(ONE_OVER_SQRT3_Q15); + + for (i=0,j=0; i<12288; i++) { + tmp[0][i] = ((uint32_t *)input)[j++]; + tmp[1][i] = ((uint32_t *)input)[j++]; + tmp[2][i] = ((uint32_t *)input)[j++]; + } + + idft12288((int16_t*)(tmp[0]),(int16_t*)(tmpo[0]),1); + idft12288((int16_t*)(tmp[1]),(int16_t*)(tmpo[1]),1); + idft12288((int16_t*)(tmp[2]),(int16_t*)(tmpo[2]),1); + + for (i=0,i2=0; i<24576; i+=8,i2+=4) { + ibfly3((simd_q15_t*)(&tmpo[0][i2]),(simd_q15_t*)(&tmpo[1][i2]),((simd_q15_t*)&tmpo[2][i2]), + (simd_q15_t*)(output+i),(simd_q15_t*)(output+24576+i),(simd_q15_t*)(output+49152+i), + (simd_q15_t*)(twa36864+i),(simd_q15_t*)(twb36864+i)); + } + if (scale==1) { + for (i=0; i<576; i++) { + y128p[0] = mulhi_int16(y128p[0],ONE_OVER_SQRT3_Q15_128); + y128p[1] = mulhi_int16(y128p[1],ONE_OVER_SQRT3_Q15_128); + y128p[2] = mulhi_int16(y128p[2],ONE_OVER_SQRT3_Q15_128); + y128p[3] = mulhi_int16(y128p[3],ONE_OVER_SQRT3_Q15_128); + y128p[4] = mulhi_int16(y128p[4],ONE_OVER_SQRT3_Q15_128); + y128p[5] = mulhi_int16(y128p[5],ONE_OVER_SQRT3_Q15_128); + y128p[6] = mulhi_int16(y128p[6],ONE_OVER_SQRT3_Q15_128); + y128p[7] = mulhi_int16(y128p[7],ONE_OVER_SQRT3_Q15_128); + y128p[8] = mulhi_int16(y128p[8],ONE_OVER_SQRT3_Q15_128); + y128p[9] = mulhi_int16(y128p[9],ONE_OVER_SQRT3_Q15_128); + y128p[10] = mulhi_int16(y128p[10],ONE_OVER_SQRT3_Q15_128); + y128p[11] = mulhi_int16(y128p[11],ONE_OVER_SQRT3_Q15_128); + y128p[12] = mulhi_int16(y128p[12],ONE_OVER_SQRT3_Q15_128); + y128p[13] = mulhi_int16(y128p[13],ONE_OVER_SQRT3_Q15_128); + y128p[14] = mulhi_int16(y128p[14],ONE_OVER_SQRT3_Q15_128); + y128p[15] = mulhi_int16(y128p[15],ONE_OVER_SQRT3_Q15_128); + y128p+=16; + } + } + _mm_empty(); + _m_empty(); } int16_t twa49152[32768] __attribute__((aligned(32))); int16_t twb49152[32768] __attribute__((aligned(32))); + // 16384 x 3 +// TbD todo dft16384 void dft49152(int16_t *input, int16_t *output,int scale) { AssertFatal(1==0,"Need to do this ..\n"); } +// TbD todo dft16384 void idft49152(int16_t *input, int16_t *output,int scale) { AssertFatal(1==0,"Need to do this ..\n"); diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index 40803c30f4..e0fa894d92 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -157,9 +157,9 @@ void phy_scope_gNB(FD_phy_scope_gnb *form, { int i, arx; //int i,i2,arx,atx,ind,k; NR_DL_FRAME_PARMS *frame_parms = &phy_vars_gnb->frame_parms; - int nsymb_ce = 12*frame_parms->N_RB_UL*frame_parms->symbols_per_tti; + //int nsymb_ce = 12*frame_parms->N_RB_UL*frame_parms->symbols_per_tti; uint8_t nb_antennas_rx = frame_parms->nb_antennas_rx; - uint8_t nb_antennas_tx = 1; // frame_parms->nb_antennas_tx; // in LTE Rel. 8 and 9 only a single transmit antenna is assumed at the UE + //uint8_t nb_antennas_tx = 1; // frame_parms->nb_antennas_tx; // in LTE Rel. 8 and 9 only a single transmit antenna is assumed at the UE int16_t **rxsig_t, **rxsig_f; // int16_t **chest_t=NULL; // int16_t **chest_f=NULL; @@ -966,7 +966,7 @@ FD_stats_form * create_form_stats_form( void ) { } void startScope(scopeParms_t * p) { - FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; + //FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; char title[255]; fl_initialize (p->argc, p->argv, NULL, 0, 0); /* diff --git a/openair1/PHY/TOOLS/nr_phy_scope.h b/openair1/PHY/TOOLS/nr_phy_scope.h index aaee08a554..3df6b81a03 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.h +++ b/openair1/PHY/TOOLS/nr_phy_scope.h @@ -26,7 +26,6 @@ #include #include #include -#include #include "common/ran_context.h" #include #include diff --git a/openair1/PHY/defs_RU.h b/openair1/PHY/defs_RU.h index 10496ced20..128a40b02e 100644 --- a/openair1/PHY/defs_RU.h +++ b/openair1/PHY/defs_RU.h @@ -38,7 +38,7 @@ #include "openairinterface5g_limits.h" #include "PHY/TOOLS/time_meas.h" #include "defs_common.h" - +#include "nfapi_nr_interface_scf.h" #define MAX_BANDS_PER_RRU 4 #define MAX_RRU_CONFIG_SIZE 1024 @@ -189,6 +189,16 @@ typedef struct RU_feptx_t_s{ int index; }RU_feptx_t; +typedef struct { + int frame; + int slot; + int fmt; + int numRA; + int prachStartSymbol; +} RU_PRACH_list_t; + +#define NUMBER_OF_NR_RU_PRACH_MAX 8 + typedef struct RU_proc_t_s { /// Pointer to associated RU descriptor struct RU_t_s *ru; @@ -480,6 +490,8 @@ typedef struct RU_t_s { int att_tx; /// flag to indicate precoding operation in RU int do_precoding; + /// FAPI confiuration + nfapi_nr_config_request_scf_t config; /// Frame parameters struct LTE_DL_FRAME_PARMS *frame_parms; struct NR_DL_FRAME_PARMS *nr_frame_parms; @@ -580,6 +592,10 @@ typedef struct RU_t_s { int32_t *bw_list[NUMBER_OF_eNB_MAX+1]; /// beamforming weight vectors int32_t **beam_weights[NUMBER_OF_eNB_MAX+1][15]; + /// prach commands + RU_PRACH_list_t prach_list[NUMBER_OF_NR_RU_PRACH_MAX]; + /// mutex for prach_list access + pthread_mutex_t prach_list_mutex; /// received frequency-domain signal for PRACH (IF4p5 RRU) int16_t **prach_rxsigF; /// received frequency-domain signal for PRACH BR (IF4p5 RRU) diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index d39f0d4e0b..8d27a42393 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -43,6 +43,8 @@ #include "PHY/CODING/nrLDPC_extern.h" #include "PHY/CODING/nrLDPC_decoder/nrLDPC_types.h" +#include "nfapi_nr_interface_scf.h" + #define MAX_NUM_RU_PER_gNB MAX_NUM_RU_PER_eNB #define MAX_PUCCH0_NID 8 @@ -52,6 +54,7 @@ typedef struct { int lut[MAX_PUCCH0_NID][160][14]; } NR_gNB_PUCCH0_LUT_t; + typedef struct { uint32_t pbch_a; uint32_t pbch_a_interleaved; @@ -155,6 +158,14 @@ typedef struct { int16_t sqrt_rho_b; } NR_gNB_DLSCH_t; +typedef struct { + int frame; + int slot; + nfapi_nr_prach_pdu_t pdu; +} gNB_PRACH_list_t; + +#define NUMBER_OF_NR_PRACH_MAX 8 + typedef struct { /// \brief ?. /// first index: ? [0..1023] (hard coded) @@ -165,6 +176,7 @@ typedef struct { int16_t **rxsigF; /// \brief local buffer to compute prach_ifft int32_t *prach_ifft; + gNB_PRACH_list_t list[NUMBER_OF_NR_PRACH_MAX]; } NR_gNB_PRACH; typedef struct { @@ -172,8 +184,8 @@ typedef struct { nfapi_nr_pusch_pdu_t ulsch_pdu; /// Frame where current HARQ round was sent uint32_t frame; - /// Subframe where current HARQ round was sent - uint32_t subframe; + /// Slot where current HARQ round was sent + uint32_t slot; /// Index of current HARQ round for this DLSCH uint8_t round; /// Last TPC command @@ -605,6 +617,9 @@ typedef struct { int prach_I0; } PHY_MEASUREMENTS_gNB; +#define MAX_NUM_NR_RX_RACH_PDUS 4 +#define MAX_NUM_NR_RX_PRACH_PREAMBLES 4 + /// Top-level PHY Data Structure for gNB typedef struct PHY_VARS_gNB_s { /// Module ID indicator for this instance @@ -630,8 +645,22 @@ typedef struct PHY_VARS_gNB_s { NR_UL_IND_t UL_INFO; pthread_mutex_t UL_INFO_mutex; - /// NFAPI PRACH information (to be removed) - nfapi_preamble_pdu_t preamble_list[MAX_NUM_RX_PRACH_PREAMBLES]; + /// NFAPI RX ULSCH information + nfapi_rx_indication_pdu_t rx_pdu_list[NFAPI_RX_IND_MAX_PDU]; + /// NFAPI RX ULSCH CRC information + nfapi_crc_indication_pdu_t crc_pdu_list[NFAPI_CRC_IND_MAX_PDU]; + /// NFAPI HARQ information + nfapi_harq_indication_pdu_t harq_pdu_list[NFAPI_HARQ_IND_MAX_PDU]; + /// NFAPI SR information + nfapi_sr_indication_pdu_t sr_pdu_list[NFAPI_SR_IND_MAX_PDU]; + /// NFAPI CQI information + nfapi_cqi_indication_pdu_t cqi_pdu_list[NFAPI_CQI_IND_MAX_PDU]; + /// NFAPI CQI information (raw component) + nfapi_cqi_indication_raw_pdu_t cqi_raw_pdu_list[NFAPI_CQI_IND_MAX_PDU]; + /// NFAPI PRACH information + nfapi_nr_prach_indication_pdu_t prach_pdu_indication_list[MAX_NUM_NR_RX_RACH_PDUS]; + /// NFAPI PRACH information + nfapi_nr_prach_indication_preamble_t preamble_list[MAX_NUM_NR_RX_PRACH_PREAMBLES]; //Sched_Rsp_t Sched_INFO; nfapi_nr_ul_tti_request_t UL_tti_req; diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h index 6f6c5ac8e9..ac71f708ec 100644 --- a/openair1/PHY/defs_nr_UE.h +++ b/openair1/PHY/defs_nr_UE.h @@ -782,6 +782,8 @@ typedef struct { int16_t amp; int16_t *prachF; int16_t *prach; + fapi_nr_ul_config_prach_pdu prach_pdu; + uint8_t prach_Config_enabled; } NR_UE_PRACH; // structure used for multiple SSB detection @@ -930,7 +932,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]; @@ -968,12 +970,13 @@ typedef struct { char ulsch_no_allocation_counter[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]; + uint8_t Msg3_startSymbol[NUMBER_OF_CONNECTED_gNB_MAX]; + uint8_t Msg3_Length[NUMBER_OF_CONNECTED_gNB_MAX]; - - 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]; + 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) @@ -1008,8 +1011,6 @@ typedef struct { int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX]; int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX]; unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX]; - uint8_t generate_prach; - uint8_t generate_nr_prach; uint8_t prach_cnt; uint8_t prach_PreambleIndex; // uint8_t prach_timer; diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h index ccc79b7d47..9caf3bc682 100644 --- a/openair1/PHY/defs_nr_common.h +++ b/openair1/PHY/defs_nr_common.h @@ -198,30 +198,32 @@ typedef struct { nr_reg_t reg_list[NR_NB_REG_PER_CCE]; } nr_cce_t; - -/// PRACH-ConfigInfo from 38.331 RRC spec typedef struct { - /// Parameter: prach-ConfigurationIndex, see TS 38.211 (6.3.3.2). - uint8_t prach_ConfigIndex; - /// Parameter: High-speed-flag, see TS 38.211 (6.3.3.1). 1 corresponds to Restricted set and 0 to Unrestricted set. - uint8_t highSpeedFlag; - /// Restricted Set Config (type A=0 , type B=1) TS 38.211 (6.3.3.1) - uint8_t restrictedSetConfig; - /// 38.211 (NCS 38.211 6.3.3.1). - uint8_t zeroCorrelationZoneConfig; - /// see TS 38.211 (6.3.3.2). - uint8_t msg1_frequencystart; -} NR_PRACH_CONFIG_INFO; - -/// PRACH-ConfigSIB or PRACH-Config -typedef struct { - /// Parameter: prach-rootSequenceIndex, see TS 38.211 (6.3.3.2). - uint16_t rootSequenceIndex; - /// prach_Config_enabled=1 means enabled.} - uint8_t prach_Config_enabled; - /// PRACH Configuration Information - NR_PRACH_CONFIG_INFO prach_ConfigInfo; -} NR_PRACH_CONFIG_COMMON; + /// PRACH format retrieved from prach_ConfigIndex + uint16_t prach_format; + /// Preamble index for PRACH (0-63) + uint8_t ra_PreambleIndex; + /// RACH MaskIndex + uint8_t ra_RACH_MaskIndex; + /// Target received power at gNB. Baseline is range -202..-60 dBm. Depends on delta preamble, power ramping counter and step. + int 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; + /// Flag for the Msg1 generation + uint8_t generate_nr_prach; +} NR_PRACH_RESOURCES_t; typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS; @@ -313,8 +315,6 @@ struct NR_DL_FRAME_PARMS { uint8_t nb_antennas_rx; /// Number of common transmit antenna ports in eNodeB (1 or 2) uint8_t nb_antenna_ports_gNB; - /// PRACH_CONFIG - NR_PRACH_CONFIG_COMMON prach_config_common; /// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP) lte_prefix_type_t Ncp; /// shift of pilot position in one RB @@ -350,9 +350,10 @@ struct NR_DL_FRAME_PARMS { uint8_t ssb_index; /// PBCH polar encoder params t_nrPolar_params pbch_polar_params; - }; + + #define KHz (1000UL) #define MHz (1000*KHz) diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 5c145a3230..a2d26765f1 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -31,6 +31,7 @@ */ #include "fapi_nr_l1.h" #include "PHY/NR_TRANSPORT/nr_transport_proto.h" +#include "PHY/NR_TRANSPORT/nr_transport.h" #include "PHY/NR_TRANSPORT/nr_dlsch.h" #include "PHY/NR_TRANSPORT/nr_dci.h" @@ -44,7 +45,7 @@ void handle_nr_nfapi_ssb_pdu(PHY_VARS_gNB *gNB,int frame,int slot, AssertFatal(dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag== 1, "bchPayloadFlat %d != 1\n", dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayloadFlag); - LOG_I(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload); + LOG_D(PHY,"%d.%d : pbch_pdu: %x\n",frame,slot,dl_tti_pdu->ssb_pdu.ssb_pdu_rel15.bchPayload); memcpy((void*)&gNB->ssb_pdu,&dl_tti_pdu->ssb_pdu,sizeof(dl_tti_pdu->ssb_pdu)); } @@ -144,16 +145,16 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ gNB = RC.gNB[Mod_id]; - uint8_t number_dl_pdu = DL_req->dl_tti_request_body.nPDUs; - // uint8_t number_ul_pdu = 0; + uint8_t number_dl_pdu = (DL_req==NULL) ? 0 : DL_req->dl_tti_request_body.nPDUs; uint8_t number_ul_dci_pdu = (UL_dci_req==NULL) ? 0 : UL_dci_req->numPdus; + uint8_t number_ul_tti_pdu = (UL_tti_req==NULL) ? 0 : UL_tti_req->n_pdus; - // if (UL_tti_req != NULL) number_ul_pdu = UL_tti_req->n_pdus; - - LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d%d DL_req:SFN/SLO:%04d%d:dl_pdu:%d tx_req:SFN/SLOT:%04d%d:pdus:%d;\n", - frame,slot, - DL_req->SFN,DL_req->Slot,number_dl_pdu, - TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs); + if (DL_req != NULL && TX_req!=NULL) + LOG_D(PHY,"NFAPI: Sched_INFO:SFN/SLOT:%04d/%d DL_req:SFN/SLO:%04d/%d:dl_pdu:%d tx_req:SFN/SLOT:%04d/%d:pdus:%d;ul_dci %d ul_tti %d\n", + frame,slot, + DL_req->SFN,DL_req->Slot,number_dl_pdu, + TX_req->SFN,TX_req->Slot,TX_req->Number_of_PDUs, + number_ul_dci_pdu,number_ul_tti_pdu); int pdcch_received=0; gNB->num_pdsch_rnti=0; @@ -174,6 +175,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ case NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE: AssertFatal(pdcch_received == 0, "pdcch_received is not 0, we can only handle one PDCCH PDU per slot\n"); + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot); handle_nfapi_nr_pdcch_pdu(gNB, frame, slot, &dl_tti_pdu->pdcch_pdu); @@ -184,6 +186,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ case NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE: { + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE for %d.%d\n",frame,slot,DL_req->SFN,DL_req->Slot); nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdu->pdsch_pdu.pdsch_pdu_rel15; uint16_t pduIndex = pdsch_pdu_rel15->pduIndex; AssertFatal(TX_req->pdu_list[pduIndex].num_TLV == 1, "TX_req->pdu_list[%d].num_TLV %d != 1\n", @@ -194,13 +197,28 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ } } - if (UL_tti_req!=NULL) memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t)); + // if (UL_tti_req!=NULL) memcpy(&gNB->UL_tti_req,UL_tti_req,sizeof(nfapi_nr_ul_tti_request_t)); for (int i=0;iul_dci_pdu_list[i]); + handle_nfapi_nr_ul_dci_pdu(gNB, frame, slot, &UL_dci_req->ul_dci_pdu_list[i]); } - + for (int i = 0; i < number_ul_tti_pdu; i++) { + switch (UL_tti_req->pdus_list[i].pdu_type) { + case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUSCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); + nr_fill_ulsch(gNB,UL_tti_req->SFN, UL_tti_req->Slot, &UL_tti_req->pdus_list[i].pusch_pdu); + break; + case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PUCCH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); + // handle_nfapi_nr_pucch_pdu(gNB,frame,slot,UL_tti_req->pdus_list[i].pucch_pdu); + break; + case NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE: + LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_TTI_PRACH_PDU_TYPE for %d.%d\n", frame, slot, UL_tti_req->SFN, UL_tti_req->Slot); + nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[i].prach_pdu; + nr_fill_prach(gNB, UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); + nr_fill_prach_ru(gNB->RU_list[0], UL_tti_req->SFN, UL_tti_req->Slot, prach_pdu); + break; + } + } } diff --git a/openair1/SCHED_NR/nr_prach_procedures.c b/openair1/SCHED_NR/nr_prach_procedures.c index b9a8ba94f1..855da5ac8a 100644 --- a/openair1/SCHED_NR/nr_prach_procedures.c +++ b/openair1/SCHED_NR/nr_prach_procedures.c @@ -32,7 +32,7 @@ #include "PHY/defs_gNB.h" #include "PHY/phy_extern.h" -#include "PHY/NR_TRANSPORT/nr_transport_proto.h" +#include "PHY/NR_TRANSPORT/nr_transport.h" #include "nfapi_nr_interface_scf.h" #include "fapi_nr_l1.h" #include "nfapi_pnf.h" @@ -47,17 +47,19 @@ #include "intertask_interface.h" -extern uint32_t nfapi_mode; +extern uint8_t nfapi_mode; extern int oai_nfapi_nr_rach_ind(nfapi_rach_indication_t *rach_ind); -void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int subframe) { +void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot, + nfapi_nr_prach_pdu_t *prach_pdu) { + uint16_t max_preamble[4],max_preamble_energy[4],max_preamble_delay[4]; uint16_t i; - gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles=0; + gNB->UL_INFO.rach_ind.number_of_pdus=0; RU_t *ru; int aa=0; @@ -75,16 +77,18 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int subframe) { } } + rx_nr_prach(gNB, + prach_pdu, frame, - subframe, + slot, &max_preamble[0], &max_preamble_energy[0], &max_preamble_delay[0] ); - LOG_D(PHY,"[RAPROC] Frame %d, subframe %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n", - frame,subframe, + LOG_D(PHY,"[RAPROC] Frame %d, slot %d : Most likely preamble %d, energy %d dB delay %d (prach_energy counter %d)\n", + frame,slot, max_preamble[0], max_preamble_energy[0]/10, max_preamble_delay[0], @@ -93,49 +97,42 @@ void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int subframe) { if ((gNB->prach_energy_counter == 100) && (max_preamble_energy[0] > gNB->measurements.prach_I0+100)) { - LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", + LOG_I(PHY,"[gNB %d][RAPROC] Frame %d, slot %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n", gNB->Mod_id, frame, - subframe, + slot, max_preamble[0], max_preamble_energy[0]/10, max_preamble_energy[0]%10, max_preamble_delay[0]); - T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(subframe), + T(T_ENB_PHY_INITIATE_RA_PROCEDURE, T_INT(gNB->Mod_id), T_INT(frame), T_INT(slot), T_INT(max_preamble[0]), T_INT(max_preamble_energy[0]), T_INT(max_preamble_delay[0])); - gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 1; - gNB->UL_INFO.rach_ind.rach_indication_body.preamble_list = &gNB->preamble_list[0]; - gNB->UL_INFO.rach_ind.rach_indication_body.tl.tag = NFAPI_RACH_INDICATION_BODY_TAG; - gNB->UL_INFO.rach_ind.header.message_id = NFAPI_RACH_INDICATION; - gNB->UL_INFO.rach_ind.sfn_sf = frame<<4 | subframe; + gNB->UL_INFO.rach_ind.number_of_pdus = 1; + gNB->UL_INFO.rach_ind.pdu_list = &gNB->prach_pdu_indication_list[0]; + gNB->UL_INFO.rach_ind.sfn = frame; + gNB->UL_INFO.rach_ind.slot = slot; - gNB->preamble_list[0].preamble_rel8.tl.tag = NFAPI_PREAMBLE_REL8_TAG; - gNB->preamble_list[0].preamble_rel8.timing_advance = max_preamble_delay[0]; - gNB->preamble_list[0].preamble_rel8.preamble = max_preamble[0]; - gNB->preamble_list[0].preamble_rel8.rnti = 1+subframe; // note: fid is implicitly 0 here - gNB->preamble_list[0].instance_length = 0; //don't know exactly what this is - - if (nfapi_mode == 1) { // If NFAPI PNF then we need to send the message to the VNF - - LOG_D(PHY,"Filling NFAPI indication for NR RACH : SFN_SF:%d TA %d, Preamble %d, rnti %x\n", - NFAPI_SFNSF2DEC(gNB->UL_INFO.rach_ind.sfn_sf), - gNB->preamble_list[0].preamble_rel8.timing_advance, - gNB->preamble_list[0].preamble_rel8.preamble, - gNB->preamble_list[0].preamble_rel8.rnti); - AssertFatal(1==0,"shouldn't be here yet..\n"); - //oai_nfapi_nr_rach_ind(&gNB->UL_INFO.rach_ind); - - gNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles = 0; - } - } // max_preamble_energy > prach_I0 + 100 - else { - gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); - if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10); - if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++; - } + gNB->prach_pdu_indication_list[0].phy_cell_id = gNB->gNB_config.cell_config.phy_cell_id.value; + gNB->prach_pdu_indication_list[0].symbol_index = prach_pdu->prach_start_symbol; // FIXME to be changed for multi-ssb (this is only the start symbol of first occasion) + gNB->prach_pdu_indication_list[0].slot_index = slot; + gNB->prach_pdu_indication_list[0].freq_index = prach_pdu->num_ra; + gNB->prach_pdu_indication_list[0].avg_rssi = (max_preamble_energy[0]<631) ? (128+(max_preamble_energy[0]/5)) : 254; + gNB->prach_pdu_indication_list[0].avg_snr = 0xff; // invalid for now + + + gNB->prach_pdu_indication_list[0].num_preamble = 1; + gNB->prach_pdu_indication_list[0].preamble_list = gNB->preamble_list; + gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_index = max_preamble[0]; + gNB->prach_pdu_indication_list[0].preamble_list[0].timing_advance = max_preamble_delay[0]; + gNB->prach_pdu_indication_list[0].preamble_list[0].preamble_pwr = 0xffffffff; + } + gNB->measurements.prach_I0 = ((gNB->measurements.prach_I0*900)>>10) + ((max_preamble_energy[0]*124)>>10); + if (frame==0) LOG_I(PHY,"prach_I0 = %d.%d dB\n",gNB->measurements.prach_I0/10,gNB->measurements.prach_I0%10); + if (gNB->prach_energy_counter < 100) gNB->prach_energy_counter++; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PRACH_RX,0); } diff --git a/openair1/SCHED_NR/nr_ru_procedures.c b/openair1/SCHED_NR/nr_ru_procedures.c index aefeec43e2..560f47059a 100644 --- a/openair1/SCHED_NR/nr_ru_procedures.c +++ b/openair1/SCHED_NR/nr_ru_procedures.c @@ -520,7 +520,7 @@ void nr_fep0(RU_t *ru, int first_half) { ru->common.rxdataF[aa], l, proc->tti_rx, - 0, + ru->N_TA_offset, 0); } } @@ -642,6 +642,8 @@ void nr_fep_full(RU_t *ru, int slot) { // if ((fp->frame_type == TDD) && // (subframe_select(fp,proc->tti_rx) != NR_UPLINK_SLOT)) return; + LOG_D(PHY,"In fep_full for slot = %d\n", proc->tti_rx); + start_meas(&ru->ofdm_demod_stats); if (ru->idx == 0) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_RU_FEPRX, 1 ); @@ -655,7 +657,7 @@ void nr_fep_full(RU_t *ru, int slot) { ru->common.rxdataF[aa], l, proc->tti_rx, - 0, + ru->N_TA_offset, 0); } } diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 1173899d1b..1ea23c21dc 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -177,9 +177,9 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); } - LOG_D(PHY, "PDSCH generation started (%d)\n", gNB->num_pdsch_rnti); for (int i=0; inum_pdsch_rnti; i++) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); + LOG_D(PHY, "PDSCH generation started (%d)\n", gNB->num_pdsch_rnti); nr_generate_pdsch(gNB->dlsch[i][0], gNB->nr_gold_pdsch_dmrs[slot], gNB->common_vars.txdataF, @@ -209,8 +209,6 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, // VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_RX,1); - - if (do_prach_rx(fp,frame,slot)) L1_nr_prach_procedures(gNB,frame,slot/fp->slots_per_subframe); */ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH_id, uint8_t harq_pid) @@ -218,7 +216,7 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH NR_DL_FRAME_PARMS *frame_parms = &gNB->frame_parms; nfapi_nr_pusch_pdu_t *pusch_pdu = &gNB->ulsch[ULSCH_id][0]->harq_processes[harq_pid]->ulsch_pdu; - uint8_t ret; + uint8_t ret, nodata_dmrs = 1; uint8_t l, number_dmrs_symbols = 0; uint32_t G; uint16_t start_symbol, number_symbols, nb_re_dmrs; @@ -227,9 +225,13 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH number_symbols = pusch_pdu->nr_of_symbols; for (l = start_symbol; l < start_symbol + number_symbols; l++) - number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01; + number_dmrs_symbols += ((pusch_pdu->ul_dmrs_symb_pos)>>l)&0x01; + + if (nodata_dmrs) + nb_re_dmrs = 12*number_dmrs_symbols; + else + nb_re_dmrs = ((pusch_pdu->dmrs_config_type == pusch_dmrs_type1)?6:4); - nb_re_dmrs = ((pusch_pdu->dmrs_config_type == pusch_dmrs_type1)?6:4); G = nr_get_G(pusch_pdu->rb_size, number_symbols, @@ -238,7 +240,6 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH pusch_pdu->qam_mod_order, pusch_pdu->nrOfLayers); - //---------------------------------------------------------- //------------------- ULSCH unscrambling ------------------- //---------------------------------------------------------- @@ -263,7 +264,6 @@ void nr_ulsch_procedures(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx, int ULSCH harq_pid, G); - if (ret > gNB->ulsch[ULSCH_id][0]->max_ldpc_iterations) LOG_I(PHY, "ULSCH %d in error\n",ULSCH_id); //gNB->ulsch[ULSCH_id+1][0]->harq_processes[harq_pid]->b @@ -379,6 +379,7 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) for(symbol = 0; symbol < NR_SYMBOLS_PER_SLOT; symbol++) { // nr_slot_fep_ul(gNB, symbol, proc->slot_rx, 0, 0); + for (aa = 0; aa < gNB->frame_parms.nb_antennas_rx; aa++) { nr_slot_fep_ul(&gNB->frame_parms, gNB->common_vars.rxdata[aa], @@ -394,63 +395,36 @@ void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) { - nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req; - int num_pdus = UL_tti_req->n_pdus; + LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d\n",frame_rx,slot_rx); - gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0; + for (int ULSCH_id=0;ULSCH_idulsch[ULSCH_id][0]; + int harq_pid; + NR_UL_gNB_HARQ_t *ulsch_harq; - nfapi_nr_uci_indication_t *uci_indication = &gNB->uci_indication; - uci_indication->sfn = frame_rx; - uci_indication->slot = slot_rx; - uci_indication->num_ucis = 0; + if ((ulsch) && + (ulsch->rnti > 0)) { + // for for an active HARQ process + for (harq_pid=0;harq_pidharq_processes[harq_pid]; + AssertFatal(ulsch_harq!=NULL,"harq_pid %d is not allocated\n",harq_pid); + if ((ulsch_harq->status == NR_ACTIVE) && + (ulsch_harq->frame == frame_rx) && + (ulsch_harq->slot == slot_rx) && + (ulsch_harq->handled == 0)){ - LOG_D(PHY,"phy_procedures_gNB_uespec_RX frame %d, slot %d, num_pdus %d\n",frame_rx,slot_rx,num_pdus); - - gNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus = 0; - - for (int i = 0; i < num_pdus; i++) { - switch (UL_tti_req->pdus_list[i].pdu_type) { - case NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE: - LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE\n",frame_rx,slot_rx); - - nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; - nr_fill_ulsch(gNB,frame_rx,slot_rx,pusch_pdu); - - uint8_t ULSCH_id = find_nr_ulsch(pusch_pdu->rnti,gNB,SEARCH_EXIST); - uint8_t harq_pid = pusch_pdu->pusch_data.harq_process_id; - uint8_t symbol_start = pusch_pdu->start_symbol_index; - uint8_t symbol_end = symbol_start + pusch_pdu->nr_of_symbols; - - for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { - nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); - } - //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1); - //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1); - nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); - nr_fill_rx_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); // indicate SDU to MAC - nr_fill_crc_indication(gNB, frame_rx, slot_rx, ULSCH_id, 0); - break; - case NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE: - LOG_D(PHY,"frame %d, slot %d, Got NFAPI_NR_UL_CONFIG_PUCCH_PDU_TYPE\n",frame_rx,slot_rx); - - nfapi_nr_pucch_pdu_t *pucch_pdu = &UL_tti_req->pdus_list[i].pucch_pdu; - switch (pucch_pdu->format_type) { - case 0: - uci_indication->uci_list[uci_indication->num_ucis].pdu_type = NFAPI_NR_UCI_FORMAT_0_1_PDU_TYPE; - uci_indication->uci_list[uci_indication->num_ucis].pdu_size = sizeof(nfapi_nr_uci_pucch_pdu_format_0_1_t); - nfapi_nr_uci_pucch_pdu_format_0_1_t *uci_pdu_format0 = &uci_indication->uci_list[uci_indication->num_ucis].pucch_pdu_format_0_1; - - nr_decode_pucch0(gNB, - slot_rx, - uci_pdu_format0, - pucch_pdu); - - uci_indication->num_ucis += 1; - break; - case 1: - break; - default: - AssertFatal(1==0,"Only PUCCH format 0 and 1 are currently supported\n"); + uint8_t symbol_start = ulsch_harq->ulsch_pdu.start_symbol_index; + uint8_t symbol_end = symbol_start + ulsch_harq->ulsch_pdu.nr_of_symbols; + for(uint8_t symbol = symbol_start; symbol < symbol_end; symbol++) { + nr_rx_pusch(gNB, ULSCH_id, frame_rx, slot_rx, symbol, harq_pid); + } + //LOG_M("rxdataF_comp.m","rxF_comp",gNB->pusch_vars[0]->rxdataF_comp[0],6900,1,1); + //LOG_M("rxdataF_ext.m","rxF_ext",gNB->pusch_vars[0]->rxdataF_ext[0],6900,1,1); + nr_ulsch_procedures(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); + nr_fill_rx_indication(gNB, frame_rx, slot_rx, ULSCH_id, harq_pid); // indicate SDU to MAC + nr_fill_crc_indication(gNB, frame_rx, slot_rx, ULSCH_id, 0); + break; + } } } } diff --git a/openair1/SCHED_NR/sched_nr.h b/openair1/SCHED_NR/sched_nr.h index 5f54539b71..b393e9566e 100644 --- a/openair1/SCHED_NR/sched_nr.h +++ b/openair1/SCHED_NR/sched_nr.h @@ -39,6 +39,7 @@ void nr_set_ssb_first_subcarrier(nfapi_nr_config_request_scf_t *cfg, NR_DL_FRAME void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, int frame_tx, int slot_tx, int do_meas); void phy_procedures_gNB_common_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx); +void L1_nr_prach_procedures(PHY_VARS_gNB *gNB,int frame,int slot,nfapi_nr_prach_pdu_t *prach_pdu); void nr_common_signal_procedures (PHY_VARS_gNB *gNB,int frame, int slot); void nr_feptx_ofdm(RU_t *ru,int frame_tx,int tti_tx); void nr_feptx_ofdm_2thread(RU_t *ru,int frame_tx,int tti_tx); diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h index e34ce2b6de..c6aea2ec08 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 69876159d6..7edbfcbd6c 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -34,155 +34,174 @@ #include "fapi_nr_ue_interface.h" #include "fapi_nr_ue_l1.h" -//#include "PHY/phy_vars_nr_ue.h" #include "PHY/defs_nr_UE.h" #include "PHY/impl_defs_nr.h" + extern PHY_VARS_NR_UE ***PHY_vars_UE_g; -int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) -{ - +int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ if(scheduled_response != NULL){ - /// module id - module_id_t module_id = scheduled_response->module_id; - /// component carrier id - uint8_t cc_id = scheduled_response->CC_id; + + module_id_t module_id = scheduled_response->module_id; + uint8_t cc_id = scheduled_response->CC_id, thread_id; uint32_t i; - int slot = scheduled_response->slot; + int slot = scheduled_response->slot; + // Note: we have to handle the thread IDs for this. To be revisited completely. - uint8_t thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot]; + thread_id = PHY_vars_UE_g[module_id][cc_id]->current_thread_id[slot]; NR_UE_PDCCH *pdcch_vars = PHY_vars_UE_g[module_id][cc_id]->pdcch_vars[thread_id][0]; 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]; - - // 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]; if(scheduled_response->dl_config != NULL){ fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config; LOG_D(PHY,"Received %d DL pdus\n",dl_config->number_pdus); pdcch_vars->nb_search_space = 0; - for(i=0; inumber_pdus; ++i){ - if(dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI){ - fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15; - memcpy((void*)&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],(void*)pdcch_config,sizeof(*pdcch_config)); - pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1; - LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space); - }else{ //FAPI_NR_DL_CONFIG_TYPE_DLSCH - // dlsch config pdu + for (i = 0; i < dl_config->number_pdus; ++i){ - fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15; - uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr; - dlsch0->current_harq_pid = current_harq_pid; - dlsch0->active = 1; - dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti; - - //dlsch0->harq_processes[0]->mcs = &dlsch_config_pdu->mcs; - - NR_DL_UE_HARQ_t *dlsch0_harq = dlsch0->harq_processes[current_harq_pid]; + if (dl_config->dl_config_list[i].pdu_type == FAPI_NR_DL_CONFIG_TYPE_DCI) { - dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart; - dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize; - dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs; - dlsch0_harq->start_rb = dlsch_config_pdu->start_rb; - dlsch0_harq->nb_symbols = dlsch_config_pdu->number_symbols; - dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol; - dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos; - dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType; - dlsch0_harq->mcs = dlsch_config_pdu->mcs; - dlsch0_harq->DCINdi = dlsch_config_pdu->ndi; - dlsch0_harq->rvidx = dlsch_config_pdu->rv; - dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH; - dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id; - dlsch0_harq->harq_ack.slot_for_feedback_ack = dlsch_config_pdu->pdsch_to_harq_feedback_time_ind; - dlsch0_harq->Nl=1; - dlsch0_harq->mcs_table=0; - dlsch0_harq->status = ACTIVE; - LOG_D(MAC,">>>> \tdlsch0->g_pucch=%d\tdlsch0_harq.mcs=%d\n",dlsch0->g_pucch,dlsch0_harq->mcs); + fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config = &dl_config->dl_config_list[i].dci_config_pdu.dci_config_rel15; + memcpy((void*)&pdcch_vars->pdcch_config[pdcch_vars->nb_search_space],(void*)pdcch_config,sizeof(*pdcch_config)); + pdcch_vars->nb_search_space = pdcch_vars->nb_search_space + 1; + LOG_D(PHY,"Number of DCI SearchSpaces %d\n",pdcch_vars->nb_search_space); - } + } else { //FAPI_NR_DL_CONFIG_TYPE_DLSCH + + fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15; + uint8_t current_harq_pid = dlsch_config_pdu->harq_process_nbr; + NR_DL_UE_HARQ_t *dlsch0_harq; + + dlsch0->current_harq_pid = current_harq_pid; + dlsch0->active = 1; + dlsch0->rnti = dl_config->dl_config_list[i].dlsch_config_pdu.rnti; + //dlsch0->harq_processes[0]->mcs = &dlsch_config_pdu->mcs; + dlsch0_harq = dlsch0->harq_processes[current_harq_pid]; + if (dlsch0_harq != NULL){ + dlsch0_harq->BWPStart = dlsch_config_pdu->BWPStart; + dlsch0_harq->BWPSize = dlsch_config_pdu->BWPSize; + dlsch0_harq->nb_rb = dlsch_config_pdu->number_rbs; + dlsch0_harq->start_rb = dlsch_config_pdu->start_rb; + dlsch0_harq->nb_symbols = dlsch_config_pdu->number_symbols; + dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol; + dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos; + dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType; + dlsch0_harq->mcs = dlsch_config_pdu->mcs; + dlsch0_harq->DCINdi = dlsch_config_pdu->ndi; + dlsch0_harq->rvidx = dlsch_config_pdu->rv; + dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH; + dlsch0_harq->harq_ack.pucch_resource_indicator = dlsch_config_pdu->pucch_resource_id; + dlsch0_harq->harq_ack.slot_for_feedback_ack = dlsch_config_pdu->pdsch_to_harq_feedback_time_ind; + dlsch0_harq->Nl=1; + dlsch0_harq->mcs_table=0; + dlsch0_harq->status = ACTIVE; + LOG_D(MAC, ">>>> \tdlsch0->g_pucch = %d\tdlsch0_harq.mcs = %d\n", dlsch0->g_pucch, dlsch0_harq->mcs); + } + } } - }else{ + } else { pdcch_vars->nb_search_space = 0; } - if(scheduled_response->ul_config != NULL){ + if (scheduled_response->ul_config != NULL){ + fapi_nr_ul_config_request_t *ul_config = scheduled_response->ul_config; - for(i=0; inumber_pdus; ++i){ - if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUSCH){ - // pusch config pdu - fapi_nr_ul_config_pusch_pdu_rel15_t *pusch_config_pdu = &ul_config->ul_config_list[i].ulsch_config_pdu.ulsch_pdu_rel15; - uint8_t current_harq_pid = pusch_config_pdu->harq_process_nbr; - ulsch0->harq_processes[current_harq_pid]->nb_rb = pusch_config_pdu->number_rbs; - ulsch0->harq_processes[current_harq_pid]->first_rb = pusch_config_pdu->start_rb; - ulsch0->harq_processes[current_harq_pid]->number_of_symbols = pusch_config_pdu->number_symbols; - ulsch0->harq_processes[current_harq_pid]->start_symbol = pusch_config_pdu->start_symbol; - ulsch0->harq_processes[current_harq_pid]->mcs = pusch_config_pdu->mcs; - ulsch0->harq_processes[current_harq_pid]->DCINdi = pusch_config_pdu->ndi; - ulsch0->harq_processes[current_harq_pid]->rvidx = pusch_config_pdu->rv; - ulsch0->harq_processes[current_harq_pid]->Nl = pusch_config_pdu->n_layers; - ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH; - } - if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PUCCH){ - // pucch config pdu - fapi_nr_ul_config_pucch_pdu *pucch_config_pdu = &ul_config->ul_config_list[i].pucch_config_pdu; - uint8_t pucch_resource_id = 0; //FIXME!!! - uint8_t format = 1; // FIXME!!! - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used - PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0].formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].hoppingId = pucch_config_pdu->hoppingId; - PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0].p0_nominal = pucch_config_pdu->p0_nominal; - /* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping; - pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used - pucch_config_dedicated->formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used - pucch_config_dedicated->formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK; - pucch_config_common->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping; - pucch_config_common->hoppingId = pucch_config_pdu->hoppingId; - pucch_config_common->p0_nominal = pucch_config_pdu->p0_nominal;*/ - } - if(ul_config->ul_config_list[i].pdu_type == FAPI_NR_UL_CONFIG_TYPE_PRACH){ - // prach config pdu - fapi_nr_ul_config_prach_pdu *prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu; - /*frame_parms.prach_config_common.rootSequenceIndex = prach_config_pdu->root_sequence_index; - frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex = prach_config_pdu->prach_configuration_index; - frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig = prach_config_pdu->zero_correlation_zone_config; - frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag = prach_config_pdu->restrictedset_config; - frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset = prach_config_pdu->prach_freq_offset;*/ - prach_resources->ra_PreambleIndex = prach_config_pdu->preamble_index; - } + + for (i = 0; i < ul_config->number_pdus; ++i){ + + uint8_t pdu_type = ul_config->ul_config_list[i].pdu_type, pucch_resource_id, current_harq_pid, format, gNB_id = 0; + /* PRACH */ + NR_PRACH_RESOURCES_t *prach_resources; + fapi_nr_ul_config_prach_pdu *prach_config_pdu; + /* PUSCH */ + fapi_nr_ul_config_pusch_pdu_rel15_t *pusch_config_pdu; + /* PUCCH */ + fapi_nr_ul_config_pucch_pdu *pucch_config_pdu; + PUCCH_ConfigCommon_nr_t *pucch_config_common_nr; + PUCCH_Config_t *pucch_config_dedicated_nr; + PUCCH_format_t *format_params; + + switch (pdu_type){ + + case (FAPI_NR_UL_CONFIG_TYPE_PUSCH): + // pusch config pdu + pusch_config_pdu = &ul_config->ul_config_list[i].ulsch_config_pdu.ulsch_pdu_rel15; + current_harq_pid = pusch_config_pdu->harq_process_nbr; + ulsch0->harq_processes[current_harq_pid]->nb_rb = pusch_config_pdu->number_rbs; + ulsch0->harq_processes[current_harq_pid]->first_rb = pusch_config_pdu->start_rb; + ulsch0->harq_processes[current_harq_pid]->number_of_symbols = pusch_config_pdu->number_symbols; + ulsch0->harq_processes[current_harq_pid]->start_symbol = pusch_config_pdu->start_symbol; + ulsch0->harq_processes[current_harq_pid]->mcs = pusch_config_pdu->mcs; + ulsch0->harq_processes[current_harq_pid]->DCINdi = pusch_config_pdu->ndi; + ulsch0->harq_processes[current_harq_pid]->rvidx = pusch_config_pdu->rv; + ulsch0->harq_processes[current_harq_pid]->Nl = pusch_config_pdu->n_layers; + ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH; + break; + + case (FAPI_NR_UL_CONFIG_TYPE_PUCCH): + // pucch config pdu + pucch_config_pdu = &ul_config->ul_config_list[i].pucch_config_pdu; + pucch_resource_id = 0; //FIXME!!! + format = 1; // FIXME!!! + pucch_config_common_nr = &PHY_vars_UE_g[module_id][cc_id]->pucch_config_common_nr[0]; + pucch_config_dedicated_nr = &PHY_vars_UE_g[module_id][cc_id]->pucch_config_dedicated_nr[0]; + format_params = &pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->format_parameters; + + format_params->initialCyclicShift = pucch_config_pdu->initialCyclicShift; + format_params->nrofSymbols = pucch_config_pdu->nrofSymbols; + format_params->startingSymbolIndex = pucch_config_pdu->startingSymbolIndex; + format_params->nrofPRBs = pucch_config_pdu->nrofPRBs; + format_params->timeDomainOCC = pucch_config_pdu->timeDomainOCC; + format_params->occ_length = pucch_config_pdu->occ_length; + format_params->occ_Index = pucch_config_pdu->occ_Index; + + pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB; + pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping; + pucch_config_dedicated_nr->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used + pucch_config_dedicated_nr->formatConfig[format - 1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used + pucch_config_dedicated_nr->formatConfig[format - 1]->pi2PBSK = pucch_config_pdu->pi2PBSK; + + pucch_config_common_nr->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping; + pucch_config_common_nr->hoppingId = pucch_config_pdu->hoppingId; + pucch_config_common_nr->p0_nominal = pucch_config_pdu->p0_nominal; + + /* pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.initialCyclicShift = pucch_config_pdu->initialCyclicShift; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofSymbols = pucch_config_pdu->nrofSymbols; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.startingSymbolIndex = pucch_config_pdu->startingSymbolIndex; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.nrofPRBs = pucch_config_pdu->nrofPRBs; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->startingPRB = pucch_config_pdu->startingPRB; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.timeDomainOCC = pucch_config_pdu->timeDomainOCC; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_length = pucch_config_pdu->occ_length; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->format_parameters.occ_Index = pucch_config_pdu->occ_Index; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->intraSlotFrequencyHopping = pucch_config_pdu->intraSlotFrequencyHopping; + pucch_config_dedicated->PUCCH_Resource[pucch_resource_id]->secondHopPRB = pucch_config_pdu->secondHopPRB; // Not sure this parameter is used + pucch_config_dedicated->formatConfig[format-1]->additionalDMRS = pucch_config_pdu->additionalDMRS; // At this point we need to know which format is going to be used + pucch_config_dedicated->formatConfig[format-1]->pi2PBSK = pucch_config_pdu->pi2PBSK; + pucch_config_common->pucch_GroupHopping = pucch_config_pdu->pucch_GroupHopping; + pucch_config_common->hoppingId = pucch_config_pdu->hoppingId; + pucch_config_common->p0_nominal = pucch_config_pdu->p0_nominal;*/ + break; + + case (FAPI_NR_UL_CONFIG_TYPE_PRACH): + // prach config pdu + prach_resources = PHY_vars_UE_g[module_id][cc_id]->prach_resources[gNB_id]; + prach_config_pdu = &ul_config->ul_config_list[i].prach_config_pdu; + memcpy((void*)&(PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_pdu), (void*)prach_config_pdu, sizeof(fapi_nr_ul_config_prach_pdu)); + PHY_vars_UE_g[module_id][cc_id]->prach_vars[gNB_id]->prach_Config_enabled = 1; + break; + + default: + break; + } } - }else{ - + } else { } - if(scheduled_response->tx_request != NULL){ - - }else{ - + if (scheduled_response->tx_request != NULL){ + } else { } } @@ -193,10 +212,10 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response) int8_t nr_ue_phy_config_request(nr_phy_config_t *phy_config){ fapi_nr_config_request_t *nrUE_config = &PHY_vars_UE_g[phy_config->Mod_id][phy_config->CC_id]->nrUE_config; - + if(phy_config != NULL) memcpy(nrUE_config,&phy_config->config_req,sizeof(fapi_nr_config_request_t)); - + return 0; } diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 509f4b6021..b7922993cf 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -53,7 +53,7 @@ #ifdef EMOS #include "SCHED/phy_procedures_emos.h" #endif - +#include "executables/softmodem-common.h" //#define DEBUG_PHY_PROC #define NR_PDCCH_SCHED @@ -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 @@ -201,14 +202,13 @@ void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id, exit(-1); } -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) -//unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162}; -/* - unsigned int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL) - { +#endif - int gain_dB = power_dBm - power_max_dBm; - int amp_x_100; +unsigned int gain_table[31] = {100,112,126,141,158,178,200,224,251,282,316,359,398,447,501,562,631,708,794,891,1000,1122,1258,1412,1585,1778,1995,2239,2512,2818,3162}; + +int get_tx_amp_prach(int power_dBm, int power_max_dBm, int N_RB_UL){ + + int gain_dB = power_dBm - power_max_dBm, amp_x_100 = -1; switch (N_RB_UL) { case 6: @@ -230,37 +230,21 @@ void nr_dump_dlsch_SI(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id, amp_x_100 = 408*AMP; // 408 = 100*sqrt(100/6) break; default: - LOG_E(PHY,"Unknown PRB size %d\n",N_RB_UL); - //mac_xface->macphy_exit(""); + LOG_E(PHY, "Unknown PRB size %d\n", N_RB_UL); + return (amp_x_100); break; } if (gain_dB < -30) { - return(amp_x_100/3162); - } else if (gain_dB>0) - return(amp_x_100); + return (amp_x_100/3162); + } else if (gain_dB > 0) + return (amp_x_100); else - return(amp_x_100/gain_table[-gain_dB]); // 245 corresponds to the factor sqrt(25/6) - } -*/ + return (amp_x_100/gain_table[-gain_dB]); // 245 corresponds to the factor sqrt(25/6) -unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb) -{ - - int gain_dB = power_dBm - power_max_dBm; - double gain_lin; - - gain_lin = pow(10,.1*gain_dB); - if ((nb_rb >0) && (nb_rb <= N_RB_UL)) { - return((int)(AMP*sqrt(gain_lin*N_RB_UL/(double)nb_rb))); - } - else { - LOG_E(PHY,"Illegal nb_rb/N_RB_UL combination (%d/%d)\n",nb_rb,N_RB_UL); - //mac_xface->macphy_exit(""); - } - return(0); + return (amp_x_100); } -#endif +#if 0 void nr_dump_dlsch_ra(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t nr_tti_rx) { @@ -300,107 +284,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; ldlsch[l][i][j]) { - for(k=0; kdlsch[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; kulsch[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) -{ - - // if contention resolution fails, go back to PRACH - PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH; - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0; - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti = 0; - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0; - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti = 0; - LOG_E(PHY,"[UE %d] Random-access procedure fails, going back to PRACH, setting SIStatus = 0, discard temporary C-RNTI and State RRC_IDLE\n",Mod_id); - //mac_xface->macphy_exit(""); -} - -void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) -{ - - int i; - - LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded. Set C-RNTI = Temporary C-RNTI\n",Mod_id); - - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0; - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0; - PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0; - PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PUSCH; - - for (i=0; i<8; i++) { - if (PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]) { - PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->status=IDLE; - PHY_vars_UE_g[Mod_id][CC_id]->dlsch[0][eNB_index][0]->harq_processes[i]->round=0; - PHY_vars_UE_g[Mod_id][CC_id]->dlsch[1][eNB_index][0]->harq_processes[i]->round=0; - PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->subframe_scheduling_flag=0; - } - } - - -} - -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) { @@ -1391,14 +1274,12 @@ 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){ + 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){ - - // 3GPP TS 38.213 p4.2 - // scale by the scs numerology - int factor_mu = 1 << mu; +uint16_t get_bw_scaling(uint16_t bwp_ul_NB_RB){ uint16_t bw_scaling; - // scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size switch (bwp_ul_NB_RB) { case 32: bw_scaling = 4; break; @@ -1409,13 +1290,37 @@ void nr_process_timing_advance(module_id_t Mod_id, uint8_t CC_id, uint8_t ta_com case 273: bw_scaling = 32; break; default: abort(); } + return bw_scaling; +} + +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){ + + // 3GPP TS 38.213 p4.2 + // scale by the scs numerology + int factor_mu = 1 << mu; + uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB); PHY_vars_UE_g[Mod_id][CC_id]->timing_advance += (ta_command - 31) * bw_scaling / factor_mu; 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); } +// WIP +// - todo: handle TA application as per ch 4.2 TS 38.213 +void nr_process_timing_advance_rar(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint16_t ta_command) { + + int factor_mu = 1 << ue->frame_parms.numerology_index; + uint16_t bwp_ul_NB_RB = ue->frame_parms.N_RB_UL; + uint16_t bw_scaling = get_bw_scaling(bwp_ul_NB_RB); + + // Transmission timing adjustment (TS 38.213 p4.2) + ue->timing_advance = bw_scaling / factor_mu; + + LOG_D(PHY, "[UE %d] Frame %d Slot %d, Received (RAR) timing advance command %d new value is %u \n", ue->Mod_id, proc->frame_rx, proc->nr_tti_rx, ta_command, ue->timing_advance); +} + #if 0 + void ue_ulsch_uespec_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t eNB_id, @@ -2323,11 +2228,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; + runmode_t mode = normal_txrx; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN); @@ -2337,15 +2243,8 @@ 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, - frame_tx, - slot_tx, - thread_id, - gNB_id); - + if (ue->UE_mode[gNB_id] == PUSCH || get_softmodem_params()->phy_test == 1){ + nr_ue_ulsch_procedures(ue, harq_pid, frame_tx, slot_tx, thread_id, gNB_id); /* if (ue->UE_mode[eNB_id] == PUSCH) { @@ -2356,33 +2255,24 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, } // UE_mode==PUSCH */ - LOG_D(PHY, "Sending data \n"); - nr_ue_pusch_common_procedures(ue, - harq_pid, - slot_tx, - thread_id, - 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)) { - - // 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); - } - } // mode is PRACH - else { - ue->generate_prach=0; + nr_ue_pusch_common_procedures(ue, + harq_pid, + slot_tx, + thread_id, + gNB_id, + &ue->frame_parms); } -*/ + + /* RACH */ + if (get_softmodem_params()->do_ra==1) { + if ((ue->UE_mode[gNB_id] == PRACH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) { + nr_ue_prach_procedures(ue, proc, gNB_id, mode); + } + else { + ue->prach_resources[gNB_id]->generate_nr_prach = 0; + } + } LOG_I(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, slot_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); @@ -2392,137 +2282,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=50; - 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; - } - - 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) { @@ -2689,7 +2448,7 @@ void restart_phy(PHY_VARS_NR_UE *ue,UE_nr_rxtx_proc_t *proc, uint8_t eNB_id,uint } #endif //(0) -void nr_ue_pbch_procedures(uint8_t eNB_id, +void nr_ue_pbch_procedures(uint8_t gNB_id, PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t abstraction_flag) @@ -2708,20 +2467,23 @@ void nr_ue_pbch_procedures(uint8_t eNB_id, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN); - //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id); + //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, gNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,gNB_id); ret = nr_rx_pbch(ue, proc, - ue->pbch_vars[eNB_id], + ue->pbch_vars[gNB_id], &ue->frame_parms, - eNB_id, + gNB_id, (ue->frame_parms.ssb_index)&7, SISO, ue->high_speed_flag); if (ret==0) { - ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0; + ue->pbch_vars[gNB_id]->pdu_errors_conseq = 0; + // Switch to PRACH state if it is first PBCH after initial synch and no timing correction is performed + if (ue->UE_mode[gNB_id] == NOT_SYNCHED && ue->no_timing_correction == 1) + ue->UE_mode[gNB_id] = PRACH; #ifdef DEBUG_PHY_PROC uint16_t frame_tx; @@ -2751,25 +2513,25 @@ void nr_ue_pbch_procedures(uint8_t eNB_id, exit(-1); */ - ue->pbch_vars[eNB_id]->pdu_errors_conseq++; - ue->pbch_vars[eNB_id]->pdu_errors++; + ue->pbch_vars[gNB_id]->pdu_errors_conseq++; + ue->pbch_vars[gNB_id]->pdu_errors++; - if (ue->pbch_vars[eNB_id]->pdu_errors_conseq>=100) { + if (ue->pbch_vars[gNB_id]->pdu_errors_conseq>=100) { LOG_E(PHY,"More that 100 consecutive PBCH errors! Exiting!\n"); exit_fun("More that 100 consecutive PBCH errors! Exiting!\n"); } } if (frame_rx % 100 == 0) { - ue->pbch_vars[eNB_id]->pdu_fer = ue->pbch_vars[eNB_id]->pdu_errors - ue->pbch_vars[eNB_id]->pdu_errors_last; - ue->pbch_vars[eNB_id]->pdu_errors_last = ue->pbch_vars[eNB_id]->pdu_errors; + ue->pbch_vars[gNB_id]->pdu_fer = ue->pbch_vars[gNB_id]->pdu_errors - ue->pbch_vars[gNB_id]->pdu_errors_last; + ue->pbch_vars[gNB_id]->pdu_errors_last = ue->pbch_vars[gNB_id]->pdu_errors; } #ifdef DEBUG_PHY_PROC LOG_D(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n", ue->Mod_id,frame_rx, nr_tti_rx, - ue->pbch_vars[eNB_id]->pdu_errors, - ue->pbch_vars[eNB_id]->pdu_errors_conseq); + ue->pbch_vars[gNB_id]->pdu_errors, + ue->pbch_vars[gNB_id]->pdu_errors_conseq); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT); } @@ -3316,17 +3078,25 @@ void nr_ue_pdsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int eNB start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]); #endif // process DLSCH received in first slot - nr_rx_pdsch(ue, - pdsch, - eNB_id, - eNB_id_i, - proc->frame_rx, - nr_tti_rx, // nr_tti_rx, - m, - first_symbol_flag, - dual_stream_UE, - i_mod, - dlsch0->current_harq_pid); + // skip DMRS symbols (will have to check later if PDSCH/DMRS are multiplexed + if (((1<harq_processes[harq_pid]->dlDmrsSymbPos) == 0) + nr_rx_pdsch(ue, + pdsch, + eNB_id, + eNB_id_i, + proc->frame_rx, + nr_tti_rx, // nr_tti_rx, + m, + first_symbol_flag, + dual_stream_UE, + i_mod, + dlsch0->current_harq_pid); + else { // This is to adjust the llr offset in the case of skipping over a dmrs symbol (i.e. in case of no PDSCH REs in DMRS) + if (pdsch == RA_PDSCH) ue->pdsch_vars_ra[eNB_id]->llr_offset[m]=ue->pdsch_vars_ra[eNB_id]->llr_offset[m-1]; + else if (pdsch == PDSCH) ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]=ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m-1]; + else AssertFatal(1==0,"not RA_PDSCH or PDSCH\n"); + } + if (pdsch == PDSCH) LOG_D(PHY,"Done processing symbol %d : llr_offset %d\n",m,ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->llr_offset[m]); #if UE_TIMING_TRACE stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[nr_tti_rx]][slot]); #if DISABLE_LOG_X @@ -3343,103 +3113,153 @@ 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) { - 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); - */ +// WIP fix: +// - time domain indication hardcoded to 0 for k2 offset +// - extend TS 38.213 ch 8.3 Msg3 PUSCH +// - b buffer +// - ulsch power offset +// - UE_mode == PUSCH case (should be handled by TA updates) +// - harq +// - optimize: mu_pusch, j and table_6_1_2_1_1_2_time_dom_res_alloc_A are already defined in nr_ue_procedures +void nr_process_rar(nr_downlink_indication_t *dl_info) { - LOG_D(PHY,"[UE %d][RAPROC] Frame %d nr_tti_rx %d Received RAR mode %d\n", - ue->Mod_id, - frame_rx, - nr_tti_rx, ue->UE_mode[eNB_id]); + module_id_t module_id = dl_info->module_id; + int cc_id = dl_info->cc_id, frame_rx = dl_info->proc->frame_rx, nr_tti_rx = dl_info->proc->nr_tti_rx, ta_command, k2, delta; + uint8_t gNB_index = dl_info->gNB_index; // *rar; + //fapi_nr_dci_indication_t *dci_ind = dl_info->dci_ind; + PHY_VARS_NR_UE *ue = PHY_vars_UE_g[module_id][cc_id]; + NR_UE_DLSCH_t *dlsch0 = ue->dlsch_ra[gNB_index]; + UE_MODE_t UE_mode = ue->UE_mode[gNB_index]; + NR_PRACH_RESOURCES_t *prach_resources = ue->prach_resources[gNB_index]; + uint16_t slots_per_frame = ue->frame_parms.slots_per_frame; + uint8_t mu_pusch = 1, sliv_S, sliv_L; + // definition table j Table 6.1.2.1.1-4 + uint8_t j = (mu_pusch==3)?3:(mu_pusch==2)?2:1; + uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PUSCH from TS 38.214 subclause 6.1.2.1.1 + {j, 0,14}, // row index 1 + {j, 0,12}, // row index 2 + {j, 0,10}, // row index 3 + {j, 2,10}, // row index 4 + {j, 4,10}, // row index 5 + {j, 4,8}, // row index 6 + {j, 4,6}, // row index 7 + {j+1,0,14}, // row index 8 + {j+1,0,12}, // row index 9 + {j+1,0,10}, // row index 10 + {j+2,0,14}, // row index 11 + {j+2,0,12}, // row index 12 + {j+2,0,10}, // row index 13 + {j, 8,6}, // row index 14 + {j+3,0,14}, // row index 15 + {j+3,0,10} // row index 16 + }; + + LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Received RAR mode %d\n", module_id, frame_rx, nr_tti_rx, UE_mode); if (ue->mac_enabled == 1) { - if ((ue->UE_mode[eNB_id] != PUSCH) && - (ue->prach_resources[eNB_id]->Msg3!=NULL)) { - LOG_D(PHY,"[UE %d][RAPROC] Frame %d nr_tti_rx %d Invoking MAC for RAR (current preamble %d)\n", - ue->Mod_id,frame_rx, - 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; - */ + if ((UE_mode != PUSCH) && (prach_resources->Msg3 != NULL)) { - if (timing_advance!=0xffff) { + LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n", module_id, frame_rx, nr_tti_rx, prach_resources->ra_PreambleIndex); - 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); + ta_command = nr_ue_process_rar(ue->Mod_id, + cc_id, + frame_rx, + dlsch0->harq_processes[0]->b, + &ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][gNB_index]->pdcch_config[0].rnti, + prach_resources->ra_PreambleIndex, + dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload - // remember this c-rnti is still a tc-rnti + if (ta_command != 0xffff) { + LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Got Temporary C-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]][gNB_index]->pdcch_config[0].rnti, + ta_command); - ue->pdcch_vars[ue->current_thread_id[nr_tti_rx]][eNB_id]->crnti_is_temporary = 1; - - //timing_advance = 0; - nr_process_timing_advance_rar(ue,proc,timing_advance); - - 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]); - - 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, - frame_rx, - nr_tti_rx, - ue->ulsch_Msg3_frame[eNB_id], - ue->ulsch_Msg3_subframe[eNB_id]); - 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->UE_mode[eNB_id] = RA_RESPONSE; - // ue->Msg3_timer[eNB_id] = 10; - ue->ulsch[eNB_id]->power_offset = 6; - ue->ulsch_no_allocation_counter[eNB_id] = 0; - } - } else { // PRACH preamble doesn't match RAR - LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n", - ue->Mod_id, - ue->prach_resources[eNB_id]->ra_PreambleIndex); + nr_process_timing_advance_rar(ue, dl_info->proc, ta_command); + + if (ue->mode != debug_prach) { + ue->ulsch_Msg3_active[gNB_index] = 1; + // TS 38.213 ch 8.3 Msg3 PUSCH + // PUSCH time domain resource allocation A for normal CP + // TS 38.214 ch 6.1.2.1.1 + k2 = table_6_1_2_1_1_2_time_dom_res_alloc_A[0][0]; + sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[0][1]; + sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[0][2]; + + switch (mu_pusch) { + case 0: + delta = 2; + break; + case 1: + delta = 3; + break; + case 2: + delta = 4; + break; + case 3: + delta = 6; + break; + } + + ue->Msg3_startSymbol[gNB_index] = sliv_S; + ue->Msg3_Length[gNB_index] = sliv_L; + ue->ulsch_Msg3_subframe[gNB_index] = (nr_tti_rx + k2 + delta) % slots_per_frame; + if (nr_tti_rx + k2 + delta > slots_per_frame){ + ue->ulsch_Msg3_frame[gNB_index] = (frame_rx + 1) % 1024; + } else { + ue->ulsch_Msg3_frame[gNB_index] = frame_rx; + } + + LOG_D(PHY,"[UE %d][RAPROC] Got Msg3_alloc Frame %d subframe %d: Msg3_frame %d, Msg3_subframe %d\n", + ue->Mod_id, + frame_rx, + nr_tti_rx, + ue->ulsch_Msg3_frame[gNB_index], + ue->ulsch_Msg3_subframe[gNB_index]); + // harq_pid = subframe2harq_pid(&ue->frame_parms, + // ue->ulsch_Msg3_frame[gNB_index], + // ue->ulsch_Msg3_subframe[gNB_index]); + // ue->ulsch[gNB_index]->harq_processes[harq_pid]->round = 0; + // ue->Msg3_timer[gNB_index] = 10; + // ue->ulsch[gNB_index].power_offset = 6; + // ue->ulsch_no_allocation_counter[gNB_index] = 0; + ue->UE_mode[gNB_index] = RA_RESPONSE; + } + } else { + LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n", ue->Mod_id, prach_resources->ra_PreambleIndex); } - } // mode != PUSCH + } + } else { + // rar = dlsch0->harq_processes[0]->b+1; + // ta_command = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); + // nr_process_timing_advance_rar(ue, dl_info->proc, ta_command); } - else { - rar = dlsch0->harq_processes[0]->b+1; - timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); - nr_process_timing_advance_rar(ue,proc,timing_advance); - } - } -#endif + +// if contention resolution fails, go back to UE mode PRACH +void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index) { + + PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; + ue->UE_mode[gNB_index] = PRACH; + + for (int i=0; i pdcch_vars[i][gNB_index]->pdcch_config[0].rnti = 0; + } + LOG_E(PHY,"[UE %d] [RAPROC] Random-access procedure fails, going back to PRACH\n", Mod_id); +} + +void nr_ra_succeeded(uint8_t Mod_id, + uint8_t CC_id, + uint8_t gNB_index){ + LOG_I(PHY,"[UE %d][RAPROC] RA procedure succeeded. UE set to PUSCH mode\n", Mod_id); + PHY_VARS_NR_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; + ue->ulsch_Msg3_active[gNB_index] = 0; + ue->UE_mode[gNB_index] = PUSCH; +} void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, @@ -3459,7 +3279,7 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, uint8_t is_cw1_active = 0; //nfapi_nr_config_request_t *cfg = &ue->nrUE_config; //uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value; - uint8_t nb_re_dmrs = 6; //(dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4; + uint8_t nb_re_dmrs = 12; //(dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4; uint16_t length_dmrs = 1; //cfg->pdsch_config.dmrs_max_length.value; uint16_t nb_symb_sch = 9; nr_downlink_indication_t dl_indication; @@ -3534,13 +3354,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; } } @@ -3728,7 +3548,17 @@ 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; + default: + 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); @@ -4363,11 +4193,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); } @@ -4376,11 +4206,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); } @@ -4389,13 +4219,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); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); + // #if UE_TIMING_TRACE + // start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); + // #endif + + nr_ue_dlsch_procedures(ue, + proc, + eNB_id, + RA_PDSCH, + ue->dlsch_ra[eNB_id], + NULL, + &ue->dlsch_ra_errors[eNB_id], + mode); + + // #if UE_TIMING_TRACE + // stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[nr_tti_rx]]); + #if DISABLE_LOG_X + printf("[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[nr_tti_rx]].p_time/(cpuf*1000.0)); + printf("[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0)); + #else + LOG_D(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n", nr_tti_rx, ue->pdsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0)); + LOG_D(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n", nr_tti_rx, ue->dlsch_procedures_stat[ue->current_thread_id[ nr_tti_rx]].p_time/(cpuf*1000.0)); + #endif + // #endif + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } // do procedures for C-RNTI @@ -4635,3 +4489,114 @@ uint8_t nr_is_ri_TXOp(PHY_VARS_NR_UE *ue, return(0); } +// WIP +// todo: +// - set tx_total_RE +// - power control as per 38.213 ch 7.4 +void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id, runmode_t runmode) { + + int frame_tx = proc->frame_tx, nr_tti_tx = proc->nr_tti_tx, prach_power; // tx_amp + uint16_t /*preamble_tx = 50,*/ pathloss; + uint8_t mod_id = ue->Mod_id; + UE_MODE_t UE_mode = get_nrUE_mode(mod_id, ue->CC_id, gNB_id); + NR_PRACH_RESOURCES_t * prach_resources = ue->prach_resources[gNB_id]; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); + + if (ue->mac_enabled == 0){ + // prach_resources->ra_PreambleIndex = preamble_tx; + prach_resources->ra_TDD_map_index = 0; + prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = 10; + prach_resources->ra_RNTI = 0x1234; + prach_resources->generate_nr_prach = 1; + } else { + // ask L2 for RACH transport + if ((runmode != rx_calib_ue) && (runmode != rx_calib_ue_med) && (runmode != rx_calib_ue_byp) && (runmode != no_L2_connect) ) { + LOG_D(PHY, "Getting PRACH resources. Frame %d Slot %d \n", frame_tx, nr_tti_tx); + // flush Msg3 Buffer + if (prach_resources->Msg3 == NULL){ + for(int i = 0; iulsch_Msg3_active[i] = 0; + } + } + nr_ue_get_rach(ue->prach_resources[gNB_id], mod_id, ue->CC_id, UE_mode, frame_tx, gNB_id, nr_tti_tx); + } + } + + if (ue->prach_resources[gNB_id] != NULL && prach_resources->generate_nr_prach == 1) { + + ue->prach_cnt = 0; + pathloss = get_nr_PL(mod_id, ue->CC_id, gNB_id); + LOG_D(PHY,"runmode %d\n",runmode); + + if ((ue->mac_enabled == 1) && (runmode != calib_prach_tx)) { + ue->tx_power_dBm[nr_tti_tx] = prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER + pathloss; + } + + LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d : Generating PRACH, preamble %d, PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, RA-RNTI %d\n", + ue->Mod_id, + frame_tx, + nr_tti_tx, + prach_resources->ra_PreambleIndex, + pathloss, + ue->tx_power_dBm[nr_tti_tx], + prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER, + prach_resources->ra_RNTI); + + //ue->tx_total_RE[nr_tti_tx] = 96; // todo + ue->prach_vars[gNB_id]->amp = AMP; + + /* #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) || defined(OAI_ADRV9371_ZC706) + tx_amp = get_tx_amp_prach(ue->tx_power_dBm[nr_tti_tx], ue->tx_power_max_dBm, ue->frame_parms.N_RB_UL); + if (tx_amp != -1) + ue->prach_vars[gNB_id]->amp = tx_amp; + #else + ue->prach_vars[gNB_id]->amp = AMP; + #endif */ + + if ((runmode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) + LOG_D(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %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); + + 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); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT); + + LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n", + ue->Mod_id, + pathloss, + ue->tx_power_dBm[nr_tti_tx], + dB_fixed(prach_power), + ue->prach_vars[gNB_id]->amp); + + if (ue->mac_enabled == 1) + nr_Msg1_transmitted(ue->Mod_id, ue->CC_id, frame_tx, gNB_id); + + LOG_I(PHY,"[UE %d][RAPROC] Frame %d, nr_tti_tx %d: Generated PRACH Msg1 (gNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB) \n", + ue->Mod_id, + frame_tx, + nr_tti_tx, + gNB_id, + prach_resources->ra_PreambleIndex, + ue->tx_power_dBm[nr_tti_tx], + pathloss); + } + + // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue + if (runmode == calib_prach_tx) + ue->prach_resources[gNB_id] = NULL; + + LOG_D(PHY,"[UE %d] frame %d nr_tti_tx %d : generate_nr_prach %d, prach_cnt %d\n", ue->Mod_id, frame_tx, nr_tti_tx, ue->prach_resources[gNB_id]->generate_nr_prach, ue->prach_cnt); + + ue->prach_cnt++; + + if (ue->prach_cnt == 3) + prach_resources->generate_nr_prach = 0; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT); +} diff --git a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c index 9632291e67..b51c8afbb0 100644 --- a/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c +++ b/openair1/SCHED_NR_UE/pucch_power_control_ue_nr.c @@ -104,7 +104,7 @@ int16_t get_pucch_tx_power_ue(PHY_VARS_NR_UE *ue, int P_O_PUCCH = P_O_NOMINAL_PUCCH + P_O_UE_PUCCH; - int16_t PL = get_nr_PL(ue, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */ + int16_t PL = get_nr_PL(ue->Mod_id, ue->CC_id, gNB_id); /* LTE function because NR path loss not yet implemented FFS TODO NR */ int16_t delta_F_PUCCH = power_config->deltaF_PUCCH_f[pucch_format]; diff --git a/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c b/openair1/SCHED_NR_UE/pucch_uci_ue_nr.c index 326c617dfb..eb2ce3598f 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 #include -#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/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 80b26c0bbd..fedf9394da 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -428,7 +428,7 @@ int main(int argc, char **argv) uint8_t is_crnti = 0, llr8_flag = 0; unsigned int TBS = 8424; unsigned int available_bits; - uint8_t nb_re_dmrs = 6; + uint8_t nb_re_dmrs = 12; // No data in dmrs symbol uint16_t length_dmrs = 1; unsigned char mod_order; uint16_t rate; @@ -442,7 +442,7 @@ int main(int argc, char **argv) mod_order = nr_get_Qm_dl(Imcs, mcs_table); rate = nr_get_code_rate_dl(Imcs, mcs_table); available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); - TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl); + TBS = nr_compute_tbs(mod_order,rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl); printf("available bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order); //dlsch->harq_ids[subframe]= 0; rel15->rbSize = nb_rb; diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 491fd52e5e..9243f55ead 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/nr_dummy_functions.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c index c9253aeedf..c7ee863c35 100644 --- a/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions.c @@ -1,7 +1,7 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0); } int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } -int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } +//int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } //int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); } int32_t get_uldl_offset(int nr_bandP) { return(0); } NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);} diff --git a/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c new file mode 100644 index 0000000000..e62155e54e --- /dev/null +++ b/openair1/SIMULATION/NR_PHY/nr_dummy_functions_prach.c @@ -0,0 +1,348 @@ +int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { return(0); } +int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) { return(0); } +int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) { return(0); } +int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } +//int oai_nfapi_nr_dl_config_req(nfapi_nr_dl_config_request_t *dl_config_req) { return(0); } +int32_t get_uldl_offset(int nr_bandP) { return(0); } +NR_IF_Module_t *NR_IF_Module_init(int Mod_id) {return(NULL);} +int dummy_nr_ue_dl_indication(nr_downlink_indication_t *dl_info) { return(0); } +int dummy_nr_ue_ul_indication(nr_uplink_indication_t *ul_info) { return(0); } +/* + * 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 "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" +#include "PHY/NR_UE_ESTIMATION/nr_estimation.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" +#include "LAYER2/MAC/mac.h" + +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; + +// WIP +// 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_PRACH_RESOURCES_t *prach_resources, + NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon; + // NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo + + int messagePowerOffsetGroupB, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, 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; // todo + + /////////////////////////////////////////////////////////// + //////////* UE Random Access Resource Selection *////////// + /////////////////////////////////////////////////////////// + + // todo: + // - 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_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000 + // --- set PREAMBLE_INDEX to ra_preamble_index + // --- 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 + // // 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 *////////// + // todo: + // - selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB + // - todo determine next available PRACH occasion + + // rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; + + AssertFatal(mac->nr_rach_ConfigCommon != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); + + nr_rach_ConfigCommon = mac->nr_rach_ConfigCommon; + + Msg3_size = mac->RA_Msg3_size; + numberOfRA_Preambles = *nr_rach_ConfigCommon->totalNumberOfRA_Preambles; + + 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->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 %lu\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA); + /* todo cases 10 -15*/ + } + + /* Power offset for preamble selection in dB */ + 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 %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB); + } + + // todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0 + mac->deltaPreamble_Msg3 = 0; + deltaPreamble_Msg3 = mac->deltaPreamble_Msg3; + } + + PLThreshold = prach_resources->RA_PCMAX - nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; + + /* Msg3 has not been transmitted yet */ + if (first_Msg3 == 1) { + if (noGroupB == 1) { + // use Group A preamble + prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; + mac->RA_usedGroupA = 1; + } else if ((Msg3_size < messageSizeGroupA) && (get_nr_PL(mod_id, CC_id, gNB_id) > PLThreshold)) { + // Group B is configured and RA preamble Group A is used + // - todo add condition on CCCH_sdu_size for initiation by CCCH + prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; + mac->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); + mac->RA_usedGroupA = 0; + } + } else { // Msg3 is being retransmitted + if (mac->RA_usedGroupA == 1 && noGroupB == 1) { + prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; + } else if (mac->RA_usedGroupA == 1 && noGroupB == 0){ + prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; + } else { + prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); + } + } + + // todo 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 + + ///////////////////////////////////////////////////////////////////////////// + //////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *////////// + ///////////////////////////////////////////////////////////////////////////// + // todo: + // - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) + // - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission + // - Extend RA_rnti computation (e.g. f_id selection, ul_carrier_id are hardcoded) + + if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) + mac->RA_PREAMBLE_TRANSMISSION_COUNTER++; + + prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, 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) + + switch (nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM){ // todo this is not used + 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 %lu\n", nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FDM); + } + + prach_ConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; + + // ra_RNTI computation + // - todo: this is for TDD FR1 only + // - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier + // - f_id: index of the PRACH occasion in the frequency domain + // - s_id is starting symbol of the PRACH occasion [0...14] + // - t_id is the first slot of the PRACH occasion in a system frame [0...80] + + ul_carrier_id = 0; // NUL + f_id = nr_rach_ConfigCommon->rach_ConfigGeneric.msg1_FrequencyStart; + 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]; + + // Pick the first slot of the PRACH occasion in a system frame + 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; + mac->ra_rnti = prach_resources->ra_RNTI; + + LOG_D(MAC, "Computed ra_RNTI is %d", prach_resources->ra_RNTI); +} + +// TbD: RA_attempt_number not used +void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ + AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + mac->ra_state = WAIT_RAR; + // Start contention resolution timer + mac->RA_attempt_number++; +} + +void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ + AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); + LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP); + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + // start contention resolution timer + mac->RA_contention_resolution_cnt = 0; + mac->RA_contention_resolution_timer_active = 1; +} + +///////////////////////////////////////////////////////////////////////// +///////* 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 + +// WIP +// todo TS 38.321: +// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX +// - BWP operation (subclause 5.15 TS 38.321) +// - handle initialization by beam failure recovery +// - handle initialization by handover +// - handle transmission on DCCH using PRACH (during handover, or sending SR for example) +// - take into account MAC CEs in size_sdu (currently hardcoded size to 1 MAC subPDU and 1 padding subheader) +// - fix rrc data req logic +// - retrieve TBS +// - add mac_rrc_nr_data_req_ue, etc ... +// - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) + + diff --git a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h index c7a30f826e..7a465e0ea3 100644 --- a/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h +++ b/openair1/SIMULATION/NR_PHY/nr_unitary_defs.h @@ -55,6 +55,24 @@ signed char quantize(double D, double x, unsigned char B) { return ((char) qxd); } + +int8_t +mac_rrc_data_req_ue( + const module_id_t Mod_idP, + const int CC_id, + const frame_t frameP, + const rb_id_t Srb_id, + const uint8_t Nb_tb, + uint8_t *const buffer_pP, + const mac_enb_index_t eNB_indexP, + const uint8_t mbsfn_sync_area + ) { return(0);} + +int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);} +//NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);} +int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } + + void fill_scc(NR_ServingCellConfigCommon_t *scc,uint64_t *ssb_bitmap,int N_RB_DL,int N_RB_UL,int mu_dl,int mu_ul) { *scc->physCellId=0; \ diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index 5c00352515..aed7eb4505 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "common/config/config_userapi.h" #include "common/utils/LOG/log.h" @@ -35,115 +36,85 @@ #include "SCHED_NR/sched_nr.h" #include "SCHED_NR_UE/phy_frame_config_nr.h" #include "PHY/phy_vars_nr_ue.h" - #include "PHY/NR_REFSIG/refsig_defs_ue.h" #include "PHY/NR_REFSIG/nr_mod_table.h" #include "PHY/MODULATION/modulation_eNB.h" #include "PHY/MODULATION/modulation_UE.h" #include "PHY/INIT/phy_init.h" #include "PHY/NR_TRANSPORT/nr_transport.h" +#include "PHY/NR_TRANSPORT/nr_transport_proto_common.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" +#include "nr_unitary_defs.h" #include "OCG_vars.h" -#include +#define NR_PRACH_DEBUG 1 +#define PRACH_WRITE_OUTPUT_DEBUG 1 PHY_VARS_gNB *gNB; PHY_VARS_NR_UE *UE; RAN_CONTEXT_t RC; RU_t *ru; - double cpuf; - extern uint16_t prach_root_sequence_map0_3[838]; - -void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe); - uint16_t NB_UE_INST=1; -volatile int oai_exit=0; - -void exit_function(const char* file, const char* function, const int line,const char *s) { - const char * msg= s==NULL ? "no comment": s; - printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg); - exit(-1); -} - - -int8_t nr_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) { - AssertFatal(1==0,"Shouldn't be here ...\n"); - return 0; -} - -uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, - sub_frame_t subframe, uint8_t eNB_index, - uint8_t *ulsch_buffer, uint16_t buflen, uint8_t *access_mode) {return(0);} - -int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind) {return(0);} - openair0_config_t openair0_cfg[MAX_CARDS]; uint8_t nfapi_mode=0; -NR_IF_Module_t *NR_IF_Module_init(int Mod_id){return(NULL);} -int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { return(0); } +int sl_ahead = 0; -uint64_t get_softmodem_optmask(void) { - return 0; -} +//void dump_nr_prach_config(NR_DL_FRAME_PARMS *frame_parms,uint8_t subframe); -int main(int argc, char **argv) -{ +/* temporary dummy implem of get_softmodem_optmask, till basic simulators implemented as device */ +uint64_t get_softmodem_optmask(void) {return 0;} +softmodem_params_t *get_softmodem_params(void) {return 0;} + +void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;} + +boolean_t pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, + const sdu_size_t sdu_buffer_sizeP, + mem_block_t *const sdu_buffer_pP) {return(false);} + +void nr_ip_over_LTE_DRB_preconfiguration(void){} +void pdcp_layer_init(void) {} +int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;} + +int main(int argc, char **argv){ char c; - - int i,aa,aarx; - double sigma2, sigma2_dB=0,SNR,snr0=-2.0,snr1=0.0,ue_speed0=0.0,ue_speed1=0.0; - uint8_t snr1set=0; - uint8_t ue_speed1set=0; - int **txdata; - double **s_re,**s_im,**r_re,**r_im; - double iqim=0.0; - int trial; //, ntrials=1; - uint8_t transmission_mode = 1,n_tx=1,n_rx=1; - uint16_t Nid_cell=0; - - uint8_t awgn_flag=0; - uint8_t hs_flag=0; - int n_frames=1; - channel_desc_t *UE2gNB; - uint32_t nsymb,tx_lev; //,tx_lev_dB; + double sigma2, sigma2_dB = 0, SNR, snr0 = -2.0, snr1 = 0.0, ue_speed0 = 0.0, ue_speed1 = 0.0; + double **s_re, **s_im, **r_re, **r_im, iqim = 0.0, delay_avg = 0, ue_speed = 0, fs, bw; + int i, aa, aarx, **txdata, trial, n_frames = 1, prach_start, rx_prach_start; //, ntrials=1; + int N_RB_UL = 106, delay = 0, NCS_config = 13, rootSequenceIndex = 1, threequarter_fs = 0, mu = 1, fd_occasion = 0, loglvl = OAILOG_INFO, numRA = 0, prachStartSymbol = 0; + uint8_t snr1set = 0, ue_speed1set = 0, transmission_mode = 1, n_tx = 1, n_rx = 1, awgn_flag = 0, msg1_frequencystart = 0, num_prach_fd_occasions = 1, prach_format; + uint8_t frame = 1, subframe = 19, config_index = 98, prach_sequence_length = 1, num_root_sequences = 16, restrictedSetConfig = 0, N_dur, N_t_slot, start_symbol; + uint16_t Nid_cell = 0, preamble_tx = 0, preamble_delay, format, format0, format1; + uint32_t tx_lev = 10000, prach_errors = 0, samp_count; //,tx_lev_dB; + uint64_t SSB_positions = 0x01, absoluteFrequencyPointA = 640000; // int8_t interf1=-19,interf2=-19; - NR_DL_FRAME_PARMS *frame_parms; - - SCM_t channel_model=Rayleigh1; - // uint8_t abstraction_flag=0,calibration_flag=0; // double prach_sinr; - int N_RB_UL=273; - uint32_t prach_errors=0; - uint8_t subframe=9; - uint16_t preamble_energy_list[64],preamble_tx=50,preamble_delay_list[64]; - uint16_t preamble_max,preamble_energy_max; - PRACH_RESOURCES_t prach_resources; - //uint8_t prach_fmt; - //int N_ZC; - int delay = 0; - double delay_avg=0; - double ue_speed = 0; - int NCS_config = 13,rootSequenceIndex=0; - int threequarter_fs = 0; - int mu=1; - uint64_t SSB_positions=0x01; + // uint32_t nsymb; + // uint16_t preamble_max, preamble_energy_max; - int loglvl=OAILOG_INFO; + NR_DL_FRAME_PARMS *frame_parms; + NR_PRACH_RESOURCES_t prach_resources; + nfapi_nr_prach_config_t *prach_config; + nfapi_nr_prach_pdu_t *prach_pdu; + fapi_nr_prach_config_t *ue_prach_config; + fapi_nr_ul_config_prach_pdu *ue_prach_pdu; + channel_desc_t *UE2gNB; + SCM_t channel_model = Rayleigh1; cpuf = get_cpu_freq_GHz(); - if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == 0) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } randominit(0); - while ((c = getopt (argc, argv, "hHaA:Cr:p:g:n:s:S:t:x:y:v:V:z:N:F:d:Z:L:R:E")) != -1) { switch (c) { case 'a': @@ -210,7 +181,7 @@ int main(int argc, char **argv) break; default: - msg("Unsupported channel model!\n"); + printf("Unsupported channel model!\n"); exit(-1); } @@ -226,13 +197,13 @@ int main(int argc, char **argv) case 's': snr0 = atof(optarg); - msg("Setting SNR0 to %f\n",snr0); + printf("Setting SNR0 to %f\n",snr0); break; case 'S': snr1 = atof(optarg); snr1set=1; - msg("Setting SNR1 to %f\n",snr1); + printf("Setting SNR1 to %f\n",snr1); break; case 'p': @@ -258,7 +229,7 @@ int main(int argc, char **argv) case 'H': printf("High-Speed Flag enabled\n"); - hs_flag = 1; + restrictedSetConfig = 1; break; case 'L': @@ -275,7 +246,7 @@ int main(int argc, char **argv) if ((transmission_mode!=1) && (transmission_mode!=2) && (transmission_mode!=6)) { - msg("Unsupported transmission mode %d\n",transmission_mode); + printf("Unsupported transmission mode %d\n",transmission_mode); exit(-1); } @@ -285,7 +256,7 @@ int main(int argc, char **argv) n_tx=atoi(optarg); if ((n_tx==0) || (n_tx>2)) { - msg("Unsupported number of tx antennas %d\n",n_tx); + printf("Unsupported number of tx antennas %d\n",n_tx); exit(-1); } @@ -295,7 +266,7 @@ int main(int argc, char **argv) n_rx=atoi(optarg); if ((n_rx==0) || (n_rx>2)) { - msg("Unsupported number of rx antennas %d\n",n_rx); + printf("Unsupported number of rx antennas %d\n",n_rx); exit(-1); } @@ -339,20 +310,13 @@ int main(int argc, char **argv) } } + // Configure log logInit(); - set_glog(loglvl); T_stdout = 1; - SET_LOG_DEBUG(PRACH); - if (snr1set==0) { - if (n_frames==1) - snr1 = snr0+.1; - else - snr1 = snr0+5.0; - } - + // Configure gNB and RU RC.gNB = (PHY_VARS_gNB**) malloc(2*sizeof(PHY_VARS_gNB *)); RC.gNB[0] = malloc(sizeof(PHY_VARS_gNB)); memset(RC.gNB[0],0,sizeof(PHY_VARS_gNB)); @@ -362,90 +326,200 @@ int main(int argc, char **argv) memset(RC.ru[0],0,sizeof(RU_t)); RC.nb_RU = 1; - gNB = RC.gNB[0]; - ru = RC.ru[0]; - - - if (ue_speed1set==0) { - if (n_frames==1) - ue_speed1 = ue_speed0+10; - else - ue_speed1 = ue_speed0+50; - } - - printf("SNR0 %f, SNR1 %f\n",snr0,snr1); - - frame_parms = &gNB->frame_parms; - - + gNB = RC.gNB[0]; + ru = RC.ru[0]; + frame_parms = &gNB->frame_parms; + prach_config = &gNB->gNB_config.prach_config; + prach_pdu = &gNB->prach_vars.list[0].pdu; + frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) s_re = malloc(2*sizeof(double*)); s_im = malloc(2*sizeof(double*)); r_re = malloc(2*sizeof(double*)); r_im = malloc(2*sizeof(double*)); - frame_parms = &gNB->frame_parms; //to be initialized I suppose (maybe not necessary for PBCH) - frame_parms->nb_antennas_tx = n_tx; - frame_parms->nb_antennas_rx = n_rx; - frame_parms->N_RB_DL = N_RB_UL; - frame_parms->N_RB_UL = N_RB_UL; - frame_parms->threequarter_fs = threequarter_fs; + frame_parms->nb_antennas_tx = n_tx; + frame_parms->nb_antennas_rx = n_rx; + frame_parms->N_RB_DL = N_RB_UL; + frame_parms->N_RB_UL = N_RB_UL; + frame_parms->threequarter_fs = threequarter_fs; + frame_parms->frame_type = TDD; + frame_parms->freq_range = nr_FR1; + frame_parms->numerology_index = mu; + nr_phy_config_request_sim(gNB, N_RB_UL, N_RB_UL, mu, Nid_cell, SSB_positions); - nr_phy_config_request_sim(gNB,N_RB_UL,N_RB_UL,mu,Nid_cell,SSB_positions); + //nsymb = (frame_parms->Ncp == 0) ? 14 : 12; - frame_parms->frame_type = TDD; - frame_parms->freq_range = nr_FR1; + printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d, Frame type %s, Frequency Range %s\n", + NUMBER_OF_OFDM_CARRIERS, + frame_parms->Ncp, + frame_parms->samples_per_subframe, + frame_parms->frame_type == FDD ? "FDD" : "TDD", + frame_parms->freq_range == nr_FR1 ? "FR1" : "FR2"); - nsymb = (frame_parms->Ncp == 0) ? 14 : 12; + ru->nr_frame_parms = frame_parms; + ru->if_south = LOCAL_RF; + ru->nb_tx = n_tx; + ru->nb_rx = n_rx; - printf("FFT Size %d, Extended Prefix %d, Samples per subframe %d,Frame type %s, Frequency Range %s\n",NUMBER_OF_OFDM_CARRIERS, - frame_parms->Ncp,frame_parms->samples_per_subframe,frame_parms->frame_type == FDD ? "FDD" : "TDD", frame_parms->freq_range == nr_FR1 ? "FR1" : "FR2"); + gNB->gNB_config.carrier_config.num_tx_ant.value = 1; + gNB->gNB_config.carrier_config.num_rx_ant.value = 1; + gNB->gNB_config.tdd_table.tdd_period.value = 6; - ru->nr_frame_parms=frame_parms; - ru->if_south = LOCAL_RF; - ru->nb_tx = n_tx; - ru->nb_rx = n_rx; + gNB->gNB_config.prach_config.num_prach_fd_occasions.value = num_prach_fd_occasions; + gNB->gNB_config.prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *) malloc(num_prach_fd_occasions*sizeof(nfapi_nr_num_prach_fd_occasions_t)); + gNB->proc.slot_rx = subframe; + + get_nr_prach_info_from_index(config_index, + (int)frame, + (int)subframe, + absoluteFrequencyPointA, + mu, + frame_parms->frame_type, + &format, + &start_symbol, + &N_t_slot, + &N_dur); + + format0 = format&0xff; // first column of format from table + format1 = (format>>8)&0xff; // second column of format from table + + if (format1 != 0xff) { + switch(format0) { + case 0xa1: + prach_format = 9; + break; + case 0xa2: + prach_format = 10; + break; + case 0xa3: + prach_format = 11; + break; + default: + AssertFatal(1==0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); + } + } else { + switch(format0) { + case 0xa1: + prach_format = 0; + break; + case 0xa2: + prach_format = 1; + break; + case 0xa3: + prach_format = 2; + break; + case 0xb1: + prach_format = 3; + break; + case 0xb2: + prach_format = 4; + break; + case 0xb3: + prach_format = 5; + break; + case 0xb4: + prach_format = 6; + break; + case 0xc0: + prach_format = 7; + break; + case 0xc2: + prach_format = 8; + break; + case 0: + // long formats are handled @ PHY + break; + case 1: + // long formats are handled @ PHY + break; + case 2: + // long formats are handled @ PHY + break; + case 3: + // long formats are handled @ PHY + break; + default: + AssertFatal(1==0, "Invalid PRACH format"); + } + } + + prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value = rootSequenceIndex; + prach_config->num_prach_fd_occasions_list[fd_occasion].k1.value = msg1_frequencystart; + prach_config->restricted_set_config.value = restrictedSetConfig; + prach_config->prach_sequence_length.value = prach_sequence_length; + prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value = num_root_sequences; + prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig); + prach_pdu->prach_format = prach_format; + + memcpy((void*)&ru->config,(void*)&RC.gNB[0]->gNB_config,sizeof(ru->config)); RC.nb_nr_L1_inst=1; phy_init_nr_gNB(gNB,0,0); nr_phy_init_RU(ru); - set_tdd_config_nr(&gNB->gNB_config, 5000, - 7, 6, - 2, 4); + gNB->common_vars.rxdata = ru->common.rxdata; + set_tdd_config_nr(&gNB->gNB_config, mu, 7, 6, 2, 4); - //configure UE + // Configure UE UE = malloc(sizeof(PHY_VARS_NR_UE)); memset((void*)UE,0,sizeof(PHY_VARS_NR_UE)); PHY_vars_UE_g = malloc(2*sizeof(PHY_VARS_NR_UE**)); PHY_vars_UE_g[0] = malloc(2*sizeof(PHY_VARS_NR_UE*)); PHY_vars_UE_g[0][0] = UE; memcpy(&UE->frame_parms,frame_parms,sizeof(NR_DL_FRAME_PARMS)); - if (init_nr_ue_signal(UE, 1, 0) != 0) - { + UE->nrUE_config.prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t)); + + if (init_nr_ue_signal(UE, 1, 0) != 0){ printf("Error at UE NR initialisation\n"); exit(-1); } - txdata = UE->common_vars.txdata; - printf("txdata %p\n",&txdata[0][subframe*frame_parms->samples_per_subframe]); + ue_prach_pdu = &UE->prach_vars[0]->prach_pdu; + ue_prach_config = &UE->nrUE_config.prach_config; + UE->prach_resources[0] = &prach_resources; + txdata = UE->common_vars.txdata; - double fs,bw; + UE->prach_vars[0]->amp = AMP; + ue_prach_pdu->root_seq_id = rootSequenceIndex; + ue_prach_pdu->num_cs = get_NCS(NCS_config, format0, restrictedSetConfig); + ue_prach_pdu->restricted_set = restrictedSetConfig; + ue_prach_pdu->freq_msg1 = msg1_frequencystart; + ue_prach_pdu->prach_format = prach_format; + ue_prach_config->prach_sub_c_spacing = mu; + ue_prach_config->prach_sequence_length = prach_sequence_length; + ue_prach_config->restricted_set_config = restrictedSetConfig; + ue_prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences = num_root_sequences; + ue_prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index = rootSequenceIndex; + ue_prach_config->num_prach_fd_occasions_list[fd_occasion].k1 = msg1_frequencystart; + + if (preamble_tx == 99) + preamble_tx = (uint16_t)(taus()&0x3f); + + if (n_frames == 1) + printf("raPreamble %d\n",preamble_tx); + + UE->prach_resources[0]->ra_PreambleIndex = preamble_tx; + + // Configure channel + bw = N_RB_UL*(180e3)*(1 << frame_parms->numerology_index); + AssertFatal(bw<=122.88e6,"Illegal channel bandwidth %f (mu %d,N_RB_UL %d)\n", bw, frame_parms->numerology_index, N_RB_UL); + + if (bw <= 30.72e6) + fs = 30.72e6; + else if (bw <= 61.44e6) + fs = 61.44e6; + else if (bw <= 122.88e6) + fs = 122.88e6; - bw = N_RB_UL*(180e3)*(1<frame_parms.numerology_index); - AssertFatal(bw<=122.88e6,"Illegal channel bandwidth %f (mu %d,N_RB_UL %d)\n",gNB->frame_parms.numerology_index,N_RB_UL); - if (bw <= 30.72e6) fs = 30.72e6; - else if (bw <= 61.44e6) fs = 61.44e6; - else if (bw <= 122.88e6) fs = 122.88e6; LOG_I(PHY,"Running with bandwidth %f Hz, fs %f samp/s, FRAME_LENGTH_COMPLEX_SAMPLES %d\n",bw,fs,FRAME_LENGTH_COMPLEX_SAMPLES); - UE2gNB = new_channel_desc_scm(UE->frame_parms.nb_antennas_tx, gNB->frame_parms.nb_antennas_rx, channel_model, - fs, - bw, + fs, + bw, 0.0, delay, 0); @@ -468,97 +542,82 @@ int main(int argc, char **argv) bzero(r_im[i],FRAME_LENGTH_COMPLEX_SAMPLES*sizeof(double)); } - UE->frame_parms.prach_config_common.rootSequenceIndex=rootSequenceIndex; - UE->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex=98; - UE->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=NCS_config; - UE->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag=hs_flag; - UE->frame_parms.prach_config_common.prach_ConfigInfo.restrictedSetConfig=0; - UE->frame_parms.prach_config_common.prach_ConfigInfo.msg1_frequencystart=0; + // compute PRACH sequence + compute_nr_prach_seq(prach_config->prach_sequence_length.value, + prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences.value, + prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index.value, + gNB->X_u); - - gNB->frame_parms.prach_config_common.rootSequenceIndex=rootSequenceIndex; - gNB->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex=98; - gNB->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=NCS_config; - gNB->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag=hs_flag; - gNB->frame_parms.prach_config_common.prach_ConfigInfo.restrictedSetConfig=0; - gNB->frame_parms.prach_config_common.prach_ConfigInfo.msg1_frequencystart=0; - - gNB->proc.slot_rx = subframe<<1; - - gNB->common_vars.rxdata = ru->common.rxdata; - - - compute_nr_prach_seq(gNB->frame_parms.prach_config_common.rootSequenceIndex, - gNB->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - gNB->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - gNB->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag, - gNB->frame_parms.frame_type, - gNB->frame_parms.freq_range, - gNB->X_u); - - compute_nr_prach_seq(UE->frame_parms.prach_config_common.rootSequenceIndex, - UE->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - UE->frame_parms.prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig, - UE->frame_parms.prach_config_common.prach_ConfigInfo.highSpeedFlag, - UE->frame_parms.frame_type, - UE->frame_parms.freq_range, - UE->X_u); - - - - UE->prach_vars[0]->amp = AMP; - - UE->prach_resources[0] = &prach_resources; - - if (preamble_tx == 99) - preamble_tx = (uint16_t)(taus()&0x3f); - - if (n_frames == 1) - printf("raPreamble %d\n",preamble_tx); - - UE->prach_resources[0]->ra_PreambleIndex = preamble_tx; - UE->prach_resources[0]->ra_TDD_map_index = 0; + compute_nr_prach_seq(ue_prach_config->prach_sequence_length, + ue_prach_config->num_prach_fd_occasions_list[fd_occasion].num_root_sequences, + ue_prach_config->num_prach_fd_occasions_list[fd_occasion].prach_root_sequence_index, + UE->X_u); /*tx_lev = generate_nr_prach(UE, 0, //gNB_id, - subframe, - 0); //Nf */ //commented for testing purpose + subframe); */ //commented for testing purpose UE_nr_rxtx_proc_t proc={0}; - nr_ue_prach_procedures(UE,&proc,0,0,0); - + proc.frame_tx = frame; + proc.nr_tti_tx = subframe; + 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); - LOG_M("txsig0.m","txs0", &txdata[0][subframe*frame_parms->samples_per_subframe],frame_parms->samples_per_subframe,1,1); - //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); + if (mu == 0) + samp_count = frame_parms->samples_per_subframe; + else + samp_count = (subframe%(frame_parms->slots_per_subframe/2)) ? frame_parms->samples_per_slotN0 : frame_parms->samples_per_slot0; + + prach_start = subframe*samp_count - UE->N_TA_offset; + + #ifdef NR_PRACH_DEBUG + LOG_M("txsig0.m", "txs0", &txdata[0][prach_start], samp_count, 1, 1); + //LOG_M("txsig1.m","txs1", txdata[1],FRAME_LENGTH_COMPLEX_SAMPLES,1,1); + #endif // multipath channel - dump_nr_prach_config(&gNB->frame_parms,subframe); + // dump_nr_prach_config(&gNB->frame_parms,subframe); - for (i=0; i<2*frame_parms->samples_per_subframe; i++) { + for (i = 0; i < samp_count<<1; i++) { for (aa=0; aa<1; aa++) { if (awgn_flag == 0) { - s_re[aa][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]); - s_im[aa][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]); + s_re[aa][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]); + s_im[aa][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]); } else { for (aarx=0; aarxframe_parms.nb_antennas_rx; aarx++) { if (aa==0) { - r_re[aarx][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]); - r_im[aarx][i] = ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]); + r_re[aarx][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]); + r_im[aarx][i] = ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]); } else { - r_re[aarx][i] += ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)]); - r_im[aarx][i] += ((double)(((short *)&txdata[aa][subframe*frame_parms->samples_per_subframe]))[(i<<1)+1]); + r_re[aarx][i] += ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)]); + r_im[aarx][i] += ((double)(((short *)&txdata[aa][prach_start]))[(i<<1)+1]); } } } } } + if (snr1set == 0) { + if (n_frames == 1) + snr1 = snr0 + .1; + else + snr1 = snr0 + 5.0; + } + printf("SNR0 %f, SNR1 %f\n", snr0, snr1); - for (SNR=snr0; SNRget_samples_per_slot(subframe,frame_parms); + + for (SNR=snr0; SNRsamples_per_subframe,0); + multipath_tv_channel(UE2gNB, s_re, s_im, r_re, r_im, frame_parms->samples_per_tti<<1, 0); } if (n_frames==1) { @@ -589,55 +648,51 @@ int main(int argc, char **argv) 10*log10(tx_lev)); } - for (i=0; isamples_per_subframe; i++) { - for (aa=0; aaframe_parms.nb_antennas_rx; aa++) { - - ((short*) &gNB->common_vars.rxdata[aa][subframe*(frame_parms->samples_per_subframe)])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); - ((short*) &gNB->common_vars.rxdata[aa][subframe*(frame_parms->samples_per_subframe)])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + for (i = 0; i< frame_parms->get_samples_per_slot(subframe,frame_parms); i++) { + for (aa = 0; aa < frame_parms->nb_antennas_rx; aa++) { + ((short*) &gNB->common_vars.rxdata[aa][rx_prach_start])[2*i] = (short) (.167*(r_re[aa][i] +sqrt(sigma2/2)*gaussdouble(0.0,1.0))); + ((short*) &gNB->common_vars.rxdata[aa][rx_prach_start])[2*i+1] = (short) (.167*(r_im[aa][i] + (iqim*r_re[aa][i]) + sqrt(sigma2/2)*gaussdouble(0.0,1.0))); } } - uint16_t preamble_rx; - rx_nr_prach_ru(ru, - 0, - subframe); - gNB->prach_vars.rxsigF = ru->prach_rxsigF; - rx_nr_prach(gNB, - 0, - subframe, - &preamble_rx, - preamble_energy_list, - preamble_delay_list); - - if (preamble_rx!=preamble_tx) + rx_nr_prach_ru(ru, prach_format, numRA, prachStartSymbol, frame, subframe); + + gNB->prach_vars.rxsigF = ru->prach_rxsigF; + + rx_nr_prach(gNB, prach_pdu, frame, subframe, &preamble_rx, &preamble_energy, &preamble_delay); + + printf(" preamble_energy %d preamble_rx %d preamble_tx %d \n", preamble_energy, preamble_rx, preamble_tx); + + if (preamble_rx != preamble_tx) prach_errors++; - else { - delay_avg += (double)preamble_delay_list[preamble_tx]; - } + else + delay_avg += (double)preamble_delay; + + N_ZC = (prach_sequence_length) ? 139 : 839; if (n_frames==1) { - printf("preamble %d (tx %d) : energy %d, delay %d\n",preamble_rx,preamble_tx,preamble_energy_list[0],preamble_delay_list[0]); - - - LOG_M("prach0.m","prach0", &txdata[0][subframe*frame_parms->samples_per_subframe],frame_parms->samples_per_subframe,1,1); - LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0],24576,1,1); - LOG_M("rxsig0.m","rxs0", - &gNB->common_vars.rxdata[0][subframe*frame_parms->samples_per_subframe], - frame_parms->samples_per_subframe,1,1); - LOG_M("rxsigF0.m","rxsF0", gNB->prach_vars.rxsigF[0],839*4,1,1); - LOG_M("prach_preamble.m","prachp",&gNB->X_u[0],839,1,1); + printf("preamble %d (tx %d) : energy %d, delay %d\n",preamble_rx,preamble_tx,preamble_energy,preamble_delay); + #ifdef NR_PRACH_DEBUG + LOG_M("prach0.m","prach0", &txdata[0][prach_start], samp_count, 1, 1); + LOG_M("prachF0.m","prachF0", &gNB->prach_vars.prachF[0], N_ZC, 1, 1); + LOG_M("rxsig0.m","rxs0", &gNB->common_vars.rxdata[0][rx_prach_start], frame_parms->samples_per_subframe, 1, 1); + //LOG_M("ru_rxsig0.m","rxs0", &ru->common.rxdata[0][rx_prach_start], frame_parms->samples_per_subframe, 1, 1); + LOG_M("rxsigF0.m","rxsF0", gNB->prach_vars.rxsigF[0], N_ZC, 1, 1); + LOG_M("prach_preamble.m","prachp", &gNB->X_u[0], N_ZC, 1, 1); + LOG_M("ue_prach_preamble.m","prachp", &UE->X_u[0], N_ZC, 1, 1); + #endif } } - - printf("SNR %f dB, UE Speed %f km/h: errors %d/%d (delay %f)\n",SNR,ue_speed,prach_errors,n_frames,delay_avg/(double)(n_frames-prach_errors)); - //printf("(%f,%f)\n",ue_speed,(double)prach_errors/(double)n_frames); + printf("SNR %f dB, UE Speed %f km/h: errors %d/%d (delay %f)\n", SNR, ue_speed, prach_errors, n_frames, delay_avg/(double)(n_frames-prach_errors)); + if (prach_errors) + break; } // UE Speed loop - - //printf("SNR %f dB, UE Speed %f km/h: errors %d/%d (delay %f)\n",SNR,ue_speed,prach_errors,n_frames,delay_avg/(double)(n_frames-prach_errors)); - // printf("(%f,%f)\n",SNR,(double)prach_errors/(double)n_frames); + if (!prach_errors) { + printf("PRACH test OK\n"); + break; + } } //SNR loop - for (i=0; i<2; i++) { free(s_re[i]); free(s_im[i]); @@ -650,17 +705,5 @@ int main(int argc, char **argv) free(r_re); free(r_im); - return(0); - } - - - -/* - for (i=1;i<4;i++) - memcpy((void *)&PHY_vars->tx_vars[0].TX_DMA_BUFFER[i*12*OFDM_SYMBOL_SIZE_COMPLEX_SAMPLES_NO_PREFIX*2], - (void *)&PHY_vars->tx_vars[0].TX_DMA_BUFFER[0], - 12*OFDM_SYMBOL_SIZE_SAMPLES_NO_PREFIX*2); -*/ - diff --git a/openair1/SIMULATION/NR_PHY/ulschsim.c b/openair1/SIMULATION/NR_PHY/ulschsim.c index 48ea26da8f..d0710f6734 100644 --- a/openair1/SIMULATION/NR_PHY/ulschsim.c +++ b/openair1/SIMULATION/NR_PHY/ulschsim.c @@ -391,7 +391,7 @@ int main(int argc, char **argv) mod_order = nr_get_Qm_ul(Imcs, 0); code_rate = nr_get_code_rate_ul(Imcs, 0); available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); - TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, Nl); + TBS = nr_compute_tbs(mod_order,code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, Nl); printf("\nAvailable bits %u TBS %u mod_order %d\n", available_bits, TBS, mod_order); diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index dea329a36e..a2e050d55b 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -46,6 +46,7 @@ #include "PHY/NR_TRANSPORT/nr_ulsch.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" #include "PHY/TOOLS/tools_defs.h" +#include "SCHED_NR/fapi_nr_l1.h" #include "SCHED_NR/sched_nr.h" #include "SCHED_NR_UE/defs.h" #include "SCHED_NR_UE/fapi_nr_ue_l1.h" @@ -53,9 +54,11 @@ #include "openair1/SIMULATION/RF/rf.h" #include "openair1/SIMULATION/NR_PHY/nr_unitary_defs.h" #include "openair2/RRC/NR/MESSAGES/asn1_msg.h" +//#include "openair1/SIMULATION/NR_PHY/nr_dummy_functions.c" #include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" + //#define DEBUG_ULSIM PHY_VARS_gNB *gNB; @@ -350,7 +353,8 @@ int main(int argc, char **argv) T_stdout = 1; get_softmodem_params()->phy_test = 1; - + get_softmodem_params()->do_ra = 0; + if (snr1set == 0) snr1 = snr0 + 10; @@ -479,7 +483,11 @@ int main(int argc, char **argv) NR_gNB_ULSCH_t *ulsch_gNB = gNB->ulsch[UE_id][0]; //nfapi_nr_ul_config_ulsch_pdu *rel15_ul = &ulsch_gNB->harq_processes[harq_pid]->ulsch_pdu; - nfapi_nr_ul_tti_request_t *UL_tti_req = &gNB->UL_tti_req; + nfapi_nr_ul_tti_request_t *UL_tti_req = malloc(sizeof(*UL_tti_req)); + NR_Sched_Rsp_t *Sched_INFO = malloc(sizeof(*Sched_INFO)); + memset((void*)Sched_INFO,0,sizeof(*Sched_INFO)); + Sched_INFO->UL_tti_req=UL_tti_req; + nfapi_nr_pusch_pdu_t *pusch_pdu = &UL_tti_req->pdus_list[0].pusch_pdu; NR_UE_ULSCH_t **ulsch_ue = UE->ulsch[0][0]; @@ -496,29 +504,20 @@ int main(int argc, char **argv) fapi_nr_ul_config_request_t ul_config; unsigned int TBS; - uint16_t number_dmrs_symbols = 0; + uint16_t number_dmrs_symbols = 1; unsigned int available_bits; - uint8_t nb_re_dmrs; - uint8_t length_dmrs = UE->pusch_config.dmrs_UplinkConfig.pusch_maxLength; + + uint8_t nb_re_dmrs=12; // no PUSCH REs + uint8_t length_dmrs = 1; unsigned char mod_order; uint16_t code_rate; - for (i = start_symbol; i < nb_symb_sch; i++) - number_dmrs_symbols += is_dmrs_symbol(i, - 0, - 0, - 0, - 0, - 0, - nb_symb_sch, - UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type, - frame_parms->ofdm_symbol_size); mod_order = nr_get_Qm_ul(Imcs, 0); - nb_re_dmrs = ((UE->pusch_config.dmrs_UplinkConfig.pusch_dmrs_type == pusch_dmrs_type1) ? 6 : 4) * number_dmrs_symbols; + code_rate = nr_get_code_rate_ul(Imcs, 0); available_bits = nr_get_G(nb_rb, nb_symb_sch, nb_re_dmrs, length_dmrs, mod_order, 1); - TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, precod_nbr_layers); + TBS = nr_compute_tbs(mod_order, code_rate, nb_rb, nb_symb_sch, nb_re_dmrs*length_dmrs, 0, 0, precod_nbr_layers); printf("\n"); @@ -578,6 +577,8 @@ int main(int argc, char **argv) pusch_pdu->pusch_data.tb_size = TBS>>3; pusch_pdu->pusch_data.num_cb = 0; + // prepare ULSCH/PUSCH reception + nr_schedule_response(Sched_INFO); // --------- setting parameters for UE -------- @@ -620,10 +621,10 @@ int main(int argc, char **argv) //////////////////////////////////////////////////// tx_offset = frame_parms->get_samples_slot_timestamp(slot,frame_parms,0); - txlev = signal_energy_amp_shift(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], + txlev = signal_energy(&UE->common_vars.txdata[0][tx_offset + 5*frame_parms->ofdm_symbol_size + 4*frame_parms->nb_prefix_samples + frame_parms->nb_prefix_samples0], frame_parms->ofdm_symbol_size + frame_parms->nb_prefix_samples); - txlev_float = (double)txlev/(double)AMP; // output of signal_energy is fixed point representation + txlev_float = (double)txlev; // output of signal_energy is fixed point representation n_errors = 0; n_false_positive = 0; @@ -642,8 +643,8 @@ int main(int argc, char **argv) //---------------------------------------------------------- for (i=0; inb_antennas_rx; ap++) { - ((short*) gNB->common_vars.rxdata[ap])[(2*i) + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); // convert to fixed point - ((short*) gNB->common_vars.rxdata[ap])[2*i+1 + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)*(double)AMP); + ((short*) gNB->common_vars.rxdata[ap])[(2*i) + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)); // convert to fixed point + ((short*) gNB->common_vars.rxdata[ap])[2*i+1 + (delay*2)] = (((int16_t *)UE->common_vars.txdata[ap])[(i<<1)+1]) + (int16_t)(sqrt(sigma/2)*gaussdouble(0.0,1.0)); } } //////////////////////////////////////////////////////////// diff --git a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c index f4835570bf..d344992586 100644 --- a/openair1/SIMULATION/TOOLS/multipath_tv_channel.c +++ b/openair1/SIMULATION/TOOLS/multipath_tv_channel.c @@ -27,18 +27,20 @@ #include "SIMULATION/RF/rf.h" #include -void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length); +void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length); double frand_a_b(double a, double b); -void tv_conv(double complex **h, double complex *x, double complex *y, uint16_t nb_samples, uint8_t nb_taps, int delay); +void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int delay); void multipath_tv_channel(channel_desc_t *desc, double **tx_sig_re, double **tx_sig_im, double **rx_sig_re, double **rx_sig_im, - uint16_t length, - uint8_t keep_channel) { - double complex **tx,**rx,* **H_t,*rx_temp; //, *tv_H_t; + uint32_t length, + uint8_t keep_channel) +{ + + double complex **tx,**rx,***H_t,*rx_temp;//, *tv_H_t; double path_loss = pow(10,desc->path_loss_dB/20); int i,j,k,dd; dd = abs(desc->channel_offset); @@ -126,7 +128,8 @@ void multipath_tv_channel(channel_desc_t *desc, } //TODO: make phi_rad a parameter of this function -void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length) { +void tv_channel(channel_desc_t *desc,double complex ***H,uint32_t length){ + int i,j,p,l,k; double *alpha,*phi_rad,pi=acos(-1),*w_Hz; alpha = (double *)calloc(desc->nb_paths,sizeof(double)); @@ -193,7 +196,8 @@ void tv_channel(channel_desc_t *desc,double complex ***H,uint16_t length) { } // time varying convolution -void tv_conv(double complex **h, double complex *x, double complex *y, uint16_t nb_samples, uint8_t nb_taps, int dd) { +void tv_conv(double complex **h, double complex *x, double complex *y, uint32_t nb_samples, uint8_t nb_taps, int dd){ + int i,j; for(i=0; i<((int)nb_samples-dd); i++) { diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h index 0bc5975d99..4b1b7edcdd 100644 --- a/openair1/SIMULATION/TOOLS/sim.h +++ b/openair1/SIMULATION/TOOLS/sim.h @@ -426,7 +426,7 @@ void multipath_tv_channel(channel_desc_t *desc, double **tx_sig_im, double **rx_sig_re, double **rx_sig_im, - uint16_t length, + uint32_t length, uint8_t keep_channel); /**@} */ diff --git a/openair2/COMMON/s1ap_messages_def.h b/openair2/COMMON/s1ap_messages_def.h index 57201721ce..5e5794fc55 100644 --- a/openair2/COMMON/s1ap_messages_def.h +++ b/openair2/COMMON/s1ap_messages_def.h @@ -66,6 +66,7 @@ MESSAGE_DEF(S1AP_E_RAB_MODIFY_RESP , MESSAGE_PRIORITY_MED, s1ap_e_rab_m MESSAGE_DEF(S1AP_E_RAB_RELEASE_RESPONSE , MESSAGE_PRIORITY_MED, s1ap_e_rab_release_resp_t , s1ap_e_rab_release_resp) MESSAGE_DEF(S1AP_PATH_SWITCH_REQ , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_t , s1ap_path_switch_req) MESSAGE_DEF(S1AP_PATH_SWITCH_REQ_ACK , MESSAGE_PRIORITY_MED, s1ap_path_switch_req_ack_t , s1ap_path_switch_req_ack) +MESSAGE_DEF(S1AP_E_RAB_MODIFICATION_IND , MESSAGE_PRIORITY_MED, s1ap_e_rab_modification_ind_t , s1ap_e_rab_modification_ind) /* S1AP -> RRC messages */ MESSAGE_DEF(S1AP_DOWNLINK_NAS , MESSAGE_PRIORITY_MED, s1ap_downlink_nas_t , s1ap_downlink_nas ) diff --git a/openair2/COMMON/s1ap_messages_types.h b/openair2/COMMON/s1ap_messages_types.h index aa718dbcf8..7225ae31b3 100644 --- a/openair2/COMMON/s1ap_messages_types.h +++ b/openair2/COMMON/s1ap_messages_types.h @@ -45,6 +45,7 @@ #define S1AP_E_RAB_MODIFY_RESP(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modify_resp #define S1AP_PATH_SWITCH_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req #define S1AP_PATH_SWITCH_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.s1ap_path_switch_req_ack +#define S1AP_E_RAB_MODIFICATION_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_e_rab_modification_ind #define S1AP_DOWNLINK_NAS(mSGpTR) (mSGpTR)->ittiMsg.s1ap_downlink_nas #define S1AP_INITIAL_CONTEXT_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_initial_context_setup_req @@ -281,12 +282,26 @@ typedef struct e_rab_tobe_added_s { uint8_t drb_ID; /* The transport layer address for the IP packets */ - transport_layer_addr_t eNB_addr; + transport_layer_addr_t sgw_addr; /* S-GW Tunnel endpoint identifier */ uint32_t gtp_teid; } e_rab_tobe_added_t; +typedef struct e_rab_admitted_tobe_added_s { + /* Unique e_rab_id for the UE. */ + uint8_t e_rab_id; + + /* Unique drb_ID for the UE. */ + uint8_t drb_ID; + + /* The transport layer address for the IP packets */ + transport_layer_addr_t gnb_addr; + + /* S-GW Tunnel endpoint identifier */ + uint32_t gtp_teid; +} e_rab_admitted_tobe_added_t; + typedef struct e_rab_tobeswitched_s { @@ -646,6 +661,27 @@ typedef struct s1ap_path_switch_req_ack_s { } s1ap_path_switch_req_ack_t; +typedef struct s1ap_e_rab_modification_ind_s { + + unsigned eNB_ue_s1ap_id:24; + + /* MME UE id */ + uint32_t mme_ue_s1ap_id; + + /* Number of e_rab setup-ed in the list */ + uint8_t nb_of_e_rabs_tobemodified; + + uint8_t nb_of_e_rabs_nottobemodified; + + /* list of e_rab setup-ed by RRC layers */ + e_rab_setup_t e_rabs_tobemodified[S1AP_MAX_E_RAB]; + + e_rab_setup_t e_rabs_nottobemodified[S1AP_MAX_E_RAB]; + + uint16_t ue_initial_id; + +} s1ap_e_rab_modification_ind_t; + // S1AP --> RRC messages typedef struct s1ap_ue_release_command_s { diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index ed3470a7d6..38b3b7d653 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -363,7 +363,7 @@ typedef struct x2ap_ENDC_sgnb_addition_req_ACK_s { uint8_t nb_e_rabs_admitted_tobeadded; /* list of e_rab to be added by RRC layers */ - e_rab_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB]; + e_rab_admitted_tobe_added_t e_rabs_admitted_tobeadded[S1AP_MAX_E_RAB]; /* list of e_rab to be setup by RRC layers */ e_rab_t e_rab_param[S1AP_MAX_E_RAB]; diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h index 4c5da80764..bc4c4cf9d9 100644 --- a/openair2/GNB_APP/RRC_nr_paramsvalues.h +++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h @@ -133,7 +133,8 @@ #define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR "prach_RootSequenceIndex_PR" #define GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX "prach_RootSequenceIndex" #define GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING "msg1_SubcarrierSpacing" -#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG "restrictedSetConfig" +#define GNB_CONFIG_STRING_RESTRICTEDSETCONFIG "restrictedSetConfig" +#define GNB_CONFIG_STRING_MSG3TRANSFPREC "msg3_transformPrecoder" #define GNB_CONFIG_STRING_PUSCHTIMEDOMAINALLOCATIONLIST "puschTimeDomainAllocationList" #define GNB_CONFIG_STRING_MSG3DELTAPREABMLE "msg3_DeltaPreamble" #define GNB_CONFIG_STRING_P0NOMINALWITHGRANT "p0_NominalWithGrant" @@ -246,7 +247,7 @@ {GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:-1,TYPE_INT64,0/*17*/},\ {GNB_CONFIG_STRING_INITIALDLBWPK0_1,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->k0,defint64val:-1,TYPE_INT64,0/*18*/},\ {GNB_CONFIG_STRING_INITIALDLBWPMAPPINGTYPE_1,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA,TYPE_INT64,0/*19*/},\ -{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*20*/}, \ +{GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_1,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*20*/}, \ {GNB_CONFIG_STRING_INITIALDLBWPK0_2,NULL,0,i64ptr:scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->k0,defint64val:-1,TYPE_INT64,0/*21*/},\ {GNB_CONFIG_STRING_INITIALDLBWPMAPPINGTYPE_2,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeA,TYPE_INT64,0/*22*/},\ {GNB_CONFIG_STRING_INITIALDLBWPSTARTSYMBOLANDLENGTH_2,NULL,0,i64ptr:&scc->downlinkConfigCommon->initialDownlinkBWP->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[2]->startSymbolAndLength,defint64val:54,TYPE_INT64,0/*23*/},\ @@ -311,11 +312,12 @@ {GNB_CONFIG_STRING_RSRPTHRESHOLDSSB,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rsrp_ThresholdSSB,defint64val:19,TYPE_INT64,0/*82*/},\ {GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEXPR,NULL,0,uptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present,defuintval:NR_RACH_ConfigCommon__prach_RootSequenceIndex_PR_l139,TYPE_UINT,0/*83*/},\ {GNB_CONFIG_STRING_PRACHROOTSEQUENCEINDEX,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139,defint64val:0,TYPE_INT64,0/*84*/},\ -{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig,defintval:NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet,TYPE_INT64,0/*85*/}, \ -{GNB_CONFIG_STRING_INITIALULBWPK2_0,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2,defint64val:-1,TYPE_INT64,0/*86*/},\ -{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,/*87*/},\ -{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:55,TYPE_INT64,0/*88*/},\ -{GNB_CONFIG_STRING_INITIALULBWPK2_1,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2,defint64val:-1,TYPE_INT64,0/*89*/}, \ +{GNB_CONFIG_STRING_RESTRICTEDSETCONFIG,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig,defintval:NR_RACH_ConfigCommon__restrictedSetConfig_unrestrictedSet,TYPE_INT64,0/*85*/}, \ +{GNB_CONFIG_STRING_MSG3TRANSFPREC,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder,defintval:1,TYPE_INT64,0/*86*/}, \ +{GNB_CONFIG_STRING_INITIALULBWPK2_0,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->k2,defint64val:-1,TYPE_INT64,0/*87*/},\ +{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,/*88*/},\ +{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_0,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[0]->startSymbolAndLength,defint64val:55,TYPE_INT64,0/*89*/},\ +{GNB_CONFIG_STRING_INITIALULBWPK2_1,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->k2,defint64val:-1,TYPE_INT64,0/*90*/}, \ {GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_1,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_1,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[1]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPK2_2,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[2]->k2,defint64val:-1,TYPE_INT64,0},\ @@ -325,7 +327,7 @@ {GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_3,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_3,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[3]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPK2_4,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->k2,defint64val:-1,TYPE_INT64,0},\ -{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*99*/}, \ +{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*100*/}, \ {GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_4,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[4]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPK2_5,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[5]->k2,defint64val:-1,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_5,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[5]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\ @@ -335,7 +337,7 @@ {GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_6,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[6]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPK2_7,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->k2,defint64val:-1,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\ -{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*109*/}, \ +{GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_7,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[7]->startSymbolAndLength,defint64val:53,TYPE_INT64,0/*110*/}, \ {GNB_CONFIG_STRING_INITIALULBWPK2_8,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->k2,defint64val:-1,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_8,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_8,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[8]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\ @@ -345,7 +347,7 @@ {GNB_CONFIG_STRING_INITIALULBWPK2_10,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->k2,defint64val:-1,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_10,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_10,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[10]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\ -{GNB_CONFIG_STRING_INITIALULBWPK2_11,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->k2,defint64val:-1,TYPE_INT64,0/*119*/}, \ +{GNB_CONFIG_STRING_INITIALULBWPK2_11,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->k2,defint64val:-1,TYPE_INT64,0/*120*/}, \ {GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_11,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_11,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[11]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPK2_12,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[12]->k2,defint64val:-1,TYPE_INT64,0},\ @@ -355,7 +357,7 @@ {GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_13,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[13]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_13,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[13]->startSymbolAndLength,defint64val:53,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPK2_14,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->k2,defint64val:-1,TYPE_INT64,0},\ -{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*129*/}, \ +{GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->mappingType,defint64val:NR_PDSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0 /*130*/}, \ {GNB_CONFIG_STRING_INITIALULBWPSTARTSYMBOLANDLENGTH_14,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[14]->startSymbolAndLength,defint64val:55,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPK2_15,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[15]->k2,defint64val:-1,TYPE_INT64,0},\ {GNB_CONFIG_STRING_INITIALULBWPMAPPINGTYPE_15,NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[15]->mappingType,defint64val:NR_PUSCH_TimeDomainResourceAllocation__mappingType_typeB,TYPE_INT64,0},\ @@ -365,7 +367,7 @@ {GNB_CONFIG_STRING_PUCCHGROUPHOPPING, NULL,0,i64ptr:&scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->pucch_GroupHopping,defint64val:NR_PUCCH_ConfigCommon__pucch_GroupHopping_neither,TYPE_INT64,0},\ {GNB_CONFIG_STRING_HOPPINGID, NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->hoppingId,defint64val:40,TYPE_INT64,0},\ {GNB_CONFIG_STRING_P0NOMINAL, NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->pucch_ConfigCommon->choice.setup->p0_nominal,defint64val:1,TYPE_INT64,0},\ -{GNB_CONFIG_STRING_SSBPOSITIONSINBURSTPR,NULL,0,uptr:&scc->ssb_PositionsInBurst->present,defuintval:NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap,TYPE_UINT,0/*139*/}, \ +{GNB_CONFIG_STRING_SSBPOSITIONSINBURSTPR,NULL,0,uptr:&scc->ssb_PositionsInBurst->present,defuintval:NR_ServingCellConfigCommon__ssb_PositionsInBurst_PR_mediumBitmap,TYPE_UINT,0/*140*/}, \ {GNB_CONFIG_STRING_SSBPOSITIONSINBURST,NULL,0,u64ptr:&ssb_bitmap,defintval:0xff,TYPE_UINT64,0}, \ {GNB_CONFIG_STRING_REFERENCESUBCARRIERSPACING,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->referenceSubcarrierSpacing,defint64val:NR_SubcarrierSpacing_kHz30,TYPE_INT64,0},\ {GNB_CONFIG_STRING_DLULTRANSMISSIONPERIODICITY,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity,defint64val:NR_TDD_UL_DL_Pattern__dl_UL_TransmissionPeriodicity_ms0p5,TYPE_INT64,0},\ @@ -379,7 +381,7 @@ {GNB_CONFIG_STRING_NROFUPLINKSLOTS2,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSlots,defint64val:-1,TYPE_INT64,0},\ {GNB_CONFIG_STRING_NROFUPLINKSYMBOLS2,NULL,0,i64ptr:&scc->tdd_UL_DL_ConfigurationCommon->pattern2->nrofUplinkSymbols,defint64val:-1,TYPE_INT64,0},\ {GNB_CONFIG_STRING_SSPBCHBLOCKPOWER,NULL,0,i64ptr:&scc->ss_PBCH_BlockPower,defint64val:20,TYPE_INT64,0}, \ -{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,defintval:-1,TYPE_INT64,0/*86*/}} +{GNB_CONFIG_STRING_MSG1SUBCARRIERSPACING,NULL,0,i64ptr:scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing,defintval:-1,TYPE_INT64,0}} diff --git a/openair2/GNB_APP/gnb_app.c b/openair2/GNB_APP/gnb_app.c index f11e302771..821174deda 100644 --- a/openair2/GNB_APP/gnb_app.c +++ b/openair2/GNB_APP/gnb_app.c @@ -71,7 +71,7 @@ static void configure_nr_rrc(uint32_t gnb_id) /*------------------------------------------------------------------------------*/ -/* + static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, const Enb_properties_array_t *enb_properties) { uint32_t gnb_id; @@ -83,18 +83,18 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, s1ap_register_enb_req_t *s1ap_register_gNB; //Type Temporarily reuse // note: there is an implicit relationship between the data structure and the message name - msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse + /*msg_p = itti_alloc_new_message (TASK_GNB_APP, S1AP_REGISTER_ENB_REQ); //Message Temporarily reuse - RCconfig_NR_S1(msg_p, gnb_id); + RCconfig_NR_S1(msg_p, gnb_id);*/ if (gnb_id == 0) RCconfig_nr_gtpu(); - s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse - LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx); + /*s1ap_register_gNB = &S1AP_REGISTER_ENB_REQ(msg_p); //Message Temporarily reuse + LOG_I(GNB_APP,"default drx %d\n",s1ap_register_gNB->default_drx);*/ LOG_I(GNB_APP,"[gNB %d] gNB_app_register for instance %d\n", gnb_id, GNB_MODULE_ID_TO_INSTANCE(gnb_id)); - itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); + //itti_send_msg_to_task (TASK_S1AP, GNB_MODULE_ID_TO_INSTANCE(gnb_id), msg_p); register_gnb_pending++; } @@ -102,7 +102,7 @@ static uint32_t gNB_app_register(uint32_t gnb_id_start, uint32_t gnb_id_end)//, return register_gnb_pending; } -*/ + /*------------------------------------------------------------------------------*/ static uint32_t gNB_app_register_x2(uint32_t gnb_id_start, uint32_t gnb_id_end) { @@ -132,6 +132,7 @@ void *gNB_app_task(void *args_p) uint32_t gnb_id_start = 0; uint32_t gnb_id_end = gnb_id_start + gnb_nb; uint32_t x2_register_gnb_pending = 0; + uint32_t register_gnb_pending=0; uint32_t gnb_id; MessageDef *msg_p = NULL; const char *msg_name = NULL; @@ -176,7 +177,7 @@ void *gNB_app_task(void *args_p) if (EPC_MODE_ENABLED) { /* Try to register each gNB */ //registered_gnb = 0; - //register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p); + register_gnb_pending = gNB_app_register (gnb_id_start, gnb_id_end);//, gnb_properties_p); } else { /* Start L2L1 task */ msg_p = itti_alloc_new_message(TASK_GNB_APP, INITIALIZE_MESSAGE); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 9355517072..69c971fb1d 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" @@ -254,6 +255,10 @@ void fix_scc(NR_ServingCellConfigCommon_t *scc,uint64_t ssbmap) { scc->uplinkConfigCommon->frequencyInfoUL->absoluteFrequencyPointA = NULL; } + // default value for msg3 precoder is NULL (0 means enabled) + if (*scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder!=0) + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder = NULL; + // fix libconfig (asn1c uses long) scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.preambleReceivedTargetPower-=((long)1<<32); *scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->p0_NominalWithGrant-=((long)1<<32); @@ -714,10 +719,14 @@ int RCconfig_nr_gtpu(void ) { if (address) { MessageDef *message; AssertFatal((message = itti_alloc_new_message(TASK_GNB_APP, GTPV1U_ENB_S1_REQ))!=NULL,""); - IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); - LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up); - GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U; - itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) + // IPV4_STR_ADDR_TO_INT_NWBO ( address, RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); + // LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up); + + + IPV4_STR_ADDR_TO_INT_NWBO ( address, GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" ); + LOG_I(GTPU,"Configuring GTPu address : %s -> %x\n",address,GTPV1U_ENB_S1_REQ(message).enb_ip_address_for_S1u_S12_S4_up); + GTPV1U_ENB_S1_REQ(message).enb_port_for_S1u_S12_S4_up = gnb_port_for_S1U; + itti_send_msg_to_task (TASK_GTPV1_U, 0, message); // data model is wrong: gtpu doesn't have enb_id (or module_id) } else LOG_E(GTPU,"invalid address for S1U\n"); diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index eef1f9c976..0d0d0e7123 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 53e7c83661..9903544612 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) @@ -86,12 +90,88 @@ typedef struct { uint8_t R:2; // octet 1 [7:6] } __attribute__ ((__packed__)) NR_MAC_SUBHEADER_FIXED; +// BSR MAC CEs +// TS 38.321 ch. 6.1.3.1 +// Short BSR for a specific logical channel group ID +typedef struct { + uint8_t Buffer_size:5; // octet 1 LSB + uint8_t LcgID:3; // octet 1 MSB +} __attribute__ ((__packed__)) NR_BSR_SHORT; + +typedef NR_BSR_SHORT NR_BSR_SHORT_TRUNCATED; + +// Long BSR for all logical channel group ID +typedef struct { + uint8_t Buffer_size7:8; + uint8_t Buffer_size6:8; + uint8_t Buffer_size5:8; + uint8_t Buffer_size4:8; + uint8_t Buffer_size3:8; + uint8_t Buffer_size2:8; + uint8_t Buffer_size1:8; + uint8_t Buffer_size0:8; + uint8_t LcgID0:1; + uint8_t LcgID1:1; + uint8_t LcgID2:1; + uint8_t LcgID3:1; + uint8_t LcgID4:1; + uint8_t LcgID5:1; + uint8_t LcgID6:1; + uint8_t LcgID7:1; +} __attribute__ ((__packed__)) NR_BSR_LONG; + +typedef NR_BSR_LONG NR_BSR_LONG_TRUNCATED; + // 38.321 ch. 6.1.3.4 typedef struct { uint8_t TA_COMMAND:6; // octet 1 [5:0] uint8_t TAGID:2; // octet 1 [7:6] } __attribute__ ((__packed__)) NR_MAC_CE_TA; +// single Entry PHR MAC CE +// TS 38.321 ch. 6.1.3.8 +typedef struct { + uint8_t PH:6; + uint8_t R1:2; + uint8_t PCMAX:6; + uint8_t R2:6; +} __attribute__ ((__packed__)) NR_SINGLE_ENTRY_PHR_MAC_CE; + +//* RAR MAC subheader // TS 38.321 ch. 6.1.5, 6.2.2 *// +// - E: The Extension field is a flag indicating if the MAC subPDU including this MAC subheader is the last MAC subPDU or not in the MAC PDU +// - T: The Type field is a flag indicating whether the MAC subheader contains a Random Access Preamble ID or a Backoff Indicator (0, BI) (1, RAPID) +// - R: Reserved bit, set to "0" +// - BI: The Backoff Indicator field identifies the overload condition in the cell. +// - RAPID: The Random Access Preamble IDentifier field identifies the transmitted Random Access Preamble + +/*!\brief RAR MAC subheader with RAPID */ +typedef struct { + uint8_t RAPID:6; + uint8_t T:1; + uint8_t E:1; +} __attribute__ ((__packed__)) NR_RA_HEADER_RAPID; + +/*!\brief RAR MAC subheader with Backoff Indicator */ +typedef struct { + uint8_t BI:4; + uint8_t R:2; + uint8_t T:1; + uint8_t E:1; +} __attribute__ ((__packed__)) NR_RA_HEADER_BI; + +// TS 38.321 ch. 6.2.3 +typedef struct { + uint8_t TA1:7; // octet 1 [6:0] + uint8_t R:1; // octet 1 [7] + uint8_t UL_GRANT_1:3; // octet 2 [2:0] + uint8_t TA2:5; // octet 2 [7:3] + uint8_t UL_GRANT_2:8; // octet 3 [7:0] + uint8_t UL_GRANT_3:8; // octet 4 [7:0] + uint8_t UL_GRANT_4:8; // octet 5 [7:0] + uint8_t TCRNTI_1:8; // octet 6 [7:0] + uint8_t TCRNTI_2:8; // octet 7 [7:0] +} __attribute__ ((__packed__)) NR_MAC_RAR; + // DCI pdu structures. Used by both gNB and UE. typedef struct { uint16_t val; @@ -100,59 +180,59 @@ typedef struct { typedef struct { -uint8_t format_indicator; //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 mcs; //5 bits -uint8_t ndi; //1 bit -uint8_t rv; //2 bits -uint8_t harq_pid; //4 bits -uint8_t tpc; //2 bits -uint8_t short_messages_indicator; //2 bits -uint8_t short_messages; //8 bits -uint8_t tb_scaling; //2 bits -uint8_t pucch_resource_indicator; //3 bits -uint8_t dmrs_sequence_initialization; //1 bit -uint8_t system_info_indicator; //1 bit + uint8_t format_indicator; //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 mcs; //5 bits + uint8_t ndi; //1 bit + uint8_t rv; //2 bits + uint8_t harq_pid; //4 bits + uint8_t tpc; //2 bits + uint8_t short_messages_indicator; //2 bits + uint8_t short_messages; //8 bits + uint8_t tb_scaling; //2 bits + uint8_t pucch_resource_indicator; //3 bits + uint8_t dmrs_sequence_initialization; //1 bit + uint8_t system_info_indicator; //1 bit -uint8_t slot_format_indicator_count; -uint8_t *slot_format_indicators; + uint8_t slot_format_indicator_count; + uint8_t *slot_format_indicators; -uint8_t pre_emption_indication_count; -uint16_t *pre_emption_indications; //14 bit each + uint8_t pre_emption_indication_count; + uint16_t *pre_emption_indications; //14 bit each -uint8_t block_number_count; -uint8_t *block_numbers; -uint8_t padding; + uint8_t block_number_count; + uint8_t *block_numbers; + uint8_t padding; -dci_field_t mcs2; //variable -dci_field_t ndi2; //variable -dci_field_t rv2; //variable -dci_field_t frequency_domain_assignment; //variable -dci_field_t time_domain_assignment; //variable -dci_field_t frequency_hopping_flag; //variable -dci_field_t vrb_to_prb_mapping; //variable -dci_field_t dai[2]; //variable -dci_field_t pdsch_to_harq_feedback_timing_indicator; //variable -dci_field_t carrier_indicator; //variable -dci_field_t bwp_indicator; //variable -dci_field_t prb_bundling_size_indicator; //variable -dci_field_t rate_matching_indicator; //variable -dci_field_t zp_csi_rs_trigger; //variable -dci_field_t transmission_configuration_indication; //variable -dci_field_t srs_request; //variable -dci_field_t cbgti; //variable -dci_field_t cbgfi; //variable -dci_field_t srs_resource_indicator; //variable -dci_field_t precoding_information; //variable -dci_field_t csi_request; //variable -dci_field_t ptrs_dmrs_association; //variable -dci_field_t beta_offset_indicator; //variable -dci_field_t cloded_loop_indicator; //variable -dci_field_t ul_sul_indicator; //variable -dci_field_t antenna_ports; //variable -dci_field_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits + dci_field_t mcs2; //variable + dci_field_t ndi2; //variable + dci_field_t rv2; //variable + dci_field_t frequency_domain_assignment; //variable + dci_field_t time_domain_assignment; //variable + dci_field_t frequency_hopping_flag; //variable + dci_field_t vrb_to_prb_mapping; //variable + dci_field_t dai[2]; //variable + dci_field_t pdsch_to_harq_feedback_timing_indicator; //variable + dci_field_t carrier_indicator; //variable + dci_field_t bwp_indicator; //variable + dci_field_t prb_bundling_size_indicator; //variable + dci_field_t rate_matching_indicator; //variable + dci_field_t zp_csi_rs_trigger; //variable + dci_field_t transmission_configuration_indication; //variable + dci_field_t srs_request; //variable + dci_field_t cbgti; //variable + dci_field_t cbgfi; //variable + dci_field_t srs_resource_indicator; //variable + dci_field_t precoding_information; //variable + dci_field_t csi_request; //variable + dci_field_t ptrs_dmrs_association; //variable + dci_field_t beta_offset_indicator; //variable + dci_field_t cloded_loop_indicator; //variable + dci_field_t ul_sul_indicator; //variable + dci_field_t antenna_ports; //variable + dci_field_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: 16 bits } dci_pdu_rel15_t; @@ -182,8 +262,8 @@ dci_field_t reserved; //1_0/C-RNTI:10 bits, 1_0/P-RNTI: 6 bits, 1_0/SI-&RA-RNTI: #define UL_SCH_LCID_CCCH 0x00 #define UL_SCH_LCID_SRB1 0x01 #define UL_SCH_LCID_SRB2 0x02 -#define UL_SCH_LCID_DTCH 0x03 -#define UL_SCH_LCID_SRB3 0x04 +#define UL_SCH_LCID_SRB3 0x03 +#define UL_SCH_LCID_DTCH 0x04 #define UL_SCH_LCID_CCCH_MSG3 0x21 #define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35 #define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36 diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 9dd797b503..e4d060fcc1 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -32,6 +32,1092 @@ #include "LAYER2/NR_MAC_gNB/mac_proto.h" +// Table 6.3.3.1-5 (38.211) NCS for preamble formats with delta_f_RA = 1.25 KHz +uint16_t NCS_unrestricted_delta_f_RA_125[16] = {0,13,15,18,22,26,32,38,46,59,76,93,119,167,279,419}; +uint16_t NCS_restricted_TypeA_delta_f_RA_125[15] = {15,18,22,26,32,38,46,55,68,82,100,128,158,202,237}; // high-speed case set Type A +uint16_t NCS_restricted_TypeB_delta_f_RA_125[13] = {15,18,22,26,32,38,46,55,68,82,100,118,137}; // high-speed case set Type B + +// Table 6.3.3.1-6 (38.211) NCS for preamble formats with delta_f_RA = 5 KHz +uint16_t NCS_unrestricted_delta_f_RA_5[16] = {0,13,26,33,38,41,49,55,64,76,93,119,139,209,279,419}; +uint16_t NCS_restricted_TypeA_delta_f_RA_5[16] = {36,57,72,81,89,94,103,112,121,132,137,152,173,195,216,237}; // high-speed case set Type A +uint16_t NCS_restricted_TypeB_delta_f_RA_5[14] = {36,57,60,63,65,68,71,77,81,85,97,109,122,137}; // high-speed case set Type B + +// Table 6.3.3.1-7 (38.211) NCS for preamble formats with delta_f_RA = 15 * 2mu KHz where mu = {0,1,2,3} +uint16_t NCS_unrestricted_delta_f_RA_15[16] = {0,2,4,6,8,10,12,13,15,17,19,23,27,34,46,69}; + +const char *prachfmt[]={"A1","A2","A3","B1","B2","B3","B4","C0","C2"}; + +uint16_t get_NCS(uint8_t index, uint16_t format0, uint8_t restricted_set_config) { + + if (format0 < 3) { + switch(restricted_set_config){ + case 0: + return(NCS_unrestricted_delta_f_RA_125[index]); + case 1: + return(NCS_restricted_TypeA_delta_f_RA_125[index]); + case 2: + return(NCS_restricted_TypeB_delta_f_RA_125[index]); + default: + AssertFatal(1==0,"Invalid restricted set config value %d",restricted_set_config); + } + } + else { + if (format0 == 3) { + switch(restricted_set_config){ + case 0: + return(NCS_unrestricted_delta_f_RA_5[index]); + case 1: + return(NCS_restricted_TypeA_delta_f_RA_5[index]); + case 2: + return(NCS_restricted_TypeB_delta_f_RA_5[index]); + default: + AssertFatal(1==0,"Invalid restricted set config value %d",restricted_set_config); + } + } + else + return(NCS_unrestricted_delta_f_RA_15[index]); + } +} + + +// Table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum/supplementary uplink +// the column 5, (SFN_nbr is a bitmap where we set bit to '1' in the position of the subframe where the RACH can be sent. +// E.g. in row 4, and column 5 we have set value 512 ('1000000000') which means RACH can be sent at subframe 9. +// E.g. in row 20 and column 5 we have set value 66 ('0001000010') which means RACH can be sent at subframe 1 or 6 +int64_t table_6_3_3_2_2_prachConfig_Index [256][9] = { +//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration +{0, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{0, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{0, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 +{0, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{0, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{0, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 +{0, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{0, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{0, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 +{0, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{0, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 +{0, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 +{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 +{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 +{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 +{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 +{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 +{0, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 +{0, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 +{0, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9 +{0, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8 +{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9 +{0, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{1, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{1, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{1, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 +{1, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{1, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{1, -1, 8, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 +{1, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{1, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{1, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 +{1, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{1, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{1, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 +{1, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 +{1, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 +{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 +{1, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 +{1, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 +{1, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 +{1, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 +{1, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 +{1, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3,6,9 +{2, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{2, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{2, -1, 4, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 +{2, -1, 2, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 +{2, -1, 2, 0, 32, 0, -1, -1, 0}, // (subframe number) 5 +{2, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 +{2, -1, 1, 0, 32, 0, -1, -1, 0}, // (subframe number) 5 +{3, -1, 16, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{3, -1, 16, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{3, -1, 16, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 +{3, -1, 8, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{3, -1, 8, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{3, -1, 8, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{3, -1, 4, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{3, -1, 4, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{3, -1, 4, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 +{3, -1, 2, 1, 2, 0, -1, -1, 0}, // (subframe number) 1 +{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subframe number) 4 +{3, -1, 2, 1, 128, 0, -1, -1, 0}, // (subframe number) 7 +{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subframe number) 9 +{3, -1, 1, 0, 2, 0, -1, -1, 0}, // (subframe number) 1 +{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subframe number) 4 +{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subframe number) 7 +{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subframe number) 1,6 +{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subframe number) 2,7 +{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subframe number) 3,8 +{3, -1, 1, 0, 146, 0, -1, -1, 0}, // (subframe number) 1,4,7 +{3, -1, 1, 0, 292, 0, -1, -1, 0}, // (subframe number) 2,5,8 +{3, -1, 1, 0, 584, 0, -1, -1, 0}, // (subframe number) 3, 6, 9 +{3, -1, 1, 0, 341, 0, -1, -1, 0}, // (subframe number) 0,2,4,6,8 +{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subframe number) 1,3,5,7,9 +{3, -1, 1, 0, 1023, 0, -1, -1, 0}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0xa1, -1, 16, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 +{0xa1, -1, 16, 1, 16, 0, 2, 6, 2}, // (subframe number) 4 +{0xa1, -1, 8, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 +{0xa1, -1, 8, 1, 16, 0, 2, 6, 2}, // (subframe number) 4 +{0xa1, -1, 4, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 +{0xa1, -1, 4, 1, 528, 0, 1, 6, 2}, // (subframe number) 4,9 +{0xa1, -1, 4, 0, 16, 0, 2, 6, 2}, // (subframe number) 4 +{0xa1, -1, 2, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 +{0xa1, -1, 2, 0, 2, 0, 2, 6, 2}, // (subframe number) 1 +{0xa1, -1, 2, 0, 16, 0, 2, 6, 2}, // (subframe number) 4 +{0xa1, -1, 2, 0, 128, 0, 2, 6, 2}, // (subframe number) 7 +{0xa1, -1, 1, 0, 16, 0, 1, 6, 2}, // (subframe number) 4 +{0xa1, -1, 1, 0, 66, 0, 1, 6, 2}, // (subframe number) 1,6 +{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subframe number) 4,9 +{0xa1, -1, 1, 0, 2, 0, 2, 6, 2}, // (subframe number) 1 +{0xa1, -1, 1, 0, 128, 0, 2, 6, 2}, // (subframe number) 7 +{0xa1, -1, 1, 0, 132, 0, 2, 6, 2}, // (subframe number) 2,7 +{0xa1, -1, 1, 0, 146, 0, 2, 6, 2}, // (subframe number) 1,4,7 +{0xa1, -1, 1, 0, 341, 0, 2, 6, 2}, // (subframe number) 0,2,4,6,8 +{0xa1, -1, 1, 0, 1023, 0, 2, 6, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0xa1, -1, 1, 0, 682, 0, 2, 6, 2}, // (subframe number) 1,3,5,7,9 +{0xa1, 0xb1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 +{0xa1, 0xb1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4 +{0xa1, 0xb1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4 +{0xa1, 0xb1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6 +{0xa1, 0xb1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 +{0xa1, 0xb1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1 +{0xa1, 0xb1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7 +{0xa1, 0xb1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7 +{0xa1, 0xb1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8 +{0xa2, -1, 16, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9 +{0xa2, -1, 16, 1, 16, 0, 2, 3, 4}, // (subframe number) 4 +{0xa2, -1, 8, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9 +{0xa2, -1, 8, 1, 16, 0, 2, 3, 4}, // (subframe number) 4 +{0xa2, -1, 4, 0, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9 +{0xa2, -1, 4, 0, 16, 0, 2, 3, 4}, // (subframe number) 4 +{0xa2, -1, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9 +{0xa2, -1, 2, 0, 2, 0, 2, 3, 4}, // (subframe number) 1 +{0xa2, -1, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4 +{0xa2, -1, 2, 0, 128, 0, 2, 3, 4}, // (subframe number) 7 +{0xa2, -1, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4 +{0xa2, -1, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6 +{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9 +{0xa2, -1, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1 +{0xa2, -1, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7 +{0xa2, -1, 1, 0, 132, 0, 2, 3, 4}, // (subframe number) 2,7 +{0xa2, -1, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7 +{0xa2, -1, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8 +{0xa2, -1, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0xa2, -1, 1, 0, 682, 0, 2, 3, 4}, // (subframe number) 1,3,5,7,9 +{0xa2, 0xb2, 2, 1, 580, 0, 1, 3, 4}, // (subframe number) 2,6,9 +{0xa2, 0xb2, 2, 0, 16, 0, 2, 3, 4}, // (subframe number) 4 +{0xa2, 0xb2, 1, 0, 16, 0, 1, 3, 4}, // (subframe number) 4 +{0xa2, 0xb2, 1, 0, 66, 0, 1, 3, 4}, // (subframe number) 1,6 +{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subframe number) 4,9 +{0xa2, 0xb2, 1, 0, 2, 0, 2, 3, 4}, // (subframe number) 1 +{0xa2, 0xb2, 1, 0, 128, 0, 2, 3, 4}, // (subframe number) 7 +{0xa2, 0xb2, 1, 0, 146, 0, 2, 3, 4}, // (subframe number) 1,4,7 +{0xa2, 0xb2, 1, 0, 341, 0, 2, 3, 4}, // (subframe number) 0,2,4,6,8 +{0xa2, 0xb2, 1, 0, 1023, 0, 2, 3, 4}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0xa3, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9 +{0xa3, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4 +{0xa3, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9 +{0xa3, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4 +{0xa3, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9 +{0xa3, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4 +{0xa3, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9 +{0xa3, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1 +{0xa3, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4 +{0xa3, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7 +{0xa3, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4 +{0xa3, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6 +{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9 +{0xa3, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1 +{0xa3, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7 +{0xa3, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7 +{0xa3, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7 +{0xa3, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8 +{0xa3, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0xa3, -1, 1, 0, 682, 0, 2, 2, 6}, // (subframe number) 1,3,5,7,9 +{0xa3, 0xb3, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9 +{0xa3, 0xb3, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4 +{0xa3, 0xb3, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4 +{0xa3, 0xb3, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6 +{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9 +{0xa3, 0xb3, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1 +{0xa3, 0xb3, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7 +{0xa3, 0xb3, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7 +{0xa3, 0xb3, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8 +{0xa3, 0xb3, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0xb1, -1, 16, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 +{0xb1, -1, 16, 1, 16, 0, 2, 7, 2}, // (subframe number) 4 +{0xb1, -1, 8, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 +{0xb1, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4 +{0xb1, -1, 4, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 +{0xb1, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9 +{0xb1, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4 +{0xb1, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 +{0xb1, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1 +{0xb1, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4 +{0xb1, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7 +{0xb1, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4 +{0xb1, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6 +{0xb1, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 +{0xb1, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1 +{0xb1, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7 +{0xb1, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7 +{0xb1, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7 +{0xb1, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8 +{0xb1, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0xb1, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9 +{0xb4, -1, 16, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9 +{0xb4, -1, 16, 1, 16, 0, 2, 1, 12}, // (subframe number) 4 +{0xb4, -1, 8, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9 +{0xb4, -1, 8, 1, 16, 0, 2, 1, 12}, // (subframe number) 4 +{0xb4, -1, 4, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9 +{0xb4, -1, 4, 0, 16, 0, 2, 1, 12}, // (subframe number) 4 +{0xb4, -1, 4, 1, 528, 0, 2, 1, 12}, // (subframe number) 4,9 +{0xb4, -1, 2, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9 +{0xb4, -1, 2, 0, 2, 0, 2, 1, 12}, // (subframe number) 1 +{0xb4, -1, 2, 0, 16, 0, 2, 1, 12}, // (subframe number) 4 +{0xb4, -1, 2, 0, 128, 0, 2, 1, 12}, // (subframe number) 7 +{0xb4, -1, 1, 0, 2, 0, 2, 1, 12}, // (subframe number) 1 +{0xb4, -1, 1, 0, 16, 0, 2, 1, 12}, // (subframe number) 4 +{0xb4, -1, 1, 0, 128, 0, 2, 1, 12}, // (subframe number) 7 +{0xb4, -1, 1, 0, 66, 0, 2, 1, 12}, // (subframe number) 1,6 +{0xb4, -1, 1, 0, 132, 0, 2, 1, 12}, // (subframe number) 2,7 +{0xb4, -1, 1, 0, 528, 0, 2, 1, 12}, // (subframe number) 4,9 +{0xb4, -1, 1, 0, 146, 0, 2, 1, 12}, // (subframe number) 1,4,7 +{0xb4, -1, 1, 0, 341, 0, 2, 1, 12}, // (subframe number) 0,2,4,6,8 +{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0xb4, -1, 1, 0, 682, 0, 2, 1, 12}, // (subframe number) 1,3,5,7,9 +{0xc0, -1, 8, 1, 16, 0, 2, 7, 2}, // (subframe number) 4 +{0xc0, -1, 4, 1, 528, 0, 1, 7, 2}, // (subframe number) 4,9 +{0xc0, -1, 4, 0, 16, 0, 2, 7, 2}, // (subframe number) 4 +{0xc0, -1, 2, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 +{0xc0, -1, 2, 0, 2, 0, 2, 7, 2}, // (subframe number) 1 +{0xc0, -1, 2, 0, 16, 0, 2, 7, 2}, // (subframe number) 4 +{0xc0, -1, 2, 0, 128, 0, 2, 7, 2}, // (subframe number) 7 +{0xc0, -1, 1, 0, 16, 0, 1, 7, 2}, // (subframe number) 4 +{0xc0, -1, 1, 0, 66, 0, 1, 7, 2}, // (subframe number) 1,6 +{0xc0, -1, 1, 0, 528, 0, 1, 7, 2}, // (subframe number) 4,9 +{0xc0, -1, 1, 0, 2, 0, 2, 7, 2}, // (subframe number) 1 +{0xc0, -1, 1, 0, 128, 0, 2, 7, 2}, // (subframe number) 7 +{0xc0, -1, 1, 0, 132, 0, 2, 7, 2}, // (subframe number) 2,7 +{0xc0, -1, 1, 0, 146, 0, 2, 7, 2}, // (subframe number) 1,4,7 +{0xc0, -1, 1, 0, 341, 0, 2, 7, 2}, // (subframe number) 0,2,4,6,8 +{0xc0, -1, 1, 0, 1023, 0, 2, 7, 2}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0xc0, -1, 1, 0, 682, 0, 2, 7, 2}, // (subframe number) 1,3,5,7,9 +{0xc2, -1, 16, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9 +{0xc2, -1, 16, 1, 16, 0, 2, 2, 6}, // (subframe number) 4 +{0xc2, -1, 8, 1, 528, 0, 1, 2, 6}, // (subframe number) 4,9 +{0xc2, -1, 8, 1, 16, 0, 2, 2, 6}, // (subframe number) 4 +{0xc2, -1, 4, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9 +{0xc2, -1, 4, 0, 16, 0, 2, 2, 6}, // (subframe number) 4 +{0xc2, -1, 2, 1, 580, 0, 2, 2, 6}, // (subframe number) 2,6,9 +{0xc2, -1, 2, 0, 2, 0, 2, 2, 6}, // (subframe number) 1 +{0xc2, -1, 2, 0, 16, 0, 2, 2, 6}, // (subframe number) 4 +{0xc2, -1, 2, 0, 128, 0, 2, 2, 6}, // (subframe number) 7 +{0xc2, -1, 1, 0, 16, 0, 1, 2, 6}, // (subframe number) 4 +{0xc2, -1, 1, 0, 66, 0, 1, 2, 6}, // (subframe number) 1,6 +{0xc2, -1, 1, 0, 528, 0, 1, 2, 6}, // (subframe number) 4,9 +{0xc2, -1, 1, 0, 2, 0, 2, 2, 6}, // (subframe number) 1 +{0xc2, -1, 1, 0, 128, 0, 2, 2, 6}, // (subframe number) 7 +{0xc2, -1, 1, 0, 132, 0, 2, 2, 6}, // (subframe number) 2,7 +{0xc2, -1, 1, 0, 146, 0, 2, 2, 6}, // (subframe number) 1,4,7 +{0xc2, -1, 1, 0, 341, 0, 2, 2, 6}, // (subframe number) 0,2,4,6,8 +{0xc2, -1, 1, 0, 1023, 0, 2, 2, 6}, // (subframe number) 0,1,2,3,4,5,6,7,8,9 +{0xc2, -1, 1, 0, 682, 0, 2, 2, 6} // (subframe number) 1,3,5,7,9 +}; +// Table 6.3.3.2-3: Random access configurations for FR1 and unpaired spectrum +int64_t table_6_3_3_2_3_prachConfig_Index [256][9] = { +//format, format, x, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration +{0, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9) +{0, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9) +{0, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9) +{0, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9) +{0, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9) +{0, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4) +{0, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4) +{0, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9) +{0, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8) +{0, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) +{0, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6) +{0, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5) +{0, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4) +{0, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3) +{0, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2) +{0, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6) +{0, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6) +{0, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9) +{0, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8) +{0, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7) +{0, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9) +{0, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9) +{0, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9) +{0, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9) +{0, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9) +{0, -1, 1, 0, 960, 0, -1, -1, 0}, // (subrame number 6,7,8,9) +{0, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9) +{0, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9) +{1, -1, 16, 1, 128, 0, -1, -1, 0}, // (subrame number 7) +{1, -1, 8, 1, 128, 0, -1, -1, 0}, // (subrame number 7) +{1, -1, 4, 1, 128, 0, -1, -1, 0}, // (subrame number 7) +{1, -1, 2, 0, 128, 0, -1, -1, 0}, // (subrame number 7) +{1, -1, 2, 1, 128, 0, -1, -1, 0}, // (subrame number 7) +{1, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) +{2, -1, 16, 1, 64, 0, -1, -1, 0}, // (subrame number 6) +{2, -1, 8, 1, 64, 0, -1, -1, 0}, // (subrame number 6) +{2, -1, 4, 1, 64, 0, -1, -1, 0}, // (subrame number 6) +{2, -1, 2, 0, 64, 7, -1, -1, 0}, // (subrame number 6) +{2, -1, 2, 1, 64, 7, -1, -1, 0}, // (subrame number 6) +{2, -1, 1, 0, 64, 7, -1, -1, 0}, // (subrame number 6) +{3, -1, 16, 1, 512, 0, -1, -1, 0}, // (subrame number 9) +{3, -1, 8, 1, 512, 0, -1, -1, 0}, // (subrame number 9) +{3, -1, 4, 1, 512, 0, -1, -1, 0}, // (subrame number 9) +{3, -1, 2, 0, 512, 0, -1, -1, 0}, // (subrame number 9) +{3, -1, 2, 1, 512, 0, -1, -1, 0}, // (subrame number 9) +{3, -1, 2, 0, 16, 0, -1, -1, 0}, // (subrame number 4) +{3, -1, 2, 1, 16, 0, -1, -1, 0}, // (subrame number 4) +{3, -1, 1, 0, 512, 0, -1, -1, 0}, // (subrame number 9) +{3, -1, 1, 0, 256, 0, -1, -1, 0}, // (subrame number 8) +{3, -1, 1, 0, 128, 0, -1, -1, 0}, // (subrame number 7) +{3, -1, 1, 0, 64, 0, -1, -1, 0}, // (subrame number 6) +{3, -1, 1, 0, 32, 0, -1, -1, 0}, // (subrame number 5) +{3, -1, 1, 0, 16, 0, -1, -1, 0}, // (subrame number 4) +{3, -1, 1, 0, 8, 0, -1, -1, 0}, // (subrame number 3) +{3, -1, 1, 0, 4, 0, -1, -1, 0}, // (subrame number 2) +{3, -1, 1, 0, 66, 0, -1, -1, 0}, // (subrame number 1,6) +{3, -1, 1, 0, 66, 7, -1, -1, 0}, // (subrame number 1,6) +{3, -1, 1, 0, 528, 0, -1, -1, 0}, // (subrame number 4,9) +{3, -1, 1, 0, 264, 0, -1, -1, 0}, // (subrame number 3,8) +{3, -1, 1, 0, 132, 0, -1, -1, 0}, // (subrame number 2,7) +{3, -1, 1, 0, 768, 0, -1, -1, 0}, // (subrame number 8,9) +{3, -1, 1, 0, 784, 0, -1, -1, 0}, // (subrame number 4,8,9) +{3, -1, 1, 0, 536, 0, -1, -1, 0}, // (subrame number 3,4,9) +{3, -1, 1, 0, 896, 0, -1, -1, 0}, // (subrame number 7,8,9) +{3, -1, 1, 0, 792, 0, -1, -1, 0}, // (subrame number 3,4,8,9) +{3, -1, 1, 0, 594, 0, -1, -1, 0}, // (subrame number 1,4,6,9) +{3, -1, 1, 0, 682, 0, -1, -1, 0}, // (subrame number 1,3,5,7,9) +{0xa1, -1, 16, 1, 512, 0, 2, 6, 2}, // (subrame number 9) +{0xa1, -1, 8, 1, 512, 0, 2, 6, 2}, // (subrame number 9) +{0xa1, -1, 4, 1, 512, 0, 1, 6, 2}, // (subrame number 9) +{0xa1, -1, 2, 1, 512, 0, 1, 6, 2}, // (subrame number 9) +{0xa1, -1, 2, 1, 528, 7, 1, 3, 2}, // (subrame number 4,9) +{0xa1, -1, 2, 1, 640, 7, 1, 3, 2}, // (subrame number 7,9) +{0xa1, -1, 2, 1, 640, 0, 1, 6, 2}, // (subrame number 7,9) +{0xa1, -1, 2, 1, 768, 0, 2, 6, 2}, // (subrame number 8,9) +{0xa1, -1, 2, 1, 528, 0, 2, 6, 2}, // (subrame number 4,9) +{0xa1, -1, 2, 1, 924, 0, 1, 6, 2}, // (subrame number 2,3,4,7,8,9) +{0xa1, -1, 1, 0, 512, 0, 2, 6, 2}, // (subrame number 9) +{0xa1, -1, 1, 0, 512, 7, 1, 3, 2}, // (subrame number 9) +{0xa1, -1, 1, 0, 512, 0, 1, 6, 2}, // (subrame number 9) +{0xa1, -1, 1, 0, 768, 0, 2, 6, 2}, // (subrame number 8,9) +{0xa1, -1, 1, 0, 528, 0, 1, 6, 2}, // (subrame number 4,9) +{0xa1, -1, 1, 0, 640, 7, 1, 3, 2}, // (subrame number 7,9) +{0xa1, -1, 1, 0, 792, 0, 1, 6, 2}, // (subrame number 3,4,8,9) +{0xa1, -1, 1, 0, 792, 0, 2, 6, 2}, // (subrame number 3,4,8,9) +{0xa1, -1, 1, 0, 682, 0, 1, 6, 2}, // (subrame number 1,3,5,7,9) +{0xa1, -1, 1, 0, 1023, 7, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9) +{0xa2, -1, 16, 1, 512, 0, 2, 3, 4}, // (subrame number 9) +{0xa2, -1, 8, 1, 512, 0, 2, 3, 4}, // (subrame number 9) +{0xa2, -1, 4, 1, 512, 0, 1, 3, 4}, // (subrame number 9) +{0xa2, -1, 2, 1, 640, 0, 1, 3, 4}, // (subrame number 7,9) +{0xa2, -1, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9) +{0xa2, -1, 2, 1, 640, 9, 1, 1, 4}, // (subrame number 7,9) +{0xa2, -1, 2, 1, 528, 9, 1, 1, 4}, // (subrame number 4,9) +{0xa2, -1, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9) +{0xa2, -1, 16, 1, 924, 0, 1, 3, 4}, // (subrame number 2,3,4,7,8,9) +{0xa2, -1, 1, 0, 4, 0, 1, 3, 4}, // (subrame number 2) +{0xa2, -1, 1, 0, 128, 0, 1, 3, 4}, // (subrame number 7) +{0xa2, -1, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9) +{0xa2, -1, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9) +{0xa2, -1, 1, 0, 512, 9, 1, 1, 4}, // (subrame number 9) +{0xa2, -1, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9) +{0xa2, -1, 1, 0, 132, 0, 1, 3, 4}, // (subrame number 2,7) +{0xa2, -1, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9) +{0xa2, -1, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9) +{0xa2, -1, 1, 0, 640, 9, 1, 1, 4}, // (subrame number 7,9) +{0xa2, -1, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9) +{0xa2, -1, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9) +{0xa2, -1, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9) +{0xa2, -1, 1, 0, 1023, 9, 1, 1, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9) +{0xa3, -1, 16, 1, 512, 0, 2, 2, 6}, // (subrame number 9) +{0xa3, -1, 8, 1, 512, 0, 2, 2, 6}, // (subrame number 9) +{0xa3, -1, 4, 1, 512, 0, 1, 2, 6}, // (subrame number 9) +{0xa3, -1, 2, 1, 528, 7, 1, 1, 6}, // (subrame number 4,9) +{0xa3, -1, 2, 1, 640, 7, 1, 1, 6}, // (subrame number 7,9) +{0xa3, -1, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9) +{0xa3, -1, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9) +{0xa3, -1, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9) +{0xa3, -1, 2, 1, 924, 0, 1, 2, 6}, // (subrame number 2,3,4,7,8,9) +{0xa3, -1, 1, 0, 4, 0, 1, 2, 6}, // (subrame number 2) +{0xa3, -1, 1, 0, 128, 0, 1, 2, 6}, // (subrame number 7) +{0xa3, -1, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9) +{0xa3, -1, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9) +{0xa3, -1, 1, 0, 512, 7, 1, 1, 6}, // (subrame number 9) +{0xa3, -1, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9) +{0xa3, -1, 1, 0, 132, 0, 1, 2, 6}, // (subrame number 2,7) +{0xa3, -1, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9) +{0xa3, -1, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9) +{0xa3, -1, 1, 0, 640, 7, 1, 1, 6}, // (subrame number 7,9) +{0xa3, -1, 1, 0, 792, 0, 1, 2, 6}, // (subrame number 3,4,8,9) +{0xa3, -1, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9) +{0xa3, -1, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9) +{0xa3, -1, 1, 0, 1023, 7, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9) +{0xb1, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9) +{0xb1, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9) +{0xb1, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9) +{0xb1, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9) +{0xb1, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9) +{0xb1, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9) +{0xb1, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9) +{0xb1, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9) +{0xb1, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9) +{0xb1, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9) +{0xb1, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9) +{0xb1, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9) +{0xb4, -1, 16, 1, 512, 0, 2, 1, 12}, // (subrame number 9) +{0xb4, -1, 8, 1, 512, 0, 2, 1, 12}, // (subrame number 9) +{0xb4, -1, 4, 1, 512, 2, 1, 1, 12}, // (subrame number 9) +{0xb4, -1, 2, 1, 512, 0, 1, 1, 12}, // (subrame number 9) +{0xb4, -1, 2, 1, 512, 2, 1, 1, 12}, // (subrame number 9) +{0xb4, -1, 2, 1, 640, 2, 1, 1, 12}, // (subrame number 7,9) +{0xb4, -1, 2, 1, 528, 2, 1, 1, 12}, // (subrame number 4,9) +{0xb4, -1, 2, 1, 528, 0, 2, 1, 12}, // (subrame number 4,9) +{0xb4, -1, 2, 1, 768, 0, 2, 1, 12}, // (subrame number 8,9) +{0xb4, -1, 2, 1, 924, 0, 1, 1, 12}, // (subrame number 2,3,4,7,8,9) +{0xb4, -1, 1, 0, 2, 0, 1, 1, 12}, // (subrame number 1) +{0xb4, -1, 1, 0, 4, 0, 1, 1, 12}, // (subrame number 2) +{0xb4, -1, 1, 0, 16, 0, 1, 1, 12}, // (subrame number 4) +{0xb4, -1, 1, 0, 128, 0, 1, 1, 12}, // (subrame number 7) +{0xb4, -1, 1, 0, 512, 0, 1, 1, 12}, // (subrame number 9) +{0xb4, -1, 1, 0, 512, 2, 1, 1, 12}, // (subrame number 9) +{0xb4, -1, 1, 0, 512, 0, 2, 1, 12}, // (subrame number 9) +{0xb4, -1, 1, 0, 528, 2, 1, 1, 12}, // (subrame number 4,9) +{0xb4, -1, 1, 0, 640, 2, 1, 1, 12}, // (subrame number 7,9) +{0xb4, -1, 1, 0, 768, 0, 2, 1, 12}, // (subrame number 8,9) +{0xb4, -1, 1, 0, 792, 2, 1, 1, 12}, // (subrame number 3,4,8,9) +{0xb4, -1, 1, 0, 682, 2, 1, 1, 12}, // (subrame number 1,3,5,7,9) +{0xb4, -1, 1, 0, 1023, 0, 2, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9) +{0xb4, -1, 1, 0, 1023, 2, 1, 1, 12}, // (subrame number 0,1,2,3,4,5,6,7,8,9) +{0xc0, -1, 16, 1, 512, 2, 2, 6, 2}, // (subrame number 9) +{0xc0, -1, 8, 1, 512, 2, 2, 6, 2}, // (subrame number 9) +{0xc0, -1, 4, 1, 512, 2, 1, 6, 2}, // (subrame number 9) +{0xc0, -1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9) +{0xc0, -1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9) +{0xc0, -1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9) +{0xc0, -1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9) +{0xc0, -1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9) +{0xc0, -1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9) +{0xc0, -1, 2, 1, 924, 2, 1, 6, 2}, // (subrame number 2,3,4,7,8,9) +{0xc0, -1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9) +{0xc0, -1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9) +{0xc0, -1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9) +{0xc0, -1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9) +{0xc0, -1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9) +{0xc0, -1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9) +{0xc0, -1, 1, 0, 792, 2, 1, 6, 2}, // (subrame number 3,4,8,9) +{0xc0, -1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9) +{0xc0, -1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9) +{0xc0, -1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9) +{0xc2, -1, 16, 1, 512, 2, 2, 2, 6}, // (subrame number 9) +{0xc2, -1, 8, 1, 512, 2, 2, 2, 6}, // (subrame number 9) +{0xc2, -1, 4, 1, 512, 2, 1, 2, 6}, // (subrame number 9) +{0xc2, -1, 2, 1, 512, 2, 1, 2, 6}, // (subrame number 9) +{0xc2, -1, 2, 1, 768, 2, 2, 2, 6}, // (subrame number 8,9) +{0xc2, -1, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9) +{0xc2, -1, 2, 1, 640, 8, 1, 1, 6}, // (subrame number 7,9) +{0xc2, -1, 2, 1, 528, 8, 1, 1, 6}, // (subrame number 4,9) +{0xc2, -1, 2, 1, 528, 2, 2, 2, 6}, // (subrame number 4,9) +{0xc2, -1, 2, 1, 924, 2, 1, 2, 6}, // (subrame number 2,3,4,7,8,9) +{0xc2, -1, 8, 1, 512, 8, 2, 1, 6}, // (subrame number 9) +{0xc2, -1, 4, 1, 512, 8, 1, 1, 6}, // (subrame number 9) +{0xc2, -1, 1, 0, 512, 2, 2, 2, 6}, // (subrame number 9) +{0xc2, -1, 1, 0, 512, 8, 1, 1, 6}, // (subrame number 9) +{0xc2, -1, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9) +{0xc2, -1, 1, 0, 768, 2, 2, 2, 6}, // (subrame number 8,9) +{0xc2, -1, 1, 0, 528, 2, 1, 2, 6}, // (subrame number 4,9) +{0xc2, -1, 1, 0, 640, 8, 1, 1, 6}, // (subrame number 7,9) +{0xc2, -1, 1, 0, 792, 2, 1, 2, 6}, // (subrame number 3,4,8,9) +{0xc2, -1, 1, 0, 792, 2, 2, 2, 6}, // (subrame number 3,4,8,9) +{0xc2, -1, 1, 0, 682, 2, 1, 2, 6}, // (subrame number 1,3,5,7,9) +{0xc2, -1, 1, 0, 1023, 8, 1, 1, 6}, // (subrame number 0,1,2,3,4,5,6,7,8,9) +{0xa1, 0xb1, 2, 1, 512, 2, 1, 6, 2}, // (subrame number 9) +{0xa1, 0xb1, 2, 1, 528, 8, 1, 3, 2}, // (subrame number 4,9) +{0xa1, 0xb1, 2, 1, 640, 8, 1, 3, 2}, // (subrame number 7,9) +{0xa1, 0xb1, 2, 1, 640, 2, 1, 6, 2}, // (subrame number 7,9) +{0xa1, 0xb1, 2, 1, 528, 2, 2, 6, 2}, // (subrame number 4,9) +{0xa1, 0xb1, 2, 1, 768, 2, 2, 6, 2}, // (subrame number 8,9) +{0xa1, 0xb1, 1, 0, 512, 2, 2, 6, 2}, // (subrame number 9) +{0xa1, 0xb1, 1, 0, 512, 8, 1, 3, 2}, // (subrame number 9) +{0xa1, 0xb1, 1, 0, 512, 2, 1, 6, 2}, // (subrame number 9) +{0xa1, 0xb1, 1, 0, 768, 2, 2, 6, 2}, // (subrame number 8,9) +{0xa1, 0xb1, 1, 0, 528, 2, 1, 6, 2}, // (subrame number 4,9) +{0xa1, 0xb1, 1, 0, 640, 8, 1, 3, 2}, // (subrame number 7,9) +{0xa1, 0xb1, 1, 0, 792, 2, 2, 6, 2}, // (subrame number 3,4,8,9) +{0xa1, 0xb1, 1, 0, 682, 2, 1, 6, 2}, // (subrame number 1,3,5,7,9) +{0xa1, 0xb1, 1, 0, 1023, 8, 1, 3, 2}, // (subrame number 0,1,2,3,4,5,6,7,8,9) +{0xa2, 0xb2, 2, 1, 512, 0, 1, 3, 4}, // (subrame number 9) +{0xa2, 0xb2, 2, 1, 528, 6, 1, 2, 4}, // (subrame number 4,9) +{0xa2, 0xb2, 2, 1, 640, 6, 1, 2, 4}, // (subrame number 7,9) +{0xa2, 0xb2, 2, 1, 528, 0, 2, 3, 4}, // (subrame number 4,9) +{0xa2, 0xb2, 2, 1, 768, 0, 2, 3, 4}, // (subrame number 8,9) +{0xa2, 0xb2, 1, 0, 512, 0, 2, 3, 4}, // (subrame number 9) +{0xa2, 0xb2, 1, 0, 512, 6, 1, 2, 4}, // (subrame number 9) +{0xa2, 0xb2, 1, 0, 512, 0, 1, 3, 4}, // (subrame number 9) +{0xa2, 0xb2, 1, 0, 768, 0, 2, 3, 4}, // (subrame number 8,9) +{0xa2, 0xb2, 1, 0, 528, 0, 1, 3, 4}, // (subrame number 4,9) +{0xa2, 0xb2, 1, 0, 640, 6, 1, 2, 4}, // (subrame number 7,9) +{0xa2, 0xb2, 1, 0, 792, 0, 1, 3, 4}, // (subrame number 3,4,8,9) +{0xa2, 0xb2, 1, 0, 792, 0, 2, 3, 4}, // (subrame number 3,4,8,9) +{0xa2, 0xb2, 1, 0, 682, 0, 1, 3, 4}, // (subrame number 1,3,5,7,9) +{0xa2, 0xb2, 1, 0, 1023, 6, 1, 2, 4}, // (subrame number 0,1,2,3,4,5,6,7,8,9) +{0xa3, 0xb3, 2, 1, 512, 0, 1, 2, 6}, // (subrame number 9) +{0xa3, 0xb3, 2, 1, 528, 2, 1, 2, 6}, // (subrame number 4,9) +{0xa3, 0xb3, 2, 1, 640, 0, 1, 2, 6}, // (subrame number 7,9) +{0xa3, 0xb3, 2, 1, 640, 2, 1, 2, 6}, // (subrame number 7,9) +{0xa3, 0xb3, 2, 1, 528, 0, 2, 2, 6}, // (subrame number 4,9) +{0xa3, 0xb3, 2, 1, 768, 0, 2, 2, 6}, // (subrame number 8,9) +{0xa3, 0xb3, 1, 0, 512, 0, 2, 2, 6}, // (subrame number 9) +{0xa3, 0xb3, 1, 0, 512, 2, 1, 2, 6}, // (subrame number 9) +{0xa3, 0xb3, 1, 0, 512, 0, 1, 2, 6}, // (subrame number 9) +{0xa3, 0xb3, 1, 0, 768, 0, 2, 2, 6}, // (subrame number 8,9) +{0xa3, 0xb3, 1, 0, 528, 0, 1, 2, 6}, // (subrame number 4,9) +{0xa3, 0xb3, 1, 0, 640, 2, 1, 2, 6}, // (subrame number 7,9) +{0xa3, 0xb3, 1, 0, 792, 0, 2, 2, 6}, // (subrame number 3,4,8,9) +{0xa3, 0xb3, 1, 0, 682, 0, 1, 2, 6}, // (subrame number 1,3,5,7,9) +{0xa3, 0xb3, 1, 0, 1023, 2, 1, 2, 6} // (subrame number 0,1,2,3,4,5,6,7,8,9) +}; +// Table 6.3.3.2-4: Random access configurations for FR2 and unpaired spectrum +int64_t table_6_3_3_2_4_prachConfig_Index [256][10] = { +//format, format, x, y, y, SFN_nbr, star_symb, slots_sfn, occ_slot, duration +{0xa1, -1, 16, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, -1, 16, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa1, -1, 8, 1, 2, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39) +{0xa1, -1, 8, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, -1, 8, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa1, -1, 4, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, -1, 4, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, -1, 4, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa1, -1, 2, 1, -1, 551911719040, 0, 2, 6, 2}, // (subframe number :7,15,23,31,39) +{0xa1, -1, 2, 1, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, -1, 2, 1, -1, 567489872400, 0, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, -1, 2, 1, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa1, -1, 1, 0, -1, 549756338176, 7, 1, 3, 2}, // (subframe number :19,39) +{0xa1, -1, 1, 0, -1, 168, 0, 1, 6, 2}, // (subframe number :3,5,7) +{0xa1, -1, 1, 0, -1, 567489331200, 7, 1, 3, 2}, // (subframe number :24,29,34,39) +{0xa1, -1, 1, 0, -1, 550293209600, 7, 2, 3, 2}, // (subframe number :9,19,29,39) +{0xa1, -1, 1, 0, -1, 687195422720, 0, 1, 6, 2}, // (subframe number :17,19,37,39) +{0xa1, -1, 1, 0, -1, 550293209600, 0, 2, 6, 2}, // (subframe number :9,19,29,39) +{0xa1, -1, 1, 0, -1, 567489872400, 0, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, -1, 1, 0, -1, 567489872400, 7, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, -1, 1, 0, -1, 10920, 7, 1, 3, 2}, // (subframe number :3,5,7,9,11,13) +{0xa1, -1, 1, 0, -1, 586405642240, 7, 1, 3, 2}, // (subframe number :23,27,31,35,39) +{0xa1, -1, 1, 0, -1, 551911719040, 0, 1, 6, 2}, // (subframe number :7,15,23,31,39) +{0xa1, -1, 1, 0, -1, 586405642240, 0, 1, 6, 2}, // (subframe number :23,27,31,35,39) +{0xa1, -1, 1, 0, -1, 965830828032, 7, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39) +{0xa1, -1, 1, 0, -1, 586406201480, 7, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa1, -1, 1, 0, -1, 586406201480, 0, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa1, -1, 1, 0, -1, 733007751850, 0, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39) +{0xa1, -1, 1, 0, -1, 1099511627775, 7, 1, 3, 2}, // (subframe number :0,1,2,…,39) +{0xa2, -1, 16, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, -1, 16, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa2, -1, 8, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, -1, 8, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa2, -1, 8, 1, 2, 550293209600, 0, 2, 3, 4}, // (subframe number :9,19,29,39) +{0xa2, -1, 4, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, -1, 4, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, -1, 4, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa2, -1, 2, 1, -1, 551911719040, 0, 2, 3, 4}, // (subframe number :7,15,23,31,39) +{0xa2, -1, 2, 1, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, -1, 2, 1, -1, 567489872400, 0, 2, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, -1, 2, 1, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa2, -1, 1, 0, -1, 549756338176, 5, 1, 2, 4}, // (subframe number :19,39) +{0xa2, -1, 1, 0, -1, 168, 0, 1, 3, 4}, // (subframe number :3,5,7) +{0xa2, -1, 1, 0, -1, 567489331200, 5, 1, 2, 4}, // (subframe number :24,29,34,39) +{0xa2, -1, 1, 0, -1, 550293209600, 5, 2, 2, 4}, // (subframe number :9,19,29,39) +{0xa2, -1, 1, 0, -1, 687195422720, 0, 1, 3, 4}, // (subframe number :17,19,37,39) +{0xa2, -1, 1, 0, -1, 550293209600, 0, 2, 3, 4}, // (subframe number :9, 19, 29, 39) +{0xa2, -1, 1, 0, -1, 551911719040, 0, 1, 3, 4}, // (subframe number :7,15,23,31,39) +{0xa2, -1, 1, 0, -1, 586405642240, 5, 1, 2, 4}, // (subframe number :23,27,31,35,39) +{0xa2, -1, 1, 0, -1, 586405642240, 0, 1, 3, 4}, // (subframe number :23,27,31,35,39) +{0xa2, -1, 1, 0, -1, 10920, 5, 1, 2, 4}, // (subframe number :3,5,7,9,11,13) +{0xa2, -1, 1, 0, -1, 10920, 0, 1, 3, 4}, // (subframe number :3,5,7,9,11,13) +{0xa2, -1, 1, 0, -1, 567489872400, 5, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, -1, 1, 0, -1, 567489872400, 0, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, -1, 1, 0, -1, 965830828032, 5, 2, 2, 4}, // (subframe number :13,14,15, 29,30,31,37,38,39) +{0xa2, -1, 1, 0, -1, 586406201480, 5, 1, 2, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa2, -1, 1, 0, -1, 586406201480, 0, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa2, -1, 1, 0, -1, 733007751850, 0, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39) +{0xa2, -1, 1, 0, -1, 1099511627775, 5, 1, 2, 4}, // (subframe number :0,1,2,…,39) +{0xa3, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa3, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa3, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39) +{0xa3, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa3, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa3, -1, 1, 0, -1, 549756338176, 7, 1, 1, 6}, // (subframe number :19,39) +{0xa3, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7) +{0xa3, -1, 1, 0, -1, 10752, 2, 1, 2, 6}, // (subframe number :9,11,13) +{0xa3, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39) +{0xa3, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39) +{0xa3, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39) +{0xa3, -1, 1, 0, -1, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39) +{0xa3, -1, 1, 0, -1, 551911719040, 0, 1, 2, 6}, // (subframe number :7,15,23,31,39) +{0xa3, -1, 1, 0, -1, 586405642240, 7, 1, 1, 6}, // (subframe number :23,27,31,35,39) +{0xa3, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39) +{0xa3, -1, 1, 0, -1, 10920, 0, 1, 2, 6}, // (subframe number :3,5,7,9,11,13) +{0xa3, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13) +{0xa3, -1, 1, 0, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, -1, 1, 0, -1, 567489872400, 7, 1, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39) +{0xa3, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa3, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa3, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39) +{0xa3, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39) +{0xb1, -1, 16, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb1, -1, 8, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb1, -1, 8, 1, 2, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39) +{0xb1, -1, 4, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb1, -1, 2, 1, -1, 567489872400, 2, 2, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb1, -1, 2, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xb1, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39) +{0xb1, -1, 1, 0, -1, 168, 2, 1, 6, 2}, // (subframe number :3,5,7) +{0xb1, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39) +{0xb1, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39) +{0xb1, -1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39) +{0xb1, -1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39) +{0xb1, -1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39) +{0xb1, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39) +{0xb1, -1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39) +{0xb1, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13) +{0xb1, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb1, -1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb1, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xb1, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39) +{0xb1, -1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xb1, -1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39) +{0xb1, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39) +{0xb4, -1, 16, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb4, -1, 16, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xb4, -1, 8, 1, 2, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb4, -1, 8, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xb4, -1, 8, 1, 2, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39) +{0xb4, -1, 4, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb4, -1, 4, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb4, -1, 4, 1, 2, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xb4, -1, 2, 1, -1, 551911719040, 2, 2, 1, 12}, // (subframe number :7,15,23,31,39) +{0xb4, -1, 2, 1, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb4, -1, 2, 1, -1, 567489872400, 0, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb4, -1, 2, 1, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xb4, -1, 1, 0, -1, 549756338176, 2, 2, 1, 12}, // (subframe number :19, 39) +{0xb4, -1, 1, 0, -1, 687195422720, 0, 1, 1, 12}, // (subframe number :17, 19, 37, 39) +{0xb4, -1, 1, 0, -1, 567489331200, 2, 1, 1, 12}, // (subframe number :24,29,34,39) +{0xb4, -1, 1, 0, -1, 550293209600, 2, 2, 1, 12}, // (subframe number :9,19,29,39) +{0xb4, -1, 1, 0, -1, 550293209600, 0, 2, 1, 12}, // (subframe number :9,19,29,39) +{0xb4, -1, 1, 0, -1, 551911719040, 0, 1, 1, 12}, // (subframe number :7,15,23,31,39) +{0xb4, -1, 1, 0, -1, 551911719040, 0, 2, 1, 12}, // (subframe number :7,15,23,31,39) +{0xb4, -1, 1, 0, -1, 586405642240, 0, 1, 1, 12}, // (subframe number :23,27,31,35,39) +{0xb4, -1, 1, 0, -1, 586405642240, 2, 2, 1, 12}, // (subframe number :23,27,31,35,39) +{0xb4, -1, 1, 0, -1, 698880, 0, 1, 1, 12}, // (subframe number :9,11,13,15,17,19) +{0xb4, -1, 1, 0, -1, 10920, 2, 1, 1, 12}, // (subframe number :3,5,7,9,11,13) +{0xb4, -1, 1, 0, -1, 567489872400, 0, 1, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb4, -1, 1, 0, -1, 567489872400, 2, 2, 1, 12}, // (subframe number :4,9,14,19,24,29,34,39) +{0xb4, -1, 1, 0, -1, 965830828032, 2, 2, 1, 12}, // (subframe number :13,14,15, 29,30,31,37,38,39) +{0xb4, -1, 1, 0, -1, 586406201480, 0, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xb4, -1, 1, 0, -1, 586406201480, 2, 1, 1, 12}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xb4, -1, 1, 0, -1, 44739240, 2, 1, 1, 12}, // (subframe number :3, 5, 7, …, 23,25) +{0xb4, -1, 1, 0, -1, 44739240, 0, 2, 1, 12}, // (subframe number :3, 5, 7, …, 23,25) +{0xb4, -1, 1, 0, -1, 733007751850, 0, 1, 1, 12}, // (subframe number :1,3,5,7,…,37,39) +{0xb4, -1, 1, 0, -1, 1099511627775, 2, 1, 1, 12}, // (subframe number :0, 1, 2,…, 39) +{0xc0, -1, 16, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc0, -1, 16, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc0, -1, 8, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc0, -1, 8, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc0, -1, 8, 1, 2, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39) +{0xc0, -1, 4, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc0, -1, 4, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc0, -1, 4, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc0, -1, 2, 1, -1, 551911719040, 0, 2, 7, 2}, // (subframe number :7,15,23,31,39) +{0xc0, -1, 2, 1, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc0, -1, 2, 1, -1, 567489872400, 0, 2, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc0, -1, 2, 1, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc0, -1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39) +{0xc0, -1, 1, 0, -1, 168, 0, 1, 7, 2}, // (subframe number :3,5,7) +{0xc0, -1, 1, 0, -1, 567489331200, 8, 1, 3, 2}, // (subframe number :24,29,34,39) +{0xc0, -1, 1, 0, -1, 550293209600, 8, 2, 3, 2}, // (subframe number :9,19,29,39) +{0xc0, -1, 1, 0, -1, 687195422720, 0, 1, 7, 2}, // (subframe number :17,19,37,39) +{0xc0, -1, 1, 0, -1, 550293209600, 0, 2, 7, 2}, // (subframe number :9,19,29,39) +{0xc0, -1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39) +{0xc0, -1, 1, 0, -1, 551911719040, 0, 1, 7, 2}, // (subframe number :7,15,23,31,39) +{0xc0, -1, 1, 0, -1, 586405642240, 0, 1, 7, 2}, // (subframe number :23,27,31,35,39) +{0xc0, -1, 1, 0, -1, 10920, 8, 1, 3, 2}, // (subframe number :3,5,7,9,11,13) +{0xc0, -1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc0, -1, 1, 0, -1, 567489872400, 0, 1, 7, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc0, -1, 1, 0, -1, 965830828032, 8, 2, 3, 2}, // (subframe number :13,14,15, 29,30,31,37,38,39) +{0xc0, -1, 1, 0, -1, 586406201480, 8, 1, 3, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc0, -1, 1, 0, -1, 586406201480, 0, 1, 7, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc0, -1, 1, 0, -1, 733007751850, 0, 1, 7, 2}, // (subframe number :1,3,5,7,…,37,39) +{0xc0, -1, 1, 0, -1, 1099511627775, 8, 1, 3, 2}, // (subframe number :0,1,2,…,39) +{0xc2, -1, 16, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc2, -1, 16, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc2, -1, 8, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc2, -1, 8, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc2, -1, 8, 1, 2, 550293209600, 0, 2, 2, 6}, // (subframe number :9,19,29,39) +{0xc2, -1, 4, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc2, -1, 4, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc2, -1, 4, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc2, -1, 2, 1, -1, 551911719040, 2, 2, 2, 6}, // (subframe number :7,15,23,31,39) +{0xc2, -1, 2, 1, -1, 567489872400, 0, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc2, -1, 2, 1, -1, 567489872400, 0, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc2, -1, 2, 1, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc2, -1, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39) +{0xc2, -1, 1, 0, -1, 168, 0, 1, 2, 6}, // (subframe number :3,5,7) +{0xc2, -1, 1, 0, -1, 567489331200, 7, 1, 1, 6}, // (subframe number :24,29,34,39) +{0xc2, -1, 1, 0, -1, 550293209600, 7, 2, 1, 6}, // (subframe number :9,19,29,39) +{0xc2, -1, 1, 0, -1, 687195422720, 0, 1, 2, 6}, // (subframe number :17,19,37,39) +{0xc2, -1, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39) +{0xc2, -1, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39) +{0xc2, -1, 1, 0, -1, 10920, 7, 1, 1, 6}, // (subframe number :3,5,7,9,11,13) +{0xc2, -1, 1, 0, -1, 586405642240, 7, 2, 1, 6}, // (subframe number :23,27,31,35,39) +{0xc2, -1, 1, 0, -1, 586405642240, 0, 1, 2, 6}, // (subframe number :23,27,31,35,39) +{0xc2, -1, 1, 0, -1, 567489872400, 7, 2, 1, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc2, -1, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xc2, -1, 1, 0, -1, 965830828032, 7, 2, 1, 6}, // (subframe number :13,14,15, 29,30,31,37,38,39) +{0xc2, -1, 1, 0, -1, 586406201480, 7, 1, 1, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc2, -1, 1, 0, -1, 586406201480, 0, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xc2, -1, 1, 0, -1, 733007751850, 0, 1, 2, 6}, // (subframe number :1,3,5,7,…,37,39) +{0xc2, -1, 1, 0, -1, 1099511627775, 7, 1, 1, 6}, // (subframe number :0,1,2,…,39) +{0xa1, 0xb1, 16, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, 0xb1, 16, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa1, 0xb1, 8, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, 0xb1, 8, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa1, 0xb1, 4, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, 0xb1, 4, 1, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa1, 0xb1, 2, 1, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, 0xb1, 1, 0, -1, 549756338176, 8, 1, 3, 2}, // (subframe number :19,39) +{0xa1, 0xb1, 1, 0, -1, 550293209600, 8, 1, 3, 2}, // (subframe number :9,19,29,39) +{0xa1, 0xb1, 1, 0, -1, 687195422720, 2, 1, 6, 2}, // (subframe number :17,19,37,39) +{0xa1, 0xb1, 1, 0, -1, 550293209600, 2, 2, 6, 2}, // (subframe number :9,19,29,39) +{0xa1, 0xb1, 1, 0, -1, 586405642240, 8, 1, 3, 2}, // (subframe number :23,27,31,35,39) +{0xa1, 0xb1, 1, 0, -1, 551911719040, 2, 1, 6, 2}, // (subframe number :7,15,23,31,39) +{0xa1, 0xb1, 1, 0, -1, 586405642240, 2, 1, 6, 2}, // (subframe number :23,27,31,35,39) +{0xa1, 0xb1, 1, 0, -1, 567489872400, 8, 1, 3, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, 0xb1, 1, 0, -1, 567489872400, 2, 1, 6, 2}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa1, 0xb1, 1, 0, -1, 586406201480, 2, 1, 6, 2}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa1, 0xb1, 1, 0, -1, 733007751850, 2, 1, 6, 2}, // (subframe number :1,3,5,7,…,37,39) +{0xa2, 0xb2, 16, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, 0xb2, 16, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa2, 0xb2, 8, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, 0xb2, 8, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa2, 0xb2, 4, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, 0xb2, 4, 1, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa2, 0xb2, 2, 1, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, 0xb2, 1, 0, -1, 549756338176, 6, 1, 2, 4}, // (subframe number :19,39) +{0xa2, 0xb2, 1, 0, -1, 550293209600, 6, 1, 2, 4}, // (subframe number :9,19,29,39) +{0xa2, 0xb2, 1, 0, -1, 687195422720, 2, 1, 3, 4}, // (subframe number :17,19,37,39) +{0xa2, 0xb2, 1, 0, -1, 550293209600, 2, 2, 3, 4}, // (subframe number :9,19,29,39) +{0xa2, 0xb2, 1, 0, -1, 586405642240, 6, 1, 2, 4}, // (subframe number :23,27,31,35,39) +{0xa2, 0xb2, 1, 0, -1, 551911719040, 2, 1, 3, 4}, // (subframe number :7,15,23,31,39) +{0xa2, 0xb2, 1, 0, -1, 586405642240, 2, 1, 3, 4}, // (subframe number :23,27,31,35,39) +{0xa2, 0xb2, 1, 0, -1, 567489872400, 6, 1, 2, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, 0xb2, 1, 0, -1, 567489872400, 2, 1, 3, 4}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa2, 0xb2, 1, 0, -1, 586406201480, 2, 1, 3, 4}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa2, 0xb2, 1, 0, -1, 733007751850, 2, 1, 3, 4}, // (subframe number :1,3,5,7,…,37,39) +{0xa3, 0xb3, 16, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, 0xb3, 16, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa3, 0xb3, 8, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, 0xb3, 8, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa3, 0xb3, 4, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, 0xb3, 4, 1, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa3, 0xb3, 2, 1, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, 0xb3, 1, 0, -1, 549756338176, 2, 1, 2, 6}, // (subframe number :19,39) +{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 1, 2, 6}, // (subframe number :9,19,29,39) +{0xa3, 0xb3, 1, 0, -1, 687195422720, 2, 1, 2, 6}, // (subframe number :17,19,37,39) +{0xa3, 0xb3, 1, 0, -1, 550293209600, 2, 2, 2, 6}, // (subframe number :9,19,29,39) +{0xa3, 0xb3, 1, 0, -1, 551911719040, 2, 1, 2, 6}, // (subframe number :7,15,23,31,39) +{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 1, 2, 6}, // (subframe number :23,27,31,35,39) +{0xa3, 0xb3, 1, 0, -1, 586405642240, 2, 2, 2, 6}, // (subframe number :23,27,31,35,39) +{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 1, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, 0xb3, 1, 0, -1, 567489872400, 2, 2, 2, 6}, // (subframe number :4,9,14,19,24,29,34,39) +{0xa3, 0xb3, 1, 0, -1, 586406201480, 2, 1, 2, 6}, // (subframe number :3,7,11,15,19,23,27,31,35,39) +{0xa3, 0xb3, 1, 0, -1, 733007751850, 2, 1, 2, 6} // (subframe number :1,3,5,7,…,37,39) +}; + + +int get_format0(uint8_t index, + uint8_t unpaired){ + + uint16_t format; + if (unpaired) + format = table_6_3_3_2_3_prachConfig_Index[index][0]; + else + format = table_6_3_3_2_2_prachConfig_Index[index][0]; + + return format; +} + + +int get_nr_prach_info_from_index(uint8_t index, + int frame, + int slot, + uint32_t pointa, + uint8_t mu, + uint8_t unpaired, + uint16_t *format, + uint8_t *start_symbol, + uint8_t *N_t_slot, + uint8_t *N_dur) { + + int x,y; + int64_t s_map; + uint8_t format2 = 0xff; + + if (pointa > 2016666) { //FR2 + int y2; + uint8_t slot_60khz; + x = table_6_3_3_2_4_prachConfig_Index[index][2]; + y = table_6_3_3_2_4_prachConfig_Index[index][3]; + y2 = table_6_3_3_2_4_prachConfig_Index[index][4]; + // checking n_sfn mod x = y + if ( (frame%x)==y || (frame%x)==y2 ) { + slot_60khz = slot >> (mu-2); // in table slots are numbered wrt 60kHz + s_map = table_6_3_3_2_4_prachConfig_Index[index][5]; + if ( (s_map>>slot_60khz)&0x01 ) { + if (mu == 3) { + if ( (table_6_3_3_2_4_prachConfig_Index[index][7] == 1) && (slot%2 == 0) ) + return 0; // no prach in even slots @ 120kHz for 1 prach per 60khz slot + } + if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ + *start_symbol = table_6_3_3_2_4_prachConfig_Index[index][6]; + *N_t_slot = table_6_3_3_2_4_prachConfig_Index[index][8]; + *N_dur = table_6_3_3_2_4_prachConfig_Index[index][9]; + if (table_6_3_3_2_4_prachConfig_Index[index][1] != -1) + format2 = (uint8_t) table_6_3_3_2_4_prachConfig_Index[index][1]; + *format = ((uint8_t) table_6_3_3_2_4_prachConfig_Index[index][0]) | (format2<<8); + LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame, + slot, + index, + pointa, + mu, + unpaired, + *start_symbol, + *N_t_slot, + *N_dur); + } + return 1; + } + else + return 0; // no prach in current slot + } + else + return 0; // no prach in current frame + } + else { + uint8_t subframe; + if (unpaired) { + x = table_6_3_3_2_3_prachConfig_Index[index][2]; + y = table_6_3_3_2_3_prachConfig_Index[index][3]; + if ( (frame%x)==y ) { + subframe = slot >> mu; + s_map = table_6_3_3_2_3_prachConfig_Index[index][4]; + if ( (s_map>>subframe)&0x01 ) { + if (mu == 1) { + if ( (table_6_3_3_2_3_prachConfig_Index[index][6] == 1) && (slot%2 == 0) ) + return 0; // no prach in even slots @ 30kHz for 1 prach per subframe + } + if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ + *start_symbol = table_6_3_3_2_3_prachConfig_Index[index][5]; + *N_t_slot = table_6_3_3_2_3_prachConfig_Index[index][7]; + *N_dur = table_6_3_3_2_3_prachConfig_Index[index][8]; + if (table_6_3_3_2_3_prachConfig_Index[index][1] != -1) + format2 = (uint8_t) table_6_3_3_2_3_prachConfig_Index[index][1]; + *format = ((uint8_t) table_6_3_3_2_3_prachConfig_Index[index][0]) | (format2<<8); + LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame, + slot, + index, + pointa, + mu, + unpaired, + *start_symbol, + *N_t_slot, + *N_dur); + } + return 1; + } + else + return 0; // no prach in current slot + } + else + return 0; // no prach in current frame + } + else { // FDD + x = table_6_3_3_2_2_prachConfig_Index[index][2]; + y = table_6_3_3_2_2_prachConfig_Index[index][3]; + if ( (frame%x)==y ) { + subframe = slot >> mu; + s_map = table_6_3_3_2_2_prachConfig_Index[index][4]; + if ( (s_map>>subframe)&0x01 ) { + if (mu == 1) { + if ( (table_6_3_3_2_2_prachConfig_Index[index][6] == 1) && (slot%2 == 0) ) + return 0; // no prach in even slots @ 30kHz for 1 prach per subframe + } + if (start_symbol != NULL && N_t_slot != NULL && N_dur != NULL && format != NULL){ + *start_symbol = table_6_3_3_2_2_prachConfig_Index[index][5]; + *N_t_slot = table_6_3_3_2_2_prachConfig_Index[index][7]; + *N_dur = table_6_3_3_2_2_prachConfig_Index[index][8]; + if (table_6_3_3_2_2_prachConfig_Index[index][1] != -1) + format2 = (uint8_t) table_6_3_3_2_2_prachConfig_Index[index][1]; + *format = ((uint8_t) table_6_3_3_2_2_prachConfig_Index[index][0]) | (format2<<8); + LOG_D(MAC,"Frame %d slot %d: Getting PRACH info from index %d absoluteFrequencyPointA %u mu %u frame_type %u start_symbol %u N_t_slot %u N_dur %u \n", frame, + slot, + index, + pointa, + mu, + unpaired, + *start_symbol, + *N_t_slot, + *N_dur); + } + return 1; + } + else + return 0; // no prach in current slot + } + else + return 0; // no prach in current frame + } + } +} + +//Table 6.3.3.1-3: Mapping from logical index i to sequence number u for preamble formats with L_RA = 839 +uint16_t table_63313[838] = { +129, 710, 140, 699, 120, 719, 210, 629, 168, 671, 84 , 755, 105, 734, 93 , 746, 70 , 769, 60 , 779, +2 , 837, 1 , 838, 56 , 783, 112, 727, 148, 691, 80 , 759, 42 , 797, 40 , 799, 35 , 804, 73 , 766, +146, 693, 31 , 808, 28 , 811, 30 , 809, 27 , 812, 29 , 810, 24 , 815, 48 , 791, 68 , 771, 74 , 765, +178, 661, 136, 703, 86 , 753, 78 , 761, 43 , 796, 39 , 800, 20 , 819, 21 , 818, 95 , 744, 202, 637, +190, 649, 181, 658, 137, 702, 125, 714, 151, 688, 217, 622, 128, 711, 142, 697, 122, 717, 203, 636, +118, 721, 110, 729, 89 , 750, 103, 736, 61 , 778, 55 , 784, 15 , 824, 14 , 825, 12 , 827, 23 , 816, +34 , 805, 37 , 802, 46 , 793, 207, 632, 179, 660, 145, 694, 130, 709, 223, 616, 228, 611, 227, 612, +132, 707, 133, 706, 143, 696, 135, 704, 161, 678, 201, 638, 173, 666, 106, 733, 83 , 756, 91 , 748, +66 , 773, 53 , 786, 10 , 829, 9 , 830, 7 , 832, 8 , 831, 16 , 823, 47 , 792, 64 , 775, 57 , 782, +104, 735, 101, 738, 108, 731, 208, 631, 184, 655, 197, 642, 191, 648, 121, 718, 141, 698, 149, 690, +216, 623, 218, 621, 152, 687, 144, 695, 134, 705, 138, 701, 199, 640, 162, 677, 176, 663, 119, 720, +158, 681, 164, 675, 174, 665, 171, 668, 170, 669, 87 , 752, 169, 670, 88 , 751, 107, 732, 81 , 758, +82 , 757, 100, 739, 98 , 741, 71 , 768, 59 , 780, 65 , 774, 50 , 789, 49 , 790, 26 , 813, 17 , 822, +13 , 826, 6 , 833, 5 , 834, 33 , 806, 51 , 788, 75 , 764, 99 , 740, 96 , 743, 97 , 742, 166, 673, +172, 667, 175, 664, 187, 652, 163, 676, 185, 654, 200, 639, 114, 725, 189, 650, 115, 724, 194, 645, +195, 644, 192, 647, 182, 657, 157, 682, 156, 683, 211, 628, 154, 685, 123, 716, 139, 700, 212, 627, +153, 686, 213, 626, 215, 624, 150, 689, 225, 614, 224, 615, 221, 618, 220, 619, 127, 712, 147, 692, +124, 715, 193, 646, 205, 634, 206, 633, 116, 723, 160, 679, 186, 653, 167, 672, 79 , 760, 85 , 754, +77 , 762, 92 , 747, 58 , 781, 62 , 777, 69 , 770, 54 , 785, 36 , 803, 32 , 807, 25 , 814, 18 , 821, +11 , 828, 4 , 835, 3 , 836, 19 , 820, 22 , 817, 41 , 798, 38 , 801, 44 , 795, 52 , 787, 45 , 794, +63 , 776, 67 , 772, 72 , 767, 76 , 763, 94 , 745, 102, 737, 90 , 749, 109, 730, 165, 674, 111, 728, +209, 630, 204, 635, 117, 722, 188, 651, 159, 680, 198, 641, 113, 726, 183, 656, 180, 659, 177, 662, +196, 643, 155, 684, 214, 625, 126, 713, 131, 708, 219, 620, 222, 617, 226, 613, 230, 609, 232, 607, +262, 577, 252, 587, 418, 421, 416, 423, 413, 426, 411, 428, 376, 463, 395, 444, 283, 556, 285, 554, +379, 460, 390, 449, 363, 476, 384, 455, 388, 451, 386, 453, 361, 478, 387, 452, 360, 479, 310, 529, +354, 485, 328, 511, 315, 524, 337, 502, 349, 490, 335, 504, 324, 515, 323, 516, 320, 519, 334, 505, +359, 480, 295, 544, 385, 454, 292, 547, 291, 548, 381, 458, 399, 440, 380, 459, 397, 442, 369, 470, +377, 462, 410, 429, 407, 432, 281, 558, 414, 425, 247, 592, 277, 562, 271, 568, 272, 567, 264, 575, +259, 580, 237, 602, 239, 600, 244, 595, 243, 596, 275, 564, 278, 561, 250, 589, 246, 593, 417, 422, +248, 591, 394, 445, 393, 446, 370, 469, 365, 474, 300, 539, 299, 540, 364, 475, 362, 477, 298, 541, +312, 527, 313, 526, 314, 525, 353, 486, 352, 487, 343, 496, 327, 512, 350, 489, 326, 513, 319, 520, +332, 507, 333, 506, 348, 491, 347, 492, 322, 517, 330, 509, 338, 501, 341, 498, 340, 499, 342, 497, +301, 538, 366, 473, 401, 438, 371, 468, 408, 431, 375, 464, 249, 590, 269, 570, 238, 601, 234, 605, +257, 582, 273, 566, 255, 584, 254, 585, 245, 594, 251, 588, 412, 427, 372, 467, 282, 557, 403, 436, +396, 443, 392, 447, 391, 448, 382, 457, 389, 450, 294, 545, 297, 542, 311, 528, 344, 495, 345, 494, +318, 521, 331, 508, 325, 514, 321, 518, 346, 493, 339, 500, 351, 488, 306, 533, 289, 550, 400, 439, +378, 461, 374, 465, 415, 424, 270, 569, 241, 598, 231, 608, 260, 579, 268, 571, 276, 563, 409, 430, +398, 441, 290, 549, 304, 535, 308, 531, 358, 481, 316, 523, 293, 546, 288, 551, 284, 555, 368, 471, +253, 586, 256, 583, 263, 576, 242, 597, 274, 565, 402, 437, 383, 456, 357, 482, 329, 510, 317, 522, +307, 532, 286, 553, 287, 552, 266, 573, 261, 578, 236, 603, 303, 536, 356, 483, 355, 484, 405, 434, +404, 435, 406, 433, 235, 604, 267, 572, 302, 537, 309, 530, 265, 574, 233, 606, 367, 472, 296, 543, +336, 503, 305, 534, 373, 466, 280, 559, 279, 560, 419, 420, 240, 599, 258, 581, 229, 610 +}; + +uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, + uint8_t nb_preambles, + uint8_t unpaired) { + + uint8_t config_index = rach_config->rach_ConfigGeneric.prach_ConfigurationIndex; + uint8_t ncs_index = rach_config->rach_ConfigGeneric.zeroCorrelationZoneConfig; + uint16_t format0 = get_format0(config_index, unpaired); + uint16_t NCS = get_NCS(ncs_index, format0, rach_config->restrictedSetConfig); + uint16_t L_ra = (rach_config->prach_RootSequenceIndex.present) ? 139 : 839; + uint16_t r,u,index,q,d_u,n_shift_ra,n_shift_ra_bar,d_start; + uint32_t w; + uint8_t found_preambles = 0; + uint8_t found_sequences = 0; + + if (rach_config->restrictedSetConfig == 0) { + if (NCS == 0) return nb_preambles; + else { + r = L_ra/NCS; + printf(" found_sequences %u\n", (nb_preambles/r)); + return (nb_preambles/r); + } + } + else{ + index = rach_config->prach_RootSequenceIndex.choice.l839; + while (found_preambles < nb_preambles) { + u = table_63313[index%(L_ra-1)]; + + q = 0; + while (((q*u)%L_ra) != 1) q++; + if (q < 420) d_u = q; + else d_u = L_ra - q; + + uint16_t n_group_ra = 0; + if (rach_config->restrictedSetConfig == 1) { + if ( (d_u<280) && (d_u>=NCS) ) { + n_shift_ra = d_u/NCS; + d_start = (d_u<<1) + (n_shift_ra * NCS); + n_group_ra = L_ra/d_start; + n_shift_ra_bar = max(0,(L_ra-(d_u<<1)-(n_group_ra*d_start))/L_ra); + } else if ( (d_u>=280) && (d_u<=((L_ra - NCS)>>1)) ) { + n_shift_ra = (L_ra - (d_u<<1))/NCS; + d_start = L_ra - (d_u<<1) + (n_shift_ra * NCS); + n_group_ra = d_u/d_start; + n_shift_ra_bar = min(n_shift_ra,max(0,(d_u- (n_group_ra*d_start))/NCS)); + } else { + n_shift_ra = 0; + n_shift_ra_bar = 0; + } + w = n_shift_ra*n_group_ra + n_shift_ra_bar; + found_preambles += w; + found_sequences++; + } + else { + AssertFatal(1==0,"Procedure to find nb of sequences for restricted type B not implemented yet"); + } + } + printf(" found_sequences %u\n", found_sequences); + return found_sequences; + } +} + + nr_bandentry_t nr_bandtable[] = { {1, 1920000, 1980000, 2110000, 2170000, 20, 422000, 100}, {2, 1850000, 1910000, 1930000, 1990000, 20, 386000, 100}, @@ -332,13 +1418,19 @@ int32_t get_nr_uldl_offset(int nr_bandP) void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, - int x_overhead) { + int x_overhead, + uint8_t nodata_dmrs, + uint8_t tb_scaling) { LOG_D(MAC, "TBS calculation\n"); nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_rel15 = &pdsch_pdu->pdsch_pdu_rel15; uint16_t N_PRB_oh = x_overhead; - uint8_t N_PRB_DMRS = (pdsch_rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000 + uint8_t N_PRB_DMRS; + if (nodata_dmrs) + N_PRB_DMRS = 12; + else + N_PRB_DMRS = (pdsch_rel15->dmrsConfigType == NFAPI_NR_DMRS_TYPE1)?6:4; //This only works for antenna port 1000 uint8_t N_sh_symb = pdsch_rel15->NrOfSymbols; uint8_t Imcs = pdsch_rel15->mcsIndex[0]; uint16_t N_RE_prime = NR_NB_SC_PER_RB*N_sh_symb - N_PRB_DMRS - N_PRB_oh; @@ -362,6 +1454,7 @@ void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, N_sh_symb, N_PRB_DMRS, N_PRB_oh, + tb_scaling, pdsch_rel15->nrOfLayers)>>3; pdsch_rel15->targetCodeRate[0] = R; diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h similarity index 65% rename from openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h rename to openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h index 6b043963b0..fccc7b8dc7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_common.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.h @@ -32,13 +32,8 @@ #ifndef __LAYER2_NR_MAC_COMMON_H__ #define __LAYER2_NR_MAC_COMMON_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); - -uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw); - -int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols); +#include "NR_PDSCH-Config.h" +#include "NR_ServingCellConfigCommon.h" typedef enum { NR_DL_DCI_FORMAT_1_0 = 0, @@ -67,4 +62,37 @@ typedef enum { NR_RNTI_TPC_SRS } nr_rnti_type_t; +uint16_t config_bandwidth(int mu, int nb_rb, int nr_band); + +void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type); + +uint64_t from_nrarfcn(int nr_bandP, uint8_t scs_index, uint32_t dl_nrarfcn); + +uint32_t to_nrarfcn(int nr_bandP, uint64_t dl_CarrierFreq, uint8_t scs_index, uint32_t bw); + +int16_t fill_dmrs_mask(NR_PDSCH_Config_t *pdsch_Config,int dmrs_TypeA_Position,int NrOfSymbols); + +int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); + +int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); + +int get_nr_prach_info_from_index(uint8_t index, + int frame, + int slot, + uint32_t pointa, + uint8_t mu, + uint8_t unpaired, + uint16_t *format, + uint8_t *start_symbol, + uint8_t *N_t_slot, + uint8_t *N_dur); + +uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, + uint8_t nb_preambles, + uint8_t unpaired); + +int get_format0(uint8_t index, uint8_t unpaired); + +uint16_t get_NCS(uint8_t index, uint16_t format, uint8_t restricted_set_config); + #endif diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_extern.h index 2cfce4766f..c33b0e42e0 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,10 @@ #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 "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 +43,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 +50,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; @@ -60,8 +61,15 @@ extern unsigned short NODE_ID[1]; /* Scheduler */ extern RAN_CONTEXT_t RC; 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; @@ -69,4 +77,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 6e214a670c..38829346c7 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -31,11 +31,9 @@ */ //#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, @@ -151,8 +149,8 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, NR_ServingCellConfigCommon_t *scc = mac->scc; int i; - mac->phy_config.Mod_id = module_id; - mac->phy_config.CC_id = cc_idP; + mac->phy_config.Mod_id = module_id; + mac->phy_config.CC_id = cc_idP; // carrier config @@ -203,12 +201,20 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, } } + lte_frame_type_t frame_type; + uint16_t band; + int32_t offset; + + get_band((cfg->carrier_config.dl_frequency)*1000, + &band, + &offset, + &frame_type); + // cell config cfg->cell_config.phy_cell_id = *scc->physCellId; - cfg->cell_config.frame_duplex_type = 1; - + cfg->cell_config.frame_duplex_type = frame_type; // SSB config cfg->ssb_config.ss_pbch_power = scc->ss_PBCH_BlockPower; @@ -270,6 +276,53 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, LOG_I(PHY,"TDD has been properly configurated\n"); } + // PRACH configuration + + uint8_t nb_preambles = 64; + if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) + nb_preambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; + + cfg->prach_config.prach_sequence_length = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1; + + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) + cfg->prach_config.prach_sub_c_spacing = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; + else + cfg->prach_config.prach_sub_c_spacing = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + cfg->prach_config.restricted_set_config = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig; + + switch (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM) { + case 0 : + cfg->prach_config.num_prach_fd_occasions = 1; + break; + case 1 : + cfg->prach_config.num_prach_fd_occasions = 2; + break; + case 2 : + cfg->prach_config.num_prach_fd_occasions = 4; + break; + case 3 : + cfg->prach_config.num_prach_fd_occasions = 8; + break; + default: + AssertFatal(1==0,"msg1 FDM identifier %ld undefined (0,1,2,3) \n", scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM); + } + + cfg->prach_config.num_prach_fd_occasions_list = (fapi_nr_num_prach_fd_occasions_t *) malloc(cfg->prach_config.num_prach_fd_occasions*sizeof(fapi_nr_num_prach_fd_occasions_t)); + for (i=0; iprach_config.num_prach_fd_occasions; i++) { + cfg->prach_config.num_prach_fd_occasions_list[i].num_prach_fd_occasions = i; + if (cfg->prach_config.prach_sequence_length) + cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l139; + else + cfg->prach_config.num_prach_fd_occasions_list[i].prach_root_sequence_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.choice.l839; + + cfg->prach_config.num_prach_fd_occasions_list[i].k1 = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FrequencyStart; + cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig; + cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, nb_preambles, frame_type); + //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences = ??? + } + + cfg->prach_config.ssb_per_rach = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1; } @@ -292,8 +345,7 @@ int nr_rrc_mac_config_req_ue( if(mibP != NULL){ mac->mib = mibP; // update by every reception } - - + if(cell_group_config != NULL ){ mac->servCellIndex = *cell_group_config->spCellConfig->servCellIndex; if (cell_group_config->spCellConfig->reconfigurationWithSync) { @@ -301,6 +353,7 @@ int nr_rrc_mac_config_req_ue( config_common_ue(mac,module_id,cc_idP); mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti); + } mac->scg = cell_group_config; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index b16464fceb..446fe90f77 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -37,6 +37,21 @@ #include #include #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" +#include "NR_MAC_COMMON/nr_mac_extern.h" + +/* RRC */ #include "NR_DRX-Config.h" #include "NR_SchedulingRequestConfig.h" #include "NR_BSR-Config.h" @@ -48,11 +63,7 @@ #include "NR_PhysicalCellGroupConfig.h" #include "NR_CellGroupConfig.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 "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" + #define NB_NR_UE_MAC_INST 1 /*!\brief Maximum number of logical channl group IDs */ @@ -61,6 +72,7 @@ /*!\brief value for indicating BSR Timer is not running */ #define NR_MAC_UE_BSR_TIMER_NOT_RUNNING (0xFFFF) + typedef enum { SFN_C_MOD_2_EQ_0, SFN_C_MOD_2_EQ_1, @@ -133,10 +145,12 @@ typedef struct { #define MAX_NUM_BWP 2 typedef enum { - RA_IDLE=0, - WAIT_RAR=1, - WAIT_CONTENTION_RESOLUTION=2 + RA_UE_IDLE = 0, + WAIT_RAR = 1, + WAIT_CONTENTION_RESOLUTION = 2, + RA_SUCCEEDED = 3 } RA_state_t; + /*!\brief Top level UE MAC structure */ typedef struct { @@ -144,13 +158,13 @@ typedef struct { NR_CellGroupConfig_t *scg; 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]; @@ -163,14 +177,67 @@ typedef struct { SFN_C_TYPE type0_pdcch_ss_sfn_c; uint32_t type0_pdcch_ss_n_c; uint32_t type0_pdcch_consecutive_slots; + int rnti_type; + + /* PDUs */ + /// Outgoing CCCH pdu for PHY + CCCH_PDU CCCH_pdu; + ULSCH_PDU ulsch_pdu; + + /* Random Access parameters */ /// state of RA procedure RA_state_t ra_state; - /// RA-rnti + /// RA-rnti uint16_t ra_rnti; - /// Temporary CRNTI + /// Temporary CRNTI uint16_t t_crnti; - /// CRNTI + /// CRNTI uint16_t crnti; + /// 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; + /// 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_indicator; + /// 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; + /// Received TPC command (in dB) from RAR + int8_t Msg3_TPC; + /// Flag to monitor if matching RAPID was received in RAR + uint8_t RA_RAPID_found; + /// Flag to monitor if BI was received in RAR + uint8_t RA_BI_found; //// 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 2741c7ff84..d41c34836d 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 @@ -154,6 +152,20 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, uint8_t gNB_index, NR_UL_TIME_ALIGNMENT_t *ul_time_alignment); + +unsigned char nr_generate_ulsch_pdu(uint8_t *sdus_payload, + uint8_t *pdu, + uint8_t num_sdus, + uint16_t *sdu_lengths, + uint8_t *sdu_lcids, + uint8_t power_headroom, + uint16_t crnti, + uint16_t truncated_bsr, + uint16_t short_bsr, + uint16_t long_bsr, + unsigned short post_padding, + uint16_t buflen); + int8_t nr_ue_process_dlsch(module_id_t module_id, int cc_id, uint8_t gNB_index, fapi_nr_dci_indication_t *dci_ind, void *pduP, uint32_t pdu_len); void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_config,int frame,int slot); @@ -170,5 +182,95 @@ 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 +*/ +int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, 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, uint16_t prach_format); + +/* Random Access */ + +/* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x +and fills the PRACH PDU per each FD occasion. +@param module_idP Index of UE instance +@param frameP Frame index +@param slotP Slot index +@returns void +*/ +void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); + +/* \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(module_id_t mod_id, + int CC_id, + frame_t frameP, + uint8_t * dlsch_buffer, + rnti_t * t_crnti, + uint8_t preamble_index, + uint8_t * selected_rar_buffer); + +void nr_process_rar(nr_downlink_indication_t *dl_info); + +void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame); + +void nr_ra_failed(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index); + +void nr_ra_succeeded(uint8_t Mod_id, uint8_t CC_id, uint8_t gNB_index); + +/* \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 void */ +void nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, + 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 void */ +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_PRACH_RESOURCES_t *prach_resources, + 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 /** @}*/ 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 0000000000..5d99acfc3a --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/nr_l1_helpers.c @@ -0,0 +1,152 @@ +/* + * 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 functions for PRACH adapted to NR +* \author Guido Casati +* \date 2019 +* \version 2.0 +* \email guido.casati@iis.fraunhofer.de +* @ingroup _mac + +*/ + +#include "PHY/defs_nr_common.h" + +#include "mac_defs.h" +#include "LAYER2/NR_MAC_COMMON/nr_mac_extern.h" +#include "LAYER2/NR_MAC_UE/mac_proto.h" + +/* TS 38.321 subclause 7.3 - return DELTA_PREAMBLE values in dB */ +int8_t nr_get_DELTA_PREAMBLE(module_id_t mod_id, int CC_id, uint16_t prach_format){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + NR_ServingCellConfigCommon_t *scc = mac->scc; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + NR_SubcarrierSpacing_t scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing; + int prach_sequence_length = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present - 1; + uint8_t prachConfigIndex, mu; + + AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); + + // SCS configuration from msg1_SubcarrierSpacing and table 4.2-1 in TS 38.211 + + 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 %lu\n", scs); + } + + // Preamble formats given by prach_ConfigurationIndex and tables 6.3.3.2-2 and 6.3.3.2-2 in TS 38.211 + + prachConfigIndex = nr_rach_ConfigCommon->rach_ConfigGeneric.prach_ConfigurationIndex; + + if (prach_sequence_length == 0) { + switch (prach_format) { + AssertFatal(prach_format < 4, "Illegal PRACH format %d for sequence length 839\n", prach_format); + + // long preamble formats + case 0: + case 3: + return 0; + + case 1: + return -3; + + case 2: + return -6; + } + } else { + switch (prach_format) { // short preamble formats + case 0: + case 3: + return 8 + 3*mu; + + case 1: + case 4: + case 8: + return 5 + 3*mu; + + case 2: + case 5: + return 3 + 3*mu; + + case 6: + return 3*mu; + + case 7: + return 5 + 3*mu; + + default: + AssertFatal(1 == 0, "[UE %d] ue_procedures.c: FATAL, Illegal preambleFormat %d, prachConfigIndex %d\n", mod_id, prach_format, prachConfigIndex); + } + } +} + +/* TS 38.321 subclause 5.1.3 - RA preamble transmission - ra_PREAMBLE_RECEIVED_TARGET_POWER configuration */ +int nr_get_Po_NOMINAL_PUSCH(NR_PRACH_RESOURCES_t *prach_resources, module_id_t mod_id, uint8_t CC_id){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + NR_ServingCellConfigCommon_t *scc = mac->scc; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + int8_t receivedTargerPower, delta_preamble; + long preambleReceivedTargetPower; + + AssertFatal(nr_rach_ConfigCommon != NULL, "[UE %d] CCid %d FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id, CC_id); + + preambleReceivedTargetPower = nr_rach_ConfigCommon->rach_ConfigGeneric.preambleReceivedTargetPower; + delta_preamble = nr_get_DELTA_PREAMBLE(mod_id, CC_id, prach_resources->prach_format); + + receivedTargerPower = preambleReceivedTargetPower + delta_preamble + (mac->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; + + return receivedTargerPower; +} \ 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 0000000000..75091d49e2 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -0,0 +1,613 @@ +/* + * 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" + +/* +#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" +#include "PHY/NR_UE_ESTIMATION/nr_estimation.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 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; + +// WIP +// 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_PRACH_RESOURCES_t *prach_resources, + NR_RACH_ConfigDedicated_t * rach_ConfigDedicated){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + NR_ServingCellConfigCommon_t *scc = mac->scc; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon; + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric; + + // NR_BeamFailureRecoveryConfig_t *beam_failure_recovery_config = &mac->RA_BeamFailureRecoveryConfig; // todo + + int messagePowerOffsetGroupB, messageSizeGroupA, PLThreshold, sizeOfRA_PreamblesGroupA, numberOfRA_Preambles, i, deltaPreamble_Msg3; + uint8_t noGroupB = 0, s_id, f_id, ul_carrier_id, prach_ConfigIndex, SFN_nbr, Msg3_size; + + // NR_RSRP_Range_t rsrp_ThresholdSSB; // todo + + /////////////////////////////////////////////////////////// + //////////* UE Random Access Resource Selection *////////// + /////////////////////////////////////////////////////////// + + // todo: + // - 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_preamble_index provided by PDCCH && ra_PreambleIndex != 0b000000 + // --- set PREAMBLE_INDEX to ra_preamble_index + // --- 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 + // // 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; + // } + + //////////* Contention-based RA preamble selection *////////// + // todo: + // - selection of SSB with SS-RSRP above rsrp-ThresholdSSB else select any SSB + // - todo determine next available PRACH occasion + + // rsrp_ThresholdSSB = *nr_rach_ConfigCommon->rsrp_ThresholdSSB; + + AssertFatal(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); + + nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + rach_ConfigGeneric = &nr_rach_ConfigCommon->rach_ConfigGeneric; + + Msg3_size = mac->RA_Msg3_size; + + numberOfRA_Preambles = 64; + if(nr_rach_ConfigCommon->totalNumberOfRA_Preambles != NULL) + numberOfRA_Preambles = *(nr_rach_ConfigCommon->totalNumberOfRA_Preambles); + + 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->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 %lu\n", nr_rach_ConfigCommon->groupBconfigured->ra_Msg3SizeGroupA); + /* todo cases 10 -15*/ + } + + /* Power offset for preamble selection in dB */ + 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 %lu\n", nr_rach_ConfigCommon->groupBconfigured->messagePowerOffsetGroupB); + } + + // todo Msg3-DeltaPreamble should be provided from higher layers, otherwise is 0 + mac->deltaPreamble_Msg3 = 0; + deltaPreamble_Msg3 = mac->deltaPreamble_Msg3; + } + + PLThreshold = prach_resources->RA_PCMAX - rach_ConfigGeneric->preambleReceivedTargetPower - deltaPreamble_Msg3 - messagePowerOffsetGroupB; + + /* Msg3 has not been transmitted yet */ + if (first_Msg3 == 1) { + if (noGroupB == 1) { + // use Group A preamble + prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; + mac->RA_usedGroupA = 1; + } else if ((Msg3_size < messageSizeGroupA) && (get_nr_PL(mod_id, CC_id, gNB_id) > PLThreshold)) { + // Group B is configured and RA preamble Group A is used + // - todo add condition on CCCH_sdu_size for initiation by CCCH + prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; + mac->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); + mac->RA_usedGroupA = 0; + } + } else { // Msg3 is being retransmitted + if (mac->RA_usedGroupA == 1 && noGroupB == 1) { + prach_resources->ra_PreambleIndex = (taus()) % numberOfRA_Preambles; + } else if (mac->RA_usedGroupA == 1 && noGroupB == 0){ + prach_resources->ra_PreambleIndex = (taus()) % sizeOfRA_PreamblesGroupA; + } else { + prach_resources->ra_PreambleIndex = sizeOfRA_PreamblesGroupA + (taus()) % (numberOfRA_Preambles - sizeOfRA_PreamblesGroupA); + } + } + + // todo 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 + + ///////////////////////////////////////////////////////////////////////////// + //////////* Random Access Preamble Transmission (5.1.3 TS 38.321) *////////// + ///////////////////////////////////////////////////////////////////////////// + // todo: + // - condition on notification of suspending power ramping counter from lower layer (5.1.3 TS 38.321) + // - check if SSB or CSI-RS have not changed since the selection in the last RA Preamble tranmission + // - Extend RA_rnti computation (e.g. f_id selection, ul_carrier_id are hardcoded) + + if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER > 1) + mac->RA_PREAMBLE_POWER_RAMPING_COUNTER++; + + prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, 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) + + prach_ConfigIndex = rach_ConfigGeneric->prach_ConfigurationIndex; + + // ra_RNTI computation + // - todo: this is for TDD FR1 only + // - ul_carrier_id: UL carrier used for RA preamble transmission, hardcoded for NUL carrier + // - f_id: index of the PRACH occasion in the frequency domain + // - s_id is starting symbol of the PRACH occasion [0...14] + // - t_id is the first slot of the PRACH occasion in a system frame [0...80] + + ul_carrier_id = 0; // NUL + f_id = rach_ConfigGeneric->msg1_FrequencyStart; + 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]; + + // Pick the first slot of the PRACH occasion in a system frame + 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; + mac->ra_rnti = prach_resources->ra_RNTI; + + LOG_D(MAC, "Computed ra_RNTI is %d", prach_resources->ra_RNTI); +} + +// TbD: RA_attempt_number not used +void nr_Msg1_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ + AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + mac->ra_state = WAIT_RAR; + // Start contention resolution timer + mac->RA_attempt_number++; +} + +void nr_Msg3_transmitted(module_id_t mod_id, uint8_t CC_id, frame_t frameP, uint8_t gNB_id){ + AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); + LOG_D(MAC,"[UE %d][RAPROC] Frame %d : Msg3_tx: Starting contention resolution timer\n", mod_id, frameP); + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + // start contention resolution timer + mac->RA_contention_resolution_cnt = 0; + mac->RA_contention_resolution_timer_active = 1; +} + +///////////////////////////////////////////////////////////////////////// +///////* 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 + +// WIP +// todo TS 38.321: +// - check if carrier to use is explicitly signalled then do (1) RA CARRIER SELECTION (SUL, NUL) (2) set PCMAX +// - BWP operation (subclause 5.15 TS 38.321) +// - handle initialization by beam failure recovery +// - handle initialization by handover +// - handle transmission on DCCH using PRACH (during handover, or sending SR for example) +// - take into account MAC CEs in size_sdu (currently hardcoded size to 1 MAC subPDU and 1 padding subheader) +// - fix rrc data req logic +// - retrieve TBS +// - add mac_rrc_nr_data_req_ue, etc ... +// - add the backoff condition here if we have it from a previous RA reponse which failed (i.e. backoff indicator) + +void nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, + 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 *mac = get_mac_inst(mod_id); + uint8_t mac_sdus[MAX_NR_ULSCH_PAYLOAD_BYTES]; + uint8_t lcid = UL_SCH_LCID_CCCH_MSG3, *payload, ra_ResponseWindow; + uint8_t config_index, mu; + int is_nr_prach_slot; + uint16_t size_sdu = 0; + unsigned short post_padding; + fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; + NR_ServingCellConfigCommon_t *scc = mac->scc; + NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; + NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; + // int32_t frame_diff = 0; + + uint8_t sdu_lcids[NB_RB_MAX] = {0}; + uint16_t sdu_lengths[NB_RB_MAX] = {0}; + int TBS_bytes = 848, header_length_total, num_sdus, offset, preambleTransMax, mac_ce_len; + + AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n"); + + if (UE_mode == PRACH) { + + LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", mac->RA_active); + + config_index = rach_ConfigGeneric->prach_ConfigurationIndex; + if (setup->msg1_SubcarrierSpacing) + mu = *setup->msg1_SubcarrierSpacing; + else + mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + is_nr_prach_slot = get_nr_prach_info_from_index(config_index, + (int)frame, + (int)nr_tti_tx, + frequencyInfoDL->absoluteFrequencyPointA, + mu, + cfg->cell_config.frame_duplex_type, + NULL, + NULL, + NULL, + NULL); + if (is_nr_prach_slot) + prach_resources->generate_nr_prach = 1; + else + prach_resources->generate_nr_prach = 0; + + AssertFatal(setup != NULL, "[UE %d] FATAL nr_rach_ConfigCommon is NULL !!!\n", mod_id); + + if (mac->RA_active == 0) { + /* RA not active - checking if RRC is ready to initiate the RA procedure */ + + LOG_I(MAC, "RA not active. Starting RA preamble initialization.\n"); + + mac->RA_RAPID_found = 0; + + /* Set RA_PREAMBLE_POWER_RAMPING_STEP */ + switch (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_PREAMBLE_BACKOFF = 0; + prach_resources->RA_SCALING_FACTOR_BI = 1; + prach_resources->RA_PCMAX = 0; // currently hardcoded to 0 + + payload = (uint8_t*) &mac->CCCH_pdu.payload; + + mac_ce_len = 0; + num_sdus = 1; + post_padding = 1; + + if (0){ + // initialisation by RRC + // CCCH PDU + // size_sdu = (uint16_t) mac_rrc_data_req_ue(mod_id, + // CC_id, + // frame, + // CCCH, + // 1, + // mac_sdus, + // gNB_id, + // 0); + LOG_D(MAC,"[UE %d] Frame %d: Requested RRCConnectionRequest, got %d bytes\n", mod_id, frame, size_sdu); + } else { + // fill ulsch_buffer with random data + for (int i = 0; i < TBS_bytes; i++){ + mac_sdus[i] = (unsigned char) (lrand48()&0xff); + } + //Sending SDUs with size 1 + //Initialize elements of sdu_lcids and sdu_lengths + sdu_lcids[0] = lcid; + sdu_lengths[0] = TBS_bytes - 3 - post_padding - mac_ce_len; + header_length_total += 2 + (sdu_lengths[0] >= 128); + size_sdu += sdu_lengths[0]; + } + + mac->RA_tx_frame = frame; + mac->RA_tx_subframe = nr_tti_tx; + mac->RA_backoff_frame = frame; + mac->RA_backoff_subframe = nr_tti_tx; + + if (size_sdu > 0) { + + LOG_I(MAC, "[UE %d] Frame %d: Initialisation Random Access Procedure\n", mod_id, frame); + + mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; + mac->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; + mac->RA_Msg3_size = size_sdu + sizeof(NR_MAC_SUBHEADER_SHORT) + sizeof(NR_MAC_SUBHEADER_SHORT); + mac->RA_prachMaskIndex = 0; + // todo: add the backoff condition here + mac->RA_backoff_cnt = 0; + mac->RA_active = 1; + prach_resources->Msg3 = payload; + + ra_ResponseWindow = rach_ConfigGeneric->ra_ResponseWindow; + switch (ra_ResponseWindow) { + case 0: + mac->RA_window_cnt = 1; + break; + case 1: + mac->RA_window_cnt = 2; + break; + case 2: + mac->RA_window_cnt = 4; + break; + case 3: + mac->RA_window_cnt = 8; + break; + case 4: + mac->RA_window_cnt = 10; + break; + case 5: + mac->RA_window_cnt = 20; + break; + case 6: + mac->RA_window_cnt = 40; + break; + case 7: + mac->RA_window_cnt = 80; + break; + } + + // Fill in preamble and PRACH resources + nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, prach_resources, NULL); + + offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer + (uint8_t *) payload, // UL MAC pdu pointer + num_sdus, // num sdus + sdu_lengths, // sdu length + sdu_lcids, // sdu lcid + 0, // power headroom + 0, // crnti + 0, // truncated bsr + 0, // short bsr + 0, // long_bsr + post_padding, + 0); + + // Padding: fill remainder with 0 + if (post_padding > 0){ + for (int j = 0; j < (TBS_bytes - offset); j++) + payload[offset + j] = 0; // mac_pdu[offset + j] = 0; + } + } + } 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 + // todo: + // - handle beam failure recovery request + // - handle DL assignment on PDCCH for RA-RNTI + // - handle backoff and raResponseWindow params + // - disabled contention resolution as OAI NSA is contention-free based + + 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, mac->RA_window_cnt, mac->RA_tx_frame, mac->RA_tx_subframe); + + if (mac->RA_BI_found){ + prach_resources->RA_PREAMBLE_BACKOFF = prach_resources->RA_SCALING_FACTOR_BI * mac->RA_backoff_indicator; + } else { + prach_resources->RA_PREAMBLE_BACKOFF = 0; + } + + if (mac->RA_window_cnt > 0 && mac->RA_RAPID_found == 1) { + // mac->ra_state = WAIT_CONTENTION_RESOLUTION; + } else { + 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, + mac->RA_window_cnt); + + mac->RA_PREAMBLE_TRANSMISSION_COUNTER++; + + preambleTransMax = -1; + switch (rach_ConfigGeneric->preambleTransMax) { + case 0: + preambleTransMax = 3; + break; + case 1: + preambleTransMax = 4; + break; + case 2: + preambleTransMax = 5; + break; + case 3: + preambleTransMax = 6; + break; + case 4: + preambleTransMax = 7; + break; + case 5: + preambleTransMax = 8; + break; + case 6: + preambleTransMax = 10; + break; + case 7: + preambleTransMax = 20; + break; + case 8: + preambleTransMax = 50; + break; + case 9: + preambleTransMax = 100; + break; + case 10: + preambleTransMax = 200; + break; + } + + if (mac->RA_PREAMBLE_TRANSMISSION_COUNTER == preambleTransMax + 1){ + LOG_D(MAC, "[UE %d] Frame %d: Maximum number of RACH attempts (%d)\n", mod_id, frame, preambleTransMax); + mac->RA_backoff_cnt = rand() % (prach_resources->RA_PREAMBLE_BACKOFF + 1); + mac->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; + prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP << 1; // 2 dB increment + prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id); + } + + // compute backoff parameters + // if (mac->RA_backoff_cnt > 0){ + // frame_diff = (sframe_t) frame - mac->RA_backoff_frame; + // if (frame_diff < 0) frame_diff = -frame_diff; + // mac->RA_backoff_frame = frame; + // mac->RA_backoff_subframe = nr_tti_tx; + // } + // compute RA window parameters + // if (mac->RA_window_cnt > 0){ + // frame_diff = (frame_t) frame - mac->RA_tx_frame; + // if (frame_diff < 0) frame_diff = -frame_diff; + // mac->RA_window_cnt -= ((10 * frame_diff) + (nr_tti_tx - mac->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, mac->RA_window_cnt); + // } + + mac->RA_tx_frame = frame; + mac->RA_tx_subframe = nr_tti_tx; + // Fill in preamble and PRACH resources + nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, NULL); + } + } + } 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; +} diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index e734ce10a5..85f09e70b8 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -35,6 +35,7 @@ #include "assertions.h" #include "LAYER2/NR_MAC_UE/mac_extern.h" #include "mac_defs.h" +#include "common/utils/nr/nr_common.h" #include #ifdef NR_PDCCH_DCI_TOOLS_DEBUG @@ -123,7 +124,7 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac,fapi_nr_dl_config_request_t *dl_ if (mac->ra_state == WAIT_RAR) { // check for RAR rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; - rel15->rnti = 2;//get_RA_RNTI(mac,frame,slot); + rel15->rnti = 2;//get_RA_RNTI(mac,frame,slot); // WIP dl_config->number_pdus = dl_config->number_pdus + 1; } else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION) { diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 5ebd57fd19..e971f725d8 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -31,28 +31,37 @@ */ -/* MAC related headers */ -#include "mac_proto.h" +#include +#include + +/* exe */ +#include "executables/nr-softmodem.h" + +/* RRC*/ +#include "RRC/NR_UE/rrc_proto.h" +#include "NR_RACH-ConfigCommon.h" +#include "NR_RACH-ConfigGeneric.h" +#include "NR_FrequencyInfoDL.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 - // 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" #include "executables/softmodem-common.h" -/* log utils */ + +/* utils */ +#include "assertions.h" + #include "common/utils/LOG/log.h" #include "SIMULATION/TOOLS/sim.h" // for taus #include "openair2/LAYER2/NR_MAC_COMMON/nr_mac.h" @@ -60,7 +69,6 @@ #include #include -//int mbms_rab_id = 2047; //#define ENABLE_MAC_PAYLOAD_DEBUG 1 #define DEBUG_EXTRACT_DCI 1 @@ -732,6 +740,9 @@ NR_UE_L2_STATE_t nr_ue_scheduler(const module_id_t module_id, */ } + if (mac->RA_contention_resolution_timer_active == 1) { + ue_contention_resolution(module_id, gNB_index, cc_id, tx_frame); + } mac->scheduled_response.dl_config = dl_config; @@ -739,6 +750,187 @@ NR_UE_L2_STATE_t nr_ue_scheduler(const module_id_t module_id, return UE_CONNECTION_OK; } +// This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x +// It fills the PRACH PDU per each FD occasion. +// PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3. +// - todo: +// - Partial configuration is actually already stored in (fapi_nr_prach_config_t) &mac->phy_config.config_req->prach_config +//// however we need rach_ConfigGeneric to retrieve the config_index +void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { + + uint8_t config_index, mu, N_dur, N_t_slot, start_symbol; + uint16_t format, format0, format1, ncs; + int msg1_FDM, is_nr_prach_slot, fdm; + + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); + + fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; + fapi_nr_ul_config_prach_pdu *prach_config_pdu; + fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; + fapi_nr_prach_config_t *prach_config = &cfg->prach_config; + + NR_ServingCellConfigCommon_t *scc = mac->scc; + NR_RACH_ConfigCommon_t *setup = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + NR_FrequencyInfoDL_t *frequencyInfoDL = scc->downlinkConfigCommon->frequencyInfoDL; + NR_RACH_ConfigGeneric_t *rach_ConfigGeneric = &setup->rach_ConfigGeneric; + config_index = rach_ConfigGeneric->prach_ConfigurationIndex; + + if (is_nr_UL_slot(scc, slotP)) { + + if (setup->msg1_SubcarrierSpacing) + mu = *setup->msg1_SubcarrierSpacing; + else + mu = frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + is_nr_prach_slot = get_nr_prach_info_from_index(config_index, + (int)frameP, + (int)slotP, + frequencyInfoDL->absoluteFrequencyPointA, + mu, + cfg->cell_config.frame_duplex_type, + &format, + &start_symbol, + &N_t_slot, + &N_dur); + if (is_nr_prach_slot) { + + fdm = rach_ConfigGeneric->msg1_FDM; + + switch (fdm){ + case 0: + case 1: + case 2: + case 3: + msg1_FDM = 1 << fdm; + break; + default: + AssertFatal(1 == 0, "Unknown msg1_FDM from rach_ConfigGeneric %d\n", fdm); + } + + format0 = format & 0xff; // single PRACH format + format1 = (format >> 8) & 0xff; // dual PRACH format + + ul_config->sfn = frameP; + ul_config->slot = slotP; + + for (int n = 0; n < msg1_FDM; n++) { // one structure per frequency domain occasion + + ul_config->ul_config_list[ul_config->number_pdus].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PRACH; + prach_config_pdu = &ul_config->ul_config_list[ul_config->number_pdus].prach_config_pdu; + memset(prach_config_pdu, 0, sizeof(fapi_nr_ul_config_prach_pdu)); + ul_config->number_pdus += 1; + + ncs = get_NCS(rach_ConfigGeneric->zeroCorrelationZoneConfig, format0, setup->restrictedSetConfig); + + // filling PRACH PDU for FAPI config request + prach_config_pdu->phys_cell_id = *scc->physCellId; + prach_config_pdu->num_prach_ocas = N_t_slot; + prach_config_pdu->prach_start_symbol = start_symbol; + prach_config_pdu->num_ra = n; + prach_config_pdu->num_cs = ncs; + prach_config_pdu->root_seq_id = prach_config->num_prach_fd_occasions_list[n].prach_root_sequence_index; + prach_config_pdu->restricted_set = prach_config->restricted_set_config; + prach_config_pdu->freq_msg1 = prach_config->num_prach_fd_occasions_list[n].k1; + + if (format1 != 0xff) { + switch(format0) { // dual PRACH format + case 0xa1: + prach_config_pdu->prach_format = 9; + break; + case 0xa2: + prach_config_pdu->prach_format = 10; + break; + case 0xa3: + prach_config_pdu->prach_format = 11; + break; + default: + AssertFatal(1 == 0, "Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); + } + } else { + switch(format0) { // single PRACH format + case 0xa1: + prach_config_pdu->prach_format = 0; + break; + case 0xa2: + prach_config_pdu->prach_format = 1; + break; + case 0xa3: + prach_config_pdu->prach_format = 2; + break; + case 0xb1: + prach_config_pdu->prach_format = 3; + break; + case 0xb2: + prach_config_pdu->prach_format = 4; + break; + case 0xb3: + prach_config_pdu->prach_format = 5; + break; + case 0xb4: + prach_config_pdu->prach_format = 6; + break; + case 0xc0: + prach_config_pdu->prach_format = 7; + break; + case 0xc2: + prach_config_pdu->prach_format = 8; + break; + case 0: + // long formats are handled @ PHY + break; + case 1: + // long formats are handled @ PHY + break; + case 2: + // long formats are handled @ PHY + break; + case 3: + // long formats are handled @ PHY + break; + default: + AssertFatal(1 == 0, "Invalid PRACH format"); + } + } + } + } + mac->scheduled_response.ul_config = ul_config; + } +} + +//////////////////////////////////////////////////////////////////////////// +/////////* Random Access Contention Resolution (5.1.35 TS 38.321) *///////// +//////////////////////////////////////////////////////////////////////////// +// Handling contention resolution timer +// WIP todo: +// - beam failure recovery +// - RA completed + +void ue_contention_resolution(module_id_t module_id, uint8_t gNB_index, int cc_id, frame_t tx_frame){ + + NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); + NR_ServingCellConfigCommon_t *scc = mac->scc; + NR_RACH_ConfigCommon_t *nr_rach_ConfigCommon = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup; + + if (mac->RA_contention_resolution_timer_active == 1) { + if (nr_rach_ConfigCommon){ + LOG_I(MAC, "Frame %d: Contention resolution timer %d/%ld\n", + tx_frame, + mac->RA_contention_resolution_cnt, + ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)); + mac->RA_contention_resolution_cnt++; + + if (mac->RA_contention_resolution_cnt == ((1 + nr_rach_ConfigCommon->ra_ContentionResolutionTimer) << 3)) { + mac->t_crnti = 0; + mac->RA_active = 0; + mac->RA_contention_resolution_timer_active = 0; + // Signal PHY to quit RA procedure + LOG_E(MAC, "[UE %u] [RAPROC] Contention resolution timer expired, RA failed, discarded TC-RNTI\n", module_id); + nr_ra_failed(module_id, cc_id, gNB_index); + } + } + } +} + #if 0 uint16_t nr_dci_format_size (PHY_VARS_NR_UE *ue, uint8_t slot, @@ -1917,7 +2109,7 @@ int nr_ue_process_dci_indication_pdu(module_id_t module_id,int cc_id, int gNB_in dci->rnti,dci->dci_format,dci->n_CCE,dci->payloadSize,*(unsigned long long*)dci->payloadBits); nr_extract_dci_info(mac,dci->dci_format,dci->payloadSize,dci->rnti,(uint64_t *)dci->payloadBits,def_dci_pdu_rel15); - nr_ue_process_dci(module_id, cc_id, gNB_index, def_dci_pdu_rel15, dci->rnti, dci->dci_format); + return (nr_ue_process_dci(module_id, cc_id, gNB_index, def_dci_pdu_rel15, dci->rnti, dci->dci_format)); } int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dci_pdu_rel15_t *dci, uint16_t rnti, uint32_t dci_format){ @@ -2677,7 +2869,6 @@ void nr_ue_send_sdu(module_id_t module_idP, LOG_D(MAC, "Handling PDU frame %d slot %d\n", frameP, slotP); uint8_t * pduP = pdu; - NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN); @@ -2773,7 +2964,9 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac, LOG_D(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu); #endif break; - + + mac->rnti_type = rnti_type; + case NR_RNTI_C: // indicating a DL DCI format 1bit @@ -3158,6 +3351,7 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, uint8_t *pdu_ptr = pduP, rx_lcid, done = 0; int pdu_len = mac_pdu_len; uint16_t mac_ce_len, mac_subheader_len, mac_sdu_len; + NR_UE_MAC_INST_t *mac = get_mac_inst(module_idP); //NR_UE_MAC_INST_t *UE_mac_inst = get_mac_inst(module_idP); //uint8_t scs = UE_mac_inst->mib->subCarrierSpacingCommon; @@ -3318,8 +3512,34 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, break; case DL_SCH_LCID_CON_RES_ID: // 38.321 Ch6.1.3.3 + // WIP todo: handle CCCH_pdu mac_ce_len = 6; + + LOG_I(MAC, "[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n", module_idP, frameP, pdu_ptr[0], pdu_ptr[1], pdu_ptr[2], pdu_ptr[3], pdu_ptr[4], pdu_ptr[5]); + if (mac->RA_active == 1) { + LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", module_idP, frameP); + mac->RA_active = 0; + // // check if RA procedure has finished completely (no contention) + // tx_sdu = &mac->CCCH_pdu.payload[3]; + // //Note: 3 assumes sizeof(SCH_SUBHEADER_SHORT) + PADDING CE, which is when UL-Grant has TBS >= 9 (64 bits) + // // (other possibility is 1 for TBS=7 (SCH_SUBHEADER_FIXED), or 2 for TBS=8 (SCH_SUBHEADER_FIXED+PADDING or // SCH_SUBHEADER_SHORT) + // for (i = 0; i < 6; i++) + // if (tx_sdu[i] != payload_ptr[i]) { + // LOG_E(MAC, "[UE %d][RAPROC] Contention detected, RA failed\n", module_idP); + // nr_ra_failed(module_idP, CC_id, eNB_index); + // mac->RA_contention_resolution_timer_active = 0; + // return; + // } + LOG_I(MAC, "[UE %d][RAPROC] Frame %d : Cleared contention resolution timer. Set C-RNTI to TC-RNTI\n", + module_idP, + frameP); + mac->RA_contention_resolution_timer_active = 0; + nr_ra_succeeded(module_idP, CC_id, gNB_index); + mac->crnti = mac->t_crnti; + mac->t_crnti = 0; + mac->ra_state = RA_SUCCEEDED; + } break; case DL_SCH_LCID_PADDING: done = 1; @@ -3385,71 +3605,180 @@ void nr_ue_process_mac_pdu(module_id_t module_idP, } } -//--------------------------------------------------------------------------------- +//////////////////////////////////////////////////////// +/////* ULSCH MAC PDU generation (6.1.2 TS 38.321) *///// +//////////////////////////////////////////////////////// +unsigned char nr_generate_ulsch_pdu(uint8_t *sdus_payload, + uint8_t *pdu, + uint8_t num_sdus, + uint16_t *sdu_lengths, + uint8_t *sdu_lcids, + uint8_t power_headroom, + uint16_t crnti, + uint16_t truncated_bsr, + uint16_t short_bsr, + uint16_t long_bsr, + unsigned short post_padding, + uint16_t buflen) { -uint16_t -nr_generate_ulsch_pdu(uint8_t *mac_pdu, - uint8_t *sdus_payload, - uint8_t num_sdus, - uint16_t *sdu_lengths, - uint8_t *sdu_lcids, - uint16_t *crnti, - uint16_t buflen) { + NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) pdu; + unsigned char last_size = 0, i, mac_header_control_elements[16], *ce_ptr, bsr = 0; + int mac_ce_size, offset; - NR_MAC_SUBHEADER_FIXED *mac_pdu_ptr = (NR_MAC_SUBHEADER_FIXED *) mac_pdu; - unsigned char * ulsch_buffer_ptr = sdus_payload; - uint8_t last_size=0; - uint16_t sdu_length_total=0; - int i; - int offset=0; + LOG_D(MAC, "[UE] Generating ULSCH PDU : num_sdus %d\n", num_sdus); - // 2) Generation of ULSCH MAC SDU subheaders - for (i = 0; i < num_sdus; i++) { - LOG_D(MAC, "[gNB] Generate ULSCH header num sdu %d len sdu %d\n", num_sdus, sdu_lengths[i]); + #ifdef DEBUG_HEADER_PARSING - if (sdu_lengths[i] < 128) { - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0; - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0; - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i]; - ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i]; - last_size = 2; - } else { - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i]; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; - ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff; - last_size = 3; - } + for (i = 0; i < num_sdus; i++) + LOG_D(MAC, "[UE] MAC subPDU %d (lcid %d length %d bytes \n", i, sdu_lcids[i], sdu_lengths[i]); - mac_pdu_ptr += last_size; + #endif - // 3) cycle through SDUs, compute each relevant and place dlsch_buffer in - memcpy((void *) mac_pdu_ptr, (void *) ulsch_buffer_ptr, sdu_lengths[i]); - ulsch_buffer_ptr+= sdu_lengths[i]; - sdu_length_total+= sdu_lengths[i]; - mac_pdu_ptr += sdu_lengths[i]; - } + // Generating UL MAC subPDUs including MAC SDU and subheader - offset = ((unsigned char *) mac_pdu_ptr - mac_pdu); + for (i = 0; i < num_sdus; i++) { + LOG_D(MAC, "[UE] Generating UL MAC subPDUs for SDU with lenght %d ( num_sdus %d )\n", sdu_lengths[i], num_sdus); - // 4) Compute final offset for padding - uint16_t padding_bytes = buflen - offset; - LOG_D(MAC, "Number of padding bytes: %d \n", padding_bytes); - if (padding_bytes > 0) { - ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0; - ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING; - mac_pdu_ptr++; + if (sdu_lcids[i] != UL_SCH_LCID_CCCH){ + if (sdu_lengths[i] < 128) { + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0; + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0; + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = sdu_lcids[i]; + ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = (unsigned char) sdu_lengths[i]; + last_size = 2; + } else { + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->R = 0; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->F = 1; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->LCID = sdu_lcids[i]; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L1 = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f; + ((NR_MAC_SUBHEADER_LONG *) mac_pdu_ptr)->L2 = (unsigned short) sdu_lengths[i] & 0xff; + last_size = 3; + } + } else { // UL CCCH SDU + mac_pdu_ptr->R = 0; + mac_pdu_ptr->LCID = sdu_lcids[i]; + } - } else { - // no MAC subPDU with padding - } + mac_pdu_ptr += last_size; + + // cycle through SDUs, compute each relevant and place ulsch_buffer in + memcpy((void *) mac_pdu_ptr, (void *) sdus_payload, sdu_lengths[i]); + sdus_payload += sdu_lengths[i]; + mac_pdu_ptr += sdu_lengths[i]; + } + + // Generating UL MAC subPDUs including MAC CEs (MAC CE and subheader) + + ce_ptr = &mac_header_control_elements[0]; + + if (power_headroom) { + // MAC CE fixed subheader + mac_pdu_ptr->R = 0; + mac_pdu_ptr->LCID = UL_SCH_LCID_SINGLE_ENTRY_PHR; + mac_pdu_ptr++; + + // PHR MAC CE (1 octet) + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PH = power_headroom; + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R1 = 0; + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->PCMAX = 0; // todo + ((NR_SINGLE_ENTRY_PHR_MAC_CE *) ce_ptr)->R2 = 0; + + mac_ce_size = sizeof(NR_SINGLE_ENTRY_PHR_MAC_CE); + + // Copying bytes for PHR MAC CEs to the mac pdu pointer + memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); + ce_ptr += mac_ce_size; + mac_pdu_ptr += (unsigned char) mac_ce_size; + } + + if (crnti) { + // MAC CE fixed subheader + mac_pdu_ptr->R = 0; + mac_pdu_ptr->LCID = CRNTI; + mac_pdu_ptr++; + + // C-RNTI MAC CE (2 octets) + * (uint16_t *) ce_ptr = crnti; + mac_ce_size = sizeof(uint16_t); + + // Copying bytes for CRNTI MAC CE to the mac pdu pointer + memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); + ce_ptr += mac_ce_size; + mac_pdu_ptr += (unsigned char) mac_ce_size; + } + + if (truncated_bsr) { + // MAC CE fixed subheader + mac_pdu_ptr->R = 0; + mac_pdu_ptr->LCID = UL_SCH_LCID_S_TRUNCATED_BSR; + mac_pdu_ptr++; + + // Short truncated BSR MAC CE (1 octet) + ((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> Buffer_size = truncated_bsr; + ((NR_BSR_SHORT_TRUNCATED *) ce_ptr)-> LcgID = 0; // todo + mac_ce_size = sizeof(NR_BSR_SHORT_TRUNCATED); + + bsr = 1 ; + } else if (short_bsr) { + // MAC CE fixed subheader + mac_pdu_ptr->R = 0; + mac_pdu_ptr->LCID = UL_SCH_LCID_S_BSR; + mac_pdu_ptr++; + + // Short truncated BSR MAC CE (1 octet) + ((NR_BSR_SHORT *) ce_ptr)->Buffer_size = short_bsr; + ((NR_BSR_SHORT *) ce_ptr)->LcgID = 0; // todo + mac_ce_size = sizeof(NR_BSR_SHORT); + + bsr = 1 ; + } else if (long_bsr) { + // MAC CE variable subheader + // todo ch 6.1.3.1. TS 38.321 + // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->R = 0; + // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->F = 0; + // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->LCID = UL_SCH_LCID_L_BSR; + // ((NR_MAC_SUBHEADER_SHORT *) mac_pdu_ptr)->L = 0; + // last_size = 2; + // mac_pdu_ptr += last_size; + + // Short truncated BSR MAC CE (1 octet) + // ((NR_BSR_LONG *) ce_ptr)->Buffer_size0 = short_bsr; + // ((NR_BSR_LONG *) ce_ptr)->LCGID0 = 0; + // mac_ce_size = sizeof(NR_BSR_LONG); // size is variable + } + + if (bsr){ + // Copying bytes for BSR MAC CE to the mac pdu pointer + memcpy((void *) mac_pdu_ptr, (void *) ce_ptr, mac_ce_size); + ce_ptr += mac_ce_size; + mac_pdu_ptr += (unsigned char) mac_ce_size; + } + + // compute offset before adding padding (if necessary) + offset = ((unsigned char *) mac_pdu_ptr - pdu); + uint16_t padding_bytes = 0; + + if(buflen > 0) // If the buflen is provided + padding_bytes = buflen - offset; + + // Compute final offset for padding + if (post_padding > 0 || padding_bytes>0) { + ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0; + ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = UL_SCH_LCID_PADDING; + mac_pdu_ptr++; + } else { + // no MAC subPDU with padding + } + + // compute final offset + offset = ((unsigned char *) mac_pdu_ptr - pdu); + + //printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - mac_pdu)); return offset; } - uint8_t nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t subframe, uint8_t eNB_index, @@ -3522,13 +3851,6 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, sdu_length_total += sdu_lengths[num_sdus]; sdu_lcids[num_sdus] = lcid; - - //Update total MAC Header size for RLC PDUs - /*if(sdu_lengths[num_sdus]<128) - total_rlc_pdu_header_len += 2; - else - total_rlc_pdu_header_len += 3;*/ - total_rlc_pdu_header_len += MAX_RLC_SDU_SUBHEADER_SIZE; //rlc_pdu_header_len_last; //Update number of SDU @@ -3553,13 +3875,18 @@ nr_ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, // Generate ULSCH PDU if (num_sdus>0) { - payload_offset = nr_generate_ulsch_pdu(ulsch_buffer, // mac header - ulsch_sdus, + payload_offset = nr_generate_ulsch_pdu(ulsch_sdus, + ulsch_buffer, // mac header num_sdus, // num sdus sdu_lengths, // sdu length sdu_lcids, // sdu lcid - NULL, // crnti - buflen); // long_bsr + 0, // power_headroom + 0, // crnti + 0, // truncated_bsr + 0, // short_bsr + 0, // long_bsr + 0, // post_padding + buflen); // TBS in bytes } else return 0; 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 0000000000..e9d3f8c327 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c @@ -0,0 +1,208 @@ +/* + * 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 + +// table 7.2-1 TS 38.321 +uint16_t table_7_2_1[16] = { + 5, // row index 0 + 10, // row index 1 + 20, // row index 2 + 30, // row index 3 + 40, // row index 4 + 60, // row index 5 + 80, // row index 6 + 120, // row index 7 + 160, // row index 8 + 240, // row index 9 + 320, // row index 10 + 480, // row index 11 + 960, // row index 12 + 1920, // row index 13 +}; + +///////////////////////////////////// +// Random Access Response PDU // +// TS 38.213 ch 8.2 // +// TS 38.321 ch 6.2.3 // +///////////////////////////////////// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise +//| E | T | R A P I D |// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// +//| R | T A |// +//| T A | UL grant |// +//| UL grant |// +//| UL grant |// +//| UL grant |// +//| T C - R N T I |// +//| T C - R N T I |// +///////////////////////////////////// +// UL grant (27 bits) // +///////////////////////////////////// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise +//|-------------------|FHF|F_alloc|// +//| Freq allocation |// +//| F_alloc |Time allocation|// +//| MCS | TPC |CSI|// +///////////////////////////////////// +// WIP todo: +// - apply UL grant freq alloc & time alloc as per 8.2 TS 38.213 +// - apply tpc command, csi req, mcs +uint16_t nr_ue_process_rar(module_id_t mod_id, + int CC_id, + frame_t frameP, + uint8_t * dlsch_buffer, + rnti_t * t_crnti, + uint8_t preamble_index, + uint8_t * selected_rar_buffer){ + + NR_UE_MAC_INST_t *ue_mac = get_mac_inst(mod_id); + NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; // RAR subheader pointer + NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); // RAR subPDU pointer + uint8_t n_subPDUs = 0; // number of RAR payloads + uint8_t n_subheaders = 0; // number of MAC RAR subheaders + uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs + unsigned char freq_hopping, msg3_t_alloc, mcs, tpc_command, csi_req; + uint16_t ta_command = 0, msg3_f_alloc, bwp_size; + int f_alloc, mask; + + AssertFatal(CC_id == 0, "RAR reception on secondary CCs is not supported yet\n"); + + while (1) { + n_subheaders++; + if (rarh->T == 1) { + n_subPDUs++; + LOG_D(MAC, "[UE %d][RAPROC] Got RAPID RAR subPDU\n", mod_id); + } else { + n_subPDUs++; + ue_mac->RA_backoff_indicator = table_7_2_1[((NR_RA_HEADER_BI *)rarh)->BI]; + ue_mac->RA_BI_found = 1; + LOG_D(MAC, "[UE %d][RAPROC] Got BI RAR subPDU %d\n", mod_id, ue_mac->RA_backoff_indicator); + } + if (rarh->RAPID == preamble_index) { + LOG_D(PHY, "[UE %d][RAPROC] Found RAR with the intended RAPID %d\n", mod_id, rarh->RAPID); + rar = (NR_MAC_RAR *) (dlsch_buffer + n_subheaders + (n_subPDUs - 1) * sizeof(NR_MAC_RAR)); + ue_mac->RA_RAPID_found = 1; + break; + } + if (rarh->E == 0) { + LOG_I(PHY, "No RAR found with the intended RAPID. \n"); + break; + } else { + rarh += sizeof(NR_MAC_RAR) + 1; + } + }; + + LOG_D(MAC, "number of RAR subheader %d; number of RAR pyloads %d\n", n_subheaders, n_subPDUs); + + // 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); + + if (ue_mac->RA_RAPID_found) { + // TC-RNTI + *t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); + ue_mac->t_crnti = *t_crnti; + ue_mac->rnti_type = NR_RNTI_TC; + // TA command + ta_command = rar->TA2 + (rar->TA1 << 5); + // CSI + csi_req = (unsigned char) (rar->UL_GRANT_4 & 0x01); + // TPC + tpc_command = (unsigned char) ((rar->UL_GRANT_4 >> 1) & 0x07); + switch (tpc_command){ + case 0: + ue_mac->Msg3_TPC = -6; + break; + case 1: + ue_mac->Msg3_TPC = -4; + break; + case 2: + ue_mac->Msg3_TPC = -2; + break; + case 3: + ue_mac->Msg3_TPC = 0; + break; + case 4: + ue_mac->Msg3_TPC = 2; + break; + case 5: + ue_mac->Msg3_TPC = 4; + break; + case 6: + ue_mac->Msg3_TPC = 6; + break; + case 7: + ue_mac->Msg3_TPC = 8; + break; + } + //MCS + mcs = (unsigned char) (rar->UL_GRANT_4 >> 4); + // time and frequency alloc + bwp_size = NRRIV2BW(ue_mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); + msg3_t_alloc = (unsigned char) (rar->UL_GRANT_3 & 0x07); + msg3_f_alloc = (uint16_t) ((rar->UL_GRANT_3 >> 4) | (rar->UL_GRANT_2 << 4) | ((rar->UL_GRANT_1 & 0x03) << 12)); + + if (bwp_size < 180) + mask = (1 << ((int) ceil(log2((bwp_size*(bwp_size+1))>>1)))) - 1; + else + mask = (1 << (28 - (int)(ceil(log2((bwp_size*(bwp_size+1))>>1))))) - 1; + + f_alloc = msg3_f_alloc & mask; + + // frequency hopping flag + freq_hopping = (unsigned char) (rar->UL_GRANT_1 >> 2); + } else { + ue_mac->t_crnti = 0; + ta_command = (0xffff); + } + + // move the selected RAR to the front of the RA_PDSCH buffer + memcpy((void *) (selected_rar_buffer + 0), (void *) rarh, 1); + memcpy((void *) (selected_rar_buffer + 1), (void *) rar, sizeof(NR_MAC_RAR)); + + return ta_command; +} diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index b5fdea6760..af75e6afff 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); @@ -121,13 +121,23 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm } } + lte_frame_type_t frame_type; + uint16_t band; + int32_t offset; + + get_band((cfg->carrier_config.dl_frequency.value)*1000, + &band, + &offset, + &frame_type); + + RC.nrmac[Mod_idP]->common_channels[0].frame_type = frame_type; // Cell configuration cfg->cell_config.phy_cell_id.value = *scc->physCellId; cfg->cell_config.phy_cell_id.tl.tag = NFAPI_NR_CONFIG_PHY_CELL_ID_TAG; cfg->num_tlv++; - cfg->cell_config.frame_duplex_type.value = 1; + cfg->cell_config.frame_duplex_type.value = frame_type; cfg->cell_config.frame_duplex_type.tl.tag = NFAPI_NR_CONFIG_FRAME_DUPLEX_TYPE_TAG; cfg->num_tlv++; @@ -143,7 +153,11 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm // PRACH configuration - cfg->prach_config.prach_sequence_length.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present; + uint8_t nb_preambles = 64; + if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles != NULL) + nb_preambles = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->totalNumberOfRA_Preambles; + + cfg->prach_config.prach_sequence_length.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->prach_RootSequenceIndex.present-1; cfg->prach_config.prach_sequence_length.tl.tag = NFAPI_NR_CONFIG_PRACH_SEQUENCE_LENGTH_TAG; cfg->num_tlv++; @@ -153,7 +167,6 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm cfg->prach_config.prach_sub_c_spacing.value = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; cfg->prach_config.prach_sub_c_spacing.tl.tag = NFAPI_NR_CONFIG_PRACH_SUB_C_SPACING_TAG; cfg->num_tlv++; - cfg->prach_config.restricted_set_config.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig; cfg->prach_config.restricted_set_config.tl.tag = NFAPI_NR_CONFIG_RESTRICTED_SET_CONFIG_TAG; cfg->num_tlv++; @@ -192,13 +205,17 @@ void config_common(int Mod_idP, int pdsch_AntennaPorts, NR_ServingCellConfigComm cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig; cfg->prach_config.num_prach_fd_occasions_list[i].prach_zero_corr_conf.tl.tag = NFAPI_NR_CONFIG_PRACH_ZERO_CORR_CONF_TAG; cfg->num_tlv++; + cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.value = compute_nr_root_seq(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup, + nb_preambles, frame_type); + cfg->prach_config.num_prach_fd_occasions_list[i].num_root_sequences.tl.tag = NFAPI_NR_CONFIG_NUM_ROOT_SEQUENCES_TAG; + cfg->num_tlv++; //cfg->prach_config.num_prach_fd_occasions_list[i].num_unused_root_sequences.value = ??? } - cfg->prach_config.ssb_per_rach.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present; + cfg->prach_config.ssb_per_rach.value = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->ssb_perRACH_OccasionAndCB_PreamblesPerSSB->present-1; cfg->prach_config.ssb_per_rach.tl.tag = NFAPI_NR_CONFIG_SSB_PER_RACH_TAG; cfg->num_tlv++; - + // SSB Table Configuration int scs_scaling = 1<<(cfg->ssb_config.scs_common.value); if (scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA < 600000) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index ff89069942..55998e1c1b 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" @@ -59,10 +59,9 @@ #include "executables/softmodem-common.h" +const uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160}; uint16_t nr_pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; -uint8_t nr_slots_per_frame[5] = {10, 20, 40, 80, 160}; - void clear_nr_nfapi_information(gNB_MAC_INST * gNB, int CC_idP, frame_t frameP, @@ -259,18 +258,6 @@ void schedule_nr_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subfram } */ -/* -void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { - - gNB_MAC_INST *gNB = RC.nrmac[module_idP]; - - // schedule PRACH for iniital BWP - - if (is_initialBWP_prach_subframe(frameP,subframeP)<0) return; - - // fill FAPI -} -*/ /* void copy_nr_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) @@ -437,8 +424,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, for (i = 0; i < MAX_MOBILES_PER_GNB; i++) { if (UE_list->active[i]) { - nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id]; - + nfapi_nr_config_request_t *cfg = &RC.nrmac[module_idP]->config[CC_id]; rnti = 0;//UE_RNTI(module_idP, i); CC_id = 0;//UE_PCCID(module_idP, i); @@ -446,7 +432,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, } //END if (UE_list->active[i]) } //END for (i = 0; i < MAX_MOBILES_PER_GNB; i++) */ - + // This schedules MIB if((slot_txP == 0) && (frame_txP & 7) == 0){ schedule_nr_mib(module_idP, frame_txP, slot_txP); @@ -466,6 +452,9 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, gNB->ta_len = 2; } + if (get_softmodem_params()->phy_test == 0) + nr_schedule_RA(module_idP, frame_txP, slot_txP); + // Phytest scheduling if (get_softmodem_params()->phy_test && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot_txP%num_slots_per_tdd))) { nr_update_pucch_scheduling(module_idP, UE_id, frame_txP, slot_txP, num_slots_per_tdd,pucch_sched); @@ -474,6 +463,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, gNB->ta_len = 0; } + /* // Allocate CCEs for good after scheduling is done for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) @@ -484,6 +474,10 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, if (is_nr_UL_slot(cc->ServingCellConfigCommon,slot_rxP)) { + if (get_softmodem_params()->phy_test == 0) { + schedule_nr_prach(module_idP, (frame_rxP+1)&1023, slot_rxP); + nr_schedule_reception_msg3(module_idP, 0, frame_rxP, slot_rxP); + } if (get_softmodem_params()->phy_test){ nr_schedule_pucch(module_idP, UE_id, frame_rxP, slot_rxP); if (is_xlsch_in_slot(*ulsch_in_slot_bitmap,slot_rxP%num_slots_per_tdd)){ diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index d74df15eac..956ca090e8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -19,44 +19,784 @@ * 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" -void -schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) -{ +/* MAC */ +#include "nr_mac_gNB.h" +#include "NR_MAC_gNB/mac_proto.h" +#include "NR_MAC_COMMON/nr_mac_extern.h" - eNB_MAC_INST *mac = RC.mac[module_idP]; - COMMON_channels_t *cc = mac->common_channels; - RA_t *ra; - uint8_t i; +/* Utils */ +#include "common/utils/LOG/log.h" +#include "common/utils/LOG/vcd_signal_dumper.h" +#include "common/utils/nr/nr_common.h" +#include "UTIL/OPT/opt.h" +#include "SIMULATION/TOOLS/sim.h" // for taus + +extern RAN_CONTEXT_t RC; + +const uint8_t nr_slots_per_frame_mac[5] = {10, 20, 40, 80, 160}; +uint8_t DELTA[4]= {2,3,4,6}; + +void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP) { + + gNB_MAC_INST *gNB = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = gNB->common_channels; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[module_idP]->UL_tti_req[0]; + + uint8_t config_index = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.prach_ConfigurationIndex; + uint8_t mu,N_dur,N_t_slot,start_symbol; + uint16_t format; + + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing) + mu = *scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg1_SubcarrierSpacing; + else + mu = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing; + + // prach is scheduled according to configuration index and tables 6.3.3.2.2 to 6.3.3.2.4 + if ( get_nr_prach_info_from_index(config_index, + (int)frameP, + (int)slotP, + scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA, + mu, + cc->frame_type, + &format, + &start_symbol, + &N_t_slot, + &N_dur) ) { + + int fdm = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.msg1_FDM; + uint16_t format0 = format&0xff; // first column of format from table + uint16_t format1 = (format>>8)&0xff; // second column of format from table + + UL_tti_req->SFN = frameP; + UL_tti_req->Slot = slotP; + for (int n=0; n<(1<pdus_list[UL_tti_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PRACH_PDU_TYPE; + UL_tti_req->pdus_list[UL_tti_req->n_pdus].pdu_size = sizeof(nfapi_nr_prach_pdu_t); + nfapi_nr_prach_pdu_t *prach_pdu = &UL_tti_req->pdus_list[UL_tti_req->n_pdus].prach_pdu; + memset(prach_pdu,0,sizeof(nfapi_nr_prach_pdu_t)); + UL_tti_req->n_pdus+=1; + + // filling the prach fapi structure + prach_pdu->phys_cell_id = *scc->physCellId; + prach_pdu->num_prach_ocas = N_t_slot; + prach_pdu->prach_start_symbol = start_symbol; + prach_pdu->num_ra = n; + prach_pdu->num_cs = get_NCS(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.zeroCorrelationZoneConfig, + format0, + scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->restrictedSetConfig); + // SCF PRACH PDU format field does not consider A1/B1 etc. possibilities + // We added 9 = A1/B1 10 = A2/B2 11 A3/B3 + if (format1!=0xff) { + switch(format0) { + case 0xa1: + prach_pdu->prach_format = 9; + break; + case 0xa2: + prach_pdu->prach_format = 10; + break; + case 0xa3: + prach_pdu->prach_format = 11; + break; + default: + AssertFatal(1==0,"Only formats A1/B1 A2/B2 A3/B3 are valid for dual format"); + } + } + else{ + switch(format0) { + case 0xa1: + prach_pdu->prach_format = 0; + break; + case 0xa2: + prach_pdu->prach_format = 1; + break; + case 0xa3: + prach_pdu->prach_format = 2; + break; + case 0xb1: + prach_pdu->prach_format = 3; + break; + case 0xb2: + prach_pdu->prach_format = 4; + break; + case 0xb3: + prach_pdu->prach_format = 5; + break; + case 0xb4: + prach_pdu->prach_format = 6; + break; + case 0xc0: + prach_pdu->prach_format = 7; + break; + case 0xc2: + prach_pdu->prach_format = 8; + break; + case 0: + // long formats are handled @ PHY + break; + case 1: + // long formats are handled @ PHY + break; + case 2: + // long formats are handled @ PHY + break; + case 3: + // long formats are handled @ PHY + break; + default: + AssertFatal(1==0,"Invalid PRACH format"); + } + } + } + } +} + + +void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, + uint16_t *msg2_frame, uint16_t *msg2_slot, + NR_ServingCellConfigCommon_t *scc, + uint16_t monitoring_slot_period, + uint16_t monitoring_offset){ + + // preferentially we schedule the msg2 in the mixed slot or in the last dl slot + // if they are allowed by search space configuration + + uint8_t mu = *scc->ssbSubcarrierSpacing; + uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow; + uint8_t slot_window; + // number of mixed slot or of last dl slot if there is no mixed slot + uint8_t last_dl_slot_period = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; + // lenght of tdd period in slots + uint8_t tdd_period_slot = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; + if (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols == 0) + last_dl_slot_period--; + if ((scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols > 0) || (scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols > 0)) + tdd_period_slot++; + + // computing start of next period + uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame_mac[mu]; + *msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot + *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1); + + switch(response_window){ + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1: + slot_window = 1; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2: + slot_window = 2; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4: + slot_window = 4; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8: + slot_window = 8; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10: + slot_window = 10; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20: + slot_window = 20; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40: + slot_window = 40; + break; + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80: + slot_window = 80; + break; + default: + AssertFatal(1==0,"Invalid response window value %d\n",response_window); + } + AssertFatal(slot_window<=nr_slots_per_frame_mac[mu],"Msg2 response window needs to be lower or equal to 10ms"); + + // slot and frame limit to transmit msg2 according to response window + uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame_mac[mu]; + uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1); + + // go to previous slot if the current scheduled slot is beyond the response window + // and if the slot is not among the PDCCH monitored ones (38.213 10.1) + while ((*msg2_slot>slot_limit) || ((*msg2_frame*nr_slots_per_frame_mac[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) { + if((*msg2_slot%tdd_period_slot) > 0) + *msg2_slot--; + else + AssertFatal(1==0,"No available DL slot to schedule msg2 has been found"); + } +} + + +void nr_initiate_ra_proc(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP, + uint16_t preamble_index, + uint8_t freq_index, + uint8_t symbol, + int16_t timing_offset){ + + uint8_t ul_carrier_id = 0; // 0 for NUL 1 for SUL + NR_SearchSpace_t *ss; + + // ra_rnti from 5.1.3 in 38.321 + uint16_t ra_rnti=1+symbol+(slotP*14)+(freq_index*14*80)+(ul_carrier_id*14*80*8); + + + + uint16_t msg2_frame, msg2_slot,monitoring_slot_period,monitoring_offset; + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + NR_UE_list_t *UE_list = &nr_mac->UE_list; + NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[0]; + NR_COMMON_channels_t *cc = &nr_mac->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_RA_t *ra = &cc->ra[0]; + + // This should be handled differently when we use the initialBWP for RA + ra->bwp_id=1; + NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); + + LOG_I(MAC, "[gNB %d][RAPROC] CC_id %d Frame %d, Slot %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, slotP, preamble_index); + + if (ra->state == RA_IDLE) { + int loop = 0; + LOG_D(MAC, "Frame %d, Slot %d: Activating RA process \n", frameP, slotP); + ra->state = Msg2; + ra->timing_offset = timing_offset; + ra->preamble_slot = slotP; + + struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + AssertFatal(commonSearchSpaceList->list.count>0, + "common SearchSpace list has 0 elements\n"); + // Common searchspace list + for (int i=0;ilist.count;i++) { + ss=commonSearchSpaceList->list.array[i]; + if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace) + ra->ra_ss=ss; + } + + // retrieving ra pdcch monitoring period and offset + find_monitoring_periodicity_offset_common(ra->ra_ss, + &monitoring_slot_period, + &monitoring_offset); + + nr_schedule_msg2(frameP, slotP, &msg2_frame, &msg2_slot, scc, monitoring_slot_period, monitoring_offset); + + ra->Msg2_frame = msg2_frame; + ra->Msg2_slot = msg2_slot; + + LOG_D(MAC, "%s() Msg2[%04d%d] SFN/SF:%04d%d\n", __FUNCTION__, ra->Msg2_frame, ra->Msg2_slot, frameP, slotP); + + do { + ra->rnti = (taus() % 65518) + 1; + loop++; + } + while (loop != 100 && !(find_nr_UE_id(module_idP, ra->rnti) == -1 && ra->rnti >= 1 && ra->rnti <= 65519)); + if (loop == 100) { + LOG_E(MAC,"%s:%d:%s: [RAPROC] initialisation random access aborted\n", __FILE__, __LINE__, __FUNCTION__); + abort(); + } + + ra->RA_rnti = ra_rnti; + ra->preamble_index = preamble_index; + + + LOG_I(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Activating Msg2 generation in frame %d, slot %d using RA rnti %x\n", + module_idP, + CC_id, + frameP, + ra->Msg2_frame, + ra->Msg2_slot, + ra->RA_rnti); + + 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); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); +} + +void nr_schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t slotP){ + + //uint8_t i = 0; + int CC_id = 0; + gNB_MAC_INST *mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + NR_RA_t *ra = &cc->ra[0]; start_meas(&mac->schedule_ra); + //for (i = 0; i < NR_NB_RA_PROC_MAX; i++) { + LOG_D(MAC,"RA[state:%d]\n",ra->state); + switch (ra->state){ + case Msg2: + nr_generate_Msg2(module_idP, CC_id, frameP, slotP); + break; + case Msg4: + //generate_Msg4(module_idP, CC_id, frameP, slotP, ra); + break; + case WAIT_Msg4_ACK: + //check_Msg4_retransmission(module_idP, CC_id, frameP, slotP, ra); + break; + default: + break; + } + //} + stop_meas(&mac->schedule_ra); +} - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { +void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc, + NR_BWP_Uplink_t *ubwp, + sub_frame_t current_slot, + frame_t current_frame, + NR_RA_t *ra) { - for (i = 0; i < NB_RA_PROC_MAX; i++) { + // msg3 is schedulend in mixed slot in the following TDD period + // for now we consider a TBS of 18 bytes - ra = (RA_t *) & cc[CC_id].ra[i]; - //LOG_D(MAC,"RA[state:%d]\n",ra->state); + int mu = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + int StartSymbolIndex, NrOfSymbols, startSymbolAndLength, temp_slot; + ra->Msg3_tda_id = 16; // initialization to a value above limit - if (ra->state == MSG2) - generate_Msg2(module_idP, CC_id, frameP, subframeP, ra); - else if (ra->state == MSG4) - generate_Msg4(module_idP, CC_id, frameP, subframeP, ra); - else if (ra->state == WAITMSG4ACK) - check_Msg4_retransmission(module_idP, CC_id, frameP, subframeP, ra); + for (int i=0; ibwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.count; i++) { + startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, &StartSymbolIndex, &NrOfSymbols); + // we want to transmit in the uplink symbols of mixed slot + if (NrOfSymbols == scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols) { + ra->Msg3_tda_id = i; + break; + } + } + AssertFatal(ra->Msg3_tda_id<16,"Unable to find Msg3 time domain allocation in list\n"); - } // for i=0 .. N_RA_PROC-1 - } // CC_id + uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2; - stop_meas(&mac->schedule_ra); + temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213 + ra->Msg3_slot = temp_slot%nr_slots_per_frame_mac[mu]; + if (nr_slots_per_frame_mac[mu]>temp_slot) + ra->Msg3_frame = current_frame; + else + ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame_mac[mu]); + + ra->msg3_nb_rb = 18; + ra->msg3_first_rb = 0; +} + + +void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){ + gNB_MAC_INST *mac = RC.nrmac[module_idP]; + nfapi_nr_ul_tti_request_t *ul_req = &mac->UL_tti_req[0]; + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + NR_RA_t *ra = &cc->ra[0]; + + if (ra->state == WAIT_Msg3) { + if ((frameP == ra->Msg3_frame) && (slotP == ra->Msg3_slot) ){ + ul_req->SFN = ra->Msg3_frame; + ul_req->Slot = ra->Msg3_slot; + ul_req->pdus_list[ul_req->n_pdus].pdu_type = NFAPI_NR_UL_CONFIG_PUSCH_PDU_TYPE; + ul_req->pdus_list[ul_req->n_pdus].pdu_size = sizeof(nfapi_nr_pusch_pdu_t); + ul_req->pdus_list[ul_req->n_pdus].pusch_pdu = ra->pusch_pdu; + ul_req->n_pdus+=1; + } + } +} + +void nr_add_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP){ + + gNB_MAC_INST *mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &mac->common_channels[CC_id]; + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + NR_RA_t *ra = &cc->ra[0]; + NR_UE_list_t *UE_list = &mac->UE_list; + int UE_id = 0; + + AssertFatal(ra->state != RA_IDLE, "RA is not active for RA %X\n", ra->rnti); + + LOG_D(MAC, "[gNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d RA is active, Msg3 in (%d,%d)\n", module_idP, frameP, slotP, CC_id, ra->Msg3_frame, ra->Msg3_slot); + + nfapi_nr_pusch_pdu_t *pusch_pdu = &ra->pusch_pdu; + memset(pusch_pdu, 0, sizeof(nfapi_nr_pusch_pdu_t)); + + + AssertFatal(UE_list->active[UE_id] >=0,"Cannot find UE_id %d is not active\n", UE_id); + + NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + LOG_D(MAC, "Frame %d, Subframe %d Adding Msg3 UL Config Request for (%d,%d) : (%d,%d,%d) for rnti: %d\n", + frameP, + slotP, + ra->Msg3_frame, + ra->Msg3_slot, + ra->msg3_nb_rb, + ra->msg3_first_rb, + ra->msg3_round, + ra->rnti); + + int startSymbolAndLength = ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->startSymbolAndLength; + int start_symbol_index,nr_of_symbols; + SLIV2SL(startSymbolAndLength, &start_symbol_index, &nr_of_symbols); + + pusch_pdu->pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + pusch_pdu->rnti = ra->rnti; + pusch_pdu->handle = 0; + int abwp_size = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + int abwp_start = NRRIV2PRBOFFSET(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275); + int ibwp_size = NRRIV2BW(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275); + int ibwp_start = NRRIV2PRBOFFSET(scc->uplinkConfigCommon->initialUplinkBWP->genericParameters.locationAndBandwidth,275); + if ((ibwp_start < abwp_start) || (ibwp_size > abwp_size)) + pusch_pdu->bwp_start = abwp_start; + else + pusch_pdu->bwp_start = ibwp_start; + pusch_pdu->bwp_size = ibwp_size; + pusch_pdu->subcarrier_spacing = ubwp->bwp_Common->genericParameters.subcarrierSpacing; + pusch_pdu->cyclic_prefix = 0; + pusch_pdu->mcs_index = 0; + pusch_pdu->mcs_table = 0; + pusch_pdu->target_code_rate = nr_get_code_rate_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + pusch_pdu->qam_mod_order = nr_get_Qm_ul(pusch_pdu->mcs_index,pusch_pdu->mcs_table); + if (scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) + pusch_pdu->transform_precoding = 1; + else + pusch_pdu->transform_precoding = 0; + pusch_pdu->data_scrambling_id = *scc->physCellId; + pusch_pdu->nrOfLayers = 1; + pusch_pdu->ul_dmrs_symb_pos = 1<dmrs_config_type = 0; + pusch_pdu->ul_dmrs_scrambling_id = *scc->physCellId; //If provided and the PUSCH is not a msg3 PUSCH, otherwise, L2 should set this to physical cell id. + pusch_pdu->scid = 0; //DMRS sequence initialization [TS38.211, sec 6.4.1.1.1]. Should match what is sent in DCI 0_1, otherwise set to 0. + pusch_pdu->dmrs_ports = 1; // 6.2.2 in 38.214 only port 0 to be used + pusch_pdu->num_dmrs_cdm_grps_no_data = 2; // no data in dmrs symbols as in 6.2.2 in 38.214 + pusch_pdu->resource_alloc = 1; //type 1 + pusch_pdu->rb_start = ra->msg3_first_rb + ibwp_start - abwp_start; // as for 6.3.1.7 in 38.211 + if (ra->msg3_nb_rb > pusch_pdu->bwp_size) + AssertFatal(1==0,"MSG3 allocated number of RBs exceed the BWP size\n"); + else + pusch_pdu->rb_size = ra->msg3_nb_rb; + pusch_pdu->vrb_to_prb_mapping = 0; + if (ubwp->bwp_Dedicated->pusch_Config->choice.setup->frequencyHopping == NULL) + pusch_pdu->frequency_hopping = 0; + else + pusch_pdu->frequency_hopping = 1; + //pusch_pdu->tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE] + pusch_pdu->uplink_frequency_shift_7p5khz = 0; + //Resource Allocation in time domain + pusch_pdu->start_symbol_index = start_symbol_index; + pusch_pdu->nr_of_symbols = nr_of_symbols; + //Optional Data only included if indicated in pduBitmap + pusch_pdu->pusch_data.rv_index = 0; // 8.3 in 38.213 + pusch_pdu->pusch_data.harq_process_id = 0; + pusch_pdu->pusch_data.new_data_indicator = 1; // new data + pusch_pdu->pusch_data.num_cb = 0; + pusch_pdu->pusch_data.tb_size = nr_compute_tbs(pusch_pdu->qam_mod_order, + pusch_pdu->target_code_rate, + pusch_pdu->rb_size, + pusch_pdu->nr_of_symbols, + 12, // nb dmrs set for no data in dmrs symbol + 0, //nb_rb_oh + 0, // to verify tb scaling + pusch_pdu->nrOfLayers = 1)>>3; + + // calling function to fill rar message + nr_fill_rar(module_idP, ra, cc->RAR_pdu.payload, pusch_pdu); + +} + +// WIP +// todo: +// - fix me +// - get msg3 alloc (see nr_process_rar) +void nr_generate_Msg2(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP){ + + int UE_id = 0, dci_formats[2], rnti_types[2], mcsIndex; + int startSymbolAndLength = 0, StartSymbolIndex = -1, NrOfSymbols = 14, StartSymbolIndex_tmp, NrOfSymbols_tmp, x_Overhead, time_domain_assignment; + gNB_MAC_INST *nr_mac = RC.nrmac[module_idP]; + NR_COMMON_channels_t *cc = &nr_mac->common_channels[0]; + NR_RA_t *ra = &cc->ra[0]; + NR_UE_list_t *UE_list = &nr_mac->UE_list; + NR_SearchSpace_t *ss = ra->ra_ss; + + uint16_t RA_rnti = ra->RA_rnti; + long locationAndBandwidth; + // uint8_t *vrb_map = cc[CC_id].vrb_map, CC_id; + + // check if UE is doing RA on CORESET0 , InitialBWP or configured BWP from SCD + // get the BW of the PDCCH for PDCCH size and RAR PDSCH size + + NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; + int dci10_bw; + + if (ra->coreset0_configured == 1) { + AssertFatal(1==0,"This is a standalone condition\n"); + } + else { // on configured BWP or initial LDBWP, bandwidth parameters in DCI correspond size of initialBWP + locationAndBandwidth = scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth; + dci10_bw = NRRIV2BW(locationAndBandwidth,275); + } + + if ((ra->Msg2_frame == frameP) && (ra->Msg2_slot == slotP)) { + + nfapi_nr_dl_tti_request_body_t *dl_req = &nr_mac->DL_req[CC_id].dl_tti_request_body; + nfapi_nr_pdu_t *tx_req = &nr_mac->TX_req[CC_id].pdu_list[nr_mac->TX_req[CC_id].Number_of_PDUs]; + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; + memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdcch_pdu->PDUType = NFAPI_NR_DL_TTI_PDCCH_PDU_TYPE; + dl_tti_pdcch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdcch_pdu)); + + nfapi_nr_dl_tti_request_pdu_t *dl_tti_pdsch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs+1]; + memset((void *)dl_tti_pdsch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); + dl_tti_pdsch_pdu->PDUType = NFAPI_NR_DL_TTI_PDSCH_PDU_TYPE; + dl_tti_pdsch_pdu->PDUSize = (uint8_t)(2+sizeof(nfapi_nr_dl_tti_pdsch_pdu)); + + nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15 = &dl_tti_pdcch_pdu->pdcch_pdu.pdcch_pdu_rel15; + nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_pdu_rel15 = &dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15; + + // Checking if the DCI allocation is feasible in current subframe + if (dl_req->nPDUs == NFAPI_NR_MAX_DL_TTI_PDUS) { + LOG_I(MAC, "[RAPROC] Subframe %d: FAPI DL structure is full, skip scheduling UE %d\n", slotP, RA_rnti); + return; + } + + LOG_I(MAC,"[gNB %d] [RAPROC] CC_id %d Frame %d, slotP %d: Generating RAR DCI, state %d\n", module_idP, CC_id, frameP, slotP, ra->state); + + // This code from this point on will not work on initialBWP or CORESET0 + AssertFatal(ra->bwp_id>0,"cannot work on initialBWP for now\n"); + + NR_CellGroupConfig_t *secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + AssertFatal(secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count == 1, + "downlinkBWP_ToAddModList has %d BWP!\n", secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); + NR_BWP_Downlink_t *bwp = secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[ra->bwp_id - 1]; + NR_BWP_Uplink_t *ubwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->uplinkConfig->uplinkBWP_ToAddModList->list.array[ra->bwp_id-1]; + + LOG_D(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw); + + mcsIndex = 0; // Qm>2 not allowed for RAR + + pdsch_pdu_rel15->pduBitmap = 0; + pdsch_pdu_rel15->rnti = RA_rnti; + pdsch_pdu_rel15->pduIndex = 0; + + + pdsch_pdu_rel15->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pdsch_pdu_rel15->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); + pdsch_pdu_rel15->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; + pdsch_pdu_rel15->CyclicPrefix = 0; + pdsch_pdu_rel15->NrOfCodewords = 1; + pdsch_pdu_rel15->targetCodeRate[0] = nr_get_code_rate_dl(mcsIndex,0); + pdsch_pdu_rel15->qamModOrder[0] = 2; + pdsch_pdu_rel15->mcsIndex[0] = mcsIndex; + if (bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL) + pdsch_pdu_rel15->mcsTable[0] = 0; + else{ + if (*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == 0) + pdsch_pdu_rel15->mcsTable[0] = 1; + else + pdsch_pdu_rel15->mcsTable[0] = 2; + } + pdsch_pdu_rel15->rvIndex[0] = 0; + pdsch_pdu_rel15->dataScramblingId = *scc->physCellId; + pdsch_pdu_rel15->nrOfLayers = 1; + pdsch_pdu_rel15->transmissionScheme = 0; + pdsch_pdu_rel15->refPoint = 0; + pdsch_pdu_rel15->dmrsConfigType = 0; + pdsch_pdu_rel15->dlDmrsScramblingId = *scc->physCellId; + pdsch_pdu_rel15->SCID = 0; + pdsch_pdu_rel15->numDmrsCdmGrpsNoData = 2; + pdsch_pdu_rel15->dmrsPorts = 1; + pdsch_pdu_rel15->resourceAlloc = 1; + pdsch_pdu_rel15->rbStart = 0; + pdsch_pdu_rel15->rbSize = 6; + pdsch_pdu_rel15->VRBtoPRBMapping = 0; // non interleaved + + for (int i=0; ibwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.count; i++) { + startSymbolAndLength = bwp->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList->list.array[i]->startSymbolAndLength; + SLIV2SL(startSymbolAndLength, &StartSymbolIndex_tmp, &NrOfSymbols_tmp); + if (NrOfSymbols_tmp < NrOfSymbols) { + NrOfSymbols = NrOfSymbols_tmp; + StartSymbolIndex = StartSymbolIndex_tmp; + time_domain_assignment = i; // this is short PDSCH added to the config to fit mixed slot + } + } + + AssertFatal(StartSymbolIndex >= 0, "StartSymbolIndex is negative\n"); + + pdsch_pdu_rel15->StartSymbolIndex = StartSymbolIndex; + pdsch_pdu_rel15->NrOfSymbols = NrOfSymbols; + pdsch_pdu_rel15->dlDmrsSymbPos = fill_dmrs_mask(NULL, scc->dmrs_TypeA_Position, NrOfSymbols); + + dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET]; + dci_pdu_rel15[0].frequency_domain_assignment.val = PRBalloc_to_locationandbandwidth0(pdsch_pdu_rel15->rbSize, + pdsch_pdu_rel15->rbStart,dci10_bw); + dci_pdu_rel15[0].time_domain_assignment.val = time_domain_assignment; + dci_pdu_rel15[0].vrb_to_prb_mapping.val = 0; + dci_pdu_rel15[0].mcs = pdsch_pdu_rel15->mcsIndex[0]; + dci_pdu_rel15[0].tb_scaling = 0; + + LOG_I(MAC, "[RAPROC] DCI type 1 payload: freq_alloc %d (%d,%d,%d), time_alloc %d, vrb to prb %d, mcs %d tb_scaling %d \n", + dci_pdu_rel15[0].frequency_domain_assignment.val, + pdsch_pdu_rel15->rbStart, + pdsch_pdu_rel15->rbSize, + dci10_bw, + dci_pdu_rel15[0].time_domain_assignment.val, + dci_pdu_rel15[0].vrb_to_prb_mapping.val, + dci_pdu_rel15[0].mcs, + dci_pdu_rel15[0].tb_scaling); + + nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, RA_rnti, 0, ss, scc, bwp); + + LOG_I(MAC, "Frame %d: Subframe %d : Adding common DL DCI for RA_RNTI %x\n", frameP, slotP, RA_rnti); + + dci_formats[0] = NR_DL_DCI_FORMAT_1_0; + rnti_types[0] = NR_RNTI_RA; + + LOG_D(MAC, "[RAPROC] DCI params: rnti %d, rnti_type %d, dci_format %d coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", + pdcch_pdu_rel15->dci_pdu.RNTI[0], + rnti_types[0], + dci_formats[0], + (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, + pdcch_pdu_rel15->StartSymbolIndex, + pdcch_pdu_rel15->DurationSymbols); + + pdcch_pdu_rel15->numDlDci++; + fill_dci_pdu_rel15(secondaryCellGroup,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types,dci10_bw,ra->bwp_id); + + dl_req->nPDUs+=2; + + // Program UL processing for Msg3 + nr_get_Msg3alloc(scc, ubwp, slotP, frameP, ra); + LOG_I(MAC, "Frame %d, Subframe %d: Setting Msg3 reception for Frame %d Subframe %d\n", frameP, slotP, ra->Msg3_frame, ra->Msg3_slot); + nr_add_msg3(module_idP, CC_id, frameP, slotP); + ra->state = WAIT_Msg3; + LOG_D(MAC,"[gNB %d][RAPROC] Frame %d, Subframe %d: RA state %d\n", module_idP, frameP, slotP, ra->state); + + x_Overhead = 0; + nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead, 1, dci_pdu_rel15[0].tb_scaling); + + // DL TX request + tx_req->PDU_length = pdsch_pdu_rel15->TBSize[0]; + tx_req->PDU_index = nr_mac->pdu_index[CC_id]++; + tx_req->num_TLV = 1; + tx_req->TLVs[0].length = 8; + nr_mac->TX_req[CC_id].SFN = frameP; + nr_mac->TX_req[CC_id].Number_of_PDUs++; + nr_mac->TX_req[CC_id].Slot = slotP; + memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&cc[CC_id].RAR_pdu.payload[0], tx_req->TLVs[0].length); + } +} + +void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP){ + NR_RA_t *ra = &RC.nrmac[module_idP]->common_channels[CC_id].ra[0]; + LOG_D(MAC,"[gNB %d][RAPROC] CC_id %d Frame %d Clear Random access information rnti %x\n", module_idP, CC_id, frameP, ra->rnti); + ra->state = IDLE; + ra->timing_offset = 0; + ra->RRC_timer = 20; + ra->rnti = 0; + ra->msg3_round = 0; +} + + +///////////////////////////////////// +// Random Access Response PDU // +// TS 38.213 ch 8.2 // +// TS 38.321 ch 6.2.3 // +///////////////////////////////////// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise +//| E | T | R A P I D |// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// +//| R | T A |// +//| T A | UL grant |// +//| UL grant |// +//| UL grant |// +//| UL grant |// +//| T C - R N T I |// +//| T C - R N T I |// +///////////////////////////////////// +// UL grant (27 bits) // +///////////////////////////////////// +//| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |// bit-wise +//|-------------------|FHF|F_alloc|// +//| Freq allocation |// +//| F_alloc |Time allocation|// +//| MCS | TPC |CSI|// +///////////////////////////////////// +// WIP +// todo: +// - handle MAC RAR BI subheader +// - sending only 1 RAR subPDU +// - UL Grant: hardcoded CSI, TPC, time alloc +// - padding +void nr_fill_rar(uint8_t Mod_idP, + NR_RA_t * ra, + uint8_t * dlsch_buffer, + nfapi_nr_pusch_pdu_t *pusch_pdu){ + + LOG_D(MAC, "[gNB] Generate RAR MAC PDU frame %d slot %d ", ra->Msg2_frame, ra-> Msg2_slot); + NR_RA_HEADER_RAPID *rarh = (NR_RA_HEADER_RAPID *) dlsch_buffer; + NR_MAC_RAR *rar = (NR_MAC_RAR *) (dlsch_buffer + 1); + unsigned char csi_req = 0, tpc_command; + uint8_t N_UL_Hop, valid_bits; + uint32_t ul_grant; + uint16_t f_alloc, prb_alloc, bwp_size, truncation=0; + + tpc_command = 3; // this is 0 dB + + /// E/T/RAPID subheader /// + // E = 0, one only RAR, first and last + // T = 1, RAPID + rarh->E = 0; + rarh->T = 1; + rarh->RAPID = ra->preamble_index; + + /// RAR MAC payload /// + rar->R = 0; + + // TA command + rar->TA1 = (uint8_t) (ra->timing_offset >> 5); // 7 MSBs of timing advance + rar->TA2 = (uint8_t) (ra->timing_offset & 0x1f); // 5 LSBs of timing advance + + // TC-RNTI + rar->TCRNTI_1 = (uint8_t) (ra->rnti >> 8); // 8 MSBs of rnti + rar->TCRNTI_2 = (uint8_t) (ra->rnti & 0xff); // 8 LSBs of rnti + + // UL grant + + ra->msg3_TPC = tpc_command; + + bwp_size = pusch_pdu->bwp_size; + prb_alloc = PRBalloc_to_locationandbandwidth0(ra->msg3_nb_rb, ra->msg3_first_rb, bwp_size); + if (bwp_size>180) { + AssertFatal(1==0,"Initial UBWP larger than 180 currently not supported"); + } + else { + valid_bits = (uint8_t)ceil(log2(bwp_size*(bwp_size+1)>>1)); + } + + if (pusch_pdu->frequency_hopping){ + AssertFatal(1==0,"PUSCH with frequency hopping currently not supported"); + } else { + for (int i=0; imcs_index << 4) | (ra->Msg3_tda_id << 8) | (f_alloc << 12) | (pusch_pdu->frequency_hopping << 26); + + rar->UL_GRANT_1 = (uint8_t) (ul_grant >> 24) & 0x07; + rar->UL_GRANT_2 = (uint8_t) (ul_grant >> 16) & 0xff; + rar->UL_GRANT_3 = (uint8_t) (ul_grant >> 8) & 0xff; + rar->UL_GRANT_4 = (uint8_t) ul_grant & 0xff; + } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_bch.c index 2a36425fae..5fa77c6ca7 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 5233270149..7777e307fb 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*/ @@ -44,6 +44,9 @@ /*TAG*/ #include "NR_TAG-Id.h" +//////////////////////////////////////////////////////// +/////* DLSCH MAC PDU generation (6.1.2 TS 38.321) *///// +//////////////////////////////////////////////////////// int nr_generate_dlsch_pdu(module_id_t module_idP, unsigned char *sdus_payload, @@ -61,7 +64,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, unsigned char * dlsch_buffer_ptr = sdus_payload; uint8_t last_size = 0; int offset = 0, mac_ce_size, i, timing_advance_cmd, tag_id = 0; - // MAC CEs uint8_t mac_header_control_elements[16], *ce_ptr; ce_ptr = &mac_header_control_elements[0]; @@ -97,6 +99,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 @@ -105,7 +108,6 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, mac_pdu_ptr += (unsigned char) mac_ce_size; } - // Contention resolution fixed subheader and MAC CE if (ue_cont_res_id) { mac_pdu_ptr->R = 0; @@ -130,8 +132,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, mac_pdu_ptr += (unsigned char) mac_ce_size; } - - // 2) Generation of DLSCH MAC SDU subheaders + // 2) Generation of DLSCH MAC subPDUs including subheaders and MAC SDUs for (i = 0; i < num_sdus; i++) { LOG_D(MAC, "[gNB] Generate DLSCH header num sdu %d len sdu %d\n", num_sdus, sdu_lengths[i]); @@ -152,14 +153,14 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, mac_pdu_ptr += last_size; - // 3) cycle through SDUs, compute each relevant and place dlsch_buffer in + // 3) cycle through SDUs, compute each relevant and place dlsch_buffer in memcpy((void *) mac_pdu_ptr, (void *) dlsch_buffer_ptr, sdu_lengths[i]); dlsch_buffer_ptr+= sdu_lengths[i]; mac_pdu_ptr += sdu_lengths[i]; } // 4) Compute final offset for padding - if (post_padding > 0) { + if (post_padding > 0) { ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->R = 0; ((NR_MAC_SUBHEADER_FIXED *) mac_pdu_ptr)->LCID = DL_SCH_LCID_PADDING; mac_pdu_ptr++; @@ -170,7 +171,7 @@ int nr_generate_dlsch_pdu(module_id_t module_idP, // compute final offset offset = ((unsigned char *) mac_pdu_ptr - mac_pdu); - + //printf("Offset %d \n", ((unsigned char *) mac_pdu_ptr - mac_pdu)); return offset; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 6b3efae991..a158635848 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" @@ -278,6 +278,9 @@ int configure_fapi_dl_pdu(int Mod_idP, secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count); NR_BWP_Downlink_t *bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, + "searchPsacesToAddModList is empty\n"); dl_tti_pdcch_pdu = &dl_req->dl_tti_pdu_list[dl_req->nPDUs]; memset((void*)dl_tti_pdcch_pdu,0,sizeof(nfapi_nr_dl_tti_request_pdu_t)); @@ -410,10 +413,10 @@ int configure_fapi_dl_pdu(int Mod_idP, nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, UE_list->rnti[UE_id], + 1, // ue-specific ss, scc, bwp); - int dci_formats[2]; int rnti_types[2]; @@ -425,11 +428,11 @@ int configure_fapi_dl_pdu(int Mod_idP, rnti_types[0] = NR_RNTI_C; - fill_dci_pdu_rel15(secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,bwp_id); + fill_dci_pdu_rel15(secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pdsch_pdu_rel15->BWPSize,bwp_id); LOG_D(MAC, "DCI params: rnti %d, rnti_type %d, dci_format %d\n \ coreset params: FreqDomainResource %llx, start_symbol %d n_symb %d\n", - pdcch_pdu_rel15->RNTI[0], + pdcch_pdu_rel15->dci_pdu.RNTI[0], rnti_types[0], dci_formats[0], (unsigned long long)pdcch_pdu_rel15->FreqDomainResource, @@ -437,7 +440,7 @@ int configure_fapi_dl_pdu(int Mod_idP, pdcch_pdu_rel15->DurationSymbols); int x_Overhead = 0; // should be 0 for initialBWP - nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead); + nr_get_tbs_dl(&dl_tti_pdsch_pdu->pdsch_pdu, x_Overhead,1,0); // Hardcode it for now TBS = dl_tti_pdsch_pdu->pdsch_pdu.pdsch_pdu_rel15.TBSize[0]; @@ -472,7 +475,7 @@ void config_uldci(NR_BWP_Uplink_t *ubwp,nfapi_nr_pusch_pdu_t *pusch_pdu,nfapi_nr dci_pdu_rel15->tpc = 2; LOG_D(MAC, "[gNB scheduler phytest] ULDCI type 0 payload: PDCCH CCEIndex %d, freq_alloc %d, time_alloc %d, freq_hop_flag %d, mcs %d tpc %d ndi %d rv %d\n", - pdcch_pdu_rel15->CceIndex[pdcch_pdu_rel15->numDlDci], + pdcch_pdu_rel15->dci_pdu.CceIndex[pdcch_pdu_rel15->numDlDci], dci_pdu_rel15->frequency_domain_assignment.val, dci_pdu_rel15->time_domain_assignment.val, dci_pdu_rel15->frequency_hopping_flag.val, @@ -519,7 +522,7 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP, tx_req->num_TLV = 1; tx_req->TLVs[0].length = tbs_bytes +2; - memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_list.DLSCH_pdu[0][0].payload[0], tbs_bytes);; + memcpy((void*)&tx_req->TLVs[0].value.direct[0], (void*)&nr_mac->UE_list.DLSCH_pdu[0][0].payload[0], tbs_bytes); nr_mac->TX_req[CC_id].Number_of_PDUs++; nr_mac->TX_req[CC_id].SFN = frameP; @@ -638,7 +641,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, //mac_sdus[i] = (unsigned char) rand(); ((uint8_t *)gNB_mac->UE_list.DLSCH_pdu[0][0].payload[0])[i] = (unsigned char) (lrand48()&0xff); } - //Sending SDUs with size 1 //Initialize elements of sdu_lcids and sdu_lengths sdu_lcids[0] = 0x05; // DRB @@ -738,6 +740,9 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, nfapi_nr_ul_tti_request_t *UL_tti_req = &RC.nrmac[Mod_idP]->UL_tti_req[0]; nfapi_nr_ul_dci_request_t *UL_dci_req = &RC.nrmac[Mod_idP]->UL_dci_req[0]; + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList!=NULL,"searchPsacesToAddModList is null\n"); + AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list.count>0, + "searchPsacesToAddModList is empty\n"); uint16_t rnti = UE_list->rnti[UE_id]; nfapi_nr_ul_dci_request_pdus_t *ul_dci_request_pdu; @@ -812,7 +817,9 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, pusch_pdu->nr_of_symbols, 6, //nb_re_dmrs - not sure where this is coming from - its not in the FAPI 0, //nb_rb_oh + 0, pusch_pdu->nrOfLayers)>>3; + pusch_pdu->pusch_data.num_cb = 0; //CBG not supported //pusch_pdu->pusch_data.cb_present_and_position; //pusch_pdu->pusch_uci; @@ -862,6 +869,7 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, nr_configure_pdcch(nr_mac, pdcch_pdu_rel15, UE_list->rnti[UE_id], + 1, // ue-specific, ss, scc, bwp); @@ -870,7 +878,7 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15, &dci_pdu_rel15[0], dci_formats, rnti_types); - fill_dci_pdu_rel15(secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,bwp_id); + fill_dci_pdu_rel15(secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id); } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index eee248e927..1cc55b79ff 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" @@ -135,8 +135,7 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, int aggregation, int search_space, // 0 common, 1 ue-specific int UE_id, - int m - ) { + int m) { // uncomment these when we allocate for common search space // NR_COMMON_channels_t *cc = nr_mac->common_channels; // NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; @@ -148,14 +147,15 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, NR_ControlResourceSet_t *coreset; + AssertFatal(UE_list->active[UE_id] >=0,"UE_id %d is not active\n",UE_id); + secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; + bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; + if (search_space == 1) { - AssertFatal(UE_list->active[UE_id] >=0,"UE_id %d is not active\n",UE_id); - secondaryCellGroup = UE_list->secondaryCellGroup[UE_id]; - bwp=secondaryCellGroup->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[bwp_id-1]; coreset = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[coreset_id]; } else { - AssertFatal(1==0,"Add code for common search space\n"); + coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; } int *cce_list = nr_mac->cce_list[bwp_id][coreset_id]; @@ -412,70 +412,74 @@ void nr_configure_css_dci_initial(nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, void nr_configure_pdcch(gNB_MAC_INST *nr_mac, nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, uint16_t rnti, + int ss_type, NR_SearchSpace_t *ss, NR_ServingCellConfigCommon_t *scc, NR_BWP_Downlink_t *bwp){ int CCEIndex = -1; + + NR_ControlResourceSet_t *coreset = NULL; if (bwp) { // This is not the InitialBWP - /// coreset - - //ControlResourceSetId - // pdcch_pdu->config_type = NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG; - AssertFatal(bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList!=NULL, - "controlResourceSetToAddModList is null\n"); - int num_list = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count; - AssertFatal(num_list>0, - "controlResourceSetToAddModList is empty\n"); - NR_ControlResourceSet_t *coreset; - int coresetid=-1; - for (int i=0;ibwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i]; - if (coreset->controlResourceSetId == *ss->controlResourceSetId) { - coresetid = i; - break; + NR_ControlResourceSet_t *temp_coreset; + NR_ControlResourceSetId_t coresetid = *ss->controlResourceSetId; + if (ss_type == 0) { // common search space + if (coresetid == 0){ + AssertFatal(1==0,"coreset0 currently not supported\n"); + } + else { + coreset = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet; + AssertFatal(coresetid==coreset->controlResourceSetId,"ID of common ss coreset does not correspond to id set in the search space\n"); } } - AssertFatal(coresetid>-1,"Couldn't find a coreset with ID %ld\n",*ss->controlResourceSetId); - + else { + int n_list = bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.count; + for (int i=0; ibwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list.array[i]; + if (coresetid==temp_coreset->controlResourceSetId) { + coreset = temp_coreset; + break; + } + } + if(coreset==NULL) + AssertFatal(1==0,"Couldn't find coreset with id %ld\n",coresetid); + } + pdcch_pdu->BWPSize = NRRIV2BW(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); pdcch_pdu->BWPStart = NRRIV2PRBOFFSET(bwp->bwp_Common->genericParameters.locationAndBandwidth,275); pdcch_pdu->SubcarrierSpacing = bwp->bwp_Common->genericParameters.subcarrierSpacing; pdcch_pdu->CyclicPrefix = (bwp->bwp_Common->genericParameters.cyclicPrefix==NULL) ? 0 : *bwp->bwp_Common->genericParameters.cyclicPrefix; + + + // first symbol + //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored"); + int sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12; + + AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n"); + AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n"); + // for SPS=14 8 MSBs in positions 13 downto 6 + uint16_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | + (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + + for (int i=0; i>(sps-1-i))&1) { + pdcch_pdu->StartSymbolIndex=i; + break; + } + } + pdcch_pdu->DurationSymbols = coreset->duration; - //frequencyDomainResources - /* uint8_t count=0, start=0, start_set=0; - // find coreset descriptor - - uint64_t bitmap = (((uint64_t)coreset->frequencyDomainResources.buf[0])<<37)| - (((uint64_t)coreset->frequencyDomainResources.buf[1])<<29)| - (((uint64_t)coreset->frequencyDomainResources.buf[2])<<21)| - (((uint64_t)coreset->frequencyDomainResources.buf[3])<<13)| - (((uint64_t)coreset->frequencyDomainResources.buf[4])<<5)| - (((uint64_t)coreset->frequencyDomainResources.buf[5])>>3); - - for (int i=0; i<45; i++) - if ((bitmap>>(44-i))&1) { - count++; - if (!start_set) { - start = i; - start_set = 1; - } - } - pdcch_pdu->rb_offset = 6*start; - pdcch_pdu->n_rb = 6*count; - */ for (int i=0;i<6;i++) pdcch_pdu->FreqDomainResource[i] = coreset->frequencyDomainResources.buf[i]; - //duration - + //cce-REG-MappingType pdcch_pdu->CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved? NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED : NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED; + if (pdcch_pdu->CceRegMappingType == NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED) { pdcch_pdu->RegBundleSize = (coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->reg_BundleSize); pdcch_pdu->InterleaverSize = (coreset->cce_REG_MappingType.choice.interleaved->interleaverSize==NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2+coreset->cce_REG_MappingType.choice.interleaved->interleaverSize); @@ -492,51 +496,22 @@ void nr_configure_pdcch(gNB_MAC_INST *nr_mac, //precoderGranularity pdcch_pdu->precoderGranularity = coreset->precoderGranularity; - - //TCI states - // - /* - //TCI present - if (coreset->tci_PresentInDCI != NULL) { - AssertFatal(coreset->tci_StatesPDCCH_ToAddList != NULL,"tci_StatesPDCCH_ToAddList is null\n"); - AssertFatal(coreset->tci_StatesPDCCH_ToAddList->list.count>0,"TCI state list is empty\n"); - for (int i=0;itci_StatesPDCCH_ToAddList->list.count;i++) { - - } - */ - - AssertFatal(ss->monitoringSymbolsWithinSlot!=NULL,"ss->monitoringSymbolsWithinSlot is null\n"); - AssertFatal(ss->monitoringSymbolsWithinSlot->buf!=NULL,"ss->monitoringSymbolsWithinSlot->buf is null\n"); - - // first symbol - //AssertFatal(pdcch_scs==kHz15, "PDCCH SCS above 15kHz not allowed if a symbol above 2 is monitored"); - int sps = bwp->bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12; - - // for SPS=14 8 MSBs in positions 13 downto 6, - uint16_t monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | - (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); - - for (int i=0; i>(sps-1-i))&1) { - pdcch_pdu->StartSymbolIndex=i; - break; - } - pdcch_pdu->RNTI[pdcch_pdu->numDlDci]=rnti; + + pdcch_pdu->dci_pdu.RNTI[pdcch_pdu->numDlDci]=rnti; if (coreset->pdcch_DMRS_ScramblingID != NULL && ss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) { - pdcch_pdu->ScramblingId[pdcch_pdu->numDlDci] = *coreset->pdcch_DMRS_ScramblingID; - pdcch_pdu->ScramblingRNTI[pdcch_pdu->numDlDci]=rnti; + pdcch_pdu->dci_pdu.ScramblingId[pdcch_pdu->numDlDci] = *coreset->pdcch_DMRS_ScramblingID; + pdcch_pdu->dci_pdu.ScramblingRNTI[pdcch_pdu->numDlDci]=rnti; } else { - pdcch_pdu->ScramblingId[pdcch_pdu->numDlDci] = *scc->physCellId; - pdcch_pdu->ScramblingRNTI[pdcch_pdu->numDlDci]=0; + pdcch_pdu->dci_pdu.ScramblingId[pdcch_pdu->numDlDci] = *scc->physCellId; + pdcch_pdu->dci_pdu.ScramblingRNTI[pdcch_pdu->numDlDci]=0; } - uint8_t nr_of_candidates,aggregation_level; - - find_aggregation_candidates(&aggregation_level, + uint8_t nr_of_candidates,aggregation_level; + find_aggregation_candidates(&aggregation_level, &nr_of_candidates, ss); @@ -550,16 +525,15 @@ void nr_configure_pdcch(gNB_MAC_INST *nr_mac, AssertFatal(CCEIndex>=0,"CCEIndex is negative \n"); - pdcch_pdu->AggregationLevel[pdcch_pdu->numDlDci] = aggregation_level; - pdcch_pdu->CceIndex[pdcch_pdu->numDlDci] = CCEIndex; + pdcch_pdu->dci_pdu.AggregationLevel[pdcch_pdu->numDlDci] = aggregation_level; + pdcch_pdu->dci_pdu.CceIndex[pdcch_pdu->numDlDci] = CCEIndex; if (ss->searchSpaceType->choice.ue_Specific->dci_Formats==NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_0_And_1_0) - pdcch_pdu->beta_PDCCH_1_0[pdcch_pdu->numDlDci]=0; + pdcch_pdu->dci_pdu.beta_PDCCH_1_0[pdcch_pdu->numDlDci]=0; - pdcch_pdu->powerControlOffsetSS[pdcch_pdu->numDlDci]=1; + pdcch_pdu->dci_pdu.powerControlOffsetSS[pdcch_pdu->numDlDci]=1; pdcch_pdu->numDlDci++; } - else { // this is for InitialBWP AssertFatal(1==0,"Fill in InitialBWP PDCCH configuration\n"); } @@ -815,28 +789,27 @@ void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup, } } + void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types, + int N_RB, int bwp_id) { - - uint16_t N_RB = pdcch_pdu_rel15->BWPSize; + uint8_t fsize=0, pos=0; uint8_t nbits=0; for (int d=0;dnumDlDci;d++) { - uint64_t *dci_pdu = (uint64_t *)pdcch_pdu_rel15->Payload[d]; + uint64_t *dci_pdu = (uint64_t *)pdcch_pdu_rel15->dci_pdu.Payload[d]; int dci_size = nr_dci_size(secondaryCellGroup,&dci_pdu_rel15[d],dci_formats[d],rnti_types[d],pdcch_pdu_rel15->BWPSize,bwp_id); - pdcch_pdu_rel15->PayloadSizeBits[d] = dci_size; - AssertFatal(pdcch_pdu_rel15->PayloadSizeBits[d]<=64, "DCI sizes above 64 bits not yet supported"); + pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d] = dci_size; + AssertFatal(pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d]<=64, "DCI sizes above 64 bits not yet supported"); if(dci_formats[d]==NR_DL_DCI_FORMAT_1_1) prepare_dci(secondaryCellGroup,&dci_pdu_rel15[d],dci_formats[d],bwp_id); - - pos = 0; /// Payload generation switch(dci_formats[d]) { @@ -846,7 +819,7 @@ void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, // Freq domain assignment fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); pos=fsize; - *dci_pdu |= ((dci_pdu_rel15->frequency_domain_assignment.val&((1<frequency_domain_assignment.val&((1< %d (0x%lx)\n",dci_pdu_rel15->frequency_domain_assignment.val,fsize,N_RB,dci_size-pos,*dci_pdu); // Time domain assignment pos+=4; @@ -860,11 +833,15 @@ void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, // MCS pos+=5; *dci_pdu |= ((uint64_t)dci_pdu_rel15->mcs&0x1f)<<(dci_size-pos); - LOG_D(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); +#ifdef DEBUG_FILL_DCI + LOG_I(MAC,"mcs %d (5 bits)=> %d (0x%lx)\n",dci_pdu_rel15->mcs,dci_size-pos,*dci_pdu); +#endif // TB scaling pos+=2; *dci_pdu |= ((uint64_t)dci_pdu_rel15->tb_scaling&0x3)<<(dci_size-pos); - LOG_D(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu); +#ifdef DEBUG_FILL_DCI + LOG_I(MAC,"tb_scaling %d (2 bits)=> %d (0x%lx)\n",dci_pdu_rel15->tb_scaling,dci_size-pos,*dci_pdu); +#endif break; case NR_RNTI_C: @@ -1288,7 +1265,6 @@ int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot) { } - int extract_startSymbol(int startSymbolAndLength) { int tmp = startSymbolAndLength/14; int tmp2 = startSymbolAndLength%14; @@ -1386,7 +1362,6 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ return -1; } - void get_pdsch_to_harq_feedback(int Mod_idP, int UE_id, NR_SearchSpace__searchSpaceType_PR ss_type, @@ -1437,7 +1412,6 @@ void get_pdsch_to_harq_feedback(int Mod_idP, } } - // function to update pucch scheduling parameters in UE list when a USS DL is scheduled void nr_update_pucch_scheduling(int Mod_idP, int UE_id, @@ -1555,6 +1529,76 @@ void nr_update_pucch_scheduling(int Mod_idP, } } +void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss, + uint16_t *slot_period, + uint16_t *offset) { + + switch(ss->monitoringSlotPeriodicityAndOffset->present) { + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1: + *slot_period = 1; + *offset = 0; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2: + *slot_period = 2; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl4: + *slot_period = 4; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl4; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl5: + *slot_period = 5; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl5; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl8: + *slot_period = 8; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl8; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl10: + *slot_period = 10; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl10; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl16: + *slot_period = 16; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl16; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl20: + *slot_period = 20; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl20; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl40: + *slot_period = 40; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl40; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl80: + *slot_period = 80; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl80; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl160: + *slot_period = 160; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl160; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl320: + *slot_period = 320; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl320; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl640: + *slot_period = 640; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl640; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1280: + *slot_period = 1280; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl1280; + break; + case NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl2560: + *slot_period = 2560; + *offset = ss->monitoringSlotPeriodicityAndOffset->choice.sl2560; + break; + default: + AssertFatal(1==0,"Invalid monitoring slot periodicity and offset value\n"); + break; + } +} void find_aggregation_candidates(uint8_t *aggregation_level, uint8_t *nr_of_candidates, diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index ade5200627..7a46ce8d85 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -28,10 +28,12 @@ * @ingroup _mac */ + #include "LAYER2/NR_MAC_gNB/mac_proto.h" #include "executables/softmodem-common.h" //#define ENABLE_MAC_PAYLOAD_DEBUG 1 + void nr_process_mac_pdu( module_id_t module_idP, uint8_t CC_id, @@ -87,7 +89,13 @@ void nr_process_mac_pdu( /*#ifdef DEBUG_HEADER_PARSING LOG_D(MAC, "[UE] LCID %d, PDU length %d\n", ((NR_MAC_SUBHEADER_FIXED *)pdu_ptr)->LCID, pdu_len); #endif*/ - + case UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY: + // 38.321 Ch6.1.3.20 + mac_ce_len = 2; + break; + case UL_SCH_LCID_CONFIGURED_GRANT_CONFIRMATION: + // 38.321 Ch6.1.3.7 + break; case UL_SCH_LCID_S_BSR: //38.321 section 6.1.3.1 //fixed length @@ -170,6 +178,24 @@ void nr_process_mac_pdu( // end of MAC PDU, can ignore the rest. break; + // MAC SDUs + case UL_SCH_LCID_SRB1: + // todo + break; + case UL_SCH_LCID_SRB2: + // todo + break; + case UL_SCH_LCID_SRB3: + // todo + break; + case UL_SCH_LCID_CCCH_MSG3: + // todo + break; + case UL_SCH_LCID_CCCH: + // todo + mac_subheader_len = 2; + break; + case UL_SCH_LCID_DTCH: // check if LCID is valid at current time. if(((NR_MAC_SUBHEADER_SHORT *)pdu_ptr)->F){ @@ -229,7 +255,6 @@ void nr_process_mac_pdu( } } - /* * When data are received on PHY and transmitted to MAC */ @@ -283,3 +308,4 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, } } } + diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 9993e650ca..d22edb1fd0 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" #define MAX_ACK_BITS 2 //only format 0 is available for now @@ -78,6 +79,48 @@ 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, uint8_t freq_index, uint8_t symbol, int16_t timing_offset); + +void nr_clear_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP); + +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_ServingCellConfigCommon_t *scc, + NR_BWP_Uplink_t *ubwp, + sub_frame_t current_subframe, + frame_t current_frame, + NR_RA_t *ra); + +/* \brief Function in gNB to fill RAR pdu when requested by PHY. +@param ra Instance of RA resources of gNB +@param dlsch_buffer Pointer to RAR input buffer +@param N_RB_UL Number of UL resource blocks +*/ +void nr_fill_rar(uint8_t Mod_idP, + NR_RA_t * ra, + uint8_t * dlsch_buffer, + nfapi_nr_pusch_pdu_t *pusch_pdu); + + +void schedule_nr_prach(module_id_t module_idP, frame_t frameP, sub_frame_t slotP); + +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); @@ -155,6 +198,7 @@ void find_search_space(int ss_type, void nr_configure_pdcch(gNB_MAC_INST *nr_mac, nfapi_nr_dl_tti_pdcch_pdu_rel15_t* pdcch_pdu, uint16_t rnti, + int ss_type, NR_SearchSpace_t *ss, NR_ServingCellConfigCommon_t *scc, NR_BWP_Downlink_t *bwp); @@ -164,6 +208,7 @@ void fill_dci_pdu_rel15(NR_CellGroupConfig_t *secondaryCellGroup, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types, + int N_RB, int bwp_id); void prepare_dci(NR_CellGroupConfig_t *secondaryCellGroup, @@ -175,23 +220,14 @@ void find_aggregation_candidates(uint8_t *aggregation_level, uint8_t *nr_of_candidates, NR_SearchSpace_t *ss); -void nr_configure_pucch(nfapi_nr_pucch_pdu_t* pucch_pdu, - NR_ServingCellConfigCommon_t *scc, - NR_BWP_Uplink_t *bwp, - uint8_t pucch_resource, - uint16_t O_uci, - uint16_t O_ack, - uint8_t SR_flag); - - int get_spf(nfapi_nr_config_request_scf_t *cfg); int to_absslot(nfapi_nr_config_request_scf_t *cfg,int frame,int slot); -void get_band(uint64_t downlink_frequency, uint16_t *current_band, int32_t *current_offset, lte_frame_type_t *current_type); - void nr_get_tbs_dl(nfapi_nr_dl_tti_pdsch_pdu *pdsch_pdu, - int x_overhead); + int x_overhead, + uint8_t nodata_dmrs, + uint8_t tb_scaling); /** \brief Computes Q based on I_MCS PDSCH and table_idx for downlink. Implements MCS Tables from 38.214. */ uint8_t nr_get_Qm_dl(uint8_t Imcs, uint8_t table_idx); uint32_t nr_get_code_rate_dl(uint8_t Imcs, uint8_t table_idx); @@ -228,9 +264,6 @@ int allocate_nr_CCEs(gNB_MAC_INST *nr_mac, int m ); -int is_nr_DL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); -int is_nr_UL_slot(NR_ServingCellConfigCommon_t *scc,slot_t slotP); - int get_dlscs(nfapi_nr_config_request_t *cfg); int get_ulscs(nfapi_nr_config_request_t *cfg); @@ -250,6 +283,17 @@ void config_nr_mib(int Mod_idP, int intraFreqReselection); +void nr_generate_Msg2(module_id_t module_idP, + int CC_id, + frame_t frameP, + sub_frame_t slotP); + +void nr_schedule_reception_msg3(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t slotP); + +void find_monitoring_periodicity_offset_common(NR_SearchSpace_t *ss, + uint16_t *slot_period, + uint16_t *offset); + void nr_process_mac_pdu( module_id_t module_idP, uint8_t CC_id, @@ -257,6 +301,7 @@ void nr_process_mac_pdu( uint8_t *pduP, uint16_t mac_pdu_len); + /* \brief Function to indicate a received SDU on ULSCH. @param Mod_id Instance ID of gNB @param CC_id Component carrier index diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index 9e8415776b..d38a251a2b 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_compute_tbs_common.c b/openair2/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c index e4e3ac05df..df23b64e07 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c +++ b/openair2/LAYER2/NR_MAC_gNB/nr_compute_tbs_common.c @@ -39,6 +39,7 @@ uint32_t nr_compute_tbs(uint16_t Qm, uint16_t nb_symb_sch, uint16_t nb_dmrs_prb, uint16_t nb_rb_oh, + uint8_t tb_scaling, uint8_t Nl) { @@ -54,7 +55,7 @@ uint32_t nr_compute_tbs(uint16_t Qm, scale = (R>1024)?11:10; // Intermediate number of information bits - Ninfo = (nb_re * R * Qm * Nl)>>scale; + Ninfo = ((nb_re * R * Qm * Nl)>>scale)>>tb_scaling; if (Ninfo <=3824) { n = max(3, floor(log2(Ninfo)) - 6); diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index e3a30c9b19..2e5912a9a1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -42,30 +42,106 @@ #include #include +/* 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" +typedef enum { + RA_IDLE = 0, + Msg2 = 1, + WAIT_Msg3 = 2, + Msg4 = 3, + WAIT_Msg4_ACK = 4 +} RA_gNB_state_t; + +/*! \brief gNB template for the Random access information */ +typedef struct { + /// Flag to indicate this process is active + RA_gNB_state_t state; + /// BWP id of RA process + int bwp_id; + /// CORESET0 configured flag + int coreset0_configured; + /// Slot where preamble was received + uint8_t preamble_slot; + /// Subframe where Msg2 is to be sent + uint8_t Msg2_slot; + /// Frame where Msg2 is to be sent + frame_t Msg2_frame; + /// Subframe where Msg3 is to be sent + sub_frame_t Msg3_slot; + /// Frame where Msg3 is to be sent + frame_t Msg3_frame; + /// Msg3 time domain allocation index + uint8_t Msg3_tda_id; + /// Subframe where Msg4 is to be sent + sub_frame_t Msg4_slot; + /// 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 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; + /// Msg3 pusch pdu + nfapi_nr_pusch_pdu_t pusch_pdu; + /// TBS used for Msg4 + int msg4_TBsize; + /// MCS used for Msg4 + int msg4_mcs; + /// RA search space + NR_SearchSpace_t *ra_ss; +} NR_RA_t; /*! \brief gNB common channels */ typedef struct { @@ -73,6 +149,7 @@ typedef struct { int p_gNB; int Ncp; int nr_band; + lte_frame_type_t frame_type; uint64_t dl_CarrierFreq; NR_BCCH_BCH_Message_t *mib; NR_ServingCellConfigCommon_t *ServingCellConfigCommon; @@ -93,7 +170,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 @@ -120,9 +197,8 @@ typedef struct { int16_t ta_update; } 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 NR_UE_sched_ctrl_t UE_sched_ctrl[MAX_MOBILES_PER_GNB]; @@ -203,5 +279,4 @@ typedef struct gNB_MAC_INST_s { int cce_list[MAX_NUM_BWP][MAX_NUM_CORESET][MAX_NUM_CCE]; } gNB_MAC_INST; - #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 91c75ac67f..fc6614f0b1 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -54,28 +54,26 @@ extern uint16_t sf_ahead; extern uint16_t sl_ahead; void handle_nr_rach(NR_UL_IND_t *UL_info) { - if (UL_info->rach_ind.rach_indication_body.number_of_preambles>0) { - 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 - - ); - */ + if (UL_info->rach_ind.number_of_pdus>0) { + AssertFatal(UL_info->rach_ind.number_of_pdus==1,"More than 1 RACH pdu not supported\n"); + UL_info->rach_ind.number_of_pdus=0; + LOG_D(MAC,"UL_info[Frame %d, Slot %d] Calling initiate_ra_proc RACH:SFN/SLOT:%d/%d\n",UL_info->frame,UL_info->slot, UL_info->rach_ind.sfn,UL_info->rach_ind.slot); + + + if (UL_info->rach_ind.pdu_list[0].num_preamble>0) + AssertFatal(UL_info->rach_ind.pdu_list[0].num_preamble==1, + "More than 1 preamble not supported\n"); + + nr_initiate_ra_proc(UL_info->module_id, + UL_info->CC_id, + UL_info->rach_ind.sfn, + UL_info->rach_ind.slot, + UL_info->rach_ind.pdu_list[0].preamble_list[0].preamble_index, + UL_info->rach_ind.pdu_list[0].freq_index, + UL_info->rach_ind.pdu_list[0].symbol_index, + UL_info->rach_ind.pdu_list[0].preamble_list[0].timing_advance); + } - } void handle_nr_sr(NR_UL_IND_t *UL_info) { @@ -230,11 +228,11 @@ void NR_UL_indication(NR_UL_IND_t *UL_info) { NR_Sched_Rsp_t *sched_info = &Sched_INFO[module_id][CC_id]; NR_IF_Module_t *ifi = if_inst[module_id]; gNB_MAC_INST *mac = RC.nrmac[module_id]; - LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d harqs:%d crcs:%d cqis:%d preambles:%d sr_ind:%d]\n", + LOG_D(PHY,"SFN/SF:%d%d module_id:%d CC_id:%d UL_info[rx_ind:%d harqs:%d crcs:%d cqis:%d rach_pdus:%d sr_ind:%d]\n", UL_info->frame,UL_info->slot, module_id,CC_id, UL_info->rx_ind.rx_indication_body.number_of_pdus, UL_info->harq_ind.harq_indication_body.number_of_harqs, UL_info->crc_ind.crc_indication_body.number_of_crcs, UL_info->cqi_ind.number_of_cqis, - UL_info->rach_ind.rach_indication_body.number_of_preambles, UL_info->sr_ind.sr_indication_body.number_of_srs); + UL_info->rach_ind.number_of_pdus, UL_info->sr_ind.sr_indication_body.number_of_srs); if (nfapi_mode != 1) { if (ifi->CC_mask==0) { diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h index 14355781d0..eaf0811883 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.h @@ -74,10 +74,7 @@ typedef struct { nfapi_cqi_indication_body_t cqi_ind; /// RACH indication list - nfapi_rach_indication_t rach_ind; - - /// RACH indication list for BR UEs - nfapi_rach_indication_t rach_ind_br; + nfapi_nr_rach_indication_t rach_ind; /// SRS indication list nfapi_srs_indication_body_t srs_ind; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 64a814bcdb..87ddd97366 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/softmodem-common.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 (nr_downlink_indication_t *dl_info){ + + LOG_D(MAC, "handling RAR at MAC layer \n"); + nr_process_rar (dl_info); + return 0; + +} + int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ NR_UE_L2_STATE_t ret; @@ -105,14 +113,17 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ mac->dl_config_request.number_pdus = 0; // clean previous FAPI messages - ret = nr_ue_scheduler( - ul_info->module_id, - ul_info->gNB_index, - ul_info->cc_id, - ul_info->frame, - ul_info->slot, - ul_info->ssb_index, - 0, 0); // TODO check tx/rx frame/slot is need for NR version + ret = nr_ue_scheduler(ul_info->module_id, + ul_info->gNB_index, + ul_info->cc_id, + ul_info->frame_rx, + ul_info->slot_rx, + ul_info->ssb_index, + ul_info->frame_tx, + ul_info->slot_tx); + + if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra) + nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx); switch(ret){ case UE_CONNECTION_OK: @@ -127,7 +138,6 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ break; } - mac->if_module->scheduled_response(&mac->scheduled_response); return 0; @@ -231,11 +241,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 +259,14 @@ 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)) << FAPI_NR_RX_PDU_TYPE_RAR; + break; - */ - break; default: - - break; - + break; } } } diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h index 0784e71584..b7ddfc0c57 100755 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.h @@ -87,9 +87,13 @@ typedef struct { /// component carrier id int cc_id; /// frame - frame_t frame; - /// slot - uint32_t slot; + frame_t frame_rx; + /// slot rx + uint32_t slot_rx; + /// frame tx + frame_t frame_tx; + /// slot tx + uint32_t slot_tx; /// ssb_index, if ssb is not present in current TTI, thie value set to -1 int ssb_index; /// dci reception indication structure diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index f050733a13..52b06b9f11 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -382,6 +382,7 @@ typedef enum e_rab_satus_e { E_RAB_STATUS_DONE, // from the eNB perspective E_RAB_STATUS_ESTABLISHED, // get the reconfigurationcomplete form UE E_RAB_STATUS_REESTABLISHED, // after HO + E_RAB_STATUS_TOMODIFY, // ENDC NSA E_RAB_STATUS_FAILED, E_RAB_STATUS_TORELEASE // to release DRB between eNB and UE } e_rab_status_t; @@ -613,6 +614,7 @@ typedef struct eNB_RRC_UE_s { /* Number of e_rab to be modified in the list */ uint8_t nb_of_modify_e_rabs; uint8_t nb_of_failed_e_rabs; + uint8_t nb_of_modify_endc_e_rabs; e_rab_param_t modify_e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; /* list of e_rab to be setup by RRC layers */ e_rab_param_t e_rab[NB_RB_MAX];//[S1AP_MAX_E_RAB]; @@ -627,6 +629,10 @@ typedef struct eNB_RRC_UE_s { uint32_t enb_gtp_teid[S1AP_MAX_E_RAB]; transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; + // LG: For GTPV1 TUNNELS ENDC + uint32_t gnb_gtp_endc_teid[S1AP_MAX_E_RAB]; + transport_layer_addr_t gnb_gtp_endc_addrs[S1AP_MAX_E_RAB]; + rb_id_t gnb_gtp_endc_ebi[S1AP_MAX_E_RAB]; /* Total number of e_rab already setup in the list */ uint8_t nb_x2u_e_rabs; // LG: For GTPV1 TUNNELS(X2U) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 1d25bf180a..c8df01722f 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -4364,6 +4364,17 @@ rrc_eNB_process_MeasurementReport( msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ); X2AP_ENDC_SGNB_ADDITION_REQ(msg).rnti = ctxt_pP->rnti; + //For the moment we have a single E-RAB which will be the one to be added to the gNB + //Not sure how to select bearers to be added if there are multiple. + X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded = 1; + for (int e_rab=0; e_rab < X2AP_ENDC_SGNB_ADDITION_REQ(msg).nb_e_rabs_tobeadded; e_rab++){ + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].gtp_teid = ue_context_pP->ue_context.e_rab[e_rab].param.gtp_teid; + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].drb_ID = 1; + memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[e_rab].sgw_addr, + &ue_context_pP->ue_context.e_rab[e_rab].param.sgw_addr, + sizeof(transport_layer_addr_t)); + } LOG_I(RRC, "[eNB %d] frame %d subframe %d: UE rnti %x switching to NSA mode\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->subframe, ctxt_pP->rnti); @@ -7478,6 +7489,41 @@ rrc_eNB_decode_dcch( } ue_context_p->ue_context.reestablishment_xid = -1; + + //Looking for a condition to trigger S1AP E-RAB-Modification-indication, based on the reception of RRCConnectionReconfigurationComplete + //including NR specific elements. Not sure if this is the correct one and the correct placement + /*if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension-> + scg_ConfigResponseNR_r15->buf!=NULL){ + //Trigger E-RAB Modification Indication + rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p); + }*/ + + if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. + nonCriticalExtension!=NULL){ + if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. + nonCriticalExtension->nonCriticalExtension!=NULL){ + if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){ + if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){ + if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){ + if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL){ + if(ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8. + nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension + ->scg_ConfigResponseNR_r15!=NULL){ + /*Trigger E-RAB Modification Indication */ + rrc_eNB_send_E_RAB_Modification_Indication(ctxt_pP, ue_context_p); + } + } + } + } + } + } + } + } else { dedicated_DRB = 1; ue_context_p->ue_context.Status = RRC_RECONFIGURED; @@ -8512,6 +8558,27 @@ void rrc_eNB_process_AdditionResponseInformation(const module_id_t enb_mod_idP, ue_context = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], m->rnti); + ue_context->ue_context.nb_of_modify_endc_e_rabs = m->nb_e_rabs_admitted_tobeadded; + + int j=0; + while(j < m->nb_e_rabs_admitted_tobeadded){ + for (int e_rab_idx=0; e_rab_idxue_context.setup_e_rabs; e_rab_idx++){ + //Update ue_context information with gNB's address and new GTP tunnel ID + if( ue_context->ue_context.e_rab[e_rab_idx].param.e_rab_id == m->e_rabs_admitted_tobeadded[j].e_rab_id){ + memcpy(ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].buffer, + m->e_rabs_admitted_tobeadded[j].gnb_addr.buffer, + m->e_rabs_admitted_tobeadded[j].gnb_addr.length); + ue_context->ue_context.gnb_gtp_endc_addrs[e_rab_idx].length = m->e_rabs_admitted_tobeadded[j].gnb_addr.length; + ue_context->ue_context.gnb_gtp_endc_teid[e_rab_idx] = m->e_rabs_admitted_tobeadded[j].gtp_teid; + ue_context->ue_context.e_rab[e_rab_idx].status = E_RAB_STATUS_TOMODIFY; + break; + } + } + j++; + } + + + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, 0, ENB_FLAG_YES, diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c index 6bbdef181b..1025d46f62 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.c +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.c @@ -92,6 +92,7 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( } } + //------------------------------------------------------------------------------ boolean_t gtpv_data_req( diff --git a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h index 00c7490359..6318ed4927 100644 --- a/openair2/RRC/LTE/rrc_eNB_GTPV1U.h +++ b/openair2/RRC/LTE/rrc_eNB_GTPV1U.h @@ -43,6 +43,13 @@ rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( uint8_t *inde_list ); +int +rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, + uint8_t *inde_list +); + /*! \fn rrc_eNB_send_GTPV1U_ENB_DELETE_TUNNEL_REQ(module_id_t enb_mod_idP, const rrc_eNB_ue_context_t* const ue_context_pP) *\brief Send GTPV1U_ENB_DELETE_TUNNEL_REQ message to GTPV1U to destroy all UE-related tunnels. *\param module_id Instance ID of eNB. diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 59998cebcc..27a442ed05 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -2284,3 +2284,75 @@ int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id) }*/ return 0; } + + +int rrc_eNB_send_E_RAB_Modification_Indication(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP) { + MessageDef *msg_p = NULL; + int e_rab = 0; + int e_rab_modify_index = 0; + int e_rab_notmodify_index = 0; + + uint8_t inde_list[ue_context_pP->ue_context.nb_of_e_rabs]; + memset(inde_list, 0, ue_context_pP->ue_context.nb_of_e_rabs*sizeof(uint8_t)); + + msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFICATION_IND); + + + S1AP_E_RAB_MODIFICATION_IND (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; + S1AP_E_RAB_MODIFICATION_IND (msg_p).mme_ue_s1ap_id = ue_context_pP->ue_context.mme_ue_s1ap_id; + + LOG_I (RRC,"E-RAB modification indication: nb nb_of_e_rabs %u status %u\n", + ue_context_pP->ue_context.nb_of_e_rabs, + ue_context_pP->ue_context.e_rab[e_rab].status); + + if (ue_context_pP->ue_context.nb_of_modify_endc_e_rabs > 0){ + S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_tobemodified = ue_context_pP->ue_context.nb_of_modify_endc_e_rabs; + for (e_rab = 0; e_rab < ue_context_pP->ue_context.setup_e_rabs ; e_rab++) { + //Add E-RAB in the list of E-RABs to be modified + if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_TOMODIFY) { + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; + memcpy(S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].eNB_addr.buffer, + ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].buffer, + ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length); + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].eNB_addr.length = ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length; + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_tobemodified[e_rab_modify_index].gtp_teid = ue_context_pP->ue_context.gnb_gtp_endc_teid[e_rab]; + e_rab_modify_index++; + } + //Add E-RAB in the list of E-RABs NOT to be modified + else{ + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; + memcpy(S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].eNB_addr.buffer, + ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].buffer, + ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length); + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].eNB_addr.length = ue_context_pP->ue_context.gnb_gtp_endc_addrs[e_rab].length; + S1AP_E_RAB_MODIFICATION_IND (msg_p).e_rabs_nottobemodified[e_rab_notmodify_index].gtp_teid = ue_context_pP->ue_context.gnb_gtp_endc_teid[e_rab]; + e_rab_notmodify_index++; + } + } + S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_nottobemodified = e_rab_notmodify_index; + } + + if (e_rab_modify_index > 0) { + LOG_I(RRC,"S1AP_E_RAB_MODIFICATION_IND: sending the message: nb_of_erabstobemodified %d, total e_rabs %d, index %d\n", + S1AP_E_RAB_MODIFICATION_IND (msg_p).nb_of_e_rabs_tobemodified, ue_context_pP->ue_context.setup_e_rabs, e_rab); + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_S1AP_ENB, + (const char *)&S1AP_E_RAB_MODIFICATION_IND (msg_p), + sizeof(s1ap_e_rab_modification_ind_t), + MSC_AS_TIME_FMT" E RAB MODIFICATION IND UE %X eNB_ue_s1ap_id %u e_rabs:%u succ", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_id_rnti, + S1AP_E_RAB_MODIFICATION_IND (msg_p).eNB_ue_s1ap_id, + e_rab_modify_index); + itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); + } else { + itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + } + + return 0; +} + + + diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h index e5ff9c27d6..a55d17bfd1 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.h +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.h @@ -285,4 +285,6 @@ int rrc_eNB_send_X2AP_UE_CONTEXT_RELEASE(const protocol_ctxt_t* const ctxt_pP, r int s1ap_ue_context_release(instance_t instance, const uint32_t eNB_ue_s1ap_id); +int rrc_eNB_send_E_RAB_Modification_Indication(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP); + #endif /* RRC_ENB_S1AP_H_ */ diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 1e8e45ef4d..0905f6d7de 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -51,9 +51,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); @@ -62,11 +61,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, @@ -84,10 +87,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 */ + 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 %ld)\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((void *)buffer_pP, (void*)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/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 02b4154c41..eeb16c3087 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -319,9 +319,10 @@ typedef struct gNB_RRC_UE_s { uint8_t nb_release_of_e_rabs; e_rab_failed_t e_rabs_release_failed[S1AP_MAX_E_RAB]; // LG: For GTPV1 TUNNELS - uint32_t enb_gtp_teid[S1AP_MAX_E_RAB]; - transport_layer_addr_t enb_gtp_addrs[S1AP_MAX_E_RAB]; - rb_id_t enb_gtp_ebi[S1AP_MAX_E_RAB]; + uint32_t gnb_gtp_teid[S1AP_MAX_E_RAB]; + transport_layer_addr_t gnb_gtp_addrs[S1AP_MAX_E_RAB]; + rb_id_t gnb_gtp_ebi[S1AP_MAX_E_RAB]; + uint32_t ul_failure_timer; uint32_t ue_release_timer; uint32_t ue_release_timer_thres; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 5770b80595..fd766f7e12 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -65,9 +65,9 @@ void rrc_gNB_generate_SgNBAdditionRequestAcknowledge( struct rrc_gNB_ue_context_s *rrc_gNB_allocate_new_UE_context(gNB_RRC_INST *rrc_instance_pP); -void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList); +void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m); -void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p); +void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m); void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellconfigcommon, NR_CellGroupConfig_t *secondaryCellGroup, @@ -89,7 +89,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc, NR_RRCReconfiguration_t *reconfig, NR_RadioBearerConfig_t *rbconfig); -int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo); +int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index fba6610554..c034663211 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -199,12 +199,12 @@ static void init_NR_SI(gNB_RRC_INST *rrc) { rrc->carrier.pdsch_AntennaPorts, (NR_ServingCellConfigCommon_t *)rrc->carrier.servingcellconfigcommon, 0, - 0, + 0, // WIP hardcoded rnti (NR_CellGroupConfig_t *)NULL ); - if (get_softmodem_params()->phy_test > 0) { + if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) { // This is for phytest only, emulate first X2 message if uecap.raw file is present FILE *fd; @@ -245,13 +245,13 @@ static void init_NR_SI(gNB_RRC_INST *rrc) { OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo, (const char *)buffer, (enc_rval.encoded+7)>>3); - parse_CG_ConfigInfo(rrc,CG_ConfigInfo); + parse_CG_ConfigInfo(rrc,CG_ConfigInfo,NULL); } else { struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc); LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p); - rrc_add_nsa_user(rrc,ue_context_p); + rrc_add_nsa_user(rrc,ue_context_p,NULL); } } } @@ -310,12 +310,6 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x (uint8_t *)m->rrc_buffer, (int) m->rrc_buffer_size);//m->rrc_buffer_size); -/* asn_dec_rval_t dec_rval = uper_decode( NULL, - &asn_DEF_LTE_UL_DCCH_Message, - (void **)<E_UL_DCCH_Message, - (uint8_t *)m->rrc_buffer, - (int) m->rrc_buffer_size, 0, 0);//m->rrc_buffer_size); -*/ gNB_RRC_INST *rrc=RC.nrrrc[gnb_mod_idP]; if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { @@ -341,7 +335,7 @@ void rrc_gNB_process_AdditionRequestInformation(const module_id_t gnb_mod_idP, x OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo, (const char *)m->rrc_buffer, (enc_rval.encoded+7)>>3); - parse_CG_ConfigInfo(rrc,CG_ConfigInfo); + parse_CG_ConfigInfo(rrc,CG_ConfigInfo,m); } diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.c b/openair2/RRC/NR/rrc_gNB_GTPV1U.c new file mode 100644 index 0000000000..9ab1bbf43a --- /dev/null +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.c @@ -0,0 +1,94 @@ +/* + * 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 rrc_gNB_GTPV1U.c + * \brief rrc GTPV1U procedures for gNB + * \author Lionel GAUTHIER, Panos MATZAKOS + * \version 1.0 + * \company Eurecom + * \email: lionel.gauthier@eurecom.fr, panagiotis.matzakos@eurecom.fr + */ + +# include "rrc_defs.h" +# include "rrc_extern.h" +# include "RRC/LTE/MESSAGES/asn1_msg.h" +# include "rrc_eNB_GTPV1U.h" +# include "rrc_eNB_UE_context.h" +# include "msc.h" +# include "openair2/RRC/NR/rrc_gNB_UE_context.h" + +//# if defined(ENABLE_ITTI) +# include "asn1_conversions.h" +# include "intertask_interface.h" +//#endif + +# include "common/ran_context.h" + +extern RAN_CONTEXT_t RC; + +int +rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, + uint8_t *inde_list +) { + rnti_t rnti; + int i; + struct rrc_gNB_ue_context_s *ue_context_p = NULL; + + if (create_tunnel_resp_pP) { + LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RX CREATE_TUNNEL_RESP num tunnels %u \n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + create_tunnel_resp_pP->num_tunnels); + rnti = create_tunnel_resp_pP->rnti; + ue_context_p = rrc_gNB_get_ue_context( + RC.nrrrc[ctxt_pP->module_id], + ctxt_pP->rnti); + + for (i = 0; i < create_tunnel_resp_pP->num_tunnels; i++) { + ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]] = create_tunnel_resp_pP->enb_S1u_teid[i]; + ue_context_p->ue_context.gnb_gtp_addrs[inde_list[i]] = create_tunnel_resp_pP->enb_addr; + ue_context_p->ue_context.gnb_gtp_ebi[inde_list[i]] = create_tunnel_resp_pP->eps_bearer_id[i]; + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP tunnel (%u, %u) bearer UE context index %u, msg index %u, id %u, gtp addr len %d \n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + create_tunnel_resp_pP->enb_S1u_teid[i], + ue_context_p->ue_context.gnb_gtp_teid[inde_list[i]], + inde_list[i], + i, + create_tunnel_resp_pP->eps_bearer_id[i], + create_tunnel_resp_pP->enb_addr.length); + } + + MSC_LOG_RX_MESSAGE( + MSC_RRC_ENB, + MSC_GTPU_ENB, + NULL,0, + MSC_AS_TIME_FMT" CREATE_TUNNEL_RESP RNTI %"PRIx16" ntuns %u ebid %u enb-s1u teid %u", + 0,0,rnti, + create_tunnel_resp_pP->num_tunnels, + ue_context_p->ue_context.gnb_gtp_ebi[0], + ue_context_p->ue_context.gnb_gtp_teid[0]); + (void)rnti; /* avoid gcc warning "set but not used" */ + return 0; + } else { + return -1; + } +} diff --git a/openair2/RRC/NR/rrc_gNB_GTPV1U.h b/openair2/RRC/NR/rrc_gNB_GTPV1U.h new file mode 100644 index 0000000000..caff825a7a --- /dev/null +++ b/openair2/RRC/NR/rrc_gNB_GTPV1U.h @@ -0,0 +1,39 @@ +/* + * 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 rrc_gNB_GTPV1U.h + * \brief rrc GTPV1U procedures for gNB + * \author Lionel GAUTHIER, Panos MATZAKOS + * \version 1.0 + * \company Eurecom + * \email: lionel.gauthier@eurecom.fr, panagiotis.matzakos@eurecom.fr + */ + +#ifndef RRC_GNB_GTPV1U_H_ +#define RRC_GNB_GTPV1U_H_ + + +int +rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + const protocol_ctxt_t *const ctxt_pP, + const gtpv1u_enb_create_tunnel_resp_t *const create_tunnel_resp_pP, + uint8_t *inde_list +); diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index 4681cabb8f..5c9c716181 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -58,7 +58,7 @@ int rrc_gNB_compare_ue_rnti_id( struct rrc_gNB_ue_context_s* c2_pP ); -RB_PROTOTYPE(rrc_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue_rnti_id); +RB_PROTOTYPE(rrc_nr_ue_tree_s, rrc_gNB_ue_context_s, entries, rrc_gNB_compare_ue_rnti_id); struct rrc_gNB_ue_context_s* rrc_gNB_allocate_new_UE_context( diff --git a/openair2/RRC/NR/rrc_gNB_internode.c b/openair2/RRC/NR/rrc_gNB_internode.c index 581015db56..916f4d63da 100644 --- a/openair2/RRC/NR/rrc_gNB_internode.c +++ b/openair2/RRC/NR/rrc_gNB_internode.c @@ -38,7 +38,7 @@ #include "LTE_UE-CapabilityRAT-ContainerList.h" #include "NR_CG-Config.h" -int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo) { +int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m) { if (CG_ConfigInfo->criticalExtensions.present == NR_CG_ConfigInfo__criticalExtensions_PR_c1) { if (CG_ConfigInfo->criticalExtensions.choice.c1) { @@ -56,7 +56,7 @@ int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo) { AssertFatal(1==0,"[InterNode] Failed to decode NR_UE_CapabilityRAT_ContainerList (%zu bits), size of OCTET_STRING %lu\n", dec_rval.consumed, cg_ConfigInfo->ue_CapabilityInfo->size); } - rrc_parse_ue_capabilities(rrc,UE_CapabilityRAT_ContainerList); + rrc_parse_ue_capabilities(rrc,UE_CapabilityRAT_ContainerList, m); } if (cg_ConfigInfo->candidateCellInfoListMN) AssertFatal(1==0,"Can't handle candidateCellInfoListMN yet\n"); } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index cf48aef459..afd5404d29 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -37,13 +37,15 @@ #include "LTE_UE-CapabilityRAT-ContainerList.h" #include "NR_CG-Config.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" +#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h" -void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc,LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList) { +void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m) { struct rrc_gNB_ue_context_s *ue_context_p = NULL; - OCTET_STRING_t *ueCapabilityRAT_Container_nr; - OCTET_STRING_t *ueCapabilityRAT_Container_MRDC; + OCTET_STRING_t *ueCapabilityRAT_Container_nr = NULL; + OCTET_STRING_t *ueCapabilityRAT_Container_MRDC = NULL; int list_size; + asn_dec_rval_t dec_rval; AssertFatal(UE_CapabilityRAT_ContainerList!=NULL,"UE_CapabilityRAT_ContainerList is null\n"); AssertFatal((list_size=UE_CapabilityRAT_ContainerList->list.count) >= 2, "UE_CapabilityRAT_ContainerList->list.size %d < 2\n",UE_CapabilityRAT_ContainerList->list.count); for (int i=0;ilist.array[i]->rat_Type == LTE_RAT_Type_eutra_nr) ueCapabilityRAT_Container_MRDC = &UE_CapabilityRAT_ContainerList->list.array[i]->ueCapabilityRAT_Container; } - AssertFatal(ueCapabilityRAT_Container_nr!=NULL,"ueCapabilityRAT_Container_nr is NULL\n"); - AssertFatal(ueCapabilityRAT_Container_MRDC!=NULL,"ueCapabilityRAT_Container_MRDC is NULL\n"); // decode and store capabilities ue_context_p = rrc_gNB_allocate_new_UE_context(rrc); - - asn_dec_rval_t dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_NR_Capability, - (void **)&ue_context_p->ue_context.UE_Capability_nr, - ueCapabilityRAT_Container_nr->buf, - ueCapabilityRAT_Container_nr->size, 0, 0); - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(RRC, "Failed to decode UE NR capabilities (%zu bytes) container size %lu\n", dec_rval.consumed,ueCapabilityRAT_Container_nr->size); - ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, - ue_context_p->ue_context.UE_Capability_nr); - ue_context_p->ue_context.UE_Capability_nr = 0; - AssertFatal(1==0,"exiting\n"); + if (ueCapabilityRAT_Container_nr != NULL) { + dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_NR_Capability, + (void **)&ue_context_p->ue_context.UE_Capability_nr, + ueCapabilityRAT_Container_nr->buf, + ueCapabilityRAT_Container_nr->size, 0, 0); + + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC, "Failed to decode UE NR capabilities (%zu bytes) container size %lu\n", dec_rval.consumed,ueCapabilityRAT_Container_nr->size); + ASN_STRUCT_FREE(asn_DEF_NR_UE_NR_Capability, + ue_context_p->ue_context.UE_Capability_nr); + ue_context_p->ue_context.UE_Capability_nr = 0; + AssertFatal(1==0,"exiting\n"); + } } - dec_rval = uper_decode(NULL, - &asn_DEF_NR_UE_MRDC_Capability, - (void **)&ue_context_p->ue_context.UE_Capability_MRDC, - ueCapabilityRAT_Container_MRDC->buf, - ueCapabilityRAT_Container_MRDC->size, 0, 0); + if (ueCapabilityRAT_Container_MRDC != NULL) { + dec_rval = uper_decode(NULL, + &asn_DEF_NR_UE_MRDC_Capability, + (void **)&ue_context_p->ue_context.UE_Capability_MRDC, + ueCapabilityRAT_Container_MRDC->buf, + ueCapabilityRAT_Container_MRDC->size, 0, 0); - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(RRC, "Failed to decode UE MRDC capabilities (%zu bytes)\n", dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, - ue_context_p->ue_context.UE_Capability_MRDC); - ue_context_p->ue_context.UE_Capability_MRDC = 0; - AssertFatal(1==0,"exiting\n"); + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC, "Failed to decode UE MRDC capabilities (%zu bytes)\n", dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_NR_UE_MRDC_Capability, + ue_context_p->ue_context.UE_Capability_MRDC); + ue_context_p->ue_context.UE_Capability_MRDC = 0; + AssertFatal(1==0,"exiting\n"); + } } // dump ue_capabilities - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_nr != NULL) ) { xer_fprint(stdout, &asn_DEF_NR_UE_NR_Capability, ue_context_p->ue_context.UE_Capability_nr); } - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + if ( LOG_DEBUGFLAG(DEBUG_ASN1 && ueCapabilityRAT_Container_MRDC != NULL) ) { xer_fprint(stdout, &asn_DEF_NR_UE_MRDC_Capability, ue_context_p->ue_context.UE_Capability_MRDC); } - rrc_add_nsa_user(rrc,ue_context_p); + rrc_add_nsa_user(rrc,ue_context_p, m); } -void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p) { +void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_p, x2ap_ENDC_sgnb_addition_req_t *m) { // generate nr-Config-r15 containers for LTE RRC : inside message for X2 EN-DC (CG-Config Message from 38.331) @@ -105,6 +109,9 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ MessageDef *msg; msg = itti_alloc_new_message(TASK_RRC_ENB, X2AP_ENDC_SGNB_ADDITION_REQ_ACK); + gtpv1u_enb_create_tunnel_req_t create_tunnel_req; + gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; + protocol_ctxt_t ctxt; // NR RRCReconfiguration @@ -130,7 +137,79 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); memset((void*)CG_Config,0,sizeof(*CG_Config)); - int CG_Config_size = generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config); + //int CG_Config_size = generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config); + generate_CG_Config(rrc,CG_Config,ue_context_p->ue_context.reconfig,ue_context_p->ue_context.rb_config); + + if(m!=NULL){ + uint8_t inde_list[m->nb_e_rabs_tobeadded]; + memset(inde_list, 0, m->nb_e_rabs_tobeadded*sizeof(uint8_t)); + + if (m->nb_e_rabs_tobeadded>0){ + for (int i=0; inb_e_rabs_tobeadded; i++){ + // Add the new E-RABs at the corresponding rrc ue context of the gNB + ue_context_p->ue_context.e_rab[i].param.e_rab_id = m->e_rabs_tobeadded[i].e_rab_id; + ue_context_p->ue_context.e_rab[i].param.gtp_teid = m->e_rabs_tobeadded[i].gtp_teid; + memcpy(&ue_context_p->ue_context.e_rab[i].param.sgw_addr, &m->e_rabs_tobeadded[i].sgw_addr, sizeof(transport_layer_addr_t)); + ue_context_p->ue_context.nb_of_e_rabs++; + //Fill the required E-RAB specific information for the creation of the S1-U tunnel between the gNB and the SGW + create_tunnel_req.eps_bearer_id[i] = ue_context_p->ue_context.e_rab[i].param.e_rab_id; + create_tunnel_req.sgw_S1u_teid[i] = ue_context_p->ue_context.e_rab[i].param.gtp_teid; + memcpy(&create_tunnel_req.sgw_addr[i], &ue_context_p->ue_context.e_rab[i].param.sgw_addr, sizeof(transport_layer_addr_t)); + inde_list[i] = i; + LOG_I(RRC,"S1-U tunnel: index %d target sgw ip %d.%d.%d.%d length %d gtp teid %u\n", + i, + create_tunnel_req.sgw_addr[i].buffer[0], + create_tunnel_req.sgw_addr[i].buffer[1], + create_tunnel_req.sgw_addr[i].buffer[2], + create_tunnel_req.sgw_addr[i].buffer[3], + create_tunnel_req.sgw_addr[i].length, + create_tunnel_req.sgw_S1u_teid[i]); + } + //PM: Is this where we should extract the rnti from? + create_tunnel_req.rnti = ue_context_p->ue_id_rnti; + create_tunnel_req.num_tunnels = m->nb_e_rabs_tobeadded; + RB_INSERT(rrc_nr_ue_tree_s, &RC.nrrrc[rrc->module_id]->rrc_ue_head, ue_context_p); + + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, rrc->module_id, GNB_FLAG_YES, ue_context_p->ue_id_rnti, 0, 0,rrc->module_id); + gtpv1u_create_s1u_tunnel( + ctxt.instance, + &create_tunnel_req, + &create_tunnel_resp); + rrc_gNB_process_GTPV1U_CREATE_TUNNEL_RESP( + &ctxt, + &create_tunnel_resp, + &inde_list[0]); + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).nb_e_rabs_admitted_tobeadded = m->nb_e_rabs_tobeadded; + for(int i=0; iue_context.nb_of_e_rabs; i++){ + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = ue_context_p->ue_context.e_rab[i].param.e_rab_id; + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid = create_tunnel_resp.enb_S1u_teid[i]; + memcpy(&X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr, &create_tunnel_resp.enb_addr, sizeof(transport_layer_addr_t)); + + //The length field in the X2AP targetting structure is expected in bits but the create_tunnel_resp returns the address length in bytes + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.length = create_tunnel_resp.enb_addr.length*8; + + LOG_I(RRC,"S1-U create_tunnel_resp tunnel: index %d target gNB ip %d.%d.%d.%d length %d gtp teid %u\n", + i, + create_tunnel_resp.enb_addr.buffer[0], + create_tunnel_resp.enb_addr.buffer[1], + create_tunnel_resp.enb_addr.buffer[2], + create_tunnel_resp.enb_addr.buffer[3], + create_tunnel_resp.enb_addr.length, + create_tunnel_resp.enb_S1u_teid[i]); + LOG_I(RRC,"X2AP sGNB Addition Request: index %d target gNB ip %d.%d.%d.%d length %d gtp teid %u\n", + i, + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[0], + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[1], + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[2], + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer[3], + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.length, + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gtp_teid); + } + } + else + LOG_W(RRC, "No E-RAB to be added received from SgNB Addition Request message \n"); + } + //X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).rrc_buffer_size = CG_Config_size; //Need to verify correct value for the buffer_size // Send to X2 entity to transport to MeNB diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 08cf33c80f..5418085108 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -155,6 +155,26 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = NULL; secondaryCellGroup->spCellConfig->reconfigurationWithSync->ext1 = NULL; + /* contention free ra */ + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated = calloc(1,sizeof(struct NR_ReconfigurationWithSync__rach_ConfigDedicated)); + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->present= NR_ReconfigurationWithSync__rach_ConfigDedicated_PR_uplink; + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink= calloc(1,sizeof(struct NR_RACH_ConfigDedicated)); + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra= calloc(1,sizeof(struct NR_CFRA)); + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->ra_Prioritization= NULL; + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions)); + memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric, &servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t)); + //secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long)); + //*secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one; + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= NULL; + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb; + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb)); + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0; + struct NR_CFRA_SSB_Resource *ssbElem = calloc(1,sizeof(struct NR_CFRA_SSB_Resource)); + ssbElem->ssb = 0; + ssbElem->ra_PreambleIndex= 63; + ASN_SEQUENCE_ADD(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ssb_ResourceList.list,ssbElem); + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->ext1 = NULL; + secondaryCellGroup->spCellConfig->rlf_TimersAndConstants = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants)); secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->present = NR_SetupRelease_RLF_TimersAndConstants_PR_setup; secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup=calloc(1,sizeof(*secondaryCellGroup->spCellConfig->rlf_TimersAndConstants->choice.setup)); @@ -407,17 +427,45 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Common->pdcch_ConfigCommon->present = NR_SetupRelease_PDCCH_ConfigCommon_PR_setup; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup = calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup)); bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->controlResourceSetZero=NULL; - bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet=NULL; - bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceZero=NULL; + bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet)); + NR_ControlResourceSet_t *coreset = calloc(1,sizeof(*coreset)); + coreset->controlResourceSetId=1; + // frequencyDomainResources '11111111 11111111 00000000 00000000 00000000 00000'B, + coreset->frequencyDomainResources.buf = calloc(1,6); + coreset->frequencyDomainResources.buf[0] = 0xff; + coreset->frequencyDomainResources.buf[1] = 0xff; + coreset->frequencyDomainResources.buf[2] = 0; + coreset->frequencyDomainResources.buf[3] = 0; + coreset->frequencyDomainResources.buf[4] = 0; + coreset->frequencyDomainResources.buf[5] = 0; + coreset->frequencyDomainResources.size = 6; + coreset->frequencyDomainResources.bits_unused = 3; + coreset->duration=1; + coreset->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved; + coreset->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; + + coreset->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset->tci_StatesPDCCH_ToAddList)); + NR_TCI_StateId_t *tci[8]; + for (int i=0;i<8;i++) { + tci[i]=calloc(1,sizeof(*tci[i])); + *tci[i] = i; + ASN_SEQUENCE_ADD(&coreset->tci_StatesPDCCH_ToAddList->list,tci[i]); + } + coreset->tci_StatesPDCCH_ToReleaseList = NULL; + coreset->tci_PresentInDCI = NULL; + coreset->pdcch_DMRS_ScramblingID = NULL; + + bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonControlResourceSet = coreset; + + bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->searchSpaceZero=NULL; bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=NULL; - bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList=calloc(1,sizeof(*bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList)); NR_SearchSpace_t *ss=calloc(1,sizeof(*ss)); ss->searchSpaceId = 1; ss->controlResourceSetId=calloc(1,sizeof(*ss->controlResourceSetId)); - *ss->controlResourceSetId=0; + *ss->controlResourceSetId=1; ss->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss->monitoringSlotPeriodicityAndOffset)); ss->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1; ss->duration=NULL; @@ -474,64 +522,13 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco bwp->bwp_Dedicated->pdcch_Config->present = NR_SetupRelease_PDCCH_Config_PR_setup; bwp->bwp_Dedicated->pdcch_Config->choice.setup = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup)); bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList)); - NR_ControlResourceSet_t *coreset0 = calloc(1,sizeof(*coreset0)); - coreset0->controlResourceSetId=1; - // frequencyDomainResources '11111111 11111111 00000000 00000000 00000000 00000'B, - coreset0->frequencyDomainResources.buf = calloc(1,6); - coreset0->frequencyDomainResources.buf[0] = 0xff; - coreset0->frequencyDomainResources.buf[1] = 0xff; - coreset0->frequencyDomainResources.buf[2] = 0; - coreset0->frequencyDomainResources.buf[3] = 0; - coreset0->frequencyDomainResources.buf[4] = 0; - coreset0->frequencyDomainResources.buf[5] = 0; - coreset0->frequencyDomainResources.size = 6; - coreset0->frequencyDomainResources.bits_unused = 3; - coreset0->duration=1; - coreset0->cce_REG_MappingType.present = NR_ControlResourceSet__cce_REG_MappingType_PR_nonInterleaved; - coreset0->precoderGranularity = NR_ControlResourceSet__precoderGranularity_sameAsREG_bundle; - coreset0->tci_StatesPDCCH_ToAddList=calloc(1,sizeof(*coreset0->tci_StatesPDCCH_ToAddList)); - NR_TCI_StateId_t *tci[8]; - for (int i=0;i<8;i++) { - tci[i]=calloc(1,sizeof(*tci[i])); - *tci[i] = i; - ASN_SEQUENCE_ADD(&coreset0->tci_StatesPDCCH_ToAddList->list,tci[i]); - } - coreset0->tci_StatesPDCCH_ToReleaseList = NULL; - coreset0->tci_PresentInDCI = NULL; - coreset0->pdcch_DMRS_ScramblingID = NULL; ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->controlResourceSetToAddModList->list, - coreset0); + coreset); bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList = calloc(1,sizeof(*bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList)); - NR_SearchSpace_t *ss3 = calloc(1,sizeof(*ss3)); + NR_SearchSpace_t *ss2 = calloc(1,sizeof(*ss2)); - ss3->searchSpaceId=3; - ss3->controlResourceSetId=calloc(1,sizeof(*ss3->controlResourceSetId)); - *ss3->controlResourceSetId=1; - ss3->monitoringSlotPeriodicityAndOffset=calloc(1,sizeof(*ss3->monitoringSlotPeriodicityAndOffset)); - ss3->monitoringSlotPeriodicityAndOffset->present = NR_SearchSpace__monitoringSlotPeriodicityAndOffset_PR_sl1; - ss3->monitoringSlotPeriodicityAndOffset->choice.sl1=(NULL_t)0; - ss3->duration=NULL; - ss3->monitoringSymbolsWithinSlot = calloc(1,sizeof(*ss3->monitoringSymbolsWithinSlot)); - ss3->monitoringSymbolsWithinSlot->buf = calloc(1,2); - ss3->monitoringSymbolsWithinSlot->size = 2; - ss3->monitoringSymbolsWithinSlot->bits_unused = 2; - ss3->monitoringSymbolsWithinSlot->buf[0]=0xc0; - ss3->monitoringSymbolsWithinSlot->buf[1]=0x0; - ss3->nrofCandidates=calloc(1,sizeof(*ss3->nrofCandidates)); - ss3->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0; - ss3->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0; - ss3->nrofCandidates->aggregationLevel4 = NR_SearchSpace__nrofCandidates__aggregationLevel4_n1; - ss3->nrofCandidates->aggregationLevel8 = NR_SearchSpace__nrofCandidates__aggregationLevel8_n0; - ss3->nrofCandidates->aggregationLevel16 = NR_SearchSpace__nrofCandidates__aggregationLevel16_n0; - ss3->searchSpaceType=calloc(1,sizeof(*ss3->searchSpaceType)); - ss3->searchSpaceType->present = NR_SearchSpace__searchSpaceType_PR_common; - ss3->searchSpaceType->choice.common = calloc(1,sizeof(*ss3->searchSpaceType->choice.common)); - ss3->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0=calloc(1,sizeof(*ss3->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0)); - ss3->searchSpaceType->choice.common->dci_Format2_0=NULL; - ss3->searchSpaceType->choice.common->dci_Format2_2=NULL; - ss3->searchSpaceType->choice.common->dci_Format2_3=NULL; ss2->searchSpaceId=2; ss2->controlResourceSetId=calloc(1,sizeof(*ss2->controlResourceSetId)); @@ -557,8 +554,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco ss2->searchSpaceType->choice.ue_Specific = calloc(1,sizeof(*ss2->searchSpaceType->choice.ue_Specific)); ss2->searchSpaceType->choice.ue_Specific->dci_Formats=NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_1_And_1_1; - ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, - ss3); ASN_SEQUENCE_ADD(&bwp->bwp_Dedicated->pdcch_Config->choice.setup->searchSpacesToAddModList->list, ss2); diff --git a/openair2/RRC/NR_UE/L2_interface_ue.c b/openair2/RRC/NR_UE/L2_interface_ue.c index cb8ded1971..08976522b0 100644 --- a/openair2/RRC/NR_UE/L2_interface_ue.c +++ b/openair2/RRC/NR_UE/L2_interface_ue.c @@ -56,4 +56,15 @@ nr_mac_rrc_data_ind_ue( return(0); +} + +int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP, + const int CC_id, + const frame_t frameP, + const rb_id_t Srb_id, + uint8_t *const buffer_pP ){ + + // todo + + 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 87e899845e..44215df218 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" #include "executables/softmodem-common.h" @@ -319,7 +319,7 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){ RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ResourceConfig_list, NR_maxNrofCSI_ResourceConfigurations); RRC_LIST_INIT(NR_UE_rrc_inst->CSI_ReportConfig_list, NR_maxNrofCSI_ReportConfigurations); - if (get_softmodem_params()->phy_test==1) { + if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) { // read in files for RRCReconfiguration and RBconfig FILE *fd; char filename[1024]; diff --git a/openair2/RRC/NR_UE/rrc_defs.h b/openair2/RRC/NR_UE/rrc_defs.h index cb1207757d..6481fb0cea 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" diff --git a/openair2/RRC/NR_UE/rrc_proto.h b/openair2/RRC/NR_UE/rrc_proto.h index 6e0d0a10de..7bc7e4b90c 100644 --- a/openair2/RRC/NR_UE/rrc_proto.h +++ b/openair2/RRC/NR_UE/rrc_proto.h @@ -102,6 +102,18 @@ int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(const module_id_t module_id, const ui \param pdu_len data length of pdu*/ int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const channel_t channel, const uint8_t* pduP, const sdu_size_t pdu_len); +/**\brief + \param module_id module id + \param CC_id component carrier id + \param frame_t frameP + \param rb_id_t SRB id + \param buffer_pP pointer to buffer*/ +int8_t mac_rrc_nr_data_req_ue(const module_id_t Mod_idP, + const int CC_id, + const frame_t frameP, + const rb_id_t Srb_id, + uint8_t *const buffer_pP); + /** @}*/ #endif diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index b297c96e56..debe5e0712 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -359,7 +359,7 @@ void x2ap_eNB_handle_sctp_init_msg_multi_cnf( * Failure means multi_sd < 0. */ if (instance->multi_sd < 0) { - X2AP_ERROR("Error: be sure to properly configure X2 in your configuration file.\n"); + X2AP_ERROR("Error: be sure to properly configure X22 in your configuration file.\n"); DevAssert(instance->multi_sd >= 0); } @@ -474,7 +474,7 @@ void x2ap_eNB_handle_sgNB_add_req(instance_t instance, x2ap_set_ids(id_manager, ue_id, x2ap_ENDC_sgnb_addition_req->rnti, ue_id, -1); x2ap_id_set_state(id_manager, ue_id, X2ID_STATE_NSA_PREPARE); - x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_eNB_data, ue_id); + x2ap_eNB_generate_ENDC_x2_SgNB_addition_request(instance_p, x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data, ue_id); } static diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.c b/openair2/X2AP/x2ap_eNB_generate_messages.c index 47a3475063..78a93e9712 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.c +++ b/openair2/X2AP/x2ap_eNB_generate_messages.c @@ -1496,7 +1496,7 @@ int x2ap_eNB_generate_ENDC_x2_setup_response( } int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( - x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id) + x2ap_eNB_instance_t *instance_p, x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id) { X2AP_X2AP_PDU_t pdu; X2AP_SgNBAdditionRequest_t *out; @@ -1516,8 +1516,6 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( int uEaggregateMaximumBitRateDownlink = 100000000; int uEaggregateMaximumBitRateUplink = 100000000; int e_rabs_tobeadded = 1; - int e_RAB_ID = 1; - int drb_ID = 2; long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present; long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present; long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present; @@ -1527,9 +1525,9 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( priority_level_t priority_level = PRIORITY_LEVEL_NO_PRIORITY; e_rab_tobe_added_t e_MCG_rabs_tobeadded; e_MCG_rabs_tobeadded.gtp_teid = 0; - e_MCG_rabs_tobeadded.eNB_addr.length = 24; + e_MCG_rabs_tobeadded.sgw_addr.length = 24; uint8_t buf[20] = { 0 }; - memcpy(e_MCG_rabs_tobeadded.eNB_addr.buffer, buf, 20*sizeof(uint8_t)); + memcpy(e_MCG_rabs_tobeadded.sgw_addr.buffer, buf, 20*sizeof(uint8_t)); FILE *fd; fd = fopen("../../../executables/uecap.raw","r"); @@ -1614,8 +1612,8 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_ToBeAdded_SgNBAddReq_ItemIEs__value_PR_E_RABs_ToBeAdded_SgNBAddReq_Item; e_RABS_ToBeAdded_SgNBAddReq_Item = &e_RABS_ToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_ToBeAdded_SgNBAddReq_Item; { - e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = drb_ID; - e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID; + e_RABS_ToBeAdded_SgNBAddReq_Item->drb_ID = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].drb_ID; + e_RABS_ToBeAdded_SgNBAddReq_Item->e_RAB_ID = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].e_rab_id; e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB; e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources; e_RABS_ToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources; @@ -1628,14 +1626,14 @@ int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = priority_level; //Continue from filling the UL_GTPtunnelEndpointInformation inspired from how it is done for the HO case - INT32_TO_OCTET_STRING(e_MCG_rabs_tobeadded.gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID); - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size = e_MCG_rabs_tobeadded.eNB_addr.length/8; - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_MCG_rabs_tobeadded.eNB_addr.length%8; + INT32_TO_OCTET_STRING(x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].gtp_teid, &e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID); + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.length/8; + e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.length%8; e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf = calloc(1, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size); memcpy (e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf, - e_MCG_rabs_tobeadded.eNB_addr.buffer, + x2ap_ENDC_sgnb_addition_req->e_rabs_tobeadded[i].sgw_addr.buffer, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size); } @@ -1691,13 +1689,7 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in // Currently hardcoded (dummy) values filling the fields of SgNB_addition_request message. To be substituted // with values coming from RRC. - uint16_t nRencryptionAlgorithms = 0; - uint16_t nRintegrityProtectionAlgorithms = 0; - uint8_t SgNBSecurityKey[32] = { 0 }; - int uEaggregateMaximumBitRateDownlink = 100000000; - int uEaggregateMaximumBitRateUplink = 100000000; int e_rabs_admitted_tobeadded = 1; - int e_RAB_ID = 1; long int pDCPatSgNB = X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present; long int mCGresources = X2AP_EN_DC_ResourceConfiguration__mCGresources_not_present; long int sCGresources = X2AP_EN_DC_ResourceConfiguration__sCGresources_not_present; @@ -1748,21 +1740,21 @@ int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *in e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_ItemIEs__value_PR_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item; e_RABS_AdmittedToBeAdded_SgNBAddReq_Item = &e_RABS_AdmittedToBeAdded_SgNBAddReq_ItemIEs->value.choice.E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item; { - e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->e_RAB_ID = e_RAB_ID; + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->e_RAB_ID = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].e_rab_id; e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.pDCPatSgNB = pDCPatSgNB; e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.mCGresources = mCGresources; e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->en_DC_ResourceConfiguration.sCGresources = sCGresources; if (pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){ e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.present = X2AP_E_RABs_Admitted_ToBeAdded_SgNBAddReqAck_Item__resource_configuration_PR_sgNBPDCPpresent; - INT32_TO_OCTET_STRING(e_SCG_rabs_tobeadded.gtp_teid, &e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID); - e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = e_SCG_rabs_tobeadded.eNB_addr.length/8; - e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = e_SCG_rabs_tobeadded.eNB_addr.length%8; + INT32_TO_OCTET_STRING(x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gtp_teid, &e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID); + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.length/8; + e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.length%8; e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf = calloc(1, e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size); memcpy (e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf, - e_SCG_rabs_tobeadded.eNB_addr.buffer, + x2ap_sgnb_addition_req_ACK->e_rabs_admitted_tobeadded[i].gnb_addr.buffer, e_RABS_AdmittedToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size); } diff --git a/openair2/X2AP/x2ap_eNB_generate_messages.h b/openair2/X2AP/x2ap_eNB_generate_messages.h index 114ed84a68..3dfccc0e52 100644 --- a/openair2/X2AP/x2ap_eNB_generate_messages.h +++ b/openair2/X2AP/x2ap_eNB_generate_messages.h @@ -70,7 +70,7 @@ int x2ap_gNB_generate_ENDC_x2_setup_request(x2ap_eNB_instance_t *instance_p, x2a int x2ap_eNB_generate_ENDC_x2_setup_response( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p); -int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id); +int x2ap_eNB_generate_ENDC_x2_SgNB_addition_request( x2ap_eNB_instance_t *instance_p, x2ap_ENDC_sgnb_addition_req_t *x2ap_ENDC_sgnb_addition_req, x2ap_eNB_data_t *x2ap_eNB_data_p, int ue_id); int x2ap_gNB_generate_ENDC_x2_SgNB_addition_request_ACK( x2ap_eNB_instance_t *instance_p, x2ap_eNB_data_t *x2ap_eNB_data_p, x2ap_ENDC_sgnb_addition_req_ACK_t *x2ap_sgnb_addition_req_ACK, int ue_id); diff --git a/openair2/X2AP/x2ap_eNB_handler.c b/openair2/X2AP/x2ap_eNB_handler.c index b7a9b70596..f518df1fd9 100644 --- a/openair2/X2AP/x2ap_eNB_handler.c +++ b/openair2/X2AP/x2ap_eNB_handler.c @@ -1749,13 +1749,22 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability; X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rab_param[i].qos.allocation_retention_priority.priority_level = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.full_E_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel; - memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.buffer, + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.buf, e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size); - X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].eNB_addr.length = + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.length = e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.transportLayerAddress.bits_unused; +LOG_I(RRC,"x2u tunnel: index %d target sgw ip %d.%d.%d.%d length %d gtp teid %u\n", + i, + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[0], + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[1], + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[2], + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.buffer[3], + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].sgw_addr.length, + X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].gtp_teid); + OCTET_STRING_TO_INT32(&e_RABS_ToBeAdded_SgNBAddReq_Item->resource_configuration.choice.sgNBPDCPpresent.s1_UL_GTPtunnelEndpoint.gTP_TEID, X2AP_ENDC_SGNB_ADDITION_REQ(msg).e_rabs_tobeadded[i].gtp_teid); } @@ -1771,7 +1780,6 @@ int x2ap_gNB_handle_ENDC_sGNB_addition_request (instance_t instance, X2AP_FIND_PROTOCOLIE_BY_ID(X2AP_SgNBAdditionRequest_IEs_t, ie, x2SgNBAdditionRequest, X2AP_ProtocolIE_ID_id_MeNBtoSgNBContainer, true); - X2AP_MeNBtoSgNBContainer_t *container = &ie->value.choice.MeNBtoSgNBContainer; if (ie->value.choice.MeNBtoSgNBContainer.size > 8192 ) // TODO: this is the size of rrc_buffer in struct x2ap_handover_req_s { printf("%s:%d: fatal: buffer too big\n", __FILE__, __LINE__); abort(); } @@ -1891,10 +1899,10 @@ int x2ap_eNB_handle_ENDC_sGNB_addition_response (instance_t instance, X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].e_rab_id = e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->e_RAB_ID ; if(e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->en_DC_ResourceConfiguration.pDCPatSgNB == X2AP_EN_DC_ResourceConfiguration__pDCPatSgNB_present){ - memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.buffer, + memcpy(X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.buffer, e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.buf, e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size); - X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].eNB_addr.length = + X2AP_ENDC_SGNB_ADDITION_REQ_ACK(msg).e_rabs_admitted_tobeadded[i].gnb_addr.length = e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.size * 8 - e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.transportLayerAddress.bits_unused; OCTET_STRING_TO_INT32(&e_RABS_Admitted_ToBeAdded_SgNBAddReqAck_Item->resource_configuration.choice.sgNBPDCPpresent.s1_DL_GTPtunnelEndpoint.gTP_TEID, @@ -1943,7 +1951,6 @@ int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance, x2ap_eNB_instance_t *instance_p; x2ap_eNB_data_t *x2ap_eNB_data; MessageDef *msg; - int ue_id; DevAssert (pdu != NULL); x2SgNBReconfigurationComplete = &pdu->choice.initiatingMessage.value.choice.SgNBReconfigurationComplete; @@ -1964,7 +1971,7 @@ int x2ap_gNB_handle_ENDC_sGNB_reconfiguration_complete (instance_t instance, instance_p = x2ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - //Allocate an ITTI X2AP_SGNB_ADDITION_REQ message instead + //Allocate an ITTI X2AP_sGNB_reconfiguration_complete message msg = itti_alloc_new_message(TASK_X2AP, X2AP_ENDC_SGNB_RECONF_COMPLETE); /* X2AP_ProtocolIE_ID_id_MeNB_UE_X2AP_ID */ diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index f15f295548..f095cce67d 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -943,6 +943,8 @@ gtpv1u_create_s1u_tunnel( memcpy(&create_tunnel_resp_pP->enb_addr.buffer, &RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up, sizeof (in_addr_t)); + + LOG_I(GTPU,"Configured GTPu address : %x\n",RC.gtpv1u_data_g->enb_ip_address_for_S1u_S12_S4_up); create_tunnel_resp_pP->enb_addr.length = sizeof (in_addr_t); addrs_length_in_bytes = create_tunnel_req_pP->sgw_addr[i].length / 8; AssertFatal((addrs_length_in_bytes == 4) || @@ -971,6 +973,15 @@ gtpv1u_create_s1u_tunnel( gtpv1u_ue_data_p->bearers[eps_bearer_id - GTPV1U_BEARER_OFFSET].teid_sgw = create_tunnel_req_pP->sgw_S1u_teid[i]; gtpv1u_ue_data_p->num_bearers++; create_tunnel_resp_pP->enb_S1u_teid[i] = s1u_teid; + + LOG_I(GTPU,"Copied to create_tunnel_resp tunnel: index %d target gNB ip %d.%d.%d.%d length %d gtp teid %u\n", + i, + create_tunnel_resp_pP->enb_addr.buffer[0], + create_tunnel_resp_pP->enb_addr.buffer[1], + create_tunnel_resp_pP->enb_addr.buffer[2], + create_tunnel_resp_pP->enb_addr.buffer[3], + create_tunnel_resp_pP->enb_addr.length, + create_tunnel_resp_pP->enb_S1u_teid[i]); } else { create_tunnel_resp_pP->enb_S1u_teid[i] = 0; create_tunnel_resp_pP->status = 0xFF; diff --git a/openair3/GTPV1-U/gtpv1u_gNB.c b/openair3/GTPV1-U/gtpv1u_gNB.c new file mode 100644 index 0000000000..1a75214d65 --- /dev/null +++ b/openair3/GTPV1-U/gtpv1u_gNB.c @@ -0,0 +1,311 @@ +/* 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 gtpv1u_gNB.c + * \brief + * \author Sebastien ROUX, Lionel GAUTHIER, Navid Nikaein, Panos MATZAKOS + * \version 1.0 + * \company Eurecom + * \email: lionel.gauthier@eurecom.fr + */ +#include +#include + +#include "mme_config.h" +#include "intertask_interface.h" +#include "msc.h" + +#include "gtpv1u.h" +#include "NwGtpv1u.h" +#include "NwGtpv1uMsg.h" +#include "NwGtpv1uPrivate.h" +#include "NwLog.h" +#include "gtpv1u_eNB_defs.h" +#include "gtpv1_u_messages_types.h" +#include "udp_eNB_task.h" +#include "common/utils/LOG/log.h" +#include "COMMON/platform_types.h" +#include "COMMON/platform_constants.h" +#include "common/utils/LOG/vcd_signal_dumper.h" +#include "common/ran_context.h" +#include "gtpv1u_eNB_defs.h" +#include "gtpv1u_eNB_task.h" +#include "gtpv1u_gNB_task.h" +#include "rrc_eNB_GTPV1U.h" + +#undef GTP_DUMP_SOCKET + +extern unsigned char NB_eNB_INST; + +extern RAN_CONTEXT_t RC; + +extern NwGtpv1uRcT gtpv1u_eNB_send_udp_msg( + NwGtpv1uUdpHandleT udpHandle, + uint8_t *buffer, + uint32_t buffer_len, + uint32_t buffer_offset, + uint32_t peerIpAddr, + uint16_t peerPort); + +extern NwGtpv1uRcT gtpv1u_eNB_log_request(NwGtpv1uLogMgrHandleT hLogMgr, + uint32_t logLevel, + NwCharT *file, + uint32_t line, + NwCharT *logStr); + +static NwGtpv1uRcT gtpv1u_start_timer_wrapper( + NwGtpv1uTimerMgrHandleT tmrMgrHandle, + uint32_t timeoutSec, + uint32_t timeoutUsec, + uint32_t tmrType, + void *timeoutArg, + NwGtpv1uTimerHandleT *hTmr) { + NwGtpv1uRcT rc = NW_GTPV1U_OK; + long timer_id; + + if (tmrType == NW_GTPV1U_TMR_TYPE_ONE_SHOT) { + timer_setup(timeoutSec, + timeoutUsec, + TASK_GTPV1_U, + INSTANCE_DEFAULT, + TIMER_ONE_SHOT, + timeoutArg, + &timer_id); + } else { + timer_setup(timeoutSec, + timeoutUsec, + TASK_GTPV1_U, + INSTANCE_DEFAULT, + TIMER_PERIODIC, + timeoutArg, + &timer_id); + } + + return rc; +} + + +static NwGtpv1uRcT +gtpv1u_stop_timer_wrapper( + NwGtpv1uTimerMgrHandleT tmrMgrHandle, + NwGtpv1uTimerHandleT hTmr) { + NwGtpv1uRcT rc = NW_GTPV1U_OK; + return rc; +} + +/* Callback called when a gtpv1u message arrived on UDP interface */ +NwGtpv1uRcT gtpv1u_gNB_process_stack_req( + NwGtpv1uUlpHandleT hUlp, + NwGtpv1uUlpApiT *pUlpApi) { + boolean_t result = FALSE; + teid_t teid = 0; + hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; + gtpv1u_teid_data_t *gtpv1u_teid_data_p = NULL; + protocol_ctxt_t ctxt; + NwGtpv1uRcT rc; + + switch(pUlpApi->apiType) { + /* Here there are two type of messages handled: + * - T-PDU + * - END-MARKER + */ + case NW_GTPV1U_ULP_API_RECV_TPDU: { + uint8_t buffer[4096]; + uint32_t buffer_len; + uint16_t msgType = NW_GTP_GPDU; + NwGtpv1uMsgT *pMsg = NULL; + /* Nw-gptv1u stack has processed a PDU. we can schedule it to PDCP + * for transmission. + */ + teid = pUlpApi->apiInfo.recvMsgInfo.teid; + pMsg = (NwGtpv1uMsgT *) pUlpApi->apiInfo.recvMsgInfo.hMsg; + msgType = pMsg->msgType; + + if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg, + buffer, &buffer_len)) { + LOG_E(GTPU, "Error while retrieving T-PDU"); + } + + itti_free(TASK_UDP, ((NwGtpv1uMsgT *)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf); +#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0 + gtpv1u_eNB_write_dump_socket(buffer,buffer_len); +#endif + rc = nwGtpv1uMsgDelete(RC.gtpv1u_data_g->gtpv1u_stack, + pUlpApi->apiInfo.recvMsgInfo.hMsg); + + if (rc != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uMsgDelete failed: 0x%x\n", rc); + } + + hash_rc = hashtable_get(RC.gtpv1u_data_g->teid_mapping, teid, (void **)>pv1u_teid_data_p); + + if (hash_rc == HASH_TABLE_OK) { +#if defined(LOG_GTPU) && LOG_GTPU > 0 + LOG_D(GTPU, "Received T-PDU from gtpv1u stack teid %u size %d -> enb module id %u ue module id %u rab id %u\n", + teid, + buffer_len, + gtpv1u_teid_data_p->enb_id, + gtpv1u_teid_data_p->ue_id, + gtpv1u_teid_data_p->eps_bearer_id); +#endif + //warning "LG eps bearer mapping to DRB id to do (offset -4)" + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, gtpv1u_teid_data_p->enb_id, ENB_FLAG_YES, gtpv1u_teid_data_p->ue_id, 0, 0,gtpv1u_teid_data_p->enb_id); + MSC_LOG_TX_MESSAGE( + MSC_GTPU_ENB, + MSC_PDCP_ENB, + NULL,0, + MSC_AS_TIME_FMT" DATA-REQ rb %u size %u", + 0,0, + (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4, + buffer_len); + + result = pdcp_data_req( + &ctxt, + SRB_FLAG_NO, + (gtpv1u_teid_data_p->eps_bearer_id) ? gtpv1u_teid_data_p->eps_bearer_id - 4: 5-4, + 0, // mui + SDU_CONFIRM_NO, // confirm + buffer_len, + buffer, + PDCP_TRANSMISSION_MODE_DATA,NULL, NULL + ); + + if ( result == FALSE ) { + if (ctxt.configured == FALSE ) + LOG_W(GTPU, "gNB node PDCP data request failed, cause: [UE:%x]RB is not configured!\n", ctxt.rnti) ; + else + LOG_W(GTPU, "PDCP data request failed\n"); + + return NW_GTPV1U_FAILURE; + } + } else { + LOG_W(GTPU, "Received T-PDU from gtpv1u stack teid %u unknown size %u", teid, buffer_len); + } + } + break; + + default: { + LOG_E(GTPU, "Received undefined UlpApi (%02x) from gtpv1u stack!\n", + pUlpApi->apiType); + } + } // end of switch + + return NW_GTPV1U_OK; +} + +int gtpv1u_gNB_init(void) { + NwGtpv1uRcT rc = NW_GTPV1U_FAILURE; + NwGtpv1uUlpEntityT ulp; + NwGtpv1uUdpEntityT udp; + NwGtpv1uLogMgrEntityT log; + NwGtpv1uTimerMgrEntityT tmr; + // enb_properties_p = enb_config_get()->properties[0]; + RC.gtpv1u_data_g = (gtpv1u_data_t *)calloc(sizeof(gtpv1u_data_t),1); + LOG_I(GTPU, "Initializing GTPU stack %p\n",&RC.gtpv1u_data_g); + //gtpv1u_data_g.gtpv1u_stack; + /* Initialize UE hashtable */ + RC.gtpv1u_data_g->ue_mapping = hashtable_create (32, NULL, NULL); + AssertFatal(RC.gtpv1u_data_g->ue_mapping != NULL, " ERROR Initializing TASK_GTPV1_U task interface: in hashtable_create returned %p\n", RC.gtpv1u_data_g->ue_mapping); + RC.gtpv1u_data_g->teid_mapping = hashtable_create (256, NULL, NULL); + AssertFatal(RC.gtpv1u_data_g->teid_mapping != NULL, " ERROR Initializing TASK_GTPV1_U task interface: in hashtable_create\n"); + // RC.gtpv1u_data_g.enb_ip_address_for_S1u_S12_S4_up = enb_properties_p->enb_ipv4_address_for_S1U; + //gtpv1u_data_g.udp_data; + RC.gtpv1u_data_g->seq_num = 0; + RC.gtpv1u_data_g->restart_counter = 0; + + /* Initializing GTPv1-U stack */ + if ((rc = nwGtpv1uInitialize(&RC.gtpv1u_data_g->gtpv1u_stack, GTPU_STACK_ENB)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "Failed to setup nwGtpv1u stack %x\n", rc); + return -1; + } + + if ((rc = nwGtpv1uSetLogLevel(RC.gtpv1u_data_g->gtpv1u_stack, + NW_LOG_LEVEL_DEBG)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "Failed to setup loglevel for stack %x\n", rc); + return -1; + } + + /* Set the ULP API callback. Called once message have been processed by the + * nw-gtpv1u stack. + */ + ulp.ulpReqCallback = gtpv1u_gNB_process_stack_req; + memset((void *)&(ulp.hUlp), 0, sizeof(NwGtpv1uUlpHandleT)); + + if ((rc = nwGtpv1uSetUlpEntity(RC.gtpv1u_data_g->gtpv1u_stack, &ulp)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uSetUlpEntity: %x", rc); + return -1; + } + + /* nw-gtpv1u stack requires an udp callback to send data over UDP. + * We provide a wrapper to UDP task. + */ + udp.udpDataReqCallback = gtpv1u_eNB_send_udp_msg; + memset((void *)&(udp.hUdp), 0, sizeof(NwGtpv1uUdpHandleT)); + + if ((rc = nwGtpv1uSetUdpEntity(RC.gtpv1u_data_g->gtpv1u_stack, &udp)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uSetUdpEntity: %x", rc); + return -1; + } + + log.logReqCallback = gtpv1u_eNB_log_request; + memset((void *)&(log.logMgrHandle), 0, sizeof(NwGtpv1uLogMgrHandleT)); + + if ((rc = nwGtpv1uSetLogMgrEntity(RC.gtpv1u_data_g->gtpv1u_stack, &log)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uSetLogMgrEntity: %x", rc); + return -1; + } + + /* Timer interface is more complicated as both wrappers doesn't send a message + * to the timer task but call the timer API functions start/stop timer. + */ + tmr.tmrMgrHandle = 0; + tmr.tmrStartCallback = gtpv1u_start_timer_wrapper; + tmr.tmrStopCallback = gtpv1u_stop_timer_wrapper; + + if ((rc = nwGtpv1uSetTimerMgrEntity(RC.gtpv1u_data_g->gtpv1u_stack, &tmr)) != NW_GTPV1U_OK) { + LOG_E(GTPU, "nwGtpv1uSetTimerMgrEntity: %x", rc); + return -1; + } + +#if defined(GTP_DUMP_SOCKET) && GTP_DUMP_SOCKET > 0 + + if ((ret = gtpv1u_eNB_create_dump_socket()) < 0) { + return -1; + } + +#endif + LOG_D(GTPU, "Initializing GTPV1U interface for eNB: DONE\n"); + return 0; +} + +void *gtpv1u_gNB_task(void *args) { + int rc = 0; + rc = gtpv1u_gNB_init(); + AssertFatal(rc == 0, "gtpv1u_eNB_init Failed"); + itti_mark_task_ready(TASK_GTPV1_U); + MSC_START_USE(); + + while(1) { + (void) gtpv1u_eNB_process_itti_msg (NULL); + } + + return NULL; +} + diff --git a/openair3/GTPV1-U/gtpv1u_gNB_task.h b/openair3/GTPV1-U/gtpv1u_gNB_task.h new file mode 100644 index 0000000000..42fae7a714 --- /dev/null +++ b/openair3/GTPV1-U/gtpv1u_gNB_task.h @@ -0,0 +1,37 @@ +/* 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 gtpv1u_gNB_task.h +* \brief +* \author Lionel Gauthier Panos Matzakos +* \company Eurecom +* \email: lionel.gauthier@eurecom.fr +*/ + +#ifndef GTPV1U_GNB_TASK_H_ +#define GTPV1U_GNB_TASK_H_ + +int gtpv1u_gNB_init(void); + +void *gtpv1u_gNB_task(void *args); + + +#endif /* GTPV1U_GNB_TASK_H_ */ + diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 3592cf80a1..c228034245 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -69,7 +69,6 @@ s1ap_eNB_config_t s1ap_config; static int s1ap_eNB_generate_s1_setup_request( s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p); - void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB); void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); @@ -361,6 +360,12 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { } break; + case S1AP_E_RAB_MODIFICATION_IND: { + s1ap_eNB_generate_E_RAB_Modification_Indication(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &S1AP_E_RAB_MODIFICATION_IND(received_msg)); + } + break; + case S1AP_UE_CONTEXT_RELEASE_COMPLETE: { s1ap_ue_context_release_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg), &S1AP_UE_CONTEXT_RELEASE_COMPLETE(received_msg)); @@ -508,3 +513,7 @@ static int s1ap_eNB_generate_s1_setup_request( s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0); return ret; } + + + + diff --git a/openair3/S1AP/s1ap_eNB_decoder.c b/openair3/S1AP/s1ap_eNB_decoder.c index 3eb182b159..4635946a05 100644 --- a/openair3/S1AP/s1ap_eNB_decoder.c +++ b/openair3/S1AP/s1ap_eNB_decoder.c @@ -112,6 +112,12 @@ static int s1ap_eNB_decode_successful_outcome(S1AP_S1AP_PDU_t *pdu) { free(res.buffer); break; + case S1AP_ProcedureCode_id_E_RABModificationIndication: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu); + free(res.buffer); + break; + + default: S1AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n", (int)pdu->choice.successfulOutcome.procedureCode); diff --git a/openair3/S1AP/s1ap_eNB_encoder.c b/openair3/S1AP/s1ap_eNB_encoder.c index 0cd46214fc..86536ac525 100644 --- a/openair3/S1AP/s1ap_eNB_encoder.c +++ b/openair3/S1AP/s1ap_eNB_encoder.c @@ -118,15 +118,20 @@ int s1ap_eNB_encode_initiating(S1AP_S1AP_PDU_t *pdu, free(res.buffer); break; + case S1AP_ProcedureCode_id_E_RABModificationIndication: + res = asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_S1AP_S1AP_PDU, pdu); + free(res.buffer); + break; + default: S1AP_DEBUG("Unknown procedure ID (%d) for initiating message\n", (int)pdu->choice.initiatingMessage.procedureCode); return -1; } - if (asn1_xer_print) { + //if (asn1_xer_print) { xer_fprint(stdout, &asn_DEF_S1AP_S1AP_PDU, (void *)pdu); - } + //} memset(&res, 0, sizeof(res)); res = asn_encode_to_new_buffer(NULL, ATS_ALIGNED_CANONICAL_PER, &asn_DEF_S1AP_S1AP_PDU, pdu); diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 87abc1ede9..28ee11187e 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -104,6 +104,11 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_ uint32_t stream, S1AP_S1AP_PDU_t *pdu); +static +int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t assoc_id, + uint32_t stream, + S1AP_S1AP_PDU_t *pdu); + /* Handlers matrix. Only eNB related procedure present here */ s1ap_message_decoded_callback messages_callback[][3] = { { 0, 0, 0 }, /* HandoverPreparation */ @@ -154,6 +159,9 @@ s1ap_message_decoded_callback messages_callback[][3] = { { 0, 0, 0 }, /* UplinkUEAssociatedLPPaTransport */ { 0, 0, 0 }, /* DownlinkNonUEAssociatedLPPaTransport */ { 0, 0, 0 }, /* UplinkNonUEAssociatedLPPaTransport */ + { 0, 0, 0 }, /* UERadioCapabilityMatch */ + { 0, 0, 0 }, /* PWSRestartIndication */ + { 0, s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm, 0 }, /* E_RABModificationIndication */ }; char *s1ap_direction2String(int s1ap_dir) { static char *s1ap_direction_String[] = { @@ -1722,3 +1730,13 @@ int s1ap_eNB_handle_s1_path_switch_request_failure(uint32_t assoc_ // TODO continue return 0; } + +static +int s1ap_eNB_handle_s1_ENDC_e_rab_modification_confirm(uint32_t assoc_id, + uint32_t stream, + S1AP_S1AP_PDU_t *pdu){ + + LOG_W(S1AP, "Implementation of S1AP E-RAB Modification confirm handler is pending...\n"); + return 0; +} + diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index d271ddf6ba..b8a4b98fef 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -1620,3 +1620,319 @@ int s1ap_eNB_path_switch_req(instance_t instance, return ret; } + + +//----------------------------------------------------------------------------- +/* +* eNB generate a S1 E_RAB Modification Indication towards MME +*/ +/*int s1ap_eNB_generate_E_RAB_Modification_Indication( + instance_t instance, + s1ap_e_rab_modification_ind_t *e_rab_modification_ind) +//----------------------------------------------------------------------------- +{ + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + S1AP_S1AP_PDU_t pdu; + S1AP_E_RABModificationIndication_t *out = NULL; + S1AP_E_RABModificationIndicationIEs_t *ie = NULL; + S1AP_E_RABToBeModifiedItemBearerModInd_t *E_RAB_ToBeModifiedItem_BearerModInd = NULL; + S1AP_E_RABToBeModifiedItemBearerModIndIEs_t *E_RAB_ToBeModifiedItem_BearerModInd_IEs = NULL; + + S1AP_E_RABNotToBeModifiedItemBearerModInd_t *E_RAB_NotToBeModifiedItem_BearerModInd = NULL; + S1AP_E_RABNotToBeModifiedItemBearerModIndIEs_t *E_RAB_NotToBeModifiedItem_BearerModInd_IEs = NULL; + + + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + uint8_t *buffer = NULL; + uint32_t len = 0; + int ret = 0; + DevAssert(s1ap_eNB_instance_p != NULL); + DevAssert(e_rab_modification_ind != NULL); + + int num_e_rabs_tobemodified = e_rab_modification_ind->nb_of_e_rabs_tobemodified; + int num_e_rabs_nottobemodified = e_rab_modification_ind->nb_of_e_rabs_nottobemodified; + + uint32_t CSG_id = 0; + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, + e_rab_modification_ind->eNB_ue_s1ap_id)) == NULL) { + // The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs + S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n", + e_rab_modification_ind->eNB_ue_s1ap_id); + return -1; + } + + // Prepare the S1AP message to encode + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_E_RABModificationIndication; + pdu.choice.initiatingMessage.criticality = S1AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_E_RABModificationIndication; + out = &pdu.choice.initiatingMessage.value.choice.E_RABModificationIndication; + // mandatory + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = e_rab_modification_ind->mme_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = e_rab_modification_ind->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + //E-RABs to be modified list + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABToBeModifiedListBearerModInd; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABToBeModifiedListBearerModInd; + + //The following two for-loops here will probably need to change. We should do a different type of search + for(int i=0; iid = S1AP_ProtocolIE_ID_id_E_RABToBeModifiedItemBearerModInd; + E_RAB_ToBeModifiedItem_BearerModInd_IEs->criticality = S1AP_Criticality_reject; + E_RAB_ToBeModifiedItem_BearerModInd_IEs->value.present = S1AP_E_RABToBeModifiedItemBearerModIndIEs__value_PR_E_RABToBeModifiedItemBearerModInd; + E_RAB_ToBeModifiedItem_BearerModInd = &E_RAB_ToBeModifiedItem_BearerModInd_IEs->value.choice.E_RABToBeModifiedItemBearerModInd; + + { + E_RAB_ToBeModifiedItem_BearerModInd->e_RAB_ID = e_rab_modification_ind->e_rabs_tobemodified[i].e_rab_id; + + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length/8; + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length%8; + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf = calloc(1, E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size); + memcpy (E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf, e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.buffer, + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size); + + INT32_TO_OCTET_STRING(e_rab_modification_ind->e_rabs_tobemodified[i].gtp_teid, &E_RAB_ToBeModifiedItem_BearerModInd->dL_GTP_TEID); + + } + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABToBeModifiedListBearerModInd.list, E_RAB_ToBeModifiedItem_BearerModInd_IEs); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + //E-RABs NOT to be modified list + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABNotToBeModifiedListBearerModInd; + ie->criticality = S1AP_Criticality_reject; + if(num_e_rabs_nottobemodified > 0) { + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABNotToBeModifiedListBearerModInd; + + for(int i=0; iid = S1AP_ProtocolIE_ID_id_E_RABNotToBeModifiedItemBearerModInd; + E_RAB_NotToBeModifiedItem_BearerModInd_IEs->criticality = S1AP_Criticality_reject; + E_RAB_NotToBeModifiedItem_BearerModInd_IEs->value.present = S1AP_E_RABNotToBeModifiedItemBearerModIndIEs__value_PR_E_RABNotToBeModifiedItemBearerModInd; + E_RAB_NotToBeModifiedItem_BearerModInd = &E_RAB_NotToBeModifiedItem_BearerModInd_IEs->value.choice.E_RABNotToBeModifiedItemBearerModInd; + + { + E_RAB_NotToBeModifiedItem_BearerModInd->e_RAB_ID = e_rab_modification_ind->e_rabs_nottobemodified[i].e_rab_id; + + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size = e_rab_modification_ind->e_rabs_nottobemodified[i].eNB_addr.length/8; + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = e_rab_modification_ind->e_rabs_nottobemodified[i].eNB_addr.length%8; + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf = + calloc(1, E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size); + memcpy (E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf, e_rab_modification_ind->e_rabs_nottobemodified[i].eNB_addr.buffer, + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size); + + INT32_TO_OCTET_STRING(e_rab_modification_ind->e_rabs_nottobemodified[i].gtp_teid, &E_RAB_NotToBeModifiedItem_BearerModInd->dL_GTP_TEID); + + } + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABNotToBeModifiedListBearerModInd.list, E_RAB_NotToBeModifiedItem_BearerModInd_IEs); + } + } + else{ + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABNotToBeModifiedListBearerModInd; + ie->value.choice.E_RABNotToBeModifiedListBearerModInd.list.size = 0; + } + + + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CSGMembershipInfo; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_CSGMembershipInfo; + ie->value.choice.CSGMembershipInfo.cSGMembershipStatus = S1AP_CSGMembershipStatus_member; + INT32_TO_BIT_STRING(CSG_id, &ie->value.choice.CSGMembershipInfo.cSG_Id); + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + S1AP_ERROR("Failed to encode S1 E-RAB modification indication \n"); + return -1; + } + + // Non UE-Associated signalling -> stream = 0 + S1AP_INFO("Size of encoded message: %d \n", len); + s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, + ue_context_p->mme_ref->assoc_id, buffer, + len, ue_context_p->tx_stream); + +//s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, len, 0); + return ret; +}*/ + +int s1ap_eNB_generate_E_RAB_Modification_Indication( + instance_t instance, + s1ap_e_rab_modification_ind_t *e_rab_modification_ind) +//----------------------------------------------------------------------------- +{ + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + S1AP_S1AP_PDU_t pdu; + S1AP_E_RABModificationIndication_t *out = NULL; + S1AP_E_RABModificationIndicationIEs_t *ie = NULL; + S1AP_E_RABToBeModifiedItemBearerModInd_t *E_RAB_ToBeModifiedItem_BearerModInd = NULL; + S1AP_E_RABToBeModifiedItemBearerModIndIEs_t *E_RAB_ToBeModifiedItem_BearerModInd_IEs = NULL; + + S1AP_E_RABNotToBeModifiedItemBearerModInd_t *E_RAB_NotToBeModifiedItem_BearerModInd = NULL; + S1AP_E_RABNotToBeModifiedItemBearerModIndIEs_t *E_RAB_NotToBeModifiedItem_BearerModInd_IEs = NULL; + + + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + uint8_t *buffer = NULL; + uint32_t len = 0; + int ret = 0; + DevAssert(s1ap_eNB_instance_p != NULL); + DevAssert(e_rab_modification_ind != NULL); + + int num_e_rabs_tobemodified = e_rab_modification_ind->nb_of_e_rabs_tobemodified; + int num_e_rabs_nottobemodified = e_rab_modification_ind->nb_of_e_rabs_nottobemodified; + + uint32_t CSG_id = 0; + uint32_t pseudo_gtp_teid = 10; + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, + e_rab_modification_ind->eNB_ue_s1ap_id)) == NULL) { + // The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs + S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n", + e_rab_modification_ind->eNB_ue_s1ap_id); + return -1; + } + + // Prepare the S1AP message to encode + memset(&pdu, 0, sizeof(pdu)); + pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; + pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_E_RABModificationIndication; + pdu.choice.initiatingMessage.criticality = S1AP_Criticality_reject; + pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_E_RABModificationIndication; + out = &pdu.choice.initiatingMessage.value.choice.E_RABModificationIndication; + /* mandatory */ + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_MME_UE_S1AP_ID; + ie->value.choice.MME_UE_S1AP_ID = e_rab_modification_ind->mme_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_ENB_UE_S1AP_ID; + ie->value.choice.ENB_UE_S1AP_ID = e_rab_modification_ind->eNB_ue_s1ap_id; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + //E-RABs to be modified list + ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABToBeModifiedListBearerModInd; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABToBeModifiedListBearerModInd; + + //The following two for-loops here will probably need to change. We should do a different type of search + for(int i=0; iid = S1AP_ProtocolIE_ID_id_E_RABToBeModifiedItemBearerModInd; + E_RAB_ToBeModifiedItem_BearerModInd_IEs->criticality = S1AP_Criticality_reject; + E_RAB_ToBeModifiedItem_BearerModInd_IEs->value.present = S1AP_E_RABToBeModifiedItemBearerModIndIEs__value_PR_E_RABToBeModifiedItemBearerModInd; + E_RAB_ToBeModifiedItem_BearerModInd = &E_RAB_ToBeModifiedItem_BearerModInd_IEs->value.choice.E_RABToBeModifiedItemBearerModInd; + + { + E_RAB_ToBeModifiedItem_BearerModInd->e_RAB_ID = e_rab_modification_ind->e_rabs_tobemodified[i].e_rab_id; + + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length/8; + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length%8; + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf = calloc(1, E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size); + memcpy (E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.buf, e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.buffer, + E_RAB_ToBeModifiedItem_BearerModInd->transportLayerAddress.size); + + INT32_TO_OCTET_STRING(e_rab_modification_ind->e_rabs_tobemodified[i].gtp_teid, &E_RAB_ToBeModifiedItem_BearerModInd->dL_GTP_TEID); + + } + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABToBeModifiedListBearerModInd.list, E_RAB_ToBeModifiedItem_BearerModInd_IEs); + } + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); + + //E-RABs NOT to be modified list + /*ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_E_RABNotToBeModifiedListBearerModInd; + ie->criticality = S1AP_Criticality_reject; + //if(num_e_rabs_nottobemodified > 0) { + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABNotToBeModifiedListBearerModInd; + + for(int i=0; iid = S1AP_ProtocolIE_ID_id_E_RABNotToBeModifiedItemBearerModInd; + E_RAB_NotToBeModifiedItem_BearerModInd_IEs->criticality = S1AP_Criticality_reject; + E_RAB_NotToBeModifiedItem_BearerModInd_IEs->value.present = S1AP_E_RABNotToBeModifiedItemBearerModIndIEs__value_PR_E_RABNotToBeModifiedItemBearerModInd; + E_RAB_NotToBeModifiedItem_BearerModInd = &E_RAB_NotToBeModifiedItem_BearerModInd_IEs->value.choice.E_RABNotToBeModifiedItemBearerModInd; + + { + E_RAB_NotToBeModifiedItem_BearerModInd->e_RAB_ID = 10; //e_rab_modification_ind->e_rabs_tobemodified[i].e_rab_id; + + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length/8; + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.bits_unused = e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.length%8; + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf = + calloc(1, E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size); + memcpy (E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.buf, e_rab_modification_ind->e_rabs_tobemodified[i].eNB_addr.buffer, + E_RAB_NotToBeModifiedItem_BearerModInd->transportLayerAddress.size); + + //INT32_TO_OCTET_STRING(e_rab_modification_ind->e_rabs_tobemodified[i].gtp_teid, &E_RAB_NotToBeModifiedItem_BearerModInd->dL_GTP_TEID); + INT32_TO_OCTET_STRING(pseudo_gtp_teid, &E_RAB_NotToBeModifiedItem_BearerModInd->dL_GTP_TEID); + + } + ASN_SEQUENCE_ADD(&ie->value.choice.E_RABNotToBeModifiedListBearerModInd.list, E_RAB_NotToBeModifiedItem_BearerModInd_IEs); + } + // } + //else{ +// ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_E_RABNotToBeModifiedListBearerModInd; +// ie->value.choice.E_RABNotToBeModifiedListBearerModInd.list.size = 0; +// } / + + + + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);*/ + + /*ie = (S1AP_E_RABModificationIndicationIEs_t *)calloc(1, sizeof(S1AP_E_RABModificationIndicationIEs_t)); + ie->id = S1AP_ProtocolIE_ID_id_CSGMembershipInfo; + ie->criticality = S1AP_Criticality_reject; + ie->value.present = S1AP_E_RABModificationIndicationIEs__value_PR_CSGMembershipInfo; + ie->value.choice.CSGMembershipInfo.cSGMembershipStatus = S1AP_CSGMembershipStatus_member; + INT32_TO_BIT_STRING(CSG_id, &ie->value.choice.CSGMembershipInfo.cSG_Id); + ie->value.choice.CSGMembershipInfo.cSG_Id.bits_unused=5; + ie->value.choice.CSGMembershipInfo.cellAccessMode = S1AP_CellAccessMode_hybrid; + ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);*/ + + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { + S1AP_ERROR("Failed to encode S1 E-RAB modification indication \n"); + return -1; + } + + // Non UE-Associated signalling -> stream = 0 + S1AP_INFO("Size of encoded message: %d \n", len); + s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, + ue_context_p->mme_ref->assoc_id, buffer, + len, ue_context_p->tx_stream); + +//s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, len, 0); + return ret; +} + + diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.h b/openair3/S1AP/s1ap_eNB_nas_procedures.h index c425719872..47f71cc795 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.h +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.h @@ -52,4 +52,8 @@ int s1ap_eNB_e_rab_release_resp(instance_t instance, int s1ap_eNB_path_switch_req(instance_t instance, s1ap_path_switch_req_t *path_switch_req_p); + +int s1ap_eNB_generate_E_RAB_Modification_Indication( + instance_t instance, s1ap_e_rab_modification_ind_t *e_rab_modification_ind); + #endif /* S1AP_ENB_NAS_PROCEDURES_H_ */ diff --git a/targets/COMMON/create_nr_tasks.c b/targets/COMMON/create_nr_tasks.c index 24c4115980..13f72b3876 100644 --- a/targets/COMMON/create_nr_tasks.c +++ b/targets/COMMON/create_nr_tasks.c @@ -51,17 +51,17 @@ int create_gNB_tasks(uint32_t gnb_nb) } if (gnb_nb > 0) { - /* Last task to create, others task must be ready before its start */ + // Last task to create, others task must be ready before its start if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { LOG_E(GNB_APP, "Create task for gNB APP failed\n"); return -1; } } -/* + if (EPC_MODE_ENABLED) { if (gnb_nb > 0) { - if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { + /*if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) { LOG_E(SCTP, "Create task for SCTP failed\n"); return -1; } @@ -69,7 +69,7 @@ int create_gNB_tasks(uint32_t gnb_nb) if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) { LOG_E(S1AP, "Create task for S1AP failed\n"); return -1; - } + }*/ if(!emulate_rf){ if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { LOG_E(UDP_, "Create task for UDP failed\n"); @@ -84,7 +84,15 @@ int create_gNB_tasks(uint32_t gnb_nb) } } -*/ + + /*if (gnb_nb > 0) { + // Last task to create, others task must be ready before its start + if (itti_create_task (TASK_GNB_APP, gNB_app_task, NULL) < 0) { + LOG_E(GNB_APP, "Create task for gNB APP failed\n"); + return -1; + } + }*/ + if (gnb_nb > 0) { LOG_I(NR_RRC,"Creating NR RRC gNB Task\n"); @@ -100,4 +108,4 @@ int create_gNB_tasks(uint32_t gnb_nb) return 0; } -#endif +//#endif diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf index 1363be3bce..d5bc492644 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.32PRB.usrpx300.conf @@ -105,8 +105,8 @@ gNBs = #1,2,4,8,10,20,40,80 ra_ResponseWindow = 4; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; #ra_ContentionResolutionTimer @@ -114,8 +114,8 @@ gNBs = ra_ContentionResolutionTimer = 7; rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR -#0 = 839, 1 = 139 - prach_RootSequenceIndex_PR = 1; +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; prach_RootSequenceIndex = 1; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf index 1fbc8e30ef..93a6c7fbc9 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band257.tm1.66PRB.usrpn300.conf @@ -105,8 +105,8 @@ gNBs = #1,2,4,8,10,20,40,80 ra_ResponseWindow = 4; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; #ra_ContentionResolutionTimer @@ -114,8 +114,8 @@ gNBs = ra_ContentionResolutionTimer = 7; rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR -#0 = 839, 1 = 139 - prach_RootSequenceIndex_PR = 1; +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; prach_RootSequenceIndex = 1; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf new file mode 100644 index 0000000000..81796ada2c --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.106PRB.slave.conf @@ -0,0 +1,295 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ({mcc = 208; mnc = 93; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641032; + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #scs-SpecificCarrierList + dl_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + dl_subcarrierSpacing = 1; + dl_carrierBandwidth = 106; + #initialDownlinkBWP + #genericParameters + # this is RBstart=0,L=50 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6366; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 12; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 + initialDLBWPstartSymbolAndLength_3 = 57; + + #uplinkConfigCommon + #frequencyInfoUL + ul_frequencyBand = 78; + #scs-SpecificCarrierList + ul_offstToCarrier = 0; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + ul_subcarrierSpacing = 1; + ul_carrierBandwidth = 106; + pMax = 20; + #initialUplinkBWP + #genericParameters + initialULBWPlocationAndBandwidth = 6366; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialULBWPsubcarrierSpacing = 1; + #rach-ConfigCommon + #rach-ConfigGeneric + prach_ConfigurationIndex = 98; +#prach_msg1_FDM +#0 = one, 1=two, 2=four, 3=eight + prach_msg1_FDM = 0; + prach_msg1_FrequencyStart = 0; + zeroCorrelationZoneConfig = 13; + preambleReceivedTargetPower = -118; +#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) + preambleTransMax = 6; +#powerRampingStep +# 0=dB0,1=dB2,2=dB4,3=dB6 + powerRampingStep = 1; +#ra_ReponseWindow +#1,2,4,8,10,20,40,80 + ra_ResponseWindow = 4; +#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; +#oneHalf (0..15) 4,8,12,16,...60,64 + ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; +#ra_ContentionResolutionTimer +#(0..7) 8,16,24,32,40,48,56,64 + ra_ContentionResolutionTimer = 7; + rsrp_ThresholdSSB = 19; +#prach-RootSequenceIndex_PR +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; + prach_RootSequenceIndex = 1; + # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex + # + msg1_SubcarrierSpacing = 1, + +# restrictedSetConfig +# 0=unrestricted, 1=restricted type A, 2=restricted type B + restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 2; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 2; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# pucch-ConfigCommon setup : +# pucchGroupHopping +# 0 = neither, 1= group hopping, 2=sequence hopping + pucchGroupHopping = 0; + hoppingId = 40; + p0_nominal = -90; +# ssb_PositionsInBurs_BitmapPR +# 1=short, 2=medium, 3=long + ssb_PositionsInBurst_PR = 2; + ssb_PositionsInBurst_Bitmap = 1; + +# ssb_periodicityServingCell +# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1 + ssb_periodicityServingCell = 2; + +# dmrs_TypeA_position +# 0 = pos2, 1 = pos3 + dmrs_TypeA_Position = 0; + +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + subcarrierSpacing = 1; + + + #tdd-UL-DL-ConfigurationCommon +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + referenceSubcarrierSpacing = 1; + # pattern1 + # dl_UL_TransmissionPeriodicity + # 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10 + dl_UL_TransmissionPeriodicity = 6; + nrofDownlinkSlots = 7; + nrofDownlinkSymbols = 6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.26"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "192.168.12.188"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "enp0s31f6"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.75/24"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "192.168.12.75/24"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + + GNB_IPV4_ADDRESS_FOR_X2C = "192.168.12.75/23"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + sdr_addrs = "addr=192.168.20.2,mgmt_addr=192.168.20.2"; + clock_src = "internal"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 904a455600..8fec9fdaab 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -46,7 +46,7 @@ gNBs = #initialDownlinkBWP #genericParameters # this is RBstart=0,L=50 (275*(L-1))+RBstart - initialDLBWPlocationAndBandwidth = 13475; + initialDLBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialDLBWPsubcarrierSpacing = 1; @@ -59,7 +59,7 @@ gNBs = #initialULBWPmappingType #0=typeA,1=typeB initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 + #this is SS=1,L=13 initialDLBWPstartSymbolAndLength_0 = 40; initialDLBWPk0_1 = 0; @@ -71,6 +71,12 @@ gNBs = initialDLBWPmappingType_2 = 0; #this is SS=1,L=12 initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 + initialDLBWPstartSymbolAndLength_3 = 57; + #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -83,7 +89,7 @@ gNBs = pMax = 20; #initialUplinkBWP #genericParameters - initialULBWPlocationAndBandwidth = 13475; + initialULBWPlocationAndBandwidth = 6366; # subcarrierSpacing # 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 initialULBWPsubcarrierSpacing = 1; @@ -105,8 +111,8 @@ gNBs = #1,2,4,8,10,20,40,80 ra_ResponseWindow = 4; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; #ra_ContentionResolutionTimer @@ -114,16 +120,16 @@ gNBs = ra_ContentionResolutionTimer = 7; rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR -#0 = 839, 1 = 139 - prach_RootSequenceIndex_PR = 1; +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; prach_RootSequenceIndex = 1; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # msg1_SubcarrierSpacing = 1, - # restrictedSetConfig # 0=unrestricted, 1=restricted type A, 2=restricted type B restrictedSetConfig = 0, + # pusch-ConfigCommon (up to 16 elements) initialULBWPk2_0 = 2; initialULBWPmappingType_0 = 1 @@ -135,6 +141,11 @@ gNBs = # this is SS=0 L=12 initialULBWPstartSymbolAndLength_1 = 69; + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + msg3_DeltaPreamble = 1; p0_NominalWithGrant =-90; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf index 06aa4f6f9f..688fae9b0f 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpx300.conf @@ -59,7 +59,7 @@ gNBs = #initialULBWPmappingType #0=typeA,1=typeB initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 + #this is SS=1,L=13 initialDLBWPstartSymbolAndLength_0 = 40; initialDLBWPk0_1 = 0; @@ -71,6 +71,11 @@ gNBs = initialDLBWPmappingType_2 = 0; #this is SS=1,L=12 initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -105,8 +110,8 @@ gNBs = #1,2,4,8,10,20,40,80 ra_ResponseWindow = 4; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; #ra_ContentionResolutionTimer @@ -114,8 +119,8 @@ gNBs = ra_ContentionResolutionTimer = 7; rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR -#0 = 839, 1 = 139 - prach_RootSequenceIndex_PR = 1; +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; prach_RootSequenceIndex = 1; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf index b82c455ef4..ae17efc9bd 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpn300.conf @@ -59,7 +59,7 @@ gNBs = #initialULBWPmappingType #0=typeA,1=typeB initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 + #this is SS=1,L=13 initialDLBWPstartSymbolAndLength_0 = 40; initialDLBWPk0_1 = 0; @@ -71,6 +71,11 @@ gNBs = initialDLBWPmappingType_2 = 0; #this is SS=1,L=12 initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -105,8 +110,8 @@ gNBs = #1,2,4,8,10,20,40,80 ra_ResponseWindow = 4; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; #ra_ContentionResolutionTimer @@ -114,8 +119,8 @@ gNBs = ra_ContentionResolutionTimer = 7; rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR -#0 = 839, 1 = 139 - prach_RootSequenceIndex_PR = 1; +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; prach_RootSequenceIndex = 1; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf index 4cbec5b86e..c907dcfe8d 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.217PRB.usrpx300.conf @@ -59,7 +59,7 @@ gNBs = #initialULBWPmappingType #0=typeA,1=typeB initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 + #this is SS=1,L=13 initialDLBWPstartSymbolAndLength_0 = 40; initialDLBWPk0_1 = 0; @@ -71,6 +71,11 @@ gNBs = initialDLBWPmappingType_2 = 0; #this is SS=1,L=12 initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -105,8 +110,8 @@ gNBs = #1,2,4,8,10,20,40,80 ra_ResponseWindow = 4; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; #ra_ContentionResolutionTimer @@ -114,8 +119,8 @@ gNBs = ra_ContentionResolutionTimer = 7; rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR -#0 = 839, 1 = 139 - prach_RootSequenceIndex_PR = 1; +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; prach_RootSequenceIndex = 1; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex # diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf index f5e2298a99..7c3a6e4ac0 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.273PRB.usrpn300.conf @@ -59,7 +59,7 @@ gNBs = #initialULBWPmappingType #0=typeA,1=typeB initialDLBWPmappingType_0 = 0; - #this is SS=2,L=3 + #this is SS=1,L=13 initialDLBWPstartSymbolAndLength_0 = 40; initialDLBWPk0_1 = 0; @@ -71,6 +71,11 @@ gNBs = initialDLBWPmappingType_2 = 0; #this is SS=1,L=12 initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=5 + initialDLBWPstartSymbolAndLength_3 = 57; #uplinkConfigCommon #frequencyInfoUL ul_frequencyBand = 78; @@ -105,8 +110,8 @@ gNBs = #1,2,4,8,10,20,40,80 ra_ResponseWindow = 4; #ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR -#0=oneeighth,1=onefourth,2=half,3=one,4=two,5=four,6=eight,7=sixteen - ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 3; +#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen + ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4; #oneHalf (0..15) 4,8,12,16,...60,64 ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 15; #ra_ContentionResolutionTimer @@ -114,8 +119,8 @@ gNBs = ra_ContentionResolutionTimer = 7; rsrp_ThresholdSSB = 19; #prach-RootSequenceIndex_PR -#0 = 839, 1 = 139 - prach_RootSequenceIndex_PR = 1; +#1 = 839, 2 = 139 + prach_RootSequenceIndex_PR = 2; prach_RootSequenceIndex = 1; # SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex #