extended handover test to check for correct SR/CQI resource setup

This commit is contained in:
Francisco Paisana 2020-06-05 19:25:43 +01:00
parent 7ce23e0afb
commit 857c4de420
3 changed files with 122 additions and 25 deletions

View File

@ -596,8 +596,8 @@ void rrc::ue::send_connection_reconf_upd(srslte::unique_byte_buffer_t pdu)
}
apply_reconf_phy_config(reconfig_r8);
phy_cfg->sched_request_cfg.setup().sr_cfg_idx = cell_ded_list.get_sr_res()->sr_I;
phy_cfg->sched_request_cfg.setup().sr_cfg_idx = cell_ded_list.get_sr_res()->sr_N_pucch;
phy_cfg->sched_request_cfg.setup().sr_cfg_idx = cell_ded_list.get_sr_res()->sr_I;
phy_cfg->sched_request_cfg.setup().sr_pucch_res_idx = cell_ded_list.get_sr_res()->sr_N_pucch;
pdu->clear();

View File

@ -238,20 +238,29 @@ int test_correct_meascfg_calculation()
}
struct mobility_test_params {
enum class test_fail_at { success, wrong_measreport, concurrent_ho, ho_prep_failure, recover } fail_at;
enum class test_event {
success,
wrong_measreport,
concurrent_ho,
ho_prep_failure,
duplicate_crnti_ce,
recover
} fail_at;
const char* to_string()
{
switch (fail_at) {
case test_fail_at::success:
case test_event::success:
return "success";
case test_fail_at::wrong_measreport:
case test_event::wrong_measreport:
return "wrong measreport";
case test_fail_at::concurrent_ho:
case test_event::concurrent_ho:
return "measreport while in handover";
case test_fail_at::ho_prep_failure:
case test_event::ho_prep_failure:
return "ho preparation failure";
case test_fail_at::recover:
case test_event::recover:
return "fail and success";
case test_event::duplicate_crnti_ce:
return "duplicate CRNTI CE";
default:
return "none";
}
@ -282,8 +291,8 @@ struct mobility_tester {
rrc_cfg_t cfg;
srsenb::rrc rrc;
mac_dummy mac;
rlc_dummy rlc;
test_dummies::mac_mobility_dummy mac;
test_dummies::rlc_mobility_dummy rlc;
test_dummies::pdcp_mobility_dummy pdcp;
phy_dummy phy;
test_dummies::s1ap_mobility_dummy s1ap;
@ -364,7 +373,7 @@ int test_s1ap_mobility(mobility_test_params test_params)
test_dummies::s1ap_mobility_dummy& s1ap = tester.s1ap;
/* Receive MeasReport from UE (correct if PCI=2) */
if (test_params.fail_at == mobility_test_params::test_fail_at::wrong_measreport) {
if (test_params.fail_at == mobility_test_params::test_event::wrong_measreport) {
uint8_t meas_report[] = {0x08, 0x10, 0x38, 0x74, 0x00, 0x0D, 0xBC, 0x80}; // PCI == 3
test_helpers::copy_msg_to_buffer(pdu, meas_report, sizeof(meas_report));
} else {
@ -375,7 +384,7 @@ int test_s1ap_mobility(mobility_test_params test_params)
tester.tic();
/* Test Case: the MeasReport is not valid */
if (test_params.fail_at == mobility_test_params::test_fail_at::wrong_measreport) {
if (test_params.fail_at == mobility_test_params::test_event::wrong_measreport) {
TESTASSERT(s1ap.last_ho_required.rrc_container == nullptr);
TESTASSERT(tester.rrc_log->warn_counter == 1);
return SRSLTE_SUCCESS;
@ -383,7 +392,7 @@ int test_s1ap_mobility(mobility_test_params test_params)
TESTASSERT(s1ap.last_ho_required.rrc_container != nullptr);
/* Test Case: Multiple concurrent MeasReports arrived. Only one HO procedure should be running */
if (test_params.fail_at == mobility_test_params::test_fail_at::concurrent_ho) {
if (test_params.fail_at == mobility_test_params::test_event::concurrent_ho) {
s1ap.last_ho_required = {};
uint8_t meas_report[] = {0x08, 0x10, 0x38, 0x74, 0x00, 0x09, 0xBC, 0x80}; // PCI == 2
test_helpers::copy_msg_to_buffer(pdu, meas_report, sizeof(meas_report));
@ -409,7 +418,7 @@ int test_s1ap_mobility(mobility_test_params test_params)
}
/* Test Case: HandoverPreparation has failed */
if (test_params.fail_at == mobility_test_params::test_fail_at::ho_prep_failure) {
if (test_params.fail_at == mobility_test_params::test_event::ho_prep_failure) {
tester.rrc.ho_preparation_complete(tester.rnti, false, nullptr);
// TESTASSERT(rrc_log->error_counter == 1);
TESTASSERT(not s1ap.last_enb_status.status_present);
@ -444,9 +453,10 @@ int test_intraenb_mobility(mobility_test_params test_params)
TESTASSERT(tester.setup_rrc() == SRSLTE_SUCCESS);
TESTASSERT(tester.run_preamble() == SRSLTE_SUCCESS);
tester.pdcp.last_sdu.sdu = nullptr;
tester.rlc.test_reset_all();
/* Receive MeasReport from UE (correct if PCI=2) */
if (test_params.fail_at == mobility_test_params::test_fail_at::wrong_measreport) {
if (test_params.fail_at == mobility_test_params::test_event::wrong_measreport) {
uint8_t meas_report[] = {0x08, 0x10, 0x38, 0x74, 0x00, 0x0D, 0xBC, 0x80}; // PCI == 3
test_helpers::copy_msg_to_buffer(pdu, meas_report, sizeof(meas_report));
} else {
@ -458,7 +468,7 @@ int test_intraenb_mobility(mobility_test_params test_params)
TESTASSERT(tester.s1ap.last_ho_required.rrc_container == nullptr);
/* Test Case: the MeasReport is not valid */
if (test_params.fail_at == mobility_test_params::test_fail_at::wrong_measreport) {
if (test_params.fail_at == mobility_test_params::test_event::wrong_measreport) {
TESTASSERT(tester.rrc_log->warn_counter == 1);
TESTASSERT(tester.pdcp.last_sdu.sdu == nullptr);
return SRSLTE_SUCCESS;
@ -468,7 +478,7 @@ int test_intraenb_mobility(mobility_test_params test_params)
TESTASSERT(not tester.s1ap.last_enb_status.status_present);
/* Test Case: Multiple concurrent MeasReports arrived. Only one HO procedure should be running */
if (test_params.fail_at == mobility_test_params::test_fail_at::concurrent_ho) {
if (test_params.fail_at == mobility_test_params::test_event::concurrent_ho) {
tester.pdcp.last_sdu = {};
uint8_t meas_report[] = {0x08, 0x10, 0x38, 0x74, 0x00, 0x09, 0xBC, 0x80}; // PCI == 2
test_helpers::copy_msg_to_buffer(pdu, meas_report, sizeof(meas_report));
@ -488,6 +498,54 @@ int test_intraenb_mobility(mobility_test_params test_params)
TESTASSERT(recfg_r8.mob_ctrl_info_present);
TESTASSERT(recfg_r8.mob_ctrl_info.new_ue_id.to_number() == tester.rnti);
TESTASSERT(recfg_r8.mob_ctrl_info.target_pci == 2);
TESTASSERT(recfg_r8.rr_cfg_ded_present);
TESTASSERT(recfg_r8.rr_cfg_ded.phys_cfg_ded_present);
const asn1::rrc::phys_cfg_ded_s& phy_cfg_ded = recfg_r8.rr_cfg_ded.phys_cfg_ded;
TESTASSERT(phy_cfg_ded.sched_request_cfg_present);
TESTASSERT(phy_cfg_ded.cqi_report_cfg_present);
/* Test Case: The UE sends a C-RNTI CE. Bearers are reestablished */
tester.pdcp.last_sdu.sdu = nullptr;
tester.rrc.upd_user(tester.rnti + 1, tester.rnti);
TESTASSERT(tester.rlc.ue_db[tester.rnti].reest_sdu_counter == 0);
TESTASSERT(tester.pdcp.last_sdu.sdu == nullptr);
/* Test Case: The UE receives a duplicate C-RNTI CE. Nothing should happen */
if (test_params.fail_at == mobility_test_params::test_event::duplicate_crnti_ce) {
TESTASSERT(tester.rlc.ue_db[tester.rnti].reest_sdu_counter == 0);
tester.rrc.upd_user(tester.rnti + 2, tester.rnti);
TESTASSERT(tester.rlc.ue_db[tester.rnti].reest_sdu_counter == 0);
TESTASSERT(tester.pdcp.last_sdu.sdu == nullptr);
TESTASSERT(tester.rlc.ue_db[tester.rnti].last_sdu == nullptr); // No Reject sent
}
/* Test Case: Terminate first Handover. No extra messages should be sent DL. SR/CQI resources match recfg message */
uint8_t recfg_complete[] = {0x10, 0x00};
test_helpers::copy_msg_to_buffer(pdu, recfg_complete, sizeof(recfg_complete));
tester.rrc.write_pdu(tester.rnti, rb_id_t::RB_ID_SRB2, std::move(pdu));
TESTASSERT(tester.pdcp.last_sdu.sdu == nullptr);
sched_interface::ue_cfg_t& ue_cfg = tester.mac.ue_db[tester.rnti];
TESTASSERT(ue_cfg.pucch_cfg.sr_configured);
TESTASSERT(ue_cfg.pucch_cfg.n_pucch_sr == phy_cfg_ded.sched_request_cfg.setup().sr_pucch_res_idx);
TESTASSERT(ue_cfg.pucch_cfg.I_sr == phy_cfg_ded.sched_request_cfg.setup().sr_cfg_idx);
TESTASSERT(ue_cfg.dl_cfg.cqi_report.pmi_idx ==
phy_cfg_ded.cqi_report_cfg.cqi_report_periodic.setup().cqi_pmi_cfg_idx);
TESTASSERT(ue_cfg.pucch_cfg.n_pucch == phy_cfg_ded.cqi_report_cfg.cqi_report_periodic.setup().cqi_pucch_res_idx);
/* Test Case: The RRC should be able to start a new handover */
uint8_t meas_report[] = {0x08, 0x10, 0x38, 0x74, 0x00, 0x05, 0xBC, 0x80}; // PCI == 1
test_helpers::copy_msg_to_buffer(pdu, meas_report, sizeof(meas_report));
tester.rrc.write_pdu(tester.rnti, 1, std::move(pdu));
tester.tic();
TESTASSERT(tester.s1ap.last_ho_required.rrc_container == nullptr);
TESTASSERT(tester.pdcp.last_sdu.sdu != nullptr);
TESTASSERT(tester.s1ap.last_ho_required.rrc_container == nullptr);
TESTASSERT(not tester.s1ap.last_enb_status.status_present);
TESTASSERT(test_helpers::unpack_asn1(ho_cmd, tester.pdcp.last_sdu.sdu));
recfg_r8 = ho_cmd.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8();
TESTASSERT(recfg_r8.mob_ctrl_info_present);
TESTASSERT(recfg_r8.mob_ctrl_info.new_ue_id.to_number() == tester.rnti);
TESTASSERT(recfg_r8.mob_ctrl_info.target_pci == 1);
return SRSLTE_SUCCESS;
}
@ -495,7 +553,7 @@ int test_intraenb_mobility(mobility_test_params test_params)
int main(int argc, char** argv)
{
srslte::logmap::set_default_log_level(srslte::LOG_LEVEL_INFO);
using fail_at = mobility_test_params::test_fail_at;
using event = mobility_test_params::test_event;
if (argc < 3) {
argparse::usage(argv[0]);
@ -506,15 +564,16 @@ int main(int argc, char** argv)
TESTASSERT(test_correct_meascfg_calculation() == 0);
// S1AP Handover
TESTASSERT(test_s1ap_mobility(mobility_test_params{fail_at::wrong_measreport}) == 0);
TESTASSERT(test_s1ap_mobility(mobility_test_params{fail_at::concurrent_ho}) == 0);
TESTASSERT(test_s1ap_mobility(mobility_test_params{fail_at::ho_prep_failure}) == 0);
TESTASSERT(test_s1ap_mobility(mobility_test_params{fail_at::success}) == 0);
TESTASSERT(test_s1ap_mobility(mobility_test_params{event::wrong_measreport}) == 0);
TESTASSERT(test_s1ap_mobility(mobility_test_params{event::concurrent_ho}) == 0);
TESTASSERT(test_s1ap_mobility(mobility_test_params{event::ho_prep_failure}) == 0);
TESTASSERT(test_s1ap_mobility(mobility_test_params{event::success}) == 0);
// intraeNB Handover
TESTASSERT(test_intraenb_mobility(mobility_test_params{fail_at::wrong_measreport}) == 0);
TESTASSERT(test_intraenb_mobility(mobility_test_params{fail_at::concurrent_ho}) == 0);
TESTASSERT(test_intraenb_mobility(mobility_test_params{fail_at::success}) == 0);
TESTASSERT(test_intraenb_mobility(mobility_test_params{event::wrong_measreport}) == 0);
TESTASSERT(test_intraenb_mobility(mobility_test_params{event::concurrent_ho}) == 0);
TESTASSERT(test_intraenb_mobility(mobility_test_params{event::duplicate_crnti_ce}) == 0);
TESTASSERT(test_intraenb_mobility(mobility_test_params{event::success}) == 0);
printf("\nSuccess\n");

View File

@ -122,6 +122,44 @@ public:
}
};
class rlc_mobility_dummy : public rlc_dummy
{
public:
struct ue_ctxt {
int nof_pdcp_sdus = 0, reest_sdu_counter = 0;
uint32_t last_lcid = 0;
srslte::unique_byte_buffer_t last_sdu;
};
std::map<uint16_t, ue_ctxt> ue_db;
void test_reset_all()
{
for (auto& u : ue_db) {
u.second = {};
}
}
void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) override
{
ue_db[rnti].nof_pdcp_sdus++;
ue_db[rnti].reest_sdu_counter++;
ue_db[rnti].last_lcid = lcid;
ue_db[rnti].last_sdu = std::move(sdu);
}
void reestablish(uint16_t rnti) final { ue_db[rnti].reest_sdu_counter = 0; }
};
class mac_mobility_dummy : public mac_dummy
{
public:
int ue_cfg(uint16_t rnti, sched_interface::ue_cfg_t* cfg) override
{
ue_db[rnti] = *cfg;
return 0;
}
std::map<uint16_t, sched_interface::ue_cfg_t> ue_db;
};
} // namespace test_dummies
namespace test_helpers {