diff --git a/lib/include/srslte/interfaces/sched_interface.h b/lib/include/srslte/interfaces/sched_interface.h index d34a0275d..ce6b11885 100644 --- a/lib/include/srslte/interfaces/sched_interface.h +++ b/lib/include/srslte/interfaces/sched_interface.h @@ -256,23 +256,23 @@ public: virtual int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code) = 0; /* DL information */ - virtual int dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t tb_idx, bool ack) = 0; - virtual int dl_rach_info(uint32_t cc_idx, dl_sched_rar_info_t rar_info) = 0; - virtual int dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t ri_value) = 0; - virtual int dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t pmi_value) = 0; - virtual int dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t cqi_value) = 0; + virtual int dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) = 0; + virtual int dl_rach_info(uint32_t enb_cc_idx, dl_sched_rar_info_t rar_info) = 0; + virtual int dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value) = 0; + virtual int dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi_value) = 0; + virtual int dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi_value) = 0; /* UL information */ - virtual int ul_crc_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, bool crc) = 0; - virtual int ul_sr_info(uint32_t tti, uint16_t rnti) = 0; - virtual int ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr, bool set_value = true) = 0; - virtual int ul_recv_len(uint16_t rnti, uint32_t lcid, uint32_t len) = 0; - virtual int ul_phr(uint16_t rnti, int phr) = 0; - virtual int ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t cqi, uint32_t ul_ch_code) = 0; + virtual int ul_crc_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, bool crc) = 0; + virtual int ul_sr_info(uint32_t tti, uint16_t rnti) = 0; + virtual int ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr, bool set_value = true) = 0; + virtual int ul_recv_len(uint16_t rnti, uint32_t lcid, uint32_t len) = 0; + virtual int ul_phr(uint16_t rnti, int phr) = 0; + virtual int ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code) = 0; /* Run Scheduler for this tti */ - virtual int dl_sched(uint32_t tti, uint32_t cc_idx, dl_sched_res_t& sched_result) = 0; - virtual int ul_sched(uint32_t tti, uint32_t cc_idx, ul_sched_res_t& sched_result) = 0; + virtual int dl_sched(uint32_t tti, uint32_t enb_cc_idx, dl_sched_res_t& sched_result) = 0; + virtual int ul_sched(uint32_t tti, uint32_t enb_cc_idx, ul_sched_res_t& sched_result) = 0; /* Custom */ virtual void set_dl_tti_mask(uint8_t* tti_mask, uint32_t nof_sfs) = 0; diff --git a/srsenb/hdr/stack/mac/scheduler.h b/srsenb/hdr/stack/mac/scheduler.h index c572fb3bb..e363ad418 100644 --- a/srsenb/hdr/stack/mac/scheduler.h +++ b/srsenb/hdr/stack/mac/scheduler.h @@ -144,21 +144,20 @@ public: int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) final; int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code) final; - int dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t tb_idx, bool ack) final; - int dl_rach_info(uint32_t cc_idx, dl_sched_rar_info_t rar_info) final; - int dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t ri_value) final; - int dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t pmi_value) final; - int dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t cqi_value) final; - - int ul_crc_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, bool crc) final; + int dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) final; + int dl_rach_info(uint32_t enb_cc_idx, dl_sched_rar_info_t rar_info) final; + int dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value) final; + int dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi_value) final; + int dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi_value) final; + int ul_crc_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, bool crc) final; int ul_sr_info(uint32_t tti, uint16_t rnti) override; int ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr, bool set_value = true) final; int ul_recv_len(uint16_t rnti, uint32_t lcid, uint32_t len) final; int ul_phr(uint16_t rnti, int phr) final; - int ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t cqi, uint32_t ul_ch_code) final; + int ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code) final; - int dl_sched(uint32_t tti, uint32_t cc_idx, dl_sched_res_t& sched_result) final; - int ul_sched(uint32_t tti, uint32_t cc_idx, ul_sched_res_t& sched_result) final; + int dl_sched(uint32_t tti, uint32_t enb_cc_idx, dl_sched_res_t& sched_result) final; + int ul_sched(uint32_t tti, uint32_t enb_cc_idx, ul_sched_res_t& sched_result) final; /* Custom functions */ diff --git a/srsenb/hdr/stack/mac/scheduler_ue.h b/srsenb/hdr/stack/mac/scheduler_ue.h index 882ccad21..c44c50d79 100644 --- a/srsenb/hdr/stack/mac/scheduler_ue.h +++ b/srsenb/hdr/stack/mac/scheduler_ue.h @@ -125,12 +125,13 @@ public: void mac_buffer_state(uint32_t ce_code); void ul_recv_len(uint32_t lcid, uint32_t len); void set_dl_ant_info(const sched_interface::ant_info_ded_t& dedicated); - void set_ul_cqi(uint32_t tti, uint32_t cc_idx, uint32_t cqi, uint32_t ul_ch_code); - void set_dl_ri(uint32_t tti, uint32_t cc_idx, uint32_t ri); - void set_dl_pmi(uint32_t tti, uint32_t cc_idx, uint32_t ri); - void set_dl_cqi(uint32_t tti, uint32_t cc_idx, uint32_t cqi); - int set_ack_info(uint32_t tti, uint32_t cc_idx, uint32_t tb_idx, bool ack); - void set_ul_crc(uint32_t tti, uint32_t cc_idx, bool crc_res); + + void set_ul_cqi(uint32_t tti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code); + void set_dl_ri(uint32_t tti, uint32_t enb_cc_idx, uint32_t ri); + void set_dl_pmi(uint32_t tti, uint32_t enb_cc_idx, uint32_t ri); + void set_dl_cqi(uint32_t tti, uint32_t enb_cc_idx, uint32_t cqi); + int set_ack_info(uint32_t tti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack); + void set_ul_crc(uint32_t tti, uint32_t enb_cc_idx, bool crc_res); /******************************************************* * Custom functions diff --git a/srsenb/src/stack/mac/scheduler.cc b/srsenb/src/stack/mac/scheduler.cc index be13a1543..ef729bb84 100644 --- a/srsenb/src/stack/mac/scheduler.cc +++ b/srsenb/src/stack/mac/scheduler.cc @@ -292,32 +292,33 @@ int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code) return ue_db_access(rnti, [ce_code](sched_ue& ue) { ue.mac_buffer_state(ce_code); }); } -int sched::dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t tb_idx, bool ack) +int sched::dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) { int ret = -1; - ue_db_access(rnti, - [tti, cc_idx, tb_idx, ack, &ret](sched_ue& ue) { ret = ue.set_ack_info(tti, cc_idx, tb_idx, ack); }); + ue_db_access(rnti, [tti, enb_cc_idx, tb_idx, ack, &ret](sched_ue& ue) { + ret = ue.set_ack_info(tti, enb_cc_idx, tb_idx, ack); + }); return ret; } -int sched::ul_crc_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, bool crc) +int sched::ul_crc_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, bool crc) { - return ue_db_access(rnti, [tti, cc_idx, crc](sched_ue& ue) { ue.set_ul_crc(tti, cc_idx, crc); }); + return ue_db_access(rnti, [tti, enb_cc_idx, crc](sched_ue& ue) { ue.set_ul_crc(tti, enb_cc_idx, crc); }); } -int sched::dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t ri_value) +int sched::dl_ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value) { - return ue_db_access(rnti, [tti, cc_idx, ri_value](sched_ue& ue) { ue.set_dl_ri(tti, cc_idx, ri_value); }); + return ue_db_access(rnti, [tti, enb_cc_idx, ri_value](sched_ue& ue) { ue.set_dl_ri(tti, enb_cc_idx, ri_value); }); } -int sched::dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t pmi_value) +int sched::dl_pmi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t pmi_value) { - return ue_db_access(rnti, [tti, cc_idx, pmi_value](sched_ue& ue) { ue.set_dl_pmi(tti, cc_idx, pmi_value); }); + return ue_db_access(rnti, [tti, enb_cc_idx, pmi_value](sched_ue& ue) { ue.set_dl_pmi(tti, enb_cc_idx, pmi_value); }); } -int sched::dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t cqi_value) +int sched::dl_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi_value) { - return ue_db_access(rnti, [tti, cc_idx, cqi_value](sched_ue& ue) { ue.set_dl_cqi(tti, cc_idx, cqi_value); }); + return ue_db_access(rnti, [tti, enb_cc_idx, cqi_value](sched_ue& ue) { ue.set_dl_cqi(tti, enb_cc_idx, cqi_value); }); } int sched::dl_rach_info(uint32_t enb_cc_idx, dl_sched_rar_info_t rar_info) @@ -325,10 +326,10 @@ int sched::dl_rach_info(uint32_t enb_cc_idx, dl_sched_rar_info_t rar_info) return carrier_schedulers[enb_cc_idx]->dl_rach_info(rar_info); } -int sched::ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t cqi, uint32_t ul_ch_code) +int sched::ul_cqi_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code) { - return ue_db_access(rnti, - [tti, cc_idx, cqi, ul_ch_code](sched_ue& ue) { ue.set_ul_cqi(tti, cc_idx, cqi, ul_ch_code); }); + return ue_db_access( + rnti, [tti, enb_cc_idx, cqi, ul_ch_code](sched_ue& ue) { ue.set_ul_cqi(tti, enb_cc_idx, cqi, ul_ch_code); }); } int sched::ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr, bool set_value) diff --git a/srsenb/src/stack/mac/scheduler_ue.cc b/srsenb/src/stack/mac/scheduler_ue.cc index 59d763ea2..12df91d1f 100644 --- a/srsenb/src/stack/mac/scheduler_ue.cc +++ b/srsenb/src/stack/mac/scheduler_ue.cc @@ -247,14 +247,15 @@ bool sched_ue::pucch_sr_collision(uint32_t current_tti, uint32_t n_cce) return false; } -int sched_ue::set_ack_info(uint32_t tti, uint32_t cc_idx, uint32_t tb_idx, bool ack) +int sched_ue::set_ack_info(uint32_t tti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) { std::lock_guard lock(mutex); int ret = -1; - if (cc_idx < carriers.size()) { - ret = carriers[cc_idx].set_ack_info(tti, tb_idx, ack); + auto p = get_cell_index(enb_cc_idx); + if (p.first) { + ret = carriers[p.second].set_ack_info(tti, tb_idx, ack); } else { - log_h->warning("Received DL ACK for invalid cell index %d\n", cc_idx); + log_h->warning("Received DL ACK for invalid cell index %d\n", enb_cc_idx); } return ret; } @@ -279,47 +280,64 @@ void sched_ue::ul_recv_len(uint32_t lcid, uint32_t len) Debug("SCHED: recv_len=%d, lcid=%d, bsr={%d,%d,%d,%d}\n", len, lcid, lch[0].bsr, lch[1].bsr, lch[2].bsr, lch[3].bsr); } -void sched_ue::set_ul_crc(uint32_t tti, uint32_t cc_idx, bool crc_res) +void sched_ue::set_ul_crc(uint32_t tti, uint32_t enb_cc_idx, bool crc_res) { std::lock_guard lock(mutex); - get_ul_harq(tti, cc_idx)->set_ack(0, crc_res); + auto p = get_cell_index(enb_cc_idx); + if (p.first) { + get_ul_harq(tti, p.second)->set_ack(0, crc_res); + } else { + log_h->warning("Received UL CRC for invalid cell index %d\n", enb_cc_idx); + } } -void sched_ue::set_dl_ri(uint32_t tti, uint32_t cc_idx, uint32_t ri) +void sched_ue::set_dl_ri(uint32_t tti, uint32_t enb_cc_idx, uint32_t ri) { std::lock_guard lock(mutex); - carriers[cc_idx].dl_ri = ri; - carriers[cc_idx].dl_ri_tti = tti; + auto p = get_cell_index(enb_cc_idx); + if (p.first) { + carriers[p.second].dl_ri = ri; + carriers[p.second].dl_ri_tti = tti; + } else { + log_h->warning("Received DL RI for invalid cell index %d\n", enb_cc_idx); + } } -void sched_ue::set_dl_pmi(uint32_t tti, uint32_t cc_idx, uint32_t pmi) +void sched_ue::set_dl_pmi(uint32_t tti, uint32_t enb_cc_idx, uint32_t pmi) { std::lock_guard lock(mutex); - if (cc_idx >= carriers.size()) { - log_h->warning("Received DL PMI for invalid cell index %d\n", cc_idx); - return; + auto p = get_cell_index(enb_cc_idx); + if (p.first) { + carriers[p.second].dl_pmi = pmi; + carriers[p.second].dl_pmi_tti = tti; + } else { + log_h->warning("Received DL PMI for invalid cell index %d\n", enb_cc_idx); } - carriers[cc_idx].dl_pmi = pmi; - carriers[cc_idx].dl_pmi_tti = tti; } -void sched_ue::set_dl_cqi(uint32_t tti, uint32_t cc_idx, uint32_t cqi) +void sched_ue::set_dl_cqi(uint32_t tti, uint32_t enb_cc_idx, uint32_t cqi) { std::lock_guard lock(mutex); - if (cc_idx >= carriers.size()) { - log_h->warning("Received DL CQI for invalid cell index %d\n", cc_idx); - return; + auto p = get_cell_index(enb_cc_idx); + if (p.second != std::numeric_limits::max()) { + carriers[p.second].dl_cqi = cqi; + carriers[p.second].dl_cqi_tti = tti; + carriers[p.second].update_cell_activity(); + } else { + log_h->warning("Received DL CQI for invalid cell index %d\n", enb_cc_idx); } - carriers[cc_idx].dl_cqi = cqi; - carriers[cc_idx].dl_cqi_tti = tti; - carriers[cc_idx].update_cell_activity(); } -void sched_ue::set_ul_cqi(uint32_t tti, uint32_t cc_idx, uint32_t cqi, uint32_t ul_ch_code) +void sched_ue::set_ul_cqi(uint32_t tti, uint32_t enb_cc_idx, uint32_t cqi, uint32_t ul_ch_code) { std::lock_guard lock(mutex); - carriers[cc_idx].ul_cqi = cqi; - carriers[cc_idx].ul_cqi_tti = tti; + auto p = get_cell_index(enb_cc_idx); + if (p.first) { + carriers[p.second].ul_cqi = cqi; + carriers[p.second].ul_cqi_tti = tti; + } else { + log_h->warning("Received SNR info for invalid cell index %d\n", enb_cc_idx); + } } void sched_ue::tpc_inc() @@ -906,11 +924,11 @@ void sched_ue::reset_pending_pids(uint32_t tti_rx, uint32_t cc_idx) } /* Gets HARQ process with oldest pending retx */ -dl_harq_proc* sched_ue::get_pending_dl_harq(uint32_t tti_tx_dl, uint32_t cc_idx) +dl_harq_proc* sched_ue::get_pending_dl_harq(uint32_t tti_tx_dl, uint32_t ue_cc_idx) { std::lock_guard lock(mutex); - if (cc_idx < carriers.size() and carriers[cc_idx].is_active()) { - return carriers[cc_idx].get_pending_dl_harq(tti_tx_dl); + if (ue_cc_idx < carriers.size() and carriers[ue_cc_idx].is_active()) { + return carriers[ue_cc_idx].get_pending_dl_harq(tti_tx_dl); } return nullptr; } @@ -932,9 +950,9 @@ ul_harq_proc* sched_ue::get_ul_harq(uint32_t tti_tx_ul, uint32_t ue_cc_idx) return nullptr; } -dl_harq_proc* sched_ue::find_dl_harq(uint32_t tti_rx, uint32_t cc_idx) +dl_harq_proc* sched_ue::find_dl_harq(uint32_t tti_rx, uint32_t ue_cc_idx) { - for (auto& h : carriers[cc_idx].dl_harq) { + for (auto& h : carriers[ue_cc_idx].dl_harq) { if (h.get_tti() == tti_rx) { return &h; } @@ -942,9 +960,9 @@ dl_harq_proc* sched_ue::find_dl_harq(uint32_t tti_rx, uint32_t cc_idx) return nullptr; } -dl_harq_proc* sched_ue::get_dl_harq(uint32_t idx, uint32_t cc_idx) +dl_harq_proc* sched_ue::get_dl_harq(uint32_t idx, uint32_t ue_cc_idx) { - return &carriers[cc_idx].dl_harq[idx]; + return &carriers[ue_cc_idx].dl_harq[idx]; } std::pair sched_ue::get_cell_index(uint32_t enb_cc_idx) const @@ -955,9 +973,9 @@ std::pair sched_ue::get_cell_index(uint32_t enb_cc_idx) const [enb_cc_idx](const sched_interface::ue_cfg_t::cc_cfg_t& u) { return u.enb_cc_idx == enb_cc_idx and u.active; }); if (it != cfg.supported_cc_list.end()) { uint32_t ue_cc_idx = std::distance(cfg.supported_cc_list.begin(), it); - return {carriers[ue_cc_idx].is_active(), enb_cc_idx}; + return {carriers[ue_cc_idx].is_active(), ue_cc_idx}; } - return {false, 0}; + return {false, std::numeric_limits::max()}; } void sched_ue::finish_tti(const tti_params_t& tti_params, uint32_t enb_cc_idx) @@ -1007,10 +1025,10 @@ srslte_dci_format_t sched_ue::get_dci_format() sched_dci_cce_t* sched_ue::get_locations(uint32_t enb_cc_idx, uint32_t cfi, uint32_t sf_idx) { if (cfi > 0 && cfi <= 3) { - return &carriers[enb_cc_idx].dci_locations[cfi - 1][sf_idx]; + return &carriers[get_cell_index(enb_cc_idx).second].dci_locations[cfi - 1][sf_idx]; } else { Error("SCHED: Invalid CFI=%d\n", cfi); - return &carriers[enb_cc_idx].dci_locations[0][sf_idx]; + return &carriers[get_cell_index(enb_cc_idx).second].dci_locations[0][sf_idx]; } } @@ -1354,8 +1372,10 @@ uint32_t sched_ue_carrier::get_required_prb_ul(uint32_t req_bytes) void sched_ue_carrier::update_cell_activity() { if (ue_cc_idx > 0 and active != cfg->supported_cc_list[ue_cc_idx].active) { - active = cfg->supported_cc_list[ue_cc_idx].active; - log_h->info("SCell index=%d is now %s\n", ue_cc_idx, active ? "active" : "inactive"); + if (dl_cqi > 0) { + active = cfg->supported_cc_list[ue_cc_idx].active; + log_h->info("SCell index=%d is now %s\n", ue_cc_idx, active ? "active" : "inactive"); + } } } diff --git a/srsenb/test/mac/scheduler_ca_test.cc b/srsenb/test/mac/scheduler_ca_test.cc index 13a82fc18..7a1dda6a6 100644 --- a/srsenb/test/mac/scheduler_ca_test.cc +++ b/srsenb/test/mac/scheduler_ca_test.cc @@ -80,7 +80,11 @@ sim_sched_args generate_default_sim_args(uint32_t nof_prb, uint32_t nof_ccs) return sim_args; } -int run_sim1() +struct test_scell_activation_params { + uint32_t pcell_idx = 0; +}; + +int test_scell_activation(test_scell_activation_params params) { /* Simulation Configuration Arguments */ uint32_t nof_prb = 25; @@ -103,20 +107,24 @@ int run_sim1() float ul_sr_exps[] = {1, 4}; // log rand float dl_data_exps[] = {1, 4}; // log rand float P_ul_sr = randf() * 0.5, P_dl = randf() * 0.5; - const uint16_t rnti1 = 70; - uint32_t pcell_idx = 0; + const uint16_t rnti1 = 70; /* Setup Simulation */ uint32_t prach_tti = 1, msg4_tot_delay = 10; // TODO: check correct value uint32_t msg4_size = 20; // TODO: Check uint32_t duration = 1000; + // Generate Cell order + std::vector cc_idxs(nof_ccs); + std::iota(cc_idxs.begin(), cc_idxs.end(), 0); + std::shuffle(cc_idxs.begin(), cc_idxs.end(), get_rand_gen()); + std::iter_swap(cc_idxs.begin(), std::find(cc_idxs.begin(), cc_idxs.end(), params.pcell_idx)); /* Simulation */ // Event PRACH: PRACH takes place for "rnti1", and carrier "pcell_idx" generator.step_until(prach_tti); tti_ev::user_cfg_ev* user = generator.add_new_default_user(duration); - user->ue_cfg->supported_cc_list[0].enb_cc_idx = pcell_idx; + user->ue_cfg->supported_cc_list[0].enb_cc_idx = cc_idxs[0]; user->rnti = rnti1; tester.test_next_ttis(generator.tti_events); TESTASSERT(tester.ue_tester->user_exists(rnti1)); @@ -151,45 +159,54 @@ int run_sim1() user->ue_cfg->supported_cc_list.resize(nof_ccs); for (uint32_t i = 0; i < user->ue_cfg->supported_cc_list.size(); ++i) { user->ue_cfg->supported_cc_list[i].active = true; - user->ue_cfg->supported_cc_list[i].enb_cc_idx = i; + user->ue_cfg->supported_cc_list[i].enb_cc_idx = cc_idxs[i]; } tester.test_next_ttis(generator.tti_events); - // When a DL newtx takes place, it should also encode the CE + // TEST: When a DL newtx takes place, it should also encode the CE for (uint32_t i = 0; i < 100; ++i) { - TESTASSERT(tester.tti_info.dl_sched_result[pcell_idx].nof_data_elems > 0); - if (tester.tti_info.dl_sched_result[pcell_idx].data[0].nof_pdu_elems[0] > 0) { + TESTASSERT(tester.tti_info.dl_sched_result[params.pcell_idx].nof_data_elems > 0); + if (tester.tti_info.dl_sched_result[params.pcell_idx].data[0].nof_pdu_elems[0] > 0) { // it is a new DL tx - TESTASSERT(tester.tti_info.dl_sched_result[pcell_idx].data[0].pdu[0][0].lcid == + TESTASSERT(tester.tti_info.dl_sched_result[params.pcell_idx].data[0].pdu[0][0].lcid == srslte::sch_subh::cetype::SCELL_ACTIVATION); break; } generator.step_tti(); tester.test_next_ttis(generator.tti_events); } + + // Event: Wait for UE to receive and ack CE. Send cqi==0, which should not activate the SCell + uint32_t cqi = 0; for (uint32_t i = 0; i < TX_DELAY; ++i) { + tester.dl_cqi_info(tester.tti_info.tti_params.tti_rx, rnti1, 1, cqi); generator.step_tti(); } tester.test_next_ttis(generator.tti_events); - // The UE has now received the CE + // The UE should now have received the CE // Event: Generate a bit more data, it should *not* go through SCells until we send a CQI + tester.dl_cqi_info(tester.tti_info.tti_params.tti_rx, rnti1, 1, cqi); generate_data(5, P_dl, P_ul_sr); tester.test_next_ttis(generator.tti_events); - TESTASSERT(tester.sched_stats->users[rnti1].tot_dl_sched_data[0] > 0); - TESTASSERT(tester.sched_stats->users[rnti1].tot_dl_sched_data[1] == 0); - TESTASSERT(tester.sched_stats->users[rnti1].tot_ul_sched_data[0] > 0); - TESTASSERT(tester.sched_stats->users[rnti1].tot_ul_sched_data[1] == 0); + TESTASSERT(tester.sched_stats->users[rnti1].tot_dl_sched_data[params.pcell_idx] > 0); + TESTASSERT(tester.sched_stats->users[rnti1].tot_ul_sched_data[params.pcell_idx] > 0); + for (uint32_t i = 1; i < cc_idxs.size(); ++i) { + TESTASSERT(tester.sched_stats->users[rnti1].tot_dl_sched_data[cc_idxs[i]] == 0); + TESTASSERT(tester.sched_stats->users[rnti1].tot_ul_sched_data[cc_idxs[i]] == 0); + } // Event: Scheduler receives dl_cqi for SCell. Data should go through SCells - const uint32_t cqi = 14; - tester.dl_cqi_info(tester.tti_info.tti_params.tti_rx, rnti1, 1, cqi); + cqi = 14; + for (uint32_t i = 1; i < cc_idxs.size(); ++i) { + tester.dl_cqi_info(tester.tti_info.tti_params.tti_rx, rnti1, cc_idxs[i], cqi); + } generate_data(10, 1.0, 1.0); tester.test_next_ttis(generator.tti_events); - TESTASSERT(tester.sched_stats->users[rnti1].tot_dl_sched_data[0] > 0); - TESTASSERT(tester.sched_stats->users[rnti1].tot_dl_sched_data[1] > 0); - TESTASSERT(tester.sched_stats->users[rnti1].tot_ul_sched_data[0] > 0); - TESTASSERT(tester.sched_stats->users[rnti1].tot_ul_sched_data[1] > 0); + for (const auto& c : cc_idxs) { + TESTASSERT(tester.sched_stats->users[rnti1].tot_dl_sched_data[c] > 0); + TESTASSERT(tester.sched_stats->users[rnti1].tot_ul_sched_data[c] > 0); + } log_global->info("[TESTER] Sim1 finished successfully\n"); return SRSLTE_SUCCESS; @@ -202,10 +219,17 @@ int main() srslte::logmap::get_instance()->set_default_log_level(srslte::LOG_LEVEL_INFO); printf("[TESTER] This is the chosen seed: %u\n", seed); - uint32_t N_runs = 1; + uint32_t N_runs = 5; for (uint32_t n = 0; n < N_runs; ++n) { printf("Sim run number: %u\n", n + 1); - TESTASSERT(run_sim1() == SRSLTE_SUCCESS); + + test_scell_activation_params p = {}; + p.pcell_idx = 0; + TESTASSERT(test_scell_activation(p) == SRSLTE_SUCCESS); + + p = {}; + p.pcell_idx = 1; + TESTASSERT(test_scell_activation(p) == SRSLTE_SUCCESS); } return 0; diff --git a/srsenb/test/mac/scheduler_test_common.cc b/srsenb/test/mac/scheduler_test_common.cc index f0afbe1ef..20b8df13d 100644 --- a/srsenb/test/mac/scheduler_test_common.cc +++ b/srsenb/test/mac/scheduler_test_common.cc @@ -695,7 +695,7 @@ int common_sched_tester::process_ack_txs() if (dl_ack.dl_harq.is_empty(tb)) { continue; } - ret |= dl_ack_info(tti_info.tti_params.tti_rx, dl_ack.rnti, dl_ack.ue_cc_idx, tb, dl_ack.ack) > 0; + ret |= dl_ack_info(tti_info.tti_params.tti_rx, dl_ack.rnti, dl_ack.enb_cc_idx, tb, dl_ack.ack) > 0; } CONDERROR(not ret, "The dl harq proc that was ACKed does not exist\n"); @@ -722,7 +722,7 @@ int common_sched_tester::process_ack_txs() CONDERROR(h->is_empty(0), "The acked UL harq is not active\n"); CONDERROR(hack.is_empty(0), "The acked UL harq was not active\n"); - ul_crc_info(tti_info.tti_params.tti_rx, ul_ack.rnti, ul_ack.ue_cc_idx, ul_ack.ack); + ul_crc_info(tti_info.tti_params.tti_rx, ul_ack.rnti, ul_ack.enb_cc_idx, ul_ack.ack); CONDERROR(!h->get_pending_data(), "UL harq lost its pending data\n"); CONDERROR(!h->has_pending_ack(), "ACK/NACKed UL harq should have a pending ACK\n"); @@ -751,11 +751,12 @@ int common_sched_tester::schedule_acks() // schedule future acks for (uint32_t i = 0; i < tti_info.dl_sched_result[ccidx].nof_data_elems; ++i) { ack_info_t ack_data; - ack_data.rnti = tti_info.dl_sched_result[ccidx].data[i].dci.rnti; - ack_data.tti = FDD_HARQ_DELAY_MS + tti_info.tti_params.tti_tx_dl; - ack_data.ue_cc_idx = ue_db[ack_data.rnti].get_cell_index(ccidx).second; + ack_data.rnti = tti_info.dl_sched_result[ccidx].data[i].dci.rnti; + ack_data.tti = FDD_HARQ_DELAY_MS + tti_info.tti_params.tti_tx_dl; + ack_data.enb_cc_idx = ccidx; + ack_data.ue_cc_idx = ue_db[ack_data.rnti].get_cell_index(ccidx).second; const srsenb::dl_harq_proc* dl_h = - ue_db[ack_data.rnti].get_dl_harq(tti_info.dl_sched_result[ccidx].data[i].dci.pid, ccidx); + ue_db[ack_data.rnti].get_dl_harq(tti_info.dl_sched_result[ccidx].data[i].dci.pid, ack_data.ue_cc_idx); ack_data.dl_harq = *dl_h; if (ack_data.dl_harq.nof_retx(0) == 0) { ack_data.ack = randf() > sim_args0.P_retx; @@ -785,11 +786,12 @@ int common_sched_tester::schedule_acks() for (uint32_t i = 0; i < tti_info.ul_sched_result[ccidx].nof_dci_elems; ++i) { const auto& pusch = tti_info.ul_sched_result[ccidx].pusch[i]; ul_ack_info_t ack_data; - ack_data.rnti = pusch.dci.rnti; - ack_data.ul_harq = *ue_db[ack_data.rnti].get_ul_harq(tti_info.tti_params.tti_tx_ul, ccidx); - ack_data.tti_tx_ul = tti_info.tti_params.tti_tx_ul; - ack_data.tti_ack = tti_info.tti_params.tti_tx_ul + FDD_HARQ_DELAY_MS; - ack_data.ue_cc_idx = ue_db[ack_data.rnti].get_cell_index(ccidx).second; + ack_data.rnti = pusch.dci.rnti; + ack_data.enb_cc_idx = ccidx; + ack_data.ue_cc_idx = ue_db[ack_data.rnti].get_cell_index(ccidx).second; + ack_data.ul_harq = *ue_db[ack_data.rnti].get_ul_harq(tti_info.tti_params.tti_tx_ul, ack_data.ue_cc_idx); + ack_data.tti_tx_ul = tti_info.tti_params.tti_tx_ul; + ack_data.tti_ack = tti_info.tti_params.tti_tx_ul + FDD_HARQ_DELAY_MS; if (ack_data.ul_harq.nof_retx(0) == 0) { ack_data.ack = randf() > sim_args0.P_retx; } else { diff --git a/srsenb/test/mac/scheduler_test_common.h b/srsenb/test/mac/scheduler_test_common.h index f3657dea5..35b05f720 100644 --- a/srsenb/test/mac/scheduler_test_common.h +++ b/srsenb/test/mac/scheduler_test_common.h @@ -202,6 +202,7 @@ protected: struct ack_info_t { uint16_t rnti; uint32_t tti; + uint32_t enb_cc_idx; uint32_t ue_cc_idx; bool ack = false; uint32_t retx_delay = 0; @@ -211,6 +212,7 @@ protected: uint16_t rnti; uint32_t tti_ack, tti_tx_ul; uint32_t ue_cc_idx; + uint32_t enb_cc_idx; bool ack = false; srsenb::ul_harq_proc ul_harq; };