diff --git a/lib/include/srsran/interfaces/enb_rrc_interfaces.h b/lib/include/srsran/interfaces/enb_rrc_interfaces.h index 8aa1d26a4..5c23a4b3f 100644 --- a/lib/include/srsran/interfaces/enb_rrc_interfaces.h +++ b/lib/include/srsran/interfaces/enb_rrc_interfaces.h @@ -34,14 +34,15 @@ public: virtual int get_erab_addr_in(uint16_t rnti, uint16_t erab_id, transp_addr_t& addr_in, uint32_t& teid_in) const = 0; virtual void set_aggregate_max_bitrate(uint16_t rnti, const asn1::s1ap::ue_aggregate_maximum_bitrate_s& bitrate) = 0; + /** - * TS 36.413, 8.2.1 - Setup E-RAB + * TS 36.413, 8.2.1 and 8.3.1 - Setup E-RAB / Initial Context Setup * @return if error, cause argument is updated with cause */ virtual int setup_erab(uint16_t rnti, uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, const transp_addr_t& addr, uint32_t gtpu_teid_out, asn1::s1ap::cause_c& cause) = 0; @@ -52,17 +53,18 @@ public: virtual int modify_erab(uint16_t rnti, uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, asn1::s1ap::cause_c& cause) = 0; /** * TS 36.413, 8.2.3 - Release E-RAB id * @return error if E-RAB id or rnti were not found */ - virtual int release_erab(uint16_t rnti, uint16_t erab_id) = 0; + virtual int release_erab(uint16_t rnti, uint16_t erab_id) = 0; + virtual void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& ue_paging_id) = 0; - /// Notify UE of ERAB updates (done via RRC Reconfiguration Message) - virtual int notify_ue_erab_updates(uint16_t rnti, const asn1::unbounded_octstring* nas_pdu) = 0; + /// TS 36.413, 8.2.1, 8.2.2, 8.2.3 - Notify UE of ERAB updates (done via RRC Reconfiguration Message) + virtual int notify_ue_erab_updates(uint16_t rnti, srsran::const_span nas_pdu) = 0; /** * Reports the reception of S1 HandoverCommand / HandoverPreparationFailure or abnormal conditions during diff --git a/lib/include/srsran/interfaces/enb_s1ap_interfaces.h b/lib/include/srsran/interfaces/enb_s1ap_interfaces.h index 8552b2aef..4b214ed50 100644 --- a/lib/include/srsran/interfaces/enb_s1ap_interfaces.h +++ b/lib/include/srsran/interfaces/enb_s1ap_interfaces.h @@ -52,12 +52,14 @@ public: uint32_t m_tmsi, uint8_t mmec) = 0; - virtual void write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) = 0; - virtual bool user_exists(uint16_t rnti) = 0; - virtual void user_mod(uint16_t old_rnti, uint16_t new_rnti) = 0; - virtual bool user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_radio) = 0; - virtual void ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res) = 0; - virtual bool is_mme_connected() = 0; + virtual void write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) = 0; + virtual bool user_exists(uint16_t rnti) = 0; + virtual void user_mod(uint16_t old_rnti, uint16_t new_rnti) = 0; + virtual bool user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_radio) = 0; + virtual bool is_mme_connected() = 0; + + /// TS 36.413, 8.3.1 - Initial Context Setup + virtual void ue_ctxt_setup_complete(uint16_t rnti) = 0; /** * Command the s1ap to transmit a HandoverRequired message to MME. diff --git a/srsenb/hdr/stack/rrc/rrc.h b/srsenb/hdr/stack/rrc/rrc.h index 944724422..c43638768 100644 --- a/srsenb/hdr/stack/rrc/rrc.h +++ b/srsenb/hdr/stack/rrc/rrc.h @@ -87,14 +87,14 @@ public: int setup_erab(uint16_t rnti, uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, const asn1::bounded_bitstring<1, 160, true, true>& addr, uint32_t gtpu_teid_out, asn1::s1ap::cause_c& cause) override; int modify_erab(uint16_t rnti, uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, asn1::s1ap::cause_c& cause) override; bool release_erabs(uint32_t rnti) override; int release_erab(uint16_t rnti, uint16_t erab_id) override; @@ -108,7 +108,7 @@ public: asn1::s1ap::cause_c& failure_cause) override; void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) override; - int notify_ue_erab_updates(uint16_t rnti, const asn1::unbounded_octstring* nas_pdu) override; + int notify_ue_erab_updates(uint16_t rnti, srsran::const_byte_span nas_pdu) override; // rrc_interface_pdcp void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override; diff --git a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h index d1ac82a8a..59d8c78df 100644 --- a/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_bearer_cfg.h @@ -83,13 +83,13 @@ public: const asn1::s1ap::erab_level_qos_params_s& qos, const asn1::bounded_bitstring<1, 160, true, true>& addr, uint32_t teid_out, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, asn1::s1ap::cause_c& cause); int release_erab(uint8_t erab_id); void release_erabs(); int modify_erab(uint8_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, asn1::s1ap::cause_c& cause); // Methods to apply bearer updates diff --git a/srsenb/hdr/stack/rrc/rrc_ue.h b/srsenb/hdr/stack/rrc/rrc_ue.h index 49c9cbfb7..6801b6ace 100644 --- a/srsenb/hdr/stack/rrc/rrc_ue.h +++ b/srsenb/hdr/stack/rrc/rrc_ue.h @@ -69,9 +69,9 @@ public: void send_connection_reject(procedure_result_code cause); void send_connection_release(); void send_connection_reest_rej(procedure_result_code cause); - void send_connection_reconf(srsran::unique_byte_buffer_t sdu = {}, - bool phy_cfg_updated = true, - const asn1::unbounded_octstring* nas_pdu = nullptr); + void send_connection_reconf(srsran::unique_byte_buffer_t sdu = {}, + bool phy_cfg_updated = true, + srsran::const_byte_span nas_pdu = {}); void send_security_mode_command(); void send_ue_cap_enquiry(); void send_ue_info_req(); @@ -116,17 +116,15 @@ public: int release_erab(uint32_t erab_id); int setup_erab(uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, const asn1::bounded_bitstring<1, 160, true, true>& addr, uint32_t gtpu_teid_out, asn1::s1ap::cause_c& cause); int modify_erab(uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, asn1::s1ap::cause_c& cause); - void notify_s1ap_ue_ctxt_setup_complete(); - // Getters for PUCCH resources int get_cqi(uint16_t* pmi_idx, uint16_t* n_pucch, uint32_t ue_cc_idx); int get_ri(uint32_t m_ri, uint16_t* ri_idx); diff --git a/srsenb/hdr/stack/upper/s1ap.h b/srsenb/hdr/stack/upper/s1ap.h index c841306d3..07aa4d525 100644 --- a/srsenb/hdr/stack/upper/s1ap.h +++ b/srsenb/hdr/stack/upper/s1ap.h @@ -49,7 +49,12 @@ struct ue_ctxt_t { class s1ap : public s1ap_interface_rrc { + using s1ap_proc_id_t = asn1::s1ap::s1ap_elem_procs_o::init_msg_c::types_opts::options; + public: + using erab_id_list = srsran::bounded_vector; + using erab_item_list = srsran::bounded_vector; + static const uint32_t ts1_reloc_prep_timeout_ms = 10000; static const uint32_t ts1_reloc_overall_timeout_ms = 10000; @@ -75,7 +80,7 @@ public: bool user_exists(uint16_t rnti) override; void user_mod(uint16_t old_rnti, uint16_t new_rnti) override; bool user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_radio) override; - void ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res) override; + void ue_ctxt_setup_complete(uint16_t rnti) override; bool is_mme_connected() override; bool send_ho_required(uint16_t rnti, uint32_t target_eci, @@ -140,10 +145,6 @@ private: asn1::s1ap::s1_setup_resp_s s1setupresponse; - // Procedure state - srsran::bounded_vector updated_erabs; - srsran::bounded_vector failed_cfg_erabs; - void build_tai_cgi(); bool connect_mme(); bool setup_s1(); @@ -243,19 +244,18 @@ private: bool has_tmsi, uint32_t m_tmsi = 0, uint8_t mmec = 0); - bool send_initial_ctxt_setup_response(const asn1::s1ap::init_context_setup_resp_s& res_); - bool send_initial_ctxt_setup_failure(); - bool send_erab_setup_response(srsran::const_span erabs_released, - srsran::const_span erabs_failed); - bool send_erab_release_response(srsran::const_span erabs_released, - srsran::const_span erabs_failed); - bool send_erab_modify_response(srsran::const_span erabs_modified, - srsran::const_span erabs_failed_to_modify); + void ue_ctxt_setup_complete(); + bool send_erab_setup_response(const erab_id_list& erabs_setup, const erab_item_list& erabs_failed); + bool send_erab_release_response(const erab_id_list& erabs_released, const erab_item_list& erabs_failed); + bool send_erab_modify_response(const erab_id_list& erabs_modified, const erab_item_list& erabs_failed); bool send_erab_release_indication(const std::vector& erabs_successfully_released); bool send_ue_cap_info_indication(srsran::unique_byte_buffer_t ue_radio_cap); bool was_uectxtrelease_requested() const { return release_requested; } + void + set_state(s1ap_proc_id_t state, const erab_id_list& erabs_updated, const erab_item_list& erabs_failed_to_update); + ue_ctxt_t ctxt = {}; uint16_t stream_id = 1; @@ -264,7 +264,7 @@ private: srsran::plmn_id_t target_plmn_, srsran::span fwd_erabs, srsran::unique_byte_buffer_t rrc_container); - //! TS 36.413, Section 8.4.6 - eNB Status Transfer procedure + void get_erab_addr(uint16_t erab_id, transp_addr_t& transp_addr, asn1::fixed_octstring<4, true>& gtpu_teid_id); // args s1ap* s1ap_ptr; @@ -275,6 +275,11 @@ private: srsran::unique_timer ts1_reloc_prep; ///< TS1_{RELOCprep} - max time for HO preparation srsran::unique_timer ts1_reloc_overall; ///< TS1_{RELOCOverall} + // Procedure state + s1ap_proc_id_t current_state; + erab_id_list updated_erabs; + srsran::bounded_vector failed_cfg_erabs; + public: // user procedures srsran::proc_t ho_prep_proc; diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index c4f27c265..71993e7a8 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -911,7 +911,7 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ // Check for a forced DL EARFCN or frequency (only valid for a single cell config (Xico's favorite feature)) if (rrc_cfg_->cell_list.size() == 1) { auto& cfg = rrc_cfg_->cell_list.at(0); - if (args_->enb.dl_earfcn > 0) { + if (args_->enb.dl_earfcn > 0 and args_->enb.dl_earfcn != cfg.dl_earfcn) { cfg.dl_earfcn = args_->enb.dl_earfcn; ERROR("Force DL EARFCN for cell PCI=%d to %d", cfg.pci, cfg.dl_earfcn); } diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 0316f20af..5e404fb6f 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -300,7 +300,6 @@ bool rrc::setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_requ { logger.info("Adding initial context for 0x%x", rnti); auto user_it = users.find(rnti); - if (user_it == users.end()) { logger.warning("Unrecognised rnti: 0x%x", rnti); return false; @@ -350,7 +349,7 @@ int rrc::release_erab(uint16_t rnti, uint16_t erab_id) return user_it->second->release_erab(erab_id); } -int rrc::notify_ue_erab_updates(uint16_t rnti, const asn1::unbounded_octstring* nas_pdu) +int rrc::notify_ue_erab_updates(uint16_t rnti, srsran::const_byte_span nas_pdu) { auto user_it = users.find(rnti); if (user_it == users.end()) { @@ -394,7 +393,7 @@ void rrc::set_aggregate_max_bitrate(uint16_t rnti, const asn1::s1ap::ue_aggregat int rrc::setup_erab(uint16_t rnti, uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, const asn1::bounded_bitstring<1, 160, true, true>& addr, uint32_t gtpu_teid_out, asn1::s1ap::cause_c& cause) @@ -412,7 +411,7 @@ int rrc::setup_erab(uint16_t rnti, int rrc::modify_erab(uint16_t rnti, uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, asn1::s1ap::cause_c& cause) { logger.info("Modifying E-RAB for 0x%x. E-RAB Id %d", rnti, erab_id); diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index ab134c40d..625b94453 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -206,7 +206,7 @@ int bearer_cfg_handler::add_erab(uint8_t const asn1::s1ap::erab_level_qos_params_s& qos, const asn1::bounded_bitstring<1, 160, true, true>& addr, uint32_t teid_out, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, asn1::s1ap::cause_c& cause) { if (erab_id < 5) { @@ -266,8 +266,8 @@ int bearer_cfg_handler::add_erab(uint8_t return SRSRAN_ERROR; } - if (nas_pdu != nullptr and nas_pdu->size() > 0) { - erab_info_list[erab_id].assign(nas_pdu->data(), nas_pdu->data() + nas_pdu->size()); + if (not nas_pdu.empty()) { + erab_info_list[erab_id].assign(nas_pdu.begin(), nas_pdu.end()); logger->info( &erab_info_list[erab_id][0], erab_info_list[erab_id].size(), "setup_erab nas_pdu -> erab_info rnti 0x%x", rnti); } @@ -319,7 +319,7 @@ void bearer_cfg_handler::release_erabs() int bearer_cfg_handler::modify_erab(uint8_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, asn1::s1ap::cause_c& cause) { logger->info("Modifying E-RAB %d", erab_id); diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index 93b05e2f5..460562349 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -905,7 +905,7 @@ bool rrc::ue::rrc_mobility::apply_ho_prep_cfg(const ho_prep_info_r8_ies_s& srsran::uint8_to_uint32(erab.gtp_teid.data(), &teid_out); asn1::s1ap::cause_c erab_cause; if (rrc_ue->bearer_list.add_erab( - erab.erab_id, erab.erab_level_qos_params, erab.transport_layer_address, teid_out, nullptr, erab_cause) != + erab.erab_id, erab.erab_level_qos_params, erab.transport_layer_address, teid_out, {}, erab_cause) != SRSRAN_SUCCESS) { erabs_failed_to_setup.emplace_back(); erabs_failed_to_setup.back().erab_id = erab.erab_id; diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 61979c2e8..8e82ba875 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -291,7 +291,7 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) break; case ul_dcch_msg_type_c::c1_c_::types::ue_cap_info: if (handle_ue_cap_info(&ul_dcch_msg.msg.c1().ue_cap_info())) { - notify_s1ap_ue_ctxt_setup_complete(); + parent->s1ap->ue_ctxt_setup_complete(rnti); send_connection_reconf(std::move(pdu)); state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE; } else { @@ -657,9 +657,9 @@ void rrc::ue::send_connection_reest_rej(procedure_result_code cause) /* * Connection Reconfiguration */ -void rrc::ue::send_connection_reconf(srsran::unique_byte_buffer_t pdu, - bool phy_cfg_updated, - const asn1::unbounded_octstring* nas_pdu) +void rrc::ue::send_connection_reconf(srsran::unique_byte_buffer_t pdu, + bool phy_cfg_updated, + srsran::const_byte_span nas_pdu) { parent->logger.debug("RRC state %d", state); @@ -699,13 +699,13 @@ void rrc::ue::send_connection_reconf(srsran::unique_byte_buffer_t pdu, mac_ctrl.handle_con_reconf(recfg_r8, ue_capabilities); // Fill in NAS PDU - Only for RRC Connection Reconfiguration during E-RAB Release Command - if (nas_pdu != nullptr and nas_pdu->size() > 0 and !recfg_r8.ded_info_nas_list_present) { + if (nas_pdu.size() > 0 and !recfg_r8.ded_info_nas_list_present) { recfg_r8.ded_info_nas_list_present = true; recfg_r8.ded_info_nas_list.resize(recfg_r8.rr_cfg_ded.drb_to_release_list.size()); // Add NAS PDU for (uint32_t idx = 0; idx < recfg_r8.rr_cfg_ded.drb_to_release_list.size(); idx++) { - recfg_r8.ded_info_nas_list[idx].resize(nas_pdu->size()); - memcpy(recfg_r8.ded_info_nas_list[idx].data(), nas_pdu->data(), nas_pdu->size()); + recfg_r8.ded_info_nas_list[idx].resize(nas_pdu.size()); + memcpy(recfg_r8.ded_info_nas_list[idx].data(), nas_pdu.data(), nas_pdu.size()); } } @@ -934,9 +934,6 @@ void rrc::ue::handle_ue_init_ctxt_setup_req(const asn1::s1ap::init_context_setup // Send RRC security mode command send_security_mode_command(); - - // Setup E-RABs - setup_erabs(msg.protocol_ies.erab_to_be_setup_list_ctxt_su_req.value); } bool rrc::ue::handle_ue_ctxt_mod_req(const asn1::s1ap::ue_context_mod_request_s& msg) @@ -967,23 +964,6 @@ bool rrc::ue::handle_ue_ctxt_mod_req(const asn1::s1ap::ue_context_mod_request_s& return true; } -void rrc::ue::notify_s1ap_ue_ctxt_setup_complete() -{ - asn1::s1ap::init_context_setup_resp_s res; - - res.protocol_ies.erab_setup_list_ctxt_su_res.value.resize(bearer_list.get_erabs().size()); - uint32_t i = 0; - for (const auto& erab : bearer_list.get_erabs()) { - res.protocol_ies.erab_setup_list_ctxt_su_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_CTXT_SU_RES); - auto& item = res.protocol_ies.erab_setup_list_ctxt_su_res.value[i].value.erab_setup_item_ctxt_su_res(); - item.erab_id = erab.second.id; - srsran::uint32_to_uint8(erab.second.teid_in, item.gtp_teid.data()); - i++; - } - - parent->s1ap->ue_ctxt_setup_complete(rnti, res); -} - void rrc::ue::set_bitrates(const asn1::s1ap::ue_aggregate_maximum_bitrate_s& rates) { bitrates = rates; @@ -1006,8 +986,11 @@ bool rrc::ue::setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l& uint32_t teid_out = 0; srsran::uint8_to_uint32(erab.gtp_teid.data(), &teid_out); - const asn1::unbounded_octstring* nas_pdu = erab.nas_pdu_present ? &erab.nas_pdu : nullptr; - asn1::s1ap::cause_c cause; + srsran::const_span nas_pdu; + if (erab.nas_pdu_present) { + nas_pdu = erab.nas_pdu; + } + asn1::s1ap::cause_c cause; bearer_list.add_erab( erab.erab_id, erab.erab_level_qos_params, erab.transport_layer_address, teid_out, nas_pdu, cause); bearer_list.add_gtpu_bearer(erab.erab_id); @@ -1040,7 +1023,7 @@ int rrc::ue::get_erab_addr_in(uint16_t erab_id, transp_addr_t& addr_in, uint32_t int rrc::ue::setup_erab(uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, const asn1::bounded_bitstring<1, 160, true, true>& addr, uint32_t gtpu_teid_out, asn1::s1ap::cause_c& cause) @@ -1061,7 +1044,7 @@ int rrc::ue::setup_erab(uint16_t erab_ int rrc::ue::modify_erab(uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_span nas_pdu, asn1::s1ap::cause_c& cause) { return bearer_list.modify_erab(erab_id, qos_params, nas_pdu, cause); diff --git a/srsenb/src/stack/upper/s1ap.cc b/srsenb/src/stack/upper/s1ap.cc index 7bdeea8c8..b4a872430 100644 --- a/srsenb/src/stack/upper/s1ap.cc +++ b/srsenb/src/stack/upper/s1ap.cc @@ -11,7 +11,6 @@ */ #include "srsenb/hdr/stack/upper/s1ap.h" -#include "srsenb/hdr/common/common_enb.h" #include "srsran/adt/scope_exit.h" #include "srsran/common/bcd_helpers.h" #include "srsran/common/enb_events.h" @@ -90,8 +89,7 @@ bool contains_erab_id(srsran::bounded_vector& failed_cfg_erabs, - srsran::bounded_vector& erabs) +void sanitize_response_erab_lists(s1ap::erab_item_list& failed_cfg_erabs, s1ap::erab_id_list& erabs) { // Sort and remove duplicates std::sort(failed_cfg_erabs.begin(), failed_cfg_erabs.end(), &lower_obj_id); @@ -101,6 +99,16 @@ void sanitize_response_erab_lists(srsran::bounded_vector +void fill_erab_failed_setup_list(OutList& output_list, const s1ap::erab_item_list& input_list) +{ + output_list.resize(input_list.size()); + for (size_t i = 0; i < input_list.size(); ++i) { + output_list[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); + output_list[i].value.erab_item() = input_list[i]; + } +} + /********************************************************* * TS 36.413 - Section 8.4.1 - "Handover Preparation" *********************************************************/ @@ -443,17 +451,13 @@ void s1ap::user_mod(uint16_t old_rnti, uint16_t new_rnti) users.find_ue_rnti(old_rnti)->ctxt.rnti = new_rnti; } -void s1ap::ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res) +void s1ap::ue_ctxt_setup_complete(uint16_t rnti) { ue* u = users.find_ue_rnti(rnti); if (u == nullptr) { return; } - if (res.protocol_ies.erab_setup_list_ctxt_su_res.value.size() > 0) { - u->send_initial_ctxt_setup_response(res); - } else { - u->send_initial_ctxt_setup_failure(); - } + u->ue_ctxt_setup_complete(); } bool s1ap::is_mme_connected() @@ -735,6 +739,44 @@ bool s1ap::handle_initialctxtsetuprequest(const init_context_setup_request_s& ms return false; } + // Update E-RABs + erab_id_list updated_erabs; + erab_item_list failed_cfg_erabs; + add_repeated_erab_ids(prot_ies.erab_to_be_setup_list_ctxt_su_req.value, failed_cfg_erabs); + + for (const auto& item : msg.protocol_ies.erab_to_be_setup_list_ctxt_su_req.value) { + const auto& erab = item.value.erab_to_be_setup_item_ctxt_su_req(); + if (contains_erab_id(failed_cfg_erabs, erab.erab_id)) { + // E-RAB is duplicate + continue; + } + WarnUnsupportFeature(erab.ext, "E-RABToBeSetupListBearerSUReq extensions"); + WarnUnsupportFeature(erab.ie_exts_present, "E-RABToBeSetupListBearerSUReq extensions"); + + if (erab.transport_layer_address.length() > 32) { + logger.error("IPv6 addresses not currently supported"); + failed_cfg_erabs.push_back(erab_item_s()); + failed_cfg_erabs.back().erab_id = erab.erab_id; + failed_cfg_erabs.back().cause.set_radio_network().value = cause_radio_network_opts::invalid_qos_combination; + continue; + } + + cause_c cause; + if (rrc->setup_erab(u->ctxt.rnti, + erab.erab_id, + erab.erab_level_qos_params, + erab.nas_pdu, + erab.transport_layer_address, + erab.gtp_teid.to_number(), + cause) == SRSRAN_SUCCESS) { + updated_erabs.push_back(erab.erab_id); + } else { + failed_cfg_erabs.push_back(erab_item_s()); + failed_cfg_erabs.back().erab_id = erab.erab_id; + failed_cfg_erabs.back().cause = cause; + } + } + /* Ideally the check below would be "if (users[rnti].is_csfb)" */ if (msg.protocol_ies.cs_fallback_ind_present) { if (msg.protocol_ies.cs_fallback_ind.value.value == cs_fallback_ind_opts::cs_fallback_required || @@ -747,6 +789,10 @@ bool s1ap::handle_initialctxtsetuprequest(const init_context_setup_request_s& ms } } + // E-RAB Setup Response is sent after the security cfg is complete + // Note: No need to notify RRC to send RRC Reconfiguration + sanitize_response_erab_lists(failed_cfg_erabs, updated_erabs); + u->set_state(s1ap_proc_id_t::init_context_setup_request, updated_erabs, failed_cfg_erabs); return true; } @@ -773,8 +819,8 @@ bool s1ap::handle_erabsetuprequest(const erab_setup_request_s& msg) rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg.protocol_ies.ueaggregate_maximum_bitrate.value); } - failed_cfg_erabs.clear(); - updated_erabs.clear(); + erab_id_list updated_erabs; + erab_item_list failed_cfg_erabs; add_repeated_erab_ids(msg.protocol_ies.erab_to_be_setup_list_bearer_su_req.value, failed_cfg_erabs); for (const auto& item : msg.protocol_ies.erab_to_be_setup_list_bearer_su_req.value) { @@ -798,7 +844,7 @@ bool s1ap::handle_erabsetuprequest(const erab_setup_request_s& msg) if (rrc->setup_erab(u->ctxt.rnti, erab.erab_id, erab.erab_level_qos_params, - &erab.nas_pdu, + erab.nas_pdu, erab.transport_layer_address, erab.gtp_teid.to_number(), cause) == SRSRAN_SUCCESS) { @@ -812,7 +858,7 @@ bool s1ap::handle_erabsetuprequest(const erab_setup_request_s& msg) // Notify UE of updates if (not updated_erabs.empty()) { - rrc->notify_ue_erab_updates(u->ctxt.rnti, nullptr); + rrc->notify_ue_erab_updates(u->ctxt.rnti, {}); } sanitize_response_erab_lists(failed_cfg_erabs, updated_erabs); @@ -829,8 +875,12 @@ bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg) return false; } - failed_cfg_erabs.clear(); - updated_erabs.clear(); + if (msg.protocol_ies.ueaggregate_maximum_bitrate_present) { + rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg.protocol_ies.ueaggregate_maximum_bitrate.value); + } + + erab_id_list updated_erabs; + erab_item_list failed_cfg_erabs; add_repeated_erab_ids(msg.protocol_ies.erab_to_be_modified_list_bearer_mod_req.value, failed_cfg_erabs); for (const auto& item : msg.protocol_ies.erab_to_be_modified_list_bearer_mod_req.value) { @@ -843,7 +893,7 @@ bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg) WarnUnsupportFeature(erab.ie_exts_present, "E-RABToBeSetupListBearerSUReq extensions"); cause_c cause; - if (rrc->modify_erab(u->ctxt.rnti, erab.erab_id, erab.erab_level_qos_params, &erab.nas_pdu, cause) == + if (rrc->modify_erab(u->ctxt.rnti, erab.erab_id, erab.erab_level_qos_params, erab.nas_pdu, cause) == SRSRAN_SUCCESS) { updated_erabs.push_back(erab.erab_id); } else { @@ -855,16 +905,12 @@ bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg) // Notify UE of updates if (not updated_erabs.empty()) { - rrc->notify_ue_erab_updates(u->ctxt.rnti, nullptr); + rrc->notify_ue_erab_updates(u->ctxt.rnti, {}); } // send E-RAB modify response back to the mme sanitize_response_erab_lists(failed_cfg_erabs, updated_erabs); - if (not u->send_erab_modify_response(updated_erabs, failed_cfg_erabs)) { - logger.info("failed to send erabreleaseresponse"); - return false; - } - return true; + return u->send_erab_modify_response(updated_erabs, failed_cfg_erabs); } /** @@ -884,10 +930,10 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg) return false; } - failed_cfg_erabs.clear(); - updated_erabs.clear(); + erab_id_list updated_erabs; + erab_item_list failed_cfg_erabs; - auto is_repeated_erab_id = [this](uint8_t erab_id) { + auto is_repeated_erab_id = [&updated_erabs, &failed_cfg_erabs](uint8_t erab_id) { return (std::count(updated_erabs.begin(), updated_erabs.end(), erab_id) > 0) or (std::any_of(failed_cfg_erabs.begin(), failed_cfg_erabs.end(), [erab_id](const erab_item_s& e) { return e.erab_id == erab_id; @@ -912,7 +958,7 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg) // Notify RRC of E-RAB update. (RRC reconf message is going to be sent. if (not updated_erabs.empty()) { - rrc->notify_ue_erab_updates(u->ctxt.rnti, nullptr); + rrc->notify_ue_erab_updates(u->ctxt.rnti, msg.protocol_ies.nas_pdu.value); } // Send E-RAB release response back to the MME @@ -970,7 +1016,7 @@ bool s1ap::handle_uectxtreleasecommand(const ue_context_release_cmd_s& msg) ue* u = nullptr; if (msg.protocol_ies.ue_s1ap_ids.value.type().value == ue_s1ap_ids_c::types_opts::ue_s1ap_id_pair) { - auto& idpair = msg.protocol_ies.ue_s1ap_ids.value.ue_s1ap_id_pair(); + const auto& idpair = msg.protocol_ies.ue_s1ap_ids.value.ue_s1ap_id_pair(); if (idpair.ext) { logger.warning("Not handling S1AP message extension"); @@ -1392,42 +1438,59 @@ bool s1ap::ue::send_uectxtreleasecomplete() return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextReleaseComplete"); } -bool s1ap::ue::send_initial_ctxt_setup_response(const asn1::s1ap::init_context_setup_resp_s& res_) +void s1ap::ue::ue_ctxt_setup_complete() { - if (not s1ap_ptr->mme_connected) { - return false; + if (current_state != s1ap_elem_procs_o::init_msg_c::types_opts::init_context_setup_request) { + logger.warning("Procedure %s,rnti=0x%x - Received unexpected complete notification", + s1ap_elem_procs_o::init_msg_c::types_opts{current_state}.to_string().c_str(), + ctxt.rnti); + return; } + current_state = s1ap_elem_procs_o::init_msg_c::types_opts::nulltype; s1ap_pdu_c tx_pdu; - tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_INIT_CONTEXT_SETUP); + if (updated_erabs.empty()) { + // It is ICS Failure + tx_pdu.set_unsuccessful_outcome().load_info_obj(ASN1_S1AP_ID_INIT_CONTEXT_SETUP); + auto& container = tx_pdu.unsuccessful_outcome().value.init_context_setup_fail().protocol_ies; - // Copy in the provided response message - tx_pdu.successful_outcome().value.init_context_setup_resp() = res_; + container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; + container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); + container.cause.value = failed_cfg_erabs.front().cause; + s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UEContextModificationFailure"); + return; + } + + // It is ICS Response + tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_INIT_CONTEXT_SETUP); + auto& container = tx_pdu.successful_outcome().value.init_context_setup_resp().protocol_ies; // Fill in the MME and eNB IDs - auto& container = tx_pdu.successful_outcome().value.init_context_setup_resp().protocol_ies; container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - // Fill in the GTP bind address for all bearers - for (uint32_t i = 0; i < container.erab_setup_list_ctxt_su_res.value.size(); ++i) { - auto& item = container.erab_setup_list_ctxt_su_res.value[i].value.erab_setup_item_ctxt_su_res(); - item.transport_layer_address.resize(32); - uint8_t addr[4]; - inet_pton(AF_INET, s1ap_ptr->args.gtp_bind_addr.c_str(), addr); - for (uint32_t j = 0; j < 4; ++j) { - item.transport_layer_address.data()[j] = addr[3 - j]; - } + // Add list of E-RABs that were not setup + if (not failed_cfg_erabs.empty()) { + container.erab_failed_to_setup_list_ctxt_su_res_present = true; + fill_erab_failed_setup_list(container.erab_failed_to_setup_list_ctxt_su_res.value, failed_cfg_erabs); + } + + // Add setup E-RABs + container.erab_setup_list_ctxt_su_res.value.resize(updated_erabs.size()); + for (size_t i = 0; i < updated_erabs.size(); ++i) { + container.erab_setup_list_ctxt_su_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_CTXT_SU_RES); + auto& item = container.erab_setup_list_ctxt_su_res.value[i].value.erab_setup_item_ctxt_su_res(); + item.erab_id = updated_erabs[i]; + get_erab_addr(item.erab_id, item.transport_layer_address, item.gtp_teid); } // Log event. event_logger::get().log_s1_ctx_create(ctxt.enb_cc_idx, ctxt.mme_ue_s1ap_id.value(), ctxt.enb_ue_s1ap_id, ctxt.rnti); - return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "InitialContextSetupResponse"); + s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E-RABSetupResponse"); } -bool s1ap::ue::send_erab_setup_response(srsran::const_span erabs_setup, - srsran::const_span erabs_failed) +bool s1ap::ue::send_erab_setup_response(const erab_id_list& erabs_setup, const erab_item_list& erabs_failed) { asn1::s1ap::s1ap_pdu_c tx_pdu; tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_ERAB_SETUP); @@ -1440,11 +1503,7 @@ bool s1ap::ue::send_erab_setup_response(srsran::const_span // Add list of E-RABs that were not setup if (not erabs_failed.empty()) { res.protocol_ies.erab_failed_to_setup_list_bearer_su_res_present = true; - res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value.resize(erabs_failed.size()); - for (size_t i = 0; i < erabs_failed.size(); ++i) { - res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); - res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value[i].value.erab_item() = erabs_failed[i]; - } + fill_erab_failed_setup_list(res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value, erabs_failed); } if (not erabs_setup.empty()) { @@ -1454,46 +1513,13 @@ bool s1ap::ue::send_erab_setup_response(srsran::const_span res.protocol_ies.erab_setup_list_bearer_su_res.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_BEARER_SU_RES); auto& item = res.protocol_ies.erab_setup_list_bearer_su_res.value[i].value.erab_setup_item_bearer_su_res(); item.erab_id = erabs_setup[i]; - uint32_t teid_in; - int ret = s1ap_ptr->rrc->get_erab_addr_in(ctxt.rnti, item.erab_id, item.transport_layer_address, teid_in); - srsran_expect(ret == SRSRAN_SUCCESS, "Invalid E-RAB setup"); - item.gtp_teid.from_number(teid_in); - } - } - - // Fill in the GTP bind address for all bearers - if (res.protocol_ies.erab_setup_list_bearer_su_res_present) { - for (uint32_t i = 0; i < res.protocol_ies.erab_setup_list_bearer_su_res.value.size(); ++i) { - auto& item = res.protocol_ies.erab_setup_list_bearer_su_res.value[i].value.erab_setup_item_bearer_su_res(); - item.transport_layer_address.resize(32); - uint8_t addr[4]; - inet_pton(AF_INET, s1ap_ptr->args.gtp_bind_addr.c_str(), addr); - for (uint32_t j = 0; j < 4; ++j) { - item.transport_layer_address.data()[j] = addr[3 - j]; - } + get_erab_addr(item.erab_id, item.transport_layer_address, item.gtp_teid); } } return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E_RABSetupResponse"); } -bool s1ap::ue::send_initial_ctxt_setup_failure() -{ - if (not s1ap_ptr->mme_connected) { - return false; - } - - s1ap_pdu_c tx_pdu; - tx_pdu.set_unsuccessful_outcome().load_info_obj(ASN1_S1AP_ID_INIT_CONTEXT_SETUP); - auto& container = tx_pdu.unsuccessful_outcome().value.init_context_setup_fail().protocol_ies; - - container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id; - container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value(); - container.cause.value.set_radio_network().value = cause_radio_network_opts::unspecified; - - return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "InitialContextSetupFailure"); -} - bool s1ap::ue::send_uectxtmodifyresp() { if (not s1ap_ptr->mme_connected) { @@ -1534,8 +1560,7 @@ bool s1ap::ue::send_uectxtmodifyfailure(const cause_c& cause) * @param erabs_failed_to_release * @return true if message was sent */ -bool s1ap::ue::send_erab_release_response(srsran::const_span erabs_released, - srsran::const_span erabs_failed) +bool s1ap::ue::send_erab_release_response(const erab_id_list& erabs_released, const erab_item_list& erabs_failed) { asn1::s1ap::s1ap_pdu_c tx_pdu; tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_ERAB_RELEASE); @@ -1559,18 +1584,13 @@ bool s1ap::ue::send_erab_release_response(srsran::const_span // Fill in which E-RABs were *not* successfully released if (not erabs_failed.empty()) { container.erab_failed_to_release_list_present = true; - container.erab_failed_to_release_list.value.resize(erabs_failed.size()); - for (size_t i = 0; i < erabs_failed.size(); ++i) { - container.erab_failed_to_release_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); - container.erab_failed_to_release_list.value[i].value.erab_item() = erabs_failed[i]; - } + fill_erab_failed_setup_list(container.erab_failed_to_release_list.value, erabs_failed); } return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E-RABReleaseResponse"); } -bool s1ap::ue::send_erab_modify_response(srsran::const_span erabs_modified, - srsran::const_span erabs_failed_to_modify) +bool s1ap::ue::send_erab_modify_response(const erab_id_list& erabs_modified, const erab_item_list& erabs_failed) { asn1::s1ap::s1ap_pdu_c tx_pdu; tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_ERAB_MODIFY); @@ -1591,13 +1611,9 @@ bool s1ap::ue::send_erab_modify_response(srsran::const_span erabs_m } // Fill in which E-RABs were *not* successfully released - if (not erabs_failed_to_modify.empty()) { + if (not erabs_failed.empty()) { container.erab_failed_to_modify_list_present = true; - container.erab_failed_to_modify_list.value.resize(erabs_failed_to_modify.size()); - for (uint32_t i = 0; i < container.erab_failed_to_modify_list.value.size(); i++) { - container.erab_failed_to_modify_list.value[i].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM); - container.erab_failed_to_modify_list.value[i].value.erab_item() = erabs_failed_to_modify[i]; - } + fill_erab_failed_setup_list(container.erab_failed_to_modify_list.value, erabs_failed); } return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E-RABModifyResponse"); @@ -1642,6 +1658,30 @@ bool s1ap::ue::send_ue_cap_info_indication(srsran::unique_byte_buffer_t ue_radio return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "UECapabilityInfoIndication"); } +void s1ap::ue::set_state(s1ap_proc_id_t next_state, + const erab_id_list& erabs_updated, + const erab_item_list& erabs_failed_to_modify) +{ + current_state = next_state; + updated_erabs.assign(erabs_updated.begin(), erabs_updated.end()); + failed_cfg_erabs.assign(erabs_failed_to_modify.begin(), erabs_failed_to_modify.end()); +} + +void s1ap::ue::get_erab_addr(uint16_t erab_id, transp_addr_t& transp_addr, asn1::fixed_octstring<4, true>& gtpu_teid_id) +{ + uint32_t teidin = 0; + int ret = s1ap_ptr->rrc->get_erab_addr_in(ctxt.rnti, erab_id, transp_addr, teidin); + srsran_expect(ret == SRSRAN_SUCCESS, "Invalid E-RAB setup"); + // Note: RRC does not yet update correctly gtpu transp_addr + transp_addr.resize(32); + uint8_t addr[4]; + inet_pton(AF_INET, s1ap_ptr->args.gtp_bind_addr.c_str(), addr); + for (uint32_t j = 0; j < 4; ++j) { + transp_addr.data()[j] = addr[3 - j]; + } + gtpu_teid_id.from_number(teidin); +} + /********************* * Handover Messages ********************/ diff --git a/srsenb/test/common/dummy_classes.h b/srsenb/test/common/dummy_classes.h index eca63b06e..725478ea6 100644 --- a/srsenb/test/common/dummy_classes.h +++ b/srsenb/test/common/dummy_classes.h @@ -104,7 +104,7 @@ public: void write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) override {} bool user_exists(uint16_t rnti) override { return true; } bool user_release(uint16_t rnti, asn1::s1ap::cause_radio_network_e cause_radio) override { return true; } - void ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res) override {} + void ue_ctxt_setup_complete(uint16_t rnti) override {} bool is_mme_connected() override { return true; } bool send_ho_required(uint16_t rnti, uint32_t target_eci, @@ -175,7 +175,7 @@ public: int setup_erab(uint16_t rnti, uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_byte_span nas_pdu, const asn1::bounded_bitstring<1, 160, true, true>& addr, uint32_t gtpu_teid_out, asn1::s1ap::cause_c& cause) override @@ -185,7 +185,7 @@ public: int modify_erab(uint16_t rnti, uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_byte_span nas_pdu, asn1::s1ap::cause_c& cause) override { return SRSRAN_SUCCESS; @@ -207,10 +207,7 @@ public: } void set_erab_status(uint16_t rnti, const asn1::s1ap::bearers_subject_to_status_transfer_list_l& erabs) override {} - int notify_ue_erab_updates(uint16_t rnti, const asn1::unbounded_octstring* nas_pdu) override - { - return SRSRAN_SUCCESS; - } + int notify_ue_erab_updates(uint16_t rnti, srsran::const_byte_span nas_pdu) override { return SRSRAN_SUCCESS; } }; } // namespace srsenb diff --git a/srsenb/test/upper/erab_setup_test.cc b/srsenb/test/upper/erab_setup_test.cc index 26138983b..fdd07990b 100644 --- a/srsenb/test/upper/erab_setup_test.cc +++ b/srsenb/test/upper/erab_setup_test.cc @@ -98,7 +98,7 @@ int test_erab_setup(srsran::log_sink_spy& spy, bool qci_exists) int ret = rrc.setup_erab(rnti, erab.erab_id, erab.erab_level_qos_params, - &erab.nas_pdu, + erab.nas_pdu, erab.transport_layer_address, erab.gtp_teid.to_number(), cause); diff --git a/srsenb/test/upper/s1ap_test.cc b/srsenb/test/upper/s1ap_test.cc index 29f6dd078..9e782696d 100644 --- a/srsenb/test/upper/s1ap_test.cc +++ b/srsenb/test/upper/s1ap_test.cc @@ -94,7 +94,7 @@ struct rrc_tester : public rrc_dummy { int modify_erab(uint16_t rnti, uint16_t erab_id, const asn1::s1ap::erab_level_qos_params_s& qos_params, - const asn1::unbounded_octstring* nas_pdu, + srsran::const_byte_span nas_pdu, asn1::s1ap::cause_c& cause) override { if (std::count(next_erabs_failed_to_modify.begin(), next_erabs_failed_to_modify.end(), erab_id) > 0) { @@ -184,13 +184,16 @@ void add_rnti(s1ap& s1ap_obj, mme_dummy& mme) 0x40, 0x0a, 0x0a, 0x1f, 0x7f, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01}; cbref = asn1::cbit_ref(icsresp, sizeof(icsresp)); TESTASSERT(s1ap_pdu.unpack(cbref) == SRSRAN_SUCCESS); - s1ap_obj.ue_ctxt_setup_complete(0x46, s1ap_pdu.successful_outcome().value.init_context_setup_resp()); + s1ap_obj.ue_ctxt_setup_complete(0x46); sdu = mme.read_msg(); TESTASSERT(sdu->N_bytes > 0); cbref = asn1::cbit_ref{sdu->msg, sdu->N_bytes}; TESTASSERT(s1ap_pdu.unpack(cbref) == SRSRAN_SUCCESS); TESTASSERT(s1ap_pdu.type().value == asn1::s1ap::s1ap_pdu_c::types_opts::successful_outcome); TESTASSERT(s1ap_pdu.successful_outcome().proc_code == ASN1_S1AP_ID_INIT_CONTEXT_SETUP); + const auto& resp = s1ap_pdu.successful_outcome().value.init_context_setup_resp().protocol_ies; + TESTASSERT(resp.erab_setup_list_ctxt_su_res.value.size() > 0); + TESTASSERT(not resp.erab_failed_to_setup_list_ctxt_su_res_present); } enum class test_event { success, wrong_erabid_mod, wrong_mme_s1ap_id, repeated_erabid_mod }; diff --git a/srsenb/test/upper/test_helpers.cc b/srsenb/test/upper/test_helpers.cc index 356f47fcb..a35873b1e 100644 --- a/srsenb/test/upper/test_helpers.cc +++ b/srsenb/test/upper/test_helpers.cc @@ -109,6 +109,18 @@ int bring_rrc_to_reconf_state(srsenb::rrc& rrc, srsran::timer_handler& timers, u asn1::cbit_ref bref(byte_buf.msg, byte_buf.N_bytes); TESTASSERT(s1ap_pdu.unpack(bref) == asn1::SRSASN_SUCCESS); rrc.setup_ue_ctxt(rnti, s1ap_pdu.init_msg().value.init_context_setup_request()); + for (auto& item : + s1ap_pdu.init_msg().value.init_context_setup_request().protocol_ies.erab_to_be_setup_list_ctxt_su_req.value) { + const auto& erab = item.value.erab_to_be_setup_item_ctxt_su_req(); + asn1::s1ap::cause_c cause; + TESTASSERT(rrc.setup_erab(rnti, + erab.erab_id, + erab.erab_level_qos_params, + erab.nas_pdu, + erab.transport_layer_address, + erab.gtp_teid.to_number(), + cause) == SRSRAN_SUCCESS); + } timers.step_all(); rrc.tti_clock();