Fix srsenb PHY and unit/component tests

This commit is contained in:
Xavier Arteaga 2020-02-11 16:03:43 +01:00 committed by Xavier Arteaga
parent 7a20e3a51e
commit bf4ecc8064
6 changed files with 211 additions and 32 deletions

View File

@ -176,6 +176,7 @@ public:
configure_mbsfn(asn1::rrc::sib_type2_s* sib2, asn1::rrc::sib_type13_r9_s* sib13, asn1::rrc::mcch_msg_s mcch) = 0;
typedef struct {
bool active = false; ///< Indicates whether PHY shall consider using this or not
uint32_t cc_idx = 0; ///< eNb Cell index
srslte::phy_cfg_t phy_cfg = {}; ///< Dedicated physical layer configuration
} phy_rrc_dedicated_t;

View File

@ -830,6 +830,11 @@ void srslte_ue_ul_pucch_resource_selection(srslte_cell_t* cell,
uci_cfg->cqi.data_enable = false;
}
// Set Scheduling request to true in UCI config if SR
if (uci_value && uci_value->scheduling_request) {
uci_cfg->is_scheduling_request_tti = true;
}
// Get PUCCH Resources
cfg->format = srslte_pucch_select_format(cfg, uci_cfg, cell->cp);
cfg->n_pucch = get_npucch(cfg, uci_cfg, uci_value, cell);

View File

@ -344,7 +344,26 @@ public:
int get_drbid_config(asn1::rrc::drb_to_add_mod_s* drb, int drbid);
bool nas_pending = false;
srslte::byte_buffer_t erab_info;
};
///< UE's Physical layer dedicated configuration
phy_interface_rrc_lte::phy_rrc_dedicated_list_t phy_rrc_dedicated_list = {};
/**
* Setups the PCell physical layer dedicated configuration of the UE. This method shall be called from the
* connection setup only.
* @param phys_cfg_ded ASN1 Physical layer configuration dedicated
*/
void apply_setup_phy_config(const asn1::rrc::phys_cfg_ded_s& phys_cfg_ded);
/**
* Reconfigures the PCell and SCell physical layer dedicated configuration of the UE. This method shall be called
* from the connection reconfiguration. `apply_setup_phy_config` shall not be called before/after. It automatically
* parses the PCell and SCell reconfiguration.
*
* @param reconfig_r8 ASN1 reconfiguration message
*/
void apply_reconf_phy_config(const asn1::rrc::rrc_conn_recfg_r8_ies_s& reconfig_r8);
}; // class ue
private:
// args

View File

@ -256,14 +256,16 @@ void phy::get_metrics(phy_metrics_t metrics[ENB_METRICS_MAX_USERS])
void phy::set_config_dedicated(uint16_t rnti, const phy_rrc_dedicated_list_t& dedicated_list)
{
// Create list
std::vector<uint32_t> scell_idx_list(dedicated_list.size());
// Create list, empty by default
std::vector<uint32_t> scell_idx_list;
for (uint32_t i = 0; i < dedicated_list.size(); i++) {
auto& config = dedicated_list[i];
// Set SCell index in list
scell_idx_list[i] = config.cc_idx;
// Configure only if active, ignore otherwise
if (config.active) {
// Set PCell/SCell index in list
scell_idx_list.push_back(config.cc_idx);
// Configure workers
for (uint32_t w = 0; w < nof_workers; w++) {
@ -274,6 +276,7 @@ void phy::set_config_dedicated(uint16_t rnti, const phy_rrc_dedicated_list_t& de
workers[w].set_config_dedicated(rnti, config.cc_idx, config.phy_cfg);
}
}
}
// Finally, set UE database
workers_common.ue_db_addmod_rnti(rnti, scell_idx_list);

View File

@ -1013,7 +1013,8 @@ rrc::ue::ue(rrc* outer_rrc, uint16_t rnti_, const sched_interface::ue_cfg_t& sch
parent(outer_rrc),
rnti(rnti_),
pool(srslte::byte_buffer_pool::get_instance()),
current_sched_ue_cfg(sched_ue_cfg)
current_sched_ue_cfg(sched_ue_cfg),
phy_rrc_dedicated_list(sched_ue_cfg.supported_cc_list.size())
{
activity_timer = outer_rrc->timers->get_unique_timer();
set_activity_timeout(MSG3_RX_TIMEOUT); // next UE response is Msg3
@ -1628,7 +1629,7 @@ void rrc::ue::send_connection_setup(bool is_setup)
parent->pdcp->add_bearer(rnti, 1, srslte::make_srb_pdcp_config_t(1, false));
// Configure PHY layer
parent->phy->set_config_dedicated(rnti, phy_cfg);
apply_setup_phy_config(*phy_cfg); // It assumes SCell has not been set before
parent->mac->phy_config_enabled(rnti, false);
rr_cfg->drb_to_add_mod_list_present = false;
@ -1707,7 +1708,8 @@ void rrc::ue::send_connection_reconf_upd(srslte::unique_byte_buffer_t pdu)
rrc_conn_recfg->crit_exts.set_c1().set_rrc_conn_recfg_r8();
rrc_conn_recfg->crit_exts.c1().rrc_conn_recfg_r8().rr_cfg_ded_present = true;
rr_cfg_ded_s* rr_cfg = &rrc_conn_recfg->crit_exts.c1().rrc_conn_recfg_r8().rr_cfg_ded;
auto& reconfig_r8 = rrc_conn_recfg->crit_exts.c1().rrc_conn_recfg_r8();
rr_cfg_ded_s* rr_cfg = &reconfig_r8.rr_cfg_ded;
rr_cfg->phys_cfg_ded_present = true;
phys_cfg_ded_s* phy_cfg = &rr_cfg->phys_cfg_ded;
@ -1738,7 +1740,7 @@ void rrc::ue::send_connection_reconf_upd(srslte::unique_byte_buffer_t pdu)
phy_cfg->cqi_report_cfg.cqi_report_mode_aperiodic = cqi_report_mode_aperiodic_e::rm30;
}
}
parent->phy->set_config_dedicated(rnti, phy_cfg);
apply_reconf_phy_config(reconfig_r8);
sr_get(&phy_cfg->sched_request_cfg.setup().sr_cfg_idx, &phy_cfg->sched_request_cfg.setup().sr_pucch_res_idx);
@ -1800,7 +1802,7 @@ void rrc::ue::send_connection_reconf(srslte::unique_byte_buffer_t pdu)
phy_cfg->pdsch_cfg_ded_present = true;
phy_cfg->pdsch_cfg_ded.p_a = parent->cfg.pdsch_cfg;
parent->phy->set_config_dedicated(rnti, phy_cfg);
apply_reconf_phy_config(*conn_reconf);
current_sched_ue_cfg.dl_ant_info = srslte::make_ant_info_ded(phy_cfg->ant_info.explicit_value());
parent->mac->ue_cfg(rnti, &current_sched_ue_cfg);
parent->mac->phy_config_enabled(rnti, false);
@ -2144,6 +2146,112 @@ void rrc::ue::send_dl_dcch(dl_dcch_msg_s* dl_dcch_msg, srslte::unique_byte_buffe
}
}
void rrc::ue::apply_setup_phy_config(const asn1::rrc::phys_cfg_ded_s& phys_cfg_ded)
{
// Return if no cell is supported
if (phy_rrc_dedicated_list.empty()) {
return;
}
// Set PCell index
phy_rrc_dedicated_list[0].active = true;
phy_rrc_dedicated_list[0].cc_idx = current_sched_ue_cfg.supported_cc_list[0].enb_cc_idx;
// Load PCell dedicated configuration
srslte::set_phy_cfg_t_dedicated_cfg(&phy_rrc_dedicated_list[0].phy_cfg, phys_cfg_ded);
// Deactivates eNb/Cells for this UE
for (uint32_t cc = 1; cc < phy_rrc_dedicated_list.size(); cc++) {
phy_rrc_dedicated_list[cc].active = false;
}
// Send configuration to physical layer
if (parent->phy != nullptr) {
parent->phy->set_config_dedicated(rnti, phy_rrc_dedicated_list);
}
}
void rrc::ue::apply_reconf_phy_config(const asn1::rrc::rrc_conn_recfg_r8_ies_s& reconfig_r8)
{
// Return if no cell is supported
if (phy_rrc_dedicated_list.empty()) {
return;
}
// Configure PCell if available configuration
if (reconfig_r8.rr_cfg_ded_present) {
auto& rr_cfg_ded = reconfig_r8.rr_cfg_ded;
if (rr_cfg_ded.phys_cfg_ded_present) {
auto& phys_cfg_ded = rr_cfg_ded.phys_cfg_ded;
srslte::set_phy_cfg_t_dedicated_cfg(&phy_rrc_dedicated_list[0].phy_cfg, phys_cfg_ded);
}
}
// Parse extensions
if (reconfig_r8.non_crit_ext_present) {
auto& reconfig_r890 = reconfig_r8.non_crit_ext;
if (reconfig_r890.non_crit_ext_present) {
auto& reconfig_r920 = reconfig_r890.non_crit_ext;
if (reconfig_r920.non_crit_ext_present) {
auto& reconfig_r1020 = reconfig_r920.non_crit_ext;
// Handle Add/Modify SCell list
if (reconfig_r1020.scell_to_add_mod_list_r10_present) {
for (const auto& scell_config : reconfig_r1020.scell_to_add_mod_list_r10) {
// UE SCell index
uint32_t scell_idx = scell_config.scell_idx_r10;
// Check that the SCell index is correct.
if (scell_idx == 0) {
// SCell index is reserved for PCell
parent->rrc_log->error("SCell index (%d) is reserved for PCell\n", scell_idx);
} else if (scell_idx < current_sched_ue_cfg.supported_cc_list.size()) {
// Get PHY configuration structure, create entry automatically
auto& phy_rrc_dedicated = phy_rrc_dedicated_list[scell_idx];
// Set eNb Cell/Carrier index
phy_rrc_dedicated.active = true;
phy_rrc_dedicated.cc_idx = current_sched_ue_cfg.supported_cc_list[scell_idx].enb_cc_idx;
// Set SCell configuration
srslte::set_phy_cfg_t_scell_config(&phy_rrc_dedicated.phy_cfg, scell_config);
} else {
// Out of bounds, log error
parent->rrc_log->error("SCell index (%d) points out of the supported list (%ld)\n",
scell_idx,
current_sched_ue_cfg.supported_cc_list.size());
}
}
}
// Handle Remove SCell list
if (reconfig_r1020.scell_to_release_list_r10_present) {
for (auto& scell_to_release : reconfig_r1020.scell_to_release_list_r10) {
if (scell_to_release == 0) {
// SCell index is reserved for PCell
parent->rrc_log->error("SCell index (%d) is reserved for PCell\n", scell_to_release);
} else if (scell_to_release < current_sched_ue_cfg.supported_cc_list.size()) {
// Deactivate cell configuration
phy_rrc_dedicated_list[scell_to_release].active = false;
} else {
// Out of bounds, log error
parent->rrc_log->error("SCell index (%d) points out of the supported list (%ld)\n",
scell_to_release,
current_sched_ue_cfg.supported_cc_list.size());
}
}
}
}
}
}
// Send configuration to physical layer
if (parent->phy != nullptr) {
parent->phy->set_config_dedicated(rnti, phy_rrc_dedicated_list);
}
}
int rrc::ue::sr_free()
{
if (sr_allocated) {

View File

@ -287,8 +287,13 @@ private:
uint32_t tb_idx;
} tti_dl_info_t;
typedef struct {
uint32_t tti;
} tti_sr_info_t;
std::queue<tti_dl_info_t> tti_dl_info_sched_queue;
std::queue<tti_dl_info_t> tti_dl_info_ack_queue;
std::queue<tti_sr_info_t> tti_sr_info_queue;
public:
explicit dummy_stack(uint16_t rnti_) : log_h("STACK"), ue_rnti(rnti_), random_gen(srslte_random_init(0))
@ -311,8 +316,14 @@ public:
int sr_detected(uint32_t tti, uint16_t rnti) override
{
tti_sr_info_t tti_sr_info = {};
tti_sr_info.tti = tti;
tti_sr_info_queue.push(tti_sr_info);
notify_sr_detected();
return 0;
log_h.info("Received SR tti=%d; rnti=x%x\n", tti, rnti);
return SRSLTE_SUCCESS;
}
int rach_detected(uint32_t tti, uint32_t primary_cc_idx, uint32_t preamble_idx, uint32_t time_adv) override
{
@ -372,7 +383,7 @@ public:
dl_sched.cfi = 1;
// Random decision on whether transmit or not
if (srslte_random_uniform_real_dist(random_gen, 0, 1) < prob_dl_grant) {
if (srslte_random_bool(random_gen, prob_dl_grant)) {
dl_sched.nof_grants = 1;
dl_sched.pdsch[0].softbuffer_tx[0] = &softbuffer_tx;
dl_sched.pdsch[0].softbuffer_tx[1] = &softbuffer_tx;
@ -446,6 +457,24 @@ public:
tti_dl_info_ack_queue.pop();
}
// Check SR match with TTI
while (tti_sr_info_queue.size() > 1) {
tti_sr_info_t tti_sr_info1 = tti_sr_info_queue.front();
// Check first TTI
TESTASSERT(tti_sr_info1.tti % 20 == 0);
// POP first from queue
tti_sr_info_queue.pop();
// Get second, do not pop
tti_sr_info_t& tti_sr_info2 = tti_sr_info_queue.front();
// Make sure the TTI difference is 20
uint32_t elapsed_tti = ((tti_sr_info2.tti + 10240) - tti_sr_info1.tti) % 10240;
TESTASSERT(elapsed_tti == 20);
}
return SRSLTE_SUCCESS;
}
};
@ -600,9 +629,9 @@ public:
for (uint32_t i = 0; i < buffers.size(); i++) {
srslte_dci_dl_t dci_dl[SRSLTE_MAX_DCI_MSG] = {};
srslte_ue_dl_cfg_t ue_dl_cfg = {};
ue_dl_cfg.cfg.cqi_report.periodic_configured = true;
ue_dl_cfg.cfg.cqi_report.periodic_mode = SRSLTE_CQI_MODE_12;
ue_dl_cfg.cfg.cqi_report.pmi_idx = 16 + i;
// ue_dl_cfg.cfg.cqi_report.periodic_configured = true;
// ue_dl_cfg.cfg.cqi_report.periodic_mode = SRSLTE_CQI_MODE_12;
// ue_dl_cfg.cfg.cqi_report.pmi_idx = 16 + i;
ue_dl_cfg.cfg.pdsch.rnti = rnti;
srslte_ue_dl_decode_fft_estimate(ue_dl_v[i], &sf_dl_cfg, &ue_dl_cfg);
@ -647,9 +676,6 @@ public:
srslte_ue_dl_gen_cqi_periodic(ue_dl_v[i], &ue_dl_cfg, 0x0f, sf_dl_cfg.tti, &uci_data);
}
// Generate Acknowledgements
srslte_ue_dl_gen_ack(ue_dl_v[0], &sf_dl_cfg, &pdsch_ack, &uci_data);
// Work UL
for (uint32_t i = 0; i < buffers.size(); i++) {
srslte_ue_ul_cfg_t ue_ul_cfg = {};
@ -657,6 +683,15 @@ public:
ue_ul_cfg.ul_cfg.pusch.softbuffers.tx = &softbuffer_tx;
ue_ul_cfg.ul_cfg.pucch.rnti = rnti;
// Generate
if (i == 0) {
// Generate scheduling request
srslte_ue_ul_gen_sr(&ue_ul_cfg, &sf_ul_cfg, &uci_data, (bool)(sf_ul_cfg.tti % 20 == 0));
// Generate Acknowledgements
srslte_ue_dl_gen_ack(ue_dl_v[0], &sf_dl_cfg, &pdsch_ack, &uci_data);
}
srslte_pusch_data_t pusch_data = {};
pusch_data.ptr = tx_data;
@ -734,7 +769,13 @@ public:
for (uint32_t i = 0; i < 4; i++) {
common_dedicated.dl_cfg.cqi_report.pmi_idx = 16 + i;
dedicated_list[i].cc_idx = (i + pcell_idx) % phy_cfg.phy_cell_cfg.size();
dedicated_list[i].active = true;
dedicated_list[i].phy_cfg = common_dedicated;
// Disable SCell stuff
if (i != pcell_index) {
dedicated_list[i].phy_cfg.ul_cfg.pucch.sr_configured = false;
}
}
enb_phy.set_config_dedicated(rnti, dedicated_list);
}
@ -795,15 +836,17 @@ int main(int argc, char** argv)
dedicated.ul_cfg.pucch.delta_pucch_shift = 1;
dedicated.ul_cfg.pucch.n_rb_2 = 0;
dedicated.ul_cfg.pucch.N_cs = 0;
dedicated.ul_cfg.pucch.N_pucch_1 = 0;
dedicated.ul_cfg.pucch.n_pucch_2 = 0;
dedicated.ul_cfg.pucch.n_pucch_sr = 0;
dedicated.ul_cfg.pucch.n_pucch_sr = 1;
dedicated.ul_cfg.pucch.N_pucch_1 = 2;
dedicated.ul_cfg.pucch.n_pucch_2 = 3;
dedicated.ul_cfg.pucch.simul_cqi_ack = true;
dedicated.ul_cfg.pucch.sr_configured = true;
dedicated.ul_cfg.pucch.I_sr = 5;
std::unique_ptr<phy_test_bench> test_bench =
std::unique_ptr<phy_test_bench>(new phy_test_bench(phy_args, phy_cfg, 0x1234, 0, dedicated));
for (uint32_t i = 0; i < 32; i++) {
for (uint32_t i = 0; i < 128; i++) {
TESTASSERT(test_bench->run_tti() >= SRSLTE_SUCCESS);
}