diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index a1abc8f45..11c517d34 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -166,7 +166,6 @@ class rrc_interface_mac : public rrc_interface_mac_common public: virtual void ho_ra_completed(bool ra_successful) = 0; virtual void release_pucch_srs() = 0; - virtual void run_tti(uint32_t tti) = 0; }; // RRC interface for PHY diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index 45f2da24a..f5a6126aa 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -62,7 +62,7 @@ public: void stop(); void start_pcap(srslte::mac_pcap* pcap_); - + /******** Interface from PHY (PHY -> MAC) ****************/ int sr_detected(uint32_t tti, uint16_t rnti) final; int rach_detected(uint32_t tti, uint32_t preamble_idx, uint32_t time_adv) final; @@ -122,7 +122,7 @@ private: // We use a rwlock in MAC to allow multiple workers to access MAC simultaneously. No conflicts will happen since access for different TTIs pthread_rwlock_t rwlock; - + // Interaction with PHY phy_interface_stack_lte* phy_h; rlc_interface_mac* rlc_h; diff --git a/srsue/hdr/stack/mac/mac.h b/srsue/hdr/stack/mac/mac.h index 33fa702a9..c3b0cb4c9 100644 --- a/srsue/hdr/stack/mac/mac.h +++ b/srsue/hdr/stack/mac/mac.h @@ -46,7 +46,6 @@ class mac : public mac_interface_phy_lte, public mac_interface_rrc, public srslte::timer_callback, public srslte::mac_interface_timers, - public thread, public mac_interface_demux { public: @@ -110,7 +109,6 @@ public: uint32_t timer_get_unique_id(); private: - void run_thread(); void clear_rntis(); bool is_in_window(uint32_t tti, int* start, int* len); @@ -159,10 +157,6 @@ private: uint8_t mch_payload_buffer[mch_payload_buffer_sz]; srslte::mch_pdu mch_msg; - // MAC thread - srslte::block_queue tti_sync; - bool running; - /* Functions for MAC Timers */ uint32_t timer_alignment; void setup_timers(int time_alignment_timer); diff --git a/srsue/hdr/stack/ue_stack_lte.h b/srsue/hdr/stack/ue_stack_lte.h index acb652169..492dd2bf4 100644 --- a/srsue/hdr/stack/ue_stack_lte.h +++ b/srsue/hdr/stack/ue_stack_lte.h @@ -26,6 +26,7 @@ #ifndef SRSUE_UE_STACK_LTE_H #define SRSUE_UE_STACK_LTE_H +#include #include #include #include @@ -47,7 +48,10 @@ namespace srsue { -class ue_stack_lte final : public ue_stack_base, public stack_interface_phy_lte, public stack_interface_gw +class ue_stack_lte final : public ue_stack_base, + public stack_interface_phy_lte, + public stack_interface_gw, + public thread { public: ue_stack_lte(); @@ -65,8 +69,8 @@ public: bool is_rrc_connected(); // RRC interface for PHY - void in_sync() { rrc.in_sync(); }; - void out_of_sync() { rrc.out_of_sync(); }; + void in_sync() final; + void out_of_sync() final; void new_phy_meas(float rsrp, float rsrq, uint32_t tti, int earfcn = -1, int pci = -1) { rrc.new_phy_meas(rsrp, rsrq, tti, earfcn, pci); @@ -99,7 +103,7 @@ public: void set_mbsfn_config(uint32_t nof_mbsfn_services) { mac.set_mbsfn_config(nof_mbsfn_services); } - void run_tti(const uint32_t tti) { mac.run_tti(tti); } + void run_tti(uint32_t tti) final; // Interface for GW void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking) final @@ -110,6 +114,10 @@ public: bool is_lcid_enabled(uint32_t lcid) final { return pdcp.is_lcid_enabled(lcid); } private: + void run_thread() final; + void run_tti_(uint32_t tti); + void stop_(); + bool running; srsue::stack_args_t args; @@ -137,6 +145,10 @@ private: // RAT-specific interfaces phy_interface_stack_lte* phy; gw_interface_stack* gw; + + // Thread + static const int STACK_MAIN_THREAD_PRIO = -1; // Use default high-priority below UHD + srslte::block_queue > pending_tasks; }; } // namespace srsue diff --git a/srsue/src/stack/mac/mac.cc b/srsue/src/stack/mac/mac.cc index 2b84a2e22..a5729f8b3 100644 --- a/srsue/src/stack/mac/mac.cc +++ b/srsue/src/stack/mac/mac.cc @@ -37,7 +37,7 @@ using namespace asn1::rrc; namespace srsue { -mac::mac() : timers(64), pdu_process_thread(&demux_unit), mch_msg(10), running(false), pcap(nullptr), thread("MAC") +mac::mac() : timers(64), pdu_process_thread(&demux_unit), mch_msg(10), pcap(nullptr) { // Create PCell HARQ entities auto ul = ul_harq_entity_ptr(new ul_harq_entity()); @@ -81,8 +81,6 @@ bool mac::init(phy_interface_mac_lte* phy, rlc_interface_mac* rlc, rrc_interface reset(); - start(MAC_MAIN_THREAD_PRIO); - return true; } @@ -93,10 +91,7 @@ void mac::stop() pdu_process_thread.stop(); - running = false; run_tti(0); // make sure it's not locked after last TTI - - wait_thread_finish(); } void mac::start_pcap(srslte::mac_pcap* pcap_) @@ -178,50 +173,37 @@ void mac::reset() clear_rntis(); } -void mac::run_tti(const uint32_t tti_) +void mac::run_tti(const uint32_t tti) { - tti_sync.push(tti_); -} - -void mac::run_thread() -{ - running = true; - - while (running) { - // Wait for next TTI - uint32_t tti = tti_sync.wait_pop(); + log_h->step(tti); - log_h->step(tti); + /* Warning: Here order of invocation of procedures is important!! */ - /* Warning: Here order of invocation of procedures is important!! */ + // Step all procedures + Debug("Running MAC tti=%d\n", tti); + bsr_procedure.step(tti); + phr_procedure.step(tti); - // Step all procedures - Debug("Running MAC tti=%d\n", tti); - bsr_procedure.step(tti); - phr_procedure.step(tti); - - // Check if BSR procedure need to start SR - if (bsr_procedure.need_to_send_sr(tti)) { - Debug("Starting SR procedure by BSR request, PHY TTI=%d\n", tti); - sr_procedure.start(); - } - if (bsr_procedure.need_to_reset_sr()) { - Debug("Resetting SR procedure by BSR request\n"); - sr_procedure.reset(); - } - sr_procedure.step(tti); - - // Check SR if we need to start RA - if (sr_procedure.need_random_access()) { - ra_procedure.start_mac_order(); - } + // Check if BSR procedure need to start SR + if (bsr_procedure.need_to_send_sr(tti)) { + Debug("Starting SR procedure by BSR request, PHY TTI=%d\n", tti); + sr_procedure.start(); + } + if (bsr_procedure.need_to_reset_sr()) { + Debug("Resetting SR procedure by BSR request\n"); + sr_procedure.reset(); + } + sr_procedure.step(tti); - ra_procedure.step(tti); - ra_window_start = 0; - ra_procedure.is_rar_window(&ra_window_start, &ra_window_length); - timers.step_all(); - rrc_h->run_tti(tti); + // Check SR if we need to start RA + if (sr_procedure.need_random_access()) { + ra_procedure.start_mac_order(); } + + ra_procedure.step(tti); + ra_window_start = 0; + ra_procedure.is_rar_window(&ra_window_start, &ra_window_length); + timers.step_all(); } void mac::bcch_start_rx(int si_window_start, int si_window_length) diff --git a/srsue/src/stack/ue_stack_lte.cc b/srsue/src/stack/ue_stack_lte.cc index 8269cb2c5..4c1034e2f 100644 --- a/srsue/src/stack/ue_stack_lte.cc +++ b/srsue/src/stack/ue_stack_lte.cc @@ -26,7 +26,7 @@ using namespace srslte; namespace srsue { -ue_stack_lte::ue_stack_lte() : running(false), args(), logger(nullptr), usim(nullptr), phy(nullptr) {} +ue_stack_lte::ue_stack_lte() : running(false), args(), logger(nullptr), usim(nullptr), phy(nullptr), thread("STACK") {} ue_stack_lte::~ue_stack_lte() { @@ -108,11 +108,21 @@ int ue_stack_lte::init(const stack_args_t& args_, srslte::logger* logger_) rrc.init(phy, &mac, &rlc, &pdcp, &nas, usim.get(), gw, &mac, &rrc_log, args.rrc); running = true; + start(STACK_MAIN_THREAD_PRIO); return SRSLTE_SUCCESS; } void ue_stack_lte::stop() +{ + if (running) { + pending_tasks.push([this]() { stop_(); }); + + wait_thread_finish(); + } +} + +void ue_stack_lte::stop_() { if (running) { usim->stop(); @@ -140,7 +150,7 @@ void ue_stack_lte::stop() bool ue_stack_lte::switch_on() { if (running) { - return nas.attach_request(); + nas.attach_request(); } return false; @@ -148,8 +158,10 @@ bool ue_stack_lte::switch_on() bool ue_stack_lte::switch_off() { - // generate detach request - nas.detach_request(); + pending_tasks.push([this]() { + // generate detach request + nas.detach_request(); + }); // wait for max. 5s for it to be sent (according to TS 24.301 Sec 25.5.2.2) const uint32_t RB_ID_SRB1 = 1; @@ -184,4 +196,34 @@ bool ue_stack_lte::is_rrc_connected() return rrc.is_connected(); } +void ue_stack_lte::run_thread() +{ + while (running) { + // FIXME: For now it is a single queue + std::function func = pending_tasks.wait_pop(); + func(); + } +} + +void ue_stack_lte::in_sync() +{ + pending_tasks.push([this]() { rrc.in_sync(); }); +} + +void ue_stack_lte::out_of_sync() +{ + pending_tasks.push([this]() { rrc.out_of_sync(); }); +} + +void ue_stack_lte::run_tti(uint32_t tti) +{ + pending_tasks.push([this, tti]() { run_tti_(tti); }); +} + +void ue_stack_lte::run_tti_(uint32_t tti) +{ + mac.run_tti(tti); + rrc.run_tti(tti); +} + } // namespace srsue diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 5bc3f0f51..ffe808084 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -137,17 +137,30 @@ private: found_plmn_t plmns; }; -class stack_dummy : public stack_interface_gw +class stack_dummy : public stack_interface_gw, public thread { public: - stack_dummy(pdcp_interface_gw* pdcp_, srsue::nas* nas_) : pdcp(pdcp_), nas(nas_) {} + stack_dummy(pdcp_interface_gw* pdcp_, srsue::nas* nas_) : pdcp(pdcp_), nas(nas_), thread("DUMMY STACK") {} + void init() { start(-1); } bool switch_on() final { return nas->attach_request(); } void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking) { pdcp->write_sdu(lcid, std::move(sdu), blocking); } bool is_lcid_enabled(uint32_t lcid) { return pdcp->is_lcid_enabled(lcid); } - + void run_thread() + { + running = true; + uint32_t counter = 0; + // while (running) { + // nas->run_tti(counter++); + // } + } + void stop() + { + running = false; + wait_thread_finish(); + } pdcp_interface_gw* pdcp = nullptr; srsue::nas* nas = nullptr; bool running = false; @@ -284,8 +297,10 @@ int mme_attach_request_test() srslte::logger* logger = &def_logstdout; gw.init(gw_args, logger, &stack); + stack.init(); // trigger test stack.switch_on(); + stack.stop(); // this will time out in the first place