diff --git a/lib/include/srsran/phy/phch/cqi.h b/lib/include/srsran/phy/phch/cqi.h index 6dc9c1fbf..4b4b8a368 100644 --- a/lib/include/srsran/phy/phch/cqi.h +++ b/lib/include/srsran/phy/phch/cqi.h @@ -118,6 +118,7 @@ typedef struct SRSRAN_API { uint32_t scell_index; ///< Indicates the cell/carrier the measurement belongs, use 0 for PCell uint32_t L; uint32_t N; + uint32_t sb_idx; srsran_cqi_type_t type; uint32_t ri_len; } srsran_cqi_cfg_t; @@ -163,7 +164,10 @@ SRSRAN_API int srsran_cqi_hl_get_no_subbands(int nof_prb); SRSRAN_API int srsran_cqi_hl_get_L(int nof_prb); -SRSRAN_API int srsran_cqi_sb_get_Nj(uint32_t j, uint32_t nof_prb); +SRSRAN_API uint32_t srsran_cqi_get_sb_idx(uint32_t tti, + uint32_t subband_label, + const srsran_cqi_report_cfg_t* cqi_report_cfg, + const srsran_cell_t* cell); SRSRAN_API uint8_t srsran_cqi_from_snr(float snr); diff --git a/lib/include/srsran/phy/utils/bit.h b/lib/include/srsran/phy/utils/bit.h index 77e55a0b7..65ba370ee 100644 --- a/lib/include/srsran/phy/utils/bit.h +++ b/lib/include/srsran/phy/utils/bit.h @@ -76,6 +76,8 @@ SRSRAN_API void srsran_bit_unpack_l(uint64_t value, uint8_t** bits, int nof_bits SRSRAN_API void srsran_bit_unpack(uint32_t value, uint8_t** bits, int nof_bits); +SRSRAN_API void srsran_bit_unpack_lsb(uint32_t value, uint8_t** bits, int nof_bits); + SRSRAN_API void srsran_bit_fprint(FILE* stream, uint8_t* bits, int nof_bits); SRSRAN_API uint32_t srsran_bit_diff(const uint8_t* x, const uint8_t* y, int nbits); diff --git a/lib/src/phy/phch/cqi.c b/lib/src/phy/phch/cqi.c index 2ee775eaa..b06fe753d 100644 --- a/lib/src/phy/phch/cqi.c +++ b/lib/src/phy/phch/cqi.c @@ -248,7 +248,7 @@ cqi_format2_subband_tostring(srsran_cqi_cfg_t* cfg, srsran_cqi_ue_subband_t* msg n += snprintf(buff + n, buff_len - n, ", cqi=%d", msg->subband_cqi); n += snprintf(buff + n, buff_len - n, ", label=%d", msg->subband_label); - + n += snprintf(buff + n, buff_len - n, ", sb_idx=%d", cfg->sb_idx); return n; } @@ -559,7 +559,7 @@ static int cqi_hl_get_bwp_J(int nof_prb) /* Returns the number of subbands in the j-th bandwidth part */ -int srsran_cqi_sb_get_Nj(uint32_t j, uint32_t nof_prb) +static int cqi_sb_get_Nj(uint32_t j, uint32_t nof_prb) { uint32_t J = cqi_hl_get_bwp_J(nof_prb); if (J == 1) { @@ -575,6 +575,15 @@ int srsran_cqi_sb_get_Nj(uint32_t j, uint32_t nof_prb) } } +uint32_t srsran_cqi_get_sb_idx(uint32_t tti, + uint32_t subband_label, + const srsran_cqi_report_cfg_t* cqi_report_cfg, + const srsran_cell_t* cell) +{ + uint32_t bw_part_idx = srsran_cqi_periodic_sb_bw_part_idx(cqi_report_cfg, tti, cell->nof_prb, cell->frame_type); + return subband_label + bw_part_idx * cqi_sb_get_Nj(bw_part_idx, cell->nof_prb); +} + /* Returns the number of bits to index a bandwidth part (L) * L = ceil(log2(nof_prb/k/J)) */ diff --git a/lib/src/phy/utils/bit.c b/lib/src/phy/utils/bit.c index c9e676e24..42cf47cbc 100644 --- a/lib/src/phy/utils/bit.c +++ b/lib/src/phy/utils/bit.c @@ -727,6 +727,22 @@ void srsran_bit_unpack(uint32_t value, uint8_t** bits, int nof_bits) *bits += nof_bits; } +/** + * Unpacks nof_bits from LSBs of value in LSB order to *bits. Advances pointer past unpacked bits. + * + * @param[in] value nof_bits lowest order bits will be unpacked in MSB order + * @param[in] nof_bits Number of bits to unpack + * @param[out] bits Points to buffer pointer. The buffer pointer will be advanced by nof_bits + */ +void srsran_bit_unpack_lsb(uint32_t value, uint8_t** bits, int nof_bits) +{ + int i; + for (i = 0; i < nof_bits; i++) { + (*bits)[nof_bits - i - 1] = (value >> (nof_bits - i - 1)) & 0x1; + } + *bits += nof_bits; +} + void srsran_bit_pack_vector(uint8_t* unpacked, uint8_t* packed, int nof_bits) { uint32_t i, nbytes; diff --git a/srsenb/hdr/phy/phy_ue_db.h b/srsenb/hdr/phy/phy_ue_db.h index 765b08cc7..ad1a36874 100644 --- a/srsenb/hdr/phy/phy_ue_db.h +++ b/srsenb/hdr/phy/phy_ue_db.h @@ -383,6 +383,15 @@ public: const srsran_uci_cfg_t& uci_cfg, const srsran_uci_value_t& uci_value); + static void send_cqi_data(uint32_t tti, + uint16_t rnti, + uint32_t cqi_cc_idx, + const srsran_cqi_cfg_t& cqi_cfg, + const srsran_cqi_value_t& cqi_value, + const srsran_cqi_report_cfg_t& cqi_report_cfg, + const srsran_cell_t& cell, + stack_interface_phy_lte* stack); + /** * Set the latest UL Transport Block resource allocation for a given RNTI, eNb cell/carrier and UL HARQ process * identifier. diff --git a/srsenb/src/phy/phy_ue_db.cc b/srsenb/src/phy/phy_ue_db.cc index 50dab80b7..a5fa379e9 100644 --- a/srsenb/src/phy/phy_ue_db.cc +++ b/srsenb/src/phy/phy_ue_db.cc @@ -606,6 +606,45 @@ int phy_ue_db::fill_uci_cfg(uint32_t tti, return uci_required ? 1 : SRSRAN_SUCCESS; } +void phy_ue_db::send_cqi_data(uint32_t tti, + uint16_t rnti, + uint32_t cqi_cc_idx, + const srsran_cqi_cfg_t& cqi_cfg, + const srsran_cqi_value_t& cqi_value, + const srsran_cqi_report_cfg_t& cqi_report_cfg, + const srsran_cell_t& cell, + stack_interface_phy_lte* stack) +{ + uint8_t stack_value = 0; + switch (cqi_cfg.type) { + case SRSRAN_CQI_TYPE_WIDEBAND: + stack_value = cqi_value.wideband.wideband_cqi; + stack->cqi_info(tti, rnti, cqi_cc_idx, stack_value); + break; + case SRSRAN_CQI_TYPE_SUBBAND_UE: + stack_value = cqi_value.subband_ue.subband_cqi; + stack->sb_cqi_info(tti, + rnti, + cqi_cc_idx, + srsran_cqi_get_sb_idx(tti, cqi_value.subband_ue.subband_label, &cqi_report_cfg, &cell), + stack_value); + break; + case SRSRAN_CQI_TYPE_SUBBAND_HL: + stack_value = cqi_value.subband_hl.wideband_cqi_cw0; + // Todo: change interface + stack->cqi_info(tti, rnti, cqi_cc_idx, stack_value); + break; + case SRSRAN_CQI_TYPE_SUBBAND_UE_DIFF: + stack_value = cqi_value.subband_ue_diff.wideband_cqi; + stack->sb_cqi_info(tti, + rnti, + cqi_cc_idx, + cqi_value.subband_ue_diff.position_subband, + stack_value + cqi_value.subband_ue_diff.subband_diff_cqi); + break; + } +} + int phy_ue_db::send_uci_data(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, @@ -664,37 +703,7 @@ int phy_ue_db::send_uci_data(uint32_t tti, if (uci_value.cqi.data_crc) { // Channel quality indicator itself if (uci_cfg.cqi.data_enable) { - uint8_t cqi_value = 0; - uint32_t sb_idx = 0; - uint32_t bw_part_idx = 0; - switch (uci_cfg.cqi.type) { - case SRSRAN_CQI_TYPE_WIDEBAND: - cqi_value = uci_value.cqi.wideband.wideband_cqi; - printf("tti=%d, wide\n", tti); - stack->cqi_info(tti, rnti, cqi_cc_idx, cqi_value); - break; - case SRSRAN_CQI_TYPE_SUBBAND_UE: - cqi_value = uci_value.cqi.subband_ue.subband_cqi; - bw_part_idx = srsran_cqi_periodic_sb_bw_part_idx( - &ue.cell_info[0].phy_cfg.dl_cfg.cqi_report, tti, cell.nof_prb, cell.frame_type); - sb_idx = - uci_value.cqi.subband_ue.subband_label + bw_part_idx * srsran_cqi_sb_get_Nj(bw_part_idx, cell.nof_prb); - stack->sb_cqi_info(tti, rnti, cqi_cc_idx, sb_idx, cqi_value); - break; - case SRSRAN_CQI_TYPE_SUBBAND_HL: - cqi_value = uci_value.cqi.subband_hl.wideband_cqi_cw0; - // Todo: change interface - stack->cqi_info(tti, rnti, cqi_cc_idx, cqi_value); - break; - case SRSRAN_CQI_TYPE_SUBBAND_UE_DIFF: - cqi_value = uci_value.cqi.subband_ue_diff.wideband_cqi; - stack->sb_cqi_info(tti, - rnti, - cqi_cc_idx, - uci_value.cqi.subband_ue_diff.position_subband, - cqi_value + uci_value.cqi.subband_ue_diff.subband_diff_cqi); - break; - } + send_cqi_data(tti, rnti, cqi_cc_idx, uci_cfg.cqi, uci_value.cqi, ue.cell_info[0].phy_cfg.dl_cfg.cqi_report, cell, stack); } // Precoding Matrix indicator (TM4)