From bfc47445eec1878f7ceb76da737a8f776b355839 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 27 Aug 2024 19:00:15 +0200 Subject: [PATCH 1/3] SRS tx power with power control state --- common/utils/nr/nr_common.c | 81 ++++++++++++ common/utils/nr/nr_common.h | 2 + .../nfapi/public_inc/fapi_nr_ue_interface.h | 1 + .../NR_ESTIMATION/nr_ul_channel_estimation.c | 2 +- openair1/PHY/NR_TRANSPORT/srs_rx.c | 2 +- .../PHY/NR_UE_TRANSPORT/srs_modulation_nr.c | 14 +- .../PHY/NR_UE_TRANSPORT/srs_modulation_nr.h | 77 ----------- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 3 + openair2/LAYER2/NR_MAC_UE/mac_proto.h | 6 + .../LAYER2/NR_MAC_UE/nr_ue_power_procedures.c | 82 ++++++++++++ openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c | 18 ++- .../tests/test_nr_ue_power_procedures.cpp | 120 ++++++++++++++++++ 12 files changed, 317 insertions(+), 91 deletions(-) diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c index fafc1bcd47..09dd5e7d94 100644 --- a/common/utils/nr/nr_common.c +++ b/common/utils/nr/nr_common.c @@ -36,6 +36,79 @@ #include "nr_common.h" #include +#define C_SRS_NUMBER (64) +#define B_SRS_NUMBER (4) + +/* TS 38.211 Table 6.4.1.4.3-1: SRS bandwidth configuration */ +static const unsigned short srs_bandwidth_config[C_SRS_NUMBER][B_SRS_NUMBER][2] = { + /* B_SRS = 0 B_SRS = 1 B_SRS = 2 B_SRS = 3 */ + /* C SRS m_srs0 N_0 m_srs1 N_1 m_srs2 N_2 m_srs3 N_3 */ + /* 0 */ {{4, 1}, {4, 1}, {4, 1}, {4, 1}}, + /* 1 */ {{8, 1}, {4, 2}, {4, 1}, {4, 1}}, + /* 2 */ {{12, 1}, {4, 3}, {4, 1}, {4, 1}}, + /* 3 */ {{16, 1}, {4, 4}, {4, 1}, {4, 1}}, + /* 4 */ {{16, 1}, {8, 2}, {4, 2}, {4, 1}}, + /* 5 */ {{20, 1}, {4, 5}, {4, 1}, {4, 1}}, + /* 6 */ {{24, 1}, {4, 6}, {4, 1}, {4, 1}}, + /* 7 */ {{24, 1}, {12, 2}, {4, 3}, {4, 1}}, + /* 8 */ {{28, 1}, {4, 7}, {4, 1}, {4, 1}}, + /* 9 */ {{32, 1}, {16, 2}, {8, 2}, {4, 2}}, + /* 10 */ {{36, 1}, {12, 3}, {4, 3}, {4, 1}}, + /* 11 */ {{40, 1}, {20, 2}, {4, 5}, {4, 1}}, + /* 12 */ {{48, 1}, {16, 3}, {8, 2}, {4, 2}}, + /* 13 */ {{48, 1}, {24, 2}, {12, 2}, {4, 3}}, + /* 14 */ {{52, 1}, {4, 13}, {4, 1}, {4, 1}}, + /* 15 */ {{56, 1}, {28, 2}, {4, 7}, {4, 1}}, + /* 16 */ {{60, 1}, {20, 3}, {4, 5}, {4, 1}}, + /* 17 */ {{64, 1}, {32, 2}, {16, 2}, {4, 4}}, + /* 18 */ {{72, 1}, {24, 3}, {12, 2}, {4, 3}}, + /* 19 */ {{72, 1}, {36, 2}, {12, 3}, {4, 3}}, + /* 20 */ {{76, 1}, {4, 19}, {4, 1}, {4, 1}}, + /* 21 */ {{80, 1}, {40, 2}, {20, 2}, {4, 5}}, + /* 22 */ {{88, 1}, {44, 2}, {4, 11}, {4, 1}}, + /* 23 */ {{96, 1}, {32, 3}, {16, 2}, {4, 4}}, + /* 24 */ {{96, 1}, {48, 2}, {24, 2}, {4, 6}}, + /* 25 */ {{104, 1}, {52, 2}, {4, 13}, {4, 1}}, + /* 26 */ {{112, 1}, {56, 2}, {28, 2}, {4, 7}}, + /* 27 */ {{120, 1}, {60, 2}, {20, 3}, {4, 5}}, + /* 28 */ {{120, 1}, {40, 3}, {8, 5}, {4, 2}}, + /* 29 */ {{120, 1}, {24, 5}, {12, 2}, {4, 3}}, + /* 30 */ {{128, 1}, {64, 2}, {32, 2}, {4, 8}}, + /* 31 */ {{128, 1}, {64, 2}, {16, 4}, {4, 4}}, + /* 32 */ {{128, 1}, {16, 8}, {8, 2}, {4, 2}}, + /* 33 */ {{132, 1}, {44, 3}, {4, 11}, {4, 1}}, + /* 34 */ {{136, 1}, {68, 2}, {4, 17}, {4, 1}}, + /* 35 */ {{144, 1}, {72, 2}, {36, 2}, {4, 9}}, + /* 36 */ {{144, 1}, {48, 3}, {24, 2}, {12, 2}}, + /* 37 */ {{144, 1}, {48, 3}, {16, 3}, {4, 4}}, + /* 38 */ {{144, 1}, {16, 9}, {8, 2}, {4, 2}}, + /* 39 */ {{152, 1}, {76, 2}, {4, 19}, {4, 1}}, + /* 40 */ {{160, 1}, {80, 2}, {40, 2}, {4, 10}}, + /* 41 */ {{160, 1}, {80, 2}, {20, 4}, {4, 5}}, + /* 42 */ {{160, 1}, {32, 5}, {16, 2}, {4, 4}}, + /* 43 */ {{168, 1}, {84, 2}, {28, 3}, {4, 7}}, + /* 44 */ {{176, 1}, {88, 2}, {44, 2}, {4, 11}}, + /* 45 */ {{184, 1}, {92, 2}, {4, 23}, {4, 1}}, + /* 46 */ {{192, 1}, {96, 2}, {48, 2}, {4, 12}}, + /* 47 */ {{192, 1}, {96, 2}, {24, 4}, {4, 6}}, + /* 48 */ {{192, 1}, {64, 3}, {16, 4}, {4, 4}}, + /* 49 */ {{192, 1}, {24, 8}, {8, 3}, {4, 2}}, + /* 50 */ {{208, 1}, {104, 2}, {52, 2}, {4, 13}}, + /* 51 */ {{216, 1}, {108, 2}, {36, 3}, {4, 9}}, + /* 52 */ {{224, 1}, {112, 2}, {56, 2}, {4, 14}}, + /* 53 */ {{240, 1}, {120, 2}, {60, 2}, {4, 15}}, + /* 54 */ {{240, 1}, {80, 3}, {20, 4}, {4, 5}}, + /* 55 */ {{240, 1}, {48, 5}, {16, 3}, {8, 2}}, + /* 56 */ {{240, 1}, {24, 10}, {12, 2}, {4, 3}}, + /* 57 */ {{256, 1}, {128, 2}, {64, 2}, {4, 16}}, + /* 58 */ {{256, 1}, {128, 2}, {32, 4}, {4, 8}}, + /* 59 */ {{256, 1}, {16, 16}, {8, 2}, {4, 2}}, + /* 60 */ {{264, 1}, {132, 2}, {44, 3}, {4, 11}}, + /* 61 */ {{272, 1}, {136, 2}, {68, 2}, {4, 17}}, + /* 62 */ {{272, 1}, {68, 4}, {4, 17}, {4, 1}}, + /* 63 */ {{272, 1}, {16, 17}, {8, 2}, {4, 2}}, +}; + const char *duplex_mode[]={"FDD","TDD"}; static const uint8_t bit_reverse_table_256[] = { @@ -1212,3 +1285,11 @@ void nr_timer_setup(NR_timer_t *timer, const uint32_t target, const uint32_t ste timer->step = step; nr_timer_stop(timer); } + +unsigned short get_m_srs(int c_srs, int b_srs) { + return srs_bandwidth_config[c_srs][b_srs][0]; +} + +unsigned short get_N_b_srs(int c_srs, int b_srs) { + return srs_bandwidth_config[c_srs][b_srs][1]; +} diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 1e4fecc4f5..9087f335c5 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -250,6 +250,8 @@ int get_scan_ssb_first_sc(const double fc, void check_ssb_raster(uint64_t freq, int band, int scs); int get_smallest_supported_bandwidth_index(int scs, frequency_range_t frequency_range, int n_rbs); +unsigned short get_m_srs(int c_srs, int b_srs); +unsigned short get_N_b_srs(int c_srs, int b_srs); #define CEILIDIV(a,b) ((a+b-1)/b) #define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1)) 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 f0d9b73e63..d0d9fc9093 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 @@ -391,6 +391,7 @@ typedef struct { uint16_t t_srs; // SRS-Periodicity in slots [3GPP TS 38.211, Sec 6.4.1.4.4], Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560 uint16_t t_offset; // Slot offset value [3GPP TS 38.211, Sec 6.4.1.4.3], Value:0->2559 nfapi_nr_ue_ul_beamforming_t beamforming; + int16_t tx_power; } fapi_nr_ul_config_srs_pdu; typedef struct { diff --git a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c index fea6b930ac..7a46cd1b20 100644 --- a/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c +++ b/openair1/PHY/NR_ESTIMATION/nr_ul_channel_estimation.c @@ -631,7 +631,7 @@ int nr_srs_channel_estimation( const uint8_t N_ap = 1<num_ant_ports; const uint8_t K_TC = 2<comb_size; - const uint16_t m_SRS_b = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0]; + const uint16_t m_SRS_b = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index); const uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC; uint8_t fd_cdm = N_ap; if (N_ap == 4 && ((K_TC == 2 && srs_pdu->cyclic_shift >= 4) || (K_TC == 4 && srs_pdu->cyclic_shift >= 6))) { diff --git a/openair1/PHY/NR_TRANSPORT/srs_rx.c b/openair1/PHY/NR_TRANSPORT/srs_rx.c index a7d975dbb7..037528b407 100644 --- a/openair1/PHY/NR_TRANSPORT/srs_rx.c +++ b/openair1/PHY/NR_TRANSPORT/srs_rx.c @@ -80,7 +80,7 @@ int nr_get_srs_signal(PHY_VARS_gNB *gNB, const uint8_t N_ap = 1<num_ant_ports; const uint8_t N_symb_SRS = 1 << srs_pdu->num_symbols; const uint8_t K_TC = 2 << srs_pdu->comb_size; - const uint16_t M_sc_b_SRS = srs_bandwidth_config[srs_pdu->config_index][srs_pdu->bandwidth_index][0] * NR_NB_SC_PER_RB/K_TC; + const uint16_t M_sc_b_SRS = get_m_srs(srs_pdu->config_index, srs_pdu->bandwidth_index) * NR_NB_SC_PER_RB / K_TC; int32_t *rx_signal; bool no_srs_signal = true; diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c index 02ad38cc0e..f362e3f218 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c @@ -110,17 +110,17 @@ uint16_t compute_F_b(frame_t frame_number, uint16_t product_N_b = 1; for (unsigned int b_prime = b_hop; b_prime < B_SRS; b_prime++) { if (b_prime != b_hop) { - product_N_b *= srs_bandwidth_config[C_SRS][b_prime][1]; + product_N_b *= get_N_b_srs(C_SRS, b_prime); } } uint16_t F_b = 0; - uint8_t N_b = srs_bandwidth_config[C_SRS][b][1]; + uint8_t N_b = get_N_b_srs(C_SRS, b); if (N_b & 1) { // Nb odd F_b = (N_b/2)*(n_SRS/product_N_b); } else { // Nb even uint16_t product_N_b_B_SRS = product_N_b; - product_N_b_B_SRS *= srs_bandwidth_config[C_SRS][B_SRS][1]; /* product for b_hop to b */ + product_N_b_B_SRS *= get_N_b_srs(C_SRS, B_SRS); /* product for b_hop to b */ F_b = (N_b/2)*((n_SRS%product_N_b_B_SRS)/product_N_b) + ((n_SRS%product_N_b_B_SRS)/2*product_N_b); } @@ -142,8 +142,8 @@ uint16_t compute_n_b(frame_t frame_number, uint8_t l_line, uint8_t b) { - uint8_t N_b = srs_bandwidth_config[C_SRS][b][1]; - uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0]; + uint8_t N_b = get_N_b_srs(C_SRS, b); + uint16_t m_SRS_b = get_m_srs(C_SRS, B_SRS); uint16_t n_b = 0; if (b_hop >= B_SRS) { @@ -211,7 +211,7 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, uint8_t N_symb_SRS = 1<num_symbols; // Number of consecutive OFDM symbols uint8_t l0 = frame_parms->symbols_per_slot - 1 - l_offset; // Starting symbol position in the time domain uint8_t n_SRS_cs_max = srs_max_number_cs[srs_config_pdu->comb_size]; - uint16_t m_SRS_b = srs_bandwidth_config[C_SRS][B_SRS][0]; // Number of resource blocks + uint16_t m_SRS_b = get_m_srs(C_SRS, B_SRS); // Number of resource blocks uint16_t M_sc_b_SRS = m_SRS_b * NR_NB_SC_PER_RB/K_TC; // Length of the SRS sequence #ifdef SRS_DEBUG @@ -273,7 +273,7 @@ int generate_srs_nr(nfapi_nr_srs_pdu_t *srs_config_pdu, } uint64_t subcarrier_offset = frame_parms->first_carrier_offset + srs_config_pdu->bwp_start*NR_NB_SC_PER_RB; double sqrt_N_ap = sqrt(N_ap); - uint16_t n_b[B_SRS_NUMBER]; + uint16_t n_b[B_SRS + 1]; // Find index of table which is for this SRS length uint16_t M_sc_b_SRS_index = 0; diff --git a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h index a017d79730..dba339d14b 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h +++ b/openair1/PHY/NR_UE_TRANSPORT/srs_modulation_nr.h @@ -35,83 +35,6 @@ #include "PHY/defs_nr_UE.h" -/************** DEFINE ********************************************/ - -#define C_SRS_NUMBER (64) -#define B_SRS_NUMBER (4) - -/************** VARIABLES *****************************************/ - -/* TS 38.211 Table 6.4.1.4.3-1: SRS bandwidth configuration */ -static const unsigned short srs_bandwidth_config[C_SRS_NUMBER][B_SRS_NUMBER][2] = { - /* B_SRS = 0 B_SRS = 1 B_SRS = 2 B_SRS = 3 */ - /* C SRS m_srs0 N_0 m_srs1 N_1 m_srs2 N_2 m_srs3 N_3 */ - /* 0 */ {{4, 1}, {4, 1}, {4, 1}, {4, 1}}, - /* 1 */ {{8, 1}, {4, 2}, {4, 1}, {4, 1}}, - /* 2 */ {{12, 1}, {4, 3}, {4, 1}, {4, 1}}, - /* 3 */ {{16, 1}, {4, 4}, {4, 1}, {4, 1}}, - /* 4 */ {{16, 1}, {8, 2}, {4, 2}, {4, 1}}, - /* 5 */ {{20, 1}, {4, 5}, {4, 1}, {4, 1}}, - /* 6 */ {{24, 1}, {4, 6}, {4, 1}, {4, 1}}, - /* 7 */ {{24, 1}, {12, 2}, {4, 3}, {4, 1}}, - /* 8 */ {{28, 1}, {4, 7}, {4, 1}, {4, 1}}, - /* 9 */ {{32, 1}, {16, 2}, {8, 2}, {4, 2}}, - /* 10 */ {{36, 1}, {12, 3}, {4, 3}, {4, 1}}, - /* 11 */ {{40, 1}, {20, 2}, {4, 5}, {4, 1}}, - /* 12 */ {{48, 1}, {16, 3}, {8, 2}, {4, 2}}, - /* 13 */ {{48, 1}, {24, 2}, {12, 2}, {4, 3}}, - /* 14 */ {{52, 1}, {4, 13}, {4, 1}, {4, 1}}, - /* 15 */ {{56, 1}, {28, 2}, {4, 7}, {4, 1}}, - /* 16 */ {{60, 1}, {20, 3}, {4, 5}, {4, 1}}, - /* 17 */ {{64, 1}, {32, 2}, {16, 2}, {4, 4}}, - /* 18 */ {{72, 1}, {24, 3}, {12, 2}, {4, 3}}, - /* 19 */ {{72, 1}, {36, 2}, {12, 3}, {4, 3}}, - /* 20 */ {{76, 1}, {4, 19}, {4, 1}, {4, 1}}, - /* 21 */ {{80, 1}, {40, 2}, {20, 2}, {4, 5}}, - /* 22 */ {{88, 1}, {44, 2}, {4, 11}, {4, 1}}, - /* 23 */ {{96, 1}, {32, 3}, {16, 2}, {4, 4}}, - /* 24 */ {{96, 1}, {48, 2}, {24, 2}, {4, 6}}, - /* 25 */ {{104, 1}, {52, 2}, {4, 13}, {4, 1}}, - /* 26 */ {{112, 1}, {56, 2}, {28, 2}, {4, 7}}, - /* 27 */ {{120, 1}, {60, 2}, {20, 3}, {4, 5}}, - /* 28 */ {{120, 1}, {40, 3}, {8, 5}, {4, 2}}, - /* 29 */ {{120, 1}, {24, 5}, {12, 2}, {4, 3}}, - /* 30 */ {{128, 1}, {64, 2}, {32, 2}, {4, 8}}, - /* 31 */ {{128, 1}, {64, 2}, {16, 4}, {4, 4}}, - /* 32 */ {{128, 1}, {16, 8}, {8, 2}, {4, 2}}, - /* 33 */ {{132, 1}, {44, 3}, {4, 11}, {4, 1}}, - /* 34 */ {{136, 1}, {68, 2}, {4, 17}, {4, 1}}, - /* 35 */ {{144, 1}, {72, 2}, {36, 2}, {4, 9}}, - /* 36 */ {{144, 1}, {48, 3}, {24, 2}, {12, 2}}, - /* 37 */ {{144, 1}, {48, 3}, {16, 3}, {4, 4}}, - /* 38 */ {{144, 1}, {16, 9}, {8, 2}, {4, 2}}, - /* 39 */ {{152, 1}, {76, 2}, {4, 19}, {4, 1}}, - /* 40 */ {{160, 1}, {80, 2}, {40, 2}, {4, 10}}, - /* 41 */ {{160, 1}, {80, 2}, {20, 4}, {4, 5}}, - /* 42 */ {{160, 1}, {32, 5}, {16, 2}, {4, 4}}, - /* 43 */ {{168, 1}, {84, 2}, {28, 3}, {4, 7}}, - /* 44 */ {{176, 1}, {88, 2}, {44, 2}, {4, 11}}, - /* 45 */ {{184, 1}, {92, 2}, {4, 23}, {4, 1}}, - /* 46 */ {{192, 1}, {96, 2}, {48, 2}, {4, 12}}, - /* 47 */ {{192, 1}, {96, 2}, {24, 4}, {4, 6}}, - /* 48 */ {{192, 1}, {64, 3}, {16, 4}, {4, 4}}, - /* 49 */ {{192, 1}, {24, 8}, {8, 3}, {4, 2}}, - /* 50 */ {{208, 1}, {104, 2}, {52, 2}, {4, 13}}, - /* 51 */ {{216, 1}, {108, 2}, {36, 3}, {4, 9}}, - /* 52 */ {{224, 1}, {112, 2}, {56, 2}, {4, 14}}, - /* 53 */ {{240, 1}, {120, 2}, {60, 2}, {4, 15}}, - /* 54 */ {{240, 1}, {80, 3}, {20, 4}, {4, 5}}, - /* 55 */ {{240, 1}, {48, 5}, {16, 3}, {8, 2}}, - /* 56 */ {{240, 1}, {24, 10}, {12, 2}, {4, 3}}, - /* 57 */ {{256, 1}, {128, 2}, {64, 2}, {4, 16}}, - /* 58 */ {{256, 1}, {128, 2}, {32, 4}, {4, 8}}, - /* 59 */ {{256, 1}, {16, 16}, {8, 2}, {4, 2}}, - /* 60 */ {{264, 1}, {132, 2}, {44, 3}, {4, 11}}, - /* 61 */ {{272, 1}, {136, 2}, {68, 2}, {4, 17}}, - /* 62 */ {{272, 1}, {68, 4}, {4, 17}, {4, 1}}, - /* 63 */ {{272, 1}, {16, 17}, {8, 2}, {4, 2}}, -}; - #define SRS_PERIODICITY (17) static const uint16_t srs_periodicity[SRS_PERIODICITY] = {1, 2, 4, 5, 8, 10, 16, 20, 32, 40, 64, 80, 160, 320, 640, 1280, 2560}; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index d9c5fa2345..aed42e6c53 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -609,6 +609,9 @@ typedef struct NR_UE_MAC_INST_s { bool pucch_power_control_initialized; int f_b_f_c; bool pusch_power_control_initialized; + int h_b_f_c; + bool srs_power_control_initialized; + int delta_msg2; } NR_UE_MAC_INST_t; /*@}*/ diff --git a/openair2/LAYER2/NR_MAC_UE/mac_proto.h b/openair2/LAYER2/NR_MAC_UE/mac_proto.h index e2d6125145..1f53812dec 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_proto.h @@ -240,6 +240,12 @@ int get_pusch_tx_power_ue( bool is_rar_tx_retx, bool transform_precoding); +int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac, + NR_SRS_Resource_t *srs_resource, + NR_SRS_ResourceSet_t *srs_resource_set, + int delta_srs, + bool is_configured_for_pusch_on_current_bwp); + int nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, int slot, frame_t frame, 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 36fbf3a527..fba8f63bd4 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -578,6 +578,7 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup)); mac->f_b_f_c = DELTA_P_rampup + delta_pusch; mac->pusch_power_control_initialized = true; + mac->delta_msg2 = delta_pusch; } else { if (!((pusch_power_without_f_b_f_c + mac->f_b_f_c >= P_CMAX && delta_pusch > 0) || (pusch_power_without_f_b_f_c + mac->f_b_f_c <= P_CMIN && delta_pusch < 0))) { @@ -595,3 +596,84 @@ int get_pusch_tx_power_ue(NR_UE_MAC_INST_t *mac, f_b_f_c); return min(P_CMAX, P_O_PUSCH + M_pusch_component + alpha * pathloss + DELTA_TF + f_b_f_c); } + +int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac, + NR_SRS_Resource_t *srs_resource, + NR_SRS_ResourceSet_t *srs_resource_set, + int delta_srs, + bool is_configured_for_pusch_on_current_bwp) +{ + NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; + AssertFatal(current_UL_BWP, "Missing configuration: need UL_BWP to calculate SRS tx power\n"); + AssertFatal(srs_resource_set->p0, "P0 mantatory present at configuration\n"); + int P_0_SRS = *srs_resource_set->p0; + + // alpha is optional, use same default as PUSCH + const float alpha_factor_table[8] = {0.0f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f}; + float alpha = srs_resource_set->alpha ? alpha_factor_table[*srs_resource_set->alpha] : 1.0f; + int m_srs_component = + 10 * log10(pow(2, current_UL_BWP->scs) * get_m_srs(srs_resource->freqHopping.c_SRS, srs_resource->freqHopping.b_SRS)); + + // The allowed MPR for SRS, PUCCH formats 0, 1, 3 and 4, and PRACH shall be as specified for QPSK modulated DFTs-OFDM of + // equivalent RB allocation. The allowed MPR for PUCCH format 2 shall be as specified for QPSK modulated CP-OFDM of equivalent RB + // allocation. + int P_CMAX = nr_get_Pcmax(mac->p_Max, + mac->nr_band, + mac->frame_type, + mac->frequency_range, + mac->current_UL_BWP->channel_bandwidth, + 2, + false, + mac->current_UL_BWP->scs, + mac->current_UL_BWP->BWPSize, + true, + get_m_srs(srs_resource->freqHopping.c_SRS, srs_resource->freqHopping.b_SRS), + 0); // TODO: Determine SRS start RB + + int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); + + int srs_power_without_h_b_f_c = P_0_SRS + alpha * pathloss + m_srs_component; + + // Power adjustment state + int h_b_f_c = 0; + bool use_pusch_power_adjustment_state = srs_resource_set->srs_PowerControlAdjustmentStates == NULL; + if (is_configured_for_pusch_on_current_bwp && use_pusch_power_adjustment_state) { + // Case 1: Use PUSCH power control adjustment state + h_b_f_c = mac->f_b_f_c; + } else { + // Case 2: Separate power control adjustment state + AssertFatal(srs_resource_set->srs_PowerControlAdjustmentStates == NULL + || *srs_resource_set->srs_PowerControlAdjustmentStates + != NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_sameAsFci2, + "Two PUSCH power adjustment states not supported"); + + bool is_tpc_accumulation_provided = current_UL_BWP->srs_Config != NULL && current_UL_BWP->srs_Config->tpc_Accumulation != NULL; + bool separate_pc_adjustment_state = srs_resource_set->srs_PowerControlAdjustmentStates + && *srs_resource_set->srs_PowerControlAdjustmentStates + == NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_separateClosedLoop; + + if (!is_tpc_accumulation_provided && (!is_configured_for_pusch_on_current_bwp || separate_pc_adjustment_state)) { + if (!mac->srs_power_control_initialized) { + NR_PRACH_RESOURCES_t *prach_resources = &mac->ra.prach_resources; + float DELTA_P_rampup_requested = + (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; + float DELTA_P_rampup = P_CMAX - (P_0_SRS + m_srs_component + alpha * pathloss); + DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup)); + mac->srs_power_control_initialized = true; + mac->h_b_f_c = DELTA_P_rampup + mac->delta_msg2; + } else { + int P_CMIN = mac->current_UL_BWP->P_CMIN; + if (!((srs_power_without_h_b_f_c + mac->h_b_f_c >= P_CMAX && delta_srs > 0) + || (srs_power_without_h_b_f_c + mac->h_b_f_c <= P_CMIN && delta_srs < 0))) { + mac->h_b_f_c += delta_srs; + } + } + h_b_f_c = mac->h_b_f_c; + } else { + // Case 3: No accumulation + h_b_f_c = delta_srs; + } + } + + return min(P_CMAX, srs_power_without_h_b_f_c + h_b_f_c); +} diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c index 84a35dcf52..a076829a8a 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c @@ -1058,7 +1058,8 @@ int configure_srs_pdu(NR_UE_MAC_INST_t *mac, NR_SRS_Resource_t *srs_resource, fapi_nr_ul_config_srs_pdu *srs_config_pdu, int period, - int offset) + int offset, + NR_SRS_ResourceSet_t *srs_resource_set) { NR_UE_UL_BWP_t *current_UL_BWP = mac->current_UL_BWP; @@ -1100,6 +1101,11 @@ int configure_srs_pdu(NR_UE_MAC_INST_t *mac, srs_config_pdu->t_offset = offset; } + bool is_configured_for_pusch_on_current_bwp = true; + int delta_srs = 0; // DCI format 2_3 not implemented + srs_config_pdu->tx_power = + get_srs_tx_power_ue(mac, srs_resource, srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + #ifdef SRS_DEBUG LOG_I(NR_MAC,"Frame = %i, slot = %i\n", frame, slot); LOG_I(NR_MAC,"srs_config_pdu->rnti = 0x%04x\n", srs_config_pdu->rnti); @@ -1142,10 +1148,11 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger int slot_offset = 0; NR_SRS_Resource_t *srs_resource = NULL; + NR_SRS_ResourceSet_t *srs_resource_set = NULL; for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) { // Find aperiodic resource set - NR_SRS_ResourceSet_t *srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; + srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; if(srs_resource_set->resourceType.present != NR_SRS_ResourceSet__resourceType_PR_aperiodic) continue; // the resource trigger need to match the DCI one @@ -1186,7 +1193,7 @@ void nr_ue_aperiodic_srs_scheduling(NR_UE_MAC_INST_t *mac, long resource_trigger fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, sched_frame, sched_slot, FAPI_NR_UL_CONFIG_TYPE_SRS); if (!pdu) return; - int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, 0, 0); + int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, 0, 0, srs_resource_set); if (ret != 0) remove_ul_config_last_item(pdu); release_ul_config(pdu, false); @@ -1204,9 +1211,10 @@ static bool nr_ue_periodic_srs_scheduling(NR_UE_MAC_INST_t *mac, frame_t frame, } bool srs_scheduled = false; + NR_SRS_ResourceSet_t *srs_resource_set = NULL; for(int rs = 0; rs < srs_config->srs_ResourceSetToAddModList->list.count; rs++) { // Find periodic resource set - NR_SRS_ResourceSet_t *srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; + srs_resource_set = srs_config->srs_ResourceSetToAddModList->list.array[rs]; if(srs_resource_set->resourceType.present != NR_SRS_ResourceSet__resourceType_PR_periodic) { continue; } @@ -1237,7 +1245,7 @@ static bool nr_ue_periodic_srs_scheduling(NR_UE_MAC_INST_t *mac, frame_t frame, fapi_nr_ul_config_request_pdu_t *pdu = lockGet_ul_config(mac, frame, slot, FAPI_NR_UL_CONFIG_TYPE_SRS); if (!pdu) return false; - int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, period, offset); + int ret = configure_srs_pdu(mac, srs_resource, &pdu->srs_config_pdu, period, offset, srs_resource_set); if (ret != 0) remove_ul_config_last_item(pdu); else 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 index c8467241b8..26f9681079 100644 --- 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 @@ -594,6 +594,126 @@ TEST(test_pcmax, test_non_obvious_bwp_size) nr_get_Pcmax(23, nr_band, frame_type, FR1, channel_bandwidth, 2, false, 1, N_RB_UL, false, 6, prb_start)); } +TEST(test_srs_power, use_pusch_power_adjustment_state) +{ + NR_UE_MAC_INST_t mac = {0}; + NR_UE_UL_BWP_t current_UL_BWP = {0}; + current_UL_BWP.scs = 1; + current_UL_BWP.BWPSize = 106; + mac.current_UL_BWP = ¤t_UL_BWP; + NR_SRS_Resource_t srs_resource = {0}; + NR_SRS_ResourceSet_t srs_resource_set = {0}; + bool is_configured_for_pusch_on_current_bwp = true; + int delta_srs = 0; + srs_resource_set.srs_PowerControlAdjustmentStates = NULL; + mac.nr_band = 78; + mac.f_b_f_c = 0; + mac.pusch_power_control_initialized = true; + long p0 = 0; + srs_resource_set.p0 = &p0; + + int tx_power = get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + + mac.f_b_f_c = 4; + + int increased_tx_power = + get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + EXPECT_EQ(tx_power + mac.f_b_f_c, increased_tx_power); +} + +TEST(test_srs_power, no_support_for_two_pusch_power_adjustment_states) +{ + NR_UE_MAC_INST_t mac = {0}; + NR_UE_UL_BWP_t current_UL_BWP = {0}; + current_UL_BWP.scs = 1; + current_UL_BWP.BWPSize = 106; + mac.current_UL_BWP = ¤t_UL_BWP; + NR_SRS_Resource_t srs_resource = {0}; + NR_SRS_ResourceSet_t srs_resource_set = {0}; + long p0 = 0; + srs_resource_set.p0 = &p0; + bool is_configured_for_pusch_on_current_bwp = true; + int delta_srs = 0; + long srs_PowerControlAdjustmentStates = NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_sameAsFci2; + srs_resource_set.srs_PowerControlAdjustmentStates = &srs_PowerControlAdjustmentStates; + mac.nr_band = 78; + mac.f_b_f_c = 0; + mac.pusch_power_control_initialized = true; + + EXPECT_DEATH(get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp), + "Two PUSCH power adjustment states not supported"); +} + +TEST(test_srs_power, no_tpc_accumulation) +{ + NR_UE_MAC_INST_t mac = {0}; + NR_UE_UL_BWP_t current_UL_BWP = {0}; + current_UL_BWP.scs = 1; + current_UL_BWP.BWPSize = 106; + mac.current_UL_BWP = ¤t_UL_BWP; + NR_SRS_Resource_t srs_resource = {0}; + NR_SRS_ResourceSet_t srs_resource_set = {0}; + long p0 = 0; + srs_resource_set.p0 = &p0; + bool is_configured_for_pusch_on_current_bwp = true; + int delta_srs = 0; + long srs_PowerControlAdjustmentStates = NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_separateClosedLoop; + srs_resource_set.srs_PowerControlAdjustmentStates = &srs_PowerControlAdjustmentStates; + mac.nr_band = 78; + mac.f_b_f_c = 0; + mac.pusch_power_control_initialized = true; + + NR_SRS_Config_t srs_Config = {0}; + long tpc_Accumulation = 0; + srs_Config.tpc_Accumulation = &tpc_Accumulation; + current_UL_BWP.srs_Config = &srs_Config; + + int tx_power = get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + + delta_srs = 4; + + int increased_tx_power = + get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + EXPECT_EQ(tx_power + delta_srs, increased_tx_power); +} + +TEST(test_srs_power, tpc_accumulation) +{ + NR_UE_MAC_INST_t mac = {0}; + NR_UE_UL_BWP_t current_UL_BWP = {0}; + current_UL_BWP.scs = 1; + current_UL_BWP.BWPSize = 106; + mac.current_UL_BWP = ¤t_UL_BWP; + NR_SRS_Resource_t srs_resource = {0}; + NR_SRS_ResourceSet_t srs_resource_set = {0}; + long p0 = 0; + srs_resource_set.p0 = &p0; + bool is_configured_for_pusch_on_current_bwp = true; + int delta_srs = 0; + long srs_PowerControlAdjustmentStates = NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_separateClosedLoop; + srs_resource_set.srs_PowerControlAdjustmentStates = &srs_PowerControlAdjustmentStates; + mac.nr_band = 78; + mac.f_b_f_c = 0; + mac.pusch_power_control_initialized = true; + mac.srs_power_control_initialized = true; + mac.h_b_f_c = 0; + + NR_SRS_Config_t srs_Config = {0}; + current_UL_BWP.srs_Config = &srs_Config; + + int tx_power = get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + + delta_srs = 4; + + int increased_tx_power = + get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + EXPECT_EQ(tx_power + delta_srs, increased_tx_power); + + int more_tx_power = + get_srs_tx_power_ue(&mac, &srs_resource, &srs_resource_set, delta_srs, is_configured_for_pusch_on_current_bwp); + EXPECT_EQ(tx_power + delta_srs * 2, more_tx_power); +} + int main(int argc, char** argv) { logInit(); From 7359c6b66ef4b4672594e59c308632fd92ee84ab Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 24 Sep 2024 12:50:27 +0200 Subject: [PATCH 2/3] Move h_b_f_c to UL BWP Move h_b_f_c (or SRS power control adjustment state) to UL BWP structure. This is a per bwp parameter so it makes sense to make its lifetime the same as BWP, even if we dont support >1 UL BWPs. --- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 3 +++ openair2/LAYER2/NR_MAC_UE/config_ue.c | 1 + openair2/LAYER2/NR_MAC_UE/mac_defs.h | 2 -- openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c | 14 +++++++------- .../tests/test_nr_ue_power_procedures.cpp | 3 +-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index f3a272330b..1dff70618e 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -577,6 +577,9 @@ typedef struct NR_UE_UL_BWP { int channel_bandwidth; // Minimum transmission power according to 38.101 6.3.1 float P_CMIN; + // SRS power control adjustment state + int h_b_f_c; + bool srs_power_control_initialized; } NR_UE_UL_BWP_t; // non-BWP serving cell configuration diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index fab0fb7a7c..be3413e308 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1513,6 +1513,7 @@ static void configure_common_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP_Up bwp->channel_bandwidth = get_supported_bw_mhz(mac->frequency_range, bw_index); // Minumum transmission power depends on bandwidth, precalculate it here bwp->P_CMIN = nr_get_Pcmin(bw_index); + bwp->srs_power_control_initialized = false; if (bwp_id == 0) { mac->sc_info.initial_ul_BWPSize = bwp->BWPSize; mac->sc_info.initial_ul_BWPStart = bwp->BWPStart; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index aed42e6c53..c913321f80 100644 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -609,8 +609,6 @@ typedef struct NR_UE_MAC_INST_s { bool pucch_power_control_initialized; int f_b_f_c; bool pusch_power_control_initialized; - int h_b_f_c; - bool srs_power_control_initialized; int delta_msg2; } NR_UE_MAC_INST_t; 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 fba8f63bd4..70d3aacb66 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_power_procedures.c @@ -653,22 +653,22 @@ int get_srs_tx_power_ue(NR_UE_MAC_INST_t *mac, == NR_SRS_ResourceSet__srs_PowerControlAdjustmentStates_separateClosedLoop; if (!is_tpc_accumulation_provided && (!is_configured_for_pusch_on_current_bwp || separate_pc_adjustment_state)) { - if (!mac->srs_power_control_initialized) { + if (!current_UL_BWP->srs_power_control_initialized) { NR_PRACH_RESOURCES_t *prach_resources = &mac->ra.prach_resources; float DELTA_P_rampup_requested = (prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER - 1) * prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP; float DELTA_P_rampup = P_CMAX - (P_0_SRS + m_srs_component + alpha * pathloss); DELTA_P_rampup = min(DELTA_P_rampup_requested, max(0, DELTA_P_rampup)); - mac->srs_power_control_initialized = true; - mac->h_b_f_c = DELTA_P_rampup + mac->delta_msg2; + current_UL_BWP->srs_power_control_initialized = true; + current_UL_BWP->h_b_f_c = DELTA_P_rampup + mac->delta_msg2; } else { int P_CMIN = mac->current_UL_BWP->P_CMIN; - if (!((srs_power_without_h_b_f_c + mac->h_b_f_c >= P_CMAX && delta_srs > 0) - || (srs_power_without_h_b_f_c + mac->h_b_f_c <= P_CMIN && delta_srs < 0))) { - mac->h_b_f_c += delta_srs; + if (!((srs_power_without_h_b_f_c + current_UL_BWP->h_b_f_c >= P_CMAX && delta_srs > 0) + || (srs_power_without_h_b_f_c + current_UL_BWP->h_b_f_c <= P_CMIN && delta_srs < 0))) { + current_UL_BWP->h_b_f_c += delta_srs; } } - h_b_f_c = mac->h_b_f_c; + h_b_f_c = current_UL_BWP->h_b_f_c; } else { // Case 3: No accumulation h_b_f_c = delta_srs; 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 index 26f9681079..760de0df3d 100644 --- 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 @@ -695,8 +695,7 @@ TEST(test_srs_power, tpc_accumulation) mac.nr_band = 78; mac.f_b_f_c = 0; mac.pusch_power_control_initialized = true; - mac.srs_power_control_initialized = true; - mac.h_b_f_c = 0; + current_UL_BWP.srs_power_control_initialized = true; NR_SRS_Config_t srs_Config = {0}; current_UL_BWP.srs_Config = &srs_Config; From fecff5f346adc8ce0e004107a57302b68558a660 Mon Sep 17 00:00:00 2001 From: Bartosz Podrygajlo Date: Tue, 24 Sep 2024 13:47:00 +0200 Subject: [PATCH 3/3] Reset SRS power control adjustment state if p0 or alpha is provided Reset h_b_f_c (SRS power control adjustment state) when SRS-ResourceSet p0 or alpha is provided by higher layers, accroding to 38.213 7.3.1. --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 36 +++++++++++++++++++-------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index be3413e308..de8fa49d48 100644 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -1280,7 +1280,7 @@ static void handle_aperiodic_srs_type(struct NR_SRS_ResourceSet__resourceType__a struct NR_SRS_ResourceSet__resourceType__aperiodic__ext1__aperiodicSRS_ResourceTriggerList); } -static void setup_srsresourceset(NR_SRS_ResourceSet_t *target, NR_SRS_ResourceSet_t *source) +static void setup_srsresourceset(NR_UE_UL_BWP_t *bwp, NR_SRS_ResourceSet_t *target, NR_SRS_ResourceSet_t *source) { target->srs_ResourceSetId = source->srs_ResourceSetId; if (source->srs_ResourceIdList) @@ -1311,15 +1311,20 @@ static void setup_srsresourceset(NR_SRS_ResourceSet_t *target, NR_SRS_ResourceSe } } target->usage = source->usage; + if (source->alpha) { + bwp->h_b_f_c = 0; + } UPDATE_IE(target->alpha, source->alpha, NR_Alpha_t); - if (source->p0) + if (source->p0) { + bwp->h_b_f_c = 0; UPDATE_IE(target->p0, source->p0, long); + } if (source->pathlossReferenceRS) UPDATE_IE(target->pathlossReferenceRS, source->pathlossReferenceRS, struct NR_PathlossReferenceRS_Config); UPDATE_IE(target->srs_PowerControlAdjustmentStates, source->srs_PowerControlAdjustmentStates, long); } -static void setup_srsconfig(NR_SRS_Config_t *source, NR_SRS_Config_t *target) +static void setup_srsconfig(NR_UE_UL_BWP_t *bwp, NR_SRS_Config_t *source, NR_SRS_Config_t *target) { UPDATE_IE(target->tpc_Accumulation, source->tpc_Accumulation, long); // SRS-Resource @@ -1337,14 +1342,25 @@ static void setup_srsconfig(NR_SRS_Config_t *source, NR_SRS_Config_t *target) srs_ResourceId); } // SRS-ResourceSet - if (source->srs_ResourceSetToAddModList) { + struct NR_SRS_Config__srs_ResourceSetToAddModList *source_srs_list = source->srs_ResourceSetToAddModList; + if (source_srs_list) { if (!target->srs_ResourceSetToAddModList) target->srs_ResourceSetToAddModList = calloc(1, sizeof(*target->srs_ResourceSetToAddModList)); - ADDMOD_IE_FROMLIST_WFUNCTION(source->srs_ResourceSetToAddModList, - target->srs_ResourceSetToAddModList, - srs_ResourceSetId, - NR_SRS_ResourceSet_t, - setup_srsresourceset); + struct NR_SRS_Config__srs_ResourceSetToAddModList *target_srs_list = target->srs_ResourceSetToAddModList; + + for (int i = 0; i < source_srs_list->list.count; i++) { + long srs_resource_id = source_srs_list->list.array[i]->srs_ResourceSetId; + int j; + for (j = 0; j < target_srs_list->list.count; j++) { + if (srs_resource_id == target_srs_list->list.array[j]->srs_ResourceSetId) + break; + } + if (j == target_srs_list->list.count) { + NR_SRS_ResourceSet_t *new = calloc(1, sizeof(*new)); + ASN_SEQUENCE_ADD(&target_srs_list->list, new); + } + setup_srsresourceset(bwp, target_srs_list->list.array[j], source_srs_list->list.array[i]); + } } if (source->srs_ResourceSetToReleaseList) { RELEASE_IE_FROMLIST(source->srs_ResourceSetToReleaseList, @@ -1459,7 +1475,7 @@ static void configure_dedicated_BWP_ul(NR_UE_MAC_INST_t *mac, int bwp_id, NR_BWP if (ul_dedicated->srs_Config->present == NR_SetupRelease_SRS_Config_PR_setup) { if (!bwp->srs_Config) bwp->srs_Config = calloc(1, sizeof(*bwp->srs_Config)); - setup_srsconfig(ul_dedicated->srs_Config->choice.setup, bwp->srs_Config); + setup_srsconfig(bwp, ul_dedicated->srs_Config->choice.setup, bwp->srs_Config); } } AssertFatal(!ul_dedicated->configuredGrantConfig, "configuredGrantConfig not supported\n");