diff --git a/lib/include/srslte/interfaces/enb_interfaces.h b/lib/include/srslte/interfaces/enb_interfaces.h index 234b934c2..c35886e37 100644 --- a/lib/include/srslte/interfaces/enb_interfaces.h +++ b/lib/include/srslte/interfaces/enb_interfaces.h @@ -438,8 +438,8 @@ public: start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& msg, const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container, srslte::byte_buffer_t& ho_cmd, - std::vector >& admitted_erabs) = 0; - virtual void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_item_s& erab) = 0; + std::vector >& admitted_erabs) = 0; + virtual void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) = 0; }; // GTPU interface for PDCP diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index b18c1b35c..8673ca229 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -92,7 +92,7 @@ public: const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container, srslte::byte_buffer_t& ho_cmd, std::vector >& admitted_erabs) override; - void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_item_s& erab) override; + void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) override; // rrc_interface_pdcp void write_pdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t pdu) override; diff --git a/srsenb/hdr/stack/rrc/rrc_mobility.h b/srsenb/hdr/stack/rrc/rrc_mobility.h index 376cc0b25..254894327 100644 --- a/srsenb/hdr/stack/rrc/rrc_mobility.h +++ b/srsenb/hdr/stack/rrc/rrc_mobility.h @@ -117,6 +117,7 @@ public: const asn1::s1ap::sourceenb_to_targetenb_transparent_container_s& container, srslte::byte_buffer_t& ho_cmd, std::vector >& admitted_erabs); + void set_erab_status(const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs); private: // Handover from source cell diff --git a/srsenb/hdr/stack/rrc/rrc_ue.h b/srsenb/hdr/stack/rrc/rrc_ue.h index adb72d5e5..e5def91c1 100644 --- a/srsenb/hdr/stack/rrc/rrc_ue.h +++ b/srsenb/hdr/stack/rrc/rrc_ue.h @@ -78,7 +78,6 @@ 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); diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 6b347abb4..db78d2633 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -470,15 +470,14 @@ 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) +void rrc::set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) { 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); + ue_it->second->mobility_handler->set_erab_status(erabs); } /******************************************************************************* diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index 139aec447..f0f47f3a7 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -824,6 +824,36 @@ bool rrc::ue::rrc_mobility::start_s1_tenb_ho( return false; } +void rrc::ue::rrc_mobility::set_erab_status(const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) +{ + for (const auto& erab : erabs) { + const auto& erab_item = erab.value.bearers_subject_to_status_transfer_item(); + auto erab_it = rrc_ue->bearer_list.get_erabs().find(erab_item.erab_id); + if (erab_it == rrc_ue->bearer_list.get_erabs().end()) { + 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(); + 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; }); + if (drb_it == drbs.end()) { + rrc_log->warning("The DRB id=%d does not exist\n", erab_item.erab_id - 4); + } + + srslte::pdcp_lte_state_t drb_state{}; + drb_state.tx_hfn = erab_item.dl_coun_tvalue.hfn; + drb_state.next_pdcp_tx_sn = erab_item.dl_coun_tvalue.pdcp_sn; + drb_state.rx_hfn = erab_item.ul_coun_tvalue.hfn; + drb_state.next_pdcp_rx_sn = erab_item.ul_coun_tvalue.pdcp_sn; + rrc_log->info("Setting lcid=%d PDCP state to {Tx SN: %d, Rx SN: %d}\n", + drb_it->lc_ch_id, + drb_state.next_pdcp_tx_sn, + drb_state.next_pdcp_rx_sn); + rrc_enb->pdcp->set_bearer_state(rrc_ue->rnti, drb_it->lc_ch_id, drb_state); + } +} + bool rrc::ue::rrc_mobility::update_ue_var_meas_cfg(const asn1::rrc::meas_cfg_s& source_meas_cfg, uint32_t target_enb_cc_idx, asn1::rrc::meas_cfg_s* diff_meas_cfg) @@ -1098,12 +1128,11 @@ void rrc::ue::rrc_mobility::s1_target_ho_st::enter(rrc_mobility* f, const ho_req } /* 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(); + dl_dcch_msg_s dl_dcch_msg; // Fill fields common to all types of handover f->fill_mobility_reconf_common(dl_dcch_msg, *target_cell->cell_common); + rrc_conn_recfg_r8_ies_s& recfg_r8 = dl_dcch_msg.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8(); // Encode MeasConfig var_meas_cfg_t current_var_meas = var_meas_cfg_t::make(ho_req.ho_prep_r8->as_cfg.source_meas_cfg); @@ -1117,10 +1146,9 @@ void rrc::ue::rrc_mobility::s1_target_ho_st::enter(rrc_mobility* f, const ho_req 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()); + f->rrc_ue->mac_ctrl->handle_ho_prep(*ho_req.ho_prep_r8, 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()); + f->rrc_ue->apply_reconf_phy_config(recfg_r8); /* Prepare Handover Command to be sent via S1AP */ ho_cmd_pdu = srslte::allocate_unique_buffer(*f->pool); diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 6195b885d..0ef585958 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -978,8 +978,6 @@ 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) { @@ -1224,7 +1222,8 @@ void rrc::ue::fill_rrc_setup_rr_config_dedicated(asn1::rrc::rr_cfg_ded_s* rr_cfg phy_cfg->ul_pwr_ctrl_ded.p0_ue_pusch = 0; phy_cfg->ul_pwr_ctrl_ded.delta_mcs_enabled = ul_pwr_ctrl_ded_s::delta_mcs_enabled_e_::en0; phy_cfg->ul_pwr_ctrl_ded.accumulation_enabled = true; - phy_cfg->ul_pwr_ctrl_ded.p0_ue_pucch = 0, phy_cfg->ul_pwr_ctrl_ded.psrs_offset = 3; + phy_cfg->ul_pwr_ctrl_ded.p0_ue_pucch = 0; + phy_cfg->ul_pwr_ctrl_ded.psrs_offset = 3; // PDSCH phy_cfg->pdsch_cfg_ded_present = true; diff --git a/srsenb/src/stack/upper/s1ap.cc b/srsenb/src/stack/upper/s1ap.cc index 576b07cd6..540730ce0 100644 --- a/srsenb/src/stack/upper/s1ap.cc +++ b/srsenb/src/stack/upper/s1ap.cc @@ -929,11 +929,9 @@ bool s1ap::handle_mme_status_transfer(const asn1::s1ap::mme_status_transfer_s& m 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); - } + rrc->set_erab_status( + u->ctxt.rnti, + msg.protocol_ies.enb_status_transfer_transparent_container.value.bearers_subject_to_status_transfer_list); return true; } diff --git a/srsenb/test/upper/rrc_mobility_test.cc b/srsenb/test/upper/rrc_mobility_test.cc index 4e2ac5429..58b2049ac 100644 --- a/srsenb/test/upper/rrc_mobility_test.cc +++ b/srsenb/test/upper/rrc_mobility_test.cc @@ -500,6 +500,22 @@ int test_s1ap_tenb_mobility(mobility_test_params test_params) 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); + // Receives MMEStatusTransfer + asn1::s1ap::bearers_subject_to_status_transfer_list_l bearers; + bearers.resize(1); + bearers[0].value.bearers_subject_to_status_transfer_item().erab_id = 5; + bearers[0].value.bearers_subject_to_status_transfer_item().dl_coun_tvalue.pdcp_sn = 100; + bearers[0].value.bearers_subject_to_status_transfer_item().dl_coun_tvalue.hfn = 3; + bearers[0].value.bearers_subject_to_status_transfer_item().ul_coun_tvalue.pdcp_sn = 120; + bearers[0].value.bearers_subject_to_status_transfer_item().ul_coun_tvalue.hfn = 4; + tester.rrc.set_erab_status(0x46, bearers); + TESTASSERT(tester.pdcp.last_state.rnti == 0x46); + TESTASSERT(tester.pdcp.last_state.lcid == 3); + TESTASSERT(tester.pdcp.last_state.state.next_pdcp_tx_sn == 100); + TESTASSERT(tester.pdcp.last_state.state.tx_hfn == 3); + TESTASSERT(tester.pdcp.last_state.state.next_pdcp_rx_sn == 120); + TESTASSERT(tester.pdcp.last_state.state.rx_hfn == 4); + // user PRACHs and sends C-RNTI CE sched_interface::ue_cfg_t ue_cfg{}; ue_cfg.supported_cc_list.resize(1); diff --git a/srsenb/test/upper/test_helpers.h b/srsenb/test/upper/test_helpers.h index b69b3a0b1..e81d35e0d 100644 --- a/srsenb/test/upper/test_helpers.h +++ b/srsenb/test/upper/test_helpers.h @@ -115,6 +115,12 @@ public: uint32_t lcid; srslte::unique_byte_buffer_t sdu; } last_sdu; + struct last_bearer_state { + uint16_t rnti; + uint32_t lcid; + srslte::pdcp_lte_state_t state; + } last_state; + std::map > drb_states; void write_sdu(uint16_t rnti, uint32_t lcid, srslte::unique_byte_buffer_t sdu) override { @@ -122,6 +128,13 @@ public: last_sdu.lcid = lcid; last_sdu.sdu = std::move(sdu); } + bool set_bearer_state(uint16_t rnti, uint32_t lcid, const srslte::pdcp_lte_state_t& state) override + { + last_state.rnti = rnti; + last_state.lcid = lcid; + last_state.state = state; + return true; + } }; class rlc_mobility_dummy : public rlc_dummy