mirror of https://github.com/PentHertz/srsLTE.git
s1ap - simplified erab setup procedure. Handle correctly the failure to setup causes
This commit is contained in:
parent
f401683960
commit
66988ffd32
|
@ -41,6 +41,7 @@ struct erab_admitted_item_s;
|
||||||
struct erab_to_be_modified_item_bearer_mod_req_s;
|
struct erab_to_be_modified_item_bearer_mod_req_s;
|
||||||
struct cause_c;
|
struct cause_c;
|
||||||
struct erab_item_s;
|
struct erab_item_s;
|
||||||
|
struct ue_aggregate_maximum_bitrate_s;
|
||||||
|
|
||||||
template <class ies_set_paramT_>
|
template <class ies_set_paramT_>
|
||||||
struct protocol_ie_single_container_s;
|
struct protocol_ie_single_container_s;
|
||||||
|
@ -71,4 +72,10 @@ bool equal_obj_id(const T& lhs, const T& rhs)
|
||||||
} // namespace s1ap
|
} // namespace s1ap
|
||||||
} // namespace asn1
|
} // namespace asn1
|
||||||
|
|
||||||
|
namespace srsenb {
|
||||||
|
|
||||||
|
using transp_addr_t = asn1::bounded_bitstring<1, 160, true, true>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif // SRSRAN_S1AP_UTILS_H
|
#endif // SRSRAN_S1AP_UTILS_H
|
||||||
|
|
|
@ -29,10 +29,22 @@ public:
|
||||||
virtual void release_ue(uint16_t rnti) = 0;
|
virtual void release_ue(uint16_t rnti) = 0;
|
||||||
virtual bool setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_request_s& msg) = 0;
|
virtual bool setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_request_s& msg) = 0;
|
||||||
virtual bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) = 0;
|
virtual bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) = 0;
|
||||||
virtual bool setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& msg) = 0;
|
|
||||||
virtual bool has_erab(uint16_t rnti, uint32_t erab_id) const = 0;
|
virtual bool has_erab(uint16_t rnti, uint32_t erab_id) const = 0;
|
||||||
virtual bool release_erabs(uint32_t rnti) = 0;
|
virtual bool release_erabs(uint32_t rnti) = 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;
|
||||||
|
/**
|
||||||
|
* TS 36.413, 8.2.1 - Setup E-RAB
|
||||||
|
* @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,
|
||||||
|
const transp_addr_t& addr,
|
||||||
|
uint32_t gtpu_teid_out,
|
||||||
|
asn1::s1ap::cause_c& cause) = 0;
|
||||||
/**
|
/**
|
||||||
* TS 36.413, 8.2.2 - Modify E-RAB
|
* TS 36.413, 8.2.2 - Modify E-RAB
|
||||||
* @return if error, cause argument is updated with cause
|
* @return if error, cause argument is updated with cause
|
||||||
|
|
|
@ -57,7 +57,6 @@ public:
|
||||||
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 void ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_setup_resp_s& res) = 0;
|
||||||
virtual void ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::erab_setup_resp_s& res) = 0;
|
|
||||||
virtual bool is_mme_connected() = 0;
|
virtual bool is_mme_connected() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,6 +29,13 @@ uint32_t get_obj_id<protocol_ie_single_container_s<erab_to_be_setup_item_ctxt_su
|
||||||
return obj.value.erab_to_be_setup_item_ctxt_su_req().erab_id;
|
return obj.value.erab_to_be_setup_item_ctxt_su_req().erab_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
uint32_t get_obj_id<protocol_ie_single_container_s<erab_to_be_setup_item_bearer_su_req_ies_o> >(
|
||||||
|
const protocol_ie_single_container_s<erab_to_be_setup_item_bearer_su_req_ies_o>& obj)
|
||||||
|
{
|
||||||
|
return obj.value.erab_to_be_setup_item_bearer_su_req().erab_id;
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
uint32_t get_obj_id<protocol_ie_single_container_s<erab_to_be_modified_item_bearer_mod_req_ies_o> >(
|
uint32_t get_obj_id<protocol_ie_single_container_s<erab_to_be_modified_item_bearer_mod_req_ies_o> >(
|
||||||
const protocol_ie_single_container_s<erab_to_be_modified_item_bearer_mod_req_ies_o>& obj)
|
const protocol_ie_single_container_s<erab_to_be_modified_item_bearer_mod_req_ies_o>& obj)
|
||||||
|
|
|
@ -81,8 +81,16 @@ public:
|
||||||
void release_ue(uint16_t rnti) override;
|
void release_ue(uint16_t rnti) override;
|
||||||
bool setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_request_s& msg) override;
|
bool setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_request_s& msg) override;
|
||||||
bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) override;
|
bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) override;
|
||||||
bool setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& msg) override;
|
|
||||||
bool has_erab(uint16_t rnti, uint32_t erab_id) const override;
|
bool has_erab(uint16_t rnti, uint32_t erab_id) const override;
|
||||||
|
int get_erab_addr_in(uint16_t rnti, uint16_t erab_id, transp_addr_t& addr_in, uint32_t& teid_in) const override;
|
||||||
|
void set_aggregate_max_bitrate(uint16_t rnti, const asn1::s1ap::ue_aggregate_maximum_bitrate_s& bitrate) override;
|
||||||
|
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,
|
||||||
|
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,
|
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,
|
||||||
|
|
|
@ -53,9 +53,6 @@ public:
|
||||||
///< Helper to access a cell cfg based on ue_cc_idx
|
///< Helper to access a cell cfg based on ue_cc_idx
|
||||||
enb_cell_common* get_ue_cc_cfg(uint32_t ue_cc_idx);
|
enb_cell_common* get_ue_cc_cfg(uint32_t ue_cc_idx);
|
||||||
|
|
||||||
/// Helper to check UE ERABs
|
|
||||||
bool has_erab(uint32_t erab_id) const { return bearer_list.get_erabs().count(erab_id) > 0; }
|
|
||||||
|
|
||||||
/// List of results a RRC procedure may produce.
|
/// List of results a RRC procedure may produce.
|
||||||
enum class procedure_result_code {
|
enum class procedure_result_code {
|
||||||
none,
|
none,
|
||||||
|
@ -110,17 +107,25 @@ public:
|
||||||
|
|
||||||
void set_bitrates(const asn1::s1ap::ue_aggregate_maximum_bitrate_s& rates);
|
void set_bitrates(const asn1::s1ap::ue_aggregate_maximum_bitrate_s& rates);
|
||||||
|
|
||||||
|
/// Helper to check UE ERABs
|
||||||
|
bool has_erab(uint32_t erab_id) const { return bearer_list.get_erabs().count(erab_id) > 0; }
|
||||||
|
int get_erab_addr_in(uint16_t erab_id, transp_addr_t& addr_in, uint32_t& teid_in) const;
|
||||||
|
|
||||||
bool setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l& e);
|
bool setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l& e);
|
||||||
bool setup_erabs(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_l& e);
|
|
||||||
bool release_erabs();
|
bool release_erabs();
|
||||||
int release_erab(uint32_t erab_id);
|
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,
|
||||||
|
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,
|
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,
|
const asn1::unbounded_octstring<true>* nas_pdu,
|
||||||
asn1::s1ap::cause_c& cause);
|
asn1::s1ap::cause_c& cause);
|
||||||
|
|
||||||
void notify_s1ap_ue_ctxt_setup_complete();
|
void notify_s1ap_ue_ctxt_setup_complete();
|
||||||
void notify_s1ap_ue_erab_setup_response(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_l& e);
|
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
|
@ -76,7 +76,6 @@ public:
|
||||||
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, const asn1::s1ap::init_context_setup_resp_s& res) override;
|
||||||
void ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::erab_setup_resp_s& res) 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,
|
||||||
|
@ -246,7 +245,8 @@ private:
|
||||||
uint8_t mmec = 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_response(const asn1::s1ap::init_context_setup_resp_s& res_);
|
||||||
bool send_initial_ctxt_setup_failure();
|
bool send_initial_ctxt_setup_failure();
|
||||||
bool send_erab_setup_response(const asn1::s1ap::erab_setup_resp_s& res_);
|
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,
|
bool send_erab_release_response(srsran::const_span<uint16_t> erabs_released,
|
||||||
srsran::const_span<asn1::s1ap::erab_item_s> erabs_failed);
|
srsran::const_span<asn1::s1ap::erab_item_s> erabs_failed);
|
||||||
bool send_erab_modify_response(srsran::const_span<uint16_t> erabs_modified,
|
bool send_erab_modify_response(srsran::const_span<uint16_t> erabs_modified,
|
||||||
|
|
|
@ -323,27 +323,6 @@ bool rrc::modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request
|
||||||
return user_it->second->handle_ue_ctxt_mod_req(msg);
|
return user_it->second->handle_ue_ctxt_mod_req(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rrc::setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& msg)
|
|
||||||
{
|
|
||||||
logger.info("Setting up erab(s) for 0x%x", rnti);
|
|
||||||
auto user_it = users.find(rnti);
|
|
||||||
|
|
||||||
if (user_it == users.end()) {
|
|
||||||
logger.warning("Unrecognised rnti: 0x%x", rnti);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg.protocol_ies.ueaggregate_maximum_bitrate_present) {
|
|
||||||
// UEAggregateMaximumBitrate
|
|
||||||
user_it->second->set_bitrates(msg.protocol_ies.ueaggregate_maximum_bitrate.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup E-RABs
|
|
||||||
user_it->second->setup_erabs(msg.protocol_ies.erab_to_be_setup_list_bearer_su_req.value);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool rrc::release_erabs(uint32_t rnti)
|
bool rrc::release_erabs(uint32_t rnti)
|
||||||
{
|
{
|
||||||
logger.info("Releasing E-RABs for 0x%x", rnti);
|
logger.info("Releasing E-RABs for 0x%x", rnti);
|
||||||
|
@ -392,6 +371,44 @@ bool rrc::has_erab(uint16_t rnti, uint32_t erab_id) const
|
||||||
return user_it->second->has_erab(erab_id);
|
return user_it->second->has_erab(erab_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rrc::get_erab_addr_in(uint16_t rnti, uint16_t erab_id, transp_addr_t& addr_in, uint32_t& teid_in) const
|
||||||
|
{
|
||||||
|
auto user_it = users.find(rnti);
|
||||||
|
if (user_it == users.end()) {
|
||||||
|
logger.warning("Unrecognised rnti: 0x%x", rnti);
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
return user_it->second->get_erab_addr_in(erab_id, addr_in, teid_in);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rrc::set_aggregate_max_bitrate(uint16_t rnti, const asn1::s1ap::ue_aggregate_maximum_bitrate_s& bitrate)
|
||||||
|
{
|
||||||
|
auto user_it = users.find(rnti);
|
||||||
|
if (user_it == users.end()) {
|
||||||
|
logger.warning("Unrecognised rnti: 0x%x", rnti);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
user_it->second->set_bitrates(bitrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
||||||
|
uint32_t gtpu_teid_out,
|
||||||
|
asn1::s1ap::cause_c& cause)
|
||||||
|
{
|
||||||
|
logger.info("Setting up erab id=%d for 0x%x", erab_id, rnti);
|
||||||
|
auto user_it = users.find(rnti);
|
||||||
|
if (user_it == users.end()) {
|
||||||
|
logger.warning("Unrecognised rnti: 0x%x", rnti);
|
||||||
|
cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::unknown_erab_id;
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
return user_it->second->setup_erab(erab_id, qos_params, nas_pdu, addr, gtpu_teid_out, cause);
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|
|
@ -992,7 +992,7 @@ void rrc::ue::set_bitrates(const asn1::s1ap::ue_aggregate_maximum_bitrate_s& rat
|
||||||
bool rrc::ue::setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l& e)
|
bool rrc::ue::setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l& e)
|
||||||
{
|
{
|
||||||
for (const auto& item : e) {
|
for (const auto& item : e) {
|
||||||
auto& erab = item.value.erab_to_be_setup_item_ctxt_su_req();
|
const auto& erab = item.value.erab_to_be_setup_item_ctxt_su_req();
|
||||||
if (erab.ext) {
|
if (erab.ext) {
|
||||||
parent->logger.warning("Not handling E-RABToBeSetupListCtxtSURequest extensions");
|
parent->logger.warning("Not handling E-RABToBeSetupListCtxtSURequest extensions");
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1004,7 @@ bool rrc::ue::setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l&
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t teid_out;
|
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;
|
const asn1::unbounded_octstring<true>* nas_pdu = erab.nas_pdu_present ? &erab.nas_pdu : nullptr;
|
||||||
asn1::s1ap::cause_c cause;
|
asn1::s1ap::cause_c cause;
|
||||||
|
@ -1015,35 +1015,6 @@ bool rrc::ue::setup_erabs(const asn1::s1ap::erab_to_be_setup_list_ctxt_su_req_l&
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rrc::ue::setup_erabs(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_l& e)
|
|
||||||
{
|
|
||||||
for (const auto& item : e) {
|
|
||||||
auto& erab = item.value.erab_to_be_setup_item_bearer_su_req();
|
|
||||||
if (erab.ext) {
|
|
||||||
parent->logger.warning("Not handling E-RABToBeSetupListBearerSUReq extensions");
|
|
||||||
}
|
|
||||||
if (erab.ie_exts_present) {
|
|
||||||
parent->logger.warning("Not handling E-RABToBeSetupListBearerSUReq extensions");
|
|
||||||
}
|
|
||||||
if (erab.transport_layer_address.length() > 32) {
|
|
||||||
parent->logger.error("IPv6 addresses not currently supported");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t teid_out;
|
|
||||||
srsran::uint8_to_uint32(erab.gtp_teid.data(), &teid_out);
|
|
||||||
asn1::s1ap::cause_c cause;
|
|
||||||
bearer_list.add_erab(
|
|
||||||
erab.erab_id, erab.erab_level_qos_params, erab.transport_layer_address, teid_out, &erab.nas_pdu, cause);
|
|
||||||
bearer_list.add_gtpu_bearer(erab.erab_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Work in progress
|
|
||||||
notify_s1ap_ue_erab_setup_response(e);
|
|
||||||
send_connection_reconf(nullptr, false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool rrc::ue::release_erabs()
|
bool rrc::ue::release_erabs()
|
||||||
{
|
{
|
||||||
bearer_list.release_erabs();
|
bearer_list.release_erabs();
|
||||||
|
@ -1055,6 +1026,39 @@ int rrc::ue::release_erab(uint32_t erab_id)
|
||||||
return bearer_list.release_erab(erab_id);
|
return bearer_list.release_erab(erab_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rrc::ue::get_erab_addr_in(uint16_t erab_id, transp_addr_t& addr_in, uint32_t& teid_in) const
|
||||||
|
{
|
||||||
|
auto it = bearer_list.get_erabs().find(erab_id);
|
||||||
|
if (it == bearer_list.get_erabs().end()) {
|
||||||
|
parent->logger.error("E-RAB id=%d for rnti=0x%x not found", erab_id, rnti);
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
addr_in = it->second.address;
|
||||||
|
teid_in = it->second.teid_in;
|
||||||
|
return SRSRAN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
||||||
|
uint32_t gtpu_teid_out,
|
||||||
|
asn1::s1ap::cause_c& cause)
|
||||||
|
{
|
||||||
|
if (bearer_list.get_erabs().count(erab_id) > 0) {
|
||||||
|
cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::multiple_erab_id_instances;
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
if (bearer_list.add_erab(erab_id, qos_params, addr, gtpu_teid_out, nas_pdu, cause) != SRSRAN_SUCCESS) {
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
if (bearer_list.add_gtpu_bearer(erab_id) != SRSRAN_SUCCESS) {
|
||||||
|
cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::radio_res_not_available;
|
||||||
|
return SRSRAN_ERROR;
|
||||||
|
}
|
||||||
|
return SRSRAN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
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,
|
const asn1::unbounded_octstring<true>* nas_pdu,
|
||||||
|
@ -1063,35 +1067,6 @@ int rrc::ue::modify_erab(uint16_t erab_id,
|
||||||
return bearer_list.modify_erab(erab_id, qos_params, nas_pdu, cause);
|
return bearer_list.modify_erab(erab_id, qos_params, nas_pdu, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rrc::ue::notify_s1ap_ue_erab_setup_response(const asn1::s1ap::erab_to_be_setup_list_bearer_su_req_l& e)
|
|
||||||
{
|
|
||||||
asn1::s1ap::erab_setup_resp_s res;
|
|
||||||
|
|
||||||
const auto& erabs = bearer_list.get_erabs();
|
|
||||||
for (const auto& erab : e) {
|
|
||||||
uint8_t id = erab.value.erab_to_be_setup_item_bearer_su_req().erab_id;
|
|
||||||
if (erabs.count(id)) {
|
|
||||||
res.protocol_ies.erab_setup_list_bearer_su_res_present = true;
|
|
||||||
res.protocol_ies.erab_setup_list_bearer_su_res.value.push_back({});
|
|
||||||
auto& item = res.protocol_ies.erab_setup_list_bearer_su_res.value.back();
|
|
||||||
item.load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_BEARER_SU_RES);
|
|
||||||
item.value.erab_setup_item_bearer_su_res().erab_id = id;
|
|
||||||
srsran::uint32_to_uint8(bearer_list.get_erabs().at(id).teid_in,
|
|
||||||
&item.value.erab_setup_item_bearer_su_res().gtp_teid[0]);
|
|
||||||
} else {
|
|
||||||
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.push_back({});
|
|
||||||
auto& item = res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value.back();
|
|
||||||
item.load_info_obj(ASN1_S1AP_ID_ERAB_ITEM);
|
|
||||||
item.value.erab_item().erab_id = id;
|
|
||||||
item.value.erab_item().cause.set_radio_network().value =
|
|
||||||
asn1::s1ap::cause_radio_network_opts::invalid_qos_combination;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parent->s1ap->ue_erab_setup_complete(rnti, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Helper method to access Cell configuration based on UE Carrier Index
|
//! Helper method to access Cell configuration based on UE Carrier Index
|
||||||
enb_cell_common* rrc::ue::get_ue_cc_cfg(uint32_t ue_cc_idx)
|
enb_cell_common* rrc::ue::get_ue_cc_cfg(uint32_t ue_cc_idx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,7 +67,7 @@ void add_repeated_erab_ids(const List&
|
||||||
{
|
{
|
||||||
for (auto it = list.begin(); it != list.end(); ++it) {
|
for (auto it = list.begin(); it != list.end(); ++it) {
|
||||||
for (auto it2 = it + 1; it2 != list.end(); ++it2) {
|
for (auto it2 = it + 1; it2 != list.end(); ++it2) {
|
||||||
if (get_obj_id(*it) == get_obj_id(*it2)) {
|
if (equal_obj_id(*it, *it2)) {
|
||||||
failed_cfg_erabs.push_back(erab_item_s());
|
failed_cfg_erabs.push_back(erab_item_s());
|
||||||
failed_cfg_erabs.back().erab_id = get_obj_id(*it);
|
failed_cfg_erabs.back().erab_id = get_obj_id(*it);
|
||||||
failed_cfg_erabs.back().cause.set_radio_network().value = cause_radio_network_opts::multiple_erab_id_instances;
|
failed_cfg_erabs.back().cause.set_radio_network().value = cause_radio_network_opts::multiple_erab_id_instances;
|
||||||
|
@ -90,6 +90,17 @@ 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,
|
||||||
|
srsran::bounded_vector<uint16_t, ASN1_S1AP_MAXNOOF_ERABS>& erabs)
|
||||||
|
{
|
||||||
|
// Sort and remove duplicates
|
||||||
|
std::sort(failed_cfg_erabs.begin(), failed_cfg_erabs.end(), &lower_obj_id<erab_item_s>);
|
||||||
|
failed_cfg_erabs.erase(std::unique(failed_cfg_erabs.begin(), failed_cfg_erabs.end(), &equal_obj_id<erab_item_s>),
|
||||||
|
failed_cfg_erabs.end());
|
||||||
|
std::sort(erabs.begin(), erabs.end());
|
||||||
|
erabs.erase(std::unique(erabs.begin(), erabs.end()), erabs.end());
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************
|
/*********************************************************
|
||||||
* TS 36.413 - Section 8.4.1 - "Handover Preparation"
|
* TS 36.413 - Section 8.4.1 - "Handover Preparation"
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
@ -445,16 +456,6 @@ void s1ap::ue_ctxt_setup_complete(uint16_t rnti, const asn1::s1ap::init_context_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void s1ap::ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::erab_setup_resp_s& res)
|
|
||||||
{
|
|
||||||
ue* u = users.find_ue_rnti(rnti);
|
|
||||||
if (u == nullptr) {
|
|
||||||
logger.error("rnti 0x%x not found", rnti);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
u->send_erab_setup_response(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool s1ap::is_mme_connected()
|
bool s1ap::is_mme_connected()
|
||||||
{
|
{
|
||||||
return mme_connected;
|
return mme_connected;
|
||||||
|
@ -768,8 +769,54 @@ bool s1ap::handle_erabsetuprequest(const erab_setup_request_s& msg)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup UE ctxt in RRC
|
if (msg.protocol_ies.ueaggregate_maximum_bitrate_present) {
|
||||||
return rrc->setup_ue_erabs(u->ctxt.rnti, msg);
|
rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg.protocol_ies.ueaggregate_maximum_bitrate.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
failed_cfg_erabs.clear();
|
||||||
|
updated_erabs.clear();
|
||||||
|
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) {
|
||||||
|
const auto& erab = item.value.erab_to_be_setup_item_bearer_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify UE of updates
|
||||||
|
if (not updated_erabs.empty()) {
|
||||||
|
rrc->notify_ue_erab_updates(u->ctxt.rnti, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
sanitize_response_erab_lists(failed_cfg_erabs, updated_erabs);
|
||||||
|
return u->send_erab_setup_response(updated_erabs, failed_cfg_erabs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg)
|
bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg)
|
||||||
|
@ -792,6 +839,8 @@ bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg)
|
||||||
// E-RAB is duplicate
|
// E-RAB is duplicate
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
WarnUnsupportFeature(erab.ext, "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) ==
|
||||||
|
@ -810,8 +859,7 @@ bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// send E-RAB modify response back to the mme
|
// send E-RAB modify response back to the mme
|
||||||
std::sort(updated_erabs.begin(), updated_erabs.end());
|
sanitize_response_erab_lists(failed_cfg_erabs, updated_erabs);
|
||||||
std::sort(failed_cfg_erabs.begin(), failed_cfg_erabs.end(), &lower_obj_id<erab_item_s>);
|
|
||||||
if (not u->send_erab_modify_response(updated_erabs, failed_cfg_erabs)) {
|
if (not u->send_erab_modify_response(updated_erabs, failed_cfg_erabs)) {
|
||||||
logger.info("failed to send erabreleaseresponse");
|
logger.info("failed to send erabreleaseresponse");
|
||||||
return false;
|
return false;
|
||||||
|
@ -867,11 +915,8 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg)
|
||||||
rrc->notify_ue_erab_updates(u->ctxt.rnti, nullptr);
|
rrc->notify_ue_erab_updates(u->ctxt.rnti, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort E-RABs to be sent
|
|
||||||
std::sort(failed_cfg_erabs.begin(), failed_cfg_erabs.end(), &lower_obj_id<erab_item_s>);
|
|
||||||
std::sort(updated_erabs.begin(), updated_erabs.end());
|
|
||||||
|
|
||||||
// Send E-RAB release response back to the MME
|
// Send E-RAB release response back to the MME
|
||||||
|
sanitize_response_erab_lists(failed_cfg_erabs, updated_erabs);
|
||||||
if (not u->send_erab_release_response(updated_erabs, failed_cfg_erabs)) {
|
if (not u->send_erab_release_response(updated_erabs, failed_cfg_erabs)) {
|
||||||
logger.info("Failed to send ERABReleaseResponse");
|
logger.info("Failed to send ERABReleaseResponse");
|
||||||
return false;
|
return false;
|
||||||
|
@ -1381,17 +1426,40 @@ bool s1ap::ue::send_initial_ctxt_setup_response(const asn1::s1ap::init_context_s
|
||||||
return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "InitialContextSetupResponse");
|
return s1ap_ptr->sctp_send_s1ap_pdu(tx_pdu, ctxt.rnti, "InitialContextSetupResponse");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool s1ap::ue::send_erab_setup_response(const erab_setup_resp_s& res_)
|
bool s1ap::ue::send_erab_setup_response(srsran::const_span<uint16_t> erabs_setup,
|
||||||
|
srsran::const_span<asn1::s1ap::erab_item_s> erabs_failed)
|
||||||
{
|
{
|
||||||
if (not s1ap_ptr->mme_connected) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
erab_setup_resp_s& res = tx_pdu.successful_outcome().value.erab_setup_resp();
|
erab_setup_resp_s& res = tx_pdu.successful_outcome().value.erab_setup_resp();
|
||||||
|
|
||||||
res = res_;
|
// Fill in the MME and eNB IDs
|
||||||
|
res.protocol_ies.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value();
|
||||||
|
res.protocol_ies.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id;
|
||||||
|
|
||||||
|
// 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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not erabs_setup.empty()) {
|
||||||
|
res.protocol_ies.erab_setup_list_bearer_su_res_present = true;
|
||||||
|
res.protocol_ies.erab_setup_list_bearer_su_res.value.resize(erabs_setup.size());
|
||||||
|
for (size_t i = 0; i < erabs_setup.size(); ++i) {
|
||||||
|
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
|
// Fill in the GTP bind address for all bearers
|
||||||
if (res.protocol_ies.erab_setup_list_bearer_su_res_present) {
|
if (res.protocol_ies.erab_setup_list_bearer_su_res_present) {
|
||||||
|
@ -1406,10 +1474,6 @@ bool s1ap::ue::send_erab_setup_response(const erab_setup_resp_s& res_)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in the MME and eNB IDs
|
|
||||||
res.protocol_ies.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value();
|
|
||||||
res.protocol_ies.enb_ue_s1ap_id.value = ctxt.enb_ue_s1ap_id;
|
|
||||||
|
|
||||||
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,6 @@ public:
|
||||||
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, const asn1::s1ap::init_context_setup_resp_s& res) override {}
|
||||||
void ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::erab_setup_resp_s& res) 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,
|
||||||
|
@ -168,12 +167,26 @@ public:
|
||||||
void release_ue(uint16_t rnti) override {}
|
void release_ue(uint16_t rnti) override {}
|
||||||
bool setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_request_s& msg) override { return true; }
|
bool setup_ue_ctxt(uint16_t rnti, const asn1::s1ap::init_context_setup_request_s& msg) override { return true; }
|
||||||
bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) override { return true; }
|
bool modify_ue_ctxt(uint16_t rnti, const asn1::s1ap::ue_context_mod_request_s& msg) override { return true; }
|
||||||
bool setup_ue_erabs(uint16_t rnti, const asn1::s1ap::erab_setup_request_s& msg) override { return true; }
|
int get_erab_addr_in(uint16_t rnti, uint16_t erab_id, transp_addr_t& addr_in, uint32_t& teid_in) const override
|
||||||
int modify_erab(uint16_t rnti,
|
{
|
||||||
uint16_t erab_id,
|
return SRSRAN_SUCCESS;
|
||||||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
}
|
||||||
const asn1::unbounded_octstring<true>* nas_pdu,
|
void set_aggregate_max_bitrate(uint16_t rnti, const asn1::s1ap::ue_aggregate_maximum_bitrate_s& bitrate) override {}
|
||||||
asn1::s1ap::cause_c& cause) override
|
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,
|
||||||
|
const asn1::bounded_bitstring<1, 160, true, true>& addr,
|
||||||
|
uint32_t gtpu_teid_out,
|
||||||
|
asn1::s1ap::cause_c& cause) override
|
||||||
|
{
|
||||||
|
return SRSRAN_SUCCESS;
|
||||||
|
}
|
||||||
|
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,
|
||||||
|
asn1::s1ap::cause_c& cause) override
|
||||||
{
|
{
|
||||||
return SRSRAN_SUCCESS;
|
return SRSRAN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -194,7 +207,10 @@ 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) { return SRSRAN_SUCCESS; }
|
int notify_ue_erab_updates(uint16_t rnti, const asn1::unbounded_octstring<true>* nas_pdu) override
|
||||||
|
{
|
||||||
|
return SRSRAN_SUCCESS;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace srsenb
|
} // namespace srsenb
|
||||||
|
|
|
@ -88,14 +88,32 @@ int test_erab_setup(srsran::log_sink_spy& spy, bool qci_exists)
|
||||||
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_erabs(rnti, s1ap_pdu.init_msg().value.erab_setup_request());
|
const auto& setupmsg = s1ap_pdu.init_msg().value.erab_setup_request().protocol_ies;
|
||||||
|
if (setupmsg.ueaggregate_maximum_bitrate_present) {
|
||||||
|
rrc.set_aggregate_max_bitrate(rnti, setupmsg.ueaggregate_maximum_bitrate.value);
|
||||||
|
}
|
||||||
|
for (const auto& item : setupmsg.erab_to_be_setup_list_bearer_su_req.value) {
|
||||||
|
const auto& erab = item.value.erab_to_be_setup_item_bearer_su_req();
|
||||||
|
asn1::s1ap::cause_c cause;
|
||||||
|
int ret = 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);
|
||||||
|
if (qci_exists) {
|
||||||
|
TESTASSERT(ret == SRSRAN_SUCCESS);
|
||||||
|
TESTASSERT(rrc.has_erab(rnti, erab.erab_id));
|
||||||
|
} else {
|
||||||
|
TESTASSERT(ret != SRSRAN_SUCCESS);
|
||||||
|
TESTASSERT(not rrc.has_erab(rnti, erab.erab_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (qci_exists) {
|
if (qci_exists) {
|
||||||
// NOTE: It does not add DRB1/ERAB-ID=5 bc that bearer already existed
|
|
||||||
TESTASSERT(s1ap.added_erab_ids.size() == 1);
|
|
||||||
TESTASSERT(spy.get_error_counter() == 0);
|
TESTASSERT(spy.get_error_counter() == 0);
|
||||||
} else {
|
} else {
|
||||||
TESTASSERT(s1ap.added_erab_ids.empty());
|
|
||||||
TESTASSERT(spy.get_error_counter() > 0);
|
TESTASSERT(spy.get_error_counter() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,6 @@ public:
|
||||||
uint16_t rnti;
|
uint16_t rnti;
|
||||||
std::vector<bearer_status_info> bearer_list;
|
std::vector<bearer_status_info> bearer_list;
|
||||||
} last_enb_status = {};
|
} last_enb_status = {};
|
||||||
std::vector<uint8_t> added_erab_ids;
|
|
||||||
struct ho_req_ack {
|
struct ho_req_ack {
|
||||||
uint16_t rnti;
|
uint16_t rnti;
|
||||||
srsran::unique_byte_buffer_t ho_cmd_pdu;
|
srsran::unique_byte_buffer_t ho_cmd_pdu;
|
||||||
|
@ -107,14 +106,6 @@ public:
|
||||||
last_ho_req_ack.not_admitted_bearers.assign(not_admitted_bearers.begin(), not_admitted_bearers.end());
|
last_ho_req_ack.not_admitted_bearers.assign(not_admitted_bearers.begin(), not_admitted_bearers.end());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::erab_setup_resp_s& res) override
|
|
||||||
{
|
|
||||||
if (res.protocol_ies.erab_setup_list_bearer_su_res_present) {
|
|
||||||
for (const auto& item : res.protocol_ies.erab_setup_list_bearer_su_res.value) {
|
|
||||||
added_erab_ids.push_back(item.value.erab_setup_item_bearer_su_res().erab_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void user_mod(uint16_t old_rnti, uint16_t new_rnti) override {}
|
void user_mod(uint16_t old_rnti, uint16_t new_rnti) override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue