/** * Copyright 2013-2022 Software Radio Systems Limited * * This file is part of srsRAN. * * srsRAN is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * srsRAN is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * A copy of the GNU Affero General Public License can be found in * the LICENSE file in the top-level directory of this distribution * and at http://www.gnu.org/licenses/. * */ #ifndef SRSRAN_HARQ_SOFTBUFFER_H #define SRSRAN_HARQ_SOFTBUFFER_H #include "srsran/adt/pool/pool_interface.h" #include "srsran/adt/span.h" extern "C" { #include "srsran/phy/common/phy_common_nr.h" #include "srsran/phy/fec/softbuffer.h" #include "srsran/phy/phch/sch_nr.h" #include "srsran/phy/utils/vector.h" } namespace srsenb { class tx_harq_softbuffer { public: tx_harq_softbuffer() { bzero(&buffer, sizeof(buffer)); } explicit tx_harq_softbuffer(uint32_t nof_prb_) { // Note: for now we use same size regardless of nof_prb_ srsran_softbuffer_tx_init_guru(&buffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB); } tx_harq_softbuffer(const tx_harq_softbuffer&) = delete; tx_harq_softbuffer(tx_harq_softbuffer&& other) noexcept { memcpy(&buffer, &other.buffer, sizeof(other.buffer)); bzero(&other.buffer, sizeof(other.buffer)); } tx_harq_softbuffer& operator=(const tx_harq_softbuffer&) = delete; tx_harq_softbuffer& operator =(tx_harq_softbuffer&& other) noexcept { if (this != &other) { destroy(); memcpy(&buffer, &other.buffer, sizeof(other.buffer)); bzero(&other.buffer, sizeof(other.buffer)); } return *this; } ~tx_harq_softbuffer() { destroy(); } void reset() { srsran_softbuffer_tx_reset(&buffer); } srsran_softbuffer_tx_t& operator*() { return buffer; } const srsran_softbuffer_tx_t& operator*() const { return buffer; } srsran_softbuffer_tx_t* operator->() { return &buffer; } const srsran_softbuffer_tx_t* operator->() const { return &buffer; } srsran_softbuffer_tx_t* get() { return &buffer; } const srsran_softbuffer_tx_t* get() const { return &buffer; } private: void destroy() { srsran_softbuffer_tx_free(&buffer); } srsran_softbuffer_tx_t buffer; }; class rx_harq_softbuffer { public: rx_harq_softbuffer() { bzero(&buffer, sizeof(buffer)); } explicit rx_harq_softbuffer(uint32_t nof_prb_) { // Note: for now we use same size regardless of nof_prb_ srsran_softbuffer_rx_init_guru(&buffer, SRSRAN_SCH_NR_MAX_NOF_CB_LDPC, SRSRAN_LDPC_MAX_LEN_ENCODED_CB); } rx_harq_softbuffer(const rx_harq_softbuffer&) = delete; rx_harq_softbuffer(rx_harq_softbuffer&& other) noexcept { memcpy(&buffer, &other.buffer, sizeof(other.buffer)); bzero(&other.buffer, sizeof(other.buffer)); } rx_harq_softbuffer& operator=(const rx_harq_softbuffer&) = delete; rx_harq_softbuffer& operator =(rx_harq_softbuffer&& other) noexcept { if (this != &other) { destroy(); memcpy(&buffer, &other.buffer, sizeof(other.buffer)); bzero(&other.buffer, sizeof(other.buffer)); } return *this; } ~rx_harq_softbuffer() { destroy(); } void reset() { srsran_softbuffer_rx_reset(&buffer); } void reset(uint32_t tbs_bits) { srsran_softbuffer_rx_reset_tbs(&buffer, tbs_bits); } srsran_softbuffer_rx_t& operator*() { return buffer; } const srsran_softbuffer_rx_t& operator*() const { return buffer; } srsran_softbuffer_rx_t* operator->() { return &buffer; } const srsran_softbuffer_rx_t* operator->() const { return &buffer; } srsran_softbuffer_rx_t* get() { return &buffer; } const srsran_softbuffer_rx_t* get() const { return &buffer; } private: void destroy() { srsran_softbuffer_rx_free(&buffer); } srsran_softbuffer_rx_t buffer; }; class harq_softbuffer_pool { public: harq_softbuffer_pool(const harq_softbuffer_pool&) = delete; harq_softbuffer_pool(harq_softbuffer_pool&&) = delete; harq_softbuffer_pool& operator=(const harq_softbuffer_pool&) = delete; harq_softbuffer_pool& operator=(harq_softbuffer_pool&&) = delete; void init_pool(uint32_t nof_prb, uint32_t batch_size = MAX_HARQ * 4, uint32_t thres = 0, uint32_t init_size = 0); srsran::unique_pool_ptr get_tx(uint32_t nof_prb); srsran::unique_pool_ptr get_rx(uint32_t nof_prb); static harq_softbuffer_pool& get_instance() { static harq_softbuffer_pool pool; return pool; } private: const static uint32_t MAX_HARQ = 16; harq_softbuffer_pool() = default; std::array >, SRSRAN_MAX_PRB_NR> tx_pool; std::array >, SRSRAN_MAX_PRB_NR> rx_pool; }; } // namespace srsenb #endif // SRSRAN_HARQ_SOFTBUFFER_H