/** * 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 SRSUE_DL_HARQ_H #define SRSUE_DL_HARQ_H #include "demux.h" #include "dl_sps.h" #include "srsran/common/mac_pcap.h" #include "srsran/common/timers.h" #include "srsue/hdr/stack/mac_common/mac_common.h" /* Downlink HARQ entity as defined in 5.3.2 of 36.321 */ namespace srsue { class dl_harq_entity { public: dl_harq_entity(uint8_t cc_idx_); bool init(ue_rnti* rntis, demux* demux_unit); void reset(); void start_pcap(srsran::mac_pcap* pcap_); /***************** PHY->MAC interface for DL processes **************************/ void new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, mac_interface_phy_lte::tb_action_dl_t* action); void tb_decoded(mac_interface_phy_lte::mac_grant_dl_t grant, bool ack[SRSRAN_MAX_CODEWORDS]); void set_si_window_start(int si_window_start); float get_average_retx(); void set_average_retx(uint32_t n_retx); private: class dl_harq_process { public: dl_harq_process(); bool init(int pid, dl_harq_entity* parent); void reset(void); void reset_ndi(); void new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, mac_interface_phy_lte::tb_action_dl_t* action); void tb_decoded(mac_interface_phy_lte::mac_grant_dl_t grant, bool ack[SRSRAN_MAX_CODEWORDS]); bool is_sps(); private: const static int RESET_DUPLICATE_TIMEOUT = 6; class dl_tb_process { public: dl_tb_process(void); ~dl_tb_process(); bool init(int pid, dl_harq_entity* parent, uint32_t tb_idx); void reset(); void reset_ndi(); void new_grant_dl(mac_interface_phy_lte::mac_grant_dl_t grant, mac_interface_phy_lte::tb_action_dl_t* action); void tb_decoded(mac_interface_phy_lte::mac_grant_dl_t grant, bool* ack_ptr); private: // Determine if it's a new transmission 5.3.2.2 bool calc_is_new_transmission(mac_interface_phy_lte::mac_grant_dl_t grant); // Internal function to reset process, caller must hold the mutex void reset_nolock(); std::mutex mutex; bool is_initiated; dl_harq_entity* harq_entity; srslog::basic_logger& logger; bool is_first_tb; bool is_new_transmission; bool is_bcch; uint32_t pid; /* HARQ Proccess ID */ uint32_t tid; /* Transport block ID */ uint8_t* payload_buffer_ptr; bool ack; uint32_t n_retx; mac_interface_phy_lte::mac_grant_dl_t cur_grant; srsran_softbuffer_rx_t softbuffer; }; /* Transport blocks */ std::vector subproc; }; // Private members of dl_harq_entity uint32_t get_harq_sps_pid(uint32_t tti); dl_sps dl_sps_assig; std::vector proc; dl_harq_process bcch_proc; demux* demux_unit = nullptr; srslog::basic_logger& logger; srsran::mac_pcap* pcap = nullptr; ue_rnti* rntis = nullptr; uint16_t last_temporal_crnti = 0; int si_window_start = 0; std::mutex retx_cnt_mutex = {}; float average_retx = 0.0; uint64_t nof_pkts = 0; uint8_t cc_idx = 0; }; typedef std::unique_ptr dl_harq_entity_ptr; typedef std::array dl_harq_entity_vector; } // namespace srsue #endif // SRSUE_DL_HARQ_H