@@ -36,6 +36,14 @@ class harq_timeout_notifier
3636 virtual void on_harq_timeout (du_ue_index_t ue_idx, bool is_dl, bool ack) = 0;
3737};
3838
39+ class noop_harq_timeout_notifier : public harq_timeout_notifier
40+ {
41+ public:
42+ void on_harq_timeout (du_ue_index_t ue_idx, bool is_dl, bool ack) override
43+ { /* do nothing */
44+ }
45+ };
46+
3947namespace harq_utils {
4048
4149const static unsigned INVALID_HARQ_REF_INDEX = std::numeric_limits<unsigned >::max();
@@ -156,7 +164,13 @@ struct cell_harq_repository {
156164class cell_harq_manager
157165{
158166public:
159- cell_harq_manager (unsigned max_ues, unsigned max_ack_wait_timeout, std::unique_ptr<harq_timeout_notifier> notifier);
167+ // / \brief Default timeout in slots after which the HARQ process assumes that the CRC/ACK went missing
168+ // / (implementation-defined).
169+ constexpr static unsigned DEFAULT_ACK_TIMEOUT_SLOTS = 256U ;
170+
171+ cell_harq_manager (unsigned max_ues = MAX_NOF_DU_UES,
172+ std::unique_ptr<harq_timeout_notifier> notifier = std::make_unique<noop_harq_timeout_notifier>(),
173+ unsigned max_ack_wait_timeout = DEFAULT_ACK_TIMEOUT_SLOTS);
160174
161175 // / Update slot, and checks if there are HARQ processes that have reached maxReTx with no ACK
162176 void slot_indication (slot_point sl_tx);
@@ -168,8 +182,10 @@ class cell_harq_manager
168182 // / Values: {2, 4, 6, 10, 12, 16}.
169183 // / \param nof_ul_harq_procs Number of UL HARQ processes that gNB can support. This value is implementation-defined
170184 // / and can up to 16 (there are up to 4 bits for HARQ-Id signalling).
171- unique_ue_harq_entity
172- add_ue (du_ue_index_t ue_idx, rnti_t crnti, unsigned nof_dl_harq_procs, unsigned nof_ul_harq_procs);
185+ unique_ue_harq_entity add_ue (du_ue_index_t ue_idx,
186+ rnti_t crnti,
187+ unsigned nof_dl_harq_procs = MAX_NOF_HARQS,
188+ unsigned nof_ul_harq_procs = MAX_NOF_HARQS);
173189
174190 // / Checks whether an UE with the provided ue index exists.
175191 bool contains (du_ue_index_t ue_idx) const ;
@@ -223,6 +239,17 @@ class dl_harq_process_view
223239 dl_harq_process_view (cell_harq_manager& cell_harq_mng_, unsigned h_ref_idx) :
224240 cell_harq_mng (&cell_harq_mng_), harq_ref_idx(h_ref_idx)
225241 {
242+ srsran_sanity_check (cell_harq_mng->dl .harqs [harq_ref_idx].status != harq_utils::harq_state_t ::empty,
243+ " Empty HARQ process created" );
244+ }
245+
246+ bool is_waiting_ack () const
247+ {
248+ return cell_harq_mng->dl .harqs [harq_ref_idx].status == harq_utils::harq_state_t ::waiting_ack;
249+ }
250+ bool has_pending_retx () const
251+ {
252+ return cell_harq_mng->dl .harqs [harq_ref_idx].status == harq_utils::harq_state_t ::pending_retx;
226253 }
227254
228255 // / \brief Update the state of the DL HARQ process waiting for an HARQ-ACK.
@@ -233,6 +260,12 @@ class dl_harq_process_view
233260
234261 const grant_params& get_grant_params () const { return cell_harq_mng->dl .harqs [harq_ref_idx].prev_tx_params ; }
235262
263+ bool operator ==(const dl_harq_process_view& other) const
264+ {
265+ return cell_harq_mng == other.cell_harq_mng and harq_ref_idx == other.harq_ref_idx ;
266+ }
267+ bool operator !=(const dl_harq_process_view& other) const { return !(*this == other); }
268+
236269private:
237270 cell_harq_manager* cell_harq_mng = nullptr ;
238271 unsigned harq_ref_idx = cell_harq_manager::INVALID_HARQ;
@@ -244,12 +277,29 @@ class ul_harq_process_view
244277 ul_harq_process_view (cell_harq_manager& cell_harq_mng_, unsigned h_ref_idx) :
245278 cell_harq_mng (&cell_harq_mng_), harq_ref_idx(h_ref_idx)
246279 {
280+ srsran_sanity_check (cell_harq_mng->ul .harqs [harq_ref_idx].status != harq_utils::harq_state_t ::empty,
281+ " Empty HARQ process created" );
282+ }
283+
284+ bool is_waiting_ack () const
285+ {
286+ return cell_harq_mng->ul .harqs [harq_ref_idx].status == harq_utils::harq_state_t ::waiting_ack;
287+ }
288+ bool has_pending_retx () const
289+ {
290+ return cell_harq_mng->ul .harqs [harq_ref_idx].status == harq_utils::harq_state_t ::pending_retx;
247291 }
248292
249293 // / Update UL HARQ state given the received CRC indication.
250294 // / \return Transport Block size of the HARQ whose state was updated.
251295 int ul_crc_info (bool ack);
252296
297+ bool operator ==(const ul_harq_process_view& other) const
298+ {
299+ return cell_harq_mng == other.cell_harq_mng and harq_ref_idx == other.harq_ref_idx ;
300+ }
301+ bool operator !=(const ul_harq_process_view& other) const { return !(*this == other); }
302+
253303private:
254304 cell_harq_manager* cell_harq_mng = nullptr ;
255305 unsigned harq_ref_idx = cell_harq_manager::INVALID_HARQ;
@@ -258,9 +308,11 @@ class ul_harq_process_view
258308class unique_ue_harq_entity
259309{
260310public:
311+ unique_ue_harq_entity () = default ;
261312 unique_ue_harq_entity (cell_harq_manager* mgr, du_ue_index_t ue_idx, rnti_t crnti_) :
262313 cell_harq_mgr (mgr), ue_index(ue_idx), crnti(crnti_)
263314 {
315+ (void )crnti;
264316 }
265317 ~unique_ue_harq_entity ();
266318 unique_ue_harq_entity (const unique_ue_harq_entity&) = delete ;
@@ -274,6 +326,8 @@ class unique_ue_harq_entity
274326 bool has_empty_dl_harqs () const { return not get_dl_ue ().free_harq_ids .empty (); }
275327 bool has_empty_ul_harqs () const { return not get_ul_ue ().free_harq_ids .empty (); }
276328
329+ void reset ();
330+
277331 std::optional<dl_harq_process_view> dl_harq (harq_id_t h_id)
278332 {
279333 if (cell_harq_mgr->dl .ues [ue_index].harqs [h_id] != harq_utils::INVALID_HARQ_REF_INDEX) {
@@ -318,7 +372,7 @@ class unique_ue_harq_entity
318372
319373 cell_harq_manager* cell_harq_mgr = nullptr ;
320374 du_ue_index_t ue_index = INVALID_DU_UE_INDEX;
321- rnti_t crnti;
375+ rnti_t crnti = rnti_t ::INVALID_RNTI ;
322376};
323377
324378} // namespace srsran
0 commit comments