mirror of https://github.com/PentHertz/srsLTE.git
s1ap - handle invalid or repeated erab ids in s1ap erab release command
This commit is contained in:
parent
7842e3bff3
commit
49bd895e29
|
@ -233,7 +233,7 @@ public:
|
|||
|
||||
iterator begin() { return iterator(this, 0); }
|
||||
iterator end() { return iterator(this, N); }
|
||||
const_iterator begin() const { return iterator(this, 0); }
|
||||
const_iterator begin() const { return const_iterator(this, 0); }
|
||||
const_iterator end() const { return const_iterator(this, N); }
|
||||
|
||||
iterator find(K id)
|
||||
|
|
|
@ -33,10 +33,9 @@ public:
|
|||
srsran::const_span<const asn1::s1ap::erab_to_be_modified_item_bearer_mod_req_s*> erabs_to_modify) = 0;
|
||||
virtual bool has_erab(uint16_t rnti, uint32_t erab_id) const = 0;
|
||||
virtual bool release_erabs(uint32_t rnti) = 0;
|
||||
virtual void release_erabs(uint32_t rnti,
|
||||
const asn1::s1ap::erab_release_cmd_s& msg,
|
||||
std::vector<uint16_t>* erabs_released,
|
||||
std::vector<uint16_t>* erabs_failed_to_release) = 0;
|
||||
virtual void release_erabs(uint32_t rnti,
|
||||
srsran::const_span<uint16_t> erabs_to_release,
|
||||
const asn1::unbounded_octstring<true>* nas_pdu) = 0;
|
||||
virtual void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& ue_paging_id) = 0;
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,6 +26,8 @@ namespace srsenb {
|
|||
|
||||
#define SRSENB_N_SRB 3
|
||||
#define SRSENB_MAX_UES 64
|
||||
const uint32_t MAX_ERAB_ID = 15;
|
||||
const uint32_t MAX_NOF_ERABS = 16;
|
||||
|
||||
using srsran::lte_drb;
|
||||
using srsran::lte_srb;
|
||||
|
|
|
@ -91,10 +91,9 @@ public:
|
|||
const asn1::s1ap::erab_level_qos_params_s& qos_params,
|
||||
const asn1::unbounded_octstring<true>* nas_pdu);
|
||||
bool release_erabs(uint32_t rnti) override;
|
||||
void release_erabs(uint32_t rnti,
|
||||
const asn1::s1ap::erab_release_cmd_s& msg,
|
||||
std::vector<uint16_t>* erabs_released,
|
||||
std::vector<uint16_t>* erabs_failed_to_release) override;
|
||||
void release_erabs(uint32_t rnti,
|
||||
srsran::const_span<uint16_t> erabs_to_release,
|
||||
const asn1::unbounded_octstring<true>* nas_pdu) override;
|
||||
void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& UEPagingID) override;
|
||||
void ho_preparation_complete(uint16_t rnti,
|
||||
bool is_success,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <map>
|
||||
|
||||
#include "srsenb/hdr/common/common_enb.h"
|
||||
#include "srsran/adt/circular_map.h"
|
||||
#include "srsran/common/buffer_pool.h"
|
||||
#include "srsran/common/common.h"
|
||||
#include "srsran/common/s1ap_pcap.h"
|
||||
|
@ -237,8 +238,9 @@ private:
|
|||
bool send_initial_ctxt_setup_response(const asn1::s1ap::init_context_setup_resp_s& res_);
|
||||
bool send_initial_ctxt_setup_failure();
|
||||
bool send_erab_setup_response(const asn1::s1ap::erab_setup_resp_s& res_);
|
||||
bool send_erab_release_response(const std::vector<uint16_t>& erabs_successfully_released,
|
||||
const std::vector<uint16_t>& erabs_failed_to_release);
|
||||
bool send_erab_release_response(
|
||||
const srsran::bounded_vector<uint16_t, MAX_NOF_ERABS>& erabs_released,
|
||||
const srsran::static_circular_map<uint16_t, asn1::s1ap::erab_item_s, MAX_NOF_ERABS>& erabs_failed_to_release);
|
||||
bool send_erab_modify_response(
|
||||
srsran::const_span<const asn1::s1ap::erab_to_be_modified_item_bearer_mod_req_s*> erabs_modified,
|
||||
srsran::const_span<std::pair<uint16_t, asn1::s1ap::cause_c> > erabs_failed_to_modify);
|
||||
|
|
|
@ -358,10 +358,9 @@ bool rrc::release_erabs(uint32_t rnti)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void rrc::release_erabs(uint32_t rnti,
|
||||
const asn1::s1ap::erab_release_cmd_s& msg,
|
||||
std::vector<uint16_t>* erabs_released,
|
||||
std::vector<uint16_t>* erabs_failed_to_release)
|
||||
void rrc::release_erabs(uint32_t rnti,
|
||||
srsran::const_span<uint16_t> erabs_to_release,
|
||||
const asn1::unbounded_octstring<true>* nas_pdu)
|
||||
{
|
||||
logger.info("Releasing E-RAB for 0x%x", rnti);
|
||||
auto user_it = users.find(rnti);
|
||||
|
@ -371,18 +370,10 @@ void rrc::release_erabs(uint32_t rnti,
|
|||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < msg.protocol_ies.erab_to_be_released_list.value.size(); i++) {
|
||||
const asn1::s1ap::erab_item_s& erab_to_release =
|
||||
msg.protocol_ies.erab_to_be_released_list.value[i].value.erab_item();
|
||||
bool ret = user_it->second->release_erab(erab_to_release.erab_id);
|
||||
if (ret) {
|
||||
erabs_released->push_back(erab_to_release.erab_id);
|
||||
} else {
|
||||
erabs_failed_to_release->push_back(erab_to_release.erab_id);
|
||||
}
|
||||
for (uint16_t erab_id : erabs_to_release) {
|
||||
bool ret = user_it->second->release_erab(erab_id);
|
||||
srsran_expect(ret, "E-RAB id=%d not found", erab_id);
|
||||
}
|
||||
const asn1::unbounded_octstring<true>* nas_pdu =
|
||||
msg.protocol_ies.nas_pdu_present ? &msg.protocol_ies.nas_pdu.value : nullptr;
|
||||
user_it->second->send_connection_reconf(nullptr, false, nas_pdu);
|
||||
}
|
||||
|
||||
|
|
|
@ -735,15 +735,18 @@ bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg)
|
|||
return false;
|
||||
}
|
||||
|
||||
// make a copy, sort by ERAB ID
|
||||
using erab_t = erab_to_be_modified_item_bearer_mod_req_s;
|
||||
using failed_erab_t = std::pair<uint16_t, cause_c>;
|
||||
srsran::bounded_vector<const erab_t*, 256> erab_mod_list;
|
||||
std::vector<failed_erab_t> erabs_failed_to_modify;
|
||||
auto& msg_erabs = msg.protocol_ies.erab_to_be_modified_list_bearer_mod_req.value;
|
||||
srsran::bounded_vector<const erab_t*, MAX_ERAB_ID + 1> erab_mod_list;
|
||||
srsran::bounded_vector<failed_erab_t, MAX_ERAB_ID + 1> erabs_failed_to_modify;
|
||||
const auto& msg_erabs = msg.protocol_ies.erab_to_be_modified_list_bearer_mod_req.value;
|
||||
|
||||
for (const auto& msg_erab : msg_erabs) {
|
||||
const erab_t& e = msg_erab.value.erab_to_be_modified_item_bearer_mod_req();
|
||||
if (msg_erabs.size() > erab_mod_list.capacity()) {
|
||||
logger.warning("Not handling more than %d E-RABs per modify request message.", erab_mod_list.capacity());
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < SRSRAN_MIN(msg_erabs.size(), erab_mod_list.capacity()); ++i) {
|
||||
const erab_t& e = msg_erabs[i].value.erab_to_be_modified_item_bearer_mod_req();
|
||||
|
||||
// Check if E-RAB exists. If not, add to "erabs_failed_to_modify" with "unknown_erab_id" cause
|
||||
if (not rrc->has_erab(u->ctxt.rnti, e.erab_id)) {
|
||||
|
@ -757,7 +760,7 @@ bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg)
|
|||
// with cause "multiple_erab_id_instances"
|
||||
for (const auto& msg_erab2 : msg_erabs) {
|
||||
const erab_t& e2 = msg_erab2.value.erab_to_be_modified_item_bearer_mod_req();
|
||||
if (&msg_erab2 != &msg_erab and e2.erab_id == e.erab_id) {
|
||||
if (&e2 != &e and e2.erab_id == e.erab_id) {
|
||||
cause_c cause;
|
||||
cause.set_radio_network().value = cause_radio_network_opts::multiple_erab_id_instances;
|
||||
erabs_failed_to_modify.emplace_back(e.erab_id, cause);
|
||||
|
@ -802,9 +805,6 @@ bool s1ap::handle_erabmodifyrequest(const erab_modify_request_s& msg)
|
|||
*/
|
||||
bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg)
|
||||
{
|
||||
std::vector<uint16_t> erab_successful_release = {};
|
||||
std::vector<uint16_t> erab_failed_to_release = {};
|
||||
|
||||
if (msg.ext) {
|
||||
logger.warning("Not handling S1AP message extension");
|
||||
}
|
||||
|
@ -814,11 +814,56 @@ bool s1ap::handle_erabreleasecommand(const erab_release_cmd_s& msg)
|
|||
return false;
|
||||
}
|
||||
|
||||
srsran::bounded_vector<uint16_t, MAX_NOF_ERABS> erabs_to_release;
|
||||
srsran::static_circular_map<uint16_t, erab_item_s, MAX_NOF_ERABS> erabs_failed_to_release;
|
||||
const auto& msg_erabs = msg.protocol_ies.erab_to_be_released_list.value;
|
||||
|
||||
for (const auto& msg_erab : msg_erabs) {
|
||||
const erab_item_s& e = msg_erab.value.erab_item();
|
||||
if (e.erab_id >= erabs_failed_to_release.capacity()) {
|
||||
logger.warning("Not handling E-RAB Ids above %zd", erabs_to_release.capacity());
|
||||
continue;
|
||||
}
|
||||
if (erabs_to_release.full()) {
|
||||
logger.warning("Not handling more than %zd releases per ERAB release request message",
|
||||
erabs_to_release.capacity());
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if E-RAB exists. If not, add to "erabs_failed_to_modify" with "unknown_erab_id" cause
|
||||
if (not rrc->has_erab(u->ctxt.rnti, e.erab_id)) {
|
||||
erabs_failed_to_release.overwrite(e.erab_id, erab_item_s());
|
||||
erabs_failed_to_release[e.erab_id].cause.set_radio_network().value = cause_radio_network_opts::unknown_erab_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check Repeated E-RABs in the modification list. If repeated, add to the list of "erabs_failed_to_modify"
|
||||
// with cause "multiple_erab_id_instances"
|
||||
for (const auto& msg_erab2 : msg_erabs) {
|
||||
const erab_item_s& e2 = msg_erab2.value.erab_item();
|
||||
if (&e2 != &e and e2.erab_id == e.erab_id) {
|
||||
erabs_failed_to_release.overwrite(e.erab_id, erab_item_s());
|
||||
erabs_failed_to_release[e.erab_id].cause.set_radio_network().value =
|
||||
cause_radio_network_opts::multiple_erab_id_instances;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (erabs_failed_to_release.has_space(e.erab_id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add to the list to modify
|
||||
erabs_to_release.push_back(e.erab_id);
|
||||
}
|
||||
|
||||
// Release E-RABs from RRC
|
||||
rrc->release_erabs(u->ctxt.rnti, msg, &erab_successful_release, &erab_failed_to_release);
|
||||
std::sort(erabs_to_release.begin(), erabs_to_release.end());
|
||||
erabs_to_release.erase(std::unique(erabs_to_release.begin(), erabs_to_release.end()), erabs_to_release.end());
|
||||
rrc->release_erabs(
|
||||
u->ctxt.rnti, erabs_to_release, msg.protocol_ies.nas_pdu_present ? &msg.protocol_ies.nas_pdu.value : nullptr);
|
||||
|
||||
// Send E-RAB release response back to the MME
|
||||
if (not u->send_erab_release_response(erab_successful_release, erab_failed_to_release)) {
|
||||
if (not u->send_erab_release_response(erabs_to_release, erabs_failed_to_release)) {
|
||||
logger.info("Failed to send ERABReleaseResponse");
|
||||
return false;
|
||||
}
|
||||
|
@ -1391,8 +1436,9 @@ bool s1ap::ue::send_uectxtmodifyfailure(const cause_c& cause)
|
|||
* @param erabs_failed_to_release
|
||||
* @return true if message was sent
|
||||
*/
|
||||
bool s1ap::ue::send_erab_release_response(const std::vector<uint16_t>& erabs_successfully_released,
|
||||
const std::vector<uint16_t>& erabs_failed_to_release)
|
||||
bool s1ap::ue::send_erab_release_response(
|
||||
const srsran::bounded_vector<uint16_t, MAX_NOF_ERABS>& erabs_released,
|
||||
const srsran::static_circular_map<uint16_t, asn1::s1ap::erab_item_s, MAX_NOF_ERABS>& erabs_failed_to_release)
|
||||
{
|
||||
if (not s1ap_ptr->mme_connected) {
|
||||
return false;
|
||||
|
@ -1406,14 +1452,14 @@ bool s1ap::ue::send_erab_release_response(const std::vector<uint16_t>& erabs_suc
|
|||
container.mme_ue_s1ap_id.value = ctxt.mme_ue_s1ap_id.value();
|
||||
|
||||
// Fill in which E-RABs were successfully released
|
||||
if (not erabs_successfully_released.empty()) {
|
||||
if (not erabs_released.empty()) {
|
||||
container.erab_release_list_bearer_rel_comp_present = true;
|
||||
container.erab_release_list_bearer_rel_comp.value.resize(erabs_successfully_released.size());
|
||||
for (uint32_t i = 0; i < container.erab_release_list_bearer_rel_comp.value.size(); i++) {
|
||||
container.erab_release_list_bearer_rel_comp.value.resize(erabs_released.size());
|
||||
for (size_t i = 0; i < erabs_released.size(); ++i) {
|
||||
container.erab_release_list_bearer_rel_comp.value[i].load_info_obj(
|
||||
ASN1_S1AP_ID_ERAB_RELEASE_ITEM_BEARER_REL_COMP);
|
||||
container.erab_release_list_bearer_rel_comp.value[i].value.erab_release_item_bearer_rel_comp().erab_id =
|
||||
erabs_successfully_released[i];
|
||||
erabs_released[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1421,12 +1467,11 @@ bool s1ap::ue::send_erab_release_response(const std::vector<uint16_t>& erabs_suc
|
|||
if (not erabs_failed_to_release.empty()) {
|
||||
container.erab_failed_to_release_list_present = true;
|
||||
container.erab_failed_to_release_list.value.resize(erabs_failed_to_release.size());
|
||||
for (uint32_t i = 0; i < container.erab_failed_to_release_list.value.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().erab_id = erabs_failed_to_release[i];
|
||||
container.erab_failed_to_release_list.value[i].value.erab_item().cause.set(asn1::s1ap::cause_c::types::misc);
|
||||
container.erab_failed_to_release_list.value[i].value.erab_item().cause.misc() =
|
||||
asn1::s1ap::cause_misc_opts::unspecified;
|
||||
size_t count = 0;
|
||||
for (const auto& erab : erabs_failed_to_release) {
|
||||
container.erab_failed_to_release_list.value[count].load_info_obj(ASN1_S1AP_ID_ERAB_ITEM);
|
||||
container.erab_failed_to_release_list.value[count].value.erab_item() = erab->second;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -174,10 +174,9 @@ public:
|
|||
{}
|
||||
bool has_erab(uint16_t rnti, uint32_t erab_id) const override { return true; }
|
||||
bool release_erabs(uint32_t rnti) override { return true; }
|
||||
void release_erabs(uint32_t rnti,
|
||||
const asn1::s1ap::erab_release_cmd_s& msg,
|
||||
std::vector<uint16_t>* erabs_released,
|
||||
std::vector<uint16_t>* erabs_failed_to_release) override
|
||||
void release_erabs(uint32_t rnti,
|
||||
srsran::const_span<uint16_t> erabs_to_release,
|
||||
const asn1::unbounded_octstring<true>* nas_pdu) override
|
||||
{}
|
||||
void add_paging_id(uint32_t ueid, const asn1::s1ap::ue_paging_id_c& ue_paging_id) override {}
|
||||
void ho_preparation_complete(uint16_t rnti,
|
||||
|
|
Loading…
Reference in New Issue