From 44dc8f8daa7265ab6e3667e3c5bc1254faa6ccd5 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo <bartosz.podrygajlo@openairinterface.org> Date: Mon, 20 May 2024 13:39:20 +0200 Subject: [PATCH] Add google test testcases for nr_get_Pcmax. --- CMakeLists.txt | 7 +- openair2/LAYER2/CMakeLists.txt | 1 + openair2/LAYER2/NR_MAC_UE/CMakeLists.txt | 5 + openair2/LAYER2/NR_MAC_UE/mac_proto.h | 11 ++- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 11 ++- .../LAYER2/NR_MAC_UE/nr_ue_power_procedures.c | 98 +++++++++++++------ openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 23 ----- .../LAYER2/NR_MAC_UE/tests/CMakeLists.txt | 6 ++ .../tests/test_nr_ue_power_procedures.cpp | 64 ++++++++++++ 9 files changed, 167 insertions(+), 59 deletions(-) create mode 100644 openair2/LAYER2/NR_MAC_UE/CMakeLists.txt create mode 100644 openair2/LAYER2/NR_MAC_UE/tests/CMakeLists.txt create mode 100644 openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 20b86b95dc9..de7e300a67b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -463,7 +463,7 @@ add_library(f1ap ${F1AP_DIR}/f1ap_handlers.c ${F1AP_DIR}/f1ap_itti_messaging.c) target_include_directories(f1ap PUBLIC F1AP_DIR) -target_link_libraries(f1ap PUBLIC asn1_f1ap) +target_link_libraries(f1ap PUBLIC asn1_f1ap L2_NR) target_link_libraries(f1ap PRIVATE ngap nr_rrc HASHTABLE) # LPP @@ -1414,7 +1414,6 @@ set (MAC_NR_SRC_UE ${NR_UE_MAC_DIR}/nr_ue_scheduler.c ${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c ${NR_UE_MAC_DIR}/nr_ra_procedures.c - ${NR_UE_MAC_DIR}/nr_ue_power_procedures.c ) set (ENB_APP_SRC @@ -1463,7 +1462,7 @@ endif() add_library(MAC_UE_NR ${MAC_NR_SRC_UE}) -target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) +target_link_libraries(MAC_UE_NR PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs PUBLIC nr_ue_power_procedures) add_library(L2_LTE ${L2_LTE_SRC}) target_link_libraries(L2_LTE PRIVATE asn1_lte_rrc_hdrs asn1_nr_rrc_hdrs) @@ -1517,7 +1516,7 @@ target_link_libraries(L2_UE PRIVATE asn1_lte_rrc_hdrs) add_library( NR_L2_UE ${NR_L2_SRC_UE} ${MAC_NR_SRC_UE} ) target_link_libraries(NR_L2_UE PRIVATE f1ap nr_rlc) -target_link_libraries(NR_L2_UE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs nr_common) +target_link_libraries(NR_L2_UE PRIVATE asn1_nr_rrc_hdrs asn1_lte_rrc_hdrs nr_common nr_ue_power_procedures) add_library(MAC_NR_COMMON ${OPENAIR2_DIR}/LAYER2/NR_MAC_COMMON/nr_mac_common.c diff --git a/openair2/LAYER2/CMakeLists.txt b/openair2/LAYER2/CMakeLists.txt index b8bc21e78cb..9360ed7b2ba 100644 --- a/openair2/LAYER2/CMakeLists.txt +++ b/openair2/LAYER2/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(nr_rlc) +add_subdirectory(NR_MAC_UE) diff --git a/openair2/LAYER2/NR_MAC_UE/CMakeLists.txt b/openair2/LAYER2/NR_MAC_UE/CMakeLists.txt new file mode 100644 index 00000000000..6589a2fda51 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/CMakeLists.txt @@ -0,0 +1,5 @@ +add_library(nr_ue_power_procedures nr_ue_power_procedures.c) +target_link_libraries(nr_ue_power_procedures PUBLIC asn1_nr_rrc ${T_LIB} MAC_NR_COMMON nr_common) +if (ENABLE_TESTS) + add_subdirectory(tests) +endif() diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index a6a60fbd7f9..01f49f8319f 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -227,7 +227,16 @@ int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, PUCCH_sched_t *pucch, fapi_nr_ul_config_pucch_pdu *pucch_pdu); -int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, int N_RB_UL, bool is_transform_precoding, int n_prbs, int start_prb); +int nr_get_Pcmax(int p_Max, + uint16_t nr_band, + frequency_range_t frequency_range, + int Qm, + bool powerBoostPi2BPSK, + int scs, + int N_RB_UL, + bool is_transform_precoding, + int n_prbs, + int start_prb); int get_sum_delta_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame); diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 5831bd2b113..1fc6f4b6e8a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -79,7 +79,16 @@ void init_RA(NR_UE_MAC_INST_t *mac, int n_prbs = get_N_RA_RB(prach_scs, mac->current_UL_BWP->scs); int start_prb = rach_ConfigGeneric->msg1_FrequencyStart + mac->current_UL_BWP->BWPStart; // PRACH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1) - prach_resources->RA_PCMAX = nr_get_Pcmax(mac, 2, false, prach_scs, cfg->carrier_config.dl_grid_size[prach_scs], true, n_prbs, start_prb); + prach_resources->RA_PCMAX = nr_get_Pcmax(mac->p_Max, + mac->nr_band, + mac->frequency_range, + 2, + false, + prach_scs, + cfg->carrier_config.dl_grid_size[prach_scs], + true, + n_prbs, + start_prb); prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; prach_resources->POWER_OFFSET_2STEP_RA = 0; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c index 3e9669775d1..e826d95e4c3 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -85,16 +85,24 @@ static int get_deltatf(uint16_t nb_of_prbs, // -- Powerclass 3 capable UE (which is default power class unless otherwise stated) // -- Maximum power reduction (MPR_c) for power class 3 // -- no additional MPR (A_MPR_c) -int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, int N_RB_UL, bool is_transform_precoding, int n_prbs, int start_prb) +int nr_get_Pcmax(int p_Max, + uint16_t nr_band, + frequency_range_t frequency_range, + int Qm, + bool powerBoostPi2BPSK, + int scs, + int N_RB_UL, + bool is_transform_precoding, + int n_prbs, + int start_prb) { - int nr_band = mac->nr_band; - if(mac->frequency_range == FR1) { - - //TODO configure P-MAX from the upper layers according to 38.331 + if (frequency_range == FR1) { + // TODO configure P-MAX from the upper layers according to 38.331 int p_powerclass = 23; // dBm assuming poweclass 3 UE - int p_emax = mac->p_Max != INT_MIN ? mac->p_Max : p_powerclass; + int p_emax = p_Max != INT_MIN ? p_Max : p_powerclass; int delta_P_powerclass = 0; // for powerclass 2 needs to be changed - if(mac->p_Max && Qm == 1 && powerBoostPi2BPSK && (nr_band == 40 || nr_band == 41 || nr_band == 77 || nr_band == 78 || nr_band == 79)) { + if (p_Max && Qm == 1 && powerBoostPi2BPSK + && (nr_band == 40 || nr_band == 41 || nr_band == 77 || nr_band == 78 || nr_band == 79)) { p_emax += 3; delta_P_powerclass -= 3; } @@ -103,54 +111,52 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, int delta_T_IB = 0; // TODO in case of band 41 and PRB allocation within 4MHz of the upper or lower limit of the band -> delta_TC = 1.5 - if(nr_band == 41) + if (nr_band == 41) LOG_E(NR_MAC, "Need to implement delta_TC for band 41\n"); int delta_TC = 0; float MPR = 0; frame_type_t frame_type = get_frame_type(nr_band, scs); - if(compare_relative_ul_channel_bw(nr_band, scs, N_RB_UL, frame_type)) { + if (compare_relative_ul_channel_bw(nr_band, scs, N_RB_UL, frame_type)) { int rb_low = (n_prbs / 2) > 1 ? (n_prbs / 2) : 1; int rb_high = N_RB_UL - rb_low - n_prbs; bool is_inner_rb = start_prb >= rb_low && start_prb <= rb_high && n_prbs <= ((N_RB_UL / 2) + (N_RB_UL & 1)); // Table 6.2.2-1 in 38.101 switch (Qm) { - case 1 : + case 1: AssertFatal(false, "MPR for Pi/2 BPSK not implemented yet\n"); break; - case 2 : + case 2: if (is_transform_precoding) { - if(!is_inner_rb) + if (!is_inner_rb) MPR = 1; - } - else { - if(is_inner_rb) + } else { + if (is_inner_rb) MPR = 1.5; else MPR = 3; } break; - case 4 : + case 4: if (is_transform_precoding) { - if(is_inner_rb) + if (is_inner_rb) MPR = 1; else MPR = 2; - } - else { - if(is_inner_rb) + } else { + if (is_inner_rb) MPR = 2; else MPR = 3; } break; - case 6 : + case 6: if (is_transform_precoding) MPR = 2.5; else MPR = 3.5; break; - case 8 : + case 8: if (is_transform_precoding) MPR = 4.5; else @@ -170,12 +176,12 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, if (P_MPR > total_reduction) total_reduction = P_MPR; int pcmax_high, pcmax_low; - if(mac->p_Max) { + if (p_Max) { pcmax_high = p_emax < (p_powerclass - delta_P_powerclass) ? p_emax : (p_powerclass - delta_P_powerclass); - pcmax_low = (p_emax - delta_TC) < (p_powerclass - delta_P_powerclass - total_reduction) ? - (p_emax - delta_TC) : (p_powerclass - delta_P_powerclass - total_reduction); - } - else { + pcmax_low = (p_emax - delta_TC) < (p_powerclass - delta_P_powerclass - total_reduction) + ? (p_emax - delta_TC) + : (p_powerclass - delta_P_powerclass - total_reduction); + } else { pcmax_high = p_powerclass - delta_P_powerclass; pcmax_low = p_powerclass - delta_P_powerclass - total_reduction; } @@ -183,8 +189,7 @@ int nr_get_Pcmax(NR_UE_MAC_INST_t *mac, int Qm, bool powerBoostPi2BPSK, int scs, int pcmax = (pcmax_low + pcmax_high) / 2; LOG_D(MAC, "Configured maximum output power: %d dBm <= PCMAX %d dBm <= %d dBm \n", pcmax_low, pcmax, pcmax_high); return pcmax; - } - else { + } else { // FR2 TODO it is even more complex because it is radiated power return 23; } @@ -294,7 +299,16 @@ int16_t get_pucch_tx_power_ue(NR_UE_MAC_INST_t *mac, // PUCCH shall be as specified for QPSK modulated DFT-s-OFDM of equivalent RB allocation (38.101-1) // TODO: P_CMAX for format 2 - int P_CMAX = nr_get_Pcmax(mac, 2, false, mac->current_UL_BWP->scs, mac->current_UL_BWP->BWPSize, true, 1, start_prb); + int P_CMAX = nr_get_Pcmax(mac->p_Max, + mac->nr_band, + mac->frequency_range, + 2, + false, + mac->current_UL_BWP->scs, + mac->current_UL_BWP->BWPSize, + true, + 1, + start_prb); int P_CMIN = -40; // TODO: minimum TX power, possibly 38.101-1 6.3.1 int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); @@ -358,3 +372,27 @@ static int get_deltatf(uint16_t nb_of_prbs, } return DELTA_TF; } + +// Returns the pathloss in dB for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission +// computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16 +// Assumptions: +// - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE +// Measurement units: +// - referenceSignalPower: dBm/RE (average EPRE of the resources elements that carry secondary synchronization signals in dBm) +int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm) +{ + fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; + int referenceSignalPower = cfg->ssb_config.ss_pbch_power; + //TODO improve PL measurements. Probably not correct as it is. + + int16_t pathloss = (int16_t)(referenceSignalPower - ssb_rsrp_dBm); + + LOG_D(NR_MAC, "pathloss %d dB, referenceSignalPower %d dBm/RE (%f mW), RSRP %d dBm (%f mW)\n", + pathloss, + referenceSignalPower, + pow(10, referenceSignalPower/10), + ssb_rsrp_dBm, + pow(10, ssb_rsrp_dBm/10)); + + return pathloss; +} diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 2a7801afb88..47464d8fb31 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -3945,26 +3945,3 @@ static void nr_ue_process_rar(NR_UE_MAC_INST_t *mac, nr_downlink_indication_t *d return; } -// Returns the pathloss in dB for the active UL BWP on the selected carrier based on the DL RS associated with the PRACH transmission -// computation according to clause 7.4 (Physical random access channel) of 3GPP TS 38.213 version 16.3.0 Release 16 -// Assumptions: -// - PRACH transmission from a UE is not in response to a detection of a PDCCH order by the UE -// Measurement units: -// - referenceSignalPower: dBm/RE (average EPRE of the resources elements that carry secondary synchronization signals in dBm) -int16_t compute_nr_SSB_PL(NR_UE_MAC_INST_t *mac, short ssb_rsrp_dBm) -{ - fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; - int referenceSignalPower = cfg->ssb_config.ss_pbch_power; - //TODO improve PL measurements. Probably not correct as it is. - - int16_t pathloss = (int16_t)(referenceSignalPower - ssb_rsrp_dBm); - - LOG_D(NR_MAC, "pathloss %d dB, referenceSignalPower %d dBm/RE (%f mW), RSRP %d dBm (%f mW)\n", - pathloss, - referenceSignalPower, - pow(10, referenceSignalPower/10), - ssb_rsrp_dBm, - pow(10, ssb_rsrp_dBm/10)); - - return pathloss; -} diff --git a/openair2/LAYER2/NR_MAC_UE/tests/CMakeLists.txt b/openair2/LAYER2/NR_MAC_UE/tests/CMakeLists.txt new file mode 100644 index 00000000000..40c8c5372bf --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/tests/CMakeLists.txt @@ -0,0 +1,6 @@ +add_executable(test_nr_ue_power_procedures + test_nr_ue_power_procedures.cpp) +target_link_libraries(test_nr_ue_power_procedures PRIVATE nr_ue_power_procedures GTest::gtest minimal_lib) +add_dependencies(tests test_nr_ue_power_procedures) +add_test(NAME test_nr_ue_power_procedures + COMMAND ./test_nr_ue_power_procedures) diff --git a/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp new file mode 100644 index 00000000000..179d94bd1b1 --- /dev/null +++ b/openair2/LAYER2/NR_MAC_UE/tests/test_nr_ue_power_procedures.cpp @@ -0,0 +1,64 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + + +#include "gtest/gtest.h" +extern "C" { +#include "openair2/LAYER2/NR_MAC_UE/mac_proto.h" +#include "executables/softmodem-common.h" +uint64_t get_softmodem_optmask(void) {return 0;} +static softmodem_params_t softmodem_params; +softmodem_params_t *get_softmodem_params(void) { + return &softmodem_params; + +} +} +#include <cstdio> +#include "common/utils/LOG/log.h" + +TEST(power_procedures_fr1, test_prach_max_tx_power_mpr) +{ + // Inner PRB, MPR = 1.5 + int prb_start = 4; + int N_RB_UL = 51; // 10Mhz + EXPECT_EQ(22, nr_get_Pcmax(23, 20, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start)); + + // Outer PRB, MPR = 3 + prb_start = 0; + EXPECT_EQ(21, nr_get_Pcmax(23, 20, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start)); + + // Channel bandwidth conditon not met, no MPR + N_RB_UL = 106; + EXPECT_EQ(23, nr_get_Pcmax(23, 20, FR1, 2, false, 1, N_RB_UL, false, 6, prb_start)); +} + +TEST(power_procedures_fr1, test_not_implemented) +{ + int N_RB_UL = 51; + EXPECT_DEATH(nr_get_Pcmax(23, 20, FR1, 1, false, 1, N_RB_UL, false, 6, 0), "MPR for Pi/2 BPSK not implemented yet"); +} + +int main(int argc, char** argv) +{ + logInit(); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} -- GitLab