@@ -59,6 +59,8 @@ void cell_harq_repository<IsDl>::slot_indication(slot_point sl_tx)
5959 while (not harqs_timing_out.empty ()) {
6060 handle_harq_ack_timeout (harqs_timing_out.front (), sl_tx);
6161 }
62+
63+ last_sl_ind = sl_tx;
6264}
6365
6466template <bool IsDl>
@@ -276,6 +278,13 @@ void cell_harq_repository<IsDl>::cancel_retxs(harq_type& h)
276278 if (h.status == harq_state_t ::empty) {
277279 return ;
278280 }
281+ if (h.status == harq_state_t ::pending_retx) {
282+ // If a retx is pending, do not allow it to take place.
283+ dealloc_harq (h);
284+ return ;
285+ }
286+ // If the HARQ is still waiting for an ACK to arrive, just mark it as max retxs have been exceeded. The ack_info
287+ // function will automatically update the HARQ state.
279288 h.max_nof_harq_retxs = h.nof_retxs ;
280289 h.retxs_cancelled = true ;
281290}
@@ -375,35 +384,27 @@ cell_harq_manager::new_ul_tx(du_ue_index_t ue_idx, rnti_t rnti, slot_point pusch
375384 return h;
376385}
377386
378- bool cell_harq_manager::new_dl_retx (harq_utils::dl_harq_process_impl& h,
379- slot_point pdsch_slot,
380- unsigned k1,
381- uint8_t harq_bit_idx)
387+ bool dl_harq_process_handle::new_retx (slot_point pdsch_slot, unsigned k1, uint8_t harq_bit_idx)
382388{
383- if (not dl.handle_new_retx (h, pdsch_slot, pdsch_slot + k1)) {
389+ dl_harq_process_impl& h = fetch_impl ();
390+ if (not harq_repo->handle_new_retx (h, pdsch_slot, pdsch_slot + k1)) {
384391 return false ;
385392 }
393+ // Reset DL-only HARQ parameters.
386394 h.harq_bit_idx = harq_bit_idx;
387395 h.pucch_ack_to_receive = 0 ;
388396 h.chosen_ack = mac_harq_ack_report_status::dtx;
389397 h.last_pucch_snr = std::nullopt ;
390398 return true ;
391399}
392400
393- bool cell_harq_manager::new_ul_retx (harq_utils::ul_harq_process_impl& h, slot_point pusch_slot)
394- {
395- return ul.handle_new_retx (h, pusch_slot, pusch_slot);
396- }
397-
398- dl_harq_process_impl::status_update cell_harq_manager::dl_ack_info (harq_utils::dl_harq_process_impl& h,
399- mac_harq_ack_report_status ack,
400- std::optional<float > pucch_snr)
401+ dl_harq_process_handle::status_update dl_harq_process_handle::dl_ack_info (mac_harq_ack_report_status ack,
402+ std::optional<float > pucch_snr)
401403{
402- using status_update = dl_harq_process_impl::status_update;
403-
404+ dl_harq_process_impl& h = fetch_impl ();
404405 if (h.status != harq_state_t ::waiting_ack) {
405406 // If the HARQ process is not expecting an HARQ-ACK, it means that it has already been ACKed/NACKed.
406- logger.warning (" rnti={} h_id={}: ACK arrived for inactive DL HARQ" , h.rnti , h.h_id );
407+ harq_repo-> logger .warning (" rnti={} h_id={}: ACK arrived for inactive DL HARQ" , h.rnti , h.h_id );
407408 return status_update::error;
408409 }
409410
@@ -419,7 +420,7 @@ dl_harq_process_impl::status_update cell_harq_manager::dl_ack_info(harq_utils::d
419420
420421 // Update HARQ state
421422 bool final_ack = h.chosen_ack == mac_harq_ack_report_status::ack;
422- dl. handle_ack (h, final_ack);
423+ harq_repo-> handle_ack (h, final_ack);
423424
424425 return final_ack ? status_update::acked : status_update::nacked;
425426 }
@@ -429,48 +430,25 @@ dl_harq_process_impl::status_update cell_harq_manager::dl_ack_info(harq_utils::d
429430 h.ack_on_timeout = h.chosen_ack == mac_harq_ack_report_status::ack;
430431 // We reduce the HARQ process timeout to receive the next HARQ-ACK. This is done because the two HARQ-ACKs should
431432 // arrive almost simultaneously, and in case the second goes missing, we don't want to block the HARQ for too long.
432- dl.harq_timeout_wheel [h.slot_ack_timeout .to_uint () % dl.harq_timeout_wheel .size ()].pop (&h);
433- h.slot_ack_timeout = last_sl_tx + SHORT_ACK_TIMEOUT_DTX;
434- dl.harq_timeout_wheel [h.slot_ack_timeout .to_uint () % dl.harq_timeout_wheel .size ()].push_front (&h);
433+ auto & wheel = harq_repo->harq_timeout_wheel ;
434+ wheel[h.slot_ack_timeout .to_uint () % wheel.size ()].pop (&h);
435+ h.slot_ack_timeout = harq_repo->last_sl_ind + SHORT_ACK_TIMEOUT_DTX;
436+ wheel[h.slot_ack_timeout .to_uint () % wheel.size ()].push_front (&h);
435437
436438 return status_update::no_update;
437439}
438440
439- int cell_harq_manager::ul_crc_info (harq_utils::ul_harq_process_impl& h, bool ack)
440- {
441- if (h.status != harq_state_t ::waiting_ack) {
442- // HARQ is not expecting CRC info.
443- logger.warning (" rnti={} h_id={}: CRC arrived for UL HARQ not expecting it" , h.rnti , h.h_id );
444- return -1 ;
445- }
446-
447- ul.handle_ack (h, ack);
448-
449- return ack ? (int )h.prev_tx_params .tbs_bytes : 0 ;
450- }
451-
452- bool dl_harq_process_view::new_retx (slot_point pdsch_slot, unsigned k1, uint8_t harq_bit_idx)
453- {
454- return cell_harq_mng->new_dl_retx (fetch_impl (), pdsch_slot, k1, harq_bit_idx);
455- }
456-
457- dl_harq_process_view::status_update dl_harq_process_view::dl_ack_info (mac_harq_ack_report_status ack,
458- std::optional<float > pucch_snr)
459- {
460- return cell_harq_mng->dl_ack_info (fetch_impl (), ack, pucch_snr);
461- }
462-
463- void dl_harq_process_view::increment_pucch_counter ()
441+ void dl_harq_process_handle::increment_pucch_counter ()
464442{
465443 ++fetch_impl ().pucch_ack_to_receive ;
466444}
467445
468- void dl_harq_process_view ::cancel_retxs ()
446+ void dl_harq_process_handle ::cancel_retxs ()
469447{
470- cell_harq_mng-> dl . cancel_retxs (fetch_impl ());
448+ harq_repo-> cancel_retxs (fetch_impl ());
471449}
472450
473- void dl_harq_process_view ::save_grant_params (const dl_harq_sched_context& ctx, const pdsch_information& pdsch)
451+ void dl_harq_process_handle ::save_grant_params (const dl_harq_sched_context& ctx, const pdsch_information& pdsch)
474452{
475453 srsran_assert (pdsch.codewords .size () == 1 , " Only one codeword supported" );
476454 dl_harq_process_impl& impl = fetch_impl ();
@@ -504,22 +482,31 @@ void dl_harq_process_view::save_grant_params(const dl_harq_sched_context& ctx, c
504482 prev_params.nof_symbols = pdsch.symbols .length ();
505483}
506484
507- bool ul_harq_process_view ::new_retx (slot_point pusch_slot)
485+ bool ul_harq_process_handle ::new_retx (slot_point pusch_slot)
508486{
509- return cell_harq_mng-> new_ul_retx (cell_harq_mng-> ul . harqs [harq_ref_idx] , pusch_slot);
487+ return harq_repo-> handle_new_retx ( fetch_impl (), pusch_slot , pusch_slot);
510488}
511489
512- int ul_harq_process_view ::ul_crc_info (bool ack)
490+ int ul_harq_process_handle ::ul_crc_info (bool ack)
513491{
514- return cell_harq_mng->ul_crc_info (cell_harq_mng->ul .harqs [harq_ref_idx], ack);
492+ ul_harq_process_impl& h = fetch_impl ();
493+ if (h.status != harq_state_t ::waiting_ack) {
494+ // HARQ is not expecting CRC info.
495+ harq_repo->logger .warning (" rnti={} h_id={}: CRC arrived for UL HARQ not expecting it" , h.rnti , h.h_id );
496+ return -1 ;
497+ }
498+
499+ harq_repo->handle_ack (h, ack);
500+
501+ return ack ? (int )h.prev_tx_params .tbs_bytes : 0 ;
515502}
516503
517- void ul_harq_process_view ::cancel_retxs ()
504+ void ul_harq_process_handle ::cancel_retxs ()
518505{
519- cell_harq_mng-> ul . cancel_retxs (fetch_impl ());
506+ harq_repo-> cancel_retxs (fetch_impl ());
520507}
521508
522- void ul_harq_process_view ::save_grant_params (const ul_harq_sched_context& ctx, const pusch_information& pusch)
509+ void ul_harq_process_handle ::save_grant_params (const ul_harq_sched_context& ctx, const pusch_information& pusch)
523510{
524511 ul_harq_process_impl& impl = fetch_impl ();
525512 srsran_assert (impl.status == harq_utils::harq_state_t ::waiting_ack,
@@ -585,84 +572,85 @@ void unique_ue_harq_entity::reset()
585572 }
586573}
587574
588- std::optional<dl_harq_process_view >
575+ std::optional<dl_harq_process_handle >
589576unique_ue_harq_entity::alloc_dl_harq (slot_point sl_tx, unsigned k1, unsigned max_harq_nof_retxs, unsigned harq_bit_idx)
590577{
591578 dl_harq_process_impl* h = cell_harq_mgr->new_dl_tx (ue_index, crnti, sl_tx, k1, max_harq_nof_retxs, harq_bit_idx);
592579 if (h == nullptr ) {
593580 return std::nullopt ;
594581 }
595- return dl_harq_process_view (* cell_harq_mgr, cell_harq_mgr->dl .get_harq_ref_idx (*h));
582+ return dl_harq_process_handle ( cell_harq_mgr-> dl , cell_harq_mgr->dl .get_harq_ref_idx (*h));
596583}
597584
598- std::optional<ul_harq_process_view> unique_ue_harq_entity::alloc_ul_harq (slot_point sl_tx, unsigned max_harq_nof_retxs)
585+ std::optional<ul_harq_process_handle> unique_ue_harq_entity::alloc_ul_harq (slot_point sl_tx,
586+ unsigned max_harq_nof_retxs)
599587{
600588 ul_harq_process_impl* h = cell_harq_mgr->new_ul_tx (ue_index, crnti, sl_tx, max_harq_nof_retxs);
601589 if (h == nullptr ) {
602590 return std::nullopt ;
603591 }
604- return ul_harq_process_view (* cell_harq_mgr, cell_harq_mgr->ul .get_harq_ref_idx (*h));
592+ return ul_harq_process_handle ( cell_harq_mgr-> ul , cell_harq_mgr->ul .get_harq_ref_idx (*h));
605593}
606594
607- std::optional<dl_harq_process_view > unique_ue_harq_entity::find_pending_dl_retx ()
595+ std::optional<dl_harq_process_handle > unique_ue_harq_entity::find_pending_dl_retx ()
608596{
609597 unsigned h_ref_idx = cell_harq_mgr->dl .find_ue_harq_in_state (ue_index, harq_state_t ::pending_retx);
610598 if (h_ref_idx == INVALID_HARQ_REF_INDEX) {
611599 return std::nullopt ;
612600 }
613- return dl_harq_process_view (* cell_harq_mgr, h_ref_idx);
601+ return dl_harq_process_handle ( cell_harq_mgr-> dl , h_ref_idx);
614602}
615603
616- std::optional<ul_harq_process_view > unique_ue_harq_entity::find_pending_ul_retx ()
604+ std::optional<ul_harq_process_handle > unique_ue_harq_entity::find_pending_ul_retx ()
617605{
618606 unsigned h_ref_idx = cell_harq_mgr->ul .find_ue_harq_in_state (ue_index, harq_state_t ::pending_retx);
619607 if (h_ref_idx == INVALID_HARQ_REF_INDEX) {
620608 return std::nullopt ;
621609 }
622- return ul_harq_process_view (* cell_harq_mgr, h_ref_idx);
610+ return ul_harq_process_handle ( cell_harq_mgr-> ul , h_ref_idx);
623611}
624612
625- std::optional<dl_harq_process_view > unique_ue_harq_entity::find_dl_harq_waiting_ack ()
613+ std::optional<dl_harq_process_handle > unique_ue_harq_entity::find_dl_harq_waiting_ack ()
626614{
627615 unsigned h_ref_idx = cell_harq_mgr->dl .find_ue_harq_in_state (ue_index, harq_state_t ::waiting_ack);
628616 if (h_ref_idx == INVALID_HARQ_REF_INDEX) {
629617 return std::nullopt ;
630618 }
631- return dl_harq_process_view (* cell_harq_mgr, h_ref_idx);
619+ return dl_harq_process_handle ( cell_harq_mgr-> dl , h_ref_idx);
632620}
633621
634- std::optional<ul_harq_process_view > unique_ue_harq_entity::find_ul_harq_waiting_ack ()
622+ std::optional<ul_harq_process_handle > unique_ue_harq_entity::find_ul_harq_waiting_ack ()
635623{
636624 unsigned h_ref_idx = cell_harq_mgr->ul .find_ue_harq_in_state (ue_index, harq_state_t ::waiting_ack);
637625 if (h_ref_idx == INVALID_HARQ_REF_INDEX) {
638626 return std::nullopt ;
639627 }
640- return ul_harq_process_view (* cell_harq_mgr, h_ref_idx);
628+ return ul_harq_process_handle ( cell_harq_mgr-> ul , h_ref_idx);
641629}
642630
643- std::optional<dl_harq_process_view > unique_ue_harq_entity::find_dl_harq (slot_point uci_slot, uint8_t harq_bit_idx)
631+ std::optional<dl_harq_process_handle > unique_ue_harq_entity::find_dl_harq (slot_point uci_slot, uint8_t harq_bit_idx)
644632{
645633 const std::vector<unsigned >& dl_harqs = cell_harq_mgr->dl .ues [ue_index].harqs ;
646634 for (unsigned h_ref_idx : dl_harqs) {
647635 if (h_ref_idx != INVALID_HARQ_REF_INDEX) {
648636 const dl_harq_process_impl& h = cell_harq_mgr->dl .harqs [h_ref_idx];
649637 if (h.status == harq_utils::harq_state_t ::waiting_ack and h.slot_ack == uci_slot and
650638 h.harq_bit_idx == harq_bit_idx) {
651- return dl_harq_process_view (* cell_harq_mgr, h_ref_idx);
639+ return dl_harq_process_handle ( cell_harq_mgr-> dl , h_ref_idx);
652640 }
653641 }
654642 }
655643 return std::nullopt ;
656644}
657645
658- std::optional<ul_harq_process_view > unique_ue_harq_entity::find_ul_harq (slot_point pusch_slot)
646+ std::optional<ul_harq_process_handle > unique_ue_harq_entity::find_ul_harq (slot_point pusch_slot)
659647{
660648 const std::vector<unsigned >& ul_harqs = cell_harq_mgr->ul .ues [ue_index].harqs ;
661649 for (unsigned h_ref_idx : ul_harqs) {
662650 if (h_ref_idx != INVALID_HARQ_REF_INDEX) {
663651 const ul_harq_process_impl& h = cell_harq_mgr->ul .harqs [h_ref_idx];
664652 if (h.status == harq_utils::harq_state_t ::waiting_ack and h.slot_tx == pusch_slot) {
665- return ul_harq_process_view (* cell_harq_mgr, h_ref_idx);
653+ return ul_harq_process_handle ( cell_harq_mgr-> ul , h_ref_idx);
666654 }
667655 }
668656 }
0 commit comments