fix RRC Connection Reestablishment procedure - correctly save old rnti bearer configuration in new rnti

This commit is contained in:
Francisco 2021-03-02 15:58:24 +00:00 committed by Francisco Paisana
parent 290f39d805
commit c03dbc6742
5 changed files with 33 additions and 35 deletions

View File

@ -107,7 +107,7 @@ public:
std::map<uint8_t, erab_t> erabs; std::map<uint8_t, erab_t> erabs;
private: private:
srslog::basic_logger& logger; srslog::basic_logger* logger;
uint16_t rnti = 0; uint16_t rnti = 0;
const rrc_cfg_t* cfg = nullptr; const rrc_cfg_t* cfg = nullptr;
gtpu_interface_rrc* gtpu = nullptr; gtpu_interface_rrc* gtpu = nullptr;

View File

@ -201,7 +201,7 @@ void security_cfg_handler::regenerate_keys_handover(uint32_t new_pci, uint32_t n
****************************/ ****************************/
bearer_cfg_handler::bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_, gtpu_interface_rrc* gtpu_) : bearer_cfg_handler::bearer_cfg_handler(uint16_t rnti_, const rrc_cfg_t& cfg_, gtpu_interface_rrc* gtpu_) :
rnti(rnti_), cfg(&cfg_), gtpu(gtpu_), logger(srslog::fetch_basic_logger("RRC")) rnti(rnti_), cfg(&cfg_), gtpu(gtpu_), logger(&srslog::fetch_basic_logger("RRC"))
{} {}
int bearer_cfg_handler::add_erab(uint8_t erab_id, int bearer_cfg_handler::add_erab(uint8_t erab_id,
@ -211,7 +211,7 @@ int bearer_cfg_handler::add_erab(uint8_t
const asn1::unbounded_octstring<true>* nas_pdu) const asn1::unbounded_octstring<true>* nas_pdu)
{ {
if (erab_id < 5) { if (erab_id < 5) {
logger.error("ERAB id=%d is invalid", erab_id); logger->error("ERAB id=%d is invalid", erab_id);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
uint8_t lcid = erab_id - 2; // Map e.g. E-RAB 5 to LCID 3 (==DRB1) uint8_t lcid = erab_id - 2; // Map e.g. E-RAB 5 to LCID 3 (==DRB1)
@ -219,11 +219,11 @@ int bearer_cfg_handler::add_erab(uint8_t
auto qci_it = cfg->qci_cfg.find(qos.qci); auto qci_it = cfg->qci_cfg.find(qos.qci);
if (qci_it == cfg->qci_cfg.end() or not qci_it->second.configured) { if (qci_it == cfg->qci_cfg.end() or not qci_it->second.configured) {
logger.error("QCI=%d not configured", qos.qci); logger->error("QCI=%d not configured", qos.qci);
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (lcid < 3 or lcid > 10) { if (lcid < 3 or lcid > 10) {
logger.error("DRB logical channel ids must be within 3 and 10"); logger->error("DRB logical channel ids must be within 3 and 10");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
const rrc_cfg_qci_t& qci_cfg = qci_it->second; const rrc_cfg_qci_t& qci_cfg = qci_it->second;
@ -234,13 +234,13 @@ int bearer_cfg_handler::add_erab(uint8_t
erabs[erab_id].teid_out = teid_out; erabs[erab_id].teid_out = teid_out;
if (addr.length() > 32) { if (addr.length() > 32) {
logger.error("Only addresses with length <= 32 are supported"); logger->error("Only addresses with length <= 32 are supported");
return SRSLTE_ERROR; return SRSLTE_ERROR;
} }
if (nas_pdu != nullptr and nas_pdu->size() > 0) { if (nas_pdu != nullptr and nas_pdu->size() > 0) {
erab_info_list[erab_id].assign(nas_pdu->data(), nas_pdu->data() + nas_pdu->size()); erab_info_list[erab_id].assign(nas_pdu->data(), nas_pdu->data() + nas_pdu->size());
logger.info( logger->info(
&erab_info_list[erab_id][0], erab_info_list[erab_id].size(), "setup_erab nas_pdu -> erab_info rnti 0x%x", rnti); &erab_info_list[erab_id][0], erab_info_list[erab_id].size(), "setup_erab nas_pdu -> erab_info rnti 0x%x", rnti);
} }
@ -266,7 +266,7 @@ bool bearer_cfg_handler::release_erab(uint8_t erab_id)
{ {
auto it = erabs.find(erab_id); auto it = erabs.find(erab_id);
if (it == erabs.end()) { if (it == erabs.end()) {
logger.warning("The user rnti=0x%x does not contain ERAB-ID=%d", rnti, erab_id); logger->warning("The user rnti=0x%x does not contain ERAB-ID=%d", rnti, erab_id);
return false; return false;
} }
@ -293,10 +293,10 @@ bool bearer_cfg_handler::modify_erab(uint8_t
const asn1::s1ap::erab_level_qos_params_s& qos, const asn1::s1ap::erab_level_qos_params_s& qos,
const asn1::unbounded_octstring<true>* nas_pdu) const asn1::unbounded_octstring<true>* nas_pdu)
{ {
logger.info("Modifying E-RAB %d", erab_id); logger->info("Modifying E-RAB %d", erab_id);
std::map<uint8_t, erab_t>::iterator erab_it = erabs.find(erab_id); std::map<uint8_t, erab_t>::iterator erab_it = erabs.find(erab_id);
if (erab_it == erabs.end()) { if (erab_it == erabs.end()) {
logger.error("Could not find E-RAB to modify"); logger->error("Could not find E-RAB to modify");
return false; return false;
} }
auto address = erab_it->second.address; auto address = erab_it->second.address;
@ -310,7 +310,7 @@ void bearer_cfg_handler::add_gtpu_bearer(uint32_t erab_id)
{ {
auto it = erabs.find(erab_id); auto it = erabs.find(erab_id);
if (it == erabs.end()) { if (it == erabs.end()) {
logger.error("Adding erab_id=%d to GTPU", erab_id); logger->error("Adding erab_id=%d to GTPU", erab_id);
return; return;
} }
it->second.teid_in = add_gtpu_bearer(erab_id, it->second.teid_out, it->second.address.to_number(), nullptr); it->second.teid_in = add_gtpu_bearer(erab_id, it->second.teid_out, it->second.address.to_number(), nullptr);
@ -323,7 +323,7 @@ uint32_t bearer_cfg_handler::add_gtpu_bearer(uint32_t
{ {
auto it = erabs.find(erab_id); auto it = erabs.find(erab_id);
if (it == erabs.end()) { if (it == erabs.end()) {
logger.error("Adding erab_id=%d to GTPU", erab_id); logger->error("Adding erab_id=%d to GTPU", erab_id);
return 0; return 0;
} }
@ -344,7 +344,7 @@ void bearer_cfg_handler::rem_gtpu_bearer(uint32_t erab_id)
// Map e.g. E-RAB 5 to LCID 3 (==DRB1) // Map e.g. E-RAB 5 to LCID 3 (==DRB1)
gtpu->rem_bearer(rnti, erab_id - 2); gtpu->rem_bearer(rnti, erab_id - 2);
} else { } else {
logger.error("Removing erab_id=%d to GTPU\n", erab_id); logger->error("Removing erab_id=%d to GTPU\n", erab_id);
} }
} }
@ -366,12 +366,12 @@ void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_
auto it = erab_info_list.find(erab_id); auto it = erab_info_list.find(erab_id);
if (it != erab_info_list.end()) { if (it != erab_info_list.end()) {
const std::vector<uint8_t>& erab_info = it->second; const std::vector<uint8_t>& erab_info = it->second;
logger.info(&erab_info[0], erab_info.size(), "connection_reconf erab_info -> nas_info rnti 0x%x", rnti); logger->info(&erab_info[0], erab_info.size(), "connection_reconf erab_info -> nas_info rnti 0x%x", rnti);
msg->ded_info_nas_list[idx].resize(erab_info.size()); msg->ded_info_nas_list[idx].resize(erab_info.size());
memcpy(msg->ded_info_nas_list[idx].data(), &erab_info[0], erab_info.size()); memcpy(msg->ded_info_nas_list[idx].data(), &erab_info[0], erab_info.size());
erab_info_list.erase(it); erab_info_list.erase(it);
} else { } else {
logger.debug("Not adding NAS message to connection reconfiguration. E-RAB id %d", erab_id); logger->debug("Not adding NAS message to connection reconfiguration. E-RAB id %d", erab_id);
} }
idx++; idx++;
} }

View File

@ -743,7 +743,7 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev&
std::vector<asn1::s1ap::erab_admitted_item_s> admitted_erabs; std::vector<asn1::s1ap::erab_admitted_item_s> admitted_erabs;
auto& fwd_tunnels = get_state<s1_target_ho_st>()->pending_tunnels; auto& fwd_tunnels = get_state<s1_target_ho_st>()->pending_tunnels;
fwd_tunnels.clear(); fwd_tunnels.clear();
for (auto& erab : rrc_ue->bearer_list.get_erabs()) { for (const auto& erab : rrc_ue->bearer_list.get_erabs()) {
admitted_erabs.emplace_back(); admitted_erabs.emplace_back();
asn1::s1ap::erab_admitted_item_s& admitted_erab = admitted_erabs.back(); asn1::s1ap::erab_admitted_item_s& admitted_erab = admitted_erabs.back();
admitted_erab.erab_id = erab.second.id; admitted_erab.erab_id = erab.second.id;
@ -907,9 +907,9 @@ void rrc::ue::rrc_mobility::handle_status_transfer(s1_target_ho_st& s, const sta
rrc_enb->pdcp->set_bearer_state(rrc_ue->rnti, drb_it->lc_ch_id, drb_state); rrc_enb->pdcp->set_bearer_state(rrc_ue->rnti, drb_it->lc_ch_id, drb_state);
} }
// Enable forwarding of GTPU SDUs to PDCP // Enable forwarding of GTPU SDUs coming from Source eNB Tunnel to PDCP
for (auto& erab : rrc_ue->bearer_list.get_erabs()) { for (uint32_t teid : s.pending_tunnels) {
rrc_enb->gtpu->set_tunnel_status(erab.second.teid_in, true); rrc_enb->gtpu->set_tunnel_status(teid, true);
} }
// Check if there is any pending Reconfiguration Complete. If there is, self-trigger // Check if there is any pending Reconfiguration Complete. If there is, self-trigger

View File

@ -516,10 +516,7 @@ void rrc::ue::handle_rrc_con_reest_complete(rrc_conn_reest_complete_s* msg, srsl
parent->pdcp->enable_encryption(rnti, RB_ID_SRB1); parent->pdcp->enable_encryption(rnti, RB_ID_SRB1);
// Reestablish current DRBs during ConnectionReconfiguration // Reestablish current DRBs during ConnectionReconfiguration
for (const auto& erab_pair : parent->users.at(old_reest_rnti)->bearer_list.get_erabs()) { bearer_list = std::move(parent->users.at(old_reest_rnti)->bearer_list);
const bearer_cfg_handler::erab_t& erab = erab_pair.second;
bearer_list.add_erab(erab.id, erab.qos_params, erab.address, erab.teid_out, nullptr);
}
// remove old RNTI // remove old RNTI
parent->rem_user_thread(old_reest_rnti); parent->rem_user_thread(old_reest_rnti);

View File

@ -142,22 +142,23 @@ void gtpu::send_pdu_to_tunnel(tunnel& tx_tun, srslte::unique_byte_buffer_t pdu,
uint32_t gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, const bearer_props* props) uint32_t gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, const bearer_props* props)
{ {
// Allocate a TEID for the incoming tunnel // Allocate a TEID for the incoming tunnel
uint32_t teid_in = ++next_teid_in; uint32_t teid_in = ++next_teid_in;
tunnel& new_tun = tunnels[teid_in]; auto insert_ret = tunnels.emplace(teid_in, tunnel{});
new_tun.teid_in = teid_in; tunnel& new_tun = insert_ret.first->second;
new_tun.rnti = rnti; new_tun.teid_in = teid_in;
new_tun.lcid = lcid; new_tun.rnti = rnti;
new_tun.spgw_addr = addr; new_tun.lcid = lcid;
new_tun.teid_out = teid_out; new_tun.spgw_addr = addr;
new_tun.teid_out = teid_out;
ue_teidin_db[rnti][lcid].push_back(teid_in); ue_teidin_db[rnti][lcid].push_back(teid_in);
logger.info("Adding bearer for rnti: 0x%x, lcid: %d, addr: 0x%x, teid_out: 0x%x, teid_in: 0x%x", logger.info("New tunnel teid_in=0x%x, teid_out=0x%x, rnti=0x%x, lcid=%d, addr=%s",
teid_in,
teid_out,
rnti, rnti,
lcid, lcid,
addr, srslte::gtpu_ntoa(htonl(addr)).c_str());
teid_out,
teid_in);
if (props != nullptr) { if (props != nullptr) {
if (props->flush_before_teidin_present) { if (props->flush_before_teidin_present) {
@ -191,7 +192,7 @@ void gtpu::set_tunnel_status(uint32_t teidin, bool dl_active)
} }
tun_it->second.dl_enabled = dl_active; tun_it->second.dl_enabled = dl_active;
if (dl_active) { if (dl_active) {
logger.info("Activing GTPU tunnel rnti=0x%x,TEID=%d. %d SDUs currently buffered", logger.info("Activating GTPU tunnel rnti=0x%x,TEID=%d. %d SDUs currently buffered",
tun_it->second.rnti, tun_it->second.rnti,
teidin, teidin,
tun_it->second.buffer.size()); tun_it->second.buffer.size());