mirror of https://github.com/PentHertz/srsLTE.git
fix rrc mobility test
This commit is contained in:
parent
66988ffd32
commit
b8fa1d1b61
|
@ -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 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;
|
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
|
* @return if error, cause argument is updated with cause
|
||||||
*/
|
*/
|
||||||
virtual int setup_erab(uint16_t rnti,
|
virtual int setup_erab(uint16_t rnti,
|
||||||
uint16_t erab_id,
|
uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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,
|
const transp_addr_t& addr,
|
||||||
uint32_t gtpu_teid_out,
|
uint32_t gtpu_teid_out,
|
||||||
asn1::s1ap::cause_c& cause) = 0;
|
asn1::s1ap::cause_c& cause) = 0;
|
||||||
|
@ -52,17 +53,18 @@ public:
|
||||||
virtual int modify_erab(uint16_t rnti,
|
virtual int modify_erab(uint16_t rnti,
|
||||||
uint16_t erab_id,
|
uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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;
|
asn1::s1ap::cause_c& cause) = 0;
|
||||||
/**
|
/**
|
||||||
* TS 36.413, 8.2.3 - Release E-RAB id
|
* TS 36.413, 8.2.3 - Release E-RAB id
|
||||||
* @return error if E-RAB id or rnti were not found
|
* @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;
|
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)
|
/// 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, const asn1::unbounded_octstring<true>* nas_pdu) = 0;
|
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
|
* Reports the reception of S1 HandoverCommand / HandoverPreparationFailure or abnormal conditions during
|
||||||
|
|
|
@ -52,12 +52,14 @@ public:
|
||||||
uint32_t m_tmsi,
|
uint32_t m_tmsi,
|
||||||
uint8_t mmec) = 0;
|
uint8_t mmec) = 0;
|
||||||
|
|
||||||
virtual void write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) = 0;
|
virtual void write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) = 0;
|
||||||
virtual bool user_exists(uint16_t rnti) = 0;
|
virtual bool user_exists(uint16_t rnti) = 0;
|
||||||
virtual void user_mod(uint16_t old_rnti, uint16_t new_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 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 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.
|
* Command the s1ap to transmit a HandoverRequired message to MME.
|
||||||
|
|
|
@ -87,14 +87,14 @@ public:
|
||||||
int setup_erab(uint16_t rnti,
|
int setup_erab(uint16_t rnti,
|
||||||
uint16_t erab_id,
|
uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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,
|
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
||||||
uint32_t gtpu_teid_out,
|
uint32_t gtpu_teid_out,
|
||||||
asn1::s1ap::cause_c& cause) override;
|
asn1::s1ap::cause_c& cause) override;
|
||||||
int modify_erab(uint16_t rnti,
|
int modify_erab(uint16_t rnti,
|
||||||
uint16_t erab_id,
|
uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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;
|
asn1::s1ap::cause_c& cause) override;
|
||||||
bool release_erabs(uint32_t rnti) override;
|
bool release_erabs(uint32_t rnti) override;
|
||||||
int release_erab(uint16_t rnti, uint16_t erab_id) override;
|
int release_erab(uint16_t rnti, uint16_t erab_id) override;
|
||||||
|
@ -108,7 +108,7 @@ public:
|
||||||
asn1::s1ap::cause_c& failure_cause) override;
|
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;
|
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
|
// rrc_interface_pdcp
|
||||||
void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override;
|
void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override;
|
||||||
|
|
|
@ -83,13 +83,13 @@ public:
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos,
|
const asn1::s1ap::erab_level_qos_params_s& qos,
|
||||||
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
||||||
uint32_t teid_out,
|
uint32_t teid_out,
|
||||||
const asn1::unbounded_octstring<true>* nas_pdu,
|
srsran::const_span<uint8_t> nas_pdu,
|
||||||
asn1::s1ap::cause_c& cause);
|
asn1::s1ap::cause_c& cause);
|
||||||
int release_erab(uint8_t erab_id);
|
int release_erab(uint8_t erab_id);
|
||||||
void release_erabs();
|
void release_erabs();
|
||||||
int modify_erab(uint8_t erab_id,
|
int modify_erab(uint8_t erab_id,
|
||||||
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,
|
srsran::const_span<uint8_t> nas_pdu,
|
||||||
asn1::s1ap::cause_c& cause);
|
asn1::s1ap::cause_c& cause);
|
||||||
|
|
||||||
// Methods to apply bearer updates
|
// Methods to apply bearer updates
|
||||||
|
|
|
@ -69,9 +69,9 @@ public:
|
||||||
void send_connection_reject(procedure_result_code cause);
|
void send_connection_reject(procedure_result_code cause);
|
||||||
void send_connection_release();
|
void send_connection_release();
|
||||||
void send_connection_reest_rej(procedure_result_code cause);
|
void send_connection_reest_rej(procedure_result_code cause);
|
||||||
void send_connection_reconf(srsran::unique_byte_buffer_t sdu = {},
|
void send_connection_reconf(srsran::unique_byte_buffer_t sdu = {},
|
||||||
bool phy_cfg_updated = true,
|
bool phy_cfg_updated = true,
|
||||||
const asn1::unbounded_octstring<true>* nas_pdu = nullptr);
|
srsran::const_byte_span nas_pdu = {});
|
||||||
void send_security_mode_command();
|
void send_security_mode_command();
|
||||||
void send_ue_cap_enquiry();
|
void send_ue_cap_enquiry();
|
||||||
void send_ue_info_req();
|
void send_ue_info_req();
|
||||||
|
@ -116,17 +116,15 @@ public:
|
||||||
int release_erab(uint32_t erab_id);
|
int release_erab(uint32_t erab_id);
|
||||||
int setup_erab(uint16_t erab_id,
|
int setup_erab(uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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,
|
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
||||||
uint32_t gtpu_teid_out,
|
uint32_t gtpu_teid_out,
|
||||||
asn1::s1ap::cause_c& cause);
|
asn1::s1ap::cause_c& cause);
|
||||||
int modify_erab(uint16_t erab_id,
|
int modify_erab(uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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);
|
asn1::s1ap::cause_c& cause);
|
||||||
|
|
||||||
void notify_s1ap_ue_ctxt_setup_complete();
|
|
||||||
|
|
||||||
// Getters for PUCCH resources
|
// Getters for PUCCH resources
|
||||||
int get_cqi(uint16_t* pmi_idx, uint16_t* n_pucch, uint32_t ue_cc_idx);
|
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);
|
int get_ri(uint32_t m_ri, uint16_t* ri_idx);
|
||||||
|
|
|
@ -49,7 +49,12 @@ struct ue_ctxt_t {
|
||||||
|
|
||||||
class s1ap : public s1ap_interface_rrc
|
class s1ap : public s1ap_interface_rrc
|
||||||
{
|
{
|
||||||
|
using s1ap_proc_id_t = asn1::s1ap::s1ap_elem_procs_o::init_msg_c::types_opts::options;
|
||||||
|
|
||||||
public:
|
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_prep_timeout_ms = 10000;
|
||||||
static const uint32_t ts1_reloc_overall_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;
|
bool user_exists(uint16_t rnti) override;
|
||||||
void user_mod(uint16_t old_rnti, uint16_t new_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;
|
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 is_mme_connected() override;
|
||||||
bool send_ho_required(uint16_t rnti,
|
bool send_ho_required(uint16_t rnti,
|
||||||
uint32_t target_eci,
|
uint32_t target_eci,
|
||||||
|
@ -140,10 +145,6 @@ private:
|
||||||
|
|
||||||
asn1::s1ap::s1_setup_resp_s s1setupresponse;
|
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();
|
void build_tai_cgi();
|
||||||
bool connect_mme();
|
bool connect_mme();
|
||||||
bool setup_s1();
|
bool setup_s1();
|
||||||
|
@ -243,19 +244,18 @@ private:
|
||||||
bool has_tmsi,
|
bool has_tmsi,
|
||||||
uint32_t m_tmsi = 0,
|
uint32_t m_tmsi = 0,
|
||||||
uint8_t mmec = 0);
|
uint8_t mmec = 0);
|
||||||
bool send_initial_ctxt_setup_response(const asn1::s1ap::init_context_setup_resp_s& res_);
|
void ue_ctxt_setup_complete();
|
||||||
bool send_initial_ctxt_setup_failure();
|
bool send_erab_setup_response(const erab_id_list& erabs_setup, const erab_item_list& erabs_failed);
|
||||||
bool send_erab_setup_response(srsran::const_span<uint16_t> erabs_released,
|
bool send_erab_release_response(const erab_id_list& erabs_released, const erab_item_list& erabs_failed);
|
||||||
srsran::const_span<asn1::s1ap::erab_item_s> erabs_failed);
|
bool send_erab_modify_response(const erab_id_list& erabs_modified, const erab_item_list& 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);
|
|
||||||
bool send_erab_release_indication(const std::vector<uint16_t>& erabs_successfully_released);
|
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 send_ue_cap_info_indication(srsran::unique_byte_buffer_t ue_radio_cap);
|
||||||
|
|
||||||
bool was_uectxtrelease_requested() const { return release_requested; }
|
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 = {};
|
ue_ctxt_t ctxt = {};
|
||||||
uint16_t stream_id = 1;
|
uint16_t stream_id = 1;
|
||||||
|
|
||||||
|
@ -264,7 +264,7 @@ private:
|
||||||
srsran::plmn_id_t target_plmn_,
|
srsran::plmn_id_t target_plmn_,
|
||||||
srsran::span<uint32_t> fwd_erabs,
|
srsran::span<uint32_t> fwd_erabs,
|
||||||
srsran::unique_byte_buffer_t rrc_container);
|
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
|
// args
|
||||||
s1ap* s1ap_ptr;
|
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_prep; ///< TS1_{RELOCprep} - max time for HO preparation
|
||||||
srsran::unique_timer ts1_reloc_overall; ///< TS1_{RELOCOverall}
|
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:
|
public:
|
||||||
// user procedures
|
// user procedures
|
||||||
srsran::proc_t<ho_prep_proc_t> ho_prep_proc;
|
srsran::proc_t<ho_prep_proc_t> ho_prep_proc;
|
||||||
|
|
|
@ -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))
|
// 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) {
|
if (rrc_cfg_->cell_list.size() == 1) {
|
||||||
auto& cfg = rrc_cfg_->cell_list.at(0);
|
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;
|
cfg.dl_earfcn = args_->enb.dl_earfcn;
|
||||||
ERROR("Force DL EARFCN for cell PCI=%d to %d", cfg.pci, cfg.dl_earfcn);
|
ERROR("Force DL EARFCN for cell PCI=%d to %d", cfg.pci, cfg.dl_earfcn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
logger.info("Adding initial context for 0x%x", rnti);
|
||||||
auto user_it = users.find(rnti);
|
auto user_it = users.find(rnti);
|
||||||
|
|
||||||
if (user_it == users.end()) {
|
if (user_it == users.end()) {
|
||||||
logger.warning("Unrecognised rnti: 0x%x", rnti);
|
logger.warning("Unrecognised rnti: 0x%x", rnti);
|
||||||
return false;
|
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);
|
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);
|
auto user_it = users.find(rnti);
|
||||||
if (user_it == users.end()) {
|
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,
|
int rrc::setup_erab(uint16_t rnti,
|
||||||
uint16_t erab_id,
|
uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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,
|
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
||||||
uint32_t gtpu_teid_out,
|
uint32_t gtpu_teid_out,
|
||||||
asn1::s1ap::cause_c& cause)
|
asn1::s1ap::cause_c& cause)
|
||||||
|
@ -412,7 +411,7 @@ int rrc::setup_erab(uint16_t rnti,
|
||||||
int rrc::modify_erab(uint16_t rnti,
|
int rrc::modify_erab(uint16_t rnti,
|
||||||
uint16_t erab_id,
|
uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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)
|
asn1::s1ap::cause_c& cause)
|
||||||
{
|
{
|
||||||
logger.info("Modifying E-RAB for 0x%x. E-RAB Id %d", rnti, erab_id);
|
logger.info("Modifying E-RAB for 0x%x. E-RAB Id %d", rnti, erab_id);
|
||||||
|
|
|
@ -206,7 +206,7 @@ int bearer_cfg_handler::add_erab(uint8_t
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos,
|
const asn1::s1ap::erab_level_qos_params_s& qos,
|
||||||
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
||||||
uint32_t teid_out,
|
uint32_t teid_out,
|
||||||
const asn1::unbounded_octstring<true>* nas_pdu,
|
srsran::const_span<uint8_t> nas_pdu,
|
||||||
asn1::s1ap::cause_c& cause)
|
asn1::s1ap::cause_c& cause)
|
||||||
{
|
{
|
||||||
if (erab_id < 5) {
|
if (erab_id < 5) {
|
||||||
|
@ -266,8 +266,8 @@ int bearer_cfg_handler::add_erab(uint8_t
|
||||||
return SRSRAN_ERROR;
|
return SRSRAN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nas_pdu != nullptr and nas_pdu->size() > 0) {
|
if (not nas_pdu.empty()) {
|
||||||
erab_info_list[erab_id].assign(nas_pdu->data(), nas_pdu->data() + nas_pdu->size());
|
erab_info_list[erab_id].assign(nas_pdu.begin(), nas_pdu.end());
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,7 @@ void bearer_cfg_handler::release_erabs()
|
||||||
|
|
||||||
int bearer_cfg_handler::modify_erab(uint8_t erab_id,
|
int bearer_cfg_handler::modify_erab(uint8_t erab_id,
|
||||||
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,
|
srsran::const_span<uint8_t> nas_pdu,
|
||||||
asn1::s1ap::cause_c& cause)
|
asn1::s1ap::cause_c& cause)
|
||||||
{
|
{
|
||||||
logger->info("Modifying E-RAB %d", erab_id);
|
logger->info("Modifying E-RAB %d", erab_id);
|
||||||
|
|
|
@ -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);
|
srsran::uint8_to_uint32(erab.gtp_teid.data(), &teid_out);
|
||||||
asn1::s1ap::cause_c erab_cause;
|
asn1::s1ap::cause_c erab_cause;
|
||||||
if (rrc_ue->bearer_list.add_erab(
|
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) {
|
SRSRAN_SUCCESS) {
|
||||||
erabs_failed_to_setup.emplace_back();
|
erabs_failed_to_setup.emplace_back();
|
||||||
erabs_failed_to_setup.back().erab_id = erab.erab_id;
|
erabs_failed_to_setup.back().erab_id = erab.erab_id;
|
||||||
|
|
|
@ -291,7 +291,7 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srsran::unique_byte_buffer_t pdu)
|
||||||
break;
|
break;
|
||||||
case ul_dcch_msg_type_c::c1_c_::types::ue_cap_info:
|
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())) {
|
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));
|
send_connection_reconf(std::move(pdu));
|
||||||
state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE;
|
state = RRC_STATE_WAIT_FOR_CON_RECONF_COMPLETE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -657,9 +657,9 @@ void rrc::ue::send_connection_reest_rej(procedure_result_code cause)
|
||||||
/*
|
/*
|
||||||
* Connection Reconfiguration
|
* Connection Reconfiguration
|
||||||
*/
|
*/
|
||||||
void rrc::ue::send_connection_reconf(srsran::unique_byte_buffer_t pdu,
|
void rrc::ue::send_connection_reconf(srsran::unique_byte_buffer_t pdu,
|
||||||
bool phy_cfg_updated,
|
bool phy_cfg_updated,
|
||||||
const asn1::unbounded_octstring<true>* nas_pdu)
|
srsran::const_byte_span nas_pdu)
|
||||||
{
|
{
|
||||||
parent->logger.debug("RRC state %d", state);
|
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);
|
mac_ctrl.handle_con_reconf(recfg_r8, ue_capabilities);
|
||||||
|
|
||||||
// Fill in NAS PDU - Only for RRC Connection Reconfiguration during E-RAB Release Command
|
// 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_present = true;
|
||||||
recfg_r8.ded_info_nas_list.resize(recfg_r8.rr_cfg_ded.drb_to_release_list.size());
|
recfg_r8.ded_info_nas_list.resize(recfg_r8.rr_cfg_ded.drb_to_release_list.size());
|
||||||
// Add NAS PDU
|
// Add NAS PDU
|
||||||
for (uint32_t idx = 0; idx < recfg_r8.rr_cfg_ded.drb_to_release_list.size(); idx++) {
|
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());
|
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());
|
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 RRC security mode command
|
||||||
send_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)
|
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;
|
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)
|
void rrc::ue::set_bitrates(const asn1::s1ap::ue_aggregate_maximum_bitrate_s& rates)
|
||||||
{
|
{
|
||||||
bitrates = 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;
|
uint32_t teid_out = 0;
|
||||||
srsran::uint8_to_uint32(erab.gtp_teid.data(), &teid_out);
|
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;
|
srsran::const_span<uint8_t> nas_pdu;
|
||||||
asn1::s1ap::cause_c cause;
|
if (erab.nas_pdu_present) {
|
||||||
|
nas_pdu = erab.nas_pdu;
|
||||||
|
}
|
||||||
|
asn1::s1ap::cause_c cause;
|
||||||
bearer_list.add_erab(
|
bearer_list.add_erab(
|
||||||
erab.erab_id, erab.erab_level_qos_params, erab.transport_layer_address, teid_out, nas_pdu, cause);
|
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);
|
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,
|
int rrc::ue::setup_erab(uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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,
|
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
||||||
uint32_t gtpu_teid_out,
|
uint32_t gtpu_teid_out,
|
||||||
asn1::s1ap::cause_c& cause)
|
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,
|
int rrc::ue::modify_erab(uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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)
|
asn1::s1ap::cause_c& cause)
|
||||||
{
|
{
|
||||||
return bearer_list.modify_erab(erab_id, qos_params, nas_pdu, cause);
|
return bearer_list.modify_erab(erab_id, qos_params, nas_pdu, cause);
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "srsenb/hdr/stack/upper/s1ap.h"
|
#include "srsenb/hdr/stack/upper/s1ap.h"
|
||||||
#include "srsenb/hdr/common/common_enb.h"
|
|
||||||
#include "srsran/adt/scope_exit.h"
|
#include "srsran/adt/scope_exit.h"
|
||||||
#include "srsran/common/bcd_helpers.h"
|
#include "srsran/common/bcd_helpers.h"
|
||||||
#include "srsran/common/enb_events.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();
|
}) != failed_cfg_erabs.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sanitize_response_erab_lists(srsran::bounded_vector<erab_item_s, ASN1_S1AP_MAXNOOF_ERABS>& failed_cfg_erabs,
|
void sanitize_response_erab_lists(s1ap::erab_item_list& failed_cfg_erabs, s1ap::erab_id_list& erabs)
|
||||||
srsran::bounded_vector<uint16_t, ASN1_S1AP_MAXNOOF_ERABS>& erabs)
|
|
||||||
{
|
{
|
||||||
// Sort and remove duplicates
|
// Sort and remove duplicates
|
||||||
std::sort(failed_cfg_erabs.begin(), failed_cfg_erabs.end(), &lower_obj_id<erab_item_s>);
|
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());
|
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"
|
* 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;
|
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);
|
ue* u = users.find_ue_rnti(rnti);
|
||||||
if (u == nullptr) {
|
if (u == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (res.protocol_ies.erab_setup_list_ctxt_su_res.value.size() > 0) {
|
u->ue_ctxt_setup_complete();
|
||||||
u->send_initial_ctxt_setup_response(res);
|
|
||||||
} else {
|
|
||||||
u->send_initial_ctxt_setup_failure();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool s1ap::is_mme_connected()
|
bool s1ap::is_mme_connected()
|
||||||
|
@ -735,6 +739,44 @@ bool s1ap::handle_initialctxtsetuprequest(const init_context_setup_request_s& ms
|
||||||
return false;
|
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)" */
|
/* 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_present) {
|
||||||
if (msg.protocol_ies.cs_fallback_ind.value.value == cs_fallback_ind_opts::cs_fallback_required ||
|
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;
|
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);
|
rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg.protocol_ies.ueaggregate_maximum_bitrate.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
failed_cfg_erabs.clear();
|
erab_id_list updated_erabs;
|
||||||
updated_erabs.clear();
|
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);
|
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) {
|
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,
|
if (rrc->setup_erab(u->ctxt.rnti,
|
||||||
erab.erab_id,
|
erab.erab_id,
|
||||||
erab.erab_level_qos_params,
|
erab.erab_level_qos_params,
|
||||||
&erab.nas_pdu,
|
erab.nas_pdu,
|
||||||
erab.transport_layer_address,
|
erab.transport_layer_address,
|
||||||
erab.gtp_teid.to_number(),
|
erab.gtp_teid.to_number(),
|
||||||
cause) == SRSRAN_SUCCESS) {
|
cause) == SRSRAN_SUCCESS) {
|
||||||
|
@ -812,7 +858,7 @@ bool s1ap::handle_erabsetuprequest(const erab_setup_request_s& msg)
|
||||||
|
|
||||||
// Notify UE of updates
|
// Notify UE of updates
|
||||||
if (not updated_erabs.empty()) {
|
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);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
failed_cfg_erabs.clear();
|
if (msg.protocol_ies.ueaggregate_maximum_bitrate_present) {
|
||||||
updated_erabs.clear();
|
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);
|
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) {
|
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");
|
WarnUnsupportFeature(erab.ie_exts_present, "E-RABToBeSetupListBearerSUReq extensions");
|
||||||
|
|
||||||
cause_c cause;
|
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) {
|
SRSRAN_SUCCESS) {
|
||||||
updated_erabs.push_back(erab.erab_id);
|
updated_erabs.push_back(erab.erab_id);
|
||||||
} else {
|
} else {
|
||||||
|
@ -855,16 +905,12 @@ bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg)
|
||||||
|
|
||||||
// Notify UE of updates
|
// Notify UE of updates
|
||||||
if (not updated_erabs.empty()) {
|
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
|
// send E-RAB modify response back to the mme
|
||||||
sanitize_response_erab_lists(failed_cfg_erabs, updated_erabs);
|
sanitize_response_erab_lists(failed_cfg_erabs, updated_erabs);
|
||||||
if (not u->send_erab_modify_response(updated_erabs, failed_cfg_erabs)) {
|
return u->send_erab_modify_response(updated_erabs, failed_cfg_erabs);
|
||||||
logger.info("failed to send erabreleaseresponse");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -884,10 +930,10 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
failed_cfg_erabs.clear();
|
erab_id_list updated_erabs;
|
||||||
updated_erabs.clear();
|
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
|
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) {
|
(std::any_of(failed_cfg_erabs.begin(), failed_cfg_erabs.end(), [erab_id](const erab_item_s& e) {
|
||||||
return e.erab_id == erab_id;
|
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.
|
// Notify RRC of E-RAB update. (RRC reconf message is going to be sent.
|
||||||
if (not updated_erabs.empty()) {
|
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
|
// 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;
|
ue* u = nullptr;
|
||||||
if (msg.protocol_ies.ue_s1ap_ids.value.type().value == ue_s1ap_ids_c::types_opts::ue_s1ap_id_pair) {
|
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) {
|
if (idpair.ext) {
|
||||||
logger.warning("Not handling S1AP message extension");
|
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");
|
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) {
|
if (current_state != s1ap_elem_procs_o::init_msg_c::types_opts::init_context_setup_request) {
|
||||||
return false;
|
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;
|
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
|
container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id;
|
||||||
tx_pdu.successful_outcome().value.init_context_setup_resp() = res_;
|
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
|
// 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.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value();
|
||||||
container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id;
|
container.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id;
|
||||||
|
|
||||||
// Fill in the GTP bind address for all bearers
|
// Add list of E-RABs that were not setup
|
||||||
for (uint32_t i = 0; i < container.erab_setup_list_ctxt_su_res.value.size(); ++i) {
|
if (not failed_cfg_erabs.empty()) {
|
||||||
auto& item = container.erab_setup_list_ctxt_su_res.value[i].value.erab_setup_item_ctxt_su_res();
|
container.erab_failed_to_setup_list_ctxt_su_res_present = true;
|
||||||
item.transport_layer_address.resize(32);
|
fill_erab_failed_setup_list(container.erab_failed_to_setup_list_ctxt_su_res.value, failed_cfg_erabs);
|
||||||
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) {
|
// Add setup E-RABs
|
||||||
item.transport_layer_address.data()[j] = addr[3 - j];
|
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.
|
// 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);
|
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,
|
bool s1ap::ue::send_erab_setup_response(const erab_id_list& erabs_setup, const erab_item_list& erabs_failed)
|
||||||
srsran::const_span<asn1::s1ap::erab_item_s> erabs_failed)
|
|
||||||
{
|
{
|
||||||
asn1::s1ap::s1ap_pdu_c tx_pdu;
|
asn1::s1ap::s1ap_pdu_c tx_pdu;
|
||||||
tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_ERAB_SETUP);
|
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
|
// Add list of E-RABs that were not setup
|
||||||
if (not erabs_failed.empty()) {
|
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_present = true;
|
||||||
res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value.resize(erabs_failed.size());
|
fill_erab_failed_setup_list(res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value, erabs_failed);
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (not erabs_setup.empty()) {
|
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);
|
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();
|
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];
|
item.erab_id = erabs_setup[i];
|
||||||
uint32_t teid_in;
|
get_erab_addr(item.erab_id, item.transport_layer_address, item.gtp_teid);
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E_RABSetupResponse");
|
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()
|
bool s1ap::ue::send_uectxtmodifyresp()
|
||||||
{
|
{
|
||||||
if (not s1ap_ptr->mme_connected) {
|
if (not s1ap_ptr->mme_connected) {
|
||||||
|
@ -1534,8 +1560,7 @@ bool s1ap::ue::send_uectxtmodifyfailure(const cause_c& cause)
|
||||||
* @param erabs_failed_to_release
|
* @param erabs_failed_to_release
|
||||||
* @return true if message was sent
|
* @return true if message was sent
|
||||||
*/
|
*/
|
||||||
bool s1ap::ue::send_erab_release_response(srsran::const_span<uint16_t> erabs_released,
|
bool s1ap::ue::send_erab_release_response(const erab_id_list& erabs_released, const erab_item_list& erabs_failed)
|
||||||
srsran::const_span<asn1::s1ap::erab_item_s> erabs_failed)
|
|
||||||
{
|
{
|
||||||
asn1::s1ap::s1ap_pdu_c tx_pdu;
|
asn1::s1ap::s1ap_pdu_c tx_pdu;
|
||||||
tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_ERAB_RELEASE);
|
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
|
// Fill in which E-RABs were *not* successfully released
|
||||||
if (not erabs_failed.empty()) {
|
if (not erabs_failed.empty()) {
|
||||||
container.erab_failed_to_release_list_present = true;
|
container.erab_failed_to_release_list_present = true;
|
||||||
container.erab_failed_to_release_list.value.resize(erabs_failed.size());
|
fill_erab_failed_setup_list(container.erab_failed_to_release_list.value, erabs_failed);
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E-RABReleaseResponse");
|
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,
|
bool s1ap::ue::send_erab_modify_response(const erab_id_list& erabs_modified, const erab_item_list& erabs_failed)
|
||||||
srsran::const_span<erab_item_s> erabs_failed_to_modify)
|
|
||||||
{
|
{
|
||||||
asn1::s1ap::s1ap_pdu_c tx_pdu;
|
asn1::s1ap::s1ap_pdu_c tx_pdu;
|
||||||
tx_pdu.set_successful_outcome().load_info_obj(ASN1_S1AP_ID_ERAB_MODIFY);
|
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
|
// 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_present = true;
|
||||||
container.erab_failed_to_modify_list.value.resize(erabs_failed_to_modify.size());
|
fill_erab_failed_setup_list(container.erab_failed_to_modify_list.value, erabs_failed);
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "E-RABModifyResponse");
|
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");
|
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
|
* Handover Messages
|
||||||
********************/
|
********************/
|
||||||
|
|
|
@ -104,7 +104,7 @@ public:
|
||||||
void write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) override {}
|
void write_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) override {}
|
||||||
bool user_exists(uint16_t rnti) override { return true; }
|
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; }
|
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 is_mme_connected() override { return true; }
|
||||||
bool send_ho_required(uint16_t rnti,
|
bool send_ho_required(uint16_t rnti,
|
||||||
uint32_t target_eci,
|
uint32_t target_eci,
|
||||||
|
@ -175,7 +175,7 @@ public:
|
||||||
int setup_erab(uint16_t rnti,
|
int setup_erab(uint16_t rnti,
|
||||||
uint16_t erab_id,
|
uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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,
|
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
||||||
uint32_t gtpu_teid_out,
|
uint32_t gtpu_teid_out,
|
||||||
asn1::s1ap::cause_c& cause) override
|
asn1::s1ap::cause_c& cause) override
|
||||||
|
@ -185,7 +185,7 @@ public:
|
||||||
int modify_erab(uint16_t rnti,
|
int modify_erab(uint16_t rnti,
|
||||||
uint16_t erab_id,
|
uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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
|
asn1::s1ap::cause_c& cause) override
|
||||||
{
|
{
|
||||||
return SRSRAN_SUCCESS;
|
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 {}
|
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 { return SRSRAN_SUCCESS; }
|
||||||
{
|
|
||||||
return SRSRAN_SUCCESS;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace srsenb
|
} // namespace srsenb
|
||||||
|
|
|
@ -98,7 +98,7 @@ int test_erab_setup(srsran::log_sink_spy& spy, bool qci_exists)
|
||||||
int ret = rrc.setup_erab(rnti,
|
int ret = rrc.setup_erab(rnti,
|
||||||
erab.erab_id,
|
erab.erab_id,
|
||||||
erab.erab_level_qos_params,
|
erab.erab_level_qos_params,
|
||||||
&erab.nas_pdu,
|
erab.nas_pdu,
|
||||||
erab.transport_layer_address,
|
erab.transport_layer_address,
|
||||||
erab.gtp_teid.to_number(),
|
erab.gtp_teid.to_number(),
|
||||||
cause);
|
cause);
|
||||||
|
|
|
@ -94,7 +94,7 @@ struct rrc_tester : public rrc_dummy {
|
||||||
int modify_erab(uint16_t rnti,
|
int modify_erab(uint16_t rnti,
|
||||||
uint16_t erab_id,
|
uint16_t erab_id,
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
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
|
asn1::s1ap::cause_c& cause) override
|
||||||
{
|
{
|
||||||
if (std::count(next_erabs_failed_to_modify.begin(), next_erabs_failed_to_modify.end(), erab_id) > 0) {
|
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};
|
0x40, 0x0a, 0x0a, 0x1f, 0x7f, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01};
|
||||||
cbref = asn1::cbit_ref(icsresp, sizeof(icsresp));
|
cbref = asn1::cbit_ref(icsresp, sizeof(icsresp));
|
||||||
TESTASSERT(s1ap_pdu.unpack(cbref) == SRSRAN_SUCCESS);
|
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();
|
sdu = mme.read_msg();
|
||||||
TESTASSERT(sdu->N_bytes > 0);
|
TESTASSERT(sdu->N_bytes > 0);
|
||||||
cbref = asn1::cbit_ref{sdu->msg, sdu->N_bytes};
|
cbref = asn1::cbit_ref{sdu->msg, sdu->N_bytes};
|
||||||
TESTASSERT(s1ap_pdu.unpack(cbref) == SRSRAN_SUCCESS);
|
TESTASSERT(s1ap_pdu.unpack(cbref) == SRSRAN_SUCCESS);
|
||||||
TESTASSERT(s1ap_pdu.type().value == asn1::s1ap::s1ap_pdu_c::types_opts::successful_outcome);
|
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);
|
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 };
|
enum class test_event { success, wrong_erabid_mod, wrong_mme_s1ap_id, repeated_erabid_mod };
|
||||||
|
|
|
@ -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);
|
asn1::cbit_ref bref(byte_buf.msg, byte_buf.N_bytes);
|
||||||
TESTASSERT(s1ap_pdu.unpack(bref) == asn1::SRSASN_SUCCESS);
|
TESTASSERT(s1ap_pdu.unpack(bref) == asn1::SRSASN_SUCCESS);
|
||||||
rrc.setup_ue_ctxt(rnti, s1ap_pdu.init_msg().value.init_context_setup_request());
|
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();
|
timers.step_all();
|
||||||
rrc.tti_clock();
|
rrc.tti_clock();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue