fix rrc mobility test

This commit is contained in:
Francisco 2021-04-14 16:42:25 +01:00 committed by Francisco Paisana
parent 66988ffd32
commit b8fa1d1b61
16 changed files with 230 additions and 189 deletions

View File

@ -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<true>* nas_pdu,
srsran::const_span<uint8_t> 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<true>* nas_pdu,
srsran::const_span<uint8_t> 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<true>* 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<uint8_t> nas_pdu) = 0;
/**
* Reports the reception of S1 HandoverCommand / HandoverPreparationFailure or abnormal conditions during

View File

@ -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.

View File

@ -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<true>* nas_pdu,
srsran::const_span<uint8_t> 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<true>* nas_pdu,
srsran::const_span<uint8_t> 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<true>* 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;

View File

@ -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<true>* nas_pdu,
srsran::const_span<uint8_t> 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<true>* nas_pdu,
srsran::const_span<uint8_t> nas_pdu,
asn1::s1ap::cause_c& cause);
// Methods to apply bearer updates

View File

@ -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<true>* 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<true>* nas_pdu,
srsran::const_span<uint8_t> 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<true>* nas_pdu,
srsran::const_span<uint8_t> 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);

View File

@ -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<uint16_t, ASN1_S1AP_MAXNOOF_ERABS>;
using erab_item_list = srsran::bounded_vector<asn1::s1ap::erab_item_s, ASN1_S1AP_MAXNOOF_ERABS>;
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<uint16_t, ASN1_S1AP_MAXNOOF_ERABS> updated_erabs;
srsran::bounded_vector<asn1::s1ap::erab_item_s, ASN1_S1AP_MAXNOOF_ERABS> 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<uint16_t> erabs_released,
srsran::const_span<asn1::s1ap::erab_item_s> erabs_failed);
bool send_erab_release_response(srsran::const_span<uint16_t> erabs_released,
srsran::const_span<asn1::s1ap::erab_item_s> erabs_failed);
bool send_erab_modify_response(srsran::const_span<uint16_t> erabs_modified,
srsran::const_span<asn1::s1ap::erab_item_s> 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<uint16_t>& 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<uint32_t> 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<asn1::s1ap::erab_item_s, ASN1_S1AP_MAXNOOF_ERABS> failed_cfg_erabs;
public:
// user procedures
srsran::proc_t<ho_prep_proc_t> ho_prep_proc;

View File

@ -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);
}

View File

@ -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<true>* 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<true>* nas_pdu,
srsran::const_span<uint8_t> 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<true>* nas_pdu,
srsran::const_span<uint8_t> nas_pdu,
asn1::s1ap::cause_c& cause)
{
logger.info("Modifying E-RAB for 0x%x. E-RAB Id %d", rnti, erab_id);

View File

@ -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<true>* nas_pdu,
srsran::const_span<uint8_t> 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<true>* nas_pdu,
srsran::const_span<uint8_t> nas_pdu,
asn1::s1ap::cause_c& cause)
{
logger->info("Modifying E-RAB %d", erab_id);

View File

@ -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;

View File

@ -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<true>* 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<true>* nas_pdu = erab.nas_pdu_present ? &erab.nas_pdu : nullptr;
asn1::s1ap::cause_c cause;
srsran::const_span<uint8_t> 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<true>* nas_pdu,
srsran::const_span<uint8_t> 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<true>* nas_pdu,
srsran::const_span<uint8_t> nas_pdu,
asn1::s1ap::cause_c& cause)
{
return bearer_list.modify_erab(erab_id, qos_params, nas_pdu, cause);

View File

@ -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<erab_item_s, ASN1_S1AP_MAXNOOF_ERAB
}) != failed_cfg_erabs.end();
}
void sanitize_response_erab_lists(srsran::bounded_vector<erab_item_s, ASN1_S1AP_MAXNOOF_ERABS>& failed_cfg_erabs,
srsran::bounded_vector<uint16_t, ASN1_S1AP_MAXNOOF_ERABS>& 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<erab_item_s>);
@ -101,6 +99,16 @@ void sanitize_response_erab_lists(srsran::bounded_vector<erab_item_s, ASN1_S1AP_
erabs.erase(std::unique(erabs.begin(), erabs.end()), erabs.end());
}
template <typename OutList>
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<uint16_t> erabs_setup,
srsran::const_span<asn1::s1ap::erab_item_s> 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<uint16_t>
// 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<uint16_t>
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<uint16_t> erabs_released,
srsran::const_span<asn1::s1ap::erab_item_s> 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<uint16_t>
// 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<uint16_t> erabs_modified,
srsran::const_span<erab_item_s> 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<uint16_t> 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
********************/

View File

@ -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<true>* 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<true>* 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<true>* 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

View File

@ -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);

View File

@ -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<true>* 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 };

View File

@ -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();