99 */
1010
1111#include " scheduler_test_simulator.h"
12+ #include " ../test_utils/indication_generators.h"
1213#include " config_generators.h"
1314#include " sched_random_utils.h"
1415#include " scheduler_test_suite.h"
@@ -50,6 +51,13 @@ scheduler_test_simulator::scheduler_test_simulator(unsigned tx_rx_dela
5051{
5152}
5253
54+ scheduler_test_simulator::scheduler_test_simulator (const scheduler_test_sim_config& cfg) :
55+ scheduler_test_simulator(cfg.sched_cfg, cfg.tx_rx_delay, cfg.max_scs)
56+ {
57+ auto_uci = cfg.auto_uci ;
58+ auto_crc = cfg.auto_crc ;
59+ }
60+
5361scheduler_test_simulator::~scheduler_test_simulator ()
5462{
5563 // Let any pending allocations complete.
@@ -79,11 +87,18 @@ void scheduler_test_simulator::add_ue(const sched_ue_creation_request_message& u
7987 run_slot ();
8088 }
8189 }
90+ rnti_to_ue_index.insert (std::make_pair (ue_request.crnti , ue_request.ue_index ));
8291}
8392
8493void scheduler_test_simulator::rem_ue (du_ue_index_t ue_index)
8594{
8695 sched->handle_ue_removal_request (ue_index);
96+ for (auto it = rnti_to_ue_index.begin (); it != rnti_to_ue_index.end (); ++it) {
97+ if (it->second == ue_index) {
98+ rnti_to_ue_index.erase (it);
99+ break ;
100+ }
101+ }
87102}
88103
89104void scheduler_test_simulator::push_dl_buffer_state (const dl_buffer_state_indication_message& upd)
@@ -114,7 +129,12 @@ void scheduler_test_simulator::run_slot(du_cell_index_t cell_idx)
114129
115130 last_sched_res_list[cell_idx] = &sched->slot_indication (next_slot, cell_idx);
116131
132+ // Ensure the scheduler result is consistent with the cell configuration and there are no collisions.
117133 test_scheduler_result_consistency (cell_cfg_list[cell_idx], next_slot, *last_sched_res_list[cell_idx]);
134+
135+ // In case auto-feedback is enabled, handle it.
136+ handle_auto_feedback (cell_idx);
137+
118138 ++next_slot;
119139}
120140
@@ -129,3 +149,51 @@ bool scheduler_test_simulator::run_slot_until(const std::function<bool()>& cond_
129149 }
130150 return count < slot_timeout;
131151}
152+
153+ void scheduler_test_simulator::handle_auto_feedback (du_cell_index_t cell_idx)
154+ {
155+ if (not auto_uci and not auto_crc) {
156+ return ;
157+ }
158+ // Note: next_slot hasn't been incremented yet.
159+ slot_point sl_rx = next_slot;
160+
161+ uci_indication uci_ind;
162+ uci_ind.cell_index = cell_idx;
163+ uci_ind.slot_rx = sl_rx;
164+ ul_crc_indication crc_ind;
165+ crc_ind.cell_index = cell_idx;
166+ crc_ind.sl_rx = sl_rx;
167+
168+ if (auto_uci) {
169+ // Handle PUCCHs.
170+ for (const pucch_info& pucch : this ->last_sched_res_list [cell_idx]->ul .pucchs ) {
171+ if (pucch.format () == pucch_format::FORMAT_1 and pucch.uci_bits .sr_bits != sr_nof_bits::no_sr) {
172+ // Skip SRs.
173+ continue ;
174+ }
175+
176+ const du_ue_index_t ue_idx = rnti_to_ue_index.at (pucch.crnti );
177+ uci_ind.ucis .push_back (test_helper::create_uci_indication_pdu (ue_idx, pucch));
178+ }
179+ }
180+
181+ for (const auto & pusch : this ->last_sched_res_list [cell_idx]->ul .puschs ) {
182+ if (auto_uci and pusch.uci .has_value ()) {
183+ const du_ue_index_t ue_idx = pusch.context .ue_index ;
184+ uci_ind.ucis .push_back (test_helper::create_uci_indication_pdu (pusch.pusch_cfg .rnti , ue_idx, pusch.uci .value ()));
185+ }
186+
187+ if (auto_crc) {
188+ crc_ind.crcs .push_back (test_helper::create_crc_pdu_indication (pusch));
189+ }
190+ }
191+
192+ // Forward indications to the scheduler.
193+ if (not uci_ind.ucis .empty ()) {
194+ this ->sched ->handle_uci_indication (uci_ind);
195+ }
196+ if (not crc_ind.crcs .empty ()) {
197+ this ->sched ->handle_crc_indication (crc_ind);
198+ }
199+ }
0 commit comments