From 487fdd56169606bf61b3663aa0971427ddf6109d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 11 Oct 2019 13:36:13 +0200 Subject: [PATCH] ttcn3: split SS interface and protect SS main thread properly the SS main thread and the provided interaces weren't protecting members correctly --- srsue/test/ttcn3/hdr/ttcn3_interfaces.h | 23 +- srsue/test/ttcn3/hdr/ttcn3_srb_interface.h | 6 +- srsue/test/ttcn3/hdr/ttcn3_sys_interface.h | 4 +- srsue/test/ttcn3/hdr/ttcn3_syssim.h | 474 +++++++++++---------- srsue/test/ttcn3/hdr/ttcn3_ut_interface.h | 4 +- srsue/test/ttcn3/src/lte_ttcn3_phy.cc | 6 + 6 files changed, 275 insertions(+), 242 deletions(-) diff --git a/srsue/test/ttcn3/hdr/ttcn3_interfaces.h b/srsue/test/ttcn3/hdr/ttcn3_interfaces.h index 3f0177c7f..1b21bc87a 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_interfaces.h +++ b/srsue/test/ttcn3/hdr/ttcn3_interfaces.h @@ -25,8 +25,8 @@ #include "srslte/common/common.h" #include "srslte/interfaces/ue_interfaces.h" -// Interface used by system interface to communicate with main component -class syssim_interface +// Interfaces used by system interface to communicate with main component +class ss_ut_interface { public: virtual void tc_start(const char* name) = 0; @@ -36,12 +36,15 @@ public: virtual void switch_off_ue() = 0; virtual void enable_data() = 0; virtual void disable_data() = 0; - virtual void set_cell_config(std::string cell_name, uint32_t earfcn, srslte_cell_t cell, const float power) = 0; - virtual void set_cell_attenuation(std::string cell_name, const float attenuation) = 0; +}; + +class ss_sys_interface +{ +public: virtual void add_bcch_pdu(srslte::unique_byte_buffer_t pdu) = 0; - virtual void add_ccch_pdu(srslte::unique_byte_buffer_t pdu) = 0; - virtual void add_dcch_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) = 0; virtual void add_pch_pdu(srslte::unique_byte_buffer_t pdu) = 0; + virtual void set_cell_attenuation(std::string cell_name, const float attenuation) = 0; + virtual void set_cell_config(std::string cell_name, uint32_t earfcn, srslte_cell_t cell, const float power) = 0; virtual void add_srb(uint32_t lcid, srslte::pdcp_config_t pdcp_config) = 0; virtual void del_srb(uint32_t lcid) = 0; virtual uint32_t get_tti() = 0; @@ -53,12 +56,18 @@ public: const srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0; }; +class ss_srb_interface +{ +public: + virtual void add_ccch_pdu(srslte::unique_byte_buffer_t pdu) = 0; + virtual void add_dcch_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) = 0; +}; + class syssim_interface_phy { public: virtual void prach_indication(uint32_t preamble_index, const uint32_t& cell_id) = 0; virtual void sr_req(uint32_t tti_tx) = 0; - // 0; virtual void virtual void tx_pdu(const uint8_t* payload, const int len, const uint32_t tx_tti) = 0; }; diff --git a/srsue/test/ttcn3/hdr/ttcn3_srb_interface.h b/srsue/test/ttcn3/hdr/ttcn3_srb_interface.h index 0f2cf8dad..ec2d305b8 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_srb_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_srb_interface.h @@ -34,10 +34,10 @@ using namespace srslte; class ttcn3_srb_interface : public netsource_handler { public: - ttcn3_srb_interface() : syssim(nullptr), pool(byte_buffer_pool::get_instance()), netsource_handler("TTCN3_SRB_IF"){}; + ttcn3_srb_interface() : pool(byte_buffer_pool::get_instance()), netsource_handler("TTCN3_SRB_IF"){}; ~ttcn3_srb_interface(){}; - void init(syssim_interface* syssim_, srslte::log* log_, std::string net_ip_, uint32_t net_port_) + void init(ss_srb_interface* syssim_, srslte::log* log_, std::string net_ip_, uint32_t net_port_) { syssim = syssim_; log = log_; @@ -166,7 +166,7 @@ private: syssim->add_dcch_pdu(lcid, std::move(pdu)); } - syssim_interface* syssim = nullptr; + ss_srb_interface* syssim = nullptr; byte_buffer_pool* pool = nullptr; }; diff --git a/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h b/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h index c85bb3252..e3575ee24 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_sys_interface.h @@ -35,7 +35,7 @@ public: ttcn3_sys_interface() : netsource_handler("TTCN3_SYS_IF"){}; ~ttcn3_sys_interface(){}; - void init(syssim_interface* syssim_, srslte::log* log_, std::string net_ip_, uint32_t net_port_) + void init(ss_sys_interface* syssim_, srslte::log* log_, std::string net_ip_, uint32_t net_port_) { syssim = syssim_; net_ip = net_ip_; @@ -596,7 +596,7 @@ private: } phy_interface_syssim* phy = nullptr; - syssim_interface* syssim = nullptr; + ss_sys_interface* syssim = nullptr; byte_buffer_pool* pool = nullptr; }; diff --git a/srsue/test/ttcn3/hdr/ttcn3_syssim.h b/srsue/test/ttcn3/hdr/ttcn3_syssim.h index 5fda05da5..b21844dda 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_syssim.h +++ b/srsue/test/ttcn3/hdr/ttcn3_syssim.h @@ -25,6 +25,7 @@ #include "dut_utils.h" #include "srslte/common/netsource_handler.h" #include "srslte/common/pdu_queue.h" +#include "srslte/common/threads.h" #include "srslte/upper/pdcp.h" #include "srslte/upper/rlc.h" #include "ttcn3_ip_ctrl_interface.h" @@ -33,14 +34,16 @@ #include "ttcn3_sys_interface.h" #include "ttcn3_ue.h" #include "ttcn3_ut_interface.h" -#include + #include #define TTCN3_CRNTI (0x1001) class ttcn3_syssim : public thread, public syssim_interface_phy, - public syssim_interface, + public ss_ut_interface, + public ss_sys_interface, + public ss_srb_interface, public rrc_interface_rlc, public rlc_interface_pdcp, public rrc_interface_pdcp, @@ -63,6 +66,8 @@ public: void init(const all_args_t& args_) { + std::lock_guard lock(mutex); + args = args_; // Make sure to get SS logging as well @@ -121,6 +126,7 @@ public: void stop() { + std::lock_guard lock(mutex); running = false; @@ -136,6 +142,7 @@ public: srb.stop(); } + // Internal function called with acquired lock void reset() { rlc.reset(); @@ -147,6 +154,8 @@ public: // Called from UT before starting testcase void tc_start(const char* name) { + std::lock_guard lock(mutex); + if (ue == nullptr) { // strip testsuite name std::string tc_name = get_tc_name(name); @@ -191,6 +200,8 @@ public: void tc_end() { + std::lock_guard lock(mutex); + if (ue != NULL) { // ask periodic thread to stop running = false; @@ -220,47 +231,16 @@ public: // only return after new UE instance is up and running } - void switch_on_ue() - { - if (ue != nullptr) { - log.info("Switching on UE ID=%d\n", run_id); - log.console("Switching on UE ID=%d\n", run_id); - - // Trigger attach procedure - ue->switch_on(); - } else { - log.error("UE not initialized. Can't switch UE on.\n"); - } - } + // Called from outside + void switch_on_ue() { event_queue.push(UE_SWITCH_ON); } - void switch_off_ue() - { - if (ue != nullptr) { - log.info("Switching off UE ID=%d\n", run_id); - log.console("Switching off UE ID=%d\n", run_id); - ue->switch_off(); - } else { - log.error("UE not initialized. Can't switch UE off.\n"); - } - } + void switch_off_ue() { event_queue.push(UE_SWITCH_OFF); } - void enable_data() - { - if (ue) { - log.info("Enabling data services on UE ID=%d\n", run_id); - ue->enable_data(); - } - } + void enable_data() { event_queue.push(ENABLE_DATA); } - void disable_data() - { - if (ue) { - log.info("Disabling data services on UE ID=%d\n", run_id); - ue->disable_data(); - } - } + void disable_data() { event_queue.push(DISABLE_DATA); } - // Interface for PHY + // Called from PHY but always from the SS main thread with lock being hold void prach_indication(uint32_t preamble_index_, const uint32_t& cell_id) { // store TTI for providing UL grant for Msg3 transmission @@ -276,6 +256,76 @@ public: } } + // Called from PHY but always from the SS main thread with lock being hold + void sr_req(uint32_t tti_tx) + { + log.info("Received SR from PHY\n"); + sr_tti = tti_tx; + } + + // Called from PHY but always from the SS main thread with lock being hold + void tx_pdu(const uint8_t* payload, const int len, const uint32_t tx_tti) + { + if (payload == NULL) { + ss_mac_log.error("Received NULL as PDU payload. Dropping.\n"); + return; + } + + // Parse MAC + mac_msg_ul.init_rx(len, true); + mac_msg_ul.parse_packet((uint8_t*)payload); + + while (mac_msg_ul.next()) { + assert(mac_msg_ul.get()); + if (mac_msg_ul.get()->is_sdu()) { + // Route logical channel + ss_mac_log.info_hex(mac_msg_ul.get()->get_sdu_ptr(), + mac_msg_ul.get()->get_payload_size(), + "PDU: rnti=0x%x, lcid=%d, %d bytes\n", + 0xdead, + mac_msg_ul.get()->get_sdu_lcid(), + mac_msg_ul.get()->get_payload_size()); + + // Push PDU to our own RLC (needed to handle status reporting, etc. correctly + ss_mac_log.info_hex(mac_msg_ul.get()->get_sdu_ptr(), + mac_msg_ul.get()->get_payload_size(), + "Route PDU to LCID=%d (%d B)\n", + mac_msg_ul.get()->get_sdu_lcid(), + mac_msg_ul.get()->get_payload_size()); + rlc.write_pdu( + mac_msg_ul.get()->get_sdu_lcid(), mac_msg_ul.get()->get_sdu_ptr(), mac_msg_ul.get()->get_payload_size()); + + // Save contention resolution if lcid == 0 + if (mac_msg_ul.get()->get_sdu_lcid() == 0) { + int nbytes = srslte::sch_subh::MAC_CE_CONTRES_LEN; + if (mac_msg_ul.get()->get_payload_size() >= (uint32_t)nbytes) { + uint8_t* ue_cri_ptr = (uint8_t*)&conres_id; + uint8_t* pkt_ptr = mac_msg_ul.get()->get_sdu_ptr(); // Warning here: we want to include the + for (int i = 0; i < nbytes; i++) { + ue_cri_ptr[nbytes - i - 1] = pkt_ptr[i]; + } + ss_mac_log.info_hex(ue_cri_ptr, nbytes, "Contention resolution ID:\n"); + } else { + ss_mac_log.error("Received CCCH UL message of invalid size=%d bytes\n", + mac_msg_ul.get()->get_payload_size()); + } + } + } + } + mac_msg_ul.reset(); + + /* Process CE after all SDUs because we need to update BSR after */ + bool bsr_received = false; + while (mac_msg_ul.next()) { + assert(mac_msg_ul.get()); + if (!mac_msg_ul.get()->is_sdu()) { + // Process MAC Control Element + bsr_received |= process_ce(mac_msg_ul.get()); + } + } + } + + // Internal function called from main thread void send_rar(uint32_t preamble_index) { log.info("Sending RAR for RAPID=%d\n", preamble_index); @@ -316,6 +366,7 @@ public: prach_tti = -1; } + // Internal function called from main thread void send_msg3_grant() { log.info("Sending Msg3 grant for C-RNTI=%d\n", crnti); @@ -330,10 +381,9 @@ public: ue->new_grant_ul(ul_grant); } - void sr_req(uint32_t tti_tx) + // Internal function called from main thread + void send_sr_ul_grant() { - log.info("Received SR from PHY\n"); - // Provide new UL grant to UE mac_interface_phy_lte::mac_grant_ul_t ul_grant = {}; ul_grant.tb.tbs = 100; // FIXME: reasonable size? @@ -343,73 +393,13 @@ public: ul_grant.pid = get_pid(tti); ue->new_grant_ul(ul_grant); - } - - void tx_pdu(const uint8_t* payload, const int len, const uint32_t tx_tti) - { - - if (payload == NULL) { - ss_mac_log.error("Received NULL as PDU payload. Dropping.\n"); - return; - } - - // Parse MAC - mac_msg_ul.init_rx(len, true); - mac_msg_ul.parse_packet((uint8_t*)payload); - - while (mac_msg_ul.next()) { - assert(mac_msg_ul.get()); - if (mac_msg_ul.get()->is_sdu()) { - // Route logical channel - ss_mac_log.info_hex(mac_msg_ul.get()->get_sdu_ptr(), - mac_msg_ul.get()->get_payload_size(), - "PDU: rnti=0x%x, lcid=%d, %d bytes\n", - 0xdead, - mac_msg_ul.get()->get_sdu_lcid(), - mac_msg_ul.get()->get_payload_size()); - // Push PDU to our own RLC (needed to handle status reporting, etc. correctly - ss_mac_log.info_hex(mac_msg_ul.get()->get_sdu_ptr(), - mac_msg_ul.get()->get_payload_size(), - "Route PDU to LCID=%d (%d B)\n", - mac_msg_ul.get()->get_sdu_lcid(), - mac_msg_ul.get()->get_payload_size()); - rlc.write_pdu( - mac_msg_ul.get()->get_sdu_lcid(), mac_msg_ul.get()->get_sdu_ptr(), mac_msg_ul.get()->get_payload_size()); - - // Save contention resolution if lcid == 0 - if (mac_msg_ul.get()->get_sdu_lcid() == 0) { - int nbytes = srslte::sch_subh::MAC_CE_CONTRES_LEN; - if (mac_msg_ul.get()->get_payload_size() >= (uint32_t)nbytes) { - uint8_t* ue_cri_ptr = (uint8_t*)&conres_id; - uint8_t* pkt_ptr = mac_msg_ul.get()->get_sdu_ptr(); // Warning here: we want to include the - for (int i = 0; i < nbytes; i++) { - ue_cri_ptr[nbytes - i - 1] = pkt_ptr[i]; - } - ss_mac_log.info_hex(ue_cri_ptr, nbytes, "Contention resolution ID:\n"); - } else { - ss_mac_log.error("Received CCCH UL message of invalid size=%d bytes\n", - mac_msg_ul.get()->get_payload_size()); - } - } - } - } - mac_msg_ul.reset(); - - /* Process CE after all SDUs because we need to update BSR after */ - bool bsr_received = false; - while (mac_msg_ul.next()) { - assert(mac_msg_ul.get()); - if (!mac_msg_ul.get()->is_sdu()) { - // Process MAC Control Element - bsr_received |= process_ce(mac_msg_ul.get()); - } - } + sr_tti = -1; } + // internal function called from tx_pdu (called from main thread) bool process_ce(srslte::sch_subh* subh) { - uint16_t rnti = dl_rnti; uint32_t buff_size[4] = {0, 0, 0, 0}; @@ -421,22 +411,10 @@ public: case srslte::sch_subh::PHR_REPORT: phr = subh->get_phr(); ss_mac_log.info("CE: Received PHR from rnti=0x%x, value=%.0f\n", rnti, phr); -#if 0 - //sched->ul_phr(rnti, (int) phr); - //metrics_phr(phr); -#endif break; case srslte::sch_subh::CRNTI: old_rnti = subh->get_c_rnti(); ss_mac_log.info("CE: Received C-RNTI from temp_rnti=0x%x, rnti=0x%x\n", rnti, old_rnti); -#if 0 - if (sched->ue_exists(old_rnti)) { - rrc->upd_user(rnti, old_rnti); - rnti = old_rnti; - } else { - Error("Updating user C-RNTI: rnti=0x%x already released\n", old_rnti); - } -#endif break; case srslte::sch_subh::TRUNC_BSR: case srslte::sch_subh::SHORT_BSR: @@ -445,13 +423,6 @@ public: ss_mac_log.error("Invalid Index Passed to lc groups\n"); break; } -#if 0 - for (uint32_t i=0;iul_bsr(rnti, lc_groups[idx][i], buff_size[idx]); - - } -#endif ss_mac_log.info("CE: Received %s BSR rnti=0x%x, lcg=%d, value=%d\n", subh->ce_type() == srslte::sch_subh::SHORT_BSR ? "Short" : "Trunc", rnti, @@ -461,13 +432,6 @@ public: break; case srslte::sch_subh::LONG_BSR: subh->get_bsr(buff_size); -#if 0 - for (idx=0;idx<4;idx++) { - for (uint32_t i=0;iul_bsr(rnti, lc_groups[idx][i], buff_size[idx]); - } - } -#endif is_bsr = true; ss_mac_log.info("CE: Received Long BSR rnti=0x%x, value=%d,%d,%d,%d\n", rnti, @@ -486,7 +450,7 @@ public: return is_bsr; } - uint32_t get_pid(const uint32_t tti) { return tti % (2 * FDD_HARQ_DELAY_MS); } + uint32_t get_pid(const uint32_t tti_) { return tti_ % (2 * FDD_HARQ_DELAY_MS); } bool get_ndi_for_new_ul_tx(const uint32_t tti_) { @@ -511,112 +475,147 @@ public: uint32_t sib_idx = 0; while (running) { - log.debug("SYSSIM-TTI=%d\n", tti); - ue->set_current_tti(tti); - dl_rnti = ue->get_dl_sched_rnti(tti); - - if (SRSLTE_RNTI_ISSI(dl_rnti)) { - // deliver SIBs one after another - mac_interface_phy_lte::mac_grant_dl_t dl_grant = {}; - dl_grant.pid = get_pid(tti); - dl_grant.rnti = dl_rnti; - dl_grant.tb[0].tbs = sibs[sib_idx]->N_bytes; - dl_grant.tb[0].ndi = get_ndi_for_new_dl_tx(tti); - ue->new_tb(dl_grant, sibs[sib_idx]->msg); - - sib_idx = (sib_idx + 1) % sibs.size(); - } else if (SRSLTE_RNTI_ISRAR(dl_rnti)) { - if (prach_tti != -1) { - rar_tti = (prach_tti + 3) % 10240; - if (tti == rar_tti) { - send_rar(prach_preamble_index); + { + std::lock_guard lock(mutex); + + tti = (tti + 1) % 10240; + + log.debug("SYSSIM-TTI=%d\n", tti); + ue->set_current_tti(tti); + + // process events, if any + while (not event_queue.empty()) { + ss_events_t ev = event_queue.wait_pop(); + switch (ev) { + case UE_SWITCH_ON: + log.console("Switching on UE ID=%d\n", run_id); + ue->switch_on(); + break; + case UE_SWITCH_OFF: + log.console("Switching off UE ID=%d\n", run_id); + ue->switch_off(); + break; + case ENABLE_DATA: + log.console("Enabling data for UE ID=%d\n", run_id); + ue->enable_data(); + break; + case DISABLE_DATA: + log.console("Disabling data for UE ID=%d\n", run_id); + ue->disable_data(); + break; } } - } else if (SRSLTE_RNTI_ISPA(dl_rnti)) { - log.debug("Searching for paging RNTI\n"); - // PCH will be triggered from SYSSIM after receiving Paging - } else if (SRSLTE_RNTI_ISUSER(dl_rnti)) { - // check if this is for contention resolution after PRACH/RAR - if (dl_rnti == crnti) { - log.debug("Searching for C-RNTI=%d\n", crnti); - - if (rar_tti != -1) { - msg3_tti = (rar_tti + 3) % 10240; - if (tti == msg3_tti) { - send_msg3_grant(); - rar_tti = -1; + + dl_rnti = ue->get_dl_sched_rnti(tti); + + if (SRSLTE_RNTI_ISSI(dl_rnti)) { + // deliver SIBs one after another + mac_interface_phy_lte::mac_grant_dl_t dl_grant = {}; + dl_grant.pid = get_pid(tti); + dl_grant.rnti = dl_rnti; + dl_grant.tb[0].tbs = sibs[sib_idx]->N_bytes; + dl_grant.tb[0].ndi = get_ndi_for_new_dl_tx(tti); + ue->new_tb(dl_grant, sibs[sib_idx]->msg); + + sib_idx = (sib_idx + 1) % sibs.size(); + } else if (SRSLTE_RNTI_ISRAR(dl_rnti)) { + if (prach_tti != -1) { + rar_tti = (prach_tti + 3) % 10240; + if (tti == rar_tti) { + send_rar(prach_preamble_index); } } - } - if (dl_rnti != 0) { - log.debug("Searching for RNTI=%d\n", dl_rnti); - - // look for DL data to be send in each bearer and provide grant accordingly - for (int lcid = 0; lcid < SRSLTE_N_RADIO_BEARERS; lcid++) { - uint32_t buf_state = rlc.get_buffer_state(lcid); - if (buf_state > 0) { - log.debug("LCID=%d, buffer_state=%d\n", lcid, buf_state); - const uint32_t mac_header_size = 10; // Add MAC header (10 B for all subheaders, etc) - if (tmp_rlc_buffer.get_tailroom() > (buf_state + mac_header_size)) { - uint32_t pdu_size = rlc.read_pdu(lcid, tmp_rlc_buffer.msg, buf_state); - tx_payload_buffer.clear(); - mac_msg_dl.init_tx(&tx_payload_buffer, pdu_size + mac_header_size, false); - - // check if this is Msg4 that needs to contain the contention resolution ID CE - if (msg3_tti != -1) { - if (lcid == 0) { - if (mac_msg_dl.new_subh()) { - if (mac_msg_dl.get()->set_con_res_id(conres_id)) { - log.info("CE: Added Contention Resolution ID=0x%lx\n", conres_id); + } else if (SRSLTE_RNTI_ISPA(dl_rnti)) { + log.debug("Searching for paging RNTI\n"); + // PCH will be triggered from SYSSIM after receiving Paging + } else if (SRSLTE_RNTI_ISUSER(dl_rnti)) { + // check if this is for contention resolution after PRACH/RAR + if (dl_rnti == crnti) { + log.debug("Searching for C-RNTI=%d\n", crnti); + + if (rar_tti != -1) { + msg3_tti = (rar_tti + 3) % 10240; + if (tti == msg3_tti) { + send_msg3_grant(); + rar_tti = -1; + } + } + } + + // check for SR + if (sr_tti != -1) { + send_sr_ul_grant(); + } + + if (dl_rnti != 0) { + log.debug("Searching for RNTI=%d\n", dl_rnti); + + // look for DL data to be send in each bearer and provide grant accordingly + for (int lcid = 0; lcid < SRSLTE_N_RADIO_BEARERS; lcid++) { + uint32_t buf_state = rlc.get_buffer_state(lcid); + if (buf_state > 0) { + log.debug("LCID=%d, buffer_state=%d\n", lcid, buf_state); + const uint32_t mac_header_size = 10; // Add MAC header (10 B for all subheaders, etc) + if (tmp_rlc_buffer.get_tailroom() > (buf_state + mac_header_size)) { + uint32_t pdu_size = rlc.read_pdu(lcid, tmp_rlc_buffer.msg, buf_state); + tx_payload_buffer.clear(); + mac_msg_dl.init_tx(&tx_payload_buffer, pdu_size + mac_header_size, false); + + // check if this is Msg4 that needs to contain the contention resolution ID CE + if (msg3_tti != -1) { + if (lcid == 0) { + if (mac_msg_dl.new_subh()) { + if (mac_msg_dl.get()->set_con_res_id(conres_id)) { + log.info("CE: Added Contention Resolution ID=0x%lx\n", conres_id); + } else { + log.error("CE: Setting Contention Resolution ID CE\n"); + } } else { - log.error("CE: Setting Contention Resolution ID CE\n"); + log.error("CE: Setting Contention Resolution ID CE. No space for a subheader\n"); } - } else { - log.error("CE: Setting Contention Resolution ID CE. No space for a subheader\n"); + msg3_tti = -1; } - msg3_tti = -1; } - } - // Add payload - if (mac_msg_dl.new_subh()) { - int n = mac_msg_dl.get()->set_sdu(lcid, pdu_size, tmp_rlc_buffer.msg); - if (n == -1) { - log.error("Error while adding SDU (%d B) to MAC PDU\n", pdu_size); - mac_msg_dl.del_subh(); + // Add payload + if (mac_msg_dl.new_subh()) { + int n = mac_msg_dl.get()->set_sdu(lcid, pdu_size, tmp_rlc_buffer.msg); + if (n == -1) { + log.error("Error while adding SDU (%d B) to MAC PDU\n", pdu_size); + mac_msg_dl.del_subh(); + } } - } - - uint8_t* mac_pdu_ptr = mac_msg_dl.write_packet(&log); - if (mac_pdu_ptr != nullptr) { - log.info_hex(mac_pdu_ptr, mac_msg_dl.get_pdu_len(), "DL MAC PDU (%d B):\n", mac_msg_dl.get_pdu_len()); - // Prepare MAC grant for CCCH - mac_interface_phy_lte::mac_grant_dl_t dl_grant = {}; - dl_grant.pid = get_pid(tti); - dl_grant.rnti = dl_rnti; - dl_grant.tb[0].tbs = mac_msg_dl.get_pdu_len(); - dl_grant.tb[0].ndi_present = true; - dl_grant.tb[0].ndi = get_ndi_for_new_dl_tx(tti); - - ue->new_tb(dl_grant, (const uint8_t*)mac_pdu_ptr); + uint8_t* mac_pdu_ptr = mac_msg_dl.write_packet(&log); + if (mac_pdu_ptr != nullptr) { + log.info_hex( + mac_pdu_ptr, mac_msg_dl.get_pdu_len(), "DL MAC PDU (%d B):\n", mac_msg_dl.get_pdu_len()); + + // Prepare MAC grant for CCCH + mac_interface_phy_lte::mac_grant_dl_t dl_grant = {}; + dl_grant.pid = get_pid(tti); + dl_grant.rnti = dl_rnti; + dl_grant.tb[0].tbs = mac_msg_dl.get_pdu_len(); + dl_grant.tb[0].ndi_present = true; + dl_grant.tb[0].ndi = get_ndi_for_new_dl_tx(tti); + + ue->new_tb(dl_grant, (const uint8_t*)mac_pdu_ptr); + } else { + log.error("Error writing DL MAC PDU\n"); + } + mac_msg_dl.reset(); } else { - log.error("Error writing DL MAC PDU\n"); + log.error("Can't fit RLC PDU into buffer (%d > %d)\n", buf_state, tmp_rlc_buffer.get_tailroom()); } - mac_msg_dl.reset(); - } else { - log.error("Can't fit RLC PDU into buffer (%d > %d)\n", buf_state, tmp_rlc_buffer.get_tailroom()); } } + // Check if we need to provide a UL grant as well } - // Check if we need to provide a UL grant as well + } else { + log.debug("Not handling RNTI=%d\n", dl_rnti); } - } else { - log.debug("Not handling RNTI=%d\n", dl_rnti); } - usleep(1000); - tti = (tti + 1) % 10240; } log.info("Leaving main thread.\n"); @@ -625,10 +624,12 @@ public: uint32_t get_tti() { return tti; } - void process_pdu(uint8_t* buff, uint32_t len, pdu_queue::channel_t channel) { log.info("%s\n", __PRETTY_FUNCTION__); } + void process_pdu(uint8_t* buff, uint32_t len, pdu_queue::channel_t channel) {} void set_cell_config(std::string name, uint32_t earfcn_, srslte_cell_t cell_, const float power) { + std::lock_guard lock(mutex); + // check if cell already exists if (not syssim_has_cell(name)) { // insert new cell @@ -647,6 +648,7 @@ public: update_cell_map(); } + // internal function bool syssim_has_cell(std::string cell_name) { for (uint32_t i = 0; i < cells.size(); ++i) { @@ -659,6 +661,7 @@ public: void set_cell_attenuation(std::string cell_name, const float value) { + std::lock_guard lock(mutex); if (not syssim_has_cell(cell_name)) { log.error("Can't set cell power. Cell not found.\n"); } @@ -674,10 +677,14 @@ public: update_cell_map(); } + // Internal function void update_cell_map() { // Find cell with highest power and select as serving cell - if (ue != NULL) { + if (not ue) { + log.error("Can't configure cell. UE not initialized.\n"); + } + // convert syssim cell list to phy cell list lte_ttcn3_phy::cell_list_t phy_cells; for (uint32_t i = 0; i < cells.size(); ++i) { @@ -691,21 +698,26 @@ public: // SYSSIM defines what cells the UE can connect to ue->set_cell_map(phy_cells); - } else { - log.error("Can't configure cell. UE not initialized.\n"); - } } - void add_bcch_pdu(unique_byte_buffer_t pdu) { sibs.push_back(std::move(pdu)); } + void add_bcch_pdu(unique_byte_buffer_t pdu) + { + std::lock_guard lock(mutex); + sibs.push_back(std::move(pdu)); + } void add_ccch_pdu(unique_byte_buffer_t pdu) { + std::lock_guard lock(mutex); + // Add to SRB0 Tx queue rlc.write_sdu(0, std::move(pdu)); } void add_dcch_pdu(uint32_t lcid, unique_byte_buffer_t pdu) { + std::lock_guard lock(mutex); + // push to PDCP and create DL grant for it log.info("Writing PDU (%d B) to LCID=%d\n", pdu->N_bytes, lcid); pdcp.write_sdu(lcid, std::move(pdu)); @@ -713,6 +725,7 @@ public: void add_pch_pdu(unique_byte_buffer_t pdu) { + std::lock_guard lock(mutex); log.info("Received PCH PDU (%d B)\n", pdu->N_bytes); // Prepare MAC grant for PCH @@ -735,12 +748,14 @@ public: void add_srb(uint32_t lcid, pdcp_config_t pdcp_config) { + std::lock_guard lock(mutex); pdcp.add_bearer(lcid, pdcp_config); rlc.add_bearer(lcid, srslte::rlc_config_t::srb_config(lcid)); } void del_srb(uint32_t lcid) { + std::lock_guard lock(mutex); // Only delete SRB1/2 if (lcid > 0) { pdcp.del_bearer(lcid); @@ -779,8 +794,7 @@ public: void write_pdu_bcch_dlsch(unique_byte_buffer_t pdu) { log.error("%s not implemented.\n", __FUNCTION__); } void write_pdu_pcch(unique_byte_buffer_t pdu) { log.error("%s not implemented.\n", __FUNCTION__); } void write_pdu_mch(uint32_t lcid, unique_byte_buffer_t pdu) { log.error("%s not implemented.\n", __FUNCTION__); } - - void max_retx_attempted() { log.debug("max_retx_attempted\n"); } + void max_retx_attempted() { log.error("%s not implemented.\n", __FUNCTION__); } std::string get_rb_name(uint32_t lcid) { @@ -848,12 +862,15 @@ private: all_args_t args = {}; - bool running = false; - srslte::byte_buffer_pool* pool = nullptr; // Simulator vars unique_ptr ue = nullptr; + std::mutex mutex; + bool running = false; + + typedef enum { UE_SWITCH_ON = 0, UE_SWITCH_OFF, ENABLE_DATA, DISABLE_DATA } ss_events_t; + block_queue event_queue; uint32_t run_id = 0; @@ -862,6 +879,7 @@ private: int32_t prach_tti = -1; int32_t rar_tti = -1; int32_t msg3_tti = -1; + int32_t sr_tti = -1; uint32_t prach_preamble_index = 0; uint16_t dl_rnti = 0; uint16_t crnti = TTCN3_CRNTI; diff --git a/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h b/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h index 76ee08f91..fa0203e23 100644 --- a/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h +++ b/srsue/test/ttcn3/hdr/ttcn3_ut_interface.h @@ -37,7 +37,7 @@ public: ttcn3_ut_interface() : netsource_handler("TTCN3_UT_IF") {} ~ttcn3_ut_interface(){}; - void init(syssim_interface* syssim_, srslte::log* log_, std::string net_ip_, uint32_t net_port_) + void init(ss_ut_interface* syssim_, srslte::log* log_, std::string net_ip_, uint32_t net_port_) { syssim = syssim_; log = log_; @@ -181,7 +181,7 @@ private: } } - syssim_interface* syssim = nullptr; + ss_ut_interface* syssim = nullptr; }; #endif // SRSUE_TTCN3_UT_INTERFACE_H \ No newline at end of file diff --git a/srsue/test/ttcn3/src/lte_ttcn3_phy.cc b/srsue/test/ttcn3/src/lte_ttcn3_phy.cc index 9ad62ec0d..01b30315c 100644 --- a/srsue/test/ttcn3/src/lte_ttcn3_phy.cc +++ b/srsue/test/ttcn3/src/lte_ttcn3_phy.cc @@ -75,6 +75,8 @@ void lte_ttcn3_phy::set_cell_map(const cell_list_t& cells_) // The interface for RRC void lte_ttcn3_phy::get_current_cell(srslte_cell_t* cell_, uint32_t* earfcn_) { + std::lock_guard lock(mutex); + if (cell_) { memcpy(cell_, &pcell.info, sizeof(srslte_cell_t)); } @@ -202,6 +204,8 @@ std::string lte_ttcn3_phy::get_type() phy_interface_mac_lte::prach_info_t lte_ttcn3_phy::prach_get_info() { + std::lock_guard lock(mutex); + prach_info_t info = {}; if (prach_tti_tx != -1) { info.is_transmitted = true; @@ -281,6 +285,8 @@ float lte_ttcn3_phy::get_pathloss_db() // Calling function hold mutex void lte_ttcn3_phy::new_grant_ul(mac_interface_phy_lte::mac_grant_ul_t ul_mac_grant) { + std::lock_guard lock(mutex); + mac_interface_phy_lte::tb_action_ul_t ul_action = {}; // Deliver grant and retrieve payload