mirror of https://github.com/PentHertz/srsLTE.git
gtpu - added comments, updated expected construct, handled in rrc the case a gtpu teid fails to allocate
This commit is contained in:
parent
82b34f3b3f
commit
5eccfad05b
|
@ -29,7 +29,9 @@ class expected
|
|||
public:
|
||||
expected() : has_val(true), val(T{}) {}
|
||||
expected(T&& t) : has_val(true), val(std::forward<T>(t)) {}
|
||||
expected(const T& t) : has_val(true), val(t) {}
|
||||
expected(E&& e) : has_val(false), unexpected(std::forward<E>(e)) {}
|
||||
expected(const E& e) : has_val(false), unexpected(e) {}
|
||||
expected(const expected& other)
|
||||
{
|
||||
if (other.has_val) {
|
||||
|
|
|
@ -185,11 +185,17 @@ inline unique_byte_buffer_t make_byte_buffer(const char* debug_ctxt) noexcept
|
|||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct byte_buffer_pool_deleter {
|
||||
void operator()(void* ptr) { byte_buffer_pool::get_instance()->deallocate_node(ptr); }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* Class to wrap objects of type T which get allocated/deallocated using the byte_buffer_pool
|
||||
* @tparam T type of the object being allocated
|
||||
*/
|
||||
template <typename T>
|
||||
struct byte_buffer_pool_ptr {
|
||||
static_assert(sizeof(T) <= byte_buffer_pool::BLOCK_SIZE, "pool_bounded_vector does not fit buffer pool block size");
|
||||
|
@ -202,6 +208,7 @@ public:
|
|||
const T* operator->() const { return ptr.get(); }
|
||||
T& operator*() { return *ptr; }
|
||||
const T& operator*() const { return *ptr; }
|
||||
bool has_value() const { return ptr.get() != nullptr; }
|
||||
|
||||
template <typename... CtorArgs>
|
||||
void emplace(CtorArgs&&... args)
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define SRSRAN_BYTE_BUFFER_H
|
||||
|
||||
#include "common.h"
|
||||
#include "srsran/adt/span.h"
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
INCLUDES
|
||||
*******************************************************************************/
|
||||
|
||||
#include "srsran/adt/span.h"
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#ifndef SRSRAN_ENB_GTPU_INTERFACES_H
|
||||
#define SRSRAN_ENB_GTPU_INTERFACES_H
|
||||
|
||||
#include "srsran/adt/expected.h"
|
||||
#include "srsran/common/byte_buffer.h"
|
||||
|
||||
namespace srsenb {
|
||||
|
@ -35,7 +36,7 @@ public:
|
|||
uint32_t flush_before_teidin = 0;
|
||||
};
|
||||
|
||||
virtual uint32_t
|
||||
virtual srsran::expected<uint32_t>
|
||||
add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, const bearer_props* props = nullptr) = 0;
|
||||
virtual void set_tunnel_status(uint32_t teidin, bool dl_active) = 0;
|
||||
virtual void rem_bearer(uint16_t rnti, uint32_t lcid) = 0;
|
||||
|
|
|
@ -92,7 +92,7 @@ public:
|
|||
|
||||
// Methods to apply bearer updates
|
||||
void add_gtpu_bearer(uint32_t erab_id);
|
||||
uint32_t add_gtpu_bearer(uint32_t erab_id,
|
||||
srsran::expected<uint32_t> add_gtpu_bearer(uint32_t erab_id,
|
||||
uint32_t teid_out,
|
||||
uint32_t addr,
|
||||
const gtpu_interface_rrc::bearer_props* props = nullptr);
|
||||
|
|
|
@ -39,10 +39,16 @@ class stack_interface_gtpu_lte;
|
|||
|
||||
class gtpu_tunnel_manager
|
||||
{
|
||||
using buffered_sdu_list = srsran::bounded_vector<std::pair<uint32_t, srsran::unique_byte_buffer_t>, 512>;
|
||||
// Buffer used to store SDUs while PDCP is still getting configured during handover.
|
||||
// Note: The buffer cannot be too large, otherwise it risks depleting the byte buffer pool.
|
||||
const static size_t BUFFER_SIZE = 512;
|
||||
using buffered_sdu_list = srsran::bounded_vector<std::pair<uint32_t, srsran::unique_byte_buffer_t>, BUFFER_SIZE>;
|
||||
|
||||
static const uint32_t undefined_pdcp_sn = std::numeric_limits<uint32_t>::max();
|
||||
|
||||
public:
|
||||
const static size_t MAX_TUNNELS_PER_UE = 4;
|
||||
// A UE should have <= 3 DRBs active, and each DRB should have two tunnels active at the same time at most
|
||||
const static size_t MAX_TUNNELS_PER_UE = 6;
|
||||
|
||||
enum class tunnel_state { pdcp_active, buffering, forward_to, forwarded_from };
|
||||
|
||||
|
@ -105,7 +111,6 @@ public:
|
|||
bool remove_rnti(uint16_t rnti);
|
||||
|
||||
private:
|
||||
static const uint32_t undefined_pdcp_sn = std::numeric_limits<uint32_t>::max();
|
||||
using tunnel_list_t = srsran::static_id_obj_pool<uint32_t, tunnel, SRSENB_MAX_UES * MAX_TUNNELS_PER_UE>;
|
||||
using tunnel_ctxt_it = typename tunnel_list_t::iterator;
|
||||
|
||||
|
@ -136,7 +141,7 @@ public:
|
|||
void stop();
|
||||
|
||||
// gtpu_interface_rrc
|
||||
uint32_t add_bearer(uint16_t rnti,
|
||||
srsran::expected<uint32_t> add_bearer(uint16_t rnti,
|
||||
uint32_t lcid,
|
||||
uint32_t addr,
|
||||
uint32_t teid_out,
|
||||
|
|
|
@ -182,7 +182,6 @@ int rrc::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& sched_ue_cfg)
|
|||
}
|
||||
|
||||
if (rnti == SRSRAN_MRNTI) {
|
||||
uint32_t teid_in = 1;
|
||||
for (auto& mbms_item : mcch.msg.c1().mbsfn_area_cfg_r9().pmch_info_list_r9[0].mbms_session_info_list_r9) {
|
||||
uint32_t lcid = mbms_item.lc_ch_id_r9;
|
||||
|
||||
|
@ -190,7 +189,7 @@ int rrc::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& sched_ue_cfg)
|
|||
mac->ue_cfg(SRSRAN_MRNTI, NULL);
|
||||
rlc->add_bearer_mrb(SRSRAN_MRNTI, lcid);
|
||||
pdcp->add_bearer(SRSRAN_MRNTI, lcid, srsran::make_drb_pdcp_config_t(1, false));
|
||||
teid_in = gtpu->add_bearer(SRSRAN_MRNTI, lcid, 1, 1);
|
||||
gtpu->add_bearer(SRSRAN_MRNTI, lcid, 1, 1);
|
||||
}
|
||||
}
|
||||
return SRSRAN_SUCCESS;
|
||||
|
|
|
@ -309,14 +309,18 @@ bool bearer_cfg_handler::modify_erab(uint8_t
|
|||
void bearer_cfg_handler::add_gtpu_bearer(uint32_t erab_id)
|
||||
{
|
||||
auto it = erabs.find(erab_id);
|
||||
if (it == erabs.end()) {
|
||||
logger->error("Adding erab_id=%d to GTPU", erab_id);
|
||||
if (it != erabs.end()) {
|
||||
srsran::expected<uint32_t> teidin =
|
||||
add_gtpu_bearer(erab_id, it->second.teid_out, it->second.address.to_number(), nullptr);
|
||||
if (teidin.has_value()) {
|
||||
it->second.teid_in = teidin.value();
|
||||
return;
|
||||
}
|
||||
it->second.teid_in = add_gtpu_bearer(erab_id, it->second.teid_out, it->second.address.to_number(), nullptr);
|
||||
}
|
||||
logger->error("Adding erab_id=%d to GTPU", erab_id);
|
||||
}
|
||||
|
||||
uint32_t bearer_cfg_handler::add_gtpu_bearer(uint32_t erab_id,
|
||||
srsran::expected<uint32_t> bearer_cfg_handler::add_gtpu_bearer(uint32_t erab_id,
|
||||
uint32_t teid_out,
|
||||
uint32_t addr,
|
||||
const gtpu_interface_rrc::bearer_props* props)
|
||||
|
@ -324,7 +328,7 @@ uint32_t bearer_cfg_handler::add_gtpu_bearer(uint32_t
|
|||
auto it = erabs.find(erab_id);
|
||||
if (it == erabs.end()) {
|
||||
logger->error("Adding erab_id=%d to GTPU", erab_id);
|
||||
return 0;
|
||||
return srsran::default_error_t();
|
||||
}
|
||||
|
||||
// Initialize ERAB tunnel in GTPU right-away. DRBs are only created during RRC setup/reconf
|
||||
|
@ -332,9 +336,14 @@ uint32_t bearer_cfg_handler::add_gtpu_bearer(uint32_t
|
|||
erab_t::gtpu_tunnel bearer;
|
||||
bearer.teid_out = teid_out;
|
||||
bearer.addr = addr;
|
||||
bearer.teid_in = gtpu->add_bearer(rnti, erab.id - 2, addr, teid_out, props);
|
||||
srsran::expected<uint32_t> teidin = gtpu->add_bearer(rnti, erab.id - 2, addr, teid_out, props);
|
||||
if (teidin.is_error()) {
|
||||
logger->error("Adding erab_id=%d to GTPU", erab_id);
|
||||
return srsran::default_error_t();
|
||||
}
|
||||
bearer.teid_in = teidin.value();
|
||||
erab.tunnels.push_back(bearer);
|
||||
return bearer.teid_in;
|
||||
return teidin;
|
||||
}
|
||||
|
||||
void bearer_cfg_handler::rem_gtpu_bearer(uint32_t erab_id)
|
||||
|
|
|
@ -784,10 +784,15 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev&
|
|||
gtpu_interface_rrc::bearer_props props;
|
||||
props.flush_before_teidin_present = true;
|
||||
props.flush_before_teidin = erab.second.teid_in;
|
||||
uint32_t dl_teid_in = rrc_ue->bearer_list.add_gtpu_bearer(
|
||||
srsran::expected<uint32_t> dl_teid_in = rrc_ue->bearer_list.add_gtpu_bearer(
|
||||
erab.second.id, erab.second.teid_out, erab.second.address.to_number(), &props);
|
||||
fwd_tunnels.push_back(dl_teid_in);
|
||||
srsran::uint32_to_uint8(dl_teid_in, admitted_erabs.back().dl_g_tp_teid.data());
|
||||
if (not dl_teid_in.has_value()) {
|
||||
logger.error("Failed to allocate GTPU TEID");
|
||||
trigger(srsran::failure_ev{});
|
||||
return;
|
||||
}
|
||||
fwd_tunnels.push_back(dl_teid_in.value());
|
||||
srsran::uint32_to_uint8(dl_teid_in.value(), admitted_erabs.back().dl_g_tp_teid.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -414,12 +414,13 @@ void gtpu::send_pdu_to_tunnel(const gtpu_tunnel& tx_tun, srsran::unique_byte_buf
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, const bearer_props* props)
|
||||
srsran::expected<uint32_t>
|
||||
gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, const bearer_props* props)
|
||||
{
|
||||
// Allocate a TEID for the incoming tunnel
|
||||
const gtpu_tunnel* new_tun = tunnels.add_tunnel(rnti, lcid, teid_out, addr);
|
||||
if (new_tun == nullptr) {
|
||||
return -1;
|
||||
return default_error_t();
|
||||
}
|
||||
uint32_t teid_in = new_tun->teid_in;
|
||||
|
||||
|
@ -436,7 +437,7 @@ uint32_t gtpu::add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t
|
|||
if (props->forward_from_teidin_present) {
|
||||
if (create_dl_fwd_tunnel(props->forward_from_teidin, teid_in) != SRSRAN_SUCCESS) {
|
||||
rem_tunnel(teid_in);
|
||||
return -1;
|
||||
return default_error_t();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -148,10 +148,10 @@ public:
|
|||
class gtpu_dummy : public gtpu_interface_rrc
|
||||
{
|
||||
public:
|
||||
uint32_t
|
||||
srsran::expected<uint32_t>
|
||||
add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, const bearer_props* props) override
|
||||
{
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
void set_tunnel_status(uint32_t teidin, bool dl_active) override {}
|
||||
void rem_bearer(uint16_t rnti, uint32_t lcid) override {}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "srsenb/hdr/stack/mac/sched_common.h"
|
||||
#include "srsran/adt/bounded_bitset.h"
|
||||
#include "srsran/adt/span.h"
|
||||
#include "srsran/common/tti_point.h"
|
||||
#include "srsran/interfaces/sched_interface.h"
|
||||
|
||||
|
|
|
@ -216,8 +216,8 @@ int test_gtpu_direct_tunneling(tunnel_test_event event)
|
|||
tenb_gtpu.init(tenb_addr_str, sgw_addr_str, "", "", &tenb_pdcp, &tenb_stack, false);
|
||||
|
||||
// create tunnels MME-SeNB and MME-TeNB
|
||||
uint32_t senb_teid_in = senb_gtpu.add_bearer(rnti, drb1, sgw_addr, sgw_teidout1);
|
||||
uint32_t tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1, sgw_addr, sgw_teidout2);
|
||||
uint32_t senb_teid_in = senb_gtpu.add_bearer(rnti, drb1, sgw_addr, sgw_teidout1).value();
|
||||
uint32_t tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1, sgw_addr, sgw_teidout2).value();
|
||||
|
||||
// Buffer PDUs in SeNB PDCP
|
||||
for (size_t sn = 6; sn < 10; ++sn) {
|
||||
|
@ -230,7 +230,7 @@ int test_gtpu_direct_tunneling(tunnel_test_event event)
|
|||
gtpu::bearer_props props;
|
||||
props.flush_before_teidin_present = true;
|
||||
props.flush_before_teidin = tenb_teid_in;
|
||||
uint32_t dl_tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1, senb_addr, 0, &props);
|
||||
uint32_t dl_tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1, senb_addr, 0, &props).value();
|
||||
props = {};
|
||||
props.forward_from_teidin_present = true;
|
||||
props.forward_from_teidin = senb_teid_in;
|
||||
|
|
Loading…
Reference in New Issue