fix drb reestablishment during handover

master
Francisco Paisana 4 years ago
parent 7bf196a6e0
commit f26b5ccde7

@ -105,6 +105,17 @@ typename Container::iterator add_rrc_obj(Container& c, const typename Container:
return it;
}
template <typename Container, typename IdType>
bool rem_rrc_obj_id(Container& c, IdType id)
{
auto it = sorted_find_rrc_obj_id(c, id);
if (it != c.end()) {
c.erase(it);
return true;
}
return false;
}
/**
* Find rrc obj id gap in list of rrc objs (e.g. {1, 2, 4} -> 3)
* Expects list to be sorted
@ -234,6 +245,21 @@ void compute_cfg_diff(const toAddModList& src_list,
toAddModList& add_diff_list,
RemoveList& rem_diff_list)
{
if (&src_list == &target_list) {
// early exit
return;
} else if (&src_list == &add_diff_list) {
// use const src_list
toAddModList src_list2 = src_list;
compute_cfg_diff(src_list2, target_list, add_diff_list, rem_diff_list);
return;
} else if (&target_list == &add_diff_list) {
// use const target_list
toAddModList target_list2 = target_list;
compute_cfg_diff(src_list, target_list2, add_diff_list, rem_diff_list);
return;
}
using it_t = typename toAddModList::const_iterator;
auto rem_func = [&rem_diff_list](it_t rem_it) { rem_diff_list.push_back(asn1::rrc::get_rrc_obj_id(*rem_it)); };
auto add_func = [&add_diff_list](it_t add_it) { add_diff_list.push_back(*add_it); };

@ -77,10 +77,6 @@ public:
const asn1::unbounded_octstring<true>* nas_pdu);
void release_erab(uint8_t erab_id);
void release_erabs();
void reest_bearers();
bool fill_rr_cfg_ded(asn1::rrc::rr_cfg_ded_s& msg);
void rr_ded_cfg_complete();
// Methods to apply bearer updates
void add_gtpu_bearer(gtpu_interface_rrc* gtpu, uint32_t erab_id);
@ -88,8 +84,6 @@ public:
const std::map<uint8_t, erab_t>& get_erabs() const { return erabs; }
const asn1::rrc::drb_to_add_mod_list_l& get_established_drbs() const { return current_drbs; }
const asn1::rrc::drb_to_add_mod_list_l& get_pending_addmod_drbs() const { return drbs_to_add; }
srslte::span<const uint8_t> get_pending_rem_drbs() const { return drbs_to_release; }
std::map<uint8_t, std::vector<uint8_t> > erab_info_list;
std::map<uint8_t, erab_t> erabs;
@ -101,10 +95,6 @@ private:
// last cfg
asn1::rrc::drb_to_add_mod_list_l current_drbs;
// pending cfg updates
asn1::rrc::drb_to_add_mod_list_l drbs_to_add;
asn1::rrc::drb_to_release_list_l drbs_to_release;
};
} // namespace srsenb

@ -56,6 +56,8 @@ sched_interface::ue_bearer_cfg_t get_bearer_default_srb2_config()
return bearer;
}
void ue_cfg_apply_srb_updates(ue_cfg_t& ue_cfg, const srb_to_add_mod_list_l& srbs);
/**
* Adds to sched_interface::ue_cfg_t the changes present in the asn1 RRCReconfiguration message that should
* only take effect after the RRCReconfigurationComplete is received
@ -266,6 +268,9 @@ void rrc::ue::mac_controller::handle_intraenb_ho_cmd(const asn1::rrc::rrc_conn_r
void rrc::ue::mac_controller::handle_ho_prep(const asn1::rrc::ho_prep_info_r8_ies_s& ho_prep)
{
// TODO: Apply configuration in ho_prep as a base
if (ho_prep.as_cfg.source_rr_cfg.srb_to_add_mod_list_present) {
ue_cfg_apply_srb_updates(current_sched_ue_cfg, ho_prep.as_cfg.source_rr_cfg.srb_to_add_mod_list);
}
}
void rrc::ue::mac_controller::set_scell_activation(const std::bitset<SRSLTE_MAX_CARRIERS>& scell_mask)
@ -328,6 +333,37 @@ void ue_cfg_apply_phy_cfg_ded(ue_cfg_t& ue_cfg, const asn1::rrc::phys_cfg_ded_s&
}
}
void ue_cfg_apply_srb_updates(ue_cfg_t& ue_cfg, const srb_to_add_mod_list_l& srbs)
{
for (const srb_to_add_mod_s& srb : srbs) {
auto& bcfg = ue_cfg.ue_bearers[srb.srb_id];
switch (srb.srb_id) {
case 1:
bcfg = get_bearer_default_srb1_config();
break;
case 2:
bcfg = get_bearer_default_srb2_config();
break;
default:
srslte::logmap::get("RRC")->warning("Invalid SRB ID %d\n", (int)srb.srb_id);
bcfg = {};
}
bcfg.direction = srsenb::sched_interface::ue_bearer_cfg_t::BOTH;
if (srb.lc_ch_cfg_present and
srb.lc_ch_cfg.type().value == srb_to_add_mod_s::lc_ch_cfg_c_::types_opts::explicit_value and
srb.lc_ch_cfg.explicit_value().ul_specific_params_present) {
// NOTE: Use UL values for DL prioritization as well
auto& ul_params = srb.lc_ch_cfg.explicit_value().ul_specific_params;
bcfg.pbr = ul_params.prioritised_bit_rate.to_number();
bcfg.priority = ul_params.prio;
bcfg.bsd = ul_params.bucket_size_dur.to_number();
if (ul_params.lc_ch_group_present) {
bcfg.group = ul_params.lc_ch_group;
}
}
}
}
void ue_cfg_apply_reconf_complete_updates(ue_cfg_t& ue_cfg,
const rrc_conn_recfg_r8_ies_s& conn_recfg,
const cell_ctxt_dedicated_list& ue_cell_list)
@ -353,33 +389,7 @@ void ue_cfg_apply_reconf_complete_updates(ue_cfg_t& ue_cfg
// Apply SRB updates
if (conn_recfg.rr_cfg_ded.srb_to_add_mod_list_present) {
for (const srb_to_add_mod_s& srb : conn_recfg.rr_cfg_ded.srb_to_add_mod_list) {
auto& bcfg = ue_cfg.ue_bearers[srb.srb_id];
switch (srb.srb_id) {
case 1:
bcfg = get_bearer_default_srb1_config();
break;
case 2:
bcfg = get_bearer_default_srb2_config();
break;
default:
srslte::logmap::get("RRC")->warning("Invalid SRB ID %d\n", (int)srb.srb_id);
bcfg = {};
}
bcfg.direction = srsenb::sched_interface::ue_bearer_cfg_t::BOTH;
if (srb.lc_ch_cfg_present and
srb.lc_ch_cfg.type().value == srb_to_add_mod_s::lc_ch_cfg_c_::types_opts::explicit_value and
srb.lc_ch_cfg.explicit_value().ul_specific_params_present) {
// NOTE: Use UL values for DL prioritization as well
auto& ul_params = srb.lc_ch_cfg.explicit_value().ul_specific_params;
bcfg.pbr = ul_params.prioritised_bit_rate.to_number();
bcfg.priority = ul_params.prio;
bcfg.bsd = ul_params.bucket_size_dur.to_number();
if (ul_params.lc_ch_group_present) {
bcfg.group = ul_params.lc_ch_group;
}
}
}
ue_cfg_apply_srb_updates(ue_cfg, conn_recfg.rr_cfg_ded.srb_to_add_mod_list);
}
}

@ -250,7 +250,7 @@ int bearer_cfg_handler::add_erab(uint8_t
}
// Set DRBtoAddMod
auto drb_it = srslte::add_rrc_obj_id(drbs_to_add, drbid);
auto drb_it = srslte::add_rrc_obj_id(current_drbs, drbid);
drb_it->lc_ch_id_present = true;
drb_it->lc_ch_id = (uint8_t)lcid;
drb_it->eps_bearer_id_present = true;
@ -276,7 +276,8 @@ void bearer_cfg_handler::release_erab(uint8_t erab_id)
}
uint8_t drb_id = erab_id - 4;
drbs_to_release.push_back(drb_id);
srslte::rem_rrc_obj_id(current_drbs, drb_id);
erabs.erase(it);
erab_info_list.erase(erab_id);
@ -291,32 +292,6 @@ void bearer_cfg_handler::release_erabs()
}
}
void bearer_cfg_handler::reest_bearers()
{
// Re-add all SRBs/DRBs
drbs_to_add = current_drbs;
}
void bearer_cfg_handler::rr_ded_cfg_complete()
{
// Apply changes in internal bearer_handler DRB/SRBtoAddModLists
srslte::apply_addmodremlist_diff(current_drbs, drbs_to_add, drbs_to_release, current_drbs);
// Reset DRBs/SRBs to Add/mod/release
drbs_to_add = {};
drbs_to_release.resize(0);
}
bool bearer_cfg_handler::fill_rr_cfg_ded(asn1::rrc::rr_cfg_ded_s& msg)
{
// Add altered bearers to message
msg.drb_to_add_mod_list_present = drbs_to_add.size() > 0;
msg.drb_to_add_mod_list = drbs_to_add;
msg.drb_to_release_list_present = drbs_to_release.size() > 0;
msg.drb_to_release_list = drbs_to_release;
return msg.srb_to_add_mod_list_present or msg.drb_to_add_mod_list_present or msg.drb_to_release_list_present;
}
void bearer_cfg_handler::add_gtpu_bearer(srsenb::gtpu_interface_rrc* gtpu, uint32_t erab_id)
{
auto it = erabs.find(erab_id);

@ -1153,17 +1153,17 @@ void rrc::ue::rrc_mobility::handle_ho_req(idle_st& s, const ho_req_rx_ev& ho_req
}
ho_cmd_pdu->N_bytes = bref2.distance_bytes();
apply_rr_cfg_ded_diff(rrc_ue->current_rr_cfg, recfg_r8.rr_cfg_ded);
/* Configure remaining layers based on pending changes */
// Update RLC + PDCP SRBs (no DRBs until MME Status Transfer)
rrc_ue->apply_pdcp_srb_updates(recfg_r8.rr_cfg_ded);
rrc_ue->apply_rlc_rb_updates(recfg_r8.rr_cfg_ded);
rrc_ue->apply_pdcp_srb_updates(rrc_ue->current_rr_cfg);
rrc_ue->apply_rlc_rb_updates(rrc_ue->current_rr_cfg);
// Update MAC
rrc_ue->mac_ctrl->handle_target_enb_ho_cmd(recfg_r8);
// Apply PHY updates
rrc_ue->apply_reconf_phy_config(recfg_r8, true);
apply_rr_cfg_ded_diff(rrc_ue->current_rr_cfg, recfg_r8.rr_cfg_ded);
/* send S1AP HandoverRequestAcknowledge */
std::vector<asn1::fixed_octstring<4, true> > admitted_erabs;
for (auto& erab : rrc_ue->bearer_list.get_erabs()) {
@ -1232,6 +1232,9 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& ho
}
}
// Save source eNB UE RR cfg as a starting point
apply_rr_cfg_ded_diff(rrc_ue->current_rr_cfg, ho_prep.as_cfg.source_rr_cfg);
// Save source UE MAC configuration as a base
rrc_ue->mac_ctrl->handle_ho_prep(ho_prep);
@ -1266,7 +1269,7 @@ void rrc::ue::rrc_mobility::handle_status_transfer(s1_target_ho_st& s, const sta
rrc_log->warning("The E-RAB Id=%d is not recognized\n", erab_item.erab_id);
continue;
}
const auto& drbs = rrc_ue->bearer_list.get_pending_addmod_drbs();
const auto& drbs = rrc_ue->bearer_list.get_established_drbs();
uint8_t drbid = erab_item.erab_id - 4;
auto drb_it =
std::find_if(drbs.begin(), drbs.end(), [drbid](const drb_to_add_mod_s& drb) { return drb.drb_id == drbid; });
@ -1363,7 +1366,6 @@ void rrc::ue::rrc_mobility::handle_crnti_ce(intraenb_ho_st& s, const user_crnti_
rrc_enb->phy->set_config(rrc_ue->rnti, rrc_ue->phy_rrc_dedicated_list);
rrc_ue->ue_security_cfg.regenerate_keys_handover(s.target_cell->cell_cfg.pci, s.target_cell->cell_cfg.dl_earfcn);
rrc_ue->bearer_list.reest_bearers();
rrc_ue->apply_pdcp_srb_updates(rrc_ue->current_rr_cfg);
rrc_ue->apply_pdcp_drb_updates(rrc_ue->current_rr_cfg);
} else {

@ -290,9 +290,6 @@ void rrc::ue::handle_rrc_con_setup_complete(rrc_conn_setup_complete_s* msg, srsl
pdu->N_bytes = msg_r8->ded_info_nas.size();
memcpy(pdu->msg, msg_r8->ded_info_nas.data(), pdu->N_bytes);
// Flag completion of RadioResource Configuration
bearer_list.rr_ded_cfg_complete();
// Signal MAC scheduler that configuration was successful
mac_ctrl->handle_con_setup_complete();
@ -434,9 +431,6 @@ void rrc::ue::handle_rrc_con_reest_complete(rrc_conn_reest_complete_s* msg, srsl
parent->gtpu->mod_bearer_rnti(old_reest_rnti, rnti);
parent->s1ap->user_mod(old_reest_rnti, rnti);
// Flag completion of RadioResource Configuration
bearer_list.rr_ded_cfg_complete();
// Signal MAC scheduler that configuration was successful
mac_ctrl->handle_con_reest_complete();
@ -604,7 +598,13 @@ void rrc::ue::send_connection_reconf_new_bearer()
dl_dcch_msg.msg.c1().rrc_conn_recfg().rrc_transaction_id = (uint8_t)((transaction_id++) % 4);
rrc_conn_recfg_r8_ies_s* conn_reconf = &dl_dcch_msg.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8();
conn_reconf->rr_cfg_ded_present = bearer_list.fill_rr_cfg_ded(conn_reconf->rr_cfg_ded);
fill_rr_cfg_ded_reconf(conn_reconf->rr_cfg_ded,
current_rr_cfg,
parent->cfg,
cell_ded_list,
bearer_list,
ue_capabilities,
reconf_cause::other);
// Setup new bearer
apply_pdcp_srb_updates(conn_reconf->rr_cfg_ded);
@ -616,6 +616,8 @@ void rrc::ue::send_connection_reconf_new_bearer()
if (conn_reconf->rr_cfg_ded_present or conn_reconf->ded_info_nas_list_present) {
send_dl_dcch(&dl_dcch_msg);
}
apply_rr_cfg_ded_diff(current_rr_cfg, conn_reconf->rr_cfg_ded);
}
void rrc::ue::handle_rrc_reconf_complete(rrc_conn_recfg_complete_s* msg, srslte::unique_byte_buffer_t pdu)
@ -624,9 +626,6 @@ void rrc::ue::handle_rrc_reconf_complete(rrc_conn_recfg_complete_s* msg, srslte:
parent->phy->complete_config(rnti);
if (last_rrc_conn_recfg.rrc_transaction_id == msg->rrc_transaction_id) {
// Flag completion of RadioResource Configuration
bearer_list.rr_ded_cfg_complete();
// Activate SCells and bearers in the MAC scheduler that were advertised in the RRC Reconf message
mac_ctrl->handle_con_reconf_complete();

@ -335,7 +335,7 @@ void fill_rr_cfg_ded_reconf(asn1::rrc::rr_cfg_ded_s& rr_cfg,
// Update DRBs if required
srslte::compute_cfg_diff(current_rr_cfg.drb_to_add_mod_list,
bearers.get_pending_addmod_drbs(),
bearers.get_established_drbs(),
rr_cfg.drb_to_add_mod_list,
rr_cfg.drb_to_release_list);
rr_cfg.drb_to_add_mod_list_present = rr_cfg.drb_to_add_mod_list.size() > 0;

Loading…
Cancel
Save