From ab78eb6d58891469438cefad68425e3320b7c375 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 25 Apr 2018 13:44:58 +0200 Subject: [PATCH] Process BCCH from pdu_process thread. Process PCCH from new thread in RRC --- lib/include/srslte/common/pdu_queue.h | 30 ++++++++++------- lib/src/common/pdu_queue.cc | 17 ++++++---- srsenb/hdr/mac/ue.h | 2 +- srsenb/src/mac/ue.cc | 2 +- srsue/hdr/mac/demux.h | 5 +-- srsue/hdr/upper/rrc.h | 17 ++++++++++ srsue/src/mac/demux.cc | 46 +++++++++++++++++---------- srsue/src/upper/rrc.cc | 32 +++++++++++++++++++ 8 files changed, 111 insertions(+), 40 deletions(-) diff --git a/lib/include/srslte/common/pdu_queue.h b/lib/include/srslte/common/pdu_queue.h index a0c2b1da9..5866ce3b3 100644 --- a/lib/include/srslte/common/pdu_queue.h +++ b/lib/include/srslte/common/pdu_queue.h @@ -41,29 +41,35 @@ namespace srslte { class pdu_queue { public: + typedef enum { + DCH, + BCH, + MCH + } channel_t; class process_callback { - public: - virtual void process_pdu(uint8_t *buff, uint32_t len, uint32_t tstamp) = 0; + public: + virtual void process_pdu(uint8_t *buff, uint32_t len, channel_t channel, uint32_t tstamp) = 0; }; pdu_queue(uint32_t pool_size = DEFAULT_POOL_SIZE) : pool(pool_size), callback(NULL), log_h(NULL) {} void init(process_callback *callback, log* log_h_); - uint8_t* request(uint32_t len); + uint8_t* request(uint32_t len); void deallocate(uint8_t* pdu); - void push(uint8_t *ptr, uint32_t len, uint32_t tstamp = 0); - + void push(uint8_t *ptr, uint32_t len, channel_t channel = DCH, uint32_t tstamp = 0); + bool process_pdus(); - + private: - const static int DEFAULT_POOL_SIZE = 64; // Number of PDU buffers in total - const static int MAX_PDU_LEN = 150*1024/8; // ~ 150 Mbps - + const static int DEFAULT_POOL_SIZE = 64; // Number of PDU buffers in total + const static int MAX_PDU_LEN = 150*1024/8; // ~ 150 Mbps + typedef struct { - uint8_t ptr[MAX_PDU_LEN]; - uint32_t len; - uint32_t tstamp; + uint8_t ptr[MAX_PDU_LEN]; + uint32_t len; + uint32_t tstamp; + channel_t channel; #ifdef SRSLTE_BUFFER_POOL_LOG_ENABLED char debug_name[128]; #endif diff --git a/lib/src/common/pdu_queue.cc b/lib/src/common/pdu_queue.cc index 061433033..9b5e83c7b 100644 --- a/lib/src/common/pdu_queue.cc +++ b/lib/src/common/pdu_queue.cc @@ -74,12 +74,13 @@ void pdu_queue::deallocate(uint8_t* pdu) * This function enqueues the packet and returns quicly because ACK * deadline is important here. */ -void pdu_queue::push(uint8_t *ptr, uint32_t len, uint32_t tstamp) +void pdu_queue::push(uint8_t *ptr, uint32_t len, channel_t channel, uint32_t tstamp) { if (ptr) { pdu_t *pdu = (pdu_t*) ptr; pdu->len = len; pdu->tstamp = tstamp; + pdu->channel = channel; pdu_q.push(pdu); } else { log_h->warning("Error pushing pdu: ptr is empty\n"); @@ -88,15 +89,17 @@ void pdu_queue::push(uint8_t *ptr, uint32_t len, uint32_t tstamp) bool pdu_queue::process_pdus() { - bool have_data = false; - uint32_t cnt = 0; - pdu_t *pdu; + bool have_data = false; + uint32_t cnt = 0; + pdu_t *pdu; while(pdu_q.try_pop(&pdu)) { if (callback) { - callback->process_pdu(pdu->ptr, pdu->len, pdu->tstamp); + callback->process_pdu(pdu->ptr, pdu->len, pdu->channel, pdu->tstamp); } - if (!pool.deallocate(pdu)) { - log_h->warning("Error deallocating from buffer pool in process_pdus(): buffer not created in this pool.\n"); + if (pdu->channel == DCH) { + if (!pool.deallocate(pdu)) { + log_h->warning("Error deallocating from buffer pool in process_pdus(): buffer not created in this pool.\n"); + } } cnt++; have_data = true; diff --git a/srsenb/hdr/mac/ue.h b/srsenb/hdr/mac/ue.h index e7fbd0c10..165c1ea3e 100644 --- a/srsenb/hdr/mac/ue.h +++ b/srsenb/hdr/mac/ue.h @@ -95,7 +95,7 @@ public: bool process_pdus(); uint8_t *request_buffer(uint32_t tti, uint32_t len); - void process_pdu(uint8_t *pdu, uint32_t nof_bytes, uint32_t tstamp); + void process_pdu(uint8_t *pdu, uint32_t nof_bytes, srslte::pdu_queue::channel_t channel, uint32_t tstamp); void push_pdu(uint32_t tti, uint32_t len); void deallocate_pdu(uint32_t tti); diff --git a/srsenb/src/mac/ue.cc b/srsenb/src/mac/ue.cc index 39e8c88e2..975d6e9b1 100644 --- a/srsenb/src/mac/ue.cc +++ b/srsenb/src/mac/ue.cc @@ -142,7 +142,7 @@ void ue::set_tti(uint32_t tti) { #include -void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, uint32_t tstamp) +void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channel_t channel, uint32_t tstamp) { // Unpack ULSCH MAC PDU mac_msg_ul.init_rx(nof_bytes, true); diff --git a/srsue/hdr/mac/demux.h b/srsue/hdr/mac/demux.h index c738a0fd3..410865c55 100644 --- a/srsue/hdr/mac/demux.h +++ b/srsue/hdr/mac/demux.h @@ -51,12 +51,13 @@ public: void push_pdu(uint8_t *buff, uint32_t nof_bytes, uint32_t tstamp); void push_pdu_bcch(uint8_t *buff, uint32_t nof_bytes, uint32_t tstamp); + void push_pdu_mch(uint8_t *buff, uint32_t nof_bytes, uint32_t tstamp); void push_pdu_temp_crnti(uint8_t *buff, uint32_t nof_bytes); void set_uecrid_callback(bool (*callback)(void*, uint64_t), void *arg); bool get_uecrid_successful(); - - void process_pdu(uint8_t *pdu, uint32_t nof_bytes, uint32_t tstamp); + + void process_pdu(uint8_t *pdu, uint32_t nof_bytes, srslte::pdu_queue::channel_t channel, uint32_t tstamp); private: const static int MAX_PDU_LEN = 150*1024/8; // ~ 150 Mbps diff --git a/srsue/hdr/upper/rrc.h b/srsue/hdr/upper/rrc.h index 602ebd55b..1e099351d 100644 --- a/srsue/hdr/upper/rrc.h +++ b/srsue/hdr/upper/rrc.h @@ -36,6 +36,7 @@ #include "srslte/interfaces/ue_interfaces.h" #include "srslte/common/security.h" #include "srslte/common/threads.h" +#include "srslte/common/block_queue.h" #include #include @@ -253,6 +254,7 @@ class rrc ,public rrc_interface_pdcp ,public rrc_interface_rlc ,public srslte::timer_callback + ,public thread { public: rrc(); @@ -310,6 +312,21 @@ public: private: + + typedef struct { + enum { + PCCH, + STOP + } command; + byte_buffer_t *pdu; + } cmd_msg_t; + + bool running; + srslte::block_queue cmd_q; + void run_thread(); + + void process_pcch(byte_buffer_t *pdu); + srslte::byte_buffer_pool *pool; srslte::log *rrc_log; phy_interface_rrc *phy; diff --git a/srsue/src/mac/demux.cc b/srsue/src/mac/demux.cc index 3e0d2f44f..640b78bd5 100644 --- a/srsue/src/mac/demux.cc +++ b/srsue/src/mac/demux.cc @@ -107,27 +107,29 @@ void demux::push_pdu_temp_crnti(uint8_t *buff, uint32_t nof_bytes) Debug("Saved MAC PDU with Temporal C-RNTI in buffer\n"); - pdus.push(buff, nof_bytes); + pdus.push(buff, nof_bytes, srslte::pdu_queue::DCH); } else { Warning("Trying to push PDU with payload size zero\n"); } } -/* Demultiplexing of logical channels and dissassemble of MAC CE - * This function enqueues the packet and returns quicly because ACK - * deadline is important here. - */ +/* Demultiplexing of logical channels and dissassemble of MAC CE + * This function enqueues the packet and returns quickly because ACK + * deadline is important here. + */ void demux::push_pdu(uint8_t *buff, uint32_t nof_bytes, uint32_t tstamp) { - return pdus.push(buff, nof_bytes, tstamp); + return pdus.push(buff, nof_bytes, srslte::pdu_queue::DCH, tstamp); } /* Demultiplexing of MAC PDU associated with SI-RNTI. The PDU passes through * the MAC in transparent mode. -* Warning: In this case function sends the message to RLC now, since SI blocks do not -* require ACK feedback to be transmitted quickly. */ void demux::push_pdu_bcch(uint8_t *buff, uint32_t nof_bytes, uint32_t tstamp) { - rlc->write_pdu_bcch_dlsch(buff, nof_bytes); + pdus.push(buff, nof_bytes, srslte::pdu_queue::BCH, tstamp); +} + +void demux::push_pdu_mch(uint8_t *buff, uint32_t nof_bytes, uint32_t tstamp) { + pdus.push(buff, nof_bytes, srslte::pdu_queue::MCH, tstamp); } bool demux::process_pdus() @@ -135,15 +137,25 @@ bool demux::process_pdus() return pdus.process_pdus(); } -void demux::process_pdu(uint8_t *mac_pdu, uint32_t nof_bytes, uint32_t tstamp) +void demux::process_pdu(uint8_t *mac_pdu, uint32_t nof_bytes, srslte::pdu_queue::channel_t channel, uint32_t tstamp) { - // Unpack DLSCH MAC PDU - mac_msg.init_rx(nof_bytes); - mac_msg.parse_packet(mac_pdu); - - process_sch_pdu(&mac_msg); - //srslte_vec_fprint_byte(stdout, mac_pdu, nof_bytes); - Debug("MAC PDU processed\n"); + Debug("Processing MAC PDU channel %d\n", channel); + switch(channel) { + case srslte::pdu_queue::DCH: + // Unpack DLSCH MAC PDU + mac_msg.init_rx(nof_bytes); + mac_msg.parse_packet(mac_pdu); + + process_sch_pdu(&mac_msg); + //srslte_vec_fprint_byte(stdout, mac_pdu, nof_bytes); + break; + case srslte::pdu_queue::BCH: + rlc->write_pdu_bcch_dlsch(mac_pdu, nof_bytes); + break; + case srslte::pdu_queue::MCH: + // Process downlink MCH + break; + } } void demux::process_sch_pdu(srslte::sch_pdu *pdu_msg) diff --git a/srsue/src/upper/rrc.cc b/srsue/src/upper/rrc.cc index ae975e1cc..8e9e60c4f 100644 --- a/srsue/src/upper/rrc.cc +++ b/srsue/src/upper/rrc.cc @@ -56,6 +56,7 @@ rrc::rrc() serving_cell = new cell_t(); neighbour_cells.reserve(NOF_NEIGHBOUR_CELLS); initiated = false; + running = false; } rrc::~rrc() @@ -139,10 +140,17 @@ void rrc::init(phy_interface_rrc *phy_, // set seed for rand (used in attach) srand(time(NULL)); + running = true; + start(); initiated = true; } void rrc::stop() { + running = false; + cmd_msg_t msg; + msg.command = cmd_msg_t::STOP; + cmd_q.push(msg); + wait_thread_finish(); } rrc_state_t rrc::get_state() { @@ -161,6 +169,23 @@ void rrc::set_args(rrc_args_t *args) { memcpy(&this->args, args, sizeof(rrc_args_t)); } +/* + * Low priority thread to run functions that can not be executed from main thread + */ +void rrc::run_thread() { + while(running) { + cmd_msg_t msg = cmd_q.wait_pop(); + switch(msg.command) { + case cmd_msg_t::STOP: + return; + case cmd_msg_t::PCCH: + process_pcch(msg.pdu); + break; + } + } +} + + /* * * RRC State Machine @@ -1639,6 +1664,13 @@ void rrc::handle_sib13() * *******************************************************************************/ void rrc::write_pdu_pcch(byte_buffer_t *pdu) { + cmd_msg_t msg; + msg.pdu = pdu; + msg.command = cmd_msg_t::PCCH; + cmd_q.push(msg); +} + +void rrc::process_pcch(byte_buffer_t *pdu) { if (pdu->N_bytes > 0 && pdu->N_bytes < SRSLTE_MAX_BUFFER_SIZE_BITS) { rrc_log->info_hex(pdu->msg, pdu->N_bytes, "PCCH message received %d bytes\n", pdu->N_bytes); rrc_log->info("PCCH message Stack latency: %ld us\n", pdu->get_latency_us());