Commit 44dc8f8d authored by Bartosz Podrygajlo's avatar Bartosz Podrygajlo

Add google test testcases for nr_get_Pcmax.

parent 4a36f7dd
......@@ -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
......
add_subdirectory(nr_rlc)
add_subdirectory(NR_MAC_UE)
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()
......@@ -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);
......
......@@ -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;
......
......@@ -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;
}
......@@ -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;
}
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)
/*
* 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();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment