diff --git a/srsenb/hdr/stack/upper/common_enb.h b/srsenb/hdr/stack/upper/common_enb.h index 1a2651bc9..6a13563ec 100644 --- a/srsenb/hdr/stack/upper/common_enb.h +++ b/srsenb/hdr/stack/upper/common_enb.h @@ -37,7 +37,7 @@ namespace srsenb { #define SRSENB_N_DRB 8 #define SRSENB_N_RADIO_BEARERS 11 -typedef enum { +enum rb_id_t { RB_ID_SRB0 = 0, RB_ID_SRB1, RB_ID_SRB2, @@ -50,8 +50,8 @@ typedef enum { RB_ID_DRB7, RB_ID_DRB8, RB_ID_N_ITEMS, -} rb_id_t; -static const char rb_id_text[RB_ID_N_ITEMS][20] = +}; +static const char* rb_id_text[] = {"SRB0", "SRB1", "SRB2", "DRB1", "DRB2", "DRB3", "DRB4", "DRB5", "DRB6", "DRB7", "DRB8"}; // Cat 3 UE - Max number of DL-SCH transport block bits received within a TTI @@ -59,6 +59,7 @@ static const char rb_id_text[RB_ID_N_ITEMS][20] = #define SRSENB_MAX_BUFFER_SIZE_BITS 102048 #define SRSENB_MAX_BUFFER_SIZE_BYTES 12756 #define SRSENB_BUFFER_HEADER_OFFSET 1024 + } // namespace srsenb #endif // SRSENB_COMMON_ENB_H diff --git a/srsenb/src/stack/rrc/CMakeLists.txt b/srsenb/src/stack/rrc/CMakeLists.txt index 687007102..3a0d7cf59 100644 --- a/srsenb/src/stack/rrc/CMakeLists.txt +++ b/srsenb/src/stack/rrc/CMakeLists.txt @@ -20,3 +20,4 @@ set(SOURCES rrc.cc rrc_ue.cc rrc_mobility.cc rrc_cell_cfg.cc rrc_bearer_cfg.cc) add_library(srsenb_rrc STATIC ${SOURCES}) + diff --git a/srsue/hdr/stack/rrc/rrc_nr.h b/srsue/hdr/stack/rrc/rrc_nr.h new file mode 100644 index 000000000..5887c7858 --- /dev/null +++ b/srsue/hdr/stack/rrc/rrc_nr.h @@ -0,0 +1,154 @@ +/* + * Copyright 2013-2020 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#ifndef SRSUE_RRC_NR_H +#define SRSUE_RRC_NR_H + +#include "srslte/asn1/rrc_nr_asn1.h" +#include "srslte/common/block_queue.h" +#include "srslte/common/buffer_pool.h" +#include "srslte/interfaces/ue_interfaces.h" +#include "srslte/interfaces/ue_nr_interfaces.h" +#include "srsue/hdr/stack/upper/gw.h" + +namespace srsue { + +// Expert arguments to create GW without proper RRC +struct core_less_args_t { + std::string ip_addr; + srsue::gw_args_t gw_args; + uint8_t drb_lcid; +}; + +struct rrc_nr_args_t { + core_less_args_t coreless; + std::string log_level; + uint32_t log_hex_limit; +}; + +struct rrc_nr_metrics_t {}; + +class rrc_nr : public rrc_interface_phy_nr, + public rrc_interface_pdcp, + public rrc_interface_rlc, + public srslte::timer_callback +{ +public: + rrc_nr(); + ~rrc_nr(); + + void init(phy_interface_rrc_nr* phy_, + mac_interface_rrc_nr* mac_, + rlc_interface_rrc* rlc_, + pdcp_interface_rrc* pdcp_, + gw_interface_rrc* gw_, + srslte::timer_handler* timers_, + stack_interface_rrc* stack_, + const rrc_nr_args_t& args_); + + void stop(); + + void get_metrics(rrc_nr_metrics_t& m); + + // Timeout callback interface + void timer_expired(uint32_t timeout_id) final; + void srslte_rrc_log(const char* str); + + enum direction_t { Rx = 0, Tx }; + template + void log_rrc_message(const std::string& source, direction_t dir, const srslte::byte_buffer_t* pdu, const T& msg); + + // PHY interface + void in_sync() final; + void out_of_sync() final; + + // MAC interface + void run_tti(uint32_t tti) final; + + // RLC interface + void max_retx_attempted() final; + + // PDCP interface + void write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) final; + void write_pdu_bcch_bch(srslte::unique_byte_buffer_t pdu) final; + void write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t pdu) final; + void write_pdu_pcch(srslte::unique_byte_buffer_t pdu) final; + void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) final; + + // STACK interface + void cell_search_completed(const phy_interface_rrc_lte::cell_search_ret_t& cs_ret, + const phy_interface_rrc_lte::phy_cell_t& found_cell); + +private: + struct cmd_msg_t { + enum { PDU, PCCH, PDU_MCH, RLF, PDU_BCCH_DLSCH, STOP } command; + srslte::unique_byte_buffer_t pdu; + uint16_t lcid; + }; + + bool running = false; + srslte::block_queue cmd_q; + + srslte::byte_buffer_pool* pool = nullptr; + phy_interface_rrc_nr* phy = nullptr; + mac_interface_rrc* mac = nullptr; + rlc_interface_rrc* rlc = nullptr; + pdcp_interface_rrc* pdcp = nullptr; + gw_interface_rrc* gw = nullptr; + stack_interface_rrc* stack = nullptr; + + srslte::log_ref log_h; + + /// RRC states (3GPP 38.331 v15.5.1 Sec 4.2.1) + enum rrc_nr_state_t { + RRC_NR_STATE_IDLE = 0, + RRC_NR_STATE_CONNECTED, + RRC_NR_STATE_CONNECTED_INACTIVE, + RRC_NR_STATE_N_ITEMS, + }; + const static char* rrc_nr_state_text[RRC_NR_STATE_N_ITEMS]; + + rrc_nr_state_t state = RRC_NR_STATE_IDLE, last_state = RRC_NR_STATE_IDLE; + uint8_t transaction_id = 0; + + rrc_nr_args_t args = {}; + + // RRC constants and timers + srslte::timer_handler* timers = nullptr; + + // Radio bearers + std::map rb_id_t = {{0, "SRB0"}, {1, "SRB1"}, {2, "SRB2"}, {3, "SRB3"}, {4, "DRB1"}}; + + std::string get_rb_name(uint32_t lcid) final + { + if (lcid < rb_id_t.size()) { + return rb_id_t.at(lcid); + } else { + return "INVALID_RB"; + } + } + + bool initiated = false; +}; + +} // namespace srsue + +#endif // SRSUE_RRC_NR_H \ No newline at end of file diff --git a/srsue/src/stack/rrc/CMakeLists.txt b/srsue/src/stack/rrc/CMakeLists.txt index a4307fbfa..52181fa4d 100644 --- a/srsue/src/stack/rrc/CMakeLists.txt +++ b/srsue/src/stack/rrc/CMakeLists.txt @@ -19,4 +19,9 @@ # set(SOURCES rrc.cc rrc_procedures.cc rrc_meas.cc) -add_library(srsue_rrc STATIC ${SOURCES}) \ No newline at end of file +add_library(srsue_rrc STATIC ${SOURCES}) + +if(ENABLE_5GNR) + set(SOURCES rrc_nr.cc) + add_library(srsgnb_rrc STATIC ${SOURCES}) +endif() diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc new file mode 100644 index 000000000..cb9777121 --- /dev/null +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -0,0 +1,101 @@ +/* + * Copyright 2013-2020 Software Radio Systems Limited + * + * This file is part of srsLTE. + * + * srsLTE is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * srsLTE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * A copy of the GNU Affero General Public License can be found in + * the LICENSE file in the top-level directory of this distribution + * and at http://www.gnu.org/licenses/. + * + */ + +#include "srsue/hdr/stack/rrc/rrc_nr.h" + +using namespace asn1::rrc_nr; + +namespace srsue { + +const char* rrc_nr::rrc_nr_state_text[] = {"IDLE", "CONNECTED", "CONNECTED-INACTIVE"}; + +rrc_nr::rrc_nr() : log_h("RRC") {} + +rrc_nr::~rrc_nr() = default; + +void rrc_nr::init(phy_interface_rrc_nr* phy_, + mac_interface_rrc_nr* mac_, + rlc_interface_rrc* rlc_, + pdcp_interface_rrc* pdcp_, + gw_interface_rrc* gw_, + srslte::timer_handler* timers_, + stack_interface_rrc* stack_, + const rrc_nr_args_t& args_) +{ + phy = phy_; + rlc = rlc_; + pdcp = pdcp_; + gw = gw_; + timers = timers_; + stack = stack_; + args = args_; + + log_h->info("Creating dummy DRB on LCID=%d\n", args.coreless.drb_lcid); + srslte::rlc_config_t rlc_cnfg = srslte::rlc_config_t::default_rlc_um_nr_config(6); + rlc->add_bearer(args.coreless.drb_lcid, rlc_cnfg); + + srslte::pdcp_config_t pdcp_cnfg{args.coreless.drb_lcid, + srslte::PDCP_RB_IS_DRB, + srslte::SECURITY_DIRECTION_DOWNLINK, + srslte::SECURITY_DIRECTION_UPLINK, + srslte::PDCP_SN_LEN_18, + srslte::pdcp_t_reordering_t::ms500, + srslte::pdcp_discard_timer_t ::ms100}; + + pdcp->add_bearer(args.coreless.drb_lcid, pdcp_cnfg); +} + +void rrc_nr::stop() {} + +void rrc_nr::get_metrics(rrc_nr_metrics_t& m) {} + +// Timeout callback interface +void rrc_nr::timer_expired(uint32_t timeout_id) {} + +void rrc_nr::srslte_rrc_log(const char* str) {} + +template +void rrc_nr::log_rrc_message(const std::string& source, direction_t dir, const srslte::byte_buffer_t* pdu, const T& msg) +{} + +// PHY interface +void rrc_nr::in_sync() {} +void rrc_nr::out_of_sync() {} + +// MAC interface +void rrc_nr::run_tti(uint32_t tti) {} + +// PDCP interface +void rrc_nr::write_pdu(uint32_t lcid, srslte::unique_byte_buffer_t pdu) {} +void rrc_nr::write_pdu_bcch_bch(srslte::unique_byte_buffer_t pdu) {} +void rrc_nr::write_pdu_bcch_dlsch(srslte::unique_byte_buffer_t pdu) {} +void rrc_nr::write_pdu_pcch(srslte::unique_byte_buffer_t pdu) {} +void rrc_nr::write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t pdu) {} + +// RLC interface +void rrc_nr::max_retx_attempted() {} + +// STACK interface +void rrc_nr::cell_search_completed(const phy_interface_rrc_lte::cell_search_ret_t& cs_ret, + const phy_interface_rrc_lte::phy_cell_t& found_cell) +{} + +} // namespace srsue \ No newline at end of file