@@ -424,6 +424,114 @@ void ue_event_manager::handle_dl_buffer_state_indication(const dl_buffer_state_i
424424 dl_bo_mng->handle_dl_buffer_state_indication (bs);
425425}
426426
427+ static void handle_discarded_pusch (const cell_slot_resource_allocator& prev_slot_result, ue_repository& ue_db)
428+ {
429+ for (const ul_sched_info& grant : prev_slot_result.result .ul .puschs ) {
430+ ue* u = ue_db.find_by_rnti (grant.pusch_cfg .rnti );
431+ if (u == nullptr ) {
432+ // UE has been removed.
433+ continue ;
434+ }
435+
436+ // - The lower layers will not attempt to decode the PUSCH and will not send any CRC indication.
437+ ul_harq_process& h_ul = u->get_pcell ().harqs .ul_harq (grant.pusch_cfg .harq_id );
438+ if (not h_ul.empty ()) {
439+ if (h_ul.tb ().nof_retxs == 0 ) {
440+ // Given that the PUSCH grant was discarded before it reached the PHY, the "new_data" flag was not handled
441+ // and the UL softbuffer was not reset. To avoid mixing different TBs in the softbuffer, it is important to
442+ // reset the UL HARQ process.
443+ h_ul.reset ();
444+ } else {
445+ // To avoid a long UL HARQ timeout window (due to lack of CRC indication), it is important to force a NACK
446+ // in the UL HARQ process.
447+ h_ul.crc_info (false );
448+ }
449+ }
450+
451+ // - The lower layers will not attempt to decode any UCI in the PUSCH and will not send any UCI indication.
452+ if (grant.uci .has_value () and grant.uci ->harq .has_value () and grant.uci ->harq ->harq_ack_nof_bits > 0 ) {
453+ // To avoid a long DL HARQ timeout window (due to lack of UCI indication), it is important to NACK the
454+ // DL HARQ processes with UCI falling in this slot.
455+ u->get_pcell ().harqs .dl_ack_info_cancelled (prev_slot_result.slot );
456+ }
457+ }
458+ }
459+
460+ static void handle_discarded_pucch (const cell_slot_resource_allocator& prev_slot_result, ue_repository& ue_db)
461+ {
462+ for (const auto & pucch : prev_slot_result.result .ul .pucchs ) {
463+ ue* u = ue_db.find_by_rnti (pucch.crnti );
464+ if (u == nullptr ) {
465+ // UE has been removed.
466+ continue ;
467+ }
468+ bool has_harq_ack = false ;
469+ switch (pucch.format ) {
470+ case pucch_format::FORMAT_1:
471+ has_harq_ack = pucch.format_1 .harq_ack_nof_bits > 0 ;
472+ break ;
473+ case pucch_format::FORMAT_2:
474+ has_harq_ack = pucch.format_2 .harq_ack_nof_bits > 0 ;
475+ break ;
476+ default :
477+ break ;
478+ }
479+
480+ // - The lower layers will not attempt to decode the PUCCH and will not send any UCI indication.
481+ if (has_harq_ack) {
482+ // To avoid a long DL HARQ timeout window (due to lack of UCI indication), it is important to force a NACK in
483+ // the DL HARQ processes with UCI falling in this slot.
484+ u->get_pcell ().harqs .dl_ack_info_cancelled (prev_slot_result.slot );
485+ }
486+ }
487+ }
488+
489+ void ue_event_manager::handle_error_indication (slot_point sl_tx,
490+ du_cell_index_t cell_index,
491+ scheduler_slot_handler::error_outcome event)
492+ {
493+ common_events.emplace (INVALID_DU_UE_INDEX, [this , sl_tx, cell_index, event]() {
494+ // Handle Error Indication.
495+
496+ const cell_slot_resource_allocator* prev_slot_result = du_cells[cell_index].res_grid ->get_history (sl_tx);
497+ if (prev_slot_result == nullptr ) {
498+ logger.warning (" cell={}, slot={}: Discarding error indication. Cause: Scheduler results associated with the slot "
499+ " of the error indication have already been erased" ,
500+ cell_index,
501+ sl_tx);
502+ return ;
503+ }
504+
505+ // In case DL PDCCHs were skipped, there will be the following consequences:
506+ // - The UE will not decode the PDSCH and will not send the respective UCI.
507+ // - The UE won't update the HARQ NDI, if new HARQ TB.
508+ // - The UCI indication coming later from the lower layers will likely contain a HARQ-ACK=DTX.
509+ // In case UL PDCCHs were skipped, there will be the following consequences:
510+ // - The UE will not decode the PUSCH.
511+ // - The UE won't update the HARQ NDI, if new HARQ TB.
512+ // - The CRC indication coming from the lower layers will likely be CRC=KO.
513+ // - Any UCI in the respective PUSCH will be likely reported as HARQ-ACK=DTX.
514+ // In neither of the cases, the HARQs will timeout, because we did not lose the UCI/CRC indications in the lower
515+ // layers. We do not need to cancel associated PUSCH grant (in UL PDCCH case) because it is important that
516+ // the PUSCH "new_data" flag reaches the lower layers, telling them whether the UL HARQ buffer needs to be reset or
517+ // not. Cancelling HARQ retransmissions is dangerous as it increases the chances of NDI ambiguity.
518+
519+ // In case of PDSCH grants being discarded, there will be the following consequences:
520+ // - If the PDCCH was not discarded,the UE will fail to decode the PDSCH and will send an HARQ-ACK=NACK. The
521+ // scheduler will retransmit the respective DL HARQ. No actions required.
522+
523+ // In case of PUCCH and PUSCH grants being discarded.
524+ if (event.pusch_and_pucch_discarded ) {
525+ handle_discarded_pusch (*prev_slot_result, ue_db);
526+
527+ handle_discarded_pucch (*prev_slot_result, ue_db);
528+ }
529+
530+ // Log event.
531+ ev_logger.enqueue (scheduler_event_logger::error_indication_event{sl_tx, event});
532+ });
533+ }
534+
427535void ue_event_manager::process_common (slot_point sl, du_cell_index_t cell_index)
428536{
429537 bool new_slot_detected = last_sl != sl;
@@ -495,12 +603,14 @@ void ue_event_manager::run(slot_point sl, du_cell_index_t cell_index)
495603 process_cell_specific (cell_index);
496604}
497605
498- void ue_event_manager::add_cell (const cell_configuration& cell_cfg_ , ue_srb0_scheduler& srb0_sched)
606+ void ue_event_manager::add_cell (cell_resource_allocator& cell_res_grid , ue_srb0_scheduler& srb0_sched)
499607{
500- srsran_assert (not cell_exists (cell_cfg_.cell_index ), " Overwriting cell configurations not supported" );
608+ const du_cell_index_t cell_index = cell_res_grid.cell_index ();
609+ srsran_assert (not cell_exists (cell_index), " Overwriting cell configurations not supported" );
501610
502- du_cells[cell_cfg_.cell_index ].cfg = &cell_cfg_;
503- du_cells[cell_cfg_.cell_index ].srb0_sched = &srb0_sched;
611+ du_cells[cell_index].cfg = &cell_res_grid.cfg ;
612+ du_cells[cell_index].res_grid = &cell_res_grid;
613+ du_cells[cell_index].srb0_sched = &srb0_sched;
504614}
505615
506616bool ue_event_manager::cell_exists (du_cell_index_t cell_index) const
0 commit comments