diff --git a/lib/include/srsran/common/common_nr.h b/lib/include/srsran/common/common_nr.h index 889046bc7..fc23fc691 100644 --- a/lib/include/srsran/common/common_nr.h +++ b/lib/include/srsran/common/common_nr.h @@ -57,6 +57,15 @@ enum class nr_drb { const uint32_t MAX_NR_DRB_ID = 29; const uint32_t MAX_NR_NOF_BEARERS = MAX_NR_DRB_ID + MAX_NR_SRB_ID; // 32 +// PDU Session ID range [1, 15]. See TS 24.007, 11.2.3.1b. +const uint32_t MAX_NR_PDU_SESSION_ID = 15; +const uint32_t MIN_NR_PDU_SESSION_ID = 1; + +constexpr bool is_nr_pdu_session_id(uint32_t pdu_session_id) +{ + return pdu_session_id >= MIN_NR_PDU_SESSION_ID and pdu_session_id <= MAX_NR_PDU_SESSION_ID; +} + constexpr bool is_nr_lcid(uint32_t lcid) { return lcid < MAX_NR_NOF_BEARERS; diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index 6114a14d9..001ebb2a4 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -49,7 +49,7 @@ class gtpu_tunnel_manager public: // 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 = 32; + const static size_t MAX_TUNNELS_PER_UE = 10; enum class tunnel_state { pdcp_active, buffering, forward_to, forwarded_from, inactive }; diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 1cfdba525..74bf0e6b0 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -65,8 +65,8 @@ gtpu_tunnel_manager::find_rnti_bearer_tunnels(uint16_t rnti, uint32_t eps_bearer logger.warning("Searching for bearer with invalid eps-BearerID=%d", eps_bearer_id); return {}; } - if (ran_type == srsran::srsran_rat_t::nr and not is_nr_lcid(eps_bearer_id)) { - logger.warning("Searching for bearer with invalid eps-BearerID=%d", eps_bearer_id); + if (ran_type == srsran::srsran_rat_t::nr and not is_nr_pdu_session_id(eps_bearer_id)) { + logger.warning("Searching for bearer with invalid PDU Session Id=%d", eps_bearer_id); return {}; } auto* ue_ptr = find_rnti_tunnels(rnti); @@ -86,8 +86,8 @@ gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t eps_bearer_id, uint32_t logger.warning("Adding TEID with invalid eps-BearerID=%d", eps_bearer_id); return nullptr; } - if (ran_type == srsran::srsran_rat_t::nr and not is_nr_lcid(eps_bearer_id)) { - logger.warning("Adding TEID with invalid eps-BearerID=%d", eps_bearer_id); + if (ran_type == srsran::srsran_rat_t::nr and not is_nr_pdu_session_id(eps_bearer_id)) { + logger.warning("Adding TEID with invalid PDU Session Id=%d", eps_bearer_id); return nullptr; } auto ret_pair = tunnels.insert(tunnel()); diff --git a/srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h b/srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h index 31ceaac77..66f49b983 100644 --- a/srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h +++ b/srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h @@ -64,8 +64,6 @@ private: pdu_session_list_t pdu_session_list; srslog::basic_logger& logger; - std::map next_lcid_list; // Map RNTI to next LCID to be allocated - int add_gtpu_bearer(uint16_t rnti, uint32_t pdu_session_id, uint32_t teid_out, diff --git a/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc b/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc index 9dab4bb5b..4b6f59f0d 100644 --- a/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc +++ b/srsgnb/src/stack/ngap/ngap_ue_bearer_manager.cc @@ -11,6 +11,7 @@ */ #include "srsgnb/hdr/stack/ngap/ngap_ue_bearer_manager.h" +#include "srsran/common/common_nr.h" namespace srsenb { ngap_ue_bearer_manager::ngap_ue_bearer_manager(gtpu_interface_rrc* gtpu_, srslog::basic_logger& logger_) : @@ -39,6 +40,10 @@ int ngap_ue_bearer_manager::add_pdu_session(uint16_t } lcid = allocate_lcid(rnti); + if (lcid >= srsran::MAX_NR_NOF_BEARERS) { + logger.error("Adding PDU Session ID=%d to GTPU. No free LCID.", pdu_session_id); + return SRSRAN_ERROR; + } // TODO: remove lcid and just use pdu_session_id and rnti as id for GTP tunnel int rtn = add_gtpu_bearer(rnti, pdu_session_id, teid_out, addr_out, tunnel); @@ -65,7 +70,6 @@ int ngap_ue_bearer_manager::reset_pdu_sessions(uint16_t rnti) auto pdu_session_id = iter->first; rem_gtpu_bearer(rnti, pdu_session_id); } - next_lcid_list.erase(rnti); return true; } @@ -116,10 +120,20 @@ void ngap_ue_bearer_manager::rem_gtpu_bearer(uint16_t rnti, uint32_t pdu_session uint8_t ngap_ue_bearer_manager::allocate_lcid(uint32_t rnti) { - if (next_lcid_list.find(rnti) == next_lcid_list.end()) { - next_lcid_list[rnti] = 4; + if (pdu_session_list.empty()) { + return 4; + } + for (unsigned lcid = 4; lcid < srsran::MAX_NR_NOF_BEARERS; lcid++) { + const auto pdu_session_it = + std::find_if(pdu_session_list.cbegin(), + pdu_session_list.cend(), + [lcid](const std::pair& t) { return t.second.lcid != lcid; }); + if (pdu_session_it != pdu_session_list.cend()) { + return lcid; + } } - return next_lcid_list[rnti]++; + // All LCIDs are used. + return srsran::MAX_NR_NOF_BEARERS; } } // namespace srsenb