extended rrc tenb s1 handover test. implemented layer reconfig during s1 handover

master
Francisco Paisana 4 years ago
parent 7605c7df23
commit db8af399f8

@ -439,6 +439,7 @@ public:
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container,
srslte::byte_buffer_t& ho_cmd,
std::vector<asn1::fixed_octstring<4, true> >& admitted_erabs) = 0;
virtual void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_item_s& erab) = 0;
};
// GTPU interface for PDCP

@ -43,7 +43,8 @@ public:
void handle_con_reconf(const asn1::rrc::rrc_conn_recfg_r8_ies_s& conn_recfg);
void handle_con_reconf_complete();
void handle_ho_prep(const asn1::rrc::ho_prep_info_r8_ies_s& ho_prep);
void handle_ho_prep(const asn1::rrc::ho_prep_info_r8_ies_s& ho_prep,
const asn1::rrc::rrc_conn_recfg_r8_ies_s& conn_recfg);
void handle_ho_prep_complete();
const sched_interface::ue_cfg_t& get_ue_sched_cfg() const { return current_sched_ue_cfg; }

@ -92,6 +92,7 @@ public:
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container,
srslte::byte_buffer_t& ho_cmd,
std::vector<asn1::fixed_octstring<4, true> >& admitted_erabs) override;
void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_item_s& erab) override;
// rrc_interface_pdcp
void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) override;

@ -148,7 +148,6 @@ private:
const asn1::rrc::meas_obj_to_add_mod_s* meas_obj = nullptr;
};
struct ho_req_rx_ev {
asn1::rrc::rrc_conn_recfg_r8_ies_s ho_cmd;
const asn1::s1ap::ho_request_s* ho_req_msg;
const asn1::rrc::ho_prep_info_r8_ies_s* ho_prep_r8;
const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s* transparent_container;
@ -166,6 +165,7 @@ private:
void enter(rrc_mobility* f, const ho_meas_report_ev& meas_report);
};
struct s1_target_ho_st {
srslte::unique_byte_buffer_t ho_cmd_pdu;
void enter(rrc_mobility* f, const ho_req_rx_ev& ho_req);
};
struct s1_source_ho_st : public subfsm_t<s1_source_ho_st> {

@ -78,6 +78,7 @@ public:
bool setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l& e);
bool setup_erabs(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_l& e);
bool release_erabs();
void set_erab_status(const asn1::s1ap::bearers_subject_to_status_transfer_item_s& erab);
// handover
void handle_ho_preparation_complete(bool is_success, srslte::unique_byte_buffer_t container);

@ -152,6 +152,7 @@ private:
bool handle_hopreparationfailure(const asn1::s1ap::ho_prep_fail_s& msg);
bool handle_s1hocommand(const asn1::s1ap::ho_cmd_s& msg);
bool handle_ho_request(const asn1::s1ap::ho_request_s& msg);
bool handle_mme_status_transfer(const asn1::s1ap::mme_status_transfer_s& msg);
// UE-specific data and procedures
struct ue {

@ -302,11 +302,28 @@ void rrc::ue::mac_controller::apply_scell_cfg_updates(uint32_t ue_cc_idx)
pending_scells_cfg->erase(it);
}
void rrc::ue::mac_controller::handle_ho_prep(const asn1::rrc::ho_prep_info_r8_ies_s& ho_prep) {}
void rrc::ue::mac_controller::handle_ho_prep_complete()
void rrc::ue::mac_controller::handle_ho_prep(const asn1::rrc::ho_prep_info_r8_ies_s& ho_prep,
const asn1::rrc::rrc_conn_recfg_r8_ies_s& conn_recfg)
{
apply_current_bearers_cfg();
// TODO: Apply configuration in ho_prep
if (conn_recfg.rr_cfg_ded_present and conn_recfg.rr_cfg_ded.phys_cfg_ded_present) {
apply_phy_cfg_updates_common(conn_recfg.rr_cfg_ded.phys_cfg_ded);
}
// Store Scells Configuration
if (conn_recfg.non_crit_ext_present and conn_recfg.non_crit_ext.non_crit_ext_present and
conn_recfg.non_crit_ext.non_crit_ext.non_crit_ext_present and
conn_recfg.non_crit_ext.non_crit_ext.non_crit_ext.scell_to_add_mod_list_r10_present) {
pending_scells_cfg.reset(new asn1::rrc::scell_to_add_mod_list_r10_l{
conn_recfg.non_crit_ext.non_crit_ext.non_crit_ext.scell_to_add_mod_list_r10});
}
// Apply changes to MAC scheduler
mac->ue_cfg(rrc_ue->rnti, &current_sched_ue_cfg);
mac->phy_config_enabled(rrc_ue->rnti, false);
}
void rrc::ue::mac_controller::handle_ho_prep_complete() {}
} // namespace srsenb

@ -470,6 +470,17 @@ uint16_t rrc::start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s&
return enb_mobility_cfg->start_ho_ue_resource_alloc(msg, container, ho_cmd, admitted_erabs);
}
void rrc::set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_item_s& erab)
{
auto ue_it = users.find(rnti);
if (ue_it == users.end()) {
rrc_log->warning("rnti=0x%x does not exist\n", rnti);
return;
}
ue_it->second->set_erab_status(erab);
}
/*******************************************************************************
Private functions
All private functions are not mutexed and must be called from a mutexed environment

@ -792,8 +792,6 @@ bool rrc::ue::rrc_mobility::start_s1_tenb_ho(
srslte::byte_buffer_t& ho_cmd_pdu,
std::vector<asn1::fixed_octstring<4, true> >& admitted_erabs)
{
const cell_ctxt_dedicated* target_cell = rrc_ue->cell_ded_list.get_ue_cc_idx(UE_PCELL_CC_IDX);
/* TS 36.331 10.2.2. - Decode HandoverPreparationInformation */
asn1::cbit_ref bref{container.rrc_container.data(), container.rrc_container.size()};
asn1::rrc::ho_prep_info_s hoprep;
@ -810,47 +808,20 @@ bool rrc::ue::rrc_mobility::start_s1_tenb_ho(
rrc_enb->log_rrc_message(
"HandoverPreparation", direction_t::fromS1AP, container.rrc_container, hoprep, "HandoverPreparation");
/* Prepare Handover Request Acknowledgment - Handover Command */
dl_dcch_msg_s dl_dcch_msg;
rrc_conn_recfg_r8_ies_s& recfg_r8 =
dl_dcch_msg.msg.set_c1().set_rrc_conn_recfg().crit_exts.set_c1().set_rrc_conn_recfg_r8();
// Fill fields common to all types of handover
fill_mobility_reconf_common(dl_dcch_msg, *target_cell->cell_common);
// Encode MeasConfig
var_meas_cfg_t current_var_meas = var_meas_cfg_t::make(hoprep_r8.as_cfg.source_meas_cfg);
recfg_r8.meas_cfg_present =
update_ue_var_meas_cfg(current_var_meas, target_cell->cell_common->enb_cc_idx, &recfg_r8.meas_cfg);
/* Prepare Handover Command to be sent via S1AP */
asn1::bit_ref bref2{ho_cmd_pdu.msg, ho_cmd_pdu.get_tailroom()};
if (dl_dcch_msg.pack(bref2) != asn1::SRSASN_SUCCESS) {
rrc_enb->rrc_log->error("Failed to pack HandoverCommand\n");
return false;
}
ho_cmd_pdu.N_bytes = bref2.distance_bytes();
rrc_enb->log_rrc_message("RRC container", direction_t::S1AP, &ho_cmd_pdu, dl_dcch_msg, "HandoverCommand");
asn1::rrc::ho_cmd_s ho_cmd;
asn1::rrc::ho_cmd_r8_ies_s& ho_cmd_r8 = ho_cmd.crit_exts.set_c1().set_ho_cmd_r8();
ho_cmd_r8.ho_cmd_msg.resize(bref2.distance_bytes());
memcpy(ho_cmd_r8.ho_cmd_msg.data(), ho_cmd_pdu.msg, bref2.distance_bytes());
bref2 = {ho_cmd_pdu.msg, ho_cmd_pdu.get_tailroom()};
if (ho_cmd.pack(bref2) != asn1::SRSASN_SUCCESS) {
rrc_enb->rrc_log->error("Failed to pack HandoverCommand\n");
return false;
}
ho_cmd_pdu.N_bytes = bref2.distance_bytes();
trigger(ho_req_rx_ev{recfg_r8, &msg, &hoprep_r8, &container});
trigger(ho_req_rx_ev{&msg, &hoprep_r8, &container});
for (auto& erab : rrc_ue->bearer_list.get_erabs()) {
admitted_erabs.push_back({});
admitted_erabs.emplace_back();
srslte::uint32_to_uint8(erab.second.teid_in, admitted_erabs.back().data());
}
return is_in_state<s1_target_ho_st>();
if (is_in_state<s1_target_ho_st>()) {
srslte::unique_byte_buffer_t pdu = std::move(get_state<s1_target_ho_st>()->ho_cmd_pdu);
memcpy(ho_cmd_pdu.msg, pdu->msg, pdu->N_bytes);
ho_cmd_pdu.N_bytes = pdu->N_bytes;
return true;
}
return false;
}
bool rrc::ue::rrc_mobility::update_ue_var_meas_cfg(const asn1::rrc::meas_cfg_s& source_meas_cfg,
@ -1126,13 +1097,53 @@ void rrc::ue::rrc_mobility::s1_target_ho_st::enter(rrc_mobility* f, const ho_req
f->rrc_ue->bearer_list.add_gtpu_bearer(f->rrc_enb->gtpu, erab.erab_id);
}
// Update MAC
f->rrc_ue->mac_ctrl->handle_ho_prep(*ho_req.ho_prep_r8);
/* Prepare Handover Request Acknowledgment - Handover Command */
dl_dcch_msg_s dl_dcch_msg;
rrc_conn_recfg_r8_ies_s& recfg_r8 =
dl_dcch_msg.msg.set_c1().set_rrc_conn_recfg().crit_exts.set_c1().set_rrc_conn_recfg_r8();
// Fill fields common to all types of handover
f->fill_mobility_reconf_common(dl_dcch_msg, *target_cell->cell_common);
// Encode MeasConfig
var_meas_cfg_t current_var_meas = var_meas_cfg_t::make(ho_req.ho_prep_r8->as_cfg.source_meas_cfg);
recfg_r8.meas_cfg_present =
f->update_ue_var_meas_cfg(current_var_meas, target_cell->cell_common->enb_cc_idx, &recfg_r8.meas_cfg);
/* Configure layers based on Reconfig Message */
// Update RLC + PDCP
f->rrc_ue->ue_security_cfg.regenerate_keys_handover(target_cell_cfg.pci, target_cell_cfg.dl_earfcn);
f->rrc_ue->bearer_list.apply_pdcp_bearer_updates(f->rrc_enb->pdcp, f->rrc_ue->ue_security_cfg);
f->rrc_ue->bearer_list.apply_rlc_bearer_updates(f->rrc_enb->rlc);
f->rrc_ue->ue_security_cfg.regenerate_keys_handover(target_cell_cfg.pci, target_cell_cfg.dl_earfcn);
// Update MAC
f->rrc_ue->mac_ctrl->handle_ho_prep(*ho_req.ho_prep_r8,
dl_dcch_msg.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8());
// Apply PHY updates
f->rrc_ue->apply_reconf_phy_config(dl_dcch_msg.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8());
/* Prepare Handover Command to be sent via S1AP */
ho_cmd_pdu = srslte::allocate_unique_buffer(*f->pool);
asn1::bit_ref bref2{ho_cmd_pdu->msg, ho_cmd_pdu->get_tailroom()};
if (dl_dcch_msg.pack(bref2) != asn1::SRSASN_SUCCESS) {
f->rrc_log->error("Failed to pack HandoverCommand\n");
f->trigger(srslte::failure_ev{});
return;
}
ho_cmd_pdu->N_bytes = bref2.distance_bytes();
f->rrc_enb->log_rrc_message("RRC container", direction_t::S1AP, ho_cmd_pdu.get(), dl_dcch_msg, "HandoverCommand");
asn1::rrc::ho_cmd_s ho_cmd;
asn1::rrc::ho_cmd_r8_ies_s& ho_cmd_r8 = ho_cmd.crit_exts.set_c1().set_ho_cmd_r8();
ho_cmd_r8.ho_cmd_msg.resize(bref2.distance_bytes());
memcpy(ho_cmd_r8.ho_cmd_msg.data(), ho_cmd_pdu->msg, bref2.distance_bytes());
bref2 = {ho_cmd_pdu->msg, ho_cmd_pdu->get_tailroom()};
if (ho_cmd.pack(bref2) != asn1::SRSASN_SUCCESS) {
f->rrc_log->error("Failed to pack HandoverCommand\n");
f->trigger(srslte::failure_ev{});
return;
}
ho_cmd_pdu->N_bytes = bref2.distance_bytes();
}
void rrc::ue::rrc_mobility::handle_recfg_complete(s1_target_ho_st& s, const recfg_complete_ev& ev)
@ -1143,9 +1154,6 @@ void rrc::ue::rrc_mobility::handle_recfg_complete(s1_target_ho_st& s, const recf
target_cell->cell_common->cell_cfg.cell_id);
uint64_t target_eci = (rrc_enb->cfg.enb_id << 8u) + target_cell->cell_common->cell_cfg.cell_id;
// Activate bearers in MAC
rrc_ue->mac_ctrl->handle_ho_prep_complete();
rrc_enb->s1ap->send_ho_notify(rrc_ue->rnti, target_eci);
}

@ -978,6 +978,8 @@ void rrc::ue::notify_s1ap_ue_erab_setup_response(const asn1::s1ap::erab_to_be_se
parent->s1ap->ue_erab_setup_complete(rnti, res);
}
void rrc::ue::set_erab_status(const asn1::s1ap::bearers_subject_to_status_transfer_item_s& erab) {}
//! Helper method to access Cell configuration based on UE Carrier Index
cell_info_common* rrc::ue::get_ue_cc_cfg(uint32_t ue_cc_idx)
{

@ -577,6 +577,8 @@ bool s1ap::handle_initiatingmessage(const init_msg_s& msg)
}
return outcome;
}
case s1ap_elem_procs_o::init_msg_c::types_opts::mme_status_transfer:
return handle_mme_status_transfer(msg.value.mme_status_transfer());
default:
s1ap_log->error("Unhandled initiating message: %s\n", msg.value.type().to_string().c_str());
}
@ -917,6 +919,24 @@ bool s1ap::send_ho_req_ack(const asn1::s1ap::ho_request_s& msg,
return sctp_send_s1ap_pdu(tx_pdu, rnti, "HandoverRequestAcknowledge");
}
bool s1ap::handle_mme_status_transfer(const asn1::s1ap::mme_status_transfer_s& msg)
{
s1ap_log->info("Received S1 MMEStatusTransfer\n");
s1ap_log->console("Received S1 MMEStatusTransfer\n");
ue* u = find_s1apmsg_user(msg.protocol_ies.enb_ue_s1ap_id.value.value, msg.protocol_ies.mme_ue_s1ap_id.value.value);
if (u == nullptr) {
return false;
}
for (const auto& bearer :
msg.protocol_ies.enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list) {
const auto& bearer_item = bearer.value.bearers_subject_to_status_transfer_item();
rrc->set_erab_status(u->ctxt.rnti, bearer_item);
}
return true;
}
void s1ap::send_ho_notify(uint16_t rnti, uint64_t target_eci)
{
ue* user_ptr = users.find_ue_rnti(rnti);

@ -278,6 +278,13 @@ struct mobility_tester {
int run_preamble()
{
rrc_log->set_level(srslte::LOG_LEVEL_NONE); // mute all the startup log
// add user
sched_interface::ue_cfg_t ue_cfg{};
ue_cfg.supported_cc_list.resize(1);
ue_cfg.supported_cc_list[0].enb_cc_idx = 0;
ue_cfg.supported_cc_list[0].active = true;
rrc.add_user(rnti, ue_cfg);
// Do all the handshaking until the first RRC Connection Reconf
test_helpers::bring_rrc_to_reconf_state(rrc, *task_sched.get_timer_handler(), rnti);
rrc_log->set_level(srslte::LOG_LEVEL_INFO);
@ -322,13 +329,6 @@ protected:
int setup_rrc_common()
{
rrc.init(cfg, &phy, &mac, &rlc, &pdcp, &s1ap, &gtpu);
// add user
sched_interface::ue_cfg_t ue_cfg;
ue_cfg.supported_cc_list.resize(1);
ue_cfg.supported_cc_list[0].enb_cc_idx = 0;
ue_cfg.supported_cc_list[0].active = true;
rrc.add_user(rnti, ue_cfg);
return SRSLTE_SUCCESS;
}
};
@ -446,6 +446,82 @@ int test_s1ap_mobility(mobility_test_params test_params)
return SRSLTE_SUCCESS;
}
int test_s1ap_tenb_mobility(mobility_test_params test_params)
{
printf("\n===== TEST: test_s1ap_tenb_mobility() for event %s =====\n", test_params.to_string());
s1ap_mobility_tester tester{test_params};
srslte::unique_byte_buffer_t pdu;
TESTASSERT(tester.generate_rrc_cfg() == SRSLTE_SUCCESS);
tester.cfg.cell_list[0].meas_cfg.meas_cells[0].eci = 0x19B01;
tester.cfg.enb_id = 0x19C;
tester.cfg.cell.id = 0x02;
tester.cfg.cell_list[0].cell_id = 0x02;
tester.cfg.cell_list[0].pci = 2;
TESTASSERT(tester.setup_rrc() == SRSLTE_SUCCESS);
/* Receive S1AP Handover Request */
asn1::s1ap::ho_request_s ho_req;
ho_req.protocol_ies.erab_to_be_setup_list_ho_req.value.resize(1);
auto& erab = ho_req.protocol_ies.erab_to_be_setup_list_ho_req.value[0].value.erab_to_be_setup_item_ho_req();
erab.erab_id = 5;
erab.erab_level_qos_params.qci = 9;
asn1::s1ap::sourceenb_to_targetenb_transparent_container_s container;
container.target_cell_id.cell_id.from_number(0x19C02);
uint8_t ho_prep_container[] = {
0x0a, 0x10, 0x0b, 0x81, 0x80, 0x00, 0x01, 0x80, 0x00, 0xf3, 0x02, 0x08, 0x00, 0x00, 0x15, 0x80, 0x00, 0x14,
0x06, 0xa4, 0x02, 0xf0, 0x04, 0x04, 0xf0, 0x00, 0x14, 0x80, 0x4a, 0x00, 0x00, 0x00, 0x02, 0x12, 0x31, 0xb6,
0xf8, 0x3e, 0xa0, 0x6f, 0x05, 0xe4, 0x65, 0x14, 0x1d, 0x39, 0xd0, 0x54, 0x4c, 0x00, 0x02, 0x54, 0x00, 0x20,
0x04, 0x60, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x00, 0x04, 0x14,
0x00, 0x67, 0x0d, 0xfb, 0xc4, 0x66, 0x06, 0x50, 0x0f, 0x00, 0x08, 0x00, 0x20, 0x80, 0x0c, 0x14, 0xca, 0x2d,
0x5c, 0xe1, 0x86, 0x35, 0x39, 0x80, 0x0e, 0x06, 0xa4, 0x40, 0x0f, 0x22, 0x78};
// 0a100b818000018000f3020800001580001406a402f00404f00014804a000000021231b6f83ea06f05e465141d39d0544c00025400200460000000100100c000000000020500041400670dfbc46606500f00080020800c14ca2d5ce1863539800e06a4400f2278
container.rrc_container.resize(sizeof(ho_prep_container));
memcpy(container.rrc_container.data(), ho_prep_container, sizeof(ho_prep_container));
pdu = srslte::allocate_unique_buffer(*srslte::byte_buffer_pool::get_instance());
std::vector<asn1::fixed_octstring<4, true> > admitted_erabs;
tester.rrc.start_ho_ue_resource_alloc(ho_req, container, *pdu, admitted_erabs);
tester.tic();
TESTASSERT(tester.rrc.get_nof_users() == 1);
TESTASSERT(tester.mac.ue_db.count(0x46));
auto& mac_ue = tester.mac.ue_db[0x46];
TESTASSERT(mac_ue.supported_cc_list[0].active);
TESTASSERT(mac_ue.supported_cc_list[0].enb_cc_idx == 0);
TESTASSERT(mac_ue.ue_bearers[rb_id_t::RB_ID_SRB0].direction == sched_interface::ue_bearer_cfg_t::BOTH);
ho_cmd_s ho_cmd;
asn1::cbit_ref bref{pdu->msg, pdu->N_bytes};
TESTASSERT(ho_cmd.unpack(bref) == asn1::SRSASN_SUCCESS);
bref = asn1::cbit_ref{ho_cmd.crit_exts.c1().ho_cmd_r8().ho_cmd_msg.data(),
ho_cmd.crit_exts.c1().ho_cmd_r8().ho_cmd_msg.size()};
dl_dcch_msg_s dl_dcch_msg;
TESTASSERT(dl_dcch_msg.unpack(bref) == asn1::SRSASN_SUCCESS);
auto& recfg_r8 = dl_dcch_msg.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8();
TESTASSERT(recfg_r8.rr_cfg_ded.phys_cfg_ded.sched_request_cfg.setup().sr_cfg_idx == 15);
TESTASSERT(recfg_r8.rr_cfg_ded.phys_cfg_ded.sched_request_cfg.setup().sr_pucch_res_idx == 0);
// user PRACHs and sends C-RNTI CE
sched_interface::ue_cfg_t ue_cfg{};
ue_cfg.supported_cc_list.resize(1);
ue_cfg.supported_cc_list[0].enb_cc_idx = 0;
ue_cfg.supported_cc_list[0].active = true;
tester.rrc.add_user(0x47, ue_cfg);
tester.rrc.upd_user(0x47, 0x46);
uint8_t recfg_complete[] = {0x10, 0x00};
test_helpers::copy_msg_to_buffer(pdu, recfg_complete);
tester.rrc.write_pdu(0x46, rb_id_t::RB_ID_SRB1, std::move(pdu));
tester.tic();
TESTASSERT(mac_ue.ue_bearers[rb_id_t::RB_ID_SRB1].direction == sched_interface::ue_bearer_cfg_t::BOTH);
TESTASSERT(mac_ue.ue_bearers[rb_id_t::RB_ID_SRB2].direction == sched_interface::ue_bearer_cfg_t::BOTH);
TESTASSERT(mac_ue.ue_bearers[rb_id_t::RB_ID_DRB1].direction == sched_interface::ue_bearer_cfg_t::BOTH);
TESTASSERT(mac_ue.pucch_cfg.I_sr == recfg_r8.rr_cfg_ded.phys_cfg_ded.sched_request_cfg.setup().sr_cfg_idx);
TESTASSERT(mac_ue.pucch_cfg.n_pucch_sr ==
recfg_r8.rr_cfg_ded.phys_cfg_ded.sched_request_cfg.setup().sr_pucch_res_idx);
return SRSLTE_SUCCESS;
}
int test_intraenb_mobility(mobility_test_params test_params)
{
printf("\n===== TEST: test_intraenb_mobility() for event %s =====\n", test_params.to_string());
@ -574,6 +650,8 @@ int main(int argc, char** argv)
TESTASSERT(test_s1ap_mobility(mobility_test_params{event::ho_prep_failure}) == 0);
TESTASSERT(test_s1ap_mobility(mobility_test_params{event::success}) == 0);
TESTASSERT(test_s1ap_tenb_mobility(mobility_test_params{event::success}) == 0);
// intraeNB Handover
TESTASSERT(test_intraenb_mobility(mobility_test_params{event::wrong_measreport}) == 0);
TESTASSERT(test_intraenb_mobility(mobility_test_params{event::concurrent_ho}) == 0);

Loading…
Cancel
Save