1313using namespace srsran ;
1414using namespace harq_utils ;
1515
16+ namespace {
17+
18+ class noop_harq_timeout_notifier : public harq_timeout_notifier
19+ {
20+ public:
21+ void on_harq_timeout (du_ue_index_t ue_idx, bool is_dl, bool ack) override
22+ { /* do nothing */
23+ }
24+ };
25+
26+ } // namespace
27+
1628template <bool IsDl>
1729cell_harq_repository<IsDl>::cell_harq_repository(unsigned max_ues,
1830 unsigned max_ack_wait_timeout,
@@ -30,10 +42,11 @@ cell_harq_repository<IsDl>::cell_harq_repository(unsigned max_ues,
3042 ues.resize (max_ues);
3143 for (unsigned i = 0 ; i != max_ues; i++) {
3244 ues[i].free_harq_ids .reserve (MAX_NOF_HARQS);
33- ues[i].harqs .resize (MAX_NOF_HARQS, INVALID_HARQ_REF_INDEX );
45+ ues[i].harqs .reserve (MAX_NOF_HARQS);
3446 }
3547
36- const unsigned RING_SIZE = 40 ; // TODO: use function to define this value.
48+ const unsigned RING_SIZE = 320 ; // TODO: use function to define this value. It must account the timeout arg and k
49+ // values
3750 harq_timeout_wheel.resize (RING_SIZE);
3851}
3952
@@ -42,8 +55,8 @@ void cell_harq_repository<IsDl>::slot_indication(slot_point sl_tx)
4255{
4356 // Handle HARQs that timed out.
4457 auto & harqs_timing_out = harq_timeout_wheel[sl_tx.to_uint () % harq_timeout_wheel.size ()];
45- for (harq_type& h : harqs_timing_out) {
46- handle_harq_ack_timeout (h , sl_tx);
58+ while ( not harqs_timing_out. empty () ) {
59+ handle_harq_ack_timeout (harqs_timing_out. front () , sl_tx);
4760 }
4861}
4962
@@ -205,13 +218,36 @@ void cell_harq_repository<IsDl>::set_pending_retx(harq_type& h)
205218 h.status = harq_state_t ::pending_retx;
206219}
207220
221+ template <bool IsDl>
222+ void cell_harq_repository<IsDl>::handle_new_retx(harq_type& h, slot_point sl_tx, slot_point sl_ack)
223+ {
224+ srsran_assert (h.status == harq_state_t ::pending_retx, " Attempt of retx in an HARQ that has no pending retx" );
225+
226+ // Remove HARQ from pending Retx list.
227+ harq_pending_retx_list.pop (&h);
228+
229+ h.status = harq_state_t ::waiting_ack;
230+ h.slot_tx = sl_tx;
231+ h.slot_ack = sl_ack;
232+ h.ndi = !h.ndi ;
233+ h.ack_on_timeout = false ;
234+ h.retxs_cancelled = false ;
235+ h.nof_retxs ++;
236+
237+ // Add HARQ to the timeout list.
238+ h.slot_ack_timeout = sl_ack + max_ack_wait_in_slots;
239+ harq_timeout_wheel[h.slot_ack_timeout .to_uint () % harq_timeout_wheel.size ()].push_front (&h);
240+ }
241+
208242template <bool IsDl>
209243void cell_harq_repository<IsDl>::reserve_ue_harqs(du_ue_index_t ue_idx, unsigned nof_harqs)
210244{
245+ ues[ue_idx].harqs .resize (nof_harqs);
211246 ues[ue_idx].free_harq_ids .resize (nof_harqs);
212247 for (unsigned count = 0 ; count != nof_harqs; count++) {
213248 harq_id_t h_id = to_harq_id (nof_harqs - count - 1 );
214249 ues[ue_idx].free_harq_ids [count] = h_id;
250+ ues[ue_idx].harqs [count] = INVALID_HARQ_REF_INDEX;
215251 }
216252}
217253
@@ -259,7 +295,7 @@ template struct harq_utils::cell_harq_repository<false>;
259295cell_harq_manager::cell_harq_manager (unsigned max_ues,
260296 std::unique_ptr<harq_timeout_notifier> notifier,
261297 unsigned max_ack_wait_timeout) :
262- timeout_notifier(std::move(notifier)),
298+ timeout_notifier(notifier != nullptr ? std::move(notifier) : std::make_unique<noop_harq_timeout_notifier>( )),
263299 logger(srslog::fetch_basic_logger(" SCHED" )),
264300 dl(max_ues, max_ack_wait_timeout, *timeout_notifier, logger),
265301 ul(max_ues, max_ack_wait_timeout, *timeout_notifier, logger)
@@ -275,14 +311,15 @@ void cell_harq_manager::slot_indication(slot_point sl_tx)
275311
276312bool cell_harq_manager::contains (du_ue_index_t ue_idx) const
277313{
278- return dl.ues [ue_idx].free_harq_ids .size () != 0 ;
314+ return ue_idx < dl. ues . size () and dl.ues [ue_idx].free_harq_ids .size () != 0 ;
279315}
280316
281317unique_ue_harq_entity
282318cell_harq_manager::add_ue (du_ue_index_t ue_idx, rnti_t crnti, unsigned nof_dl_harq_procs, unsigned nof_ul_harq_procs)
283319{
284- srsran_assert (nof_dl_harq_procs > 0 , " Invalid number of HARQs" );
285- srsran_assert (nof_ul_harq_procs > 0 , " Invalid number of HARQs" );
320+ srsran_sanity_check (nof_dl_harq_procs > 0 , " Invalid number of HARQs" );
321+ srsran_sanity_check (nof_ul_harq_procs > 0 , " Invalid number of HARQs" );
322+ srsran_sanity_check (ue_idx < dl.ues .size (), " Invalid ue_index" );
286323 srsran_assert (not contains (ue_idx), " Creating UE with duplicate ue_index" );
287324 dl.reserve_ue_harqs (ue_idx, nof_dl_harq_procs);
288325 ul.reserve_ue_harqs (ue_idx, nof_ul_harq_procs);
@@ -330,6 +367,23 @@ cell_harq_manager::new_ul_tx(du_ue_index_t ue_idx, slot_point pusch_slot, unsign
330367 return h;
331368}
332369
370+ void cell_harq_manager::new_dl_retx (harq_utils::dl_harq_process_impl& h,
371+ slot_point pdsch_slot,
372+ unsigned k1,
373+ uint8_t harq_bit_idx)
374+ {
375+ dl.handle_new_retx (h, pdsch_slot, pdsch_slot + k1);
376+ h.harq_bit_idx = harq_bit_idx;
377+ h.pucch_ack_to_receive = 0 ;
378+ h.chosen_ack = mac_harq_ack_report_status::dtx;
379+ h.last_pucch_snr = std::nullopt ;
380+ }
381+
382+ void cell_harq_manager::new_ul_retx (harq_utils::ul_harq_process_impl& h, slot_point pusch_slot)
383+ {
384+ ul.handle_new_retx (h, pusch_slot, pusch_slot);
385+ }
386+
333387dl_harq_process_impl::status_update cell_harq_manager::dl_ack_info (harq_utils::dl_harq_process_impl& h,
334388 mac_harq_ack_report_status ack,
335389 std::optional<float > pucch_snr)
@@ -384,12 +438,22 @@ int cell_harq_manager::ul_crc_info(harq_utils::ul_harq_process_impl& h, bool ack
384438 return ack ? (int )h.prev_tx_params .tbs_bytes : 0 ;
385439}
386440
441+ void dl_harq_process_view::new_retx (slot_point pdsch_slot, unsigned k1, uint8_t harq_bit_idx)
442+ {
443+ cell_harq_mng->new_dl_retx (cell_harq_mng->dl .harqs [harq_ref_idx], pdsch_slot, k1, harq_bit_idx);
444+ }
445+
387446dl_harq_process_view::status_update dl_harq_process_view::dl_ack_info (mac_harq_ack_report_status ack,
388447 std::optional<float > pucch_snr)
389448{
390449 return cell_harq_mng->dl_ack_info (cell_harq_mng->dl .harqs [harq_ref_idx], ack, pucch_snr);
391450}
392451
452+ void ul_harq_process_view::new_retx (slot_point pusch_slot)
453+ {
454+ cell_harq_mng->new_ul_retx (cell_harq_mng->ul .harqs [harq_ref_idx], pusch_slot);
455+ }
456+
393457int ul_harq_process_view::ul_crc_info (bool ack)
394458{
395459 return cell_harq_mng->ul_crc_info (cell_harq_mng->ul .harqs [harq_ref_idx], ack);
0 commit comments