diff --git a/lib/include/srslte/mac/mac_nr_pdu.h b/lib/include/srslte/mac/mac_nr_pdu.h index a441799fd..185c791a5 100644 --- a/lib/include/srslte/mac/mac_nr_pdu.h +++ b/lib/include/srslte/mac/mac_nr_pdu.h @@ -101,6 +101,7 @@ public: bool is_ulsch(); void init_tx(byte_buffer_t* buffer_, uint32_t pdu_len_, bool is_ulsch_ = false); + void init_rx(bool ulsch_ = false); uint32_t add_sdu(const uint32_t lcid_, const uint8_t* payload_, const uint32_t len_); diff --git a/lib/src/mac/mac_nr_pdu.cc b/lib/src/mac/mac_nr_pdu.cc index 304fbf72a..4a8ebe990 100644 --- a/lib/src/mac/mac_nr_pdu.cc +++ b/lib/src/mac/mac_nr_pdu.cc @@ -262,6 +262,15 @@ void mac_nr_sch_pdu::init_tx(byte_buffer_t* buffer_, uint32_t pdu_len_, bool uls ulsch = ulsch_; } +void mac_nr_sch_pdu::init_rx(bool ulsch_) +{ + buffer = nullptr; + subpdus.clear(); + pdu_len = 0; + remaining_len = 0; + ulsch = ulsch_; +} + uint32_t mac_nr_sch_pdu::size_header_sdu(const uint32_t lcid, const uint32_t nbytes) { if (ulsch && (lcid == mac_nr_sch_subpdu::CCCH_SIZE_48 || lcid == mac_nr_sch_subpdu::CCCH_SIZE_64)) { diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index f936e4f5f..913bda089 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -49,6 +49,7 @@ namespace srsenb { class gnb_stack_nr final : public srsenb::enb_stack_base, public stack_interface_phy_nr, + public stack_interface_mac, public srsue::stack_interface_gw, public srslte::task_handler_interface, public srslte::thread @@ -67,6 +68,7 @@ public: // PHY->MAC interface int sf_indication(const uint32_t tti); + int rx_data_indication(rx_data_ind_t& grant); // Temporary GW interface void write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking); @@ -74,6 +76,9 @@ public: bool switch_on(); void run_tti(uint32_t tti); + // MAC interface to trigger processing of received PDUs + void process_pdus() final; + // Task Handling interface srslte::timer_handler::unique_timer get_unique_timer() final { return timers.get_unique_timer(); } srslte::task_multiqueue::queue_handler make_task_queue() final { return pending_tasks.get_queue_handler(); } @@ -84,14 +89,14 @@ public: private: void run_thread() final; - void run_tti_impl(); + void run_tti_impl(uint32_t tti); // args srsenb::stack_args_t args = {}; srslte::logger* logger = nullptr; phy_interface_stack_nr* phy = nullptr; - // timers + /* Functions for MAC Timers */ srslte::timer_handler timers; // derived @@ -113,9 +118,9 @@ private: srslte::task_multiqueue pending_tasks; std::vector deferred_stack_tasks; ///< enqueues stack tasks from within. Avoids locking srslte::task_thread_pool background_tasks; ///< Thread pool used for long, low-priority tasks - int sync_queue_id = -1, background_queue_id = -1; + int sync_queue_id = -1, ue_queue_id = -1, gw_queue_id = -1, mac_queue_id = -1, background_queue_id = -1; }; } // namespace srsenb -#endif // SRSLTE_GNB_STACK_NR_H \ No newline at end of file +#endif // SRSLTE_GNB_STACK_NR_H diff --git a/srsenb/hdr/stack/mac/mac_nr.h b/srsenb/hdr/stack/mac/mac_nr.h index 1101a1409..91d39aa1d 100644 --- a/srsenb/hdr/stack/mac/mac_nr.h +++ b/srsenb/hdr/stack/mac/mac_nr.h @@ -22,6 +22,7 @@ #ifndef SRSENB_MAC_NR_H #define SRSENB_MAC_NR_H +#include "srslte/common/block_queue.h" #include "srslte/common/logmap.h" #include "srslte/common/mac_nr_pcap.h" #include "srslte/mac/mac_nr_pdu.h" @@ -38,6 +39,7 @@ struct mac_nr_args_t { // params for the dummy user srsenb::sched_interface::sched_args_t sched; uint16_t rnti; + uint32_t drb_lcid; // Add args std::string log_level; @@ -53,6 +55,7 @@ public: int init(const mac_nr_args_t& args_, phy_interface_stack_nr* phy, + stack_interface_mac* stack_, rlc_interface_mac_nr* rlc_, rrc_interface_mac_nr* rrc_); void stop(); @@ -69,16 +72,23 @@ public: // Interface for PHY int sf_indication(const uint32_t tti); + int rx_data_indication(stack_interface_phy_nr::rx_data_ind_t& grant); + + void process_pdus(); private: void get_dl_config(const uint32_t tti, phy_interface_stack_nr::dl_config_request_t& config_request, phy_interface_stack_nr::tx_request_t& tx_request); - // Interaction with PHY - phy_interface_stack_nr* phy_h = nullptr; - rlc_interface_mac_nr* rlc_h = nullptr; - rrc_interface_mac_nr* rrc_h = nullptr; + // PDU processing + int handle_pdu(srslte::unique_byte_buffer_t pdu); + + // Interaction with other components + phy_interface_stack_nr* phy_h = nullptr; + stack_interface_mac* stack_h = nullptr; + rlc_interface_mac_nr* rlc_h = nullptr; + rrc_interface_mac_nr* rrc_h = nullptr; std::unique_ptr pcap = nullptr; srslte::log_ref log_h; @@ -101,10 +111,14 @@ private: // UE-specific buffer srslte::mac_nr_sch_pdu ue_tx_pdu; std::vector ue_tx_buffer; + srslte::block_queue + ue_rx_pdu_queue; ///< currently only DCH PDUs supported (add BCH, PCH, etc) srslte::unique_byte_buffer_t ue_rlc_buffer; + + srslte::mac_nr_sch_pdu ue_rx_pdu; }; } // namespace srsenb -#endif // SRSENB_MAC_NR_H \ No newline at end of file +#endif // SRSENB_MAC_NR_H diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index 802e29f5c..02e367003 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -35,8 +35,13 @@ gnb_stack_nr::gnb_stack_nr(srslte::logger* logger_) : logger(logger_), timers(12 m_gw.reset(new srsue::gw()); // m_gtpu.reset(new srsenb::gtpu()); + ue_queue_id = pending_tasks.add_queue(); sync_queue_id = pending_tasks.add_queue(); + gw_queue_id = pending_tasks.add_queue(); + mac_queue_id = pending_tasks.add_queue(); background_queue_id = pending_tasks.add_queue(); + + background_tasks.start(); } gnb_stack_nr::~gnb_stack_nr() @@ -74,7 +79,8 @@ int gnb_stack_nr::init(const srsenb::stack_args_t& args_, const rrc_nr_cfg_t& rr mac_args.pcap = args.mac_pcap; mac_args.sched = args.mac.sched; mac_args.rnti = args.coreless.rnti; - m_mac->init(mac_args, phy, m_rlc.get(), m_rrc.get()); + mac_args.drb_lcid = args.coreless.drb_lcid; + m_mac->init(mac_args, phy, this, m_rlc.get(), m_rrc.get()); m_rlc->init(m_pdcp.get(), m_rrc.get(), m_mac.get(), &timers); @@ -142,15 +148,20 @@ void gnb_stack_nr::run_thread() void gnb_stack_nr::run_tti(uint32_t tti) { current_tti = tti; - pending_tasks.push(sync_queue_id, [this]() { run_tti_impl(); }); + pending_tasks.push(sync_queue_id, [this, tti]() { run_tti_impl(tti); }); } -void gnb_stack_nr::run_tti_impl() +void gnb_stack_nr::run_tti_impl(uint32_t tti) { // m_ngap->run_tti(); timers.step_all(); } +void gnb_stack_nr::process_pdus() +{ + pending_tasks.push(mac_queue_id, [this]() { m_mac->process_pdus(); }); +} + /******************************************************** * * Interface for upper layer timers @@ -169,6 +180,11 @@ int gnb_stack_nr::sf_indication(const uint32_t tti) return m_mac->sf_indication(tti); } +int gnb_stack_nr::rx_data_indication(rx_data_ind_t& grant) +{ + return m_mac->rx_data_indication(grant); +} + // Temporary GW interface void gnb_stack_nr::write_sdu(uint32_t lcid, srslte::unique_byte_buffer_t sdu, bool blocking) { @@ -205,4 +221,4 @@ void gnb_stack_nr::defer_task(srslte::move_task_t task) deferred_stack_tasks.push_back(std::move(task)); } -} // namespace srsenb \ No newline at end of file +} // namespace srsenb diff --git a/srsenb/src/stack/mac/mac_nr.cc b/srsenb/src/stack/mac/mac_nr.cc index 17609a0db..5db5e0721 100644 --- a/srsenb/src/stack/mac/mac_nr.cc +++ b/srsenb/src/stack/mac/mac_nr.cc @@ -48,14 +48,16 @@ mac_nr::~mac_nr() int mac_nr::init(const mac_nr_args_t& args_, phy_interface_stack_nr* phy_, + stack_interface_mac* stack_, rlc_interface_mac_nr* rlc_, rrc_interface_mac_nr* rrc_) { args = args_; - phy_h = phy_; - rlc_h = rlc_; - rrc_h = rrc_; + phy_h = phy_; + stack_h = stack_; + rlc_h = rlc_; + rrc_h = rrc_; log_h->set_level(args.log_level); log_h->set_hex_limit(args.log_hex_limit); @@ -149,6 +151,11 @@ void mac_nr::get_dl_config(const uint32_t tti, ue_tx_pdu.add_sdu(4, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes); ue_tx_pdu.pack(); + log_h->debug_hex(ue_tx_buffer.at(buffer_index)->msg, + ue_tx_buffer.at(buffer_index)->N_bytes, + "Generated MAC PDU (%d B)\n", + ue_tx_buffer.at(buffer_index)->N_bytes); + tx_request.pdus[tx_request.nof_pdus].data[0] = ue_tx_buffer.at(buffer_index)->msg; tx_request.pdus[tx_request.nof_pdus].length = ue_tx_buffer.at(buffer_index)->N_bytes; tx_request.pdus[tx_request.nof_pdus].index = tx_request.nof_pdus; @@ -188,6 +195,56 @@ int mac_nr::sf_indication(const uint32_t tti) return SRSLTE_SUCCESS; } +int mac_nr::rx_data_indication(stack_interface_phy_nr::rx_data_ind_t& rx_data) +{ + // push received PDU on queue + if (rx_data.tb != nullptr) { + if (pcap) { + pcap->write_ul_crnti(rx_data.tb->msg, rx_data.tb->N_bytes, rx_data.rnti, true, rx_data.tti); + } + ue_rx_pdu_queue.push(std::move(rx_data.tb)); + } + + // inform stack that new PDUs may have been received + stack_h->process_pdus(); + + return SRSLTE_SUCCESS; +} + +/** + * Called from the main stack thread to process received PDUs + */ +void mac_nr::process_pdus() +{ + while (started and not ue_rx_pdu_queue.empty()) { + srslte::unique_byte_buffer_t pdu = ue_rx_pdu_queue.wait_pop(); + /// TODO; delegate to demux class + handle_pdu(std::move(pdu)); + } +} + +int mac_nr::handle_pdu(srslte::unique_byte_buffer_t pdu) +{ + log_h->info_hex(pdu->msg, pdu->N_bytes, "Handling MAC PDU (%d B)\n", pdu->N_bytes); + + ue_rx_pdu.init_rx(true); + ue_rx_pdu.unpack(pdu->msg, pdu->N_bytes); + + for (uint32_t i = 0; i < ue_rx_pdu.get_num_subpdus(); ++i) { + srslte::mac_nr_sch_subpdu subpdu = ue_rx_pdu.get_subpdu(i); + log_h->info("Handling subPDU %d/%d: lcid=%d, sdu_len=%d\n", + i, + ue_rx_pdu.get_num_subpdus(), + subpdu.get_lcid(), + subpdu.get_sdu_length()); + + if (subpdu.get_lcid() == args.drb_lcid) { + rlc_h->write_pdu(args.rnti, subpdu.get_lcid(), subpdu.get_sdu(), subpdu.get_sdu_length()); + } + } + return SRSLTE_SUCCESS; +} + int mac_nr::cell_cfg(srsenb::sched_interface::cell_cfg_t* cell_cfg) { cfg = *cell_cfg;