diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 024b04aec..935e20855 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -657,6 +657,13 @@ class phy_interface_stack_lte : public phy_interface_mac_lte, public phy_interfa { }; +// Generic Task Management + Timer interface for upper stack +class task_handler_interface_lte +{ +public: + virtual srslte::timer_handler::unique_timer get_unique_timer() = 0; +}; + } // namespace srsue #endif // SRSLTE_UE_INTERFACES_H diff --git a/srsenb/test/common/dummy_classes.h b/srsenb/test/common/dummy_classes.h index 5104bf6d5..2b2332a3a 100644 --- a/srsenb/test/common/dummy_classes.h +++ b/srsenb/test/common/dummy_classes.h @@ -19,8 +19,8 @@ * */ -#ifndef SRSLTE_DUMMY_CLASSES_H -#define SRSLTE_DUMMY_CLASSES_H +#ifndef SRSENB_DUMMY_CLASSES_H +#define SRSENB_DUMMY_CLASSES_H #include "srslte/interfaces/enb_interfaces.h" @@ -134,4 +134,4 @@ public: } // namespace srsenb -#endif // SRSLTE_DUMMY_CLASSES_H +#endif // SRSENB_DUMMY_CLASSES_H diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index ea6538b14..dcd5342c6 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -287,7 +287,7 @@ class rrc : public rrc_interface_nas, public srslte::timer_callback { public: - rrc(srslte::log* rrc_log_); + rrc(srslte::log* rrc_log_, task_handler_interface_lte* task_handler_); ~rrc(); void init(phy_interface_rrc_lte* phy_, @@ -297,7 +297,6 @@ public: nas_interface_rrc* nas_, usim_interface_rrc* usim_, gw_interface_rrc* gw_, - srslte::timer_handler* timers_, stack_interface_rrc* stack_, const rrc_args_t& args_); @@ -375,16 +374,17 @@ private: void process_pcch(srslte::unique_byte_buffer_t pdu); - srslte::byte_buffer_pool* pool = nullptr; - srslte::log* rrc_log = nullptr; - phy_interface_rrc_lte* phy = nullptr; - mac_interface_rrc* mac = nullptr; - rlc_interface_rrc* rlc = nullptr; - pdcp_interface_rrc* pdcp = nullptr; - nas_interface_rrc* nas = nullptr; - usim_interface_rrc* usim = nullptr; - gw_interface_rrc* gw = nullptr; - stack_interface_rrc* stack = nullptr; + task_handler_interface_lte* task_handler = nullptr; + srslte::byte_buffer_pool* pool = nullptr; + srslte::log* rrc_log = nullptr; + phy_interface_rrc_lte* phy = nullptr; + mac_interface_rrc* mac = nullptr; + rlc_interface_rrc* rlc = nullptr; + pdcp_interface_rrc* pdcp = nullptr; + nas_interface_rrc* nas = nullptr; + usim_interface_rrc* usim = nullptr; + gw_interface_rrc* gw = nullptr; + stack_interface_rrc* stack = nullptr; srslte::unique_byte_buffer_t dedicated_info_nas; @@ -426,7 +426,6 @@ private: std::map drbs; // RRC constants and timers - srslte::timer_handler* timers = nullptr; uint32_t n310_cnt = 0, N310 = 0; uint32_t n311_cnt = 0, N311 = 0; srslte::timer_handler::unique_timer t300, t301, t302, t310, t311, t304; diff --git a/srsue/hdr/stack/rrc/rrc_meas.h b/srsue/hdr/stack/rrc/rrc_meas.h index 3bf81de51..b70cc11c7 100644 --- a/srsue/hdr/stack/rrc/rrc_meas.h +++ b/srsue/hdr/stack/rrc/rrc_meas.h @@ -86,7 +86,6 @@ private: }; var_meas_cfg* meas_cfg = nullptr; srslte::log* log_h = nullptr; - srslte::timer_handler* timers = nullptr; rrc* rrc_ptr = nullptr; std::map varMeasReportList; }; diff --git a/srsue/hdr/stack/rrc/rrc_procedures.h b/srsue/hdr/stack/rrc/rrc_procedures.h index 3c32af334..c1d9ca959 100644 --- a/srsue/hdr/stack/rrc/rrc_procedures.h +++ b/srsue/hdr/stack/rrc/rrc_procedures.h @@ -75,28 +75,35 @@ private: state_t state; }; +/**************************************************************** + * TS 36.331 Sec 5.2.3 - Acquisition of an SI message procedure + ***************************************************************/ class rrc::si_acquire_proc { public: const static int SIB_SEARCH_TIMEOUT_MS = 1000; + struct si_acq_timer_expired { + uint32_t timer_id; + }; explicit si_acquire_proc(rrc* parent_); srslte::proc_outcome_t init(uint32_t sib_index_); srslte::proc_outcome_t step(); static const char* name() { return "SI Acquire"; } + srslte::proc_outcome_t react(si_acq_timer_expired ev); + void then(const srslte::proc_state_t& result); private: - static uint32_t sib_start_tti(uint32_t tti, uint32_t period, uint32_t offset, uint32_t sf); + void start_si_acquire(); // conts rrc* rrc_ptr; srslte::log* log_h; // state - uint32_t period = 0, sched_index = 0; - uint32_t start_tti = 0; - uint32_t sib_index = 0; - uint32_t last_win_start = 0; + srslte::timer_handler::unique_timer si_acq_timeout, si_acq_retry_timer; + uint32_t period = 0, sched_index = 0; + uint32_t sib_index = 0; }; class rrc::serving_cell_config_proc diff --git a/srsue/hdr/stack/ue_stack_lte.h b/srsue/hdr/stack/ue_stack_lte.h index aef541618..66613f440 100644 --- a/srsue/hdr/stack/ue_stack_lte.h +++ b/srsue/hdr/stack/ue_stack_lte.h @@ -55,6 +55,7 @@ class ue_stack_lte final : public ue_stack_base, public stack_interface_gw, public stack_interface_mac, public stack_interface_rrc, + public task_handler_interface_lte, public thread { public: @@ -122,6 +123,9 @@ public: void start_cell_search() final; void start_cell_select(const phy_interface_rrc_lte::phy_cell_t* cell) final; + // Task Handling interface + srslte::timer_handler::unique_timer get_unique_timer() override { return timers.get_unique_timer(); } + private: void run_thread() final; void run_tti_impl(uint32_t tti); diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 19758a71c..49f117d5e 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -50,7 +49,7 @@ const static uint32_t required_sibs[NOF_REQUIRED_SIBS] = {0, 1, 2, 12}; // SIB1, Base functions *******************************************************************************/ -rrc::rrc(srslte::log* rrc_log_) : +rrc::rrc(srslte::log* rrc_log_, task_handler_interface_lte* task_handler_) : state(RRC_STATE_IDLE), last_state(RRC_STATE_CONNECTED), drb_up(false), @@ -65,7 +64,8 @@ rrc::rrc(srslte::log* rrc_log_) : plmn_searcher(this), cell_reselector(this), connection_reest(this), - serving_cell(unique_cell_t(new cell_t())) + serving_cell(unique_cell_t(new cell_t())), + task_handler(task_handler_) { measurements = std::unique_ptr(new rrc_meas(rrc_log)); } @@ -102,7 +102,6 @@ void rrc::init(phy_interface_rrc_lte* phy_, nas_interface_rrc* nas_, usim_interface_rrc* usim_, gw_interface_rrc* gw_, - srslte::timer_handler* timers_, stack_interface_rrc* stack_, const rrc_args_t& args_) { @@ -118,19 +117,17 @@ void rrc::init(phy_interface_rrc_lte* phy_, args = args_; - // Use MAC timers - timers = timers_; state = RRC_STATE_IDLE; plmn_is_selected = false; security_is_activated = false; - t300 = timers->get_unique_timer(); - t301 = timers->get_unique_timer(); - t302 = timers->get_unique_timer(); - t310 = timers->get_unique_timer(); - t311 = timers->get_unique_timer(); - t304 = timers->get_unique_timer(); + t300 = task_handler->get_unique_timer(); + t301 = task_handler->get_unique_timer(); + t302 = task_handler->get_unique_timer(); + t310 = task_handler->get_unique_timer(); + t311 = task_handler->get_unique_timer(); + t304 = task_handler->get_unique_timer(); ue_identity_configured = false; @@ -420,7 +417,7 @@ void rrc::process_new_cell_meas(const std::vector& meas) void rrc::out_of_sync() { // CAUTION: We do not lock in this function since they are called from real-time threads - if (serving_cell && timers && rrc_log) { + if (serving_cell && rrc_log) { phy_sync_state = phy_out_of_sync; // upon receiving N310 consecutive "out-of-sync" indications for the PCell from lower layers while neither T300, diff --git a/srsue/src/stack/rrc/rrc_meas.cc b/srsue/src/stack/rrc/rrc_meas.cc index 4622bc0f0..80251b56e 100644 --- a/srsue/src/stack/rrc/rrc_meas.cc +++ b/srsue/src/stack/rrc/rrc_meas.cc @@ -178,7 +178,6 @@ asn1::dyn_array::iterator rrc::rrc_meas::find_pci_in_meas_ob void rrc::rrc_meas::var_meas_report_list::init(rrc* rrc_ptr_) { rrc_ptr = rrc_ptr_; - timers = rrc_ptr_->timers; } /* Generate report procedure 5.5.5 */ @@ -338,7 +337,7 @@ void rrc::rrc_meas::var_meas_report_list::set_measId(const uint32_t m // triggerType ‘event’ as well as for triggerType ‘periodical’ if (!varMeasReportList.at(measId).periodic_timer.is_valid() && (report_cfg.report_amount.to_number() > 1 || report_cfg.report_amount.to_number() == -1)) { - varMeasReportList.at(measId).periodic_timer = timers->get_unique_timer(); + varMeasReportList.at(measId).periodic_timer = rrc_ptr->task_handler->get_unique_timer(); varMeasReportList.at(measId).periodic_timer.set(report_cfg.report_interv.to_number()); } varMeasReportList.at(measId).report_cfg = std::move(report_cfg); diff --git a/srsue/src/stack/rrc/rrc_procedures.cc b/srsue/src/stack/rrc/rrc_procedures.cc index f6f44fcea..a44cf91ed 100644 --- a/srsue/src/stack/rrc/rrc_procedures.cc +++ b/srsue/src/stack/rrc/rrc_procedures.cc @@ -166,113 +166,186 @@ proc_outcome_t rrc::cell_search_proc::react(const cell_search_event_t& event) return proc_outcome_t::yield; } -/************************************** - * SI Acquire Procedure - *************************************/ +/**************************************************************** + * TS 36.331 Sec 5.2.3 - Acquisition of an SI message procedure + ***************************************************************/ -rrc::si_acquire_proc::si_acquire_proc(rrc* parent_) : rrc_ptr(parent_), log_h(parent_->rrc_log) {} +// Helper functions -proc_outcome_t rrc::si_acquire_proc::init(uint32_t sib_index_) +/** + * compute "T" (aka si-Periodicity) and "n" (order of entry in schedulingInfoList). + * @param sib_index SI index of interest + * @param sib1 configuration of SIB1 + * @return {T, n} if successful, {0, 0} if sib_index was not found + */ +std::pair compute_si_periodicity_and_idx(uint32_t sib_index, const asn1::rrc::sib_type1_s* sib1) { - Info("Starting SI Acquire procedure for SIB%d\n", sib_index_ + 1); - sib_index = sib_index_; - start_tti = rrc_ptr->mac->get_current_tti(); - period = 0; - sched_index = 0; - last_win_start = 0; - - // set period/sched_index if (sib_index == 0) { - period = 20; - sched_index = 0; - } else { - // Instruct MAC to look for SIB2..13 - if (not rrc_ptr->serving_cell->has_sib1()) { - Error("Trying to acquire SIB%d but SIB1 not received yet\n", sib_index + 1); - return proc_outcome_t::error; - } - asn1::rrc::sib_type1_s* sib1 = rrc_ptr->serving_cell->sib1ptr(); - - if (sib_index == 1) { - // SIB2 scheduling - period = sib1->sched_info_list[0].si_periodicity.to_number(); - sched_index = 0; - } else { - // SIB3+ scheduling Section 5.2.3 - bool found = false; - for (uint32_t i = 0; i < sib1->sched_info_list.size() && not found; ++i) { - for (uint32_t j = 0; j < sib1->sched_info_list[i].sib_map_info.size() && not found; ++j) { - if (sib1->sched_info_list[i].sib_map_info[j].to_number() == sib_index + 1) { - period = sib1->sched_info_list[i].si_periodicity.to_number(); - sched_index = i; - found = true; - } - } - } - if (not found) { - Info("Could not find SIB%d scheduling in SIB1\n", sib_index + 1); - return proc_outcome_t::success; + return {20, 0}; + } + if (sib_index == 1) { + // SIB2 scheduling + return {sib1->sched_info_list[0].si_periodicity.to_number(), 0}; + } + // SIB3+ scheduling Section 5.2.3 + for (uint32_t i = 0; i < sib1->sched_info_list.size(); ++i) { + for (uint32_t j = 0; j < sib1->sched_info_list[i].sib_map_info.size(); ++j) { + if (sib1->sched_info_list[i].sib_map_info[j].to_number() == sib_index + 1) { + return {sib1->sched_info_list[i].si_periodicity.to_number(), i}; } } } + return {0, 0}; +} - return step(); +/** + * Determine the start TTI of SI-window (see TS 36.331 Sec 5.2.3) + * @param tti current TTI + * @param T Parameter "T" representing a SIB si-Periodicity + * @param offset frame offset for the start of SI-window + * @param a subframe when SI-window starts + * @return next TTI when SI-window starts + */ +uint32_t sib_start_tti(uint32_t tti, uint32_t T, uint32_t offset, uint32_t a) +{ + return (T * 10 * (1 + tti / (T * 10)) + (offset * 10) + a) % 10240; // the 1 means next opportunity } -proc_outcome_t rrc::si_acquire_proc::step() +/** + * Determine SI-window [start, length] (see TS 36.331 Sec 5.2.3) + * @param sib_index index of SI-message of interest + * @return + */ +std::pair +compute_si_window(uint32_t tti, uint32_t sib_index, uint32_t n, uint32_t T, const asn1::rrc::sib_type1_s* sib1) { - uint32_t tti = rrc_ptr->mac->get_current_tti(); - uint32_t tti_diff1 = srslte_tti_interval(tti, start_tti); - bool has_timeout = tti_diff1 >= SIB_SEARCH_TIMEOUT_MS and tti_diff1 < 10240 / 2; - if (has_timeout or rrc_ptr->serving_cell->has_sib(sib_index)) { - if (rrc_ptr->serving_cell->has_sib(sib_index)) { - Info("SIB%d acquired successfully\n", sib_index + 1); - return proc_outcome_t::success; - } else { - Error("Timeout while acquiring SIB%d\n", sib_index + 1); - return proc_outcome_t::error; - } + uint32_t si_win_start; + uint32_t si_win_len; // si-WindowLength or "w" + if (sib_index == 0) { + si_win_len = 1; + si_win_start = sib_start_tti(tti, 2, 0, 5); } else { + si_win_len = sib1->si_win_len.to_number(); + uint32_t x = n * si_win_len; + uint32_t a = x % 10; // subframe #a when the SI-window starts + uint32_t offset = x / 10; // frame offset + si_win_start = sib_start_tti(tti, T, offset, a); + } + return {si_win_start, si_win_len}; +} - uint32_t tti_diff2 = srslte_tti_interval(tti, last_win_start); +// SI Acquire class - // If first time or inside retry window, trigger MAC to decode SIB - uint32_t retry_period = (sib_index == 0) ? 20 : period * 5; - if (last_win_start == 0 or (tti_diff2 > retry_period and tti_diff2 < 1000)) { +rrc::si_acquire_proc::si_acquire_proc(rrc* parent_) : + rrc_ptr(parent_), + log_h(parent_->rrc_log), + si_acq_timeout(rrc_ptr->task_handler->get_unique_timer()), + si_acq_retry_timer(rrc_ptr->task_handler->get_unique_timer()) +{ + // SIB acquisition procedure timeout. + // NOTE: The standard does not specify this timeout + si_acq_timeout.set(SIB_SEARCH_TIMEOUT_MS, + [this](uint32_t tid) { rrc_ptr->si_acquirer.trigger(si_acq_timer_expired{tid}); }); +} - // compute win start and len - uint32_t si_win_start, si_win_len; - if (sib_index == 0) { - si_win_len = 1; - si_win_start = sib_start_tti(tti, 2, 0, 5); - } else { - asn1::rrc::sib_type1_s* sib1 = rrc_ptr->serving_cell->sib1ptr(); +proc_outcome_t rrc::si_acquire_proc::init(uint32_t sib_index_) +{ + const uint32_t nof_sib_harq_retxs = 5; - si_win_len = sib1->si_win_len.to_number(); - uint32_t x = sched_index * si_win_len; - uint32_t sf = x % 10, offset = x / 10; - si_win_start = sib_start_tti(tti, period, offset, sf); - } - last_win_start = si_win_start; - - // Instruct MAC to decode SIB - rrc_ptr->mac->bcch_start_rx(si_win_start, si_win_len); - Info("Instructed MAC to search for SIB%d, win_start=%d, win_len=%d, period=%d, sched_index=%d\n", - sib_index + 1, - si_win_start, - si_win_len, - period, - sched_index); - } + // make sure we dont already have the SIB of interest + if (rrc_ptr->serving_cell->has_sib(sib_index_)) { + Info("The UE has already acquired SIB%d\n", sib_index + 1); + return proc_outcome_t::success; } + Info("Starting SI Acquisition procedure for SIB%d\n", sib_index_ + 1); + + // make sure SIB1 is captured before other SIBs + sib_index = sib_index_; + if (sib_index > 0 and not rrc_ptr->serving_cell->has_sib1()) { + Error("Trying to acquire SIB%d but SIB1 not received yet\n", sib_index + 1); + return proc_outcome_t::error; + } + + // compute the si-Periodicity and schedInfoList index + auto ret = compute_si_periodicity_and_idx(sib_index, rrc_ptr->serving_cell->sib1ptr()); + if (ret.first == 0) { + Info("Could not find SIB%d scheduling in SIB1\n", sib_index + 1); + return proc_outcome_t::error; + } + period = ret.first; + sched_index = ret.second; + + // setup retry timer handler based on si-Periodicity and number of retxs + uint32_t retry_period = (sib_index == 0) ? 20 : period * nof_sib_harq_retxs; + si_acq_retry_timer.set(retry_period, + [this](uint32_t tid) { rrc_ptr->si_acquirer.trigger(si_acq_timer_expired{tid}); }); + + // trigger new SI acquisition procedure in MAC + start_si_acquire(); + + // start timeout timer + si_acq_timeout.run(); return proc_outcome_t::yield; } -// Determine SI messages scheduling as in 36.331 5.2.3 Acquisition of an SI message -uint32_t rrc::si_acquire_proc::sib_start_tti(uint32_t tti, uint32_t period, uint32_t offset, uint32_t sf) +void rrc::si_acquire_proc::then(const srslte::proc_state_t& result) +{ + // make sure timers are stopped + si_acq_retry_timer.stop(); + si_acq_timeout.stop(); + + if (result.is_success()) { + Info("SIB%d acquired successfully\n", sib_index + 1); + } else { + Error("Failed to acquire SIB%d\n", sib_index + 1); + } +} + +void rrc::si_acquire_proc::start_si_acquire() { - return (period * 10 * (1 + tti / (period * 10)) + (offset * 10) + sf) % 10240; // the 1 means next opportunity + // Instruct MAC to decode SIB (non-blocking) + uint32_t tti = rrc_ptr->mac->get_current_tti(); + auto ret = compute_si_window(tti, sib_index, sched_index, period, rrc_ptr->serving_cell->sib1ptr()); + uint32_t si_win_start = ret.first, si_win_len = ret.second; + rrc_ptr->mac->bcch_start_rx(si_win_start, si_win_len); + + // start window retry timer + si_acq_retry_timer.run(); + + Info("Instructed MAC to search for SIB%d, win_start=%d, win_len=%d, period=%d, sched_index=%d\n", + sib_index + 1, + si_win_start, + si_win_len, + period, + sched_index); +} + +proc_outcome_t rrc::si_acquire_proc::step() +{ + // If meanwhile we have received the SIB, return success + return rrc_ptr->serving_cell->has_sib(sib_index) ? proc_outcome_t::success : proc_outcome_t::yield; +} + +srslte::proc_outcome_t rrc::si_acquire_proc::react(si_acq_timer_expired ev) +{ + if (rrc_ptr->serving_cell->has_sib(sib_index)) { + return proc_outcome_t::success; + } + + // retry si acquire + if (ev.timer_id == si_acq_retry_timer.id()) { + start_si_acquire(); + return proc_outcome_t::yield; + } + + // timeout. SI acquire failed + if (ev.timer_id == si_acq_timeout.id()) { + Error("Timeout while acquiring SIB%d\n", sib_index + 1); + } else { + Error("Unrecognized timer id\n"); + } + return proc_outcome_t::error; } /************************************** diff --git a/srsue/src/stack/ue_stack_lte.cc b/srsue/src/stack/ue_stack_lte.cc index db39388a1..3fa33dcee 100644 --- a/srsue/src/stack/ue_stack_lte.cc +++ b/srsue/src/stack/ue_stack_lte.cc @@ -36,7 +36,7 @@ ue_stack_lte::ue_stack_lte() : phy(nullptr), rlc(&rlc_log), mac(&mac_log), - rrc(&rrc_log), + rrc(&rrc_log, this), pdcp(&timers, &pdcp_log), nas(&timers), thread("STACK"), @@ -139,7 +139,7 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_) rlc.init(&pdcp, &rrc, &timers, 0 /* RB_ID_SRB0 */); pdcp.init(&rlc, &rrc, gw); nas.init(usim.get(), &rrc, gw, args.nas); - rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, &timers, this, args.rrc); + rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, this, args.rrc); running = true; start(STACK_MAIN_THREAD_PRIO); diff --git a/srsue/test/common/dummy_classes.h b/srsue/test/common/dummy_classes.h new file mode 100644 index 000000000..feec2508b --- /dev/null +++ b/srsue/test/common/dummy_classes.h @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2019 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#ifndef SRSUE_DUMMY_CLASSES_H +#define SRSUE_DUMMY_CLASSES_H + +#include "srslte/interfaces/ue_interfaces.h" + +namespace srsue { + +class stack_dummy : public task_handler_interface_lte +{ +public: + srslte::timer_handler::unique_timer get_unique_timer() override { return timers.get_unique_timer(); } + + srslte::timer_handler timers; +}; + +} // namespace srsue + +#endif // SRSUE_DUMMY_CLASSES_H diff --git a/srsue/test/upper/rrc_meas_test.cc b/srsue/test/upper/rrc_meas_test.cc index 39adfb62c..878194325 100644 --- a/srsue/test/upper/rrc_meas_test.cc +++ b/srsue/test/upper/rrc_meas_test.cc @@ -27,6 +27,7 @@ #include "srsue/hdr/stack/rrc/rrc.h" #include "srsue/hdr/stack/rrc/rrc_meas.h" #include "srsue/hdr/stack/upper/nas.h" +#include "srsue/test/common/dummy_classes.h" #include using namespace asn1::rrc; @@ -164,25 +165,22 @@ private: bool meas_res_received = false; }; -static srslte::timer_handler global_timers; - class rrc_test : public rrc { + srslte::timer_handler* timers = nullptr; + public: - rrc_test(srslte::log* log_) : rrc(log_) + rrc_test(srslte::log* log_, stack_dummy* task_handler_) : rrc(log_, task_handler_), timers(&task_handler_->timers) { pool = srslte::byte_buffer_pool::get_instance(); - nastest = std::unique_ptr(new nas_test(&global_timers)); - pdcptest = std::unique_ptr(new pdcp_test(log_, &global_timers)); + nastest = std::unique_ptr(new nas_test(timers)); + pdcptest = std::unique_ptr(new pdcp_test(log_, timers)); }; - void init() - { - rrc::init(&phytest, nullptr, nullptr, pdcptest.get(), nastest.get(), nullptr, nullptr, &global_timers, nullptr, {}); - } + void init() { rrc::init(&phytest, nullptr, nullptr, pdcptest.get(), nastest.get(), nullptr, nullptr, nullptr, {}); } void run_tti(uint32_t tti_) { - global_timers.step_all(); + timers->step_all(); rrc::run_tti(tti_); } @@ -276,7 +274,8 @@ int cell_select_test() printf("====== Cell Select Testing ===============\n"); printf("==========================================================\n"); - rrc_test rrctest(&log1); + stack_dummy stack; + rrc_test rrctest(&log1, &stack); rrctest.init(); rrctest.connect(); @@ -305,7 +304,8 @@ int meas_obj_test() printf("====== Object Configuration Testing ===============\n"); printf("==========================================================\n"); - rrc_test rrctest(&log1); + stack_dummy stack; + rrc_test rrctest(&log1, &stack); rrctest.init(); rrctest.connect(); @@ -720,7 +720,8 @@ int a1event_report_test(uint32_t a1_rsrp_th, printf("============ Report Testing A1 ===============\n"); printf("==========================================================\n"); - rrc_test rrctest(&log1); + stack_dummy stack; + rrc_test rrctest(&log1, &stack); rrctest.init(); rrctest.connect(); @@ -853,7 +854,8 @@ int a3event_report_test(uint32_t a3_offset, uint32_t hyst, bool report_on_leave) printf("============ Report Testing A3 ===============\n"); printf("==========================================================\n"); - rrc_test rrctest(&log1); + stack_dummy stack; + rrc_test rrctest(&log1, &stack); rrctest.init(); rrctest.connect();