mirror of https://github.com/PentHertz/srsLTE.git
stack lte: create an gtpu-pdcp adapter class that correctly converts lcids to eps bearers and vice-versa
This commit is contained in:
parent
4b2f079581
commit
2ade4628ca
|
@ -49,6 +49,8 @@ public:
|
|||
struct radio_bearer_t {
|
||||
srsran::srsran_rat_t rat;
|
||||
uint32_t lcid;
|
||||
uint32_t eps_bearer_id;
|
||||
bool is_valid() const { return rat != srsran_rat_t::nulltype; }
|
||||
};
|
||||
|
||||
/// Single user interface (for UE)
|
||||
|
@ -69,6 +71,8 @@ public:
|
|||
// Stack interface to retrieve active RB
|
||||
radio_bearer_t get_radio_bearer(uint32_t eps_bearer_id);
|
||||
|
||||
radio_bearer_t get_lcid_bearer(uint16_t rnti, uint32_t lcid);
|
||||
|
||||
/// Multi-user interface (see comments above)
|
||||
void add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid);
|
||||
void remove_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id);
|
||||
|
@ -81,10 +85,14 @@ private:
|
|||
srslog::basic_logger& logger;
|
||||
|
||||
typedef std::map<uint32_t, radio_bearer_t> eps_rb_map_t;
|
||||
std::map<uint16_t, eps_rb_map_t> users_map;
|
||||
struct user_bearers {
|
||||
eps_rb_map_t bearers;
|
||||
std::map<uint32_t, uint32_t> lcid_to_eps_bearer_id;
|
||||
};
|
||||
std::map<uint16_t, user_bearers> users_map;
|
||||
|
||||
const uint16_t default_key = 0xffff; // dummy RNTI used for public interface without explicit RNTI
|
||||
radio_bearer_t invalid_rb = {srsran::srsran_rat_t::nulltype, 0};
|
||||
radio_bearer_t invalid_rb = {srsran::srsran_rat_t::nulltype, 0, 0};
|
||||
};
|
||||
|
||||
} // namespace srsran
|
||||
|
|
|
@ -31,7 +31,7 @@ struct gtpu_args_t {
|
|||
class gtpu_interface_pdcp
|
||||
{
|
||||
public:
|
||||
virtual void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) = 0;
|
||||
virtual void write_pdu(uint16_t rnti, uint32_t bearer_id, srsran::unique_byte_buffer_t pdu) = 0;
|
||||
};
|
||||
|
||||
// GTPU interface for RRC
|
||||
|
@ -45,12 +45,15 @@ public:
|
|||
uint32_t flush_before_teidin = 0;
|
||||
};
|
||||
|
||||
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;
|
||||
virtual void mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti) = 0;
|
||||
virtual void rem_user(uint16_t rnti) = 0;
|
||||
virtual srsran::expected<uint32_t> add_bearer(uint16_t rnti,
|
||||
uint32_t eps_bearer_id,
|
||||
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 eps_bearer_id) = 0;
|
||||
virtual void mod_bearer_rnti(uint16_t old_rnti, uint16_t new_rnti) = 0;
|
||||
virtual void rem_user(uint16_t rnti) = 0;
|
||||
};
|
||||
|
||||
} // namespace srsenb
|
||||
|
|
|
@ -32,19 +32,20 @@ void bearer_manager::add_eps_bearer(uint8_t eps_bearer_id, srsran::srsran_rat_t
|
|||
void bearer_manager::add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, srsran::srsran_rat_t rat, uint32_t lcid)
|
||||
{
|
||||
srsran::rwlock_write_guard rw_lock(rwlock);
|
||||
auto user_it = users_map.find(rnti);
|
||||
auto user_it = users_map.find(rnti);
|
||||
if (user_it == users_map.end()) {
|
||||
// add empty bearer map
|
||||
users_map.emplace(rnti, eps_rb_map_t{});
|
||||
user_it = users_map.find(rnti);
|
||||
auto p = users_map.emplace(rnti, user_bearers{});
|
||||
user_it = p.first;
|
||||
}
|
||||
|
||||
auto bearer_it = user_it->second.find(eps_bearer_id);
|
||||
if (bearer_it != user_it->second.end()) {
|
||||
auto bearer_it = user_it->second.bearers.find(eps_bearer_id);
|
||||
if (bearer_it != user_it->second.bearers.end()) {
|
||||
logger.error("EPS bearer ID %d already registered", eps_bearer_id);
|
||||
return;
|
||||
}
|
||||
user_it->second.emplace(eps_bearer_id, radio_bearer_t{rat, lcid});
|
||||
user_it->second.bearers.emplace(eps_bearer_id, radio_bearer_t{rat, lcid, eps_bearer_id});
|
||||
user_it->second.lcid_to_eps_bearer_id.emplace(lcid, eps_bearer_id);
|
||||
logger.info("Registered EPS bearer ID %d for lcid=%d over %s-PDCP", eps_bearer_id, lcid, to_string(rat).c_str());
|
||||
}
|
||||
|
||||
|
@ -63,12 +64,14 @@ void bearer_manager::remove_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id)
|
|||
return;
|
||||
}
|
||||
|
||||
auto bearer_it = user_it->second.find(eps_bearer_id);
|
||||
if (bearer_it == user_it->second.end()) {
|
||||
auto bearer_it = user_it->second.bearers.find(eps_bearer_id);
|
||||
if (bearer_it == user_it->second.bearers.end()) {
|
||||
logger.error("Can't remove EPS bearer ID %d", eps_bearer_id);
|
||||
return;
|
||||
}
|
||||
user_it->second.erase(bearer_it);
|
||||
uint32_t lcid = bearer_it->second.lcid;
|
||||
user_it->second.bearers.erase(bearer_it);
|
||||
user_it->second.lcid_to_eps_bearer_id.erase(lcid);
|
||||
logger.info("Removed mapping for EPS bearer ID %d", eps_bearer_id);
|
||||
}
|
||||
|
||||
|
@ -87,7 +90,8 @@ void bearer_manager::reset(uint16_t rnti)
|
|||
return;
|
||||
}
|
||||
|
||||
user_it->second.clear();
|
||||
user_it->second.lcid_to_eps_bearer_id.clear();
|
||||
user_it->second.bearers.clear();
|
||||
logger.info("Reset EPS bearer manager");
|
||||
}
|
||||
|
||||
|
@ -106,7 +110,7 @@ bool bearer_manager::has_active_radio_bearer(uint16_t rnti, uint32_t eps_bearer_
|
|||
return false;
|
||||
}
|
||||
|
||||
return user_it->second.find(eps_bearer_id) != user_it->second.end();
|
||||
return user_it->second.bearers.find(eps_bearer_id) != user_it->second.bearers.end();
|
||||
}
|
||||
|
||||
// Stack interface
|
||||
|
@ -115,6 +119,22 @@ bearer_manager::radio_bearer_t bearer_manager::get_radio_bearer(uint32_t eps_bea
|
|||
return get_radio_bearer(default_key, eps_bearer_id);
|
||||
}
|
||||
|
||||
bearer_manager::radio_bearer_t bearer_manager::get_lcid_bearer(uint16_t rnti, uint32_t lcid)
|
||||
{
|
||||
srsran::rwlock_read_guard rw_lock(rwlock);
|
||||
|
||||
auto user_it = users_map.find(rnti);
|
||||
if (user_it == users_map.end()) {
|
||||
return invalid_rb;
|
||||
}
|
||||
|
||||
auto lcid_it = user_it->second.lcid_to_eps_bearer_id.find(lcid);
|
||||
if (lcid_it != user_it->second.lcid_to_eps_bearer_id.end()) {
|
||||
return user_it->second.bearers.at(lcid_it->second);
|
||||
}
|
||||
return invalid_rb;
|
||||
}
|
||||
|
||||
bearer_manager::radio_bearer_t bearer_manager::get_radio_bearer(uint16_t rnti, uint32_t eps_bearer_id)
|
||||
{
|
||||
srsran::rwlock_read_guard rw_lock(rwlock);
|
||||
|
@ -124,10 +144,10 @@ bearer_manager::radio_bearer_t bearer_manager::get_radio_bearer(uint16_t rnti, u
|
|||
return invalid_rb;
|
||||
}
|
||||
|
||||
if (user_it->second.find(eps_bearer_id) != user_it->second.end()) {
|
||||
return user_it->second.at(eps_bearer_id);
|
||||
if (user_it->second.bearers.find(eps_bearer_id) != user_it->second.bearers.end()) {
|
||||
return user_it->second.bearers.at(eps_bearer_id);
|
||||
}
|
||||
return invalid_rb;
|
||||
}
|
||||
|
||||
} // namespace srsue
|
||||
} // namespace srsran
|
|
@ -36,6 +36,8 @@
|
|||
|
||||
namespace srsenb {
|
||||
|
||||
class gtpu_pdcp_adapter;
|
||||
|
||||
class enb_stack_lte final : public enb_stack_base,
|
||||
public stack_interface_phy_lte,
|
||||
public stack_interface_phy_nr,
|
||||
|
@ -178,6 +180,10 @@ private:
|
|||
srsran::task_scheduler task_sched;
|
||||
srsran::task_queue_handle enb_task_queue, sync_task_queue, metrics_task_queue;
|
||||
|
||||
// bearer management
|
||||
srsran::bearer_manager bearers; // helper to manage mapping between EPS and radio bearers
|
||||
std::unique_ptr<gtpu_pdcp_adapter> gtpu_adapter;
|
||||
|
||||
srsenb::mac mac;
|
||||
srsenb::rlc rlc;
|
||||
srsenb::pdcp pdcp;
|
||||
|
@ -191,10 +197,8 @@ private:
|
|||
srsenb::pdcp pdcp_nr;
|
||||
srsenb::rrc_nr rrc_nr;
|
||||
|
||||
srsran::bearer_manager bearers; // helper to manage mapping between EPS and radio bearers
|
||||
|
||||
// RAT-specific interfaces
|
||||
phy_interface_stack_lte* phy = nullptr;
|
||||
phy_interface_stack_lte* phy = nullptr;
|
||||
phy_interface_stack_nr* phy_nr = nullptr;
|
||||
|
||||
// state
|
||||
|
|
|
@ -22,6 +22,23 @@ using namespace srsran;
|
|||
|
||||
namespace srsenb {
|
||||
|
||||
class gtpu_pdcp_adapter : public gtpu_interface_pdcp
|
||||
{
|
||||
public:
|
||||
gtpu_pdcp_adapter(gtpu* gtpu_, srsran::bearer_manager& bearers_) : gtpu_obj(gtpu_), bearers(&bearers_) {}
|
||||
|
||||
/// Converts LCID to EPS-BearerID and sends corresponding PDU to GTPU
|
||||
void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu)
|
||||
{
|
||||
auto bearer = bearers->get_lcid_bearer(rnti, lcid);
|
||||
gtpu_obj->write_pdu(rnti, bearer.eps_bearer_id, std::move(pdu));
|
||||
}
|
||||
|
||||
private:
|
||||
gtpu* gtpu_obj = nullptr;
|
||||
srsran::bearer_manager* bearers = nullptr;
|
||||
};
|
||||
|
||||
enb_stack_lte::enb_stack_lte(srslog::sink& log_sink) :
|
||||
thread("STACK"),
|
||||
mac_logger(srslog::fetch_basic_logger("MAC", log_sink)),
|
||||
|
@ -145,13 +162,16 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_)
|
|||
// add sync queue
|
||||
sync_task_queue = task_sched.make_task_queue(args.sync_queue_size);
|
||||
|
||||
// setup bearer managers
|
||||
gtpu_adapter.reset(new gtpu_pdcp_adapter(>pu, bearers));
|
||||
|
||||
// Init all LTE layers
|
||||
if (!mac.init(args.mac, rrc_cfg.cell_list, phy, &rlc, &rrc)) {
|
||||
stack_logger.error("Couldn't initialize MAC");
|
||||
return SRSRAN_ERROR;
|
||||
}
|
||||
rlc.init(&pdcp, &rrc, &mac, task_sched.get_timer_handler());
|
||||
pdcp.init(&rlc, &rrc, >pu);
|
||||
pdcp.init(&rlc, &rrc, gtpu_adapter.get());
|
||||
if (rrc.init(rrc_cfg, phy, &mac, &rlc, &pdcp, &s1ap, >pu, &rrc_nr) != SRSRAN_SUCCESS) {
|
||||
stack_logger.error("Couldn't initialize RRC");
|
||||
return SRSRAN_ERROR;
|
||||
|
@ -281,16 +301,14 @@ void enb_stack_lte::run_thread()
|
|||
void enb_stack_lte::write_sdu(uint16_t rnti, uint32_t eps_bearer_id, srsran::unique_byte_buffer_t sdu, int pdcp_sn)
|
||||
{
|
||||
auto bearer = bearers.get_radio_bearer(rnti, eps_bearer_id);
|
||||
auto task = [this, rnti, eps_bearer_id, bearer, pdcp_sn](srsran::unique_byte_buffer_t& sdu) {
|
||||
// route SDU to PDCP entity
|
||||
if (bearer.rat == srsran_rat_t::lte) {
|
||||
pdcp.write_sdu(rnti, bearer.lcid, std::move(sdu), pdcp_sn);
|
||||
} else if (bearer.rat == srsran_rat_t::nr) {
|
||||
pdcp_nr.write_sdu(rnti, bearer.lcid, std::move(sdu), pdcp_sn);
|
||||
} else {
|
||||
stack_logger.warning("Can't deliver SDU for EPS bearer %d. Dropping it.", eps_bearer_id);
|
||||
}
|
||||
};
|
||||
// route SDU to PDCP entity
|
||||
if (bearer.rat == srsran_rat_t::lte) {
|
||||
pdcp.write_sdu(rnti, bearer.lcid, std::move(sdu), pdcp_sn);
|
||||
} else if (bearer.rat == srsran_rat_t::nr) {
|
||||
pdcp_nr.write_sdu(rnti, bearer.lcid, std::move(sdu), pdcp_sn);
|
||||
} else {
|
||||
stack_logger.warning("Can't deliver SDU for EPS bearer %d. Dropping it.", eps_bearer_id);
|
||||
}
|
||||
}
|
||||
|
||||
std::map<uint32_t, srsran::unique_byte_buffer_t> enb_stack_lte::get_buffered_pdus(uint16_t rnti, uint32_t lcid)
|
||||
|
|
|
@ -394,7 +394,7 @@ srsran::expected<uint32_t> bearer_cfg_handler::add_gtpu_bearer(uint32_t
|
|||
erab_t::gtpu_tunnel bearer;
|
||||
bearer.teid_out = teid_out;
|
||||
bearer.addr = addr;
|
||||
srsran::expected<uint32_t> teidin = gtpu->add_bearer(rnti, erab.lcid, addr, teid_out, props);
|
||||
srsran::expected<uint32_t> teidin = gtpu->add_bearer(rnti, erab.id, addr, teid_out, props);
|
||||
if (teidin.is_error()) {
|
||||
logger->error("Adding erab_id=%d to GTPU", erab_id);
|
||||
return srsran::default_error_t();
|
||||
|
@ -411,7 +411,7 @@ void bearer_cfg_handler::rem_gtpu_bearer(uint32_t erab_id)
|
|||
logger->warning("Removing erab_id=%d from GTPU", erab_id);
|
||||
return;
|
||||
}
|
||||
gtpu->rem_bearer(rnti, it->second.lcid);
|
||||
gtpu->rem_bearer(rnti, it->second.id);
|
||||
}
|
||||
|
||||
void bearer_cfg_handler::fill_pending_nas_info(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg)
|
||||
|
|
|
@ -29,35 +29,35 @@ static const size_t PDU_HEADER_SIZE = 20;
|
|||
class pdcp_tester : public pdcp_dummy
|
||||
{
|
||||
public:
|
||||
void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu, int pdcp_sn) override
|
||||
void write_sdu(uint16_t rnti, uint32_t eps_bearer_id, srsran::unique_byte_buffer_t sdu, int pdcp_sn) override
|
||||
{
|
||||
last_sdu = std::move(sdu);
|
||||
last_pdcp_sn = pdcp_sn;
|
||||
last_rnti = rnti;
|
||||
last_lcid = lcid;
|
||||
last_sdu = std::move(sdu);
|
||||
last_pdcp_sn = pdcp_sn;
|
||||
last_rnti = rnti;
|
||||
last_eps_bearer_id = eps_bearer_id;
|
||||
}
|
||||
std::map<uint32_t, srsran::unique_byte_buffer_t> get_buffered_pdus(uint16_t rnti, uint32_t lcid) override
|
||||
std::map<uint32_t, srsran::unique_byte_buffer_t> get_buffered_pdus(uint16_t rnti, uint32_t eps_bearer_id) override
|
||||
{
|
||||
return std::move(buffered_pdus);
|
||||
}
|
||||
void send_status_report(uint16_t rnti) override {}
|
||||
void send_status_report(uint16_t rnti, uint32_t lcid) override {}
|
||||
void send_status_report(uint16_t rnti, uint32_t eps_bearer_id) override {}
|
||||
|
||||
void push_buffered_pdu(uint32_t sn, srsran::unique_byte_buffer_t pdu) { buffered_pdus[sn] = std::move(pdu); }
|
||||
|
||||
void clear()
|
||||
{
|
||||
last_sdu = nullptr;
|
||||
last_pdcp_sn = -1;
|
||||
last_lcid = 0;
|
||||
last_rnti = SRSRAN_INVALID_RNTI;
|
||||
last_sdu = nullptr;
|
||||
last_pdcp_sn = -1;
|
||||
last_eps_bearer_id = 0;
|
||||
last_rnti = SRSRAN_INVALID_RNTI;
|
||||
}
|
||||
|
||||
std::map<uint32_t, srsran::unique_byte_buffer_t> buffered_pdus;
|
||||
srsran::unique_byte_buffer_t last_sdu;
|
||||
int last_pdcp_sn = -1;
|
||||
uint16_t last_rnti = SRSRAN_INVALID_RNTI;
|
||||
uint32_t last_lcid = 0;
|
||||
int last_pdcp_sn = -1;
|
||||
uint16_t last_rnti = SRSRAN_INVALID_RNTI;
|
||||
uint32_t last_eps_bearer_id = 0;
|
||||
};
|
||||
|
||||
struct dummy_socket_manager : public srsran::socket_manager_itf {
|
||||
|
@ -153,44 +153,44 @@ void test_gtpu_tunnel_manager()
|
|||
const char* sgw_addr_str = "127.0.0.1";
|
||||
struct sockaddr_in sgw_sockaddr = {};
|
||||
srsran::net_utils::set_sockaddr(&sgw_sockaddr, sgw_addr_str, GTPU_PORT);
|
||||
uint32_t sgw_addr = ntohl(sgw_sockaddr.sin_addr.s_addr);
|
||||
const uint32_t drb1_lcid = 3;
|
||||
uint32_t sgw_addr = ntohl(sgw_sockaddr.sin_addr.s_addr);
|
||||
const uint32_t drb1_eps_bearer_id = 5;
|
||||
srsran::task_scheduler task_sched;
|
||||
gtpu_args_t gtpu_args = {};
|
||||
|
||||
gtpu_tunnel_manager tunnels(&task_sched, srslog::fetch_basic_logger("GTPU"));
|
||||
tunnels.init(gtpu_args, nullptr);
|
||||
TESTASSERT(tunnels.find_tunnel(0) == nullptr);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_lcid).empty());
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_eps_bearer_id).empty());
|
||||
TESTASSERT(tunnels.find_rnti_tunnels(0x46) == nullptr);
|
||||
|
||||
// Creation of tunnels for different users and lcids
|
||||
const gtpu_tunnel* tun = tunnels.add_tunnel(0x46, drb1_lcid, 5, sgw_addr);
|
||||
// Creation of tunnels for different users and bearers
|
||||
const gtpu_tunnel* tun = tunnels.add_tunnel(0x46, drb1_eps_bearer_id, 5, sgw_addr);
|
||||
TESTASSERT(tun != nullptr);
|
||||
TESTASSERT(tunnels.find_tunnel(tun->teid_in) == tun);
|
||||
const gtpu_tunnel* tun2 = tunnels.add_tunnel(0x47, drb1_lcid, 6, sgw_addr);
|
||||
const gtpu_tunnel* tun2 = tunnels.add_tunnel(0x47, drb1_eps_bearer_id, 6, sgw_addr);
|
||||
TESTASSERT(tun2 != nullptr);
|
||||
TESTASSERT(tunnels.find_tunnel(tun2->teid_in) == tun2);
|
||||
tun2 = tunnels.add_tunnel(0x47, drb1_lcid + 1, 7, sgw_addr);
|
||||
tun2 = tunnels.add_tunnel(0x47, drb1_eps_bearer_id + 1, 7, sgw_addr);
|
||||
TESTASSERT(tun2 != nullptr);
|
||||
TESTASSERT(tunnels.find_tunnel(tun2->teid_in) == tun2);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_lcid).size() == 1);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x47, drb1_lcid).size() == 1);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x47, drb1_lcid + 1).size() == 1);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_eps_bearer_id).size() == 1);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x47, drb1_eps_bearer_id).size() == 1);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x47, drb1_eps_bearer_id + 1).size() == 1);
|
||||
|
||||
// TEST: Creation/Removal of indirect tunnel
|
||||
const gtpu_tunnel* fwd_tun = tunnels.add_tunnel(0x46, drb1_lcid, 8, sgw_addr);
|
||||
const gtpu_tunnel* fwd_tun = tunnels.add_tunnel(0x46, drb1_eps_bearer_id, 8, sgw_addr);
|
||||
TESTASSERT(fwd_tun != nullptr);
|
||||
TESTASSERT(tunnels.find_tunnel(fwd_tun->teid_in) == fwd_tun);
|
||||
tunnels.setup_forwarding(tun->teid_in, fwd_tun->teid_in);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_lcid).size() == 2);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_eps_bearer_id).size() == 2);
|
||||
// Removing a tunnel also clears any associated forwarding tunnel
|
||||
TESTASSERT(tunnels.remove_tunnel(tun->teid_in));
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_lcid).empty());
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_eps_bearer_id).empty());
|
||||
|
||||
// TEST: Prioritization of one TEID over another
|
||||
const gtpu_tunnel* before_tun = tunnels.add_tunnel(0x46, drb1_lcid, 7, sgw_addr);
|
||||
const gtpu_tunnel* after_tun = tunnels.add_tunnel(0x46, drb1_lcid, 8, sgw_addr);
|
||||
const gtpu_tunnel* before_tun = tunnels.add_tunnel(0x46, drb1_eps_bearer_id, 7, sgw_addr);
|
||||
const gtpu_tunnel* after_tun = tunnels.add_tunnel(0x46, drb1_eps_bearer_id, 8, sgw_addr);
|
||||
TESTASSERT(before_tun != nullptr and after_tun != nullptr);
|
||||
tunnels.set_tunnel_priority(before_tun->teid_in, after_tun->teid_in);
|
||||
for (uint32_t i = 0; i < 1000; ++i) {
|
||||
|
@ -200,9 +200,9 @@ void test_gtpu_tunnel_manager()
|
|||
tunnels.handle_rx_pdcp_sdu(before_tun->teid_in);
|
||||
}
|
||||
// Removing active TEID, will automatically switch TEID paths
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_lcid).size() == 2);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_eps_bearer_id).size() == 2);
|
||||
tunnels.remove_tunnel(before_tun->teid_in);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_lcid).size() == 1);
|
||||
TESTASSERT(tunnels.find_rnti_bearer_tunnels(0x46, drb1_eps_bearer_id).size() == 1);
|
||||
TESTASSERT(after_tun->state == gtpu_tunnel_manager::tunnel_state::pdcp_active);
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ int test_gtpu_direct_tunneling(tunnel_test_event event)
|
|||
srslog::basic_logger& logger = srslog::fetch_basic_logger("TEST");
|
||||
logger.info("\n\n**** Test GTPU Direct Tunneling ****\n");
|
||||
uint16_t rnti = 0x46, rnti2 = 0x50;
|
||||
uint32_t drb1 = 3;
|
||||
uint32_t drb1_bearer_id = 5;
|
||||
uint32_t sgw_teidout1 = 1, sgw_teidout2 = 2;
|
||||
const char * sgw_addr_str = "127.0.0.1", *senb_addr_str = "127.0.1.1", *tenb_addr_str = "127.0.1.2";
|
||||
struct sockaddr_in senb_sockaddr = {}, sgw_sockaddr = {}, tenb_sockaddr = {};
|
||||
|
@ -246,8 +246,8 @@ int test_gtpu_direct_tunneling(tunnel_test_event event)
|
|||
tenb_gtpu.init(gtpu_args, &tenb_pdcp);
|
||||
|
||||
// create tunnels MME-SeNB and MME-TeNB
|
||||
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();
|
||||
uint32_t senb_teid_in = senb_gtpu.add_bearer(rnti, drb1_bearer_id, sgw_addr, sgw_teidout1).value();
|
||||
uint32_t tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1_bearer_id, sgw_addr, sgw_teidout2).value();
|
||||
|
||||
// Buffer PDUs in SeNB PDCP
|
||||
for (size_t sn = 6; sn < 10; ++sn) {
|
||||
|
@ -260,11 +260,11 @@ 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).value();
|
||||
uint32_t dl_tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1_bearer_id, senb_addr, 0, &props).value();
|
||||
props = {};
|
||||
props.forward_from_teidin_present = true;
|
||||
props.forward_from_teidin = senb_teid_in;
|
||||
senb_gtpu.add_bearer(rnti, drb1, tenb_addr, dl_tenb_teid_in, &props);
|
||||
senb_gtpu.add_bearer(rnti, drb1_bearer_id, tenb_addr, dl_tenb_teid_in, &props);
|
||||
|
||||
std::vector<uint8_t> data_vec(10);
|
||||
std::iota(data_vec.begin(), data_vec.end(), 0);
|
||||
|
@ -280,7 +280,7 @@ int test_gtpu_direct_tunneling(tunnel_test_event event)
|
|||
pdu_view = srsran::make_span(tenb_pdcp.last_sdu);
|
||||
TESTASSERT(std::count(pdu_view.begin() + PDU_HEADER_SIZE, pdu_view.end(), 7) == 10);
|
||||
TESTASSERT(tenb_pdcp.last_rnti == rnti2);
|
||||
TESTASSERT(tenb_pdcp.last_lcid == drb1);
|
||||
TESTASSERT(tenb_pdcp.last_eps_bearer_id == drb1_bearer_id);
|
||||
TESTASSERT(tenb_pdcp.last_pdcp_sn == (int)7);
|
||||
|
||||
// TEST: verify that PDCP buffered SNs have been forwarded through SeNB->TeNB tunnel
|
||||
|
@ -289,7 +289,7 @@ int test_gtpu_direct_tunneling(tunnel_test_event event)
|
|||
pdu_view = srsran::make_span(tenb_pdcp.last_sdu);
|
||||
TESTASSERT(std::count(pdu_view.begin() + PDU_HEADER_SIZE, pdu_view.end(), sn) == 10);
|
||||
TESTASSERT(tenb_pdcp.last_rnti == rnti2);
|
||||
TESTASSERT(tenb_pdcp.last_lcid == drb1);
|
||||
TESTASSERT(tenb_pdcp.last_eps_bearer_id == drb1_bearer_id);
|
||||
TESTASSERT(tenb_pdcp.last_pdcp_sn == (int)sn);
|
||||
}
|
||||
|
||||
|
@ -302,7 +302,7 @@ int test_gtpu_direct_tunneling(tunnel_test_event event)
|
|||
pdu_view = srsran::make_span(tenb_pdcp.last_sdu);
|
||||
TESTASSERT(pdu_view.size() == encoded_data.size() and
|
||||
std::equal(pdu_view.begin(), pdu_view.end(), encoded_data.begin()));
|
||||
TESTASSERT(tenb_pdcp.last_rnti == rnti2 and tenb_pdcp.last_lcid == drb1);
|
||||
TESTASSERT(tenb_pdcp.last_rnti == rnti2 and tenb_pdcp.last_eps_bearer_id == drb1_bearer_id);
|
||||
|
||||
// TEST: verify that MME->TeNB packets are buffered until SeNB->TeNB tunnel is closed
|
||||
tenb_pdcp.clear();
|
||||
|
@ -361,7 +361,7 @@ int test_gtpu_direct_tunneling(tunnel_test_event event)
|
|||
if (event != tunnel_test_event::ue_removal_no_marker) {
|
||||
// The User is removed in SeNB in case it hasn't and there was no reestablishment
|
||||
if (std::uniform_int_distribution<uint32_t>{0, 1}(g) > 0) {
|
||||
senb_gtpu.rem_bearer(0x46, 3);
|
||||
senb_gtpu.rem_bearer(0x46, drb1_bearer_id);
|
||||
}
|
||||
senb_gtpu.rem_user(0x46);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue