Commit 224c5538 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/NR_UE_get_Pmax' into integration_2023_w15

parents c6a04db9 41d9e775
...@@ -1513,6 +1513,7 @@ set (MAC_NR_SRC_UE ...@@ -1513,6 +1513,7 @@ set (MAC_NR_SRC_UE
${NR_UE_MAC_DIR}/nr_ue_scheduler.c ${NR_UE_MAC_DIR}/nr_ue_scheduler.c
${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c ${NR_UE_MAC_DIR}/nr_ue_dci_configuration.c
${NR_UE_MAC_DIR}/nr_ra_procedures.c ${NR_UE_MAC_DIR}/nr_ra_procedures.c
${NR_UE_MAC_DIR}/nr_ue_power_procedures.c
) )
set (ENB_APP_SRC set (ENB_APP_SRC
......
...@@ -36,20 +36,20 @@ ...@@ -36,20 +36,20 @@
const char *duplex_mode[]={"FDD","TDD"}; const char *duplex_mode[]={"FDD","TDD"};
int tables_5_3_2[5][11] = { int tables_5_3_2[5][12] = {
{25, 52, 79, 106, 133, 160, 216, 270, -1, -1, -1}, // 15 FR1 {25, 52, 79, 106, 133, 160, 216, 270, -1, -1, -1, -1}, // 15 FR1
{11, 24, 38, 51, 65, 78, 106, 133, 162, 217, 273}, // 30 FR1 {11, 24, 38, 51, 65, 78, 106, 133, 162, 217, 245, 273},// 30 FR1
{-1, 11, 18, 24, 31, 38, 51, 65, 79, 107, 135}, // 60 FR1 {-1, 11, 18, 24, 31, 38, 51, 65, 79, 107, 121, 135}, // 60 FR1
{66, 132, 264, -1 , -1, -1, -1, -1, -1, -1, -1}, // 60 FR2 {66, 132, 264, -1 , -1, -1, -1, -1, -1, -1, -1, -1}, // 60 FR2
{32, 66, 132, 264, -1, -1, -1, -1, -1, -1, -1} // 120FR2 {32, 66, 132, 264, -1, -1, -1, -1, -1, -1, -1, -1} // 120FR2
}; };
int get_supported_band_index(int scs, int band, int n_rbs){ int get_supported_band_index(int scs, int band, int n_rbs)
{
int scs_index = scs; int scs_index = scs;
if (band>256) if (band > 256)
scs_index++; scs_index++;
for (int i=0; i<11; i++) { for (int i = 0; i < 11; i++) {
if(n_rbs == tables_5_3_2[scs][i]) if(n_rbs == tables_5_3_2[scs][i])
return i; return i;
} }
...@@ -130,6 +130,66 @@ const nr_bandentry_t nr_bandtable[] = { ...@@ -130,6 +130,66 @@ const nr_bandentry_t nr_bandtable[] = {
{261,27500040,28350000,27500040,28350000, 2,2070833, 120} {261,27500040,28350000,27500040,28350000, 2,2070833, 120}
}; };
int get_supported_bw_khz(frequency_range_t frequency_range, int bw_index)
{
if (frequency_range == FR1) {
switch (bw_index) {
case 0 :
return 5000; // 5MHz
case 1 :
return 10000;
case 2 :
return 15000;
case 3 :
return 20000;
case 4 :
return 25000;
case 5 :
return 30000;
case 6 :
return 40000;
case 7 :
return 50000;
case 8 :
return 60000;
case 9 :
return 80000;
case 10 :
return 90000;
case 11 :
return 100000;
default :
AssertFatal(false, "Invalid band index for FR1 %d\n", bw_index);
}
}
else {
switch (bw_index) {
case 0 :
return 50000; // 50MHz
case 1 :
return 100000;
case 2 :
return 200000;
case 3 :
return 400000;
default :
AssertFatal(false, "Invalid band index for FR2 %d\n", bw_index);
}
}
}
bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_t frame_type)
{
// 38.101-1 section 6.2.2
// Relative channel bandwidth <= 4% for TDD bands and <= 3% for FDD bands
int index = get_nr_table_idx(nr_band, scs);
int bw_index = get_supported_band_index(scs, nr_band, nb_ul);
int band_size_khz = get_supported_bw_khz(nr_band > 256 ? FR2 : FR1, bw_index);
float limit = frame_type == TDD ? 0.04 : 0.03;
float rel_bw = (float) (2 * band_size_khz) / (float) (nr_bandtable[index].ul_max + nr_bandtable[index].ul_min);
return rel_bw <= limit;
}
uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex) uint16_t get_band(uint64_t downlink_frequency, int32_t delta_duplex)
{ {
const int64_t dl_freq_khz = downlink_frequency / 1000; const int64_t dl_freq_khz = downlink_frequency / 1000;
......
...@@ -93,6 +93,7 @@ int get_nb_periods_per_frame(uint8_t tdd_period); ...@@ -93,6 +93,7 @@ int get_nb_periods_per_frame(uint8_t tdd_period);
int get_supported_band_index(int scs, int band, int n_rbs); int get_supported_band_index(int scs, int band, int n_rbs);
long rrc_get_max_nr_csrs(const int max_rbs, long b_SRS); long rrc_get_max_nr_csrs(const int max_rbs, long b_SRS);
void get_K1_K2(int N1, int N2, int *K1, int *K2); void get_K1_K2(int N1, int N2, int *K1, int *K2);
bool compare_relative_ul_channel_bw(int nr_band, int scs, int nb_ul, frame_type_t frame_type);
void get_samplerate_and_bw(int mu, void get_samplerate_and_bw(int mu,
int n_rb, int n_rb,
int8_t threequarter_fs, int8_t threequarter_fs,
......
...@@ -174,7 +174,6 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac, ...@@ -174,7 +174,6 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
} }
} }
mac->nr_band = *scc->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR;
mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology); mac->frame_type = get_frame_type(mac->nr_band, get_softmodem_params()->numerology);
// cell config // cell config
...@@ -261,8 +260,8 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac, ...@@ -261,8 +260,8 @@ void config_common_ue_sa(NR_UE_MAC_INST_t *mac,
void config_common_ue(NR_UE_MAC_INST_t *mac, void config_common_ue(NR_UE_MAC_INST_t *mac,
module_id_t module_id, module_id_t module_id,
int cc_idP) { int cc_idP)
{
fapi_nr_config_request_t *cfg = &mac->phy_config.config_req; fapi_nr_config_request_t *cfg = &mac->phy_config.config_req;
NR_ServingCellConfigCommon_t *scc = mac->scc; NR_ServingCellConfigCommon_t *scc = mac->scc;
int i; int i;
...@@ -717,7 +716,7 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id, ...@@ -717,7 +716,7 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id,
if (sccP != NULL) { if (sccP != NULL) {
mac->scc_SIB = sccP; mac->scc_SIB = sccP;
LOG_D(NR_MAC, "In %s: Keeping ServingCellConfigCommonSIB\n", __FUNCTION__); mac->nr_band = *sccP->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR;
config_common_ue_sa(mac, module_id, cc_idP); config_common_ue_sa(mac, module_id, cc_idP);
configure_current_BWP(mac, sccP, NULL); configure_current_BWP(mac, sccP, NULL);
...@@ -758,6 +757,7 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id, ...@@ -758,6 +757,7 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id,
ra->rach_ConfigDedicated = scell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; ra->rach_ConfigDedicated = scell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
} }
mac->scc = scell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; mac->scc = scell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
mac->nr_band = *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
mac->physCellId = *mac->scc->physCellId; mac->physCellId = *mac->scc->physCellId;
config_common_ue(mac,module_id,cc_idP); config_common_ue(mac,module_id,cc_idP);
mac->crnti = scell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; mac->crnti = scell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity;
...@@ -793,6 +793,7 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id, ...@@ -793,6 +793,7 @@ int nr_rrc_mac_config_req_ue(module_id_t module_id,
ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; ra->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink;
} }
mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon;
mac->nr_band = *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
if (mac->scc_SIB) { if (mac->scc_SIB) {
free(mac->scc_SIB); free(mac->scc_SIB);
mac->scc_SIB = NULL; mac->scc_SIB = NULL;
......
...@@ -307,6 +307,8 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac, ...@@ -307,6 +307,8 @@ void nr_ue_configure_pucch(NR_UE_MAC_INST_t *mac,
PUCCH_sched_t *pucch, PUCCH_sched_t *pucch,
fapi_nr_ul_config_pucch_pdu *pucch_pdu); 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);
/* Random Access */ /* Random Access */
/* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x /* \brief This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211 tables 6.3.3.2.x
......
...@@ -40,93 +40,13 @@ ...@@ -40,93 +40,13 @@
#include <executables/softmodem-common.h> #include <executables/softmodem-common.h>
// Implementation of 6.2.4 Configured ransmitted power
// 3GPP TS 38.101-1 version 16.5.0 Release 16
// -
// The UE is allowed to set its configured maximum output power PCMAX,f,c for carrier f of serving cell c in each slot.
// The configured maximum output power PCMAX,f,c is set within the following bounds: PCMAX_L,f,c <= PCMAX,f,c <= PCMAX_H,f,c
// -
// Measurement units:
// - p_max: dBm
// - delta_TC_c: dB
// - P_powerclass: dBm
// - delta_P_powerclass: dB
// - MPR_c: dB
// - delta_MPR_c: dB
// - delta_T_IB_c dB
// - delta_rx_SRS dB
// note:
// - Assuming:
// -- Powerclass 3 capable UE (which is default power class unless otherwise stated)
// -- Maximum power reduction (MPR_c) for power class 3, QPSK, inner RB allocations
// -- no additional MPR (A_MPR_c)
// todo:
// - in current implementation delta_P_powerclass is not handling power classes different from 3
long nr_get_Pcmax(module_id_t mod_id){
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
uint32_t band = (mac->scc!=NULL) ? *mac->scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0] :
*mac->scc_SIB->downlinkConfigCommon.frequencyInfoDL.frequencyBandList.list.array[0]->freqBandIndicatorNR;
NR_P_Max_t p_max = 0;
uint8_t P_powerclass = 23;
uint8_t delta_P_powerclass = 0;
uint8_t MPR_c = 1;
uint8_t delta_MPR_c = 0;
uint8_t A_MPR_c = 0;
uint8_t delta_T_IB_c = 0;
uint8_t delta_TC_c = 0;
uint8_t delta_rx_SRS = 0;
uint8_t P_MPR_c = 0;
long P_cmax_l = 0;
long P_cmax_h = 0;
long P_cmax = 0;
if (band == 28 && mac->phy_config.config_req.carrier_config.uplink_bandwidth == 30){
delta_MPR_c = 1;
}
if (mac->cg && mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1){
if (*mac->cg->spCellConfig->spCellConfigDedicated->uplinkConfig->ext1->powerBoostPi2BPSK == 1){
// TbD: assuming power class 3 capable UE operating in TDD bands n40, n41, n77, n78, and n79 with Pi/2 BPSK modulation
delta_P_powerclass = -3;
p_max += 3;
}
}
NR_P_Max_t *p_Max = (mac->scc!=NULL) ? mac->scc->uplinkConfigCommon->frequencyInfoUL->p_Max : mac->scc_SIB->uplinkConfigCommon->frequencyInfoUL.p_Max;
if (p_Max){
p_max += *p_Max;
LOG_D(MAC, "In %s maximum UL transmission power p_max is %ld dBm \n", __FUNCTION__, p_max);
P_cmax_l = min(p_max - delta_TC_c, (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c));
P_cmax_h = min(p_max, P_powerclass - delta_P_powerclass);
} else {
P_cmax_l = (P_powerclass - delta_P_powerclass) - max(max(MPR_c + delta_MPR_c, A_MPR_c) + delta_T_IB_c + delta_TC_c + delta_rx_SRS, P_MPR_c);
P_cmax_h = P_powerclass - delta_P_powerclass;
}
P_cmax = (P_cmax_h + P_cmax_l) / 2;
LOG_D(MAC, "In %s configured maximum output power: %ld dBm <= PCMAX %ld dBm <= %ld dBm \n", __FUNCTION__, P_cmax_l, P_cmax, P_cmax_h);
return P_cmax;
}
int16_t get_prach_tx_power(module_id_t mod_id) { int16_t get_prach_tx_power(module_id_t mod_id) {
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra; RA_config_t *ra = &mac->ra;
int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm); int16_t pathloss = compute_nr_SSB_PL(mac, mac->ssb_measurements.ssb_rsrp_dBm);
int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30); int16_t ra_preamble_rx_power = (int16_t)(ra->prach_resources.ra_PREAMBLE_RECEIVED_TARGET_POWER - pathloss + 30);
return min(nr_get_Pcmax(mod_id), ra_preamble_rx_power); return min(ra->prach_resources.RA_PCMAX, ra_preamble_rx_power);
} }
...@@ -153,7 +73,13 @@ void init_RA(module_id_t mod_id, ...@@ -153,7 +73,13 @@ void init_RA(module_id_t mod_id,
ra->RA_backoff_cnt = 0; ra->RA_backoff_cnt = 0;
prach_resources->RA_PREAMBLE_BACKOFF = 0; prach_resources->RA_PREAMBLE_BACKOFF = 0;
prach_resources->RA_PCMAX = nr_get_Pcmax(mod_id); NR_SubcarrierSpacing_t prach_scs = *nr_rach_ConfigCommon->msg1_SubcarrierSpacing;
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;
int carrier_bandwidth = mac->scc_SIB ? mac->scc_SIB->uplinkConfigCommon->frequencyInfoUL.scs_SpecificCarrierList.list.array[0]->carrierBandwidth :
mac->scc->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->carrierBandwidth;
// 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, carrier_bandwidth, true, n_prbs, start_prb);
prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1; prach_resources->RA_PREAMBLE_POWER_RAMPING_COUNTER = 1;
prach_resources->POWER_OFFSET_2STEP_RA = 0; prach_resources->POWER_OFFSET_2STEP_RA = 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 power control procedures
* \author Francesco Mani
* \date 2023
* \version 0.1
* \email: email@francescomani.it
* \note
* \warning
*/
#include "LAYER2/NR_MAC_UE/mac_proto.h"
// Implementation of 6.2.4 Configured ransmitted power
// 3GPP TS 38.101-1 version 16.5.0 Release 16
// -
// The UE is allowed to set its configured maximum output power PCMAX,f,c for carrier f of serving cell c in each slot.
// The configured maximum output power PCMAX,f,c is set within the following bounds: PCMAX_L,f,c <= PCMAX,f,c <= PCMAX_H,f,c
// -
// Measurement units:
// - p_max: dBm
// - delta_TC_c: dB
// - P_powerclass: dBm
// - delta_P_powerclass: dB
// - MPR_c: dB
// - delta_MPR_c: dB
// - delta_T_IB_c dB
// - delta_rx_SRS dB
// note:
// - Assuming:
// -- 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_band = mac->nr_band;
if(mac->frequency_range == FR1) {
//TODO configure P-MAX from the upper layers according to 38.331
long *p_emax = (mac->scc!=NULL) ? mac->scc->uplinkConfigCommon->frequencyInfoUL->p_Max : mac->scc_SIB->uplinkConfigCommon->frequencyInfoUL.p_Max;
int p_powerclass = 23; // dBm assuming poweclass 3 UE
int delta_P_powerclass = 0; // for powerclass 2 needs to be changed
if(p_emax && 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;
}
// TODO to be set for CA and DC
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)
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)) {
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 :
AssertFatal(false, "MPR for Pi/2 BPSK not implemented yet\n");
break;
case 2 :
if (is_transform_precoding) {
if(!is_inner_rb)
MPR = 1;
}
else {
if(is_inner_rb)
MPR = 1.5;
else
MPR = 3;
}
break;
case 4 :
if (is_transform_precoding) {
if(is_inner_rb)
MPR = 1;
else
MPR = 2;
}
else {
if(is_inner_rb)
MPR = 2;
else
MPR = 3;
}
break;
case 6 :
if (is_transform_precoding)
MPR = 2.5;
else
MPR = 3.5;
break;
case 8 :
if (is_transform_precoding)
MPR = 4.5;
else
MPR = 6.5;
break;
break;
default:
AssertFatal(false, "Invalid Qm %d\n", Qm);
}
}
int A_MPR = 0; // TODO too complicated to implement for now (see 6.2.3 in 38.101-1)
int delta_rx_SRS = 0; // TODO for SRS
int P_MPR = 0; // to ensure compliance with applicable electromagnetic energy absorption requirements
float total_reduction = (MPR > A_MPR ? MPR : A_MPR) + delta_T_IB + delta_TC + delta_rx_SRS;
if (P_MPR > total_reduction)
total_reduction = P_MPR;
int pcmax_high, pcmax_low;
if(p_emax) {
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_high = p_powerclass - delta_P_powerclass;
pcmax_low = p_powerclass - delta_P_powerclass - total_reduction;
}
// TODO we need a strategy to select a value between minimum and maximum allowed PC_max
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 {
// FR2 TODO it is even more complex because it is radiated power
return 23;
}
}
...@@ -998,8 +998,6 @@ void set_dl_mcs_table(int scs, ...@@ -998,8 +998,6 @@ void set_dl_mcs_table(int scs,
} }
} }
AssertFatal(bw_rb>0,"Could not find scs-SpecificCarrierList element for scs %d",scs); AssertFatal(bw_rb>0,"Could not find scs-SpecificCarrierList element for scs %d",scs);
int bw = get_supported_band_index(scs, band, bw_rb);
AssertFatal(bw>=0,"Supported band corresponding to %d RBs not found\n", bw_rb);
bool supported = false; bool supported = false;
if (band>256) { if (band>256) {
......
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