mirror of https://github.com/PentHertz/srsLTE.git
ttcn3: split SS interface and protect SS main thread properly
the SS main thread and the provided interaces weren't protecting members correctly
This commit is contained in:
parent
80ef7f8497
commit
487fdd5616
|
@ -25,8 +25,8 @@
|
||||||
#include "srslte/common/common.h"
|
#include "srslte/common/common.h"
|
||||||
#include "srslte/interfaces/ue_interfaces.h"
|
#include "srslte/interfaces/ue_interfaces.h"
|
||||||
|
|
||||||
// Interface used by system interface to communicate with main component
|
// Interfaces used by system interface to communicate with main component
|
||||||
class syssim_interface
|
class ss_ut_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void tc_start(const char* name) = 0;
|
virtual void tc_start(const char* name) = 0;
|
||||||
|
@ -36,12 +36,15 @@ public:
|
||||||
virtual void switch_off_ue() = 0;
|
virtual void switch_off_ue() = 0;
|
||||||
virtual void enable_data() = 0;
|
virtual void enable_data() = 0;
|
||||||
virtual void disable_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_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 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 add_srb(uint32_t lcid, srslte::pdcp_config_t pdcp_config) = 0;
|
||||||
virtual void del_srb(uint32_t lcid) = 0;
|
virtual void del_srb(uint32_t lcid) = 0;
|
||||||
virtual uint32_t get_tti() = 0;
|
virtual uint32_t get_tti() = 0;
|
||||||
|
@ -53,12 +56,18 @@ public:
|
||||||
const srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo) = 0;
|
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
|
class syssim_interface_phy
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void prach_indication(uint32_t preamble_index, const uint32_t& cell_id) = 0;
|
virtual void prach_indication(uint32_t preamble_index, const uint32_t& cell_id) = 0;
|
||||||
virtual void sr_req(uint32_t tti_tx) = 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;
|
virtual void tx_pdu(const uint8_t* payload, const int len, const uint32_t tx_tti) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,10 @@ using namespace srslte;
|
||||||
class ttcn3_srb_interface : public netsource_handler
|
class ttcn3_srb_interface : public netsource_handler
|
||||||
{
|
{
|
||||||
public:
|
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(){};
|
~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_;
|
syssim = syssim_;
|
||||||
log = log_;
|
log = log_;
|
||||||
|
@ -166,7 +166,7 @@ private:
|
||||||
syssim->add_dcch_pdu(lcid, std::move(pdu));
|
syssim->add_dcch_pdu(lcid, std::move(pdu));
|
||||||
}
|
}
|
||||||
|
|
||||||
syssim_interface* syssim = nullptr;
|
ss_srb_interface* syssim = nullptr;
|
||||||
byte_buffer_pool* pool = nullptr;
|
byte_buffer_pool* pool = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
ttcn3_sys_interface() : netsource_handler("TTCN3_SYS_IF"){};
|
ttcn3_sys_interface() : netsource_handler("TTCN3_SYS_IF"){};
|
||||||
~ttcn3_sys_interface(){};
|
~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_;
|
syssim = syssim_;
|
||||||
net_ip = net_ip_;
|
net_ip = net_ip_;
|
||||||
|
@ -596,7 +596,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
phy_interface_syssim* phy = nullptr;
|
phy_interface_syssim* phy = nullptr;
|
||||||
syssim_interface* syssim = nullptr;
|
ss_sys_interface* syssim = nullptr;
|
||||||
byte_buffer_pool* pool = nullptr;
|
byte_buffer_pool* pool = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "dut_utils.h"
|
#include "dut_utils.h"
|
||||||
#include "srslte/common/netsource_handler.h"
|
#include "srslte/common/netsource_handler.h"
|
||||||
#include "srslte/common/pdu_queue.h"
|
#include "srslte/common/pdu_queue.h"
|
||||||
|
#include "srslte/common/threads.h"
|
||||||
#include "srslte/upper/pdcp.h"
|
#include "srslte/upper/pdcp.h"
|
||||||
#include "srslte/upper/rlc.h"
|
#include "srslte/upper/rlc.h"
|
||||||
#include "ttcn3_ip_ctrl_interface.h"
|
#include "ttcn3_ip_ctrl_interface.h"
|
||||||
|
@ -33,14 +34,16 @@
|
||||||
#include "ttcn3_sys_interface.h"
|
#include "ttcn3_sys_interface.h"
|
||||||
#include "ttcn3_ue.h"
|
#include "ttcn3_ue.h"
|
||||||
#include "ttcn3_ut_interface.h"
|
#include "ttcn3_ut_interface.h"
|
||||||
#include <pthread.h>
|
|
||||||
#include <srslte/interfaces/ue_interfaces.h>
|
#include <srslte/interfaces/ue_interfaces.h>
|
||||||
|
|
||||||
#define TTCN3_CRNTI (0x1001)
|
#define TTCN3_CRNTI (0x1001)
|
||||||
|
|
||||||
class ttcn3_syssim : public thread,
|
class ttcn3_syssim : public thread,
|
||||||
public syssim_interface_phy,
|
public syssim_interface_phy,
|
||||||
public syssim_interface,
|
public ss_ut_interface,
|
||||||
|
public ss_sys_interface,
|
||||||
|
public ss_srb_interface,
|
||||||
public rrc_interface_rlc,
|
public rrc_interface_rlc,
|
||||||
public rlc_interface_pdcp,
|
public rlc_interface_pdcp,
|
||||||
public rrc_interface_pdcp,
|
public rrc_interface_pdcp,
|
||||||
|
@ -63,6 +66,8 @@ public:
|
||||||
|
|
||||||
void init(const all_args_t& args_)
|
void init(const all_args_t& args_)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
args = args_;
|
args = args_;
|
||||||
|
|
||||||
// Make sure to get SS logging as well
|
// Make sure to get SS logging as well
|
||||||
|
@ -121,6 +126,7 @@ public:
|
||||||
|
|
||||||
void stop()
|
void stop()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
running = false;
|
running = false;
|
||||||
|
|
||||||
|
@ -136,6 +142,7 @@ public:
|
||||||
srb.stop();
|
srb.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Internal function called with acquired lock
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
rlc.reset();
|
rlc.reset();
|
||||||
|
@ -147,6 +154,8 @@ public:
|
||||||
// Called from UT before starting testcase
|
// Called from UT before starting testcase
|
||||||
void tc_start(const char* name)
|
void tc_start(const char* name)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
if (ue == nullptr) {
|
if (ue == nullptr) {
|
||||||
// strip testsuite name
|
// strip testsuite name
|
||||||
std::string tc_name = get_tc_name(name);
|
std::string tc_name = get_tc_name(name);
|
||||||
|
@ -191,6 +200,8 @@ public:
|
||||||
|
|
||||||
void tc_end()
|
void tc_end()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
if (ue != NULL) {
|
if (ue != NULL) {
|
||||||
// ask periodic thread to stop
|
// ask periodic thread to stop
|
||||||
running = false;
|
running = false;
|
||||||
|
@ -220,47 +231,16 @@ public:
|
||||||
// only return after new UE instance is up and running
|
// only return after new UE instance is up and running
|
||||||
}
|
}
|
||||||
|
|
||||||
void switch_on_ue()
|
// Called from outside
|
||||||
{
|
void switch_on_ue() { event_queue.push(UE_SWITCH_ON); }
|
||||||
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
|
void switch_off_ue() { event_queue.push(UE_SWITCH_OFF); }
|
||||||
ue->switch_on();
|
|
||||||
} else {
|
|
||||||
log.error("UE not initialized. Can't switch UE on.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void switch_off_ue()
|
void enable_data() { event_queue.push(ENABLE_DATA); }
|
||||||
{
|
|
||||||
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 enable_data()
|
void disable_data() { event_queue.push(DISABLE_DATA); }
|
||||||
{
|
|
||||||
if (ue) {
|
|
||||||
log.info("Enabling data services on UE ID=%d\n", run_id);
|
|
||||||
ue->enable_data();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable_data()
|
// Called from PHY but always from the SS main thread with lock being hold
|
||||||
{
|
|
||||||
if (ue) {
|
|
||||||
log.info("Disabling data services on UE ID=%d\n", run_id);
|
|
||||||
ue->disable_data();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interface for PHY
|
|
||||||
void prach_indication(uint32_t preamble_index_, const uint32_t& cell_id)
|
void prach_indication(uint32_t preamble_index_, const uint32_t& cell_id)
|
||||||
{
|
{
|
||||||
// store TTI for providing UL grant for Msg3 transmission
|
// store TTI for providing UL grant for Msg3 transmission
|
||||||
|
@ -276,78 +256,16 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_rar(uint32_t preamble_index)
|
// Called from PHY but always from the SS main thread with lock being hold
|
||||||
{
|
|
||||||
log.info("Sending RAR for RAPID=%d\n", preamble_index);
|
|
||||||
|
|
||||||
// Prepare RAR grant
|
|
||||||
uint8_t grant_buffer[64] = {};
|
|
||||||
srslte_dci_rar_grant_t rar_grant = {};
|
|
||||||
rar_grant.tpc_pusch = 3;
|
|
||||||
srslte_dci_rar_pack(&rar_grant, grant_buffer);
|
|
||||||
|
|
||||||
// Create MAC PDU and add RAR subheader
|
|
||||||
srslte::rar_pdu rar_pdu;
|
|
||||||
rar_buffer.clear();
|
|
||||||
|
|
||||||
const int rar_pdu_len = 64;
|
|
||||||
rar_pdu.init_tx(&rar_buffer, rar_pdu_len);
|
|
||||||
rar_pdu.set_backoff(11); // Backoff of 480ms to prevent UE from PRACHing too fast
|
|
||||||
if (rar_pdu.new_subh()) {
|
|
||||||
rar_pdu.get()->set_rapid(preamble_index);
|
|
||||||
rar_pdu.get()->set_ta_cmd(0);
|
|
||||||
rar_pdu.get()->set_temp_crnti(crnti);
|
|
||||||
rar_pdu.get()->set_sched_grant(grant_buffer);
|
|
||||||
}
|
|
||||||
rar_pdu.write_packet(rar_buffer.msg);
|
|
||||||
rar_buffer.N_bytes = rar_pdu_len;
|
|
||||||
|
|
||||||
// Prepare grant and pass all to MAC
|
|
||||||
mac_interface_phy_lte::mac_grant_dl_t dl_grant = {};
|
|
||||||
dl_grant.pid = get_pid(tti);
|
|
||||||
dl_grant.rnti = 0x1; // must be a valid RAR-RNTI
|
|
||||||
dl_grant.tb[0].tbs = rar_buffer.N_bytes;
|
|
||||||
dl_grant.tb[0].ndi = get_ndi_for_new_dl_tx(tti);
|
|
||||||
|
|
||||||
// send grant and pass payload to TB data (grant contains length)
|
|
||||||
ue->new_tb(dl_grant, rar_buffer.msg);
|
|
||||||
|
|
||||||
// reset last PRACH transmission tti
|
|
||||||
prach_tti = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void send_msg3_grant()
|
|
||||||
{
|
|
||||||
log.info("Sending Msg3 grant for C-RNTI=%d\n", crnti);
|
|
||||||
mac_interface_phy_lte::mac_grant_ul_t ul_grant = {};
|
|
||||||
|
|
||||||
ul_grant.tb.tbs = 32;
|
|
||||||
ul_grant.tb.ndi_present = true;
|
|
||||||
ul_grant.tb.ndi = get_ndi_for_new_ul_tx(tti);
|
|
||||||
ul_grant.rnti = crnti;
|
|
||||||
ul_grant.pid = get_pid(tti);
|
|
||||||
|
|
||||||
ue->new_grant_ul(ul_grant);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sr_req(uint32_t tti_tx)
|
void sr_req(uint32_t tti_tx)
|
||||||
{
|
{
|
||||||
log.info("Received SR from PHY\n");
|
log.info("Received SR from PHY\n");
|
||||||
|
sr_tti = tti_tx;
|
||||||
// Provide new UL grant to UE
|
|
||||||
mac_interface_phy_lte::mac_grant_ul_t ul_grant = {};
|
|
||||||
ul_grant.tb.tbs = 100; // FIXME: reasonable size?
|
|
||||||
ul_grant.tb.ndi_present = true;
|
|
||||||
ul_grant.tb.ndi = get_ndi_for_new_ul_tx(tti);
|
|
||||||
ul_grant.rnti = crnti;
|
|
||||||
ul_grant.pid = get_pid(tti);
|
|
||||||
|
|
||||||
ue->new_grant_ul(ul_grant);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
void tx_pdu(const uint8_t* payload, const int len, const uint32_t tx_tti)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (payload == NULL) {
|
if (payload == NULL) {
|
||||||
ss_mac_log.error("Received NULL as PDU payload. Dropping.\n");
|
ss_mac_log.error("Received NULL as PDU payload. Dropping.\n");
|
||||||
return;
|
return;
|
||||||
|
@ -407,9 +325,81 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Internal function called from main thread
|
||||||
|
void send_rar(uint32_t preamble_index)
|
||||||
|
{
|
||||||
|
log.info("Sending RAR for RAPID=%d\n", preamble_index);
|
||||||
|
|
||||||
|
// Prepare RAR grant
|
||||||
|
uint8_t grant_buffer[64] = {};
|
||||||
|
srslte_dci_rar_grant_t rar_grant = {};
|
||||||
|
rar_grant.tpc_pusch = 3;
|
||||||
|
srslte_dci_rar_pack(&rar_grant, grant_buffer);
|
||||||
|
|
||||||
|
// Create MAC PDU and add RAR subheader
|
||||||
|
srslte::rar_pdu rar_pdu;
|
||||||
|
rar_buffer.clear();
|
||||||
|
|
||||||
|
const int rar_pdu_len = 64;
|
||||||
|
rar_pdu.init_tx(&rar_buffer, rar_pdu_len);
|
||||||
|
rar_pdu.set_backoff(11); // Backoff of 480ms to prevent UE from PRACHing too fast
|
||||||
|
if (rar_pdu.new_subh()) {
|
||||||
|
rar_pdu.get()->set_rapid(preamble_index);
|
||||||
|
rar_pdu.get()->set_ta_cmd(0);
|
||||||
|
rar_pdu.get()->set_temp_crnti(crnti);
|
||||||
|
rar_pdu.get()->set_sched_grant(grant_buffer);
|
||||||
|
}
|
||||||
|
rar_pdu.write_packet(rar_buffer.msg);
|
||||||
|
rar_buffer.N_bytes = rar_pdu_len;
|
||||||
|
|
||||||
|
// Prepare grant and pass all to MAC
|
||||||
|
mac_interface_phy_lte::mac_grant_dl_t dl_grant = {};
|
||||||
|
dl_grant.pid = get_pid(tti);
|
||||||
|
dl_grant.rnti = 0x1; // must be a valid RAR-RNTI
|
||||||
|
dl_grant.tb[0].tbs = rar_buffer.N_bytes;
|
||||||
|
dl_grant.tb[0].ndi = get_ndi_for_new_dl_tx(tti);
|
||||||
|
|
||||||
|
// send grant and pass payload to TB data (grant contains length)
|
||||||
|
ue->new_tb(dl_grant, rar_buffer.msg);
|
||||||
|
|
||||||
|
// reset last PRACH transmission tti
|
||||||
|
prach_tti = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal function called from main thread
|
||||||
|
void send_msg3_grant()
|
||||||
|
{
|
||||||
|
log.info("Sending Msg3 grant for C-RNTI=%d\n", crnti);
|
||||||
|
mac_interface_phy_lte::mac_grant_ul_t ul_grant = {};
|
||||||
|
|
||||||
|
ul_grant.tb.tbs = 32;
|
||||||
|
ul_grant.tb.ndi_present = true;
|
||||||
|
ul_grant.tb.ndi = get_ndi_for_new_ul_tx(tti);
|
||||||
|
ul_grant.rnti = crnti;
|
||||||
|
ul_grant.pid = get_pid(tti);
|
||||||
|
|
||||||
|
ue->new_grant_ul(ul_grant);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal function called from main thread
|
||||||
|
void send_sr_ul_grant()
|
||||||
|
{
|
||||||
|
// Provide new UL grant to UE
|
||||||
|
mac_interface_phy_lte::mac_grant_ul_t ul_grant = {};
|
||||||
|
ul_grant.tb.tbs = 100; // FIXME: reasonable size?
|
||||||
|
ul_grant.tb.ndi_present = true;
|
||||||
|
ul_grant.tb.ndi = get_ndi_for_new_ul_tx(tti);
|
||||||
|
ul_grant.rnti = crnti;
|
||||||
|
ul_grant.pid = get_pid(tti);
|
||||||
|
|
||||||
|
ue->new_grant_ul(ul_grant);
|
||||||
|
|
||||||
|
sr_tti = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// internal function called from tx_pdu (called from main thread)
|
||||||
bool process_ce(srslte::sch_subh* subh)
|
bool process_ce(srslte::sch_subh* subh)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint16_t rnti = dl_rnti;
|
uint16_t rnti = dl_rnti;
|
||||||
|
|
||||||
uint32_t buff_size[4] = {0, 0, 0, 0};
|
uint32_t buff_size[4] = {0, 0, 0, 0};
|
||||||
|
@ -421,22 +411,10 @@ public:
|
||||||
case srslte::sch_subh::PHR_REPORT:
|
case srslte::sch_subh::PHR_REPORT:
|
||||||
phr = subh->get_phr();
|
phr = subh->get_phr();
|
||||||
ss_mac_log.info("CE: Received PHR from rnti=0x%x, value=%.0f\n", rnti, 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;
|
break;
|
||||||
case srslte::sch_subh::CRNTI:
|
case srslte::sch_subh::CRNTI:
|
||||||
old_rnti = subh->get_c_rnti();
|
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);
|
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;
|
break;
|
||||||
case srslte::sch_subh::TRUNC_BSR:
|
case srslte::sch_subh::TRUNC_BSR:
|
||||||
case srslte::sch_subh::SHORT_BSR:
|
case srslte::sch_subh::SHORT_BSR:
|
||||||
|
@ -445,13 +423,6 @@ public:
|
||||||
ss_mac_log.error("Invalid Index Passed to lc groups\n");
|
ss_mac_log.error("Invalid Index Passed to lc groups\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
for (uint32_t i=0;i<lc_groups[idx].size();i++) {
|
|
||||||
// Indicate BSR to scheduler
|
|
||||||
sched->ul_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",
|
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",
|
subh->ce_type() == srslte::sch_subh::SHORT_BSR ? "Short" : "Trunc",
|
||||||
rnti,
|
rnti,
|
||||||
|
@ -461,13 +432,6 @@ public:
|
||||||
break;
|
break;
|
||||||
case srslte::sch_subh::LONG_BSR:
|
case srslte::sch_subh::LONG_BSR:
|
||||||
subh->get_bsr(buff_size);
|
subh->get_bsr(buff_size);
|
||||||
#if 0
|
|
||||||
for (idx=0;idx<4;idx++) {
|
|
||||||
for (uint32_t i=0;i<lc_groups[idx].size();i++) {
|
|
||||||
sched->ul_bsr(rnti, lc_groups[idx][i], buff_size[idx]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
is_bsr = true;
|
is_bsr = true;
|
||||||
ss_mac_log.info("CE: Received Long BSR rnti=0x%x, value=%d,%d,%d,%d\n",
|
ss_mac_log.info("CE: Received Long BSR rnti=0x%x, value=%d,%d,%d,%d\n",
|
||||||
rnti,
|
rnti,
|
||||||
|
@ -486,7 +450,7 @@ public:
|
||||||
return is_bsr;
|
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_)
|
bool get_ndi_for_new_ul_tx(const uint32_t tti_)
|
||||||
{
|
{
|
||||||
|
@ -511,8 +475,37 @@ public:
|
||||||
uint32_t sib_idx = 0;
|
uint32_t sib_idx = 0;
|
||||||
|
|
||||||
while (running) {
|
while (running) {
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
|
tti = (tti + 1) % 10240;
|
||||||
|
|
||||||
log.debug("SYSSIM-TTI=%d\n", tti);
|
log.debug("SYSSIM-TTI=%d\n", tti);
|
||||||
ue->set_current_tti(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dl_rnti = ue->get_dl_sched_rnti(tti);
|
dl_rnti = ue->get_dl_sched_rnti(tti);
|
||||||
|
|
||||||
if (SRSLTE_RNTI_ISSI(dl_rnti)) {
|
if (SRSLTE_RNTI_ISSI(dl_rnti)) {
|
||||||
|
@ -548,6 +541,12 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for SR
|
||||||
|
if (sr_tti != -1) {
|
||||||
|
send_sr_ul_grant();
|
||||||
|
}
|
||||||
|
|
||||||
if (dl_rnti != 0) {
|
if (dl_rnti != 0) {
|
||||||
log.debug("Searching for RNTI=%d\n", dl_rnti);
|
log.debug("Searching for RNTI=%d\n", dl_rnti);
|
||||||
|
|
||||||
|
@ -589,7 +588,8 @@ public:
|
||||||
|
|
||||||
uint8_t* mac_pdu_ptr = mac_msg_dl.write_packet(&log);
|
uint8_t* mac_pdu_ptr = mac_msg_dl.write_packet(&log);
|
||||||
if (mac_pdu_ptr != nullptr) {
|
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());
|
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
|
// Prepare MAC grant for CCCH
|
||||||
mac_interface_phy_lte::mac_grant_dl_t dl_grant = {};
|
mac_interface_phy_lte::mac_grant_dl_t dl_grant = {};
|
||||||
|
@ -614,9 +614,8 @@ public:
|
||||||
} else {
|
} else {
|
||||||
log.debug("Not handling RNTI=%d\n", dl_rnti);
|
log.debug("Not handling RNTI=%d\n", dl_rnti);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
tti = (tti + 1) % 10240;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Leaving main thread.\n");
|
log.info("Leaving main thread.\n");
|
||||||
|
@ -625,10 +624,12 @@ public:
|
||||||
|
|
||||||
uint32_t get_tti() { return tti; }
|
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)
|
void set_cell_config(std::string name, uint32_t earfcn_, srslte_cell_t cell_, const float power)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
// check if cell already exists
|
// check if cell already exists
|
||||||
if (not syssim_has_cell(name)) {
|
if (not syssim_has_cell(name)) {
|
||||||
// insert new cell
|
// insert new cell
|
||||||
|
@ -647,6 +648,7 @@ public:
|
||||||
update_cell_map();
|
update_cell_map();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// internal function
|
||||||
bool syssim_has_cell(std::string cell_name)
|
bool syssim_has_cell(std::string cell_name)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < cells.size(); ++i) {
|
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)
|
void set_cell_attenuation(std::string cell_name, const float value)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
if (not syssim_has_cell(cell_name)) {
|
if (not syssim_has_cell(cell_name)) {
|
||||||
log.error("Can't set cell power. Cell not found.\n");
|
log.error("Can't set cell power. Cell not found.\n");
|
||||||
}
|
}
|
||||||
|
@ -674,10 +677,14 @@ public:
|
||||||
update_cell_map();
|
update_cell_map();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Internal function
|
||||||
void update_cell_map()
|
void update_cell_map()
|
||||||
{
|
{
|
||||||
// Find cell with highest power and select as serving cell
|
// 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
|
// convert syssim cell list to phy cell list
|
||||||
lte_ttcn3_phy::cell_list_t phy_cells;
|
lte_ttcn3_phy::cell_list_t phy_cells;
|
||||||
for (uint32_t i = 0; i < cells.size(); ++i) {
|
for (uint32_t i = 0; i < cells.size(); ++i) {
|
||||||
|
@ -691,21 +698,26 @@ public:
|
||||||
|
|
||||||
// SYSSIM defines what cells the UE can connect to
|
// SYSSIM defines what cells the UE can connect to
|
||||||
ue->set_cell_map(phy_cells);
|
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<std::mutex> lock(mutex);
|
||||||
|
sibs.push_back(std::move(pdu));
|
||||||
|
}
|
||||||
|
|
||||||
void add_ccch_pdu(unique_byte_buffer_t pdu)
|
void add_ccch_pdu(unique_byte_buffer_t pdu)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
// Add to SRB0 Tx queue
|
// Add to SRB0 Tx queue
|
||||||
rlc.write_sdu(0, std::move(pdu));
|
rlc.write_sdu(0, std::move(pdu));
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_dcch_pdu(uint32_t lcid, unique_byte_buffer_t pdu)
|
void add_dcch_pdu(uint32_t lcid, unique_byte_buffer_t pdu)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
// push to PDCP and create DL grant for it
|
// push to PDCP and create DL grant for it
|
||||||
log.info("Writing PDU (%d B) to LCID=%d\n", pdu->N_bytes, lcid);
|
log.info("Writing PDU (%d B) to LCID=%d\n", pdu->N_bytes, lcid);
|
||||||
pdcp.write_sdu(lcid, std::move(pdu));
|
pdcp.write_sdu(lcid, std::move(pdu));
|
||||||
|
@ -713,6 +725,7 @@ public:
|
||||||
|
|
||||||
void add_pch_pdu(unique_byte_buffer_t pdu)
|
void add_pch_pdu(unique_byte_buffer_t pdu)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
log.info("Received PCH PDU (%d B)\n", pdu->N_bytes);
|
log.info("Received PCH PDU (%d B)\n", pdu->N_bytes);
|
||||||
|
|
||||||
// Prepare MAC grant for PCH
|
// Prepare MAC grant for PCH
|
||||||
|
@ -735,12 +748,14 @@ public:
|
||||||
|
|
||||||
void add_srb(uint32_t lcid, pdcp_config_t pdcp_config)
|
void add_srb(uint32_t lcid, pdcp_config_t pdcp_config)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
pdcp.add_bearer(lcid, pdcp_config);
|
pdcp.add_bearer(lcid, pdcp_config);
|
||||||
rlc.add_bearer(lcid, srslte::rlc_config_t::srb_config(lcid));
|
rlc.add_bearer(lcid, srslte::rlc_config_t::srb_config(lcid));
|
||||||
}
|
}
|
||||||
|
|
||||||
void del_srb(uint32_t lcid)
|
void del_srb(uint32_t lcid)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
// Only delete SRB1/2
|
// Only delete SRB1/2
|
||||||
if (lcid > 0) {
|
if (lcid > 0) {
|
||||||
pdcp.del_bearer(lcid);
|
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_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_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 write_pdu_mch(uint32_t lcid, unique_byte_buffer_t pdu) { log.error("%s not implemented.\n", __FUNCTION__); }
|
||||||
|
void max_retx_attempted() { log.error("%s not implemented.\n", __FUNCTION__); }
|
||||||
void max_retx_attempted() { log.debug("max_retx_attempted\n"); }
|
|
||||||
|
|
||||||
std::string get_rb_name(uint32_t lcid)
|
std::string get_rb_name(uint32_t lcid)
|
||||||
{
|
{
|
||||||
|
@ -848,12 +862,15 @@ private:
|
||||||
|
|
||||||
all_args_t args = {};
|
all_args_t args = {};
|
||||||
|
|
||||||
bool running = false;
|
|
||||||
|
|
||||||
srslte::byte_buffer_pool* pool = nullptr;
|
srslte::byte_buffer_pool* pool = nullptr;
|
||||||
|
|
||||||
// Simulator vars
|
// Simulator vars
|
||||||
unique_ptr<ttcn3_ue> ue = nullptr;
|
unique_ptr<ttcn3_ue> 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<ss_events_t> event_queue;
|
||||||
|
|
||||||
uint32_t run_id = 0;
|
uint32_t run_id = 0;
|
||||||
|
|
||||||
|
@ -862,6 +879,7 @@ private:
|
||||||
int32_t prach_tti = -1;
|
int32_t prach_tti = -1;
|
||||||
int32_t rar_tti = -1;
|
int32_t rar_tti = -1;
|
||||||
int32_t msg3_tti = -1;
|
int32_t msg3_tti = -1;
|
||||||
|
int32_t sr_tti = -1;
|
||||||
uint32_t prach_preamble_index = 0;
|
uint32_t prach_preamble_index = 0;
|
||||||
uint16_t dl_rnti = 0;
|
uint16_t dl_rnti = 0;
|
||||||
uint16_t crnti = TTCN3_CRNTI;
|
uint16_t crnti = TTCN3_CRNTI;
|
||||||
|
|
|
@ -37,7 +37,7 @@ public:
|
||||||
ttcn3_ut_interface() : netsource_handler("TTCN3_UT_IF") {}
|
ttcn3_ut_interface() : netsource_handler("TTCN3_UT_IF") {}
|
||||||
~ttcn3_ut_interface(){};
|
~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_;
|
syssim = syssim_;
|
||||||
log = log_;
|
log = log_;
|
||||||
|
@ -181,7 +181,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
syssim_interface* syssim = nullptr;
|
ss_ut_interface* syssim = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SRSUE_TTCN3_UT_INTERFACE_H
|
#endif // SRSUE_TTCN3_UT_INTERFACE_H
|
|
@ -75,6 +75,8 @@ void lte_ttcn3_phy::set_cell_map(const cell_list_t& cells_)
|
||||||
// The interface for RRC
|
// The interface for RRC
|
||||||
void lte_ttcn3_phy::get_current_cell(srslte_cell_t* cell_, uint32_t* earfcn_)
|
void lte_ttcn3_phy::get_current_cell(srslte_cell_t* cell_, uint32_t* earfcn_)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
if (cell_) {
|
if (cell_) {
|
||||||
memcpy(cell_, &pcell.info, sizeof(srslte_cell_t));
|
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()
|
phy_interface_mac_lte::prach_info_t lte_ttcn3_phy::prach_get_info()
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
prach_info_t info = {};
|
prach_info_t info = {};
|
||||||
if (prach_tti_tx != -1) {
|
if (prach_tti_tx != -1) {
|
||||||
info.is_transmitted = true;
|
info.is_transmitted = true;
|
||||||
|
@ -281,6 +285,8 @@ float lte_ttcn3_phy::get_pathloss_db()
|
||||||
// Calling function hold mutex
|
// Calling function hold mutex
|
||||||
void lte_ttcn3_phy::new_grant_ul(mac_interface_phy_lte::mac_grant_ul_t ul_mac_grant)
|
void lte_ttcn3_phy::new_grant_ul(mac_interface_phy_lte::mac_grant_ul_t ul_mac_grant)
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
mac_interface_phy_lte::tb_action_ul_t ul_action = {};
|
mac_interface_phy_lte::tb_action_ul_t ul_action = {};
|
||||||
|
|
||||||
// Deliver grant and retrieve payload
|
// Deliver grant and retrieve payload
|
||||||
|
|
Loading…
Reference in New Issue