mirror of https://github.com/PentHertz/srsLTE.git
Multiple fixes HARQ ACK/NACK feedback and CSI reporting for MIMO and CA
This commit is contained in:
parent
cb6a8444df
commit
784bf81a1a
|
@ -151,10 +151,13 @@ SRSLTE_API void srslte_enb_dl_gen_ack(const srslte_cell_t* cell,
|
|||
* info itself. Note that it expects that the HARQ-ACK info has been set prior the UCI Data decoding.
|
||||
*
|
||||
* @param cell points to the physical layer cell parameters
|
||||
* @param uci_cfg points to the UCI configration
|
||||
* @param uci_value points to the received UCI values
|
||||
* @param ack_info is the HARQ-ACK information
|
||||
*/
|
||||
SRSLTE_API void
|
||||
srslte_enb_dl_get_ack(const srslte_cell_t* cell, const srslte_uci_value_t* uci_value, srslte_pdsch_ack_t* pdsch_ack);
|
||||
SRSLTE_API void srslte_enb_dl_get_ack(const srslte_cell_t* cell,
|
||||
const srslte_uci_cfg_t* uci_cfg,
|
||||
const srslte_uci_value_t* uci_value,
|
||||
srslte_pdsch_ack_t* pdsch_ack);
|
||||
|
||||
#endif // SRSLTE_ENB_DL_H
|
||||
|
|
|
@ -120,7 +120,6 @@ typedef enum {
|
|||
|
||||
typedef struct SRSLTE_API {
|
||||
bool data_enable;
|
||||
bool ri_present;
|
||||
bool pmi_present;
|
||||
bool four_antenna_ports; ///< If cell has 4 antenna ports then true otherwise false
|
||||
bool rank_is_not_one; ///< If rank > 1 then true otherwise false
|
||||
|
|
|
@ -421,7 +421,7 @@ bool srslte_enb_dl_gen_cqi_periodic(const srslte_cell_t* cell,
|
|||
{
|
||||
bool cqi_enabled = false;
|
||||
if (srslte_cqi_periodic_ri_send(&dl_cfg->cqi_report, tti, cell->frame_type)) {
|
||||
cqi_cfg->ri_len = 1; /* Asumes only 1 bit for RI */
|
||||
cqi_cfg->ri_len = srslte_ri_nof_bits(cell);
|
||||
cqi_enabled = true;
|
||||
} else if (srslte_cqi_periodic_send(&dl_cfg->cqi_report, tti, cell->frame_type)) {
|
||||
cqi_cfg->type = SRSLTE_CQI_TYPE_WIDEBAND;
|
||||
|
@ -445,7 +445,7 @@ bool srslte_enb_dl_gen_cqi_aperiodic(const srslte_cell_t* cell,
|
|||
|
||||
cqi_cfg->type = SRSLTE_CQI_TYPE_SUBBAND_HL;
|
||||
if (dl_cfg->tm == SRSLTE_TM3 || dl_cfg->tm == SRSLTE_TM4) {
|
||||
cqi_cfg->ri_present = true;
|
||||
cqi_cfg->ri_len = srslte_ri_nof_bits(cell);
|
||||
}
|
||||
cqi_cfg->N = (cell->nof_prb > 7) ? srslte_cqi_hl_get_no_subbands(cell->nof_prb) : 0;
|
||||
cqi_cfg->four_antenna_ports = (cell->nof_ports == 4);
|
||||
|
@ -493,45 +493,135 @@ void srslte_enb_dl_gen_ack(const srslte_cell_t* cell,
|
|||
*uci_cfg = uci_data.cfg;
|
||||
}
|
||||
|
||||
static void get_ack_fdd(const srslte_uci_value_t* uci_value, srslte_pdsch_ack_t* pdsch_ack)
|
||||
static void enb_dl_get_ack_fdd_all_spatial_bundling(const srslte_uci_value_t* uci_value,
|
||||
srslte_pdsch_ack_t* pdsch_ack,
|
||||
uint32_t nof_tb)
|
||||
{
|
||||
uint32_t nof_tb = 1;
|
||||
if (pdsch_ack->transmission_mode > SRSLTE_TM2) {
|
||||
nof_tb = SRSLTE_MAX_CODEWORDS;
|
||||
}
|
||||
|
||||
// Second clause: When 2 CC are configured with PUCCH CS mode and SR is also requested, bundle spatial codewords
|
||||
if (pdsch_ack->nof_cc == SRSLTE_PUCCH_CS_MAX_CARRIERS && uci_value->scheduling_request == true &&
|
||||
pdsch_ack->ack_nack_feedback_mode == SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_CS) {
|
||||
for (uint32_t cc_idx = 0; cc_idx < pdsch_ack->nof_cc; cc_idx++) {
|
||||
if (pdsch_ack->cc[cc_idx].m[0].present) {
|
||||
if (uci_value->ack.ack_value[cc_idx] == 1) {
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++) {
|
||||
for (uint32_t cc_idx = 0; cc_idx < pdsch_ack->nof_cc; cc_idx++) {
|
||||
if (pdsch_ack->cc[cc_idx].m[0].present) {
|
||||
if (uci_value->ack.ack_value[cc_idx] == 1) {
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++) {
|
||||
// Check that TB was transmitted
|
||||
if (pdsch_ack->cc[cc_idx].m[0].value[tb] != 2) {
|
||||
pdsch_ack->cc[cc_idx].m[0].value[tb] = uci_value->ack.ack_value[cc_idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// By default, in FDD we just pass through all HARQ-ACK bits
|
||||
uint32_t n = 0;
|
||||
for (uint32_t cc_idx = 0; cc_idx < pdsch_ack->nof_cc; cc_idx++) {
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++, n++) {
|
||||
if (pdsch_ack->cc[cc_idx].m[0].present) {
|
||||
pdsch_ack->cc[cc_idx].m[0].value[tb] = uci_value->ack.ack_value[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
enb_dl_get_ack_fdd_pcell_skip_drx(const srslte_uci_value_t* uci_value, srslte_pdsch_ack_t* pdsch_ack, uint32_t nof_tb)
|
||||
{
|
||||
if (pdsch_ack->cc[0].m[0].present) {
|
||||
if (uci_value->ack.ack_value[0] == 1) {
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++) {
|
||||
// Check that TB was transmitted
|
||||
if (pdsch_ack->cc[0].m[0].value[tb] != 2) {
|
||||
pdsch_ack->cc[0].m[0].value[tb] = uci_value->ack.ack_value[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
enb_dl_get_ack_fdd_all_keep_drx(const srslte_uci_value_t* uci_value, srslte_pdsch_ack_t* pdsch_ack, uint32_t nof_tb)
|
||||
{
|
||||
for (uint32_t cc_idx = 0; cc_idx < pdsch_ack->nof_cc; cc_idx++) {
|
||||
if (pdsch_ack->cc[cc_idx].m[0].present) {
|
||||
if (uci_value->ack.ack_value[cc_idx] == 1) {
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++) {
|
||||
// Check that TB was transmitted
|
||||
if (pdsch_ack->cc[cc_idx].m[0].value[tb] != 2) {
|
||||
pdsch_ack->cc[cc_idx].m[0].value[tb] = uci_value->ack.ack_value[cc_idx * nof_tb + tb];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_ack_fdd(const srslte_uci_cfg_t* uci_cfg, const srslte_uci_value_t* uci_value, srslte_pdsch_ack_t* pdsch_ack)
|
||||
{
|
||||
// Number of transport blocks for the current Transmission Mode
|
||||
uint32_t nof_tb = 1;
|
||||
if (pdsch_ack->transmission_mode > SRSLTE_TM2) {
|
||||
nof_tb = SRSLTE_MAX_CODEWORDS;
|
||||
}
|
||||
|
||||
// Count number of transmissions
|
||||
uint32_t tb_count = 0; // All transmissions
|
||||
uint32_t tb_count_cc0 = 0; // Transmissions on PCell
|
||||
for (uint32_t cc_idx = 0; cc_idx < pdsch_ack->nof_cc; cc_idx++) {
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++) {
|
||||
if (pdsch_ack->cc[cc_idx].m[0].present && pdsch_ack->cc[cc_idx].m[0].value[tb] != 2) {
|
||||
tb_count++;
|
||||
}
|
||||
|
||||
// Save primary cell number of TB
|
||||
if (cc_idx == 0) {
|
||||
tb_count_cc0 = tb_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Does CSI report need to be transmitted?
|
||||
bool csi_report = uci_cfg->cqi.data_enable || uci_cfg->cqi.ri_len;
|
||||
|
||||
switch (pdsch_ack->ack_nack_feedback_mode) {
|
||||
|
||||
case SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_NORMAL:
|
||||
// Get ACK from PCell only, skipping DRX
|
||||
enb_dl_get_ack_fdd_pcell_skip_drx(uci_value, pdsch_ack, nof_tb);
|
||||
break;
|
||||
case SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_CS:
|
||||
if (pdsch_ack->nof_cc == 1) {
|
||||
enb_dl_get_ack_fdd_pcell_skip_drx(uci_value, pdsch_ack, nof_tb);
|
||||
} else if (pdsch_ack->is_pusch_available) {
|
||||
enb_dl_get_ack_fdd_all_keep_drx(uci_value, pdsch_ack, nof_tb);
|
||||
} else if (uci_value->scheduling_request) {
|
||||
// For FDD with PUCCH format 1b with channel selection, when both HARQ-ACK and SR are transmitted in the same
|
||||
// sub-frame a UE shall transmit the HARQ-ACK on its assigned HARQ-ACK PUCCH resource with channel selection as
|
||||
// defined in subclause 10.1.2.2.1 for a negative SR transmission and transmit one HARQ-ACK bit per serving cell
|
||||
// on its assigned SR PUCCH resource for a positive SR transmission according to the following:
|
||||
// − if only one transport block or a PDCCH indicating downlink SPS release is detected on a serving cell, the
|
||||
// HARQ-ACK bit for the serving cell is the HARQ-ACK bit corresponding to the transport block or the PDCCH
|
||||
// indicating downlink SPS release;
|
||||
// − if two transport blocks are received on a serving cell, the HARQ-ACK bit for the serving cell is generated
|
||||
// by spatially bundling the HARQ-ACK bits corresponding to the transport blocks;
|
||||
// − if neither PDSCH transmission for which HARQ-ACK response shall be provided nor PDCCH indicating
|
||||
// downlink SPS release is detected for a serving cell, the HARQ-ACK bit for the serving cell is set to NACK;
|
||||
enb_dl_get_ack_fdd_all_spatial_bundling(uci_value, pdsch_ack, nof_tb);
|
||||
} else if (csi_report) {
|
||||
enb_dl_get_ack_fdd_pcell_skip_drx(uci_value, pdsch_ack, nof_tb);
|
||||
} else {
|
||||
enb_dl_get_ack_fdd_all_keep_drx(uci_value, pdsch_ack, nof_tb);
|
||||
}
|
||||
break;
|
||||
case SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_PUCCH3:
|
||||
if (tb_count == tb_count_cc0) {
|
||||
enb_dl_get_ack_fdd_pcell_skip_drx(uci_value, pdsch_ack, nof_tb);
|
||||
} else {
|
||||
enb_dl_get_ack_fdd_all_keep_drx(uci_value, pdsch_ack, nof_tb);
|
||||
}
|
||||
break;
|
||||
case SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_ERROR:
|
||||
default:; // Do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void srslte_enb_dl_get_ack(const srslte_cell_t* cell,
|
||||
const srslte_uci_cfg_t* uci_cfg,
|
||||
const srslte_uci_value_t* uci_value,
|
||||
srslte_pdsch_ack_t* pdsch_ack)
|
||||
{
|
||||
if (cell->frame_type == SRSLTE_FDD) {
|
||||
get_ack_fdd(uci_value, pdsch_ack);
|
||||
get_ack_fdd(uci_cfg, uci_value, pdsch_ack);
|
||||
} else {
|
||||
ERROR("Not implemented for TDD\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -322,7 +322,7 @@ int srslte_cqi_size(srslte_cqi_cfg_t* cfg)
|
|||
int size = 0;
|
||||
|
||||
if (!cfg->data_enable) {
|
||||
return 0;
|
||||
return cfg->ri_len;
|
||||
}
|
||||
|
||||
switch (cfg->type) {
|
||||
|
|
|
@ -1205,7 +1205,7 @@ static int dci_format2AB_unpack(srslte_cell_t* cell,
|
|||
dci->pinfo = srslte_bit_pack(&y, precoding_bits_f2a(cell->nof_ports));
|
||||
}
|
||||
|
||||
// Apply TB swap table
|
||||
// Apply TB swap table according to 3GPP 36.212 R8, section 5.3.3.1.5
|
||||
if (nof_tb == 2) {
|
||||
// Table 5.3.3.1.5-1
|
||||
for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
||||
|
@ -1213,10 +1213,6 @@ static int dci_format2AB_unpack(srslte_cell_t* cell,
|
|||
}
|
||||
} else {
|
||||
// Table 5.3.3.1.5-2
|
||||
if (!SRSLTE_DCI_IS_TB_EN(dci->tb[0])) {
|
||||
dci->tb[0] = dci->tb[1];
|
||||
}
|
||||
SRSLTE_DCI_TB_DISABLE(dci->tb[1]);
|
||||
for (uint32_t i = 0; i < SRSLTE_MAX_CODEWORDS; i++) {
|
||||
dci->tb[i].cw_idx = 0;
|
||||
}
|
||||
|
|
|
@ -1025,7 +1025,7 @@ static int uci_decode_ri_ack(srslte_sch_t* q,
|
|||
|
||||
// If there is RI and CQI, assume RI = 1 for the purpose of RI/ACK decoding (3GPP 36.212 Clause 5.2.4.1. )
|
||||
if (cfg->uci_cfg.cqi.data_enable) {
|
||||
if (cfg->uci_cfg.cqi.type == SRSLTE_CQI_TYPE_SUBBAND_HL && cfg->uci_cfg.cqi.ri_present) {
|
||||
if (cfg->uci_cfg.cqi.type == SRSLTE_CQI_TYPE_SUBBAND_HL && cfg->uci_cfg.cqi.ri_len) {
|
||||
cfg->uci_cfg.cqi.rank_is_not_one = false;
|
||||
}
|
||||
}
|
||||
|
@ -1075,7 +1075,7 @@ static int uci_decode_ri_ack(srslte_sch_t* q,
|
|||
|
||||
// Now set correct RI
|
||||
if (cfg->uci_cfg.cqi.data_enable) {
|
||||
if (cfg->uci_cfg.cqi.type == SRSLTE_CQI_TYPE_SUBBAND_HL && cfg->uci_cfg.cqi.ri_present) {
|
||||
if (cfg->uci_cfg.cqi.type == SRSLTE_CQI_TYPE_SUBBAND_HL && cfg->uci_cfg.cqi.ri_len) {
|
||||
cfg->uci_cfg.cqi.rank_is_not_one = uci_data->ri > 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -945,70 +945,186 @@ void srslte_ue_dl_gen_cqi_aperiodic(srslte_ue_dl_t* q,
|
|||
}
|
||||
}
|
||||
|
||||
static void ue_dl_gen_ack_fdd_none(const srslte_pdsch_ack_t* ack_info, srslte_uci_data_t* uci_data)
|
||||
{
|
||||
// Set all carriers number of ACKs to 0
|
||||
for (uint32_t i = 0; i < ack_info->nof_cc; i++) {
|
||||
uci_data->cfg.ack[i].nof_acks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ue_dl_gen_ack_fdd_pcell_skip_drx(const srslte_pdsch_ack_t* ack_info, srslte_uci_data_t* uci_data, uint32_t nof_tb)
|
||||
{
|
||||
uint32_t ack_idx = 0;
|
||||
|
||||
// Find ACK/NACK
|
||||
if (ack_info->cc[0].m[0].present) {
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++) {
|
||||
if (ack_info->cc[0].m[0].value[tb] != 2) {
|
||||
uci_data->value.ack.ack_value[ack_idx] = ack_info->cc[0].m[0].value[tb];
|
||||
ack_idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set number of ACKs for PCell
|
||||
uci_data->cfg.ack[0].nof_acks = ack_idx;
|
||||
|
||||
// Set rest of carriers to 0 ACKs
|
||||
for (uint32_t i = 1; i < ack_info->nof_cc; i++) {
|
||||
uci_data->cfg.ack[i].nof_acks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ue_dl_gen_ack_fdd_all_keep_drx(const srslte_pdsch_ack_t* ack_info, srslte_uci_data_t* uci_data, uint32_t nof_tb)
|
||||
{
|
||||
|
||||
for (uint32_t cc_idx = 0; cc_idx < ack_info->nof_cc; cc_idx++) {
|
||||
// Find ACK/NACK
|
||||
if (ack_info->cc[cc_idx].m[0].present) {
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++) {
|
||||
if (ack_info->cc[cc_idx].m[0].value[tb] != 2) {
|
||||
uci_data->value.ack.ack_value[cc_idx * nof_tb + tb] = ack_info->cc[cc_idx].m[0].value[tb];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set all carriers to maximum number of TBs
|
||||
uci_data->cfg.ack[cc_idx].nof_acks = nof_tb;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ue_dl_gen_ack_fdd_all_spatial_bundling(const srslte_pdsch_ack_t* ack_info, srslte_uci_data_t* uci_data, uint32_t nof_tb)
|
||||
{
|
||||
uint32_t nof_ack = 0;
|
||||
|
||||
for (uint32_t cc_idx = 0; cc_idx < ack_info->nof_cc; cc_idx++) {
|
||||
if (ack_info->cc[cc_idx].m[0].present) {
|
||||
uci_data->value.ack.ack_value[cc_idx] = 1;
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++) {
|
||||
if (ack_info->cc[cc_idx].m[0].value[tb] != 2) {
|
||||
uci_data->value.ack.ack_value[cc_idx] &= ack_info->cc[cc_idx].m[0].value[tb];
|
||||
nof_ack++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
uci_data->value.ack.ack_value[cc_idx] = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// If no ACK is counted, set all zero, bundle otherwise
|
||||
for (uint32_t i = 0; i < SRSLTE_PUCCH_CS_MAX_CARRIERS; i++) {
|
||||
uci_data->cfg.ack[i].nof_acks = (nof_ack == 0) ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* UE downlink procedure for reporting HARQ-ACK bits in FDD, Section 7.3 36.213
|
||||
*/
|
||||
static void gen_ack_fdd(const srslte_pdsch_ack_t* ack_info, srslte_uci_data_t* uci_data)
|
||||
{
|
||||
// Number of transport blocks for the current Transmission Mode
|
||||
uint32_t nof_tb = 1;
|
||||
if (ack_info->transmission_mode > SRSLTE_TM2) {
|
||||
nof_tb = SRSLTE_MAX_CODEWORDS;
|
||||
}
|
||||
|
||||
// Second clause: When 2 CC are configured with PUCCH CS mode and SR is also requested, bundle spatial codewords
|
||||
if (!ack_info->is_pusch_available && ack_info->nof_cc == SRSLTE_PUCCH_CS_MAX_CARRIERS &&
|
||||
uci_data->value.scheduling_request == true &&
|
||||
ack_info->ack_nack_feedback_mode == SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_CS) {
|
||||
uint32_t nof_ack = 0;
|
||||
for (uint32_t cc_idx = 0; cc_idx < ack_info->nof_cc; cc_idx++) {
|
||||
if (ack_info->cc[cc_idx].m[0].present) {
|
||||
uci_data->value.ack.ack_value[cc_idx] = 1;
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++) {
|
||||
if (ack_info->cc[cc_idx].m[0].value[tb] != 2) {
|
||||
uci_data->value.ack.ack_value[cc_idx] &= ack_info->cc[cc_idx].m[0].value[tb];
|
||||
nof_ack++;
|
||||
}
|
||||
}
|
||||
// Count number of transmissions
|
||||
uint32_t tb_count = 0; // All transmissions
|
||||
uint32_t tb_count_cc0 = 0; // Transmissions on PCell
|
||||
for (uint32_t cc_idx = 0; cc_idx < ack_info->nof_cc; cc_idx++) {
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++) {
|
||||
if (ack_info->cc[cc_idx].m[0].present && ack_info->cc[cc_idx].m[0].value[tb] != 2) {
|
||||
tb_count++;
|
||||
}
|
||||
|
||||
// Save primary cell number of TB
|
||||
if (cc_idx == 0) {
|
||||
tb_count_cc0 = tb_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if no transmission counted return without reporting any ACK/NACK
|
||||
if (tb_count == 0) {
|
||||
ue_dl_gen_ack_fdd_none(ack_info, uci_data);
|
||||
return;
|
||||
}
|
||||
|
||||
// Count total of Uplink Control Bits
|
||||
uint32_t total_uci_bits =
|
||||
tb_count + srslte_cqi_size(&uci_data->cfg.cqi) + (uci_data->value.scheduling_request ? 1 : 0);
|
||||
|
||||
// Does CSI report need to be transmitted?
|
||||
bool csi_report = uci_data->cfg.cqi.data_enable || uci_data->cfg.cqi.ri_len;
|
||||
|
||||
// Logic for dropping CSI report if required
|
||||
if (csi_report && !ack_info->is_pusch_available) {
|
||||
bool drop_csi_report = true; ///< CSI report shall be dropped by default
|
||||
|
||||
// 3GPP 36.213 R.15 Section 10.1.1:
|
||||
// For FDD or for FDD-TDD and primary cell frame structure type 1 and for a UE that is configured with more than
|
||||
// one serving cell, in case of collision between a periodic CSI report and an HARQ-ACK in a same subframe without
|
||||
// PUSCH,
|
||||
|
||||
// - if the parameter simultaneousAckNackAndCQI provided by higher layers is set TRUE and if the HARQ-ACK
|
||||
// corresponds to a PDSCH transmission or PDCCH/EPDCCH indicating downlink SPS release only on the
|
||||
// primary cell, then the periodic CSI report is multiplexed with HARQ-ACK on PUCCH using PUCCH format 2/2a/2b
|
||||
drop_csi_report &= !(tb_count_cc0 == tb_count && ack_info->simul_cqi_ack);
|
||||
|
||||
// - else if the UE is configured with PUCCH format 3 and if the parameter simultaneousAckNackAndCQI-Format3-
|
||||
// r11 provided by higher layers is set TRUE, and if PUCCH resource is determined according to subclause
|
||||
// 10.1.2.2.2, and
|
||||
// - if the total number of bits in the subframe corresponding to HARQ-ACKs, SR (if any), and the CSI is not
|
||||
// larger than 22 or
|
||||
// - if the total number of bits in the subframe corresponding to spatially bundled HARQ-ACKs, SR (if any),
|
||||
// and the CSI is not larger than 22 then the periodic CSI report is multiplexed with HARQ-ACK on PUCCH
|
||||
// using the determined PUCCH format 3 resource according to [4]
|
||||
drop_csi_report &= !(ack_info->simul_cqi_ack_pucch3 && total_uci_bits <= 22);
|
||||
|
||||
// - otherwise, CSI is dropped
|
||||
if (drop_csi_report) {
|
||||
uci_data->cfg.cqi.data_enable = false;
|
||||
uci_data->cfg.cqi.ri_len = 0;
|
||||
csi_report = false;
|
||||
}
|
||||
}
|
||||
|
||||
// For each HARQ ACK/NACK feedback mode
|
||||
switch (ack_info->ack_nack_feedback_mode) {
|
||||
|
||||
case SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_NORMAL:
|
||||
// Get ACK from PCell only, skipping DRX
|
||||
ue_dl_gen_ack_fdd_pcell_skip_drx(ack_info, uci_data, nof_tb);
|
||||
break;
|
||||
case SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_CS:
|
||||
// Configured with more than serving cell and PUCCH Format 1b with channel selection
|
||||
if (ack_info->nof_cc == 1) {
|
||||
ue_dl_gen_ack_fdd_pcell_skip_drx(ack_info, uci_data, nof_tb);
|
||||
} else if (ack_info->is_pusch_available) {
|
||||
ue_dl_gen_ack_fdd_all_keep_drx(ack_info, uci_data, nof_tb);
|
||||
} else if (uci_data->value.scheduling_request) {
|
||||
// For FDD with PUCCH format 1b with channel selection, when both HARQ-ACK and SR are transmitted in the same
|
||||
// sub-frame a UE shall transmit the HARQ-ACK on its assigned HARQ-ACK PUCCH resource with channel selection as
|
||||
// defined in subclause 10.1.2.2.1 for a negative SR transmission and transmit one HARQ-ACK bit per serving cell
|
||||
// on its assigned SR PUCCH resource for a positive SR transmission according to the following:
|
||||
// − if only one transport block or a PDCCH indicating downlink SPS release is detected on a serving cell, the
|
||||
// HARQ-ACK bit for the serving cell is the HARQ-ACK bit corresponding to the transport block or the PDCCH
|
||||
// indicating downlink SPS release;
|
||||
// − if two transport blocks are received on a serving cell, the HARQ-ACK bit for the serving cell is generated
|
||||
// by spatially bundling the HARQ-ACK bits corresponding to the transport blocks;
|
||||
// − if neither PDSCH transmission for which HARQ-ACK response shall be provided nor PDCCH indicating
|
||||
// downlink SPS release is detected for a serving cell, the HARQ-ACK bit for the serving cell is set to NACK;
|
||||
ue_dl_gen_ack_fdd_all_spatial_bundling(ack_info, uci_data, nof_tb);
|
||||
} else if (csi_report) {
|
||||
ue_dl_gen_ack_fdd_pcell_skip_drx(ack_info, uci_data, nof_tb);
|
||||
} else {
|
||||
uci_data->value.ack.ack_value[cc_idx] = 2;
|
||||
ue_dl_gen_ack_fdd_all_keep_drx(ack_info, uci_data, nof_tb);
|
||||
}
|
||||
}
|
||||
|
||||
// If no ACK is counted, set all zero, bundle otherwise
|
||||
for (uint32_t i = 0; i < SRSLTE_PUCCH_CS_MAX_CARRIERS; i++) {
|
||||
uci_data->cfg.ack[i].nof_acks = (nof_ack == 0) ? 0 : 1;
|
||||
}
|
||||
} else {
|
||||
// By default, in FDD we just pass through all HARQ-ACK bits
|
||||
uint32_t tb_count = 0;
|
||||
uint32_t tb_count_cc0 = 0;
|
||||
uint32_t n = 0;
|
||||
for (uint32_t cc_idx = 0; cc_idx < ack_info->nof_cc; cc_idx++) {
|
||||
for (uint32_t tb = 0; tb < nof_tb; tb++, n++) {
|
||||
uci_data->value.ack.ack_value[n] = ack_info->cc[cc_idx].m[0].value[tb];
|
||||
if (ack_info->cc[cc_idx].m[0].present && ack_info->cc[cc_idx].m[0].value[tb] != 2) {
|
||||
tb_count++;
|
||||
}
|
||||
|
||||
// Save primary cell number of TB
|
||||
if (cc_idx == 0) {
|
||||
tb_count_cc0 = tb_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t total_uci_bits =
|
||||
tb_count + srslte_cqi_size(&uci_data->cfg.cqi) + (uci_data->value.scheduling_request ? 1 : 0);
|
||||
|
||||
if (tb_count == 0) {
|
||||
// If no PDSCH TB detected, set all to zeros and do not modify the UCI configuration
|
||||
for (int i = 0; i < ack_info->nof_cc; i++) {
|
||||
uci_data->cfg.ack[i].nof_acks = 0;
|
||||
}
|
||||
} else if (ack_info->nof_cc == 1) {
|
||||
// If only 1 configured cell, report 1 or 2 bits depending on number of detected TB
|
||||
uci_data->cfg.ack[0].nof_acks = tb_count;
|
||||
} else if (ack_info->ack_nack_feedback_mode == SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_PUCCH3 &&
|
||||
tb_count_cc0 == tb_count) {
|
||||
break;
|
||||
case SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_PUCCH3:
|
||||
// According to 3GPP 36.213 Section 10.1.2.2.2 PUCCH format 3 HARQ-ACK procedure
|
||||
// For FDD with PUCCH format 3, the UE shall use PUCCH resource n_pucch_3 or n_pucch_1 for transmission of
|
||||
// HARQ-ACK in subframe n where
|
||||
|
@ -1021,56 +1137,15 @@ static void gen_ack_fdd(const srslte_pdsch_ack_t* ack_info, srslte_uci_data_t* u
|
|||
// - for a PDSCH transmission on the secondary cell indicated by the detection of a corresponding PDCCH in
|
||||
// subframe n − 4 , the UE shall use PUCCH format 3 and PUCCH resource n_pucch_3 where the value of n PUCCH
|
||||
// is determined according to higher layer configuration and Table 10.1.2.2.2-1.
|
||||
uci_data->cfg.ack[0].nof_acks = tb_count_cc0; // So, set only PCell
|
||||
|
||||
for (int i = 1; i < ack_info->nof_cc; i++) {
|
||||
uci_data->cfg.ack[i].nof_acks = 0;
|
||||
if (tb_count == tb_count_cc0) {
|
||||
ue_dl_gen_ack_fdd_pcell_skip_drx(ack_info, uci_data, nof_tb);
|
||||
} else {
|
||||
ue_dl_gen_ack_fdd_all_keep_drx(ack_info, uci_data, nof_tb);
|
||||
}
|
||||
} else {
|
||||
// For 2 or more configured cells, report nof_tb per carrier except if there are no HARQ-ACK bits to report, in
|
||||
// which case we set to 0
|
||||
for (int i = 0; i < ack_info->nof_cc; i++) {
|
||||
uci_data->cfg.ack[i].nof_acks = nof_tb;
|
||||
}
|
||||
}
|
||||
|
||||
if (tb_count && uci_data->cfg.cqi.data_enable && !ack_info->is_pusch_available) {
|
||||
bool drop_csi_report = true; ///< CSI report shall be dropped by default
|
||||
|
||||
// 3GPP 36.213 R.15 Section 10.1.1:
|
||||
// For FDD or for FDD-TDD and primary cell frame structure type 1 and for a UE that is configured with more than
|
||||
// one serving cell, in case of collision between a periodic CSI report and an HARQ-ACK in a same subframe without
|
||||
// PUSCH,
|
||||
|
||||
// - if the parameter simultaneousAckNackAndCQI provided by higher layers is set TRUE and if the HARQ-ACK
|
||||
// corresponds to a PDSCH transmission or PDCCH/EPDCCH indicating downlink SPS release only on the
|
||||
// primary cell, then the periodic CSI report is multiplexed with HARQ-ACK on PUCCH using PUCCH format 2/2a/2b
|
||||
if ((tb_count_cc0 == tb_count && ack_info->simul_cqi_ack)) {
|
||||
// Do not drop CSI report
|
||||
drop_csi_report = false;
|
||||
|
||||
// Set number of active only ACKs
|
||||
uci_data->cfg.ack[0].nof_acks = tb_count_cc0;
|
||||
|
||||
// Set all SCell number of ACKs to 0
|
||||
for (int i = 1; i < ack_info->nof_cc; i++) {
|
||||
uci_data->cfg.ack[i].nof_acks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// - else if the UE is configured with PUCCH format 3 and if the parameter simultaneousAckNackAndCQI-Format3-
|
||||
// r11 provided by higher layers is set TRUE, and if PUCCH resource is determined according to subclause
|
||||
// 10.1.2.2.2, and
|
||||
// - if the total number of bits in the subframe corresponding to HARQ-ACKs, SR (if any), and the CSI is not
|
||||
// larger than 22 or
|
||||
// - if the total number of bits in the subframe corresponding to spatially bundled HARQ-ACKs, SR (if any),
|
||||
// and the CSI is not larger than 22 then the periodic CSI report is multiplexed with HARQ-ACK on PUCCH
|
||||
// using the determined PUCCH format 3 resource according to [4]
|
||||
drop_csi_report &= !(ack_info->simul_cqi_ack_pucch3 && total_uci_bits <= 22);
|
||||
|
||||
// - otherwise, CSI is dropped
|
||||
uci_data->cfg.cqi.data_enable = !drop_csi_report;
|
||||
}
|
||||
break;
|
||||
case SRSLTE_PUCCH_ACK_NACK_FEEDBACK_MODE_ERROR:
|
||||
default:; // Do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
// n_cce values are just copied
|
||||
|
@ -1297,7 +1372,6 @@ void srslte_ue_dl_gen_ack(const srslte_cell_t* cell,
|
|||
const srslte_pdsch_ack_t* ack_info,
|
||||
srslte_uci_data_t* uci_data)
|
||||
{
|
||||
|
||||
if (cell->frame_type == SRSLTE_FDD) {
|
||||
gen_ack_fdd(ack_info, uci_data);
|
||||
} else {
|
||||
|
|
|
@ -266,7 +266,7 @@ public:
|
|||
uint16_t rnti,
|
||||
bool aperiodic_cqi_request,
|
||||
bool is_pusch_available,
|
||||
srslte_uci_cfg_t& uci_cfg) const;
|
||||
srslte_uci_cfg_t& uci_cfg);
|
||||
|
||||
/**
|
||||
* Sends the decoded Uplink Control Information by PUCCH or PUSCH to MAC
|
||||
|
|
|
@ -361,10 +361,13 @@ void phy_ue_db::set_ack_pending(uint32_t tti, uint32_t enb_cc_idx, const srslte_
|
|||
pdsch_ack_m.resource.tpc_for_pucch = dci.tpc_pucch;
|
||||
|
||||
// Set TB info
|
||||
for (uint32_t i = 0; i < srslte_dci_format_max_tb(dci.format); i++) {
|
||||
if (SRSLTE_DCI_IS_TB_EN(dci.tb[i])) {
|
||||
pdsch_ack_m.value[i] = 1;
|
||||
for (uint32_t tb_idx = 0; tb_idx < SRSLTE_MAX_CODEWORDS; tb_idx++) {
|
||||
// Count only if the TB is enabled and the TB index is valid for the DCI format
|
||||
if (SRSLTE_DCI_IS_TB_EN(dci.tb[tb_idx]) and tb_idx < srslte_dci_format_max_tb(dci.format)) {
|
||||
pdsch_ack_m.value[tb_idx] = 1;
|
||||
pdsch_ack_m.k++;
|
||||
} else {
|
||||
pdsch_ack_m.value[tb_idx] = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -374,7 +377,7 @@ bool phy_ue_db::fill_uci_cfg(uint32_t tti,
|
|||
uint16_t rnti,
|
||||
bool aperiodic_cqi_request,
|
||||
bool is_pusch_available,
|
||||
srslte_uci_cfg_t& uci_cfg) const
|
||||
srslte_uci_cfg_t& uci_cfg)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
|
||||
|
@ -391,9 +394,12 @@ bool phy_ue_db::fill_uci_cfg(uint32_t tti,
|
|||
return false;
|
||||
}
|
||||
|
||||
const auto& ue = ue_db.at(rnti);
|
||||
const auto& pcell_cfg = ue.cell_info[0].phy_cfg;
|
||||
bool uci_required = false;
|
||||
common_ue& ue = ue_db.at(rnti);
|
||||
const srslte::phy_cfg_t& pcell_cfg = ue.cell_info[0].phy_cfg;
|
||||
bool uci_required = false;
|
||||
|
||||
const cell_info_t& pcell_info = ue.cell_info[0];
|
||||
const srslte_cell_t& pcell = cell_cfg_list->at(pcell_info.enb_cc_idx).cell;
|
||||
|
||||
// Check if SR opportunity (will only be used in PUCCH)
|
||||
uci_cfg.is_scheduling_request_tti = (srslte_ue_ul_sr_send_tti(&pcell_cfg.ul_cfg.pucch, tti) == 1);
|
||||
|
@ -420,20 +426,17 @@ bool phy_ue_db::fill_uci_cfg(uint32_t tti,
|
|||
// If no periodic CQI report required, check aperiodic reporting
|
||||
if ((not periodic_cqi_required) and aperiodic_cqi_request) {
|
||||
// Aperiodic only supported for PCell
|
||||
const cell_info_t& pcell_info = ue.cell_info[0];
|
||||
const srslte_cell_t& cell = cell_cfg_list->at(pcell_info.enb_cc_idx).cell;
|
||||
const srslte_dl_cfg_t& dl_cfg = pcell_info.phy_cfg.dl_cfg;
|
||||
const srslte_dl_cfg_t& dl_cfg = pcell_info.phy_cfg.dl_cfg;
|
||||
|
||||
uci_required = srslte_enb_dl_gen_cqi_aperiodic(&cell, &dl_cfg, pcell_info.last_ri, &uci_cfg.cqi);
|
||||
uci_required = srslte_enb_dl_gen_cqi_aperiodic(&pcell, &dl_cfg, pcell_info.last_ri, &uci_cfg.cqi);
|
||||
}
|
||||
|
||||
// Get pending ACKs from PDSCH
|
||||
srslte_dl_sf_cfg_t dl_sf_cfg = {};
|
||||
dl_sf_cfg.tti = tti;
|
||||
const srslte_cell_t& cell = cell_cfg_list->at(ue.cell_info[0].enb_cc_idx).cell;
|
||||
srslte_pdsch_ack_t ack_info = ue.pdsch_ack[TTIMOD(tti)];
|
||||
ack_info.is_pusch_available = is_pusch_available;
|
||||
srslte_enb_dl_gen_ack(&cell, &dl_sf_cfg, &ack_info, &uci_cfg);
|
||||
srslte_dl_sf_cfg_t dl_sf_cfg = {};
|
||||
dl_sf_cfg.tti = tti;
|
||||
srslte_pdsch_ack_t& pdsch_ack = ue.pdsch_ack[TTIMOD(tti)];
|
||||
pdsch_ack.is_pusch_available = is_pusch_available;
|
||||
srslte_enb_dl_gen_ack(&pcell, &dl_sf_cfg, &pdsch_ack, &uci_cfg);
|
||||
uci_required |= (srslte_uci_cfg_total_ack(&uci_cfg) > 0);
|
||||
|
||||
// Return whether UCI needs to be decoded
|
||||
|
@ -468,15 +471,17 @@ void phy_ue_db::send_uci_data(uint32_t tti,
|
|||
|
||||
// Get ACK info
|
||||
srslte_pdsch_ack_t& pdsch_ack = ue.pdsch_ack[TTIMOD(tti)];
|
||||
srslte_enb_dl_get_ack(&cell_cfg_list->at(ue.cell_info[0].enb_cc_idx).cell, &uci_value, &pdsch_ack);
|
||||
srslte_enb_dl_get_ack(&cell_cfg_list->at(ue.cell_info[0].enb_cc_idx).cell, &uci_cfg, &uci_value, &pdsch_ack);
|
||||
|
||||
// Iterate over the ACK information
|
||||
for (uint32_t scell_idx = 0; scell_idx < SRSLTE_MAX_CARRIERS; scell_idx++) {
|
||||
const srslte_pdsch_ack_cc_t& pdsch_ack_cc = pdsch_ack.cc[scell_idx];
|
||||
for (uint32_t m = 0; m < pdsch_ack_cc.M; m++) {
|
||||
if (pdsch_ack_cc.m[m].present) {
|
||||
for (uint32_t tb = 0; tb < pdsch_ack_cc.m[m].k; tb++) {
|
||||
stack->ack_info(tti, rnti, ue.cell_info[scell_idx].enb_cc_idx, tb, pdsch_ack_cc.m[m].value[tb] == 1);
|
||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
|
||||
if (pdsch_ack_cc.m[m].value[tb] != 2) {
|
||||
stack->ack_info(tti, rnti, ue.cell_info[scell_idx].enb_cc_idx, tb, pdsch_ack_cc.m[m].value[tb] == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -511,12 +516,6 @@ void phy_ue_db::send_uci_data(uint32_t tti,
|
|||
stack->cqi_info(tti, rnti, cqi_cc_idx, cqi_value);
|
||||
}
|
||||
|
||||
// Rank indicator (TM3 and TM4)
|
||||
if (uci_cfg.cqi.ri_len) {
|
||||
stack->ri_info(tti, rnti, cqi_cc_idx, uci_value.ri);
|
||||
cqi_scell_info.last_ri = uci_value.ri;
|
||||
}
|
||||
|
||||
// Precoding Matrix indicator (TM4)
|
||||
if (uci_cfg.cqi.pmi_present) {
|
||||
uint8_t pmi_value = 0;
|
||||
|
@ -534,6 +533,12 @@ void phy_ue_db::send_uci_data(uint32_t tti,
|
|||
stack->pmi_info(tti, rnti, cqi_cc_idx, pmi_value);
|
||||
}
|
||||
}
|
||||
|
||||
// Rank indicator (TM3 and TM4)
|
||||
if (uci_cfg.cqi.ri_len) {
|
||||
stack->ri_info(tti, rnti, cqi_cc_idx, uci_value.ri);
|
||||
cqi_scell_info.last_ri = uci_value.ri;
|
||||
}
|
||||
}
|
||||
|
||||
void phy_ue_db::set_last_ul_tb(uint16_t rnti, uint32_t enb_cc_idx, uint32_t pid, srslte_ra_tb_t tb)
|
||||
|
|
|
@ -35,19 +35,62 @@ target_link_libraries(enb_phy_test
|
|||
|
||||
set(ENB_PHY_TEST_DURATION 128)
|
||||
|
||||
# Basic eNb PHY test:
|
||||
# eNb PHY test:
|
||||
# - Single carrier
|
||||
# - Transmission Mode 1
|
||||
# - 1 eNb cell/carrier (no carrier aggregation)
|
||||
# - maximum bandwidth 100
|
||||
add_test(enb_phy_test_base enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 )
|
||||
# - 100 PRB
|
||||
add_test(enb_phy_test_tm1 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=1)
|
||||
|
||||
# Five carrier aggregation using PUCCH3
|
||||
# - 6 eNb cell/carrier (only using 5 aggregated)
|
||||
# Single carrier TM2 eNb PHY test:
|
||||
# - Single carrier
|
||||
# - Transmission Mode 2
|
||||
# - 1 eNb cell/carrier (no carrier aggregation)
|
||||
# - 6 PRB
|
||||
add_test(enb_phy_test_tm2 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=2)
|
||||
|
||||
# Single carrier TM3 eNb PHY test:
|
||||
# - Single carrier
|
||||
# - Transmission Mode 3
|
||||
# - 1 eNb cell/carrier (no carrier aggregation)
|
||||
# - 6 PRB
|
||||
add_test(enb_phy_test_tm3 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=3)
|
||||
|
||||
# Single carrier eNb PHY test:
|
||||
# - Single carrier
|
||||
# - Transmission Mode 4
|
||||
# - 1 eNb cell/carrier (no carrier aggregation)
|
||||
# - 6 PRB
|
||||
add_test(enb_phy_test_tm4 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --cell.nof_prb=100 --tm=4)
|
||||
|
||||
# Five carrier aggregation using PUCCH3:
|
||||
# - 6 eNb cell/carrier
|
||||
# - Transmission Mode 1
|
||||
# - 5 Aggregated carriers
|
||||
# - 6 PRB
|
||||
# - PUCCH format 3 ACK/NACK feedback mode and more than 2 ACK/NACK bits in PUSCH
|
||||
add_test(enb_phy_test_ca_pucch3 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=3,4,0,1,2 --ack_mode=pucch3 --cell.nof_prb=6 )
|
||||
add_test(enb_phy_test_tm1_ca_pucch3 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=3,4,0,1,2 --ack_mode=pucch3 --cell.nof_prb=6 --tm=1)
|
||||
|
||||
# Two carrier aggregation using Channel Selection
|
||||
# - 6 eNb cell/carrier (only using 2 aggregated)
|
||||
# Five carrier aggregation using PUCCH3:
|
||||
# - 6 eNb cell/carrier
|
||||
# - Transmission Mode 4
|
||||
# - 5 Aggregated carriers
|
||||
# - 6 PRB
|
||||
# - PUCCH format 3 ACK/NACK feedback mode and more than 2 ACK/NACK bits in PUSCH
|
||||
add_test(enb_phy_test_tm4_ca_pucch3 enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=0,4,3,1,2 --ack_mode=pucch3 --cell.nof_prb=6 --tm=4)
|
||||
|
||||
# Two carrier aggregation using Channel Selection:
|
||||
# - 6 eNb cell/carrier
|
||||
# - Transmission Mode 1
|
||||
# - 2 Aggregated carriers
|
||||
# - 6 PRB
|
||||
# - PUCCH format 1b with Channel selection ACK/NACK feedback mode
|
||||
add_test(enb_phy_test_cs enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=5,4 --ack_mode=cs --cell.nof_prb=6 )
|
||||
add_test(enb_phy_test_tm1_ca_cs enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=5,4 --ack_mode=cs --cell.nof_prb=6 --tm=1)
|
||||
|
||||
# Two carrier aggregation using Channel Selection:
|
||||
# - 6 eNb cell/carrier
|
||||
# - Transmission Mode 4
|
||||
# - 2 Aggregated carriers
|
||||
# - 6 PRB
|
||||
# - PUCCH format 1b with Channel selection ACK/NACK feedback mode
|
||||
add_test(enb_phy_test_tm4_ca_cs enb_phy_test --duration=${ENB_PHY_TEST_DURATION} --nof_enb_cells=6 --ue_cell_list=1,5 --ack_mode=cs --cell.nof_prb=6 --tm=4)
|
||||
|
|
|
@ -255,19 +255,20 @@ typedef std::unique_ptr<dummy_radio> unique_dummy_radio_t;
|
|||
class dummy_stack : public srsenb::stack_interface_phy_lte
|
||||
{
|
||||
private:
|
||||
static constexpr float prob_dl_grant = 0.50f;
|
||||
static constexpr float prob_ul_grant = 0.10f;
|
||||
static constexpr uint32_t cfi = 2;
|
||||
static constexpr float prob_dl_grant = 0.50f;
|
||||
static constexpr float prob_ul_grant = 0.10f;
|
||||
static constexpr uint32_t cfi = 2;
|
||||
|
||||
srsenb::phy_cell_cfg_list_t phy_cell_cfg;
|
||||
std::mutex mutex;
|
||||
std::condition_variable cvar;
|
||||
srslte::log_filter log_h;
|
||||
srslte_softbuffer_tx_t softbuffer_tx = {};
|
||||
srslte_softbuffer_rx_t softbuffer_rx[SRSLTE_MAX_CARRIERS][SRSLTE_FDD_NOF_HARQ] = {};
|
||||
uint8_t* data = nullptr;
|
||||
uint16_t ue_rnti = 0;
|
||||
srslte_random_t random_gen = nullptr;
|
||||
srsenb::phy_cell_cfg_list_t phy_cell_cfg;
|
||||
srsenb::phy_interface_rrc_lte::phy_rrc_dedicated_list_t phy_rrc;
|
||||
std::mutex mutex;
|
||||
std::condition_variable cvar;
|
||||
srslte::log_filter log_h;
|
||||
srslte_softbuffer_tx_t softbuffer_tx = {};
|
||||
srslte_softbuffer_rx_t softbuffer_rx[SRSLTE_MAX_CARRIERS][SRSLTE_FDD_NOF_HARQ] = {};
|
||||
uint8_t* data = nullptr;
|
||||
uint16_t ue_rnti = 0;
|
||||
srslte_random_t random_gen = nullptr;
|
||||
|
||||
CALLBACK(sr_detected);
|
||||
CALLBACK(rach_detected);
|
||||
|
@ -290,7 +291,7 @@ private:
|
|||
uint32_t tti;
|
||||
uint32_t cc_idx;
|
||||
uint32_t tb_idx;
|
||||
uint32_t ack;
|
||||
bool ack;
|
||||
} tti_dl_info_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -322,14 +323,16 @@ private:
|
|||
uint32_t ul_riv = 0;
|
||||
|
||||
public:
|
||||
explicit dummy_stack(srsenb::phy_cfg_t& phy_cfg_,
|
||||
const std::string& log_level,
|
||||
uint16_t rnti_,
|
||||
std::vector<uint32_t>& active_cell_list_) :
|
||||
explicit dummy_stack(const srsenb::phy_cfg_t& phy_cfg_,
|
||||
const srsenb::phy_interface_rrc_lte::phy_rrc_dedicated_list_t& phy_rrc_,
|
||||
const std::string& log_level,
|
||||
uint16_t rnti_,
|
||||
std::vector<uint32_t>& active_cell_list_) :
|
||||
log_h("STACK"),
|
||||
ue_rnti(rnti_),
|
||||
random_gen(srslte_random_init(rnti_)),
|
||||
phy_cell_cfg(phy_cfg_.phy_cell_cfg),
|
||||
phy_rrc(phy_rrc_),
|
||||
active_cell_list(active_cell_list_)
|
||||
{
|
||||
log_h.set_level(log_level);
|
||||
|
@ -415,11 +418,17 @@ public:
|
|||
int ri_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t ri_value) override
|
||||
{
|
||||
notify_ri_info();
|
||||
|
||||
log_h.info("Received RI tti=%d; rnti=0x%x; cc_idx=%d; ri=%d;\n", tti, rnti, cc_idx, ri_value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int pmi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t pmi_value) override
|
||||
{
|
||||
notify_pmi_info();
|
||||
|
||||
log_h.info("Received PMI tti=%d; rnti=0x%x; cc_idx=%d; pmi=%d;\n", tti, rnti, cc_idx, pmi_value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
int cqi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t cqi_value) override
|
||||
|
@ -453,7 +462,7 @@ public:
|
|||
tti_dl_info_t tti_dl_info = {};
|
||||
tti_dl_info.tti = tti;
|
||||
tti_dl_info.cc_idx = cc_idx;
|
||||
tti_dl_info.tb_idx = 0;
|
||||
tti_dl_info.tb_idx = tb_idx;
|
||||
tti_dl_info.ack = ack;
|
||||
tti_dl_info_ack_queue.push(tti_dl_info);
|
||||
|
||||
|
@ -484,14 +493,25 @@ public:
|
|||
dl_sched_res[0].cfi = cfi;
|
||||
|
||||
// Iterate for each carrier
|
||||
uint32_t scell_idx = 0;
|
||||
for (uint32_t& cc_idx : active_cell_list) {
|
||||
auto& dl_sched = dl_sched_res[cc_idx];
|
||||
|
||||
// Required
|
||||
dl_sched.cfi = cfi;
|
||||
|
||||
// Default TB scheduling
|
||||
bool sched_tb[SRSLTE_MAX_TB] = {};
|
||||
|
||||
sched_tb[0] = srslte_random_bool(random_gen, prob_dl_grant);
|
||||
|
||||
// Schedule second TB for TM3 or TM4
|
||||
if (phy_rrc[scell_idx].phy_cfg.dl_cfg.tm == SRSLTE_TM3 or phy_rrc[scell_idx].phy_cfg.dl_cfg.tm == SRSLTE_TM4) {
|
||||
sched_tb[1] = srslte_random_bool(random_gen, prob_dl_grant);
|
||||
}
|
||||
|
||||
// Random decision on whether transmit or not
|
||||
bool sched = srslte_random_bool(random_gen, prob_dl_grant);
|
||||
bool sched = sched_tb[0] | sched_tb[1];
|
||||
|
||||
// RNTI needs to be valid
|
||||
sched &= (ue_rnti != 0);
|
||||
|
@ -511,18 +531,24 @@ public:
|
|||
dl_sched.pdsch[0].dci.type0_alloc.rbg_bitmask = 0xffffffff;
|
||||
dl_sched.pdsch[0].dci.rnti = ue_rnti;
|
||||
dl_sched.pdsch[0].dci.alloc_type = SRSLTE_RA_ALLOC_TYPE0;
|
||||
dl_sched.pdsch[0].dci.tb[0].cw_idx = 0;
|
||||
dl_sched.pdsch[0].dci.tb[0].mcs_idx = 27;
|
||||
dl_sched.pdsch[0].dci.tb[0].rv = 0;
|
||||
dl_sched.pdsch[0].dci.tb[0].ndi = false;
|
||||
dl_sched.pdsch[0].dci.tb[1].cw_idx = 1;
|
||||
dl_sched.pdsch[0].dci.tb[1].mcs_idx = 0;
|
||||
dl_sched.pdsch[0].dci.tb[1].rv = 1;
|
||||
dl_sched.pdsch[0].dci.tb[1].ndi = false;
|
||||
dl_sched.pdsch[0].data[0] = data;
|
||||
dl_sched.pdsch[0].data[1] = data;
|
||||
dl_sched.pdsch[0].dci.format = SRSLTE_DCI_FORMAT1;
|
||||
dl_sched.pdsch[0].dci.tpc_pucch = (location.ncce + 1) % SRSLTE_PUCCH_SIZE_AN_CS;
|
||||
dl_sched.pdsch[0].dci.tpc_pucch = (location.ncce) % SRSLTE_PUCCH_SIZE_AN_CS;
|
||||
|
||||
// Set DCI format depending on the transmission mode
|
||||
switch (phy_rrc[0].phy_cfg.dl_cfg.tm) {
|
||||
default:
|
||||
case SRSLTE_TM1:
|
||||
case SRSLTE_TM2:
|
||||
dl_sched.pdsch[0].dci.format = SRSLTE_DCI_FORMAT1;
|
||||
break;
|
||||
case SRSLTE_TM3:
|
||||
dl_sched.pdsch[0].dci.format = SRSLTE_DCI_FORMAT2A;
|
||||
break;
|
||||
case SRSLTE_TM4:
|
||||
dl_sched.pdsch[0].dci.format = SRSLTE_DCI_FORMAT2;
|
||||
break;
|
||||
}
|
||||
|
||||
// Push grant info in queue
|
||||
tti_dl_info_t tti_dl_info = {};
|
||||
|
@ -531,11 +557,34 @@ public:
|
|||
tti_dl_info.tb_idx = 0;
|
||||
tti_dl_info.ack = true;
|
||||
|
||||
// Push to queue
|
||||
tti_dl_info_sched_queue.push(tti_dl_info);
|
||||
// Schedule TB
|
||||
uint32_t cw_count = 0;
|
||||
for (uint32_t tb = 0; tb < SRSLTE_MAX_TB; tb++) {
|
||||
if (sched_tb[tb]) {
|
||||
log_h.debug("Transmitted DL grant tti=%d; rnti=0x%x; cc=%d; tb=%d;\n", tti, ue_rnti, cc_idx, tb);
|
||||
|
||||
// Create Grant with maximum safe MCS
|
||||
dl_sched.pdsch[0].dci.tb[tb].cw_idx = cw_count++;
|
||||
dl_sched.pdsch[0].dci.tb[tb].mcs_idx = 27;
|
||||
dl_sched.pdsch[0].dci.tb[tb].rv = 0;
|
||||
dl_sched.pdsch[0].dci.tb[tb].ndi = false;
|
||||
|
||||
// Push to queue
|
||||
tti_dl_info.tb_idx = tb;
|
||||
tti_dl_info_sched_queue.push(tti_dl_info);
|
||||
} else {
|
||||
// Create Grant with no TB
|
||||
dl_sched.pdsch[0].dci.tb[tb].cw_idx = 0;
|
||||
dl_sched.pdsch[0].dci.tb[tb].mcs_idx = 0;
|
||||
dl_sched.pdsch[0].dci.tb[tb].rv = 1;
|
||||
dl_sched.pdsch[0].dci.tb[tb].ndi = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dl_sched.nof_grants = 0;
|
||||
}
|
||||
|
||||
scell_idx++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -624,11 +673,8 @@ public:
|
|||
void set_sched_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) override { notify_set_sched_dl_tti_mask(); }
|
||||
void rl_failure(uint16_t rnti) override { notify_rl_failure(); }
|
||||
void rl_ok(uint16_t rnti) override { notify_rl_ok(); }
|
||||
void tti_clock() override
|
||||
{
|
||||
notify_tti_clock();
|
||||
}
|
||||
int run_tti()
|
||||
void tti_clock() override { notify_tti_clock(); }
|
||||
int run_tti()
|
||||
{
|
||||
// Check DL ACKs match with grants
|
||||
while (not tti_dl_info_ack_queue.empty()) {
|
||||
|
@ -700,6 +746,7 @@ private:
|
|||
std::vector<cf_t*> buffers = {};
|
||||
dummy_radio* radio = nullptr;
|
||||
uint32_t sf_len = 0;
|
||||
uint32_t nof_ports = 0;
|
||||
uint16_t rnti = 0;
|
||||
srslte_dl_sf_cfg_t sf_dl_cfg = {};
|
||||
srslte_ul_sf_cfg_t sf_ul_cfg = {};
|
||||
|
@ -707,6 +754,7 @@ private:
|
|||
uint8_t* tx_data = nullptr;
|
||||
srsenb::phy_interface_rrc_lte::phy_rrc_dedicated_list_t phy_rrc_cfg = {};
|
||||
srslte::log_filter log_h;
|
||||
std::map<uint32_t, uint32_t> last_ri = {};
|
||||
|
||||
public:
|
||||
dummy_ue(dummy_radio* _radio,
|
||||
|
@ -714,16 +762,19 @@ public:
|
|||
std::string log_level,
|
||||
uint16_t rnti_,
|
||||
const srsenb::phy_interface_rrc_lte::phy_rrc_dedicated_list_t& phy_rrc_cfg_) :
|
||||
radio(_radio), log_h("UE PHY", nullptr, true), phy_rrc_cfg(phy_rrc_cfg_)
|
||||
radio(_radio),
|
||||
log_h("UE PHY", nullptr, true),
|
||||
phy_rrc_cfg(phy_rrc_cfg_)
|
||||
{
|
||||
// Calculate subframe length
|
||||
sf_len = static_cast<uint32_t>(SRSLTE_SF_LEN_PRB(cell_list[0].cell.nof_prb));
|
||||
rnti = rnti_;
|
||||
nof_ports = cell_list[0].cell.nof_ports;
|
||||
sf_len = static_cast<uint32_t>(SRSLTE_SF_LEN_PRB(cell_list[0].cell.nof_prb));
|
||||
rnti = rnti_;
|
||||
|
||||
log_h.set_level(std::move(log_level));
|
||||
|
||||
// Initialise one buffer per eNb
|
||||
for (uint32_t i = 0; i < cell_list.size(); i++) {
|
||||
for (uint32_t i = 0; i < cell_list.size() * nof_ports; i++) {
|
||||
// Allocate buffers
|
||||
cf_t* buffer = srslte_vec_cf_malloc(sf_len);
|
||||
if (not buffer) {
|
||||
|
@ -747,7 +798,7 @@ public:
|
|||
|
||||
// Initialise UE DL
|
||||
if (srslte_ue_dl_init(
|
||||
ue_dl, &buffers[cc_idx], cell_list[cc_idx].cell.nof_prb, cell_list[cc_idx].cell.nof_ports)) {
|
||||
ue_dl, &buffers[cc_idx * nof_ports], cell_list[cc_idx].cell.nof_prb, cell_list[cc_idx].cell.nof_ports)) {
|
||||
ERROR("Initiating UE DL\n");
|
||||
}
|
||||
|
||||
|
@ -767,7 +818,7 @@ public:
|
|||
ue_ul_v.push_back(ue_ul);
|
||||
|
||||
// Initialise UE UL
|
||||
if (srslte_ue_ul_init(ue_ul, buffers[cc_idx], cell_list[cc_idx].cell.nof_prb)) {
|
||||
if (srslte_ue_ul_init(ue_ul, buffers[cc_idx * nof_ports], cell_list[cc_idx].cell.nof_prb)) {
|
||||
ERROR("Setting UE UL cell\n");
|
||||
}
|
||||
|
||||
|
@ -856,6 +907,11 @@ public:
|
|||
ue_dl_cfg.cfg.cqi_report.periodic_mode = SRSLTE_CQI_MODE_12;
|
||||
ue_dl_cfg.cfg.pdsch.rnti = rnti;
|
||||
|
||||
int report_ri_cc_idx = -1;
|
||||
if (last_ri.count(i)) {
|
||||
ue_dl_cfg.last_ri = last_ri[i];
|
||||
}
|
||||
|
||||
srslte_ue_dl_decode_fft_estimate(ue_dl_v[i], &sf_dl_cfg, &ue_dl_cfg);
|
||||
|
||||
// Get DL Grants
|
||||
|
@ -883,8 +939,14 @@ public:
|
|||
pdsch_ack.cc[i].m[0].resource.n_cce = dci_dl->location.ncce;
|
||||
pdsch_ack.cc[i].m[0].resource.grant_cc_idx = i;
|
||||
pdsch_ack.cc[i].m[0].resource.tpc_for_pucch = dci_dl->tpc_pucch;
|
||||
pdsch_ack.cc[i].m[0].value[0] = 1;
|
||||
pdsch_ack.cc[i].m[0].value[1] = 1;
|
||||
|
||||
for (uint32_t tb_idx = 0; tb_idx < SRSLTE_MAX_TB; tb_idx++) {
|
||||
if (ue_dl_cfg.cfg.pdsch.grant.tb[tb_idx].enabled) {
|
||||
pdsch_ack.cc[i].m[0].value[tb_idx] = 1;
|
||||
} else {
|
||||
pdsch_ack.cc[i].m[0].value[tb_idx] = 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pdsch_ack.cc[i].M = 1;
|
||||
pdsch_ack.cc[i].m[0].present = false;
|
||||
|
@ -892,6 +954,11 @@ public:
|
|||
|
||||
// Generate CQI periodic if required
|
||||
srslte_ue_dl_gen_cqi_periodic(ue_dl_v[i], &ue_dl_cfg, 0x0f, sf_ul_cfg.tti, &uci_data);
|
||||
|
||||
if (srslte_cqi_periodic_ri_send(&ue_dl_cfg.cfg.cqi_report, sf_ul_cfg.tti, ue_dl_v[i]->cell.frame_type) &&
|
||||
uci_data.cfg.cqi.ri_len) {
|
||||
uci_data.cfg.cqi.scell_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
return SRSLTE_SUCCESS;
|
||||
|
@ -945,6 +1012,10 @@ public:
|
|||
|
||||
// Generate Acknowledgements
|
||||
srslte_ue_dl_gen_ack(&ue_dl_v[i]->cell, &sf_dl_cfg, &pdsch_ack, &uci_data);
|
||||
|
||||
if (uci_data.cfg.cqi.ri_len) {
|
||||
last_ri[uci_data.cfg.cqi.scell_index] = uci_data.value.ri;
|
||||
}
|
||||
}
|
||||
|
||||
// Set UCI only for PCel
|
||||
|
@ -1000,20 +1071,44 @@ class phy_test_bench
|
|||
{
|
||||
public:
|
||||
struct args_t {
|
||||
uint16_t rnti = 0x1234;
|
||||
uint32_t duration = 10240;
|
||||
uint32_t nof_enb_cells = 1;
|
||||
srslte_cell_t cell = {};
|
||||
uint16_t rnti = 0x1234;
|
||||
uint32_t duration = 10240;
|
||||
uint32_t nof_enb_cells = 1;
|
||||
srslte_cell_t cell = {};
|
||||
std::string ue_cell_list_str = "0"; ///< First indicates PCell
|
||||
std::vector<uint32_t> ue_cell_list = {0};
|
||||
std::string ack_mode = "normal";
|
||||
std::string log_level = "none";
|
||||
|
||||
std::string ack_mode = "normal";
|
||||
std::string log_level = "none";
|
||||
uint32_t tm_u32 = 1;
|
||||
srslte_tm_t tm = SRSLTE_TM1;
|
||||
args_t()
|
||||
{
|
||||
cell.nof_prb = 6;
|
||||
cell.nof_ports = 1;
|
||||
}
|
||||
|
||||
// Initialises secondary parameters
|
||||
void init()
|
||||
{
|
||||
switch (tm_u32) {
|
||||
case 2:
|
||||
cell.nof_ports = 2;
|
||||
tm = SRSLTE_TM2;
|
||||
break;
|
||||
case 3:
|
||||
cell.nof_ports = 2;
|
||||
tm = SRSLTE_TM3;
|
||||
break;
|
||||
case 4:
|
||||
cell.nof_ports = 2;
|
||||
tm = SRSLTE_TM4;
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
cell.nof_ports = 1;
|
||||
tm = SRSLTE_TM1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -1068,29 +1163,41 @@ public:
|
|||
phy_cfg.prach_cnfg.prach_cfg_info.zero_correlation_zone_cfg = 5;
|
||||
|
||||
// Create base UE dedicated configuration
|
||||
srslte::phy_cfg_t dedicated = {};
|
||||
dedicated.ul_cfg.pucch.ack_nack_feedback_mode = srslte_string_ack_nack_feedback_mode(args.ack_mode.c_str());
|
||||
dedicated.ul_cfg.pucch.delta_pucch_shift = delta_pucch;
|
||||
dedicated.ul_cfg.pucch.n_rb_2 = 2;
|
||||
dedicated.ul_cfg.pucch.N_cs = 0;
|
||||
dedicated.ul_cfg.pucch.n_pucch_sr = 0;
|
||||
dedicated.ul_cfg.pucch.N_pucch_1 = N_pucch_1;
|
||||
dedicated.ul_cfg.pucch.n_pucch_2 = 5;
|
||||
dedicated.ul_cfg.pucch.simul_cqi_ack = true;
|
||||
dedicated.ul_cfg.pucch.sr_configured = true;
|
||||
dedicated.ul_cfg.pucch.I_sr = 5;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[0][0] = N_pucch_1 + delta_pucch * 1;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[1][0] = N_pucch_1 + delta_pucch * 2;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[2][0] = N_pucch_1 + delta_pucch * 3;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[3][0] = N_pucch_1 + delta_pucch * 4;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[0][1] = N_pucch_1 + delta_pucch * 2;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[1][1] = N_pucch_1 + delta_pucch * 3;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[2][1] = N_pucch_1 + delta_pucch * 4;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[3][1] = N_pucch_1 + delta_pucch * 1;
|
||||
srslte::phy_cfg_t dedicated = {};
|
||||
|
||||
// Configure DL
|
||||
dedicated.dl_cfg.tm = args.tm;
|
||||
|
||||
// Configure reporting
|
||||
dedicated.dl_cfg.cqi_report.periodic_configured = true;
|
||||
dedicated.dl_cfg.cqi_report.pmi_idx = 25;
|
||||
dedicated.dl_cfg.cqi_report.periodic_mode = SRSLTE_CQI_MODE_20;
|
||||
dedicated.ul_cfg.pusch.uci_offset.I_offset_ack = 7;
|
||||
|
||||
if (args.tm == SRSLTE_TM3 or args.tm == SRSLTE_TM4) {
|
||||
dedicated.dl_cfg.cqi_report.ri_idx_present = true;
|
||||
dedicated.dl_cfg.cqi_report.ri_idx = 483; // Every 8 CQI/PMI report, schedule an RI report
|
||||
}
|
||||
|
||||
// Configure UL Resources
|
||||
dedicated.ul_cfg.pucch.ack_nack_feedback_mode = srslte_string_ack_nack_feedback_mode(args.ack_mode.c_str());
|
||||
dedicated.ul_cfg.pucch.delta_pucch_shift = delta_pucch;
|
||||
dedicated.ul_cfg.pucch.n_rb_2 = 2;
|
||||
dedicated.ul_cfg.pucch.N_cs = 0;
|
||||
dedicated.ul_cfg.pucch.n_pucch_sr = 0;
|
||||
dedicated.ul_cfg.pucch.N_pucch_1 = N_pucch_1;
|
||||
dedicated.ul_cfg.pucch.n_pucch_2 = 5;
|
||||
dedicated.ul_cfg.pucch.simul_cqi_ack = true;
|
||||
dedicated.ul_cfg.pucch.sr_configured = true;
|
||||
dedicated.ul_cfg.pucch.I_sr = 5;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[0][0] = N_pucch_1 + 2;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[1][0] = N_pucch_1 + 3;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[2][0] = N_pucch_1 + 4;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[3][0] = N_pucch_1 + 5;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[0][1] = N_pucch_1 + 3;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[1][1] = N_pucch_1 + 4;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[2][1] = N_pucch_1 + 5;
|
||||
dedicated.ul_cfg.pucch.n1_pucch_an_cs[3][1] = N_pucch_1 + 6;
|
||||
dedicated.ul_cfg.pusch.uci_offset.I_offset_ack = 7;
|
||||
|
||||
// Configure UE PHY
|
||||
std::array<bool, SRSLTE_MAX_CARRIERS> activation = {}; ///< Activation/Deactivation vector
|
||||
|
@ -1111,10 +1218,11 @@ public:
|
|||
}
|
||||
|
||||
/// Create Radio instance
|
||||
radio = unique_dummy_radio_t(new dummy_radio(args.nof_enb_cells, args.cell.nof_prb, args.log_level));
|
||||
radio = unique_dummy_radio_t(
|
||||
new dummy_radio(args.nof_enb_cells * args.cell.nof_ports, args.cell.nof_prb, args.log_level));
|
||||
|
||||
/// Create Dummy Stack isntance
|
||||
stack = unique_dummy_stack_t(new dummy_stack(phy_cfg, args.log_level, args.rnti, args.ue_cell_list));
|
||||
stack = unique_dummy_stack_t(new dummy_stack(phy_cfg, phy_rrc_cfg, args.log_level, args.rnti, args.ue_cell_list));
|
||||
|
||||
/// eNb PHY initialisation instance
|
||||
enb_phy = unique_srsenb_phy_t(new srsenb::phy(&logger_stdout));
|
||||
|
@ -1171,6 +1279,7 @@ int parse_args(int argc, char** argv, phy_test_bench::args_t& args)
|
|||
("ack_mode", bpo::value<std::string>(&args.ack_mode), "HARQ ACK/NACK mode: normal, pucch3, cs")
|
||||
("cell.nof_prb", bpo::value<uint32_t>(&args.cell.nof_prb)->default_value(args.cell.nof_prb), "eNb Cell/Carrier bandwidth")
|
||||
("cell.nof_ports", bpo::value<uint32_t>(&args.cell.nof_ports)->default_value(args.cell.nof_ports), "eNb Cell/Carrier number of ports")
|
||||
("tm", bpo::value<uint32_t>(&args.tm_u32)->default_value(args.tm_u32), "Transmission mode")
|
||||
;
|
||||
|
||||
options.add(common).add_options()("help", "Show this message");
|
||||
|
@ -1216,6 +1325,9 @@ int main(int argc, char** argv)
|
|||
// Parse arguments
|
||||
TESTASSERT(parse_args(argc, argv, test_args) == SRSLTE_SUCCESS);
|
||||
|
||||
// Initialize secondary parameters
|
||||
test_args.init();
|
||||
|
||||
// Create Test Bench
|
||||
unique_phy_test_bench test_bench = unique_phy_test_bench(new phy_test_bench(test_args));
|
||||
|
||||
|
|
Loading…
Reference in New Issue