rework cell list and SIB handling in SS

This commit is contained in:
Andre Puschmann 2019-10-17 16:21:21 +02:00
parent 891a66a2e5
commit 755a0599c4
7 changed files with 140 additions and 68 deletions

View File

@ -120,6 +120,8 @@ public:
void run_tti();
private:
void select_pcell();
srslte::logger* logger = nullptr;
srslte::log_filter log;

View File

@ -41,7 +41,7 @@ public:
class ss_sys_interface
{
public:
virtual void add_bcch_pdu(srslte::unique_byte_buffer_t pdu) = 0;
virtual void add_bcch_dlsch_pdu(const std::string cell_name, 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;
@ -61,6 +61,7 @@ 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;
virtual void reestablish_bearer(uint32_t lcid) = 0;
};
class syssim_interface_phy

View File

@ -151,6 +151,11 @@ private:
memcpy(pdu->msg, payload, pdu->N_bytes);
syssim->add_ccch_pdu(std::move(pdu));
// FIXME: is there a better way to check for RRCConnectionReestablishment?
if (ccch_is_rrc_reestablishment(document)) {
syssim->reestablish_bearer(1);
}
}
// Todo: move to SYSSIM
@ -166,6 +171,19 @@ private:
syssim->add_dcch_pdu(lcid, std::move(pdu));
}
bool ccch_is_rrc_reestablishment(Document& document)
{
const Value& dcch = document["RrcPdu"]["Ccch"];
if (dcch.HasMember("message_")) {
if (dcch["message_"].HasMember("c1")) {
if (dcch["message_"]["c1"].HasMember("rrcConnectionReestablishment")) {
return true;
}
}
}
return false;
}
ss_srb_interface* syssim = nullptr;
byte_buffer_pool* pool = nullptr;
};

View File

@ -103,8 +103,8 @@ private:
sib->N_bytes = tb_len;
// Push to main component
log->info_hex(sib->msg, sib->N_bytes, "Received BCCH DL-SCH\n");
syssim->add_bcch_pdu(std::move(sib));
log->info_hex(sib->msg, sib->N_bytes, "Received BCCH DL-SCH for %s\n", cell_name.GetString());
syssim->add_bcch_dlsch_pdu(cell_name.GetString(), std::move(sib));
consumed_bytes = payload_ptr - payload;
}

View File

@ -148,7 +148,7 @@ public:
rlc.reset();
pdcp.reset();
cells.clear();
pcell = {};
pcell_idx = -1;
}
// Called from UT before starting testcase
@ -198,20 +198,22 @@ public:
}
}
// Called from UT to terminate the testcase
void tc_end()
{
// ask periodic thread to stop before locking mutex
running = false;
std::lock_guard<std::mutex> lock(mutex);
if (ue != NULL) {
// ask periodic thread to stop
running = false;
if (ue != nullptr) {
log.info("Deinitializing UE ID=%d\n", run_id);
log.console("Deinitializing UE ID=%d\n", run_id);
ue->stop();
// wait until SS main thread has terminated before resetting UE
wait_thread_finish();
ue.reset();
// Reset SS' RLC and PDCP
@ -243,17 +245,16 @@ public:
// 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)
{
// verify that UE intends to send PRACH on current Pcell
if (cells[pcell_idx]->cell.id != cell_id) {
log.error(
"UE is attempting to PRACH on pci=%d while current Pcell is pci=%d\n", cell_id, cells[pcell_idx]->cell.id);
return;
}
// store TTI for providing UL grant for Msg3 transmission
prach_tti = tti;
prach_preamble_index = preamble_index_;
// update active pcell (chosen by UE) in syssim
for (auto& cell : cells) {
if (cell.cell.id == cell_id) {
pcell = cell;
break;
}
}
}
// Called from PHY but always from the SS main thread with lock being hold
@ -513,11 +514,11 @@ public:
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].tbs = cells[pcell_idx]->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();
ue->new_tb(dl_grant, cells[pcell_idx]->sibs[sib_idx]->msg);
log.info("Delivered SIB%d for pcell_idx=%d\n", sib_idx, pcell_idx);
sib_idx = (sib_idx + 1) % cells[pcell_idx]->sibs.size();
} else if (SRSLTE_RNTI_ISRAR(dl_rnti)) {
if (prach_tti != -1) {
rar_tti = (prach_tti + 3) % 10240;
@ -634,12 +635,12 @@ public:
if (not syssim_has_cell(name)) {
// insert new cell
log.info("Adding cell %s with cellId=%d and power=%.2f dBm\n", name.c_str(), cell_.id, power);
syssim_cell_t cell = {};
cell.name = name;
cell.cell = cell_;
cell.initial_power = power;
cell.earfcn = earfcn_;
cells.push_back(cell);
unique_syssim_cell_t cell = unique_syssim_cell_t(new syssim_cell_t);
cell->name = name;
cell->cell = cell_;
cell->initial_power = power;
cell->earfcn = earfcn_;
cells.push_back(std::move(cell));
} else {
// cell is already there
log.info("Cell already there, reconfigure\n");
@ -651,8 +652,8 @@ public:
// internal function
bool syssim_has_cell(std::string cell_name)
{
for (uint32_t i = 0; i < cells.size(); ++i) {
if (cells[i].name == cell_name) {
for (auto& cell : cells) {
if (cell->name == cell_name) {
return true;
}
}
@ -667,9 +668,9 @@ public:
}
// update cell's power
for (uint32_t i = 0; i < cells.size(); ++i) {
if (cells[i].name == cell_name) {
cells[i].attenuation = value;
for (auto& cell : cells) {
if (cell->name == cell_name) {
cell->attenuation = value;
break;
}
}
@ -685,25 +686,51 @@ public:
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;
for (uint32_t i = 0; i < cells.size(); ++i) {
for (auto& ss_cell : cells) {
lte_ttcn3_phy::cell_t phy_cell = {};
phy_cell.info = cells[i].cell;
phy_cell.power = cells[i].initial_power - cells[i].attenuation;
phy_cell.earfcn = cells[i].earfcn;
log.debug("Configuring cell %d with PCI=%d with TxPower=%f\n", i, phy_cell.info.id, phy_cell.power);
phy_cell.info = ss_cell->cell;
phy_cell.power = ss_cell->initial_power - ss_cell->attenuation;
phy_cell.earfcn = ss_cell->earfcn;
log.info("Configuring cell with PCI=%d with TxPower=%.2f\n", phy_cell.info.id, phy_cell.power);
phy_cells.push_back(phy_cell);
}
// SYSSIM defines what cells the UE can connect to
ue->set_cell_map(phy_cells);
}
// reselect SS Pcell
float max_power = -145;
for (uint32_t i = 0; i < cells.size(); ++i) {
float actual_power = cells[i]->initial_power - cells[i]->attenuation;
if (actual_power > max_power) {
max_power = actual_power;
pcell_idx = i;
log.info("Selecting PCI=%d with TxPower=%.2f as Pcell\n", cells[pcell_idx]->cell.id, max_power);
}
}
}
void add_bcch_pdu(unique_byte_buffer_t pdu)
bool have_valid_pcell() { return (pcell_idx >= 0 && pcell_idx < static_cast<int>(cells.size())); }
void add_bcch_dlsch_pdu(const string cell_name, unique_byte_buffer_t pdu)
{
std::lock_guard<std::mutex> lock(mutex);
sibs.push_back(std::move(pdu));
if (not syssim_has_cell(cell_name)) {
log.error("Can't add BCCH to cell. Cell not found.\n");
}
// add SIB
for (auto& cell : cells) {
if (cell->name == cell_name) {
cell->sibs.push_back(std::move(pdu));
break;
}
}
}
void add_ccch_pdu(unique_byte_buffer_t pdu)
@ -753,6 +780,14 @@ public:
rlc.add_bearer(lcid, srslte::rlc_config_t::srb_config(lcid));
}
void reestablish_bearer(uint32_t lcid)
{
std::lock_guard<std::mutex> lock(mutex);
log.info("Reestablishing LCID=%d\n", lcid);
pdcp.reestablish(lcid);
rlc.reestablish(lcid);
}
void del_srb(uint32_t lcid)
{
std::lock_guard<std::mutex> lock(mutex);
@ -782,7 +817,7 @@ public:
// prepend pcell PCID
pdu->msg--;
*pdu->msg = static_cast<uint8_t>(pcell.cell.id);
*pdu->msg = static_cast<uint8_t>(cells[pcell_idx]->cell.id);
pdu->N_bytes++;
// push content to Titan
@ -832,6 +867,7 @@ public:
const srslte::CIPHERING_ALGORITHM_ID_ENUM cipher_algo,
const srslte::INTEGRITY_ALGORITHM_ID_ENUM integ_algo)
{
log.info("Setting AS security for LCID=%d\n", lcid);
pdcp.config_security(lcid, k_rrc_enc.data(), k_rrc_int.data(), k_up_enc.data(), cipher_algo, integ_algo);
pdcp.enable_integrity(lcid);
pdcp.enable_encryption(lcid);
@ -874,7 +910,6 @@ private:
uint32_t run_id = 0;
std::vector<unique_byte_buffer_t> sibs;
int32_t tti = 0;
int32_t prach_tti = -1;
int32_t rar_tti = -1;
@ -890,13 +925,15 @@ private:
// Map between the cellId (name) used by 3GPP test suite and srsLTE cell struct
typedef struct {
std::string name;
srslte_cell_t cell;
float initial_power;
float attenuation;
uint32_t earfcn;
srslte_cell_t cell = {};
float initial_power = 0.0;
float attenuation = 0.0;
uint32_t earfcn = 0;
std::vector<unique_byte_buffer_t> sibs;
} syssim_cell_t;
std::vector<syssim_cell_t> cells;
syssim_cell_t pcell = {};
typedef std::unique_ptr<syssim_cell_t> unique_syssim_cell_t;
std::vector<unique_syssim_cell_t> cells;
int32_t pcell_idx = -1;
srslte::pdu_queue pdus;
srslte::sch_pdu mac_msg_dl, mac_msg_ul;

View File

@ -100,7 +100,13 @@ public:
void stop()
{
// nothing to do here
if (stack) {
stack->stop();
}
if (phy) {
phy->stop();
}
}
bool switch_on() { return stack->switch_on(); }

View File

@ -47,7 +47,7 @@ int lte_ttcn3_phy::init(const phy_args_t& args_, stack_interface_phy_lte* stack_
// ue_phy_base interface
int lte_ttcn3_phy::init(const phy_args_t& args_)
{
log.init("PHY ", logger);
log.init("PHY ", logger, true);
log.set_level(args_.log.phy_level);
return SRSLTE_SUCCESS;
@ -130,15 +130,8 @@ int lte_ttcn3_phy::meas_stop(uint32_t earfcn, int pci)
return 0;
};
/* Cell search and selection procedures */
phy_interface_rrc_lte::cell_search_ret_t lte_ttcn3_phy::cell_search(phy_cell_t* found_cell)
void lte_ttcn3_phy::select_pcell()
{
std::lock_guard<std::mutex> lock(mutex);
log.info("Running cell search in PHY\n");
cell_search_ret_t ret = {};
// select strongest cell as PCell
float max_power = -145;
int max_index = 0;
@ -148,11 +141,22 @@ phy_interface_rrc_lte::cell_search_ret_t lte_ttcn3_phy::cell_search(phy_cell_t*
max_index = i;
}
}
pcell = cells[max_index];
log.info("Setting PCell to EARFCN=%d CellId=%d with RS power=%.2f\n", pcell.earfcn, pcell.info.id, pcell.power);
}
// Consider cell found if above -100dBm
if (max_power >= MIN_IN_SYNC_POWER) {
pcell = cells[max_index];
log.info("Setting PCell to EARFCN=%d CellId=%d with RS power=%.2f\n", pcell.earfcn, pcell.info.id, max_power);
/* Cell search and selection procedures */
phy_interface_rrc_lte::cell_search_ret_t lte_ttcn3_phy::cell_search(phy_cell_t* found_cell)
{
std::lock_guard<std::mutex> lock(mutex);
select_pcell();
log.info("Running cell search in PHY\n");
cell_search_ret_t ret = {};
// Consider cell found if Pcell power >= -100dBm
if (pcell.power >= MIN_IN_SYNC_POWER) {
if (found_cell) {
found_cell->earfcn = pcell.earfcn;
found_cell->cell = pcell.info;
@ -166,15 +170,22 @@ phy_interface_rrc_lte::cell_search_ret_t lte_ttcn3_phy::cell_search(phy_cell_t*
return ret;
};
bool lte_ttcn3_phy::cell_select(phy_cell_t* cell)
bool lte_ttcn3_phy::cell_select(phy_cell_t* rrc_cell)
{
log.debug("%s not implemented.\n", __FUNCTION__);
return true;
// try to find RRC cell in current cell map
for (auto& cell : cells) {
if (cell.info.id == rrc_cell->cell.id) {
pcell = cell;
return true;
}
}
return false;
};
bool lte_ttcn3_phy::cell_is_camping()
{
return true;
return (pcell.power >= MIN_IN_SYNC_POWER);
};
void lte_ttcn3_phy::reset()
@ -205,14 +216,11 @@ std::string lte_ttcn3_phy::get_type()
phy_interface_mac_lte::prach_info_t lte_ttcn3_phy::prach_get_info()
{
std::lock_guard<std::mutex> lock(mutex);
prach_info_t info = {};
if (prach_tti_tx != -1) {
info.is_transmitted = true;
info.tti_ra = prach_tti_tx;
}
log.info("Return prach_tti_tx=%d\n", prach_tti_tx);
return info;
}