Added UE Mode 3-1 aperiodic reporting

master
Xavier Arteaga 7 years ago
parent cdb788617b
commit b084b153cf

@ -55,13 +55,22 @@ typedef struct {
} srslte_cqi_periodic_cfg_t;
/* Table 5.2.2.6.2-1: Fields for channel quality information feedback for higher layer configured subband
CQI reports
(transmission mode 1, transmission mode 2, transmission mode 3, transmission mode 7 and
transmission mode 8 configured without PMI/RI reporting). */
CQI reports (transmission mode 1, transmission mode 2, transmission mode 3, transmission mode 7 and
transmission mode 8 configured without PMI/RI reporting). */
/* Table 5.2.2.6.2-2: Fields for channel quality information (CQI) feedback for higher layer configured subband CQI
reports (transmission mode 4, transmission mode 5 and transmission mode 6). */
typedef struct SRSLTE_API {
uint8_t wideband_cqi; // 4-bit width
uint32_t subband_diff_cqi; // 2N-bit width
uint32_t N;
uint8_t wideband_cqi_cw0; // 4-bit width
uint32_t subband_diff_cqi_cw0; // 2N-bit width
uint8_t wideband_cqi_cw1; // if RI > 1 then 4-bit width otherwise 0-bit width
uint32_t subband_diff_cqi_cw1; // if RI > 1 then 2N-bit width otherwise 0-bit width
uint32_t pmi; // if RI > 1 then 2-bit width otherwise 1-bit width
uint32_t N;
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
} srslte_cqi_hl_subband_t;
/* Table 5.2.2.6.3-1: Fields for channel quality information feedback for UE selected subband CQI

@ -73,6 +73,7 @@ typedef struct SRSLTE_API {
uint8_t uci_ack; // 1st codeword bit for HARQ-ACK
uint8_t uci_ack_2; // 2st codeword bit for HARQ-ACK
uint32_t uci_ack_len;
bool ri_periodic_report;
bool scheduling_request;
bool channel_selection;
bool cqi_ack;

@ -44,11 +44,38 @@
*******************************************************/
int srslte_cqi_hl_subband_pack(srslte_cqi_hl_subband_t *msg, uint8_t buff[SRSLTE_CQI_MAX_BITS])
{
uint8_t *body_ptr = buff;
srslte_bit_unpack(msg->wideband_cqi, &body_ptr, 4);
srslte_bit_unpack(msg->subband_diff_cqi, &body_ptr, 2*msg->N);
return 4+2*msg->N;
uint8_t *body_ptr = buff;
uint32_t bit_count = 0;
/* Unpack codeword 0, common for 3GPP 36.212 Tables 5.2.2.6.2-1 and 5.2.2.6.2-2 */
srslte_bit_unpack(msg->wideband_cqi_cw0, &body_ptr, 4);
srslte_bit_unpack(msg->subband_diff_cqi_cw0, &body_ptr, 2*msg->N);
bit_count += 4+2*msg->N;
/* Unpack codeword 1, 3GPP 36.212 Table 5.2.2.6.2-2 */
if (msg->rank_is_not_one) {
srslte_bit_unpack(msg->wideband_cqi_cw1, &body_ptr, 4);
srslte_bit_unpack(msg->subband_diff_cqi_cw1, &body_ptr, 2*msg->N);
bit_count += 4+2*msg->N;
}
/* If PMI is present, unpack it */
if (msg->pmi_present) {
if (msg->four_antenna_ports) {
srslte_bit_unpack(msg->pmi, &body_ptr, 4);
bit_count += 4;
} else {
if (msg->rank_is_not_one) {
srslte_bit_unpack(msg->pmi, &body_ptr, 1);
bit_count += 1;
} else {
srslte_bit_unpack(msg->pmi, &body_ptr, 2);
bit_count += 2;
}
}
}
return bit_count;
}
int srslte_cqi_ue_subband_pack(srslte_cqi_ue_subband_t *msg, uint8_t buff[SRSLTE_CQI_MAX_BITS])
@ -98,11 +125,37 @@ int srslte_cqi_value_pack(srslte_cqi_value_t *value, uint8_t buff[SRSLTE_CQI_MAX
int srslte_cqi_hl_subband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_hl_subband_t *msg)
{
uint8_t *body_ptr = buff;
msg->wideband_cqi = srslte_bit_pack(&body_ptr, 4);
msg->subband_diff_cqi = srslte_bit_pack(&body_ptr, 2*msg->N);
return 4+2*msg->N;
uint8_t *body_ptr = buff;
uint32_t bit_count = 0;
msg->wideband_cqi_cw0 = (uint8_t) srslte_bit_pack(&body_ptr, 4);
msg->subband_diff_cqi_cw0 = srslte_bit_pack(&body_ptr, 2*msg->N);
bit_count += 4+2*msg->N;
/* Unpack codeword 1, 3GPP 36.212 Table 5.2.2.6.2-2 */
if (msg->rank_is_not_one) {
msg->wideband_cqi_cw1 = (uint8_t) srslte_bit_pack(&body_ptr, 4);
msg->subband_diff_cqi_cw1 = srslte_bit_pack(&body_ptr, 2*msg->N);
bit_count += 4+2*msg->N;
}
/* If PMI is present, unpack it */
if (msg->pmi_present) {
if (msg->four_antenna_ports) {
msg->pmi = (uint8_t) srslte_bit_pack(&body_ptr, 4);
bit_count += 4;
} else {
if (msg->rank_is_not_one) {
msg->pmi = (uint8_t) srslte_bit_pack(&body_ptr, 1);
bit_count += 1;
} else {
msg->pmi = (uint8_t) srslte_bit_pack(&body_ptr, 2);
bit_count += 2;
}
}
}
return bit_count;
}
int srslte_cqi_ue_subband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_ue_subband_t *msg)

@ -173,7 +173,7 @@ srslte_pucch_format_t srslte_pucch_get_format(srslte_uci_data_t *uci_data, srslt
{
srslte_pucch_format_t format = SRSLTE_PUCCH_FORMAT_ERROR;
// No CQI data
if (uci_data->uci_cqi_len == 0) {
if (uci_data->uci_cqi_len == 0 && uci_data->uci_ri_len == 0) {
// 1-bit ACK + optional SR
if (uci_data->uci_ack_len == 1) {
format = SRSLTE_PUCCH_FORMAT_1A;

@ -684,6 +684,7 @@ int srslte_ue_dl_ri_pmi_select(srslte_ue_dl_t *q, uint8_t *ri, uint8_t *pmi, flo
}
/* Set RI */
q->ri = best_ri;
if (ri != NULL) {
*ri = best_ri;
}
@ -719,9 +720,10 @@ int srslte_ue_dl_ri_select(srslte_ue_dl_t *q, uint8_t *ri, float *cn) {
*cn = _cn;
}
q->ri = (uint8_t)((_cn < 17.0f)? 1:0);
/* Set rank indicator */
if (!ret && ri) {
*ri = (uint8_t)((_cn < 17.0f)? 1:0);
*ri = (uint8_t) q->ri;
}
return ret;

@ -273,21 +273,33 @@ int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant,
void pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t format,
uint8_t pucch_bits[SRSLTE_PUCCH_MAX_BITS],
uint8_t pucch2_bits[SRSLTE_PUCCH_MAX_BITS])
{
{
uint8_t uci_buffer[SRSLTE_CQI_MAX_BITS];
uint8_t uci_buffer_len = 0;
if (format == SRSLTE_PUCCH_FORMAT_1A || format == SRSLTE_PUCCH_FORMAT_1B) {
pucch_bits[0] = uci_data->uci_ack;
pucch_bits[1] = uci_data->uci_ack_2; // this will be ignored in format 1a
}
if (format >= SRSLTE_PUCCH_FORMAT_2) {
/* Append Differential CQI */
memcpy(&uci_data->uci_cqi[uci_data->uci_cqi_len], uci_data->uci_dif_cqi, uci_data->uci_dif_cqi_len);
uci_data->uci_cqi_len += uci_data->uci_dif_cqi_len;
/* Put RI (goes alone) */
if (uci_data->ri_periodic_report) {
uci_buffer[0] = uci_data->uci_ri; // It assumes only 1 bit of RI
uci_buffer_len += uci_data->uci_ri_len;
} else {
/* Append CQI */
memcpy(&uci_buffer[uci_buffer_len], uci_data->uci_cqi, uci_data->uci_cqi_len);
uci_buffer_len += uci_data->uci_cqi_len;
/* Append PMI */
memcpy(&uci_data->uci_cqi[uci_data->uci_cqi_len], uci_data->uci_pmi, uci_data->uci_pmi_len);
uci_data->uci_cqi_len += uci_data->uci_pmi_len;
/* Append Differential CQI */
memcpy(&uci_buffer[uci_buffer_len], uci_data->uci_dif_cqi, uci_data->uci_dif_cqi_len);
uci_buffer_len += uci_data->uci_dif_cqi_len;
srslte_uci_encode_cqi_pucch(uci_data->uci_cqi, uci_data->uci_cqi_len, pucch_bits);
/* Append PMI */
memcpy(&uci_buffer[uci_buffer_len], uci_data->uci_pmi, uci_data->uci_pmi_len);
uci_buffer_len += uci_data->uci_pmi_len;
}
srslte_uci_encode_cqi_pucch(uci_buffer, uci_buffer_len, pucch_bits);
if (format > SRSLTE_PUCCH_FORMAT_2) {
pucch2_bits[0] = uci_data->uci_ack;
pucch2_bits[1] = uci_data->uci_ack_2; // this will be ignored in format 2a

@ -445,7 +445,7 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch)
if (ue_db[rnti].cqi_en) {
wideband_cqi_value = cqi_value.wideband.wideband_cqi;
} else if (grants[i].grant.cqi_request) {
wideband_cqi_value = cqi_value.subband_hl.wideband_cqi;
wideband_cqi_value = cqi_value.subband_hl.wideband_cqi_cw0;
}
snprintf(cqi_str, 64, ", cqi=%d", wideband_cqi_value);
}

@ -74,7 +74,8 @@ private:
/* Internal methods */
bool extract_fft_and_pdcch_llr();
void compute_ri();
/* ... for DL */
bool decode_pdcch_ul(mac_interface_phy::mac_grant_t *grant);
bool decode_pdcch_dl(mac_interface_phy::mac_grant_t *grant);

@ -255,39 +255,6 @@ void phch_worker::work_imp()
if (dl_action.generate_ack) {
set_uci_ack(dl_ack, dl_mac_grant.tb_en);
}
/* Select Rank Indicator by computing Condition Number */
if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_3) {
if (ue_dl.nof_rx_antennas > 1) {
/* If 2 ort more receiving antennas, select RI */
float cn = 0.0f;
srslte_ue_dl_ri_select(&ue_dl, &uci_data.uci_ri, &cn);
uci_data.uci_ri_len = 1;
} else {
/* If only one receiving antenna, force RI for 1 layer */
uci_data.uci_ri = 0;
uci_data.uci_ri_len = 1;
Warning("Only one receiving antenna with TM3. Forcing RI=1 layer.\n");
}
} else if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4){
float sinr = 0.0f;
uint8 packed_pmi = 0;
srslte_ue_dl_ri_pmi_select(&ue_dl, &uci_data.uci_ri, &packed_pmi, &sinr);
srslte_bit_unpack_vector(&packed_pmi, uci_data.uci_pmi, 2);
uci_data.uci_ri_len = 1;
if (uci_data.uci_ri == 0) {
uci_data.uci_pmi_len = 2;
uci_data.uci_dif_cqi_len = 0;
} else {
uci_data.uci_pmi_len = 1;
uci_data.uci_dif_cqi_len = 3;
}
/* If only one antenna in TM4 print limitation warning */
if (ue_dl.nof_rx_antennas < 2) {
Warning("Only one receiving antenna with TM4. Forcing RI=1 layer (PMI=%d).\n", packed_pmi);
}
}
}
}
@ -343,7 +310,7 @@ void phch_worker::work_imp()
phy->set_pending_ack(TTI_RX_ACK(tti), ue_ul.pusch_cfg.grant.n_prb_tilde[0], ul_action.phy_grant.ul.ncs_dmrs);
}
} else if (dl_action.generate_ack || uci_data.scheduling_request || uci_data.uci_cqi_len > 0) {
} else if (dl_action.generate_ack || uci_data.scheduling_request || uci_data.uci_cqi_len > 0 || uci_data.uci_ri_len > 0) {
encode_pucch();
signal_ready = true;
} else if (srs_is_ready_to_send()) {
@ -392,6 +359,42 @@ void phch_worker::work_imp()
#endif
}
void phch_worker::compute_ri() {
if (uci_data.uci_ri_len > 0) {
/* Do nothing */
} else if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_3) {
if (ue_dl.nof_rx_antennas > 1) {
/* If 2 ort more receiving antennas, select RI */
float cn = 0.0f;
srslte_ue_dl_ri_select(&ue_dl, &uci_data.uci_ri, &cn);
Info("RI select %d layers, κ=%fdB\n", uci_data.uci_ri + 1, cn);
} else {
/* If only one receiving antenna, force RI for 1 layer */
uci_data.uci_ri = 0;
Warning("Only one receiving antenna with TM3. Forcing RI=1 layer.\n");
}
uci_data.uci_ri_len = 1;
} else if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) {
float sinr = 0.0f;
uint8 packed_pmi = 0;
srslte_ue_dl_ri_pmi_select(&ue_dl, &uci_data.uci_ri, &packed_pmi, &sinr);
if (uci_data.uci_ri == 0) {
uci_data.uci_pmi_len = 2;
uci_data.uci_dif_cqi_len = 0;
} else {
uci_data.uci_pmi_len = 1;
uci_data.uci_dif_cqi_len = 3;
}
srslte_bit_unpack_vector(&packed_pmi, uci_data.uci_pmi, uci_data.uci_pmi_len);
Info("ri=%d; pmi=%d; SINR=%.1fdB\n", ue_dl.ri, ue_dl.pmi[ue_dl.ri], 10*log10f(ue_dl.sinr[ue_dl.ri][ue_dl.pmi[ue_dl.ri]]));
/* If only one antenna in TM4 print limitation warning */
if (ue_dl.nof_rx_antennas < 2) {
Warning("Only one receiving antenna with TM4. Forcing RI=1 layer (PMI=%d).\n", packed_pmi);
}
uci_data.uci_ri_len = 1;
}
}
bool phch_worker::extract_fft_and_pdcch_llr() {
bool decode_pdcch = false;
@ -797,21 +800,15 @@ void phch_worker::reset_uci()
void phch_worker::set_uci_ack(bool ack[SRSLTE_MAX_CODEWORDS], bool tb_en[SRSLTE_MAX_CODEWORDS])
{
uint32_t nof_tb = 0;
if (tb_en[0]) {
uci_data.uci_ack = (uint8_t) ((ack[0]) ? 1 : 0);
nof_tb = 1;
} else {
uci_data.uci_ack = 1;
}
if (tb_en[1]) {
uci_data.uci_ack_2 = (uint8_t) ((ack[1]) ? 1 : 0);
nof_tb = 2;
/* Map ACK according to 3GPP 36.212 clause 5.2.3.1 */
uint32_t nof_ack = 0;
for (uint32_t tb = 0; tb < SRSLTE_MAX_CODEWORDS; tb++) {
if (tb_en[tb]) {
((nof_ack == 0)?uci_data.uci_ack:uci_data.uci_ack_2) = (uint8_t)(ack[tb]?1:0);
nof_ack++;
}
}
uci_data.uci_ack_len = nof_tb;
uci_data.uci_ack_len = nof_ack;
}
void phch_worker::set_uci_sr()
@ -836,14 +833,9 @@ void phch_worker::set_uci_periodic_cqi()
if (period_cqi.configured && rnti_is_set) {
if (period_cqi.ri_idx_present && srslte_ri_send(period_cqi.pmi_idx, period_cqi.ri_idx, TTI_TX(tti))) {
if (uci_data.uci_ri_len) {
uci_data.uci_cqi[0] = uci_data.uci_ri;
uci_data.uci_cqi_len = uci_data.uci_ri_len;
uci_data.uci_ri_len = 0;
uci_data.uci_dif_cqi_len = 0;
uci_data.uci_pmi_len = 0;
Info("PUCCH: Periodic RI=%d\n", uci_data.uci_cqi[0]);
}
compute_ri();
uci_data.ri_periodic_report = true;
Info("PUCCH: Periodic RI=%d\n", uci_data.uci_ri);
} else if (srslte_cqi_send(period_cqi.pmi_idx, TTI_TX(tti))) {
srslte_cqi_value_t cqi_report;
if (period_cqi.format_is_subband) {
@ -865,6 +857,16 @@ void phch_worker::set_uci_periodic_cqi()
}
Info("PUCCH: Periodic CQI=%d, SNR=%.1f dB\n", cqi_report.wideband.wideband_cqi, phy->avg_snr_db);
}
if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) {
if (ue_dl.ri == 0) {
uci_data.uci_pmi_len = 2;
} else {
uci_data.uci_pmi_len = 1;
uci_data.uci_dif_cqi_len = 3;
}
uint8_t *ptr = uci_data.uci_pmi;
srslte_bit_unpack(ue_dl.pmi[ue_dl.ri], &ptr, uci_data.uci_pmi_len);
}
uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
rar_cqi_request = false;
}
@ -886,18 +888,71 @@ void phch_worker::set_uci_aperiodic_cqi()
reported RI. For other transmission modes they are reported conditioned on rank 1.
*/
if (rnti_is_set) {
srslte_cqi_value_t cqi_report;
srslte_cqi_value_t cqi_report = {0};
cqi_report.type = SRSLTE_CQI_TYPE_SUBBAND_HL;
cqi_report.subband_hl.wideband_cqi = srslte_cqi_from_snr(phy->avg_snr_db);
cqi_report.subband_hl.wideband_cqi_cw0 = srslte_cqi_from_snr(phy->avg_snr_db);
// TODO: implement subband CQI properly
cqi_report.subband_hl.subband_diff_cqi = 0; // Always report zero offset on all subbands
cqi_report.subband_hl.subband_diff_cqi_cw0 = 0; // Always report zero offset on all subbands
cqi_report.subband_hl.N = (cell.nof_prb > 7) ? srslte_cqi_hl_get_no_subbands(cell.nof_prb) : 0;
Info("PUSCH: Aperiodic CQI=%d, SNR=%.1f dB, for %d subbands\n", cqi_report.wideband.wideband_cqi, phy->avg_snr_db, cqi_report.subband_hl.N);
uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
}
break;
case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM31:
/* only Higher Layer-configured subband feedback support right now, according to TS36.213 section 7.2.1
- A single precoding matrix is selected from the codebook subset assuming transmission on set S subbands
- A UE shall report one subband CQI value per codeword for each set S subband which are calculated assuming
the use of the single precoding matrix in all subbands and assuming transmission in the corresponding
subband.
- A UE shall report a wideband CQI value per codeword which is calculated assuming the use of the single
precoding matrix in all subbands and transmission on set S subbands
- The UE shall report the single selected precoding matrix indicator.
- For transmission mode 4 the reported PMI and CQI values are calculated conditioned on the reported RI. For
other transmission modes they are reported conditioned on rank 1.
*/
if (rnti_is_set) {
/* Compute RI, PMI and SINR */
compute_ri();
/* Select RI, PMI and SINR */
uint32_t ri = ue_dl.ri; // Select RI (0: 1 layer, 1: 2 layer, otherwise: not implemented)
uint32_t pmi = ue_dl.pmi[ri]; // Select PMI
float sinr_db = 10 * log10(ue_dl.sinr[ri][pmi]);
/* Fill CQI Report */
srslte_cqi_value_t cqi_report = {0};
cqi_report.type = SRSLTE_CQI_TYPE_SUBBAND_HL;
cqi_report.subband_hl.wideband_cqi_cw0 = srslte_cqi_from_snr(sinr_db);
cqi_report.subband_hl.subband_diff_cqi_cw0 = 0; // Always report zero offset on all subbands
if (ri > 0) {
cqi_report.subband_hl.rank_is_not_one = true;
cqi_report.subband_hl.wideband_cqi_cw1 = srslte_cqi_from_snr(sinr_db);
cqi_report.subband_hl.subband_diff_cqi_cw1 = 0; // Always report zero offset on all subbands
}
cqi_report.subband_hl.pmi = pmi;
cqi_report.subband_hl.pmi_present = true;
cqi_report.subband_hl.four_antenna_ports = (cell.nof_ports == 4);
// TODO: implement subband CQI properly
cqi_report.subband_hl.N = (uint32_t) ((cell.nof_prb > 7) ? srslte_cqi_hl_get_no_subbands(cell.nof_prb) : 0);
if (cqi_report.subband_hl.rank_is_not_one) {
Info("PUSCH: Aperiodic ri~1, CQI=%02d/%02d, SINR=%2.1f/%2.1fdB, pmi=%d for %d subbands\n",
cqi_report.subband_hl.wideband_cqi_cw0, cqi_report.subband_hl.wideband_cqi_cw1,
sinr_db, sinr_db, pmi, cqi_report.subband_hl.N);
} else {
Info("PUSCH: Aperiodic ri=1, CQI=%d/%d, SINR=%2.1f dB, for %d subbands\n",
cqi_report.wideband.wideband_cqi,
phy->avg_snr_db, cqi_report.subband_hl.N);
}
uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi);
}
break;
default:
Warning("Received CQI request but mode %s is not supported\n",
liblte_rrc_cqi_report_mode_aperiodic_text[phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic]);
@ -979,7 +1034,7 @@ void phch_worker::encode_pucch()
char timestr[64];
timestr[0]='\0';
if (uci_data.scheduling_request || uci_data.uci_ack_len > 0 || uci_data.uci_cqi_len > 0)
if (uci_data.scheduling_request || uci_data.uci_ack_len > 0 || uci_data.uci_cqi_len > 0 || uci_data.uci_ri_len > 0)
{
// Drop CQI if there is collision with ACK

Loading…
Cancel
Save