/** * * \section COPYRIGHT * * Copyright 2013-2020 Software Radio Systems Limited * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the distribution. * */ #include "srsenb/hdr/stack/mac/sched_ue_ctrl/tpc.h" #include "srslte/common/test_common.h" namespace srsenb { int test_finite_target_snr() { const uint32_t nof_prbs = 50; const int target_snr = 15; tpc tpcfsm(nof_prbs, 15); // TEST: While no SNR info is provided, no TPC commands are sent for (uint32_t i = 0; i < 100; ++i) { tpcfsm.new_tti(); TESTASSERT(tpcfsm.encode_pucch_tpc() == 0); TESTASSERT(tpcfsm.encode_pusch_tpc() == 0); } // TEST: current SNR above target SNR. Checks: // - TPC commands should be sent to decrease power // - The sum power of TPC commands should not exceed the difference between current and target SNRs int snr_diff = 10; tpcfsm.set_snr(target_snr + snr_diff); int sum_pusch = 0, sum_pucch = 0; for (uint32_t i = 0; i < 100; ++i) { tpcfsm.new_tti(); sum_pusch += tpcfsm.encode_pusch_tpc(); TESTASSERT(sum_pusch < 0 and sum_pusch >= -snr_diff); sum_pucch += tpcfsm.encode_pucch_tpc(); TESTASSERT(sum_pucch < 0 and sum_pucch >= -snr_diff); } // TEST: current SNR below target SNR. Checks: // - TPC commands should be sent to increase power // - The sum of TPC commands should not exceed the difference between current and target SNRs snr_diff = -10; tpcfsm.set_snr(target_snr + snr_diff); sum_pusch = 0; sum_pucch = 0; for (uint32_t i = 0; i < 100; ++i) { tpcfsm.new_tti(); sum_pusch += tpcfsm.encode_pusch_tpc(); TESTASSERT(sum_pusch > 0 and sum_pusch <= -snr_diff); sum_pucch += tpcfsm.encode_pucch_tpc(); TESTASSERT(sum_pucch > 0 and sum_pucch <= -snr_diff); } return SRSLTE_SUCCESS; } int test_undefined_target_snr() { const uint32_t nof_prbs = 50; tpc tpcfsm(nof_prbs); TESTASSERT(tpcfsm.max_ul_prbs() == 50); // TEST: While the PHR is not updated, a limited number of TPC commands should be sent int sum_pusch = 0, sum_pucch = 0; for (uint32_t i = 0; i < 100; ++i) { tpcfsm.new_tti(); sum_pusch += tpcfsm.encode_pusch_tpc(); sum_pucch += tpcfsm.encode_pucch_tpc(); } TESTASSERT(sum_pusch <= 3 and sum_pusch >= -1); TESTASSERT(sum_pucch <= 3 and sum_pucch >= -1); // TEST: SNR info should not affect TPC in undefined target SNR mode int snr_info = 10; tpcfsm.set_snr(snr_info); sum_pusch = 0; sum_pucch = 0; for (uint32_t i = 0; i < 100; ++i) { tpcfsm.new_tti(); sum_pusch += tpcfsm.encode_pusch_tpc(); sum_pucch += tpcfsm.encode_pucch_tpc(); } TESTASSERT(sum_pusch == 0); TESTASSERT(sum_pucch == 0); // TEST: If the PHR allows full utilization of available PRBs, the TPC slightly increments UL Tx power int phr = 30; tpcfsm.set_phr(phr); TESTASSERT(tpcfsm.max_ul_prbs() == 50); sum_pusch = 0; sum_pucch = 0; for (uint32_t i = 0; i < 100; ++i) { tpcfsm.new_tti(); sum_pusch += tpcfsm.encode_pusch_tpc(); sum_pucch += tpcfsm.encode_pucch_tpc(); } TESTASSERT(sum_pusch > 0 and sum_pusch <= 3); TESTASSERT(sum_pucch > 0 and sum_pucch <= 3); // TEST: PHR is too low to allow all PRBs to be allocated. This event should not affect TPC commands phr = 5; tpcfsm.set_phr(phr); TESTASSERT(tpcfsm.max_ul_prbs() < 50); for (uint32_t i = 0; i < 100; ++i) { tpcfsm.new_tti(); TESTASSERT(tpcfsm.encode_pusch_tpc() == 0); TESTASSERT(tpcfsm.encode_pucch_tpc() == 0); } // TEST: PHR is negative. The TPC should slightly decrease Tx UL power until next PHR phr = -1; tpcfsm.set_phr(phr); TESTASSERT(tpcfsm.max_ul_prbs() == tpc::PHR_NEG_NOF_PRB); sum_pusch = 0; sum_pucch = 0; for (uint32_t i = 0; i < 100; ++i) { tpcfsm.new_tti(); sum_pusch += tpcfsm.encode_pusch_tpc(); sum_pucch += tpcfsm.encode_pucch_tpc(); } TESTASSERT(sum_pusch <= 0 and sum_pusch >= -1); TESTASSERT(sum_pucch <= 0 and sum_pucch >= -1); return SRSLTE_SUCCESS; } } // namespace srsenb int main() { TESTASSERT(srsenb::test_finite_target_snr() == 0); TESTASSERT(srsenb::test_undefined_target_snr() == 0); printf("Success\n"); }