From 9ffdb1e62da2ed1eaf47dcd6c33386c54dd0bf0c Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 11 Jan 2018 14:37:01 +0100 Subject: [PATCH] Refactored PMI/CQI/RI reporting --- lib/include/srslte/phy/phch/cqi.h | 13 ++++ lib/include/srslte/phy/phch/uci.h | 4 -- lib/src/phy/enb/enb_ul.c | 13 +--- lib/src/phy/phch/cqi.c | 75 ++++++++++++++++++++-- lib/src/phy/phch/pusch.c | 2 - lib/src/phy/ue/ue_ul.c | 21 ++---- srsenb/src/phy/phch_worker.cc | 54 ++++++++-------- srsue/hdr/phy/phch_worker.h | 2 +- srsue/src/phy/phch_worker.cc | 102 ++++++++++++++---------------- 9 files changed, 162 insertions(+), 124 deletions(-) diff --git a/lib/include/srslte/phy/phch/cqi.h b/lib/include/srslte/phy/phch/cqi.h index 1560ef92c..f1f7eb03c 100644 --- a/lib/include/srslte/phy/phch/cqi.h +++ b/lib/include/srslte/phy/phch/cqi.h @@ -90,8 +90,19 @@ typedef struct SRSLTE_API { transmission mode 8 configured without PMI/RI reporting). This is for PUCCH Format 2 reports */ + +/* Table 5.2.3.3.1-2: UCI fields for channel quality and precoding information (CQI/PMI) feedback for +wideband reports (transmission mode 4, transmission mode 5 and transmission mode 6) +This is for PUCCH Format 2 reports +*/ + typedef struct SRSLTE_API { uint8_t wideband_cqi; // 4-bit width + uint8_t spatial_diff_cqi; // If Rank==1 then it is 0-bit width otherwise it is 3-bit width + uint8_t pmi; + 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_format2_wideband_t; typedef struct SRSLTE_API { @@ -165,4 +176,6 @@ SRSLTE_API int srslte_cqi_hl_get_subband_size(int num_prbs); SRSLTE_API int srslte_cqi_hl_get_no_subbands(int num_prbs); +SRSLTE_API void srslte_cqi_to_str(const uint8_t *cqi_value, int cqi_len, char *str, int str_len); + #endif // CQI_ diff --git a/lib/include/srslte/phy/phch/uci.h b/lib/include/srslte/phy/phch/uci.h index 6ea00c5d1..ebbd98238 100644 --- a/lib/include/srslte/phy/phch/uci.h +++ b/lib/include/srslte/phy/phch/uci.h @@ -64,10 +64,6 @@ typedef struct SRSLTE_API { typedef struct SRSLTE_API { uint8_t uci_cqi[SRSLTE_CQI_MAX_BITS]; uint32_t uci_cqi_len; - uint8_t uci_dif_cqi[SRSLTE_DIF_CQI_MAX_BITS]; - uint32_t uci_dif_cqi_len; - uint8_t uci_pmi[SRSLTE_PMI_MAX_BITS]; - uint8_t uci_pmi_len; uint8_t uci_ri; // Only 1-bit supported for RI uint32_t uci_ri_len; uint8_t uci_ack; // 1st codeword bit for HARQ-ACK diff --git a/lib/src/phy/enb/enb_ul.c b/lib/src/phy/enb/enb_ul.c index 8ea5dd3e4..0c561ef5a 100644 --- a/lib/src/phy/enb/enb_ul.c +++ b/lib/src/phy/enb/enb_ul.c @@ -292,9 +292,7 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint16_t rnti, uint8_t pucch_bits[SRSLTE_PUCCH_MAX_BITS]; if (q->users[rnti]) { - uint32_t nof_uci_bits = uci_data->ri_periodic_report ? uci_data->uci_ri_len : (uci_data->uci_cqi_len + - uci_data->uci_dif_cqi_len + - uci_data->uci_pmi_len); + uint32_t nof_uci_bits = uci_data->ri_periodic_report ? uci_data->uci_ri_len : (uci_data->uci_cqi_len); int ret_val = get_pucch(q, rnti, pdcch_n_cce, sf_rx, uci_data, pucch_bits, nof_uci_bits); // If we are looking for SR and ACK at the same time and ret=0, means there is no SR. @@ -323,15 +321,6 @@ int srslte_enb_ul_get_pucch(srslte_enb_ul_t *q, uint16_t rnti, memcpy(uci_data->uci_cqi, pucch_bits, uci_data->uci_cqi_len*sizeof(uint8_t)); } - if (uci_data->uci_dif_cqi_len) { - memcpy(uci_data->uci_dif_cqi, pucch_bits + uci_data->uci_cqi_len, uci_data->uci_dif_cqi_len*sizeof(uint8_t)); - } - - if (uci_data->uci_pmi_len) { - memcpy(uci_data->uci_pmi, pucch_bits + uci_data->uci_cqi_len + uci_data->uci_dif_cqi_len, - uci_data->uci_pmi_len*sizeof(uint8_t)); - } - if (uci_data->uci_ri_len) { uci_data->uci_ri = pucch_bits[0]; /* Assume only one bit of RI */ } diff --git a/lib/src/phy/phch/cqi.c b/lib/src/phy/phch/cqi.c index 8589ee51a..a115bcd28 100644 --- a/lib/src/phy/phch/cqi.c +++ b/lib/src/phy/phch/cqi.c @@ -88,11 +88,30 @@ int srslte_cqi_ue_subband_pack(srslte_cqi_ue_subband_t *msg, uint8_t buff[SRSLTE return 4+2+msg->L; } -int srslte_cqi_format2_wideband_pack(srslte_cqi_format2_wideband_t *msg, uint8_t buff[SRSLTE_CQI_MAX_BITS]) +/* Pack CQI following 3GPP TS 36.212 Tables 5.2.3.3.1-1 and 5.2.3.3.1-2 */ +int srslte_cqi_format2_wideband_pack(srslte_cqi_format2_wideband_t *msg, uint8_t buff[SRSLTE_CQI_MAX_BITS]) { - uint8_t *body_ptr = buff; - srslte_bit_unpack(msg->wideband_cqi, &body_ptr, 4); - return 4; + uint8_t *body_ptr = buff; + + srslte_bit_unpack(msg->wideband_cqi, &body_ptr, 4); + + if (msg->pmi_present) { + if (msg->four_antenna_ports) { + if (msg->rank_is_not_one) { + srslte_bit_unpack(msg->spatial_diff_cqi, &body_ptr, 3); + } + srslte_bit_unpack(msg->pmi, &body_ptr, 4); + } else { + if (msg->rank_is_not_one) { + srslte_bit_unpack(msg->spatial_diff_cqi, &body_ptr, 3); + srslte_bit_unpack(msg->pmi, &body_ptr, 1); + } else { + srslte_bit_unpack(msg->pmi, &body_ptr, 2); + } + } + } + + return (int)(body_ptr - buff); } int srslte_cqi_format2_subband_pack(srslte_cqi_format2_subband_t *msg, uint8_t buff[SRSLTE_CQI_MAX_BITS]) @@ -168,10 +187,27 @@ int srslte_cqi_ue_subband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_u return 4+2+msg->L; } -int srslte_cqi_format2_wideband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_format2_wideband_t *msg) +/* Unpack CQI following 3GPP TS 36.212 Tables 5.2.3.3.1-1 and 5.2.3.3.1-2 */ +int srslte_cqi_format2_wideband_unpack(uint8_t buff[SRSLTE_CQI_MAX_BITS], srslte_cqi_format2_wideband_t *msg) { uint8_t *body_ptr = buff; - msg->wideband_cqi = srslte_bit_pack(&body_ptr, 4); + msg->wideband_cqi = (uint8_t) srslte_bit_pack(&body_ptr, 4); + + if (msg->pmi_present) { + if (msg->four_antenna_ports) { + if (msg->rank_is_not_one) { + msg->spatial_diff_cqi = (uint8_t) srslte_bit_pack(&body_ptr, 3); + } + msg->pmi = (uint8_t) srslte_bit_pack(&body_ptr, 4); + } else { + if (msg->rank_is_not_one) { + msg->spatial_diff_cqi = (uint8_t) srslte_bit_pack(&body_ptr, 3); + msg->pmi = (uint8_t) srslte_bit_pack(&body_ptr, 1); + } else { + msg->pmi = (uint8_t) srslte_bit_pack(&body_ptr, 2); + } + } + } return 4; } @@ -203,7 +239,26 @@ int srslte_cqi_size(srslte_cqi_value_t *value) { switch(value->type) { case SRSLTE_CQI_TYPE_WIDEBAND: + /* Compute size according to 3GPP TS 36.212 Tables 5.2.3.3.1-1 and 5.2.3.3.1-2 */ size = 4; + if (value->wideband.pmi_present) { + if (value->wideband.four_antenna_ports) { + if (value->wideband.rank_is_not_one) { + size += 3; // Differential + } else { + size += 0; // Differential + } + size += 4; // PMI + } else { + if (value->wideband.rank_is_not_one) { + size += 3; // Differential + size += 1; // PMI + } else { + size += 0; // Differential + size += 2; // PMI + } + } + } break; case SRSLTE_CQI_TYPE_SUBBAND: size = 4 + (value->subband.subband_label_2_bits) ? 2 : 1; @@ -398,3 +453,11 @@ int srslte_cqi_hl_get_no_subbands(int nof_prb) return 0; } } + +void srslte_cqi_to_str(const uint8_t *cqi_value, int cqi_len, char *str, int str_len) { + int i = 0; + for (i = 0; i < cqi_len && i < (str_len - 1); i++) { + str[i] = (cqi_value[i] == 0)?(char)'0':(char)'1'; + } + str[i] = '\0'; +} diff --git a/lib/src/phy/phch/pusch.c b/lib/src/phy/phch/pusch.c index c493555dd..feb4e8b4f 100644 --- a/lib/src/phy/phch/pusch.c +++ b/lib/src/phy/phch/pusch.c @@ -612,8 +612,6 @@ int srslte_pusch_decode(srslte_pusch_t *q, if (cqi_value->type == SRSLTE_CQI_TYPE_SUBBAND_HL && cqi_value->subband_hl.ri_present) { cqi_value->subband_hl.rank_is_not_one = false; uci_data->uci_ri_len = (q->cell.nof_ports == 4) ? 2 : 1; - } else { - uci_data->uci_ri_len = 0; } uci_data->uci_cqi_len = (uint32_t) srslte_cqi_size(cqi_value); } diff --git a/lib/src/phy/ue/ue_ul.c b/lib/src/phy/ue/ue_ul.c index 63411fb25..5580a99d1 100644 --- a/lib/src/phy/ue/ue_ul.c +++ b/lib/src/phy/ue/ue_ul.c @@ -274,9 +274,6 @@ 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 @@ -284,22 +281,12 @@ void pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t format if (format >= SRSLTE_PUCCH_FORMAT_2) { /* 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; + uint8_t temp[2] = {uci_data->uci_ri, 0}; + srslte_uci_encode_cqi_pucch(temp, uci_data->uci_ri_len, pucch_bits); } 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 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; - - /* 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; + /* Put CQI Report*/ + srslte_uci_encode_cqi_pucch(uci_data->uci_cqi, uci_data->uci_cqi_len, pucch_bits); } - 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 diff --git a/srsenb/src/phy/phch_worker.cc b/srsenb/src/phy/phch_worker.cc index cec997176..66b9780d1 100644 --- a/srsenb/src/phy/phch_worker.cc +++ b/srsenb/src/phy/phch_worker.cc @@ -444,10 +444,9 @@ unlock: int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch) { - srslte_uci_data_t uci_data; - bzero(&uci_data, sizeof(srslte_uci_data_t)); - - uint32_t wideband_cqi_value = 0; + srslte_uci_data_t uci_data = {0}; + uint32_t wideband_cqi_value = 0, wideband_pmi = 0; + bool wideband_pmi_present = false; uint32_t n_rb_ho = 0; for (uint32_t i=0;iinfo_hex(grants[i].data, phy_grant.mcs.tbs / 8, - "PUSCH: rnti=0x%x, prb=(%d,%d), tbs=%d, mcs=%d, rv=%d, snr=%.1f dB, n_iter=%d, crc=%s%s%s%s%s%s\n", + "PUSCH: rnti=0x%x, prb=(%d,%d), tbs=%d, mcs=%d, rv=%d, snr=%.1f dB, n_iter=%d, crc=%s%s%s%s%s%s%s\n", rnti, phy_grant.n_prb[0], phy_grant.n_prb[0] + phy_grant.L_prb, phy_grant.mcs.tbs / 8, phy_grant.mcs.idx, grants[i].grant.rv_idx, snr_db, @@ -596,6 +601,7 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch) (acks_pending[0] || acks_pending[1]) ? ", ack=" : "", (acks_pending[0]) ? (uci_data.uci_ack ? "1" : "0") : "", (acks_pending[1]) ? (uci_data.uci_ack_2 ? "1" : "0") : "", + uci_data.uci_cqi_len > 0 ? ", cqi=" : "", uci_data.uci_cqi_len > 0 ? cqi_str : "", uci_data.uci_ri_len > 0 ? ((uci_data.uci_ri == 0) ? ", ri=0" : ", ri=1") : "", timestr); @@ -631,10 +637,10 @@ int phch_worker::decode_pusch(srslte_enb_ul_pusch_t *grants, uint32_t nof_pusch) if (uci_data.uci_ri_len > 0 && crc_res) { phy->mac->ri_info(tti_rx, rnti, uci_data.uci_ri); } - if (cqi_value.subband_hl.pmi_present && crc_res) { - phy->mac->pmi_info(tti_rx, rnti, cqi_value.subband_hl.pmi); + if (wideband_pmi_present && crc_res) { + phy->mac->pmi_info(tti_rx, rnti, wideband_pmi); } - + ue_db[rnti]. // Save metrics stats ue_db[rnti].metrics_ul(phy_grant.mcs.idx, 0, snr_db, srslte_pusch_last_noi(&enb_ul.pusch)); } @@ -652,8 +658,7 @@ int phch_worker::decode_pucch() if (rnti >= SRSLTE_CRNTI_START && rnti <= SRSLTE_CRNTI_END && ue_db[rnti].has_grant_tti != (int) tti_rx) { // Check if user needs to receive PUCCH - bool needs_pucch = false, needs_ack[SRSLTE_MAX_TB] = {false}, needs_sr = false, needs_cqi = false, - needs_ri = false; + bool needs_pucch = false, needs_ack[SRSLTE_MAX_TB] = {false}, needs_sr = false, needs_cqi = false; uint32_t last_n_pdcch = 0; bzero(&uci_data, sizeof(srslte_uci_data_t)); @@ -672,25 +677,23 @@ int phch_worker::decode_pucch() uci_data.uci_ack_len++; } } - srslte_cqi_value_t cqi_value; + srslte_cqi_value_t cqi_value = {0}; LIBLTE_RRC_PHYSICAL_CONFIG_DEDICATED_STRUCT *dedicated = &ue_db[rnti].dedicated; LIBLTE_RRC_TRANSMISSION_MODE_ENUM tx_mode = dedicated->antenna_info_explicit_value.tx_mode; if (ue_db[rnti].cqi_en && (ue_db[rnti].pucch_cqi_ack || !needs_ack[0] || !needs_ack[1])) { if (ue_db[rnti].ri_en && srslte_ri_send(ue_db[rnti].pmi_idx, ue_db[rnti].ri_idx, tti_rx)) { needs_pucch = true; - needs_ri = true; uci_data.uci_ri_len = 1; uci_data.ri_periodic_report = true; } else if (srslte_cqi_send(ue_db[rnti].pmi_idx, tti_rx)) { needs_pucch = true; needs_cqi = true; cqi_value.type = SRSLTE_CQI_TYPE_WIDEBAND; - uci_data.uci_cqi_len = srslte_cqi_size(&cqi_value); if (tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) { - //uci_data.uci_dif_cqi_len = 3; - uci_data.uci_pmi_len = 2; + cqi_value.wideband.pmi_present = true; } + uci_data.uci_cqi_len = (uint32_t) srslte_cqi_size(&cqi_value); } } @@ -714,7 +717,7 @@ int phch_worker::decode_pucch() char cqi_ri_str[64] = {0}; if (srslte_pucch_get_last_corr(&enb_ul.pucch) > PUCCH_RL_CORR_TH) { - if (uci_data.uci_ri_len && needs_ri) { + if (uci_data.ri_periodic_report) { phy->mac->ri_info(tti_rx, rnti, uci_data.uci_ri); sprintf(cqi_ri_str, ", ri=%d", uci_data.uci_ri); } else if (uci_data.uci_cqi_len && needs_cqi) { @@ -722,15 +725,10 @@ int phch_worker::decode_pucch() phy->mac->cqi_info(tti_rx, rnti, cqi_value.wideband.wideband_cqi); sprintf(cqi_ri_str, ", cqi=%d", cqi_value.wideband.wideband_cqi); - if (uci_data.uci_pmi_len) { - uint32_t packed_pmi = uci_data.uci_pmi[0]; - if (uci_data.uci_pmi_len > 1) { - packed_pmi = (packed_pmi << 1) + uci_data.uci_pmi[1]; - } - phy->mac->pmi_info(tti_rx, rnti, packed_pmi); - sprintf(cqi_ri_str, "%s, pmi=%c", cqi_ri_str, packed_pmi + 0x30); + if (cqi_value.type == SRSLTE_CQI_TYPE_WIDEBAND && cqi_value.wideband.pmi_present) { + phy->mac->pmi_info(tti_rx, rnti, cqi_value.wideband.pmi); + sprintf(cqi_ri_str, "%s, pmi=%d", cqi_ri_str, cqi_value.wideband.pmi); } - } } log_h->info("PUCCH: rnti=0x%x, corr=%.2f, n_pucch=%d, n_prb=%d%s%s%s%s\n", @@ -740,7 +738,7 @@ int phch_worker::decode_pucch() (uci_data.uci_ack_len)?(uci_data.uci_ack?", ack=1":", ack=0"):"", (uci_data.uci_ack_len > 1)?(uci_data.uci_ack_2?"1":"0"):"", needs_sr?(uci_data.scheduling_request?", sr=yes":", sr=no"):"", - (needs_cqi || needs_ri)?cqi_ri_str:""); + (needs_cqi || uci_data.ri_periodic_report)?cqi_ri_str:""); // Notify MAC of RL status diff --git a/srsue/hdr/phy/phch_worker.h b/srsue/hdr/phy/phch_worker.h index e1d943880..679fd177c 100644 --- a/srsue/hdr/phy/phch_worker.h +++ b/srsue/hdr/phy/phch_worker.h @@ -76,7 +76,7 @@ private: /* Internal methods */ bool extract_fft_and_pdcch_llr(); - void compute_ri(); + void compute_ri(uint8_t *ri, uint8_t *pmi, float *sinr); /* ... for DL */ bool decode_pdcch_ul(mac_interface_phy::mac_grant_t *grant); diff --git a/srsue/src/phy/phch_worker.cc b/srsue/src/phy/phch_worker.cc index bc178b970..016483468 100644 --- a/srsue/src/phy/phch_worker.cc +++ b/srsue/src/phy/phch_worker.cc @@ -382,39 +382,21 @@ 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) { +void phch_worker::compute_ri(uint8_t *ri, uint8_t *pmi, float *sinr) { + 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); + srslte_ue_dl_ri_select(&ue_dl, ri, &cn); + Debug("TM3 RI select %d layers, κ=%fdB\n", (*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); - } + srslte_ue_dl_ri_pmi_select(&ue_dl, ri, pmi, sinr); + Debug("TM4 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]])); uci_data.uci_ri_len = 1; } } @@ -867,23 +849,28 @@ void phch_worker::set_uci_periodic_cqi() { int cqi_fixed = phy->args->cqi_fixed; int cqi_max = phy->args->cqi_max; - + + uint8_t ri = (uint8_t) ue_dl.ri; + uint8_t pmi = (uint8_t) ue_dl.pmi[ri]; + float sinr = ue_dl.sinr[ri][pmi]; + 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))) { /* Compute RI, PMI and SINR */ - compute_ri(); - + compute_ri(&ri, &pmi, &sinr); + uci_data.uci_ri = ri; + uci_data.uci_ri_len = 1; uci_data.ri_periodic_report = true; - Info("PUCCH: Periodic RI=%d\n", uci_data.uci_ri); + Debug("PUCCH: Periodic ri=%d\n", ri); } else if (srslte_cqi_send(period_cqi.pmi_idx, TTI_TX(tti))) { - srslte_cqi_value_t cqi_report; + srslte_cqi_value_t cqi_report = {0}; if (period_cqi.format_is_subband) { // TODO: Implement subband periodic reports cqi_report.type = SRSLTE_CQI_TYPE_SUBBAND; cqi_report.subband.subband_cqi = srslte_cqi_from_snr(phy->avg_snr_db); cqi_report.subband.subband_label = 0; log_h->console("Warning: Subband CQI periodic reports not implemented\n"); - Info("PUCCH: Periodic CQI=%d, SNR=%.1f dB\n", cqi_report.subband.subband_cqi, phy->avg_snr_db); + Debug("PUCCH: Periodic CQI=%d, SNR=%.1f dB\n", cqi_report.subband.subband_cqi, phy->avg_snr_db); } else { cqi_report.type = SRSLTE_CQI_TYPE_WIDEBAND; if (cqi_fixed >= 0) { @@ -894,19 +881,14 @@ void phch_worker::set_uci_periodic_cqi() if (cqi_max >= 0 && cqi_report.wideband.wideband_cqi > cqi_max) { cqi_report.wideband.wideband_cqi = cqi_max; } - 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; + if (phy->config->dedicated.antenna_info_explicit_value.tx_mode == LIBLTE_RRC_TRANSMISSION_MODE_4) { + cqi_report.wideband.pmi_present = true; + cqi_report.wideband.pmi = pmi; + cqi_report.wideband.rank_is_not_one = (ri != 0); } - uint8_t *ptr = uci_data.uci_pmi; - srslte_bit_unpack(ue_dl.pmi[ue_dl.ri], &ptr, uci_data.uci_pmi_len); + Debug("PUCCH: Periodic CQI=%d, SNR=%.1f dB\n", cqi_report.wideband.wideband_cqi, phy->avg_snr_db); } - uci_data.uci_cqi_len = srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi); + uci_data.uci_cqi_len = (uint32_t) srslte_cqi_value_pack(&cqi_report, uci_data.uci_cqi); rar_cqi_request = false; } } @@ -914,9 +896,13 @@ void phch_worker::set_uci_periodic_cqi() void phch_worker::set_uci_aperiodic_cqi() { + uint8_t ri = (uint8_t) ue_dl.ri; + uint8_t pmi = (uint8_t) ue_dl.pmi[ri]; + float sinr = ue_dl.sinr[ri][pmi]; + if (phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic_present) { /* Compute RI, PMI and SINR */ - compute_ri(); + compute_ri(&ri, &pmi, &sinr); switch(phy->config->dedicated.cqi_report_cnfg.report_mode_aperiodic) { case LIBLTE_RRC_CQI_REPORT_MODE_APERIODIC_RM30: @@ -1054,15 +1040,20 @@ void phch_worker::encode_pusch(srslte_ra_ul_grant_t *grant, uint8_t *payload, ui snprintf(timestr, 64, ", tot_time=%4d us", (int) logtime_start[0].tv_usec); #endif + char cqi_str[32] = ""; + srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, cqi_str, 32); + uint8_t dummy[2] = {0,0}; - log_h->info("PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s\n", + log_h->info("PUSCH: tti_tx=%d, alloc=(%d,%d), tbs=%d, mcs=%d, rv=%d%s%s%s, cfo=%.1f KHz%s%s%s\n", (tti + HARQ_DELAY_MS) % 10240, grant->n_prb[0], grant->n_prb[0] + grant->L_prb, grant->mcs.tbs / 8, grant->mcs.idx, rv, uci_data.uci_ack_len > 0 ? (uci_data.uci_ack ? ", ack=1" : "0") : "", uci_data.uci_ack_len > 1 ? (uci_data.uci_ack_2 ? "1" : "0") : "", uci_data.uci_ri_len > 0 ? (uci_data.uci_ri ? ", ri=1" : ", ri=0") : "", - cfo * 15, timestr); + cfo * 15, timestr, + uci_data.uci_cqi_len > 0 ? ", cqi=" : "", + uci_data.uci_cqi_len > 0 ? cqi_str : ""); // Store metrics ul_metrics.mcs = grant->mcs.idx; @@ -1102,17 +1093,20 @@ void phch_worker::encode_pucch() float tx_power = srslte_ue_ul_pucch_power(&ue_ul, phy->pathloss, ue_ul.last_pucch_format, uci_data.uci_cqi_len, uci_data.uci_ack_len); float gain = set_power(tx_power); - - Info("PUCCH: tti_tx=%d, n_pucch=%d, n_prb=%d, ack=%s%s, ri=%s, pmi=%s%s, sr=%s, cfo=%.1f KHz%s\n", - (tti+4)%10240, + + char str_cqi[32] = ""; + srslte_cqi_to_str(uci_data.uci_cqi, uci_data.uci_cqi_len, str_cqi, 32); + + Info("PUCCH: tti_tx=%d, n_pucch=%d, n_prb=%d, ack=%s%s%s%s%s, sr=%s, cfo=%.1f KHz%s\n", + (tti + 4) % 10240, ue_ul.pucch.last_n_pucch, ue_ul.pucch.last_n_prb, - uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no", - uci_data.uci_ack_len>1?(uci_data.uci_ack_2?"1":"0"):"", - uci_data.uci_ri_len>0?(uci_data.uci_ri?"1":"0"):"no", - uci_data.uci_pmi_len>0?(uci_data.uci_pmi[1]?"1":"0"):"no", - uci_data.uci_pmi_len>0?(uci_data.uci_pmi[0]?"1":"0"):"", - uci_data.scheduling_request?"yes":"no", - cfo*15, timestr); + uci_data.uci_ack_len > 0 ? (uci_data.uci_ack ? "1" : "0") : "no", + uci_data.uci_ack_len > 1 ? (uci_data.uci_ack_2 ? "1" : "0") : "", + uci_data.uci_ri_len > 0 ? (uci_data.uci_ri ? ", ri=1" : ", ri=0") : "", + uci_data.uci_cqi_len > 0 ? ", cqi=" : "", + uci_data.uci_cqi_len > 0 ? str_cqi : "", + uci_data.scheduling_request ? "yes" : "no", + cfo * 15, timestr); } if (uci_data.scheduling_request) {