From b134781d368b7b92080371ec53af0ad21810cc7f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 21 Sep 2021 12:00:23 +0200 Subject: [PATCH 01/83] enb: remove redundant RLC/PDPC classes for NR the RLC/PDCP entities for NR are included in the RLC/PDCP wrapper classes and don't require their own --- srsenb/hdr/stack/gnb_stack_nr.h | 6 - srsenb/hdr/stack/upper/pdcp_nr.h | 117 -------------- srsenb/hdr/stack/upper/rlc_nr.h | 95 ----------- srsenb/src/stack/upper/CMakeLists.txt | 4 +- srsenb/src/stack/upper/pdcp_nr.cc | 180 --------------------- srsenb/src/stack/upper/rlc_nr.cc | 224 -------------------------- 6 files changed, 2 insertions(+), 624 deletions(-) delete mode 100644 srsenb/hdr/stack/upper/pdcp_nr.h delete mode 100644 srsenb/hdr/stack/upper/rlc_nr.h delete mode 100644 srsenb/src/stack/upper/pdcp_nr.cc delete mode 100644 srsenb/src/stack/upper/rlc_nr.cc diff --git a/srsenb/hdr/stack/gnb_stack_nr.h b/srsenb/hdr/stack/gnb_stack_nr.h index d20135c7a..e0f1b4954 100644 --- a/srsenb/hdr/stack/gnb_stack_nr.h +++ b/srsenb/hdr/stack/gnb_stack_nr.h @@ -20,8 +20,6 @@ #include "srsenb/hdr/stack/mac/nr/mac_nr.h" #include "srsenb/hdr/stack/rrc/rrc_nr.h" -#include "srsenb/hdr/stack/upper/pdcp_nr.h" -#include "srsenb/hdr/stack/upper/rlc_nr.h" #include "upper/pdcp.h" #include "upper/rlc.h" #include "upper/sdap.h" @@ -29,10 +27,6 @@ #include "enb_stack_base.h" #include "srsran/interfaces/gnb_interfaces.h" -// This is needed for GW -#include "srsran/interfaces/ue_interfaces.h" -#include "srsue/hdr/stack/upper/gw.h" - namespace srsenb { class gnb_stack_nr final : public srsenb::enb_stack_base, diff --git a/srsenb/hdr/stack/upper/pdcp_nr.h b/srsenb/hdr/stack/upper/pdcp_nr.h deleted file mode 100644 index 3ea7b676d..000000000 --- a/srsenb/hdr/stack/upper/pdcp_nr.h +++ /dev/null @@ -1,117 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2021 Software Radio Systems Limited - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the distribution. - * - */ - -#include "srsran/interfaces/gnb_interfaces.h" -#include "srsran/interfaces/ue_gw_interfaces.h" -#include "srsran/interfaces/ue_rlc_interfaces.h" -#include "srsran/upper/pdcp.h" -#include - -#ifndef SRSENB_PDCP_NR_H -#define SRSENB_PDCP_NR_H - -namespace srsenb { - -struct pdcp_nr_args_t { - std::string log_level; - uint32_t log_hex_limit; -}; - -class pdcp_nr : public pdcp_interface_rlc_nr, public pdcp_interface_sdap_nr, public pdcp_interface_rrc_nr -{ -public: - explicit pdcp_nr(srsran::task_sched_handle task_sched_, const char* logname); - virtual ~pdcp_nr() = default; - void init(const pdcp_nr_args_t& args_, - rlc_interface_pdcp_nr* rlc_, - rrc_interface_pdcp_nr* rrc_, - sdap_interface_pdcp_nr* gtpu_); - void stop(); - - // pdcp_interface_rlc_nr - void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu); - void notify_delivery(uint16_t rnti, uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn); - void notify_failure(uint16_t rnti, uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sn); - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} - - // pdcp_interface_rrc_nr - void reset(uint16_t rnti) final; - void add_user(uint16_t rnti) final; - void rem_user(uint16_t rnti) final; - void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) final; - void add_bearer(uint16_t rnti, uint32_t lcid, srsran::pdcp_config_t cnfg) final; - void config_security(uint16_t rnti, uint32_t lcid, srsran::as_security_config_t sec_cfg) final; - void enable_integrity(uint16_t rnti, uint32_t lcid) final; - void enable_encryption(uint16_t rnti, uint32_t lcid) final; - -private: - class user_interface_rlc final : public srsue::rlc_interface_pdcp - { - public: - uint16_t rnti; - srsenb::rlc_interface_pdcp_nr* rlc; - // rlc_interface_pdcp_nr - void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu) final; - void discard_sdu(uint32_t lcid, uint32_t discard_sn) final; - bool rb_is_um(uint32_t lcid) final; - bool sdu_queue_is_full(uint32_t lcid) final; - }; - - class user_interface_sdap : public srsue::gw_interface_pdcp - { - public: - uint16_t rnti; - srsenb::sdap_interface_pdcp_nr* sdap; - // gw_interface_pdcp - void write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) final; - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) final {} - }; - - class user_interface_rrc : public srsue::rrc_interface_pdcp - { - public: - uint16_t rnti; - srsenb::rrc_interface_pdcp_nr* rrc; - // rrc_interface_pdcp_nr - void write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) final; - void write_pdu_bcch_bch(srsran::unique_byte_buffer_t pdu) final; - void write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu) final; - void write_pdu_pcch(srsran::unique_byte_buffer_t pdu) final; - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) final {} - void notify_pdcp_integrity_error(uint32_t lcid) final {} - const char* get_rb_name(uint32_t lcid) final; - }; - - class user_interface - { - public: - user_interface_rlc rlc_itf; - user_interface_sdap sdap_itf; - user_interface_rrc rrc_itf; - std::unique_ptr pdcp; - }; - - // args - pdcp_nr_args_t m_args = {}; - rlc_interface_pdcp_nr* m_rlc = nullptr; - rrc_interface_pdcp_nr* m_rrc = nullptr; - sdap_interface_pdcp_nr* m_sdap = nullptr; - - std::map users; - - srsran::task_sched_handle task_sched; - srslog::basic_logger& logger; -}; - -} // namespace srsenb - -#endif // SRSENB_PDCP_NR_H diff --git a/srsenb/hdr/stack/upper/rlc_nr.h b/srsenb/hdr/stack/upper/rlc_nr.h deleted file mode 100644 index 978439bf4..000000000 --- a/srsenb/hdr/stack/upper/rlc_nr.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2021 Software Radio Systems Limited - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the distribution. - * - */ - -#ifndef SRSENB_RLC_NR_H -#define SRSENB_RLC_NR_H - -#include "srsran/interfaces/gnb_interfaces.h" -#include "srsran/interfaces/gnb_mac_interfaces.h" -#include "srsran/rlc/rlc.h" -#include - -namespace srsenb { - -typedef struct { - uint32_t lcid; - uint32_t plmn; - uint16_t mtch_stop; - uint8_t* payload; -} mch_service_t; - -class rlc_nr final : public rlc_interface_mac_nr, public rlc_interface_rrc_nr, public rlc_interface_pdcp_nr -{ -public: - explicit rlc_nr(const char* logname); - void init(pdcp_interface_rlc_nr* pdcp_, - rrc_interface_rlc_nr* rrc_, - mac_interface_rlc_nr* mac_, - srsran::timer_handler* timers_); - void stop(); - - // rlc_interface_rrc_nr - void clear_buffer(uint16_t rnti); - void add_user(uint16_t rnti); - void rem_user(uint16_t rnti); - void add_bearer(uint16_t rnti, uint32_t lcid, srsran::rlc_config_t cnfg); - void add_bearer_mrb(uint16_t rnti, uint32_t lcid); - - // rlc_interface_pdcp_nr - void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu); - bool rb_is_um(uint16_t rnti, uint32_t lcid); - bool sdu_queue_is_full(uint16_t rnti, uint32_t lcid); - const char* get_rb_name(uint32_t lcid); - - // rlc_interface_mac_nr - int read_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes); - // void read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t* payload); - void write_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes); - void read_pdu_pcch(uint8_t* payload, uint32_t buffer_size); - -private: - class user_interface : public srsue::pdcp_interface_rlc, public srsue::rrc_interface_rlc - { - public: - void write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu); - void notify_delivery(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns); - void notify_failure(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns); - void write_pdu_bcch_bch(srsran::unique_byte_buffer_t sdu); - void write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t sdu); - void write_pdu_pcch(srsran::unique_byte_buffer_t sdu); - void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} - void max_retx_attempted() final; - void protocol_failure() final; - const char* get_rb_name(uint32_t lcid) final; - uint16_t rnti; - - srsenb::pdcp_interface_rlc_nr* m_pdcp = nullptr; - srsenb::rrc_interface_rlc_nr* m_rrc = nullptr; - std::unique_ptr m_rlc; - rlc_nr* parent = nullptr; - }; - - // args - srsran::timer_handler* timers = nullptr; - mac_interface_rlc_nr* m_mac = nullptr; - pdcp_interface_rlc_nr* m_pdcp = nullptr; - rrc_interface_rlc_nr* m_rrc = nullptr; - srslog::basic_logger& logger; - - // state - std::map users; - std::vector mch_services; -}; - -} // namespace srsenb - -#endif // SRSENB_RLC_NR_H diff --git a/srsenb/src/stack/upper/CMakeLists.txt b/srsenb/src/stack/upper/CMakeLists.txt index 30e22062c..53637962a 100644 --- a/srsenb/src/stack/upper/CMakeLists.txt +++ b/srsenb/src/stack/upper/CMakeLists.txt @@ -10,5 +10,5 @@ set(SOURCES gtpu.cc pdcp.cc rlc.cc) add_library(srsenb_upper STATIC ${SOURCES}) target_link_libraries(srsenb_upper srsran_asn1 srsran_gtpu) -set(SOURCES pdcp_nr.cc rlc_nr.cc sdap.cc) -add_library(srsgnb_upper STATIC ${SOURCES}) +set(SOURCES sdap.cc) +add_library(srsgnb_upper STATIC ${SOURCES}) \ No newline at end of file diff --git a/srsenb/src/stack/upper/pdcp_nr.cc b/srsenb/src/stack/upper/pdcp_nr.cc deleted file mode 100644 index 540efdbce..000000000 --- a/srsenb/src/stack/upper/pdcp_nr.cc +++ /dev/null @@ -1,180 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2021 Software Radio Systems Limited - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the distribution. - * - */ - -#include "srsenb/hdr/stack/upper/pdcp_nr.h" -#include "srsenb/hdr/common/common_enb.h" - -namespace srsenb { - -pdcp_nr::pdcp_nr(srsran::task_sched_handle task_sched_, const char* logname) : - task_sched(task_sched_), logger(srslog::fetch_basic_logger(logname)) -{} - -void pdcp_nr::init(const pdcp_nr_args_t& args_, - rlc_interface_pdcp_nr* rlc_, - rrc_interface_pdcp_nr* rrc_, - sdap_interface_pdcp_nr* sdap_) -{ - m_args = args_; - m_rlc = rlc_; - m_rrc = rrc_; - m_sdap = sdap_; - - logger.set_level(srslog::str_to_basic_level(m_args.log_level)); - logger.set_hex_dump_max_size(m_args.log_hex_limit); -} - -void pdcp_nr::stop() -{ - for (auto& user : users) { - user.second.pdcp->stop(); - } - users.clear(); -} - -void pdcp_nr::add_user(uint16_t rnti) -{ - if (users.count(rnti) == 0) { - users[rnti].pdcp.reset(new srsran::pdcp(task_sched, "PDCP")); - users[rnti].rlc_itf.rnti = rnti; - users[rnti].sdap_itf.rnti = rnti; - users[rnti].rrc_itf.rnti = rnti; - users[rnti].rlc_itf.rlc = m_rlc; - users[rnti].rrc_itf.rrc = m_rrc; - users[rnti].sdap_itf.sdap = m_sdap; - users[rnti].pdcp->init(&users[rnti].rlc_itf, &users[rnti].rrc_itf, &users[rnti].sdap_itf); - } -} - -void pdcp_nr::rem_user(uint16_t rnti) -{ - users.erase(rnti); -} - -void pdcp_nr::add_bearer(uint16_t rnti, uint32_t lcid, srsran::pdcp_config_t cfg) -{ - if (users.count(rnti)) { - users[rnti].pdcp->add_bearer(lcid, cfg); - } -} - -void pdcp_nr::reset(uint16_t rnti) -{ - if (users.count(rnti)) { - users[rnti].pdcp->reset(); - } -} - -void pdcp_nr::config_security(uint16_t rnti, uint32_t lcid, srsran::as_security_config_t sec_cfg) -{ - if (users.count(rnti)) { - users[rnti].pdcp->config_security(lcid, sec_cfg); - } -} - -void pdcp_nr::enable_integrity(uint16_t rnti, uint32_t lcid) -{ - users[rnti].pdcp->enable_integrity(lcid, srsran::DIRECTION_TXRX); -} - -void pdcp_nr::enable_encryption(uint16_t rnti, uint32_t lcid) -{ - users[rnti].pdcp->enable_encryption(lcid, srsran::DIRECTION_TXRX); -} - -void pdcp_nr::write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) -{ - if (users.count(rnti)) { - users[rnti].pdcp->write_pdu(lcid, std::move(sdu)); - } else { - logger.error("Can't write PDU. RNTI=0x%X doesn't exist.", rnti); - } -} - -void pdcp_nr::notify_delivery(uint16_t rnti, uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) -{ - if (users.count(rnti)) { - users[rnti].pdcp->notify_delivery(lcid, pdcp_sns); - } else { - logger.error("Can't notify Ack of PDU. RNTI=0x%X doesn't exist.", rnti); - } -} - -void pdcp_nr::notify_failure(uint16_t rnti, uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) -{ - if (users.count(rnti)) { - users[rnti].pdcp->notify_failure(lcid, pdcp_sns); - } else { - logger.error("Can't notify Ack of PDU. RNTI=0x%X doesn't exist.", rnti); - } -} - -void pdcp_nr::write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) -{ - if (users.count(rnti)) { - users[rnti].pdcp->write_sdu(lcid, std::move(sdu)); - } else { - logger.error("Can't write SDU. RNTI=0x%X doesn't exist.", rnti); - } -} - -void pdcp_nr::user_interface_sdap::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) -{ - sdap->write_pdu(rnti, lcid, std::move(pdu)); -} - -void pdcp_nr::user_interface_rlc::write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu) -{ - rlc->write_sdu(rnti, lcid, std::move(sdu)); -} - -void pdcp_nr::user_interface_rlc::discard_sdu(uint32_t lcid, uint32_t discard_sn) -{ - fprintf(stderr, "discard_sdu method not implemented.\n"); -} - -bool pdcp_nr::user_interface_rlc::rb_is_um(uint32_t lcid) -{ - return rlc->rb_is_um(rnti, lcid); -} - -bool pdcp_nr::user_interface_rlc::sdu_queue_is_full(uint32_t lcid) -{ - return rlc->sdu_queue_is_full(rnti, lcid); -} - -void pdcp_nr::user_interface_rrc::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) -{ - rrc->write_pdu(rnti, lcid, std::move(pdu)); -} - -void pdcp_nr::user_interface_rrc::write_pdu_bcch_bch(srsran::unique_byte_buffer_t pdu) -{ - ERROR("Error: Received BCCH from ue=%d", rnti); -} - -void pdcp_nr::user_interface_rrc::write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu) -{ - ERROR("Error: Received BCCH from ue=%d", rnti); -} - -void pdcp_nr::user_interface_rrc::write_pdu_pcch(srsran::unique_byte_buffer_t pdu) -{ - ERROR("Error: Received PCCH from ue=%d", rnti); -} - -const char* pdcp_nr::user_interface_rrc::get_rb_name(uint32_t lcid) -{ - return srsenb::get_rb_name(lcid); -} - -} // namespace srsenb diff --git a/srsenb/src/stack/upper/rlc_nr.cc b/srsenb/src/stack/upper/rlc_nr.cc deleted file mode 100644 index b441c83df..000000000 --- a/srsenb/src/stack/upper/rlc_nr.cc +++ /dev/null @@ -1,224 +0,0 @@ -/** - * - * \section COPYRIGHT - * - * Copyright 2013-2021 Software Radio Systems Limited - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the distribution. - * - */ - -#include "srsenb/hdr/stack/upper/rlc_nr.h" -#include "srsran/common/common_nr.h" -namespace srsenb { - -rlc_nr::rlc_nr(const char* logname) : logger(srslog::fetch_basic_logger(logname)) {} - -void rlc_nr::init(pdcp_interface_rlc_nr* pdcp_, - rrc_interface_rlc_nr* rrc_, - mac_interface_rlc_nr* mac_, - srsran::timer_handler* timers_) -{ - m_pdcp = pdcp_; - m_rrc = rrc_; - m_mac = mac_; - timers = timers_; -} - -void rlc_nr::stop() -{ - for (auto& user : users) { - user.second.m_rlc->stop(); - } - users.clear(); -} - -void rlc_nr::add_user(uint16_t rnti) -{ - if (users.count(rnti) == 0) { - user_interface user_itf; - user_itf.rnti = rnti; - user_itf.m_pdcp = m_pdcp; - user_itf.m_rrc = m_rrc; - user_itf.parent = this; - user_itf.m_rlc.reset(new srsran::rlc(logger.id().c_str())); - users[rnti] = std::move(user_itf); - users[rnti].m_rlc->init(&users[rnti], &users[rnti], timers, (int)srsran::nr_srb::srb0); - } -} - -void rlc_nr::rem_user(uint16_t rnti) -{ - if (users.count(rnti)) { - users[rnti].m_rlc->stop(); - users.erase(rnti); - } else { - logger.error("Removing rnti=0x%x. Already removed", rnti); - } -} - -void rlc_nr::clear_buffer(uint16_t rnti) -{ - if (users.count(rnti)) { - users[rnti].m_rlc->empty_queue(); - for (int i = 0; i < SRSRAN_N_RADIO_BEARERS; i++) { - m_mac->rlc_buffer_state(rnti, i, 0, 0); - } - logger.info("Cleared buffer rnti=0x%x", rnti); - } -} - -void rlc_nr::add_bearer(uint16_t rnti, uint32_t lcid, srsran::rlc_config_t cnfg) -{ - if (users.count(rnti)) { - users[rnti].m_rlc->add_bearer(lcid, cnfg); - } -} - -void rlc_nr::add_bearer_mrb(uint16_t rnti, uint32_t lcid) -{ - if (users.count(rnti)) { - users[rnti].m_rlc->add_bearer_mrb(lcid); - } -} - -void rlc_nr::read_pdu_pcch(uint8_t* payload, uint32_t buffer_size) -{ - m_rrc->read_pdu_pcch(payload, buffer_size); -} - -int rlc_nr::read_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) -{ - int ret; - uint32_t tx_queue; - - if (users.count(rnti)) { - if (rnti != SRSRAN_MRNTI) { - ret = users[rnti].m_rlc->read_pdu(lcid, payload, nof_bytes); - tx_queue = users[rnti].m_rlc->get_buffer_state(lcid); - } else { - ret = users[rnti].m_rlc->read_pdu_mch(lcid, payload, nof_bytes); - tx_queue = users[rnti].m_rlc->get_total_mch_buffer_state(lcid); - } - // In the eNodeB, there is no polling for buffer state from the scheduler, thus - // communicate buffer state every time a PDU is read - - uint32_t retx_queue = 0; - logger.debug("Buffer state PDCP: rnti=0x%x, lcid=%d, tx_queue=%d", rnti, lcid, tx_queue); - m_mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); - } else { - ret = SRSRAN_ERROR; - } - return ret; -} - -void rlc_nr::write_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) -{ - if (users.count(rnti)) { - users[rnti].m_rlc->write_pdu(lcid, payload, nof_bytes); - - // In the eNodeB, there is no polling for buffer state from the scheduler, thus - // communicate buffer state every time a new PDU is written - uint32_t tx_queue = users[rnti].m_rlc->get_buffer_state(lcid); - uint32_t retx_queue = 0; - logger.debug("Buffer state PDCP: rnti=0x%x, lcid=%d, tx_queue=%d", rnti, lcid, tx_queue); - m_mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); - } -} - -// void rlc::read_pdu_bcch_dlsch(uint32_t sib_index, uint8_t* payload) -//{ -// // RLC is transparent for BCCH -// m_rrc->read_pdu_bcch_dlsch(sib_index, payload); -//} - -void rlc_nr::write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) -{ - uint32_t tx_queue; - - if (users.count(rnti)) { - if (rnti != SRSRAN_MRNTI) { - users[rnti].m_rlc->write_sdu(lcid, std::move(sdu)); - tx_queue = users[rnti].m_rlc->get_buffer_state(lcid); - } else { - users[rnti].m_rlc->write_sdu_mch(lcid, std::move(sdu)); - tx_queue = users[rnti].m_rlc->get_total_mch_buffer_state(lcid); - } - // In the eNodeB, there is no polling for buffer state from the scheduler, thus - // communicate buffer state every time a new SDU is written - - uint32_t retx_queue = 0; - m_mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); - logger.info("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d", rnti, lcid, tx_queue); - } -} - -bool rlc_nr::rb_is_um(uint16_t rnti, uint32_t lcid) -{ - bool ret = false; - if (users.count(rnti)) { - ret = users[rnti].m_rlc->rb_is_um(lcid); - } - return ret; -} - -bool rlc_nr::sdu_queue_is_full(uint16_t rnti, uint32_t lcid) -{ - bool ret = false; - if (users.count(rnti)) { - ret = users[rnti].m_rlc->sdu_queue_is_full(lcid); - } - return ret; -} -void rlc_nr::user_interface::max_retx_attempted() -{ - m_rrc->max_retx_attempted(rnti); -} - -void rlc_nr::user_interface::protocol_failure() -{ - m_rrc->protocol_failure(rnti); -} - -void rlc_nr::user_interface::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu) -{ - if (lcid == (int)srsran::nr_srb::srb0) { - m_rrc->write_pdu(rnti, lcid, std::move(sdu)); - } else { - m_pdcp->write_pdu(rnti, lcid, std::move(sdu)); - } -} - -void rlc_nr::user_interface::write_pdu_bcch_bch(srsran::unique_byte_buffer_t sdu) -{ - ERROR("Error: Received BCCH from ue=%d", rnti); -} - -void rlc_nr::user_interface::write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t sdu) -{ - ERROR("Error: Received BCCH from ue=%d", rnti); -} - -void rlc_nr::user_interface::write_pdu_pcch(srsran::unique_byte_buffer_t sdu) -{ - ERROR("Error: Received PCCH from ue=%d", rnti); -} - -const char* rlc_nr::user_interface::get_rb_name(uint32_t lcid) -{ - return m_rrc->get_rb_name(lcid); -} - -void rlc_nr::user_interface::notify_delivery(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) -{ - m_pdcp->notify_delivery(rnti, lcid, pdcp_sns); -} - -void rlc_nr::user_interface::notify_failure(uint32_t lcid, const srsran::pdcp_sn_vector_t& pdcp_sns) -{ - m_pdcp->notify_failure(rnti, lcid, pdcp_sns); -} - -} // namespace srsenb From 26cc6d7886198619745a4cb3d8df1cf49b12d656 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 21 Sep 2021 12:12:55 +0200 Subject: [PATCH 02/83] ue: remove stack type parameter for the moment we always use the LTE stack (also for NSA mode). For SA we likely pick a smarter approach to pick the stack type, i.e. using the ARFCN specified in the config. --- srsue/hdr/stack/ue_stack_base.h | 1 - srsue/src/main.cc | 1 - srsue/src/test/ttcn3/src/ttcn3_ue.cc | 22 ++-- srsue/src/ue.cc | 146 ++++++++++----------------- 4 files changed, 62 insertions(+), 108 deletions(-) diff --git a/srsue/hdr/stack/ue_stack_base.h b/srsue/hdr/stack/ue_stack_base.h index d03321763..1fa5f35ce 100644 --- a/srsue/hdr/stack/ue_stack_base.h +++ b/srsue/hdr/stack/ue_stack_base.h @@ -56,7 +56,6 @@ typedef struct { } stack_log_args_t; typedef struct { - std::string type; pkt_trace_args_t pkt_trace; stack_log_args_t log; usim_args_t usim; diff --git a/srsue/src/main.cc b/srsue/src/main.cc index fa1f9825f..e63afe241 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -67,7 +67,6 @@ static int parse_args(all_args_t* args, int argc, char* argv[]) common.add_options() ("ue.radio", bpo::value(&args->rf.type)->default_value("multi"), "Type of the radio [multi]") ("ue.phy", bpo::value(&args->phy.type)->default_value("lte"), "Type of the PHY [lte]") - ("ue.stack", bpo::value(&args->stack.type)->default_value("lte"), "Type of the upper stack [lte, nr]") ("rf.srate", bpo::value(&args->rf.srate_hz)->default_value(0.0), "Force Tx and Rx sampling rate in Hz") ("rf.freq_offset", bpo::value(&args->rf.freq_offset)->default_value(0), "(optional) Frequency offset") diff --git a/srsue/src/test/ttcn3/src/ttcn3_ue.cc b/srsue/src/test/ttcn3/src/ttcn3_ue.cc index 568f9d98d..4cea8d901 100644 --- a/srsue/src/test/ttcn3/src/ttcn3_ue.cc +++ b/srsue/src/test/ttcn3/src/ttcn3_ue.cc @@ -50,24 +50,18 @@ int ttcn3_ue::init(all_args_t args, syssim_interface_phy* syssim_, const std::st args.phy.dl_earfcn = "3400"; args.rf.type = "none"; - args.stack.type = "lte"; args.phy.type = "lte_ttcn3"; // Instantiate layers and stack together our UE - if (args.stack.type == "lte") { - stack = std::unique_ptr(new ue_stack_lte); - if (!stack) { - srsran::console("Error creating LTE stack instance.\n"); - return SRSRAN_ERROR; - } + stack = std::unique_ptr(new ue_stack_lte); + if (!stack) { + srsran::console("Error creating LTE stack instance.\n"); + return SRSRAN_ERROR; + } - phy = std::unique_ptr(new srsue::lte_ttcn3_phy); - if (!phy) { - srsran::console("Error creating LTE PHY instance.\n"); - return SRSRAN_ERROR; - } - } else { - srsran::console("Invalid stack type %s. Supported values are [lte].\n", args.stack.type.c_str()); + phy = std::unique_ptr(new srsue::lte_ttcn3_phy); + if (!phy) { + srsran::console("Error creating LTE PHY instance.\n"); return SRSRAN_ERROR; } diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index 9a3594ae2..d2ef6e5d0 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -54,109 +54,71 @@ int ue::init(const all_args_t& args_) } // Instantiate layers and stack together our UE - if (args.stack.type == "lte") { - std::unique_ptr lte_stack(new ue_stack_lte); - if (!lte_stack) { - srsran::console("Error creating LTE stack instance.\n"); - return SRSRAN_ERROR; - } - - std::unique_ptr gw_ptr(new gw(srslog::fetch_basic_logger("GW"))); - if (!gw_ptr) { - srsran::console("Error creating a GW instance.\n"); - return SRSRAN_ERROR; - } - - std::unique_ptr lte_phy = std::unique_ptr(new srsue::phy); - if (!lte_phy) { - srsran::console("Error creating LTE PHY instance.\n"); - return SRSRAN_ERROR; - } - - std::unique_ptr lte_radio = std::unique_ptr(new srsran::radio); - if (!lte_radio) { - srsran::console("Error creating radio multi instance.\n"); - return SRSRAN_ERROR; - } - - // init layers - if (lte_radio->init(args.rf, lte_phy.get())) { - srsran::console("Error initializing radio.\n"); - return SRSRAN_ERROR; - } - - // from here onwards do not exit immediately if something goes wrong as sub-layers may already use interfaces - if (lte_phy->init(args.phy, lte_stack.get(), lte_radio.get())) { - srsran::console("Error initializing PHY.\n"); - ret = SRSRAN_ERROR; - } + std::unique_ptr lte_stack(new ue_stack_lte); + if (!lte_stack) { + srsran::console("Error creating LTE stack instance.\n"); + return SRSRAN_ERROR; + } - srsue::phy_args_nr_t phy_args_nr = {}; - phy_args_nr.max_nof_prb = args.phy.nr_max_nof_prb; - phy_args_nr.rf_channel_offset = args.phy.nof_lte_carriers; - phy_args_nr.nof_carriers = args.phy.nof_nr_carriers; - phy_args_nr.nof_phy_threads = args.phy.nof_phy_threads; - phy_args_nr.worker_cpu_mask = args.phy.worker_cpu_mask; - phy_args_nr.log = args.phy.log; - phy_args_nr.store_pdsch_ko = args.phy.nr_store_pdsch_ko; - if (lte_phy->init(phy_args_nr, lte_stack.get(), lte_radio.get())) { - srsran::console("Error initializing NR PHY.\n"); - ret = SRSRAN_ERROR; - } + std::unique_ptr gw_ptr(new gw(srslog::fetch_basic_logger("GW"))); + if (!gw_ptr) { + srsran::console("Error creating a GW instance.\n"); + return SRSRAN_ERROR; + } - if (lte_stack->init(args.stack, lte_phy.get(), lte_phy.get(), gw_ptr.get())) { - srsran::console("Error initializing stack.\n"); - ret = SRSRAN_ERROR; - } + std::unique_ptr lte_phy = std::unique_ptr(new srsue::phy); + if (!lte_phy) { + srsran::console("Error creating LTE PHY instance.\n"); + return SRSRAN_ERROR; + } - if (gw_ptr->init(args.gw, lte_stack.get())) { - srsran::console("Error initializing GW.\n"); - ret = SRSRAN_ERROR; - } + std::unique_ptr lte_radio = std::unique_ptr(new srsran::radio); + if (!lte_radio) { + srsran::console("Error creating radio multi instance.\n"); + return SRSRAN_ERROR; + } - // move ownership - stack = std::move(lte_stack); - gw_inst = std::move(gw_ptr); - phy = std::move(lte_phy); - radio = std::move(lte_radio); - } else if (args.stack.type == "nr") { - logger.info("Initializing NR stack"); - std::unique_ptr nr_stack(new srsue::ue_stack_nr()); - std::unique_ptr nr_radio(new srsran::radio_null); - std::unique_ptr nr_phy; - std::unique_ptr gw_ptr(new gw(srslog::fetch_basic_logger("GW"))); - - // Init layers - if (nr_radio->init(args.rf, nullptr)) { - srsran::console("Error initializing radio.\n"); - return SRSRAN_ERROR; - } + // init layers + if (lte_radio->init(args.rf, lte_phy.get())) { + srsran::console("Error initializing radio.\n"); + return SRSRAN_ERROR; + } - if (nr_phy->init(args.phy)) { - srsran::console("Error initializing PHY.\n"); - return SRSRAN_ERROR; - } + // from here onwards do not exit immediately if something goes wrong as sub-layers may already use interfaces + if (lte_phy->init(args.phy, lte_stack.get(), lte_radio.get())) { + srsran::console("Error initializing PHY.\n"); + ret = SRSRAN_ERROR; + } - if (nr_stack->init(args.stack)) { - srsran::console("Error initializing stack.\n"); - return SRSRAN_ERROR; - } + srsue::phy_args_nr_t phy_args_nr = {}; + phy_args_nr.max_nof_prb = args.phy.nr_max_nof_prb; + phy_args_nr.rf_channel_offset = args.phy.nof_lte_carriers; + phy_args_nr.nof_carriers = args.phy.nof_nr_carriers; + phy_args_nr.nof_phy_threads = args.phy.nof_phy_threads; + phy_args_nr.worker_cpu_mask = args.phy.worker_cpu_mask; + phy_args_nr.log = args.phy.log; + phy_args_nr.store_pdsch_ko = args.phy.nr_store_pdsch_ko; + if (lte_phy->init(phy_args_nr, lte_stack.get(), lte_radio.get())) { + srsran::console("Error initializing NR PHY.\n"); + ret = SRSRAN_ERROR; + } - if (gw_ptr->init(args.gw, nr_stack.get())) { - srsran::console("Error initializing GW.\n"); - return SRSRAN_ERROR; - } + if (lte_stack->init(args.stack, lte_phy.get(), lte_phy.get(), gw_ptr.get())) { + srsran::console("Error initializing stack.\n"); + ret = SRSRAN_ERROR; + } - // move ownership - stack = std::move(nr_stack); - gw_inst = std::move(gw_ptr); - phy = std::move(nr_phy); - radio = std::move(nr_radio); - } else { - srsran::console("Invalid stack type %s. Supported values are [lte].\n", args.stack.type.c_str()); + if (gw_ptr->init(args.gw, lte_stack.get())) { + srsran::console("Error initializing GW.\n"); ret = SRSRAN_ERROR; } + // move ownership + stack = std::move(lte_stack); + gw_inst = std::move(gw_ptr); + phy = std::move(lte_phy); + radio = std::move(lte_radio); + if (phy) { srsran::console("Waiting PHY to initialize ... "); phy->wait_initialize(); From cdfbe28b6927269744b9c11e78e2e70cb5940cdf Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 25 Aug 2021 08:48:47 +0200 Subject: [PATCH 03/83] Initial NR-MIB packing/unpacking --- lib/include/srsran/phy/common/phy_common_nr.h | 8 + lib/include/srsran/phy/phch/pbch_msg_nr.h | 62 ++++++ lib/include/srsran/phy/phch/pbch_nr.h | 20 +- lib/include/srsran/phy/phch/phch_cfg_nr.h | 8 - lib/src/phy/phch/pbch_msg_nr.c | 179 ++++++++++++++++++ lib/src/phy/phch/pbch_nr.c | 30 +-- lib/src/phy/phch/test/CMakeLists.txt | 4 + lib/src/phy/phch/test/mib_nr_test.c | 109 +++++++++++ lib/src/phy/sync/test/ssb_decode_test.c | 2 +- 9 files changed, 367 insertions(+), 55 deletions(-) create mode 100644 lib/include/srsran/phy/phch/pbch_msg_nr.h create mode 100644 lib/src/phy/phch/pbch_msg_nr.c create mode 100644 lib/src/phy/phch/test/mib_nr_test.c diff --git a/lib/include/srsran/phy/common/phy_common_nr.h b/lib/include/srsran/phy/common/phy_common_nr.h index 87a679fbd..b5da5ada1 100644 --- a/lib/include/srsran/phy/common/phy_common_nr.h +++ b/lib/include/srsran/phy/common/phy_common_nr.h @@ -357,6 +357,14 @@ typedef enum SRSRAN_API { SRSRAN_DUPLEX_MODE_INVALID } srsran_duplex_mode_t; +/** + * @brief Determines whether the first DMRS goes into symbol index 2 or 3 + */ +typedef enum { + srsran_dmrs_sch_typeA_pos_2 = 0, // Start in slot symbol index 2 (default) + srsran_dmrs_sch_typeA_pos_3 // Start in slot symbol index 3 +} srsran_dmrs_sch_typeA_pos_t; + /** * @brief NR carrier parameters. It is a combination of fixed cell and bandwidth-part (BWP) */ diff --git a/lib/include/srsran/phy/phch/pbch_msg_nr.h b/lib/include/srsran/phy/phch/pbch_msg_nr.h new file mode 100644 index 000000000..8d1e09c09 --- /dev/null +++ b/lib/include/srsran/phy/phch/pbch_msg_nr.h @@ -0,0 +1,62 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSRAN_PBCH_MSG_NR_H +#define SRSRAN_PBCH_MSG_NR_H + +#include "srsran/config.h" +#include "srsran/phy/common/phy_common_nr.h" +#include +#include + +/** + * @brief NR PBCH payload size generated by higher layers, deduced from TS 38.331 MIB description + */ +#define SRSRAN_PBCH_MSG_NR_SZ 24 + +/** + * @brief Describes the NR PBCH message + */ +typedef struct SRSRAN_API { + uint8_t payload[SRSRAN_PBCH_MSG_NR_SZ]; ///< Actual PBCH payload provided by higher layers + uint8_t sfn_4lsb; ///< SFN 4 LSB + uint8_t ssb_idx; ///< SS/PBCH blocks index described in TS 38.213 4.1 + uint8_t k_ssb_msb; ///< Subcarrier offset MSB described in TS 38.211 7.4.3.1 + bool hrf; ///< Half Radio Frame bit + bool crc; ///< Decoder only, it is true only if the received CRC matches +} srsran_pbch_msg_nr_t; + +typedef struct SRSRAN_API { + uint32_t sfn; ///< System frame number + uint8_t ssb_idx; ///< SS/PBCH blocks index described in TS 38.213 4.1 + bool hrf; ///< Half Radio Frame bit + srsran_subcarrier_spacing_t scs_common; ///< Subcarrier spacing common + uint32_t ssb_offset; ///< SSB subcarrier offset + srsran_dmrs_sch_typeA_pos_t dmrs_typeA_pos; ///< DMRS typeA position + uint32_t coreset0_idx; ///< CORESET Zero configuration index (0-15) + uint32_t ss0_idx; ///< SearchSpace Zero configuration index (0-15) + bool cell_barred; ///< Set to true if the cell is barred + bool intra_freq_reselection; ///< Set to true if allowed + uint32_t spare; ///< Unused bits +} srsran_mib_nr_t; + +SRSRAN_API bool srsran_pbch_msg_nr_is_mib(const srsran_pbch_msg_nr_t* msg); + +SRSRAN_API int srsran_pbch_msg_nr_mib_pack(const srsran_mib_nr_t* mib, srsran_pbch_msg_nr_t* msg); + +SRSRAN_API int srsran_pbch_msg_nr_mib_unpack(const srsran_pbch_msg_nr_t* pbch_msg, srsran_mib_nr_t* mib); + +SRSRAN_API uint32_t srsran_pbch_msg_info(const srsran_pbch_msg_nr_t* msg, char* str, uint32_t str_len); + +SRSRAN_API uint32_t srsran_pbch_msg_nr_mib_info(const srsran_mib_nr_t* mib, char* str, uint32_t str_len); + +#endif // SRSRAN_PBCH_MSG_NR_H diff --git a/lib/include/srsran/phy/phch/pbch_nr.h b/lib/include/srsran/phy/phch/pbch_nr.h index c91f68bdf..0ce10f0d8 100644 --- a/lib/include/srsran/phy/phch/pbch_nr.h +++ b/lib/include/srsran/phy/phch/pbch_nr.h @@ -20,11 +20,7 @@ #include "srsran/phy/fec/polar/polar_encoder.h" #include "srsran/phy/fec/polar/polar_rm.h" #include "srsran/phy/modem/modem_table.h" - -/** - * @brief NR PBCH payload size generated by higher layers, deduced from TS 38.331 MIB description - */ -#define SRSRAN_PBCH_NR_PAYLOAD_SZ 24 +#include "srsran/phy/phch/pbch_msg_nr.h" /** * @brief Describes the NR PBCH object initialisation arguments @@ -59,18 +55,6 @@ typedef struct SRSRAN_API { srsran_modem_table_t qpsk; } srsran_pbch_nr_t; -/** - * @brief Describes the PBCH message - */ -typedef struct SRSRAN_API { - uint8_t payload[SRSRAN_PBCH_NR_PAYLOAD_SZ]; ///< Actual PBCH payload provided by higher layers - uint8_t sfn_4lsb; ///< SFN 4 LSB - uint8_t ssb_idx; ///< SS/PBCH blocks index described in TS 38.213 4.1 - uint8_t k_ssb_msb; ///< Subcarrier offset MSB described in TS 38.211 7.4.3.1 - bool hrf; ///< Half Radio Frame bit - bool crc; ///< Decoder only, it is true only if the received CRC matches -} srsran_pbch_msg_nr_t; - /** * @brief Initialises an NR PBCH object with the provided arguments * @param q NR PBCH object @@ -112,6 +96,4 @@ SRSRAN_API int srsran_pbch_nr_decode(srsran_pbch_nr_t* q, const cf_t ce[SRSRAN_SSB_NOF_RE], srsran_pbch_msg_nr_t* msg); -SRSRAN_API uint32_t srsran_pbch_msg_info(const srsran_pbch_msg_nr_t* msg, char* str, uint32_t str_len); - #endif // SRSRAN_PBCH_NR_H diff --git a/lib/include/srsran/phy/phch/phch_cfg_nr.h b/lib/include/srsran/phy/phch/phch_cfg_nr.h index a8e8d337c..cd76ecc0b 100644 --- a/lib/include/srsran/phy/phch/phch_cfg_nr.h +++ b/lib/include/srsran/phy/phch/phch_cfg_nr.h @@ -49,14 +49,6 @@ typedef enum { srsran_dmrs_sch_len_2 // double, 2 symbol long } srsran_dmrs_sch_len_t; -/** - * @brief Determines whether the first pilot goes into symbol index 2 or 3 - */ -typedef enum { - srsran_dmrs_sch_typeA_pos_2 = 0, // Start in slot symbol index 2 (default) - srsran_dmrs_sch_typeA_pos_3 // Start in slot symbol index 3 -} srsran_dmrs_sch_typeA_pos_t; - /** * @brief Determines additional symbols if possible to be added */ diff --git a/lib/src/phy/phch/pbch_msg_nr.c b/lib/src/phy/phch/pbch_msg_nr.c new file mode 100644 index 000000000..9f223be24 --- /dev/null +++ b/lib/src/phy/phch/pbch_msg_nr.c @@ -0,0 +1,179 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ +#include "srsran/phy/phch/pbch_msg_nr.h" +#include "srsran/phy/utils/bit.h" +#include "srsran/phy/utils/vector.h" + +static bool pbch_msg_nr_is_mib(const srsran_pbch_msg_nr_t* msg) +{ + return msg->payload[0] == 0; +} + +bool srsran_pbch_msg_nr_is_mib(const srsran_pbch_msg_nr_t* msg) +{ + if (msg == NULL) { + return false; + } + + return pbch_msg_nr_is_mib(msg); +} + +int srsran_pbch_msg_nr_mib_pack(const srsran_mib_nr_t* mib, srsran_pbch_msg_nr_t* pbch_msg) +{ + if (mib == NULL || pbch_msg == NULL) { + return SRSRAN_ERROR_INVALID_INPUTS; + } + + // Copy PBCH message context + pbch_msg->sfn_4lsb = mib->sfn & 0b1111; + pbch_msg->ssb_idx = mib->ssb_idx; + pbch_msg->k_ssb_msb = mib->ssb_offset >> 4U; + pbch_msg->hrf = mib->hrf; + + // Pack MIB payload + uint8_t* y = pbch_msg->payload; + + // MIB - 1 bit + *(y++) = 0; + + // systemFrameNumber - 6 bits MSB + srsran_bit_unpack(mib->sfn >> 4U, &y, 6); + + // subCarrierSpacingCommon - 1 bit + *(y++) = (mib->scs_common == srsran_subcarrier_spacing_15kHz || mib->scs_common == srsran_subcarrier_spacing_60kHz) + ? 0 + : 1; + + // ssb-SubcarrierOffset - 4 bits + srsran_bit_unpack(mib->ssb_offset, &y, 4); + + // dmrs-TypeA-Position - 1 bit + *(y++) = (mib->dmrs_typeA_pos == srsran_dmrs_sch_typeA_pos_2) ? 0 : 1; + + // pdcch-ConfigSIB1 + // controlResourceSetZero - 4 bits + srsran_bit_unpack(mib->coreset0_idx, &y, 4); + + // searchSpaceZero - 4 bits + srsran_bit_unpack(mib->ss0_idx, &y, 4); + + // Barred - 1 bit + *(y++) = (mib->cell_barred) ? 0 : 1; + + // intraFreqReselection - 1 bit + *(y++) = (mib->intra_freq_reselection) ? 0 : 1; + + // Spare - 1 bit + srsran_bit_unpack(mib->spare, &y, 1); + + return SRSRAN_SUCCESS; +} + +int srsran_pbch_msg_nr_mib_unpack(const srsran_pbch_msg_nr_t* pbch_msg, srsran_mib_nr_t* mib) +{ + if (mib == NULL || pbch_msg == NULL) { + return SRSRAN_ERROR_INVALID_INPUTS; + } + + // Copy PBCH message context + mib->sfn = pbch_msg->sfn_4lsb; + mib->ssb_idx = pbch_msg->ssb_idx; + mib->hrf = pbch_msg->hrf; + mib->ssb_offset = pbch_msg->k_ssb_msb << 4U; + + // Pack MIB payload + uint8_t* y = (uint8_t*)pbch_msg->payload; + + // MIB - 1 bit + if (!pbch_msg_nr_is_mib(pbch_msg)) { + return SRSRAN_ERROR; + } + y++; + + // systemFrameNumber - 6 bits MSB + mib->sfn |= srsran_bit_pack(&y, 6) << 4U; + + // subCarrierSpacingCommon - 1 bit + mib->scs_common = *(y++) == 0 ? srsran_subcarrier_spacing_15kHz : srsran_subcarrier_spacing_30kHz; + + // ssb-SubcarrierOffset - 4 bits + mib->ssb_offset |= srsran_bit_pack(&y, 4); + + // dmrs-TypeA-Position - 1 bit + mib->dmrs_typeA_pos = *(y++) == 0 ? srsran_dmrs_sch_typeA_pos_2 : srsran_dmrs_sch_typeA_pos_3; + + // pdcch-ConfigSIB1 + // controlResourceSetZero - 4 bits + mib->coreset0_idx = srsran_bit_pack(&y, 4); + + // searchSpaceZero - 4 bits + mib->ss0_idx = srsran_bit_pack(&y, 4); + + // Barred - 1 bit + mib->cell_barred = (*(y++) == 0); + + // intraFreqReselection - 1 bit + mib->intra_freq_reselection = (*(y++) == 0); + + // Spare - 1 bit + mib->spare = srsran_bit_pack(&y, 1); + + return SRSRAN_SUCCESS; +} + +uint32_t srsran_pbch_msg_info(const srsran_pbch_msg_nr_t* msg, char* str, uint32_t str_len) +{ + if (msg == NULL || str == NULL || str_len == 0) { + return 0; + } + + uint32_t len = 0; + + len = srsran_print_check(str, str_len, len, "payload="); + + len += srsran_vec_sprint_hex(&str[len], str_len - len, (uint8_t*)msg->payload, SRSRAN_PBCH_MSG_NR_SZ); + + len = srsran_print_check(str, + str_len, + len, + " sfn_lsb=%d ssb_idx=%d k_ssb_msb=%d hrf=%d ", + msg->sfn_4lsb, + msg->ssb_idx, + msg->k_ssb_msb, + msg->hrf); + + return len; +} + +uint32_t srsran_pbch_msg_nr_mib_info(const srsran_mib_nr_t* mib, char* str, uint32_t str_len) +{ + uint32_t len = 0; + + len = srsran_print_check(str, + str_len, + len, + "sfn=%d ssb_idx=%d hrf=%c scs=%d ssb_offset=%d dmrs_typeA_pos=%s coreset0=%d ss0=%d " + "barred=%c intra_freq_reselection=%c spare=%d", + mib->sfn, + mib->ssb_idx, + mib->hrf ? 'y' : 'n', + SRSRAN_SUBC_SPACING_NR(mib->scs_common) / 1000, + mib->ssb_offset, + mib->dmrs_typeA_pos == srsran_dmrs_sch_typeA_pos_2 ? "pos2" : "pos3", + mib->coreset0_idx, + mib->ss0_idx, + mib->cell_barred ? 'y' : 'n', + mib->intra_freq_reselection ? 'y' : 'n', + mib->spare); + + return len; +} diff --git a/lib/src/phy/phch/pbch_nr.c b/lib/src/phy/phch/pbch_nr.c index bc4e28c9a..e91145ac8 100644 --- a/lib/src/phy/phch/pbch_nr.c +++ b/lib/src/phy/phch/pbch_nr.c @@ -43,7 +43,7 @@ /* * Number of generated payload bits, called A */ -#define PBCH_NR_A (SRSRAN_PBCH_NR_PAYLOAD_SZ + 8) +#define PBCH_NR_A (SRSRAN_PBCH_MSG_NR_SZ + 8) /* * Number of payload bits plus CRC @@ -184,7 +184,7 @@ static void pbch_nr_pbch_msg_pack(const srsran_pbch_nr_cfg_t* cfg, const srsran_pbch_msg_nr_t* msg, uint8_t a[PBCH_NR_A]) { // Extract actual payload size - uint32_t A_hat = SRSRAN_PBCH_NR_PAYLOAD_SZ; + uint32_t A_hat = SRSRAN_PBCH_MSG_NR_SZ; // Put SFN in a_hat[A_hat] to a_hat[A_hat + 3] uint32_t j_sfn = 0; @@ -231,7 +231,7 @@ pbch_nr_pbch_msg_unpack(const srsran_pbch_nr_cfg_t* cfg, const uint8_t a[PBCH_NR } // Extract actual payload size - uint32_t A_hat = SRSRAN_PBCH_NR_PAYLOAD_SZ; + uint32_t A_hat = SRSRAN_PBCH_MSG_NR_SZ; // Put SFN in a_hat[A_hat] to a_hat[A_hat + 3] uint32_t j_sfn = 0; @@ -651,27 +651,3 @@ int srsran_pbch_nr_decode(srsran_pbch_nr_t* q, return SRSRAN_SUCCESS; } - -uint32_t srsran_pbch_msg_info(const srsran_pbch_msg_nr_t* msg, char* str, uint32_t str_len) -{ - if (msg == NULL || str == NULL || str_len == 0) { - return 0; - } - - uint32_t len = 0; - - len = srsran_print_check(str, str_len, len, "payload="); - - len += srsran_vec_sprint_hex(&str[len], str_len - len, (uint8_t*)msg->payload, SRSRAN_PBCH_NR_PAYLOAD_SZ); - - len = srsran_print_check(str, - str_len, - len, - " sfn_lsb=%d ssb_idx=%d k_ssb_msb=%d hrf=%d ", - msg->sfn_4lsb, - msg->ssb_idx, - msg->k_ssb_msb, - msg->hrf); - - return len; -} diff --git a/lib/src/phy/phch/test/CMakeLists.txt b/lib/src/phy/phch/test/CMakeLists.txt index 965651324..7a93a4de9 100644 --- a/lib/src/phy/phch/test/CMakeLists.txt +++ b/lib/src/phy/phch/test/CMakeLists.txt @@ -627,6 +627,10 @@ add_executable(dci_nr_test dci_nr_test.c) target_link_libraries(dci_nr_test srsran_phy) add_nr_test(dci_nr_test dci_nr_test) +add_executable(mib_nr_test mib_nr_test.c) +target_link_libraries(mib_nr_test srsran_phy) +add_nr_test(mib_nr_test mib_nr_test) + add_executable(pucch_nr_test pucch_nr_test.c) target_link_libraries(pucch_nr_test srsran_phy) add_nr_test(pucch_nr_test pucch_nr_test) diff --git a/lib/src/phy/phch/test/mib_nr_test.c b/lib/src/phy/phch/test/mib_nr_test.c new file mode 100644 index 000000000..4ea88fbc7 --- /dev/null +++ b/lib/src/phy/phch/test/mib_nr_test.c @@ -0,0 +1,109 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srsran/phy/phch/pbch_msg_nr.h" +#include "srsran/phy/utils/debug.h" +#include "srsran/phy/utils/random.h" +#include "srsran/support/srsran_test.h" +#include +#include + +static uint32_t nof_repetitions = 16; +static srsran_random_t random_gen = NULL; + +static int test_packing_unpacking() +{ + for (uint32_t r = 0; r < nof_repetitions; r++) { + srsran_mib_nr_t mib = {}; + mib.sfn = srsran_random_uniform_int_dist(random_gen, 0, 1023); + mib.ssb_idx = srsran_random_uniform_int_dist(random_gen, 0, 127); + mib.hrf = srsran_random_bool(random_gen, 0.5f); + mib.scs_common = + srsran_random_bool(random_gen, 0.5f) ? srsran_subcarrier_spacing_15kHz : srsran_subcarrier_spacing_30kHz; + mib.ssb_offset = srsran_random_uniform_int_dist(random_gen, 0, 31); + mib.dmrs_typeA_pos = + srsran_random_bool(random_gen, 0.5f) ? srsran_dmrs_sch_typeA_pos_2 : srsran_dmrs_sch_typeA_pos_3; + mib.coreset0_idx = srsran_random_uniform_int_dist(random_gen, 0, 15); + mib.ss0_idx = srsran_random_uniform_int_dist(random_gen, 0, 15); + mib.cell_barred = srsran_random_bool(random_gen, 0.5f); + mib.intra_freq_reselection = srsran_random_bool(random_gen, 0.5f); + mib.spare = srsran_random_uniform_int_dist(random_gen, 0, 1); + + srsran_pbch_msg_nr_t pbch_msg = {}; + TESTASSERT(srsran_pbch_msg_nr_mib_pack(&mib, &pbch_msg) == SRSRAN_SUCCESS); + + TESTASSERT(srsran_pbch_msg_nr_is_mib(&pbch_msg)); + + srsran_mib_nr_t mib2 = {}; + TESTASSERT(srsran_pbch_msg_nr_mib_unpack(&pbch_msg, &mib2) == SRSRAN_SUCCESS); + + char str1[256]; + char str2[256]; + char strp[256]; + srsran_pbch_msg_nr_mib_info(&mib, str1, (uint32_t)sizeof(str1)); + srsran_pbch_msg_nr_mib_info(&mib2, str2, (uint32_t)sizeof(str2)); + srsran_pbch_msg_info(&pbch_msg, strp, (uint32_t)sizeof(strp)); + + if (memcmp(&mib, &mib2, sizeof(srsran_mib_nr_t)) != 0) { + ERROR("Failed packing/unpacking MIB"); + printf(" Source: %s\n", str1); + printf("Unpacked: %s\n", str2); + printf(" Packed: %s\n", strp); + return SRSRAN_ERROR; + } + } + + return SRSRAN_SUCCESS; +} + +static void usage(char* prog) +{ + printf("Usage: %s [cpndv]\n", prog); + printf("\t-v Increase verbose [default none]\n"); + printf("\t-R Set number of Packing/Unpacking [default %d]\n", nof_repetitions); +} + +static void parse_args(int argc, char** argv) +{ + int opt; + while ((opt = getopt(argc, argv, "vR")) != -1) { + switch (opt) { + case 'v': + srsran_verbose++; + break; + case 'R': + nof_repetitions = (uint32_t)strtol(argv[optind], NULL, 10); + break; + default: + usage(argv[0]); + exit(-1); + } + } +} + +int main(int argc, char** argv) +{ + parse_args(argc, argv); + + int ret = SRSRAN_ERROR; + random_gen = srsran_random_init(1234); + + if (test_packing_unpacking() < SRSRAN_SUCCESS) { + goto clean_exit; + } + + ret = SRSRAN_SUCCESS; + +clean_exit: + srsran_random_free(random_gen); + return ret; +} diff --git a/lib/src/phy/sync/test/ssb_decode_test.c b/lib/src/phy/sync/test/ssb_decode_test.c index 5374b3571..ac7510c93 100644 --- a/lib/src/phy/sync/test/ssb_decode_test.c +++ b/lib/src/phy/sync/test/ssb_decode_test.c @@ -82,7 +82,7 @@ static void gen_pbch_msg(srsran_pbch_msg_nr_t* pbch_msg, uint32_t ssb_idx) SRSRAN_MEM_ZERO(pbch_msg, srsran_pbch_msg_nr_t, 1); // Generate payload - srsran_random_bit_vector(random_gen, pbch_msg->payload, SRSRAN_PBCH_NR_PAYLOAD_SZ); + srsran_random_bit_vector(random_gen, pbch_msg->payload, SRSRAN_PBCH_MSG_NR_SZ); pbch_msg->ssb_idx = ssb_idx; pbch_msg->crc = true; From 182202bdb000a7813ffa43529639bfe7fd6499f8 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 21 Sep 2021 15:53:40 +0200 Subject: [PATCH 04/83] Added NR PHY SR test cases --- test/phy/CMakeLists.txt | 25 ++++++++++++++++++++++++- test/phy/nr_phy_test.cc | 13 ++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/test/phy/CMakeLists.txt b/test/phy/CMakeLists.txt index 5644bffb2..3edbc0afc 100644 --- a/test/phy/CMakeLists.txt +++ b/test/phy/CMakeLists.txt @@ -93,9 +93,10 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} ) + # Test PRACH transmission and detection add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_prach nr_phy_test --reference=carrier=${NR_PHY_TEST_BW} - --duration=1000 # 100 slots + --duration=1000 # 1000 slots --gnb.stack.pdsch.slots=none # No PDSCH --gnb.stack.pusch.slots=none # No PUSCH --gnb.phy.nof_threads=${NR_PHY_TEST_GNB_NOF_THREADS} @@ -103,5 +104,27 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) --ue.stack.prach.preamble=10 # Use preamble 10 --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} ) + + # Test scheduling request + add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_sr nr_phy_test + --reference=carrier=${NR_PHY_TEST_BW} + --duration=1000 # 1000 slots + --gnb.stack.pdsch.slots=none # No PDSCH + --gnb.stack.pusch.slots=none # No PUSCH + --gnb.phy.nof_threads=${NR_PHY_TEST_GNB_NOF_THREADS} + --ue.stack.sr.period=4 # Transmit SR every 4 opportunities + --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} + ) + + # Test scheduling request multiplexed with HARQ ACK feedback + add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_sr_harq nr_phy_test + --reference=carrier=${NR_PHY_TEST_BW} + --duration=1000 # 1000 slots + --gnb.stack.pdsch.slots=all # All PDSCH + --gnb.stack.pusch.slots=none # No PUSCH + --gnb.phy.nof_threads=${NR_PHY_TEST_GNB_NOF_THREADS} + --ue.stack.sr.period=4 # Transmit SR every 4 opportunities + --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} + ) endforeach () endif () diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index 618c85d6b..ce5b97f40 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -264,11 +264,14 @@ int main(int argc, char** argv) // Print SR if (metrics.ue_stack.sr_count > 0) { srsran::console("SR:\n"); - srsran::console(" +------------+------------+\n"); - srsran::console(" | %10s | %10s |\n", "Transmit'd", "Received"); - srsran::console(" +------------+------------+\n"); - srsran::console(" | %10d | %10d |\n", metrics.ue_stack.sr_count, metrics.gnb_stack.sr_count); - srsran::console(" +------------+------------+\n"); + srsran::console(" +------------+------------+------------+\n"); + srsran::console(" | %10s | %10s | %10s |\n", "Transmit'd", "Received", "Detection"); + srsran::console(" +------------+------------+------------+\n"); + srsran::console(" | %10d | %10d | %10.5f |\n", + metrics.ue_stack.sr_count, + metrics.gnb_stack.sr_count, + (double)metrics.gnb_stack.sr_count / (double)metrics.ue_stack.sr_count); + srsran::console(" +------------+------------+------------+\n"); } // Assert metrics From e2facef540107e0eac4ea789103650f775a6eae5 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 22 Sep 2021 11:31:54 +0200 Subject: [PATCH 05/83] Abort radio application if decimation/interpolation ratios are not integer --- lib/src/radio/radio.cc | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index 27366f482..9d83d86fd 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -14,6 +14,7 @@ #include "srsran/common/standard_streams.h" #include "srsran/common/string_helpers.h" #include "srsran/config.h" +#include "srsran/support/srsran_assert.h" #include #include #include @@ -702,6 +703,13 @@ void radio::set_rx_srate(const double& srate) } } + // Assert ratio is integer + srsran_assert(((uint32_t)cur_rx_srate % (uint32_t)srate) == 0, + "The sampling rate ratio is not integer (%.2f MHz / %.2 MHz = %.3f)", + cur_rx_srate / 1e6, + srate / 1e6, + cur_rx_srate / srate); + // Update decimators uint32_t ratio = (uint32_t)ceil(cur_rx_srate / srate); for (uint32_t ch = 0; ch < nof_channels; ch++) { @@ -948,6 +956,13 @@ void radio::set_tx_srate(const double& srate) } } + // Assert ratio is integer + srsran_assert(((uint32_t)cur_tx_srate % (uint32_t)srate) == 0, + "The sampling rate ratio is not integer (%.2f MHz / %.2 MHz = %.3f)", + cur_rx_srate / 1e6, + srate / 1e6, + cur_rx_srate / srate); + // Update interpolators uint32_t ratio = (uint32_t)ceil(cur_tx_srate / srate); for (uint32_t ch = 0; ch < nof_channels; ch++) { From 55f5f74ff39b8760db6d4de468be5e1c4d456fa8 Mon Sep 17 00:00:00 2001 From: faluco Date: Mon, 20 Sep 2021 12:41:59 +0200 Subject: [PATCH 06/83] Fixed case where calling gw::setup_if_addr after ue attachment would spawn a new thread without closing the current one. This would end up being a resource leak as the number of threads grow forever until the application crashes. --- srsue/hdr/stack/upper/gw.h | 23 +++++++++-------------- srsue/src/stack/upper/gw.cc | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/srsue/hdr/stack/upper/gw.h b/srsue/hdr/stack/upper/gw.h index 8ea0a345b..aec223558 100644 --- a/srsue/hdr/stack/upper/gw.h +++ b/srsue/hdr/stack/upper/gw.h @@ -54,14 +54,9 @@ public: void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu); // NAS interface - int setup_if_addr(uint32_t eps_bearer_id, - uint8_t pdn_type, - uint32_t ip_addr, - uint8_t* ipv6_if_addr, - char* err_str); + int setup_if_addr(uint32_t eps_bearer_id, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char* err_str); int deactivate_eps_bearer(const uint32_t eps_bearer_id); - int apply_traffic_flow_template(const uint8_t& eps_bearer_id, - const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft); + int apply_traffic_flow_template(const uint8_t& eps_bearer_id, const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft); void set_test_loop_mode(const test_loop_mode_state_t mode, const uint32_t ip_pdu_delay_ms); // RRC interface @@ -75,13 +70,13 @@ private: gw_args_t args = {}; - std::atomic running = {false}; - bool run_enable = false; - int32_t netns_fd = 0; - int32_t tun_fd = 0; - struct ifreq ifr = {}; - int32_t sock = 0; - bool if_up = false; + std::atomic running = {false}; + std::atomic run_enable = {false}; + int32_t netns_fd = 0; + int32_t tun_fd = 0; + struct ifreq ifr = {}; + int32_t sock = 0; + bool if_up = false; static const int NOT_ASSIGNED = -1; int32_t default_eps_bearer_id = NOT_ASSIGNED; diff --git a/srsue/src/stack/upper/gw.cc b/srsue/src/stack/upper/gw.cc index 76fc7d97c..57c400cff 100644 --- a/srsue/src/stack/upper/gw.cc +++ b/srsue/src/stack/upper/gw.cc @@ -179,6 +179,13 @@ void gw::write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) int gw::setup_if_addr(uint32_t eps_bearer_id, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char* err_str) { int err; + + // Make sure the worker thread is terminated before spawning a new one. + if (running) { + run_enable = false; + thread_cancel(); + wait_thread_finish(); + } if (pdn_type == LIBLTE_MME_PDN_TYPE_IPV4 || pdn_type == LIBLTE_MME_PDN_TYPE_IPV4V6) { err = setup_if_addr4(ip_addr, err_str); if (err != SRSRAN_SUCCESS) { @@ -195,6 +202,7 @@ int gw::setup_if_addr(uint32_t eps_bearer_id, uint8_t pdn_type, uint32_t ip_addr default_eps_bearer_id = static_cast(eps_bearer_id); // Setup a thread to receive packets from the TUN device + run_enable = true; start(GW_THREAD_PRIO); return SRSRAN_SUCCESS; @@ -446,6 +454,9 @@ int gw::setup_if_addr4(uint32_t ip_addr, char* err_str) } } + if (sock > 0) { + close(sock); + } // Setup the IP address sock = socket(AF_INET, SOCK_DGRAM, 0); ifr.ifr_addr.sa_family = AF_INET; @@ -495,6 +506,9 @@ int gw::setup_if_addr6(uint8_t* ipv6_if_id, char* err_str) } } + if (sock > 0) { + close(sock); + } // Setup the IP address sock = socket(AF_INET6, SOCK_DGRAM, 0); ifr.ifr_addr.sa_family = AF_INET6; From d0ce17f736cd05481eb17c1761369cd5defe3efb Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Tue, 21 Sep 2021 18:03:39 +0200 Subject: [PATCH 07/83] Added SSB different SCS combination unit test --- lib/src/phy/sync/test/CMakeLists.txt | 14 ++++++++++++-- lib/src/phy/sync/test/ssb_decode_test.c | 18 +++++++++++++++++- lib/src/phy/sync/test/ssb_measure_test.c | 18 +++++++++++++++++- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/lib/src/phy/sync/test/CMakeLists.txt b/lib/src/phy/sync/test/CMakeLists.txt index a7ac7b186..b0c63a635 100644 --- a/lib/src/phy/sync/test/CMakeLists.txt +++ b/lib/src/phy/sync/test/CMakeLists.txt @@ -129,11 +129,21 @@ add_test(cfo_test_2 cfo_test -f 0.99849 -n 1000) add_executable(ssb_measure_test ssb_measure_test.c) target_link_libraries(ssb_measure_test srsran_phy) -add_nr_test(ssb_measure_test ssb_measure_test) add_executable(ssb_decode_test ssb_decode_test.c) target_link_libraries(ssb_decode_test srsran_phy) -add_nr_test(ssb_decode_test ssb_decode_test) + +# For each supported SSB subcarrier spacing +foreach (SSB_SCS 15 30) + # For each supported Cell/Carrier subcarrier spacing + foreach (CELL_SCS 15 30) + # Test SSB measurements + add_nr_test(ssb_measure_test_${SSB_SCS}_${CELL_SCS} ssb_measure_test -s ${SSB_SCS} -S ${CELL_SCS}) + + # Test SSB PBCH decoding + add_nr_test(ssb_decode_test_${SSB_SCS}_${CELL_SCS} ssb_decode_test -s ${SSB_SCS} -S ${CELL_SCS}) + endforeach () +endforeach () add_executable(ssb_file_test ssb_file_test.c) target_link_libraries(ssb_file_test srsran_phy) diff --git a/lib/src/phy/sync/test/ssb_decode_test.c b/lib/src/phy/sync/test/ssb_decode_test.c index ac7510c93..91377ea88 100644 --- a/lib/src/phy/sync/test/ssb_decode_test.c +++ b/lib/src/phy/sync/test/ssb_decode_test.c @@ -41,14 +41,30 @@ static cf_t* buffer = NULL; // Base-band buffer static void usage(char* prog) { printf("Usage: %s [v]\n", prog); + printf("\t-s SSB subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(ssb_scs)); + printf("\t-S cell/carrier subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(carrier_scs)); printf("\t-v [set srsran_verbose to debug, default none]\n"); } static void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "v")) != -1) { + while ((opt = getopt(argc, argv, "Ssv")) != -1) { switch (opt) { + case 's': + ssb_scs = srsran_subcarrier_spacing_from_str(argv[optind]); + if (ssb_scs == srsran_subcarrier_spacing_invalid) { + ERROR("Invalid SSB subcarrier spacing %s\n", argv[optind]); + exit(-1); + } + break; + case 'S': + carrier_scs = srsran_subcarrier_spacing_from_str(argv[optind]); + if (carrier_scs == srsran_subcarrier_spacing_invalid) { + ERROR("Invalid Cell/Carrier subcarrier spacing %s\n", argv[optind]); + exit(-1); + } + break; case 'v': srsran_verbose++; break; diff --git a/lib/src/phy/sync/test/ssb_measure_test.c b/lib/src/phy/sync/test/ssb_measure_test.c index d4e5b39c0..830d0a5e9 100644 --- a/lib/src/phy/sync/test/ssb_measure_test.c +++ b/lib/src/phy/sync/test/ssb_measure_test.c @@ -45,14 +45,30 @@ static cf_t* buffer = NULL; // Base-band buffer static void usage(char* prog) { printf("Usage: %s [v]\n", prog); + printf("\t-s SSB subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(ssb_scs)); + printf("\t-S cell/carrier subcarrier spacing [default, %s kHz]\n", srsran_subcarrier_spacing_to_str(carrier_scs)); printf("\t-v [set srsran_verbose to debug, default none]\n"); } static void parse_args(int argc, char** argv) { int opt; - while ((opt = getopt(argc, argv, "v")) != -1) { + while ((opt = getopt(argc, argv, "Ssv")) != -1) { switch (opt) { + case 's': + ssb_scs = srsran_subcarrier_spacing_from_str(argv[optind]); + if (ssb_scs == srsran_subcarrier_spacing_invalid) { + ERROR("Invalid SSB subcarrier spacing %s\n", argv[optind]); + exit(-1); + } + break; + case 'S': + carrier_scs = srsran_subcarrier_spacing_from_str(argv[optind]); + if (carrier_scs == srsran_subcarrier_spacing_invalid) { + ERROR("Invalid Cell/Carrier subcarrier spacing %s\n", argv[optind]); + exit(-1); + } + break; case 'v': srsran_verbose++; break; From 107eba9d6665548a9faef3b386e7a9eccaeaf68a Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Wed, 8 Sep 2021 12:58:52 +0200 Subject: [PATCH 08/83] Fixed srsue namespace --- srsue/src/stack/rrc/test/rrc_meas_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsue/src/stack/rrc/test/rrc_meas_test.cc b/srsue/src/stack/rrc/test/rrc_meas_test.cc index 8785d88b2..e84022896 100644 --- a/srsue/src/stack/rrc/test/rrc_meas_test.cc +++ b/srsue/src/stack/rrc/test/rrc_meas_test.cc @@ -244,7 +244,7 @@ private: bool meas_res_received = false; }; -class rrc_test : public rrc +class rrc_test : public srsue::rrc { stack_test_dummy* stack = nullptr; From bbe54fb24856b285dbdd7acffd368a833cf1480a Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Wed, 8 Sep 2021 15:09:23 +0200 Subject: [PATCH 09/83] Fix uninitialized issue in NAS 5G pack/unpacking --- lib/include/srsran/asn1/nas_5g_ies.h | 108 +++++++++++++++------------ 1 file changed, 59 insertions(+), 49 deletions(-) diff --git a/lib/include/srsran/asn1/nas_5g_ies.h b/lib/include/srsran/asn1/nas_5g_ies.h index 1467de9f4..6efdfc1f2 100644 --- a/lib/include/srsran/asn1/nas_5g_ies.h +++ b/lib/include/srsran/asn1/nas_5g_ies.h @@ -55,8 +55,8 @@ public: }; typedef nas_enumerated follow_on_request_bit_type; - follow_on_request_bit_type follow_on_request_bit; - registration_type_type registration_type; + follow_on_request_bit_type follow_on_request_bit = follow_on_request_bit_type_::options::no_follow_on_request_pending; + registration_type_type registration_type = registration_type_type_::options::initial_registration; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -87,8 +87,9 @@ public: }; typedef nas_enumerated nas_key_set_identifier_type; - security_context_flag_type security_context_flag; - nas_key_set_identifier_type nas_key_set_identifier; + security_context_flag_type security_context_flag = security_context_flag_type_::options::native_security_context; + nas_key_set_identifier_type nas_key_set_identifier = + nas_key_set_identifier_type_::options::no_key_is_available_or_reserved; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -274,42 +275,42 @@ public: guti_5g_s& set_guti_5g() { - set(identity_types::guti_5g); + set(identity_types::guti_5g); choice_container = srslog::detail::any{guti_5g_s()}; return *srslog::detail::any_cast(&choice_container); } imei_s& set_imei() { - set(identity_types::imei); + set(identity_types::imei); choice_container = srslog::detail::any{imei_s()}; return *srslog::detail::any_cast(&choice_container); } s_tmsi_5g_s& set_s_tmsi_5g() { - set(identity_types::s_tmsi_5g); + set(identity_types::s_tmsi_5g); choice_container = srslog::detail::any{s_tmsi_5g_s()}; return *srslog::detail::any_cast(&choice_container); } imeisv_s& set_imeisv() { - set(identity_types::imeisv); + set(identity_types::imeisv); choice_container = srslog::detail::any{imeisv_s()}; return *srslog::detail::any_cast(&choice_container); } mac_address_s& set_mac_address() { - set(identity_types::mac_address); + set(identity_types::mac_address); choice_container = srslog::detail::any{mac_address_s()}; return *srslog::detail::any_cast(&choice_container); } eui_64_s& set_eui_64() { - set(identity_types::eui_64); + set(identity_types::eui_64); choice_container = srslog::detail::any{eui_64_s()}; return *srslog::detail::any_cast(&choice_container); } @@ -318,7 +319,7 @@ public: SRSASN_CODE unpack(asn1::cbit_ref& bref); private: - identity_types type_; + identity_types type_ = identity_types_::options::no_identity; srslog::detail::any choice_container; }; // mobile_identity_5gs_t @@ -429,6 +430,8 @@ public: }; // s_nssai_t + + // IE: NSSAI // Reference: 9.11.3.37 class nssai_t @@ -649,7 +652,7 @@ public: }; typedef nas_enumerated UE_usage_setting_type; - UE_usage_setting_type ue_usage_setting; + UE_usage_setting_type ue_usage_setting = UE_usage_setting_type_::options::voice_centric; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -674,7 +677,7 @@ public: }; typedef nas_enumerated drx_value_type; - drx_value_type drx_value; + drx_value_type drx_value = drx_value_type_::options::drx_value_not_specified; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -740,7 +743,7 @@ public: }; typedef nas_enumerated Payload_container_type_type; - Payload_container_type_type payload_container_type; + Payload_container_type_type payload_container_type = Payload_container_type_type_::options::n1_sm_information; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -821,10 +824,10 @@ public: }; typedef nas_enumerated PNB_EPS_CIoT_type; - PNB_EPS_CIoT_type pnb_eps_c_io_t; - PNB_5GS_CIoT_type pnb_5gs_c_io_t; - NG_RAN_RCU_type ng_ran_rcu; - SMS_requested_type sms_requested; + PNB_EPS_CIoT_type pnb_eps_c_io_t = PNB_EPS_CIoT_type_::options::no_additional_information; + PNB_5GS_CIoT_type pnb_5gs_c_io_t = PNB_5GS_CIoT_type_::options::no_additional_information; + NG_RAN_RCU_type ng_ran_rcu = NG_RAN_RCU_type_::options::ue_radio_capability_update_not_needed; + SMS_requested_type sms_requested = SMS_requested_type_::options::sms_over_nas_not_supported; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1056,7 +1059,7 @@ public: }; typedef nas_enumerated nb_n1_mode_drx_value_type; - nb_n1_mode_drx_value_type nb_n1_mode_drx_value; + nb_n1_mode_drx_value_type nb_n1_mode_drx_value = nb_n1_mode_drx_value_type_::options::drx_value_not_specified; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1110,10 +1113,11 @@ public: }; typedef nas_enumerated registration_result_type; - Emergency_registered_type emergency_registered; - NSSAA_to_be_performed_type nssaa_to_be_performed; - SMS_allowed_type sms_allowed; - registration_result_type registration_result; + Emergency_registered_type emergency_registered = + Emergency_registered_type_::options::not_registered_for_emergency_services; + NSSAA_to_be_performed_type nssaa_to_be_performed = NSSAA_to_be_performed_type_::options::nssaa_is_to_be_performed; + SMS_allowed_type sms_allowed = SMS_allowed_type_::options::sms_over_nas_not_allowed; + registration_result_type registration_result = registration_result_type_::options::access_3_gpp; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1300,7 +1304,7 @@ public: }; typedef nas_enumerated NSSAI_inclusion_mode_type; - NSSAI_inclusion_mode_type nssai_inclusion_mode; + NSSAI_inclusion_mode_type nssai_inclusion_mode = NSSAI_inclusion_mode_type_::options::nssai_inclusion_mode_a; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1344,7 +1348,8 @@ public: }; typedef nas_enumerated Deletion_request_type; - Deletion_request_type deletion_request; + Deletion_request_type deletion_request = + Deletion_request_type_::options::ue_radio_capability_id_deletion_not_requested; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1439,7 +1444,7 @@ public: }; typedef nas_enumerated cause_5gmm_type; - cause_5gmm_type cause_5gmm; + cause_5gmm_type cause_5gmm = cause_5gmm_type_::options::illegal_ue; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1482,9 +1487,10 @@ public: }; typedef nas_enumerated access_type_type; - switch_off_type switch_off; - re_registration_required_type re_registration_required; - access_type_type access_type; + switch_off_type switch_off = switch_off_type_::options::normal_de_registration; + re_registration_required_type re_registration_required = + re_registration_required_type_::options::re_registration_not_required; + access_type_type access_type = access_type_type_::options::access_3_gpp; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1526,7 +1532,7 @@ public: }; typedef nas_enumerated Service_type_value_type; - Service_type_value_type service_type_value; + Service_type_value_type service_type_value = Service_type_value_type_::options::signalling; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1550,7 +1556,8 @@ public: }; typedef nas_enumerated control_plane_service_type_value_type; - control_plane_service_type_value_type control_plane_service_type_value; + control_plane_service_type_value_type control_plane_service_type_value = + control_plane_service_type_value_type_::options::mobile_originating_request; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1613,7 +1620,7 @@ public: }; typedef nas_enumerated value_type; - value_type value; + value_type value = value_type_::options::no_adjustment_for_daylight_saving_time; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1647,7 +1654,7 @@ public: }; typedef nas_enumerated SCMR_type; - SCMR_type scmr; + SCMR_type scmr = SCMR_type_::options::no_additional_information; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1734,7 +1741,7 @@ public: }; typedef nas_enumerated identity_types; - identity_types type_of_identity; + identity_types type_of_identity = identity_types_::options::suci; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1930,7 +1937,7 @@ public: }; typedef nas_enumerated Access_type_value_type; - Access_type_value_type access_type_value; + Access_type_value_type access_type_value = Access_type_value_type_::options::access_3_gpp; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1969,7 +1976,7 @@ public: }; typedef nas_enumerated Request_type_value_type; - Request_type_value_type request_type_value; + Request_type_value_type request_type_value = request_type_t::Request_type_value_type_::options::initial_request; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2002,7 +2009,8 @@ public: }; typedef nas_enumerated MA_PDU_session_information_value_type; - MA_PDU_session_information_value_type ma_pdu_session_information_value; + MA_PDU_session_information_value_type ma_pdu_session_information_value = + MA_PDU_session_information_value_type_::options::ma_pdu_session_network_upgrade_is_allowed; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2026,7 +2034,8 @@ public: }; typedef nas_enumerated Downlink_data_expected_type; - Downlink_data_expected_type downlink_data_expected; + Downlink_data_expected_type downlink_data_expected = + Downlink_data_expected_type_::options::no_information_regarding_ddx_is_conveyed; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2060,8 +2069,8 @@ public: }; typedef nas_enumerated max_data_rate_UPIP_downlink_type; - max_data_rate_UPIP_uplink_type max_data_rate_upip_uplink; - max_data_rate_UPIP_downlink_type max_data_rate_upip_downlink; + max_data_rate_UPIP_uplink_type max_data_rate_upip_uplink = max_data_rate_UPIP_uplink_type_::options::kbps_64; + max_data_rate_UPIP_downlink_type max_data_rate_upip_downlink = max_data_rate_UPIP_downlink_type_::options::kbps_64; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2087,7 +2096,7 @@ public: }; typedef nas_enumerated PDU_session_type_value_type; - PDU_session_type_value_type pdu_session_type_value; + PDU_session_type_value_type pdu_session_type_value = PDU_session_type_value_type_::options::ipv4; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2114,7 +2123,7 @@ public: }; typedef nas_enumerated SSC_mode_value_type; - SSC_mode_value_type ssc_mode_value; + SSC_mode_value_type ssc_mode_value = ssc_mode_t::SSC_mode_value_type_::options::ssc_mode_1; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2239,7 +2248,7 @@ public: }; typedef nas_enumerated CID_Length_type; - CID_Length_type cid__length; + CID_Length_type cid__length = CID_Length_type_::options::ethernet_header_compression_not_used; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2263,7 +2272,7 @@ public: typedef nas_enumerated PDU_session_type_value_type; bool si6_lla; - PDU_session_type_value_type pdu_session_type_value; + PDU_session_type_value_type pdu_session_type_value = PDU_session_type_value_type_::options::ipv4; std::array ipv4; std::array ipv6; std::array smf_i_pv6_link_local_address; @@ -2325,9 +2334,9 @@ public: }; typedef nas_enumerated unit_session_AMBR_type; - unit_session_AMBR_type unit_session_ambr_for_downlink; + unit_session_AMBR_type unit_session_ambr_for_downlink = unit_session_AMBR_type_::options::not_used; uint16_t session_ambr_for_downlink; - unit_session_AMBR_type unit_session_ambr_for_uplink; + unit_session_AMBR_type unit_session_ambr_for_uplink = unit_session_AMBR_type_::options::not_used; uint16_t session_ambr_for_uplink; SRSASN_CODE pack(asn1::bit_ref& bref); @@ -2391,7 +2400,7 @@ public: }; typedef nas_enumerated cause_value_type; - cause_value_type cause_value; + cause_value_type cause_value = cause_value_type_::options::operator_determined_barring; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2470,7 +2479,7 @@ public: }; typedef nas_enumerated EPT_S1_type; - EPT_S1_type ept_s1; + EPT_S1_type ept_s1 = EPT_S1_type_::options::ethernet_pdn_type_in_s1_mode_not_supported; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2542,7 +2551,8 @@ public: }; typedef nas_enumerated abo_type; - abo_type abo; + abo_type abo = + congestion_re_attempt_indicator_5gsm_t::abo_type_::options::the_back_off_timer_is_applied_in_the_registered_plmn; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); From c670383ae96ce8d265e553b89f6018807e705e0f Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Wed, 8 Sep 2021 12:02:07 +0200 Subject: [PATCH 10/83] Added NAS 5G functions incoming msg and reg proc --- lib/include/srsran/asn1/nas_5g_ies.h | 518 ++++++++--------- lib/include/srsran/asn1/nas_5g_msg.h | 2 +- .../srsran/interfaces/rrc_interface_types.h | 43 ++ .../srsran/interfaces/ue_nas_interfaces.h | 1 + .../srsran/interfaces/ue_rrc_interfaces.h | 6 + srsue/hdr/stack/upper/nas_5g.h | 42 +- srsue/hdr/stack/upper/nas_5g_procedures.h | 1 + srsue/hdr/stack/upper/nas_5gmm_state.h | 3 +- srsue/hdr/stack/upper/nas_base.h | 14 +- srsue/hdr/stack/upper/test/nas_test_common.h | 14 +- srsue/src/stack/upper/nas_5g.cc | 530 +++++++++++++++++- srsue/src/stack/upper/nas_5g_procedures.cc | 1 + 12 files changed, 900 insertions(+), 275 deletions(-) diff --git a/lib/include/srsran/asn1/nas_5g_ies.h b/lib/include/srsran/asn1/nas_5g_ies.h index 6efdfc1f2..95e40ae1d 100644 --- a/lib/include/srsran/asn1/nas_5g_ies.h +++ b/lib/include/srsran/asn1/nas_5g_ies.h @@ -329,26 +329,26 @@ private: class capability_5gmm_t { public: - bool sgc; - bool iphc_cp_c_io_t_5g; - bool n3_data; - bool cp_c_io_t_5g; - bool restrict_ec; - bool lpp; - bool ho_attach; - bool s1_mode; - bool racs; - bool nssaa; - bool lcs_5g; - bool v2_xcnpc5; - bool v2_xcepc5; - bool v2_x; - bool up_c_io_t_5g; - bool srvcc_5g; - bool ehc_cp_c_io_t_5g; - bool multiple_up; - bool wusa; - bool cag; + bool sgc = false; + bool iphc_cp_c_io_t_5g = false; + bool n3_data = false; + bool cp_c_io_t_5g = false; + bool restrict_ec = false; + bool lpp = false; + bool ho_attach = false; + bool s1_mode = false; + bool racs = false; + bool nssaa = false; + bool lcs_5g = false; + bool v2_xcnpc5 = false; + bool v2_xcepc5 = false; + bool v2_x = false; + bool up_c_io_t_5g = false; + bool srvcc_5g = false; + bool ehc_cp_c_io_t_5g = false; + bool multiple_up = false; + bool wusa = false; + bool cag = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -360,39 +360,39 @@ public: class ue_security_capability_t { public: - bool ea0_5g_supported; - bool ea1_128_5g_supported; - bool ea2_128_5g_supported; - bool ea3_128_5g_supported; - bool ea4_5g_supported; - bool ea5_5g_supported; - bool ea6_5g_supported; - bool ea7_5g_supported; - bool ia0_5g_supported; - bool ia1_128_5g_supported; - bool ia2_128_5g_supported; - bool ia3_128_5g_supported; - bool ia4_5g_supported; - bool ia5_5g_supported; - bool ia6_5g_supported; - bool ia7_5g_supported; - bool eps_caps_present; - bool eea0_supported; - bool eea1_128_supported; - bool eea2_128_supported; - bool eea3_128_supported; - bool eea4_supported; - bool eea5_supported; - bool eea6_supported; - bool eea7_supported; - bool eia0_supported; - bool eia1_128_supported; - bool eia2_128_supported; - bool eia3_128_supported; - bool eia4_supported; - bool eia5_supported; - bool eia6_supported; - bool eia7_supported; + bool ea0_5g_supported = false; + bool ea1_128_5g_supported = false; + bool ea2_128_5g_supported = false; + bool ea3_128_5g_supported = false; + bool ea4_5g_supported = false; + bool ea5_5g_supported = false; + bool ea6_5g_supported = false; + bool ea7_5g_supported = false; + bool ia0_5g_supported = false; + bool ia1_128_5g_supported = false; + bool ia2_128_5g_supported = false; + bool ia3_128_5g_supported = false; + bool ia4_5g_supported = false; + bool ia5_5g_supported = false; + bool ia6_5g_supported = false; + bool ia7_5g_supported = false; + bool eps_caps_present = false; + bool eea0_supported = false; + bool eea1_128_supported = false; + bool eea2_128_supported = false; + bool eea3_128_supported = false; + bool eea4_supported = false; + bool eea5_supported = false; + bool eea6_supported = false; + bool eea7_supported = false; + bool eia0_supported = false; + bool eia1_128_supported = false; + bool eia2_128_supported = false; + bool eia3_128_supported = false; + bool eia4_supported = false; + bool eia5_supported = false; + bool eia6_supported = false; + bool eia7_supported = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -463,67 +463,67 @@ public: class s1_ue_network_capability_t { public: - bool eea0_supported; - bool eea1_128_supported; - bool eea2_128_supported; - bool eea3_128_supported; - bool eea4_supported; - bool eea5_supported; - bool eea6_supported; - bool eea7_supported; - bool eia0_supported; - bool eia1_128_supported; - bool eia2_128_supported; - bool eia3_128_supported; - bool eia4_supported; - bool eia5_supported; - bool eia6_supported; - bool eia7_supported; - bool uea0_supported; - bool uea1_128_supported; - bool uea2_128_supported; - bool uea3_128_supported; - bool uea4_supported; - bool uea5_supported; - bool uea6_supported; - bool uea7_supported; - bool ucs2_support; - bool uia1_128_supported; - bool uia2_128_supported; - bool uia3_128_supported; - bool uia4_supported; - bool uia5_supported; - bool uia6_supported; - bool uia7_supported; - bool pro_se_dd_supported; - bool pro_se_supported; - bool h245_ash_supported; - bool acc_csfb_supported; - bool llp_supported; - bool lcs_supported; - bool srvcc_capability_supported; - bool nf_capability_supported; - bool e_pco_supported; - bool hc_cp_c_io_t_supported; - bool e_rw_o_pdn_supported; - bool s1_u_data_supported; - bool up_c_io_t_supported; - bool cp_c_io_t_supported; - bool pro_se_relay_supported; - bool pro_se_dc_supported; - bool max_15_eps_bearer_supported; - bool sgc_supported; - bool n1mode_supported; - bool dcnr_supported; - bool cp_backoff_supported; - bool restrict_ec_supported; - bool v2_x_pc5_supported; - bool multiple_drb_supported; - bool nr_pc5_supported; - bool up_mt_edt_supported; - bool cp_mt_edt_supported; - bool wus_supported; - bool racs_supported; + bool eea0_supported = false; + bool eea1_128_supported = false; + bool eea2_128_supported = false; + bool eea3_128_supported = false; + bool eea4_supported = false; + bool eea5_supported = false; + bool eea6_supported = false; + bool eea7_supported = false; + bool eia0_supported = false; + bool eia1_128_supported = false; + bool eia2_128_supported = false; + bool eia3_128_supported = false; + bool eia4_supported = false; + bool eia5_supported = false; + bool eia6_supported = false; + bool eia7_supported = false; + bool uea0_supported = false; + bool uea1_128_supported = false; + bool uea2_128_supported = false; + bool uea3_128_supported = false; + bool uea4_supported = false; + bool uea5_supported = false; + bool uea6_supported = false; + bool uea7_supported = false; + bool ucs2_support = false; + bool uia1_128_supported = false; + bool uia2_128_supported = false; + bool uia3_128_supported = false; + bool uia4_supported = false; + bool uia5_supported = false; + bool uia6_supported = false; + bool uia7_supported = false; + bool pro_se_dd_supported = false; + bool pro_se_supported = false; + bool h245_ash_supported = false; + bool acc_csfb_supported = false; + bool llp_supported = false; + bool lcs_supported = false; + bool srvcc_capability_supported = false; + bool nf_capability_supported = false; + bool e_pco_supported = false; + bool hc_cp_c_io_t_supported = false; + bool e_rw_o_pdn_supported = false; + bool s1_u_data_supported = false; + bool up_c_io_t_supported = false; + bool cp_c_io_t_supported = false; + bool pro_se_relay_supported = false; + bool pro_se_dc_supported = false; + bool max_15_eps_bearer_supported = false; + bool sgc_supported = false; + bool n1mode_supported = false; + bool dcnr_supported = false; + bool cp_backoff_supported = false; + bool restrict_ec_supported = false; + bool v2_x_pc5_supported = false; + bool multiple_drb_supported = false; + bool nr_pc5_supported = false; + bool up_mt_edt_supported = false; + bool cp_mt_edt_supported = false; + bool wus_supported = false; + bool racs_supported = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -535,22 +535,22 @@ public: class uplink_data_status_t { public: - bool psi_7; - bool psi_6; - bool psi_5; - bool psi_4; - bool psi_3; - bool psi_2; - bool psi_1; - bool psi_0; - bool psi_15; - bool psi_14; - bool psi_13; - bool psi_12; - bool psi_11; - bool psi_10; - bool psi_9; - bool psi_8; + bool psi_7 = false; + bool psi_6 = false; + bool psi_5 = false; + bool psi_4 = false; + bool psi_3 = false; + bool psi_2 = false; + bool psi_1 = false; + bool psi_0 = false; + bool psi_15 = false; + bool psi_14 = false; + bool psi_13 = false; + bool psi_12 = false; + bool psi_11 = false; + bool psi_10 = false; + bool psi_9 = false; + bool psi_8 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -562,22 +562,22 @@ public: class pdu_session_status_t { public: - bool psi_7; - bool psi_6; - bool psi_5; - bool psi_4; - bool psi_3; - bool psi_2; - bool psi_1; - bool psi_0; - bool psi_15; - bool psi_14; - bool psi_13; - bool psi_12; - bool psi_11; - bool psi_10; - bool psi_9; - bool psi_8; + bool psi_7 = false; + bool psi_6 = false; + bool psi_5 = false; + bool psi_4 = false; + bool psi_3 = false; + bool psi_2 = false; + bool psi_1 = false; + bool psi_0 = false; + bool psi_15 = false; + bool psi_14 = false; + bool psi_13 = false; + bool psi_12 = false; + bool psi_11 = false; + bool psi_10 = false; + bool psi_9 = false; + bool psi_8 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -589,8 +589,8 @@ public: class mico_indication_t { public: - bool sprti; - bool aai; + bool sprti = false; + bool aai = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -602,8 +602,8 @@ public: class ue_status_t { public: - bool n1_mode_reg; - bool s1_mode_reg; + bool n1_mode_reg = false; + bool s1_mode_reg = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -615,22 +615,22 @@ public: class allowed_pdu_session_status_t { public: - bool psi_7; - bool psi_6; - bool psi_5; - bool psi_4; - bool psi_3; - bool psi_2; - bool psi_1; - bool psi_0; - bool psi_15; - bool psi_14; - bool psi_13; - bool psi_12; - bool psi_11; - bool psi_10; - bool psi_9; - bool psi_8; + bool psi_7 = false; + bool psi_6 = false; + bool psi_5 = false; + bool psi_4 = false; + bool psi_3 = false; + bool psi_2 = false; + bool psi_1 = false; + bool psi_0 = false; + bool psi_15 = false; + bool psi_14 = false; + bool psi_13 = false; + bool psi_12 = false; + bool psi_11 = false; + bool psi_10 = false; + bool psi_9 = false; + bool psi_8 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -767,8 +767,8 @@ public: class network_slicing_indication_t { public: - bool nssci; - bool dcni; + bool nssci = false; + bool dcni = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -871,22 +871,22 @@ public: class eps_bearer_context_status_t { public: - bool ebi_7; - bool ebi_6; - bool ebi_5; - bool ebi_4; - bool ebi_3; - bool ebi_2; - bool ebi_1; - bool ebi_0; - bool ebi_15; - bool ebi_14; - bool ebi_13; - bool ebi_12; - bool ebi_11; - bool ebi_10; - bool ebi_9; - bool ebi_8; + bool ebi_7 = false; + bool ebi_6 = false; + bool ebi_5 = false; + bool ebi_4 = false; + bool ebi_3 = false; + bool ebi_2 = false; + bool ebi_1 = false; + bool ebi_0 = false; + bool ebi_15 = false; + bool ebi_14 = false; + bool ebi_13 = false; + bool ebi_12 = false; + bool ebi_11 = false; + bool ebi_10 = false; + bool ebi_9 = false; + bool ebi_8 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1010,7 +1010,7 @@ public: class additional_information_requested_t { public: - bool cipher_key; + bool cipher_key = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1032,7 +1032,7 @@ public: class n5gc_indication_t { public: - bool n5gcreg; + bool n5gcreg = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1181,22 +1181,22 @@ public: class pdu_session_reactivation_result_t { public: - bool psi_7; - bool psi_6; - bool psi_5; - bool psi_4; - bool psi_3; - bool psi_2; - bool psi_1; - bool psi_0; - bool psi_15; - bool psi_14; - bool psi_13; - bool psi_12; - bool psi_11; - bool psi_10; - bool psi_9; - bool psi_8; + bool psi_7 = false; + bool psi_6 = false; + bool psi_5 = false; + bool psi_4 = false; + bool psi_3 = false; + bool psi_2 = false; + bool psi_1 = false; + bool psi_0 = false; + bool psi_15 = false; + bool psi_14 = false; + bool psi_13 = false; + bool psi_12 = false; + bool psi_11 = false; + bool psi_10 = false; + bool psi_9 = false; + bool psi_8 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1326,7 +1326,7 @@ public: class non_3_gpp_nw_provided_policies_t { public: - bool n3_en; + bool n3_en = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1632,7 +1632,7 @@ public: class sms_indication_t { public: - bool sms_availability_indication; + bool sms_availability_indication = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1785,8 +1785,9 @@ public: }; typedef nas_enumerated ciphering_algorithm_type; - ciphering_algorithm_type ciphering_algorithm; - integrity_protection_algorithm_type integrity_protection_algorithm; + ciphering_algorithm_type ciphering_algorithm = ciphering_algorithm_type_::options::ea0_5g; + integrity_protection_algorithm_type integrity_protection_algorithm = + integrity_protection_algorithm_type_::options::ia0_5g; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1808,7 +1809,7 @@ public: }; typedef nas_enumerated imeisv_request_type; - imeisv_request_type imeisv_request; + imeisv_request_type imeisv_request = imeisv_request_type_::options::imeisv_not_requested; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1852,8 +1853,9 @@ public: }; typedef nas_enumerated ciphering_algorithm_type; - ciphering_algorithm_type ciphering_algorithm; - integrity_protection_algorithm_type integrity_protection_algorithm; + ciphering_algorithm_type ciphering_algorithm = ciphering_algorithm_type_::options::eea0; + integrity_protection_algorithm_type integrity_protection_algorithm = + integrity_protection_algorithm_type_::options::eia0; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1865,8 +1867,8 @@ public: class additional_5g_security_information_t { public: - bool rinmr; - bool hdp; + bool rinmr = false; + bool hdp = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -1878,44 +1880,44 @@ public: class s1_ue_security_capability_t { public: - bool eea0; - bool eea1_128; - bool eea2_128; - bool eea3_128; - bool eea4; - bool eea5; - bool eea6; - bool eea7; - bool eia0; - bool eia1_128; - bool eia2_128; - bool eia3_128; - bool eia4; - bool eia5; - bool eia6; - bool eia7; - bool uea0; - bool uea1; - bool uea2; - bool uea3; - bool uea4; - bool uea5; - bool uea6; - bool uea7; - bool uia1; - bool uia2; - bool uia3; - bool uia4; - bool uia5; - bool uia6; - bool uia7; - bool gea1; - bool gea2; - bool gea3; - bool gea4; - bool gea5; - bool gea6; - bool gea7; + bool eea0 = false; + bool eea1_128 = false; + bool eea2_128 = false; + bool eea3_128 = false; + bool eea4 = false; + bool eea5 = false; + bool eea6 = false; + bool eea7 = false; + bool eia0 = false; + bool eia1_128 = false; + bool eia2_128 = false; + bool eia3_128 = false; + bool eia4 = false; + bool eia5 = false; + bool eia6 = false; + bool eia7 = false; + bool uea0 = false; + bool uea1 = false; + bool uea2 = false; + bool uea3 = false; + bool uea4 = false; + bool uea5 = false; + bool uea6 = false; + bool uea7 = false; + bool uia1 = false; + bool uia2 = false; + bool uia3 = false; + bool uia4 = false; + bool uia5 = false; + bool uia6 = false; + bool uia7 = false; + bool gea1 = false; + bool gea2 = false; + bool gea3 = false; + bool gea4 = false; + bool gea5 = false; + bool gea6 = false; + bool gea7 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2157,7 +2159,7 @@ public: class always_on_pdu_session_requested_t { public: - bool apsi; + bool apsi = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2271,7 +2273,7 @@ public: }; typedef nas_enumerated PDU_session_type_value_type; - bool si6_lla; + bool si6_lla = false; PDU_session_type_value_type pdu_session_type_value = PDU_session_type_value_type_::options::ipv4; std::array ipv4; std::array ipv6; @@ -2437,7 +2439,7 @@ public: class always_on_pdu_session_indication_t { public: - bool apsr; + bool apsr = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2515,7 +2517,7 @@ public: class control_plane_only_indication_t { public: - bool cpoi; + bool cpoi = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2527,9 +2529,9 @@ public: class allowed_ssc_mode_t { public: - bool ssc3; - bool ssc2; - bool ssc1; + bool ssc3 = false; + bool ssc2 = false; + bool ssc1 = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); @@ -2564,8 +2566,8 @@ public: class re_attempt_indicator_t { public: - bool eplmnc; - bool ratc; + bool eplmnc = false; + bool ratc = false; SRSASN_CODE pack(asn1::bit_ref& bref); SRSASN_CODE unpack(asn1::cbit_ref& bref); diff --git a/lib/include/srsran/asn1/nas_5g_msg.h b/lib/include/srsran/asn1/nas_5g_msg.h index 53d6b37b1..a53f697bd 100644 --- a/lib/include/srsran/asn1/nas_5g_msg.h +++ b/lib/include/srsran/asn1/nas_5g_msg.h @@ -2471,7 +2471,7 @@ public: private: SRSASN_CODE unpack(asn1::cbit_ref& bref); SRSASN_CODE pack(asn1::bit_ref& bref); - srslog::detail::any msg_container; + srslog::detail::any msg_container = srslog::detail::any{registration_request_t()}; }; } // namespace nas_5g } // namespace srsran diff --git a/lib/include/srsran/interfaces/rrc_interface_types.h b/lib/include/srsran/interfaces/rrc_interface_types.h index 269e476ff..9a403691b 100644 --- a/lib/include/srsran/interfaces/rrc_interface_types.h +++ b/lib/include/srsran/interfaces/rrc_interface_types.h @@ -185,6 +185,49 @@ inline std::string to_string(const scg_failure_cause_t& cause) "nulltype"}; return enum_to_text(options, (uint32_t)scg_failure_cause_t::nulltype, (uint32_t)cause); } + +enum class nr_establishment_cause_t { + emergency, + highPriorityAccess, + mt_Access, + mo_Signalling, + mo_Data, + mo_VoiceCall, + mo_VideoCall, + mo_SMS, + mps_PriorityAccess, + mcs_PriorityAccess, + spare6, + spare5, + spare4, + spare3, + spare2, + spare1, + nulltype +}; +inline std::string to_string(const nr_establishment_cause_t& cause) +{ + constexpr static const char* options[] = { + "emergency", + "highPriorityAccess", + "mt_Access", + "mo_Signalling", + "mo_Data", + "mo_VoiceCall", + "mo_VideoCall", + "mo_SMS", + "mps_PriorityAccess", + "mcs_PriorityAccess", + "spare6", + "spare5", + "spare4", + "spare3", + "spare2", + "spare1", + }; + return enum_to_text(options, (uint32_t)nr_establishment_cause_t::nulltype, (uint32_t)cause); +} + /*************************** * PHY Config **************************/ diff --git a/lib/include/srsran/interfaces/ue_nas_interfaces.h b/lib/include/srsran/interfaces/ue_nas_interfaces.h index e9fe56f43..4bbe3dfba 100644 --- a/lib/include/srsran/interfaces/ue_nas_interfaces.h +++ b/lib/include/srsran/interfaces/ue_nas_interfaces.h @@ -42,6 +42,7 @@ public: class nas_5g_interface_rrc_nr { public: + virtual int write_pdu(srsran::unique_byte_buffer_t pdu) = 0; }; class nas_5g_interface_procedures diff --git a/lib/include/srsran/interfaces/ue_rrc_interfaces.h b/lib/include/srsran/interfaces/ue_rrc_interfaces.h index ca1ded8a8..f3796fa35 100644 --- a/lib/include/srsran/interfaces/ue_rrc_interfaces.h +++ b/lib/include/srsran/interfaces/ue_rrc_interfaces.h @@ -116,6 +116,12 @@ public: class rrc_nr_interface_nas_5g { public: + virtual ~rrc_nr_interface_nas_5g() = default; + virtual int write_sdu(srsran::unique_byte_buffer_t sdu) = 0; + virtual bool is_connected() = 0; + virtual int connection_request(srsran::nr_establishment_cause_t cause, srsran::unique_byte_buffer_t sdu) = 0; + virtual uint16_t get_mcc() = 0; + virtual uint16_t get_mnc() = 0; }; } // namespace srsue diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 0695aaf17..2124f5aea 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -14,6 +14,8 @@ #define SRSUE_NAS_5G_H #include "nas_base.h" +#include "srsran/asn1/nas_5g_ies.h" +#include "srsran/asn1/nas_5g_msg.h" #include "srsran/common/buffer_pool.h" #include "srsran/common/common.h" #include "srsran/common/nas_pcap.h" @@ -51,6 +53,8 @@ public: // Stack+RRC interface bool is_registered(); + int write_pdu(srsran::unique_byte_buffer_t pdu); + // timer callback void timer_expired(uint32_t timeout_id); @@ -68,13 +72,23 @@ private: bool running = false; + bool initial_sec_command = false; + srsran::nas_5g::mobile_identity_5gs_t::guti_5g_s guti_5g; + + srsran::nas_5g::nas_5gs_msg initial_registration_request_stored; + nas_args_t cfg = {}; - mm5g_state_t state = {}; + mm5g_state_t state; // Security bool ia5g_caps[8] = {}; bool ea5g_caps[8] = {}; + // TS 23.003 Sec. 6.2.2 IMEISV's last two octets are Software Version Number (SVN) + // which identifies the software version number of the mobile equipment + const uint8_t ue_svn_oct1 = 0x5; + const uint8_t ue_svn_oct2 = 0x3; + // timers srsran::task_sched_handle task_sched; srsran::timer_handler::unique_timer t3502; // started when registration failure and the attempt counter is equal to 5 @@ -99,7 +113,31 @@ private: srsran::proc_t registration_proc; - int send_registration_request(); + // Message sender + int send_registration_request(); + int send_authentication_response(const uint8_t res[16]); + int send_security_mode_reject(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause); + int send_authentication_failure(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause, + const uint8_t* auth_fail_param); + int send_security_mode_complete(const srsran::nas_5g::security_mode_command_t& security_mode_command); + int send_registration_complete(); + + void fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps); + int apply_security_config(srsran::unique_byte_buffer_t& pdu, uint8_t sec_hdr_type); + + // message handler + int handle_registration_accept(srsran::nas_5g::registration_accept_t& registration_accept); + int handle_registration_reject(srsran::nas_5g::registration_reject_t& registration_reject); + int handle_authentication_request(srsran::nas_5g::authentication_request_t& authentication_request); + int handle_identity_request(srsran::nas_5g::identity_request_t& identity_request); + int handle_service_accept(srsran::nas_5g::service_accept_t& service_accept); + int handle_service_reject(srsran::nas_5g::service_reject_t& service_reject); + int handle_security_mode_command(srsran::nas_5g::security_mode_command_t& security_mode_command, + srsran::unique_byte_buffer_t pdu); + int handle_deregistration_accept_ue_terminated( + srsran::nas_5g::deregistration_accept_ue_terminated_t& deregistration_accept_ue_terminated); + int handle_deregistration_request_ue_terminated( + srsran::nas_5g::deregistration_request_ue_terminated_t& deregistration_request_ue_terminated); }; } // namespace srsue #endif \ No newline at end of file diff --git a/srsue/hdr/stack/upper/nas_5g_procedures.h b/srsue/hdr/stack/upper/nas_5g_procedures.h index 85ef15bcd..9d6b08e3a 100644 --- a/srsue/hdr/stack/upper/nas_5g_procedures.h +++ b/srsue/hdr/stack/upper/nas_5g_procedures.h @@ -30,6 +30,7 @@ public: explicit registration_procedure(nas_5g_interface_procedures* parent_nas_); srsran::proc_outcome_t init(); srsran::proc_outcome_t step(); + srsran::proc_outcome_t then(); static const char* name() { return "Registration Procedure"; } private: diff --git a/srsue/hdr/stack/upper/nas_5gmm_state.h b/srsue/hdr/stack/upper/nas_5gmm_state.h index b28280b61..3489c7336 100644 --- a/srsue/hdr/stack/upper/nas_5gmm_state.h +++ b/srsue/hdr/stack/upper/nas_5gmm_state.h @@ -57,6 +57,7 @@ public: update_needed, }; + mm5g_state_t(srslog::basic_logger& logger_) : logger(logger_) {} // FSM setters void set_null(); void set_deregistered(deregistered_substate_t substate); @@ -77,7 +78,7 @@ private: state_t state = state_t::null; deregistered_substate_t deregistered_substate = deregistered_substate_t::null; registered_substate_t registered_substate = registered_substate_t::null; - srslog::basic_logger& logger = srslog::fetch_basic_logger("NAS-5G"); + srslog::basic_logger& logger; }; const char* mm5g_state_text(mm5g_state_t::state_t type); diff --git a/srsue/hdr/stack/upper/nas_base.h b/srsue/hdr/stack/upper/nas_base.h index 8f9efbe11..5688482d8 100644 --- a/srsue/hdr/stack/upper/nas_base.h +++ b/srsue/hdr/stack/upper/nas_base.h @@ -49,9 +49,17 @@ protected: LIBLTE_MME_EPS_MOBILE_ID_GUTI_STRUCT guti; }; - nas_sec_ctxt ctxt = {}; - uint8_t k_nas_enc[32] = {}; - uint8_t k_nas_int[32] = {}; + struct nas_5g_sec_ctxt { + uint8_t ksi; + uint8_t k_amf[32]; + uint32_t tx_count; + uint32_t rx_count; + }; + + nas_sec_ctxt ctxt = {}; + nas_5g_sec_ctxt ctxt_5g = {}; + uint8_t k_nas_enc[32] = {}; + uint8_t k_nas_int[32] = {}; int parse_security_algorithm_list(std::string algorithm_string, bool* algorithm_caps); diff --git a/srsue/hdr/stack/upper/test/nas_test_common.h b/srsue/hdr/stack/upper/test/nas_test_common.h index bc88a9e89..05be81df4 100644 --- a/srsue/hdr/stack/upper/test/nas_test_common.h +++ b/srsue/hdr/stack/upper/test/nas_test_common.h @@ -131,15 +131,23 @@ public: plmns[0].plmn_id.from_number(mcc, mnc); plmns[0].tac = 0xffff; } - void init(nas_5g* nas_5g_) { nas_5g_ptr = nas_5g_; } - void write_sdu(unique_byte_buffer_t sdu) + void init(srsue::nas_5g* nas_5g_) { nas_5g_ptr = nas_5g_; } + int write_sdu(unique_byte_buffer_t sdu) { last_sdu_len = sdu->N_bytes; // printf("NAS generated SDU (len=%d):\n", sdu->N_bytes); + return SRSRAN_SUCCESS; + } + virtual bool is_connected() { return true; } + virtual int connection_request(srsran::nr_establishment_cause_t cause, srsran::unique_byte_buffer_t sdu) + { + return SRSRAN_SUCCESS; } + uint16_t get_mcc() { return 0x0000; } + uint16_t get_mnc() { return 0x0000; } private: - nas_5g* nas_5g_ptr; + srsue::nas_5g* nas_5g_ptr; uint32_t last_sdu_len; nas_interface_rrc::found_plmn_t plmns[nas_interface_rrc::MAX_FOUND_PLMNS]; }; diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index e4147f349..2d13272b6 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -48,7 +48,8 @@ nas_5g::nas_5g(srslog::basic_logger& logger_, srsran::task_sched_handle task_sch t3511(task_sched_.get_unique_timer()), t3521(task_sched_.get_unique_timer()), reregistration_timer(task_sched_.get_unique_timer()), - registration_proc(this) + registration_proc(this), + state(logger_) { // Configure timers t3502.set(t3502_duration_ms, [this](uint32_t tid) { timer_expired(tid); }); @@ -150,25 +151,27 @@ int nas_5g::send_registration_request() logger.info("Generating registration request"); - nas_5gs_msg nas_msg; - nas_msg.hdr.extended_protocol_discriminator = + initial_registration_request_stored.hdr.extended_protocol_discriminator = nas_5gs_hdr::extended_protocol_discriminator_opts::extended_protocol_discriminator_5gmm; - registration_request_t& reg_req = nas_msg.set_registration_request(); + registration_request_t& reg_req = initial_registration_request_stored.set_registration_request(); reg_req.registration_type_5gs.follow_on_request_bit = - registration_type_5gs_t::follow_on_request_bit_type_::options::no_follow_on_request_pending; + registration_type_5gs_t::follow_on_request_bit_type_::options::follow_on_request_pending; reg_req.registration_type_5gs.registration_type = registration_type_5gs_t::registration_type_type_::options::initial_registration; mobile_identity_5gs_t::suci_s& suci = reg_req.mobile_identity_5gs.set_suci(); suci.supi_format = mobile_identity_5gs_t::suci_s::supi_format_type_::options::imsi; usim->get_home_mcc_bytes(suci.mcc.data(), suci.mcc.size()); - usim->get_home_mcc_bytes(suci.mnc.data(), suci.mnc.size()); + usim->get_home_mnc_bytes(suci.mnc.data(), suci.mnc.size()); suci.scheme_output.resize(5); usim->get_home_msin_bcd(suci.scheme_output.data(), 5); logger.info("Requesting IMSI attach (IMSI=%s)", usim->get_imsi_str().c_str()); - if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + reg_req.ue_security_capability_present = true; + fill_security_caps(reg_req.ue_security_capability); + + if (initial_registration_request_stored.pack(pdu) != SRSASN_SUCCESS) { logger.error("Failed to pack registration request"); return SRSRAN_ERROR; } @@ -181,11 +184,358 @@ int nas_5g::send_registration_request() logger.debug("Starting T3410. Timeout in %d ms.", t3510.duration()); t3510.run(); + if (rrc_nr->is_connected() == true) { + rrc_nr->write_sdu(std::move(pdu)); + } else { + logger.debug("Initiating RRC NR Connection"); + if (rrc_nr->connection_request(nr_establishment_cause_t::mo_Signalling, std::move(pdu)) != SRSRAN_SUCCESS) { + logger.warning("Error starting RRC NR connection"); + return SRSRAN_ERROR; + } + } + state.set_registered_initiated(); return SRSRAN_SUCCESS; } +int nas_5g::send_authentication_response(const uint8_t res[16]) +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + logger.info("Generating Authentication Response"); + + nas_5gs_msg nas_msg; + authentication_response_t& auth_resp = nas_msg.set_authentication_response(); + auth_resp.authentication_response_parameter_present = true; + auth_resp.authentication_response_parameter.res.resize(16); + memcpy(auth_resp.authentication_response_parameter.res.data(), res, 16); + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack authentication response"); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + // if (apply_security_config(pdu, current_sec_hdr) != SRSASN_SUCCESS) { + // logger.error("Error applying NAS security."); + // return SRSRAN_ERROR; + // } + + logger.info("Sending Authentication Response"); + rrc_nr->write_sdu(std::move(pdu)); + + return SRSRAN_SUCCESS; +} + +int nas_5g::send_security_mode_reject(const cause_5gmm_t::cause_5gmm_type_::options cause) +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + nas_5gs_msg nas_msg; + security_mode_reject_t& security_mode_reject = nas_msg.set_security_mode_reject(); + security_mode_reject.cause_5gmm.cause_5gmm = cause; + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack authentication response"); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + logger.info("Sending Authentication Response"); + rrc_nr->write_sdu(std::move(pdu)); + + return SRSRAN_SUCCESS; +} +void copy_msg_to_buffer(unique_byte_buffer_t& pdu, const_byte_span msg) +{ + pdu = srsran::make_byte_buffer(); + if (pdu == nullptr) { + srslog::fetch_basic_logger("ALL").error("Couldn't allocate PDU in %s().", __FUNCTION__); + return; + } + memcpy(pdu->msg, msg.data(), msg.size()); + pdu->N_bytes = msg.size(); +} + +int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_command_t& security_mode_command) +{ + uint8_t current_sec_hdr = LIBLTE_MME_SECURITY_HDR_TYPE_INTEGRITY_AND_CIPHERED_WITH_NEW_EPS_SECURITY_CONTEXT; + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + logger.info("Generating Security Mode Complete"); + + nas_5gs_msg nas_msg; + security_mode_complete_t& security_mode_complete = nas_msg.set_security_mode_complete(); + + if (security_mode_command.imeisv_request_present) { + security_mode_complete.imeisv_present = true; + mobile_identity_5gs_t::imeisv_s& imeisv = security_mode_complete.imeisv.set_imeisv(); + usim->get_imei_vec(imeisv.imeisv.data(), 15); + imeisv.imeisv[14] = ue_svn_oct1; + imeisv.imeisv[15] = ue_svn_oct2; + } + + registration_request_t& modified_registration_request = initial_registration_request_stored.registration_request(); + modified_registration_request.capability_5gmm_present = true; + modified_registration_request.requested_nssai_present = true; + modified_registration_request.update_type_5gs_present = true; + + s_nssai_t s_nssai; + s_nssai.type = s_nssai_t::SST_type_::options::sst; + s_nssai.sst = 1; + modified_registration_request.requested_nssai.s_nssai_list = {s_nssai}; + + modified_registration_request.capability_5gmm.lpp = 0; + modified_registration_request.capability_5gmm.ho_attach = 0; + modified_registration_request.capability_5gmm.s1_mode = 0; + + modified_registration_request.update_type_5gs.ng_ran_rcu.value = + update_type_5gs_t::NG_RAN_RCU_type::options::ue_radio_capability_update_not_needed; + modified_registration_request.update_type_5gs.sms_requested.value = + update_type_5gs_t::SMS_requested_type::options::sms_over_nas_not_supported; + + security_mode_complete.nas_message_container_present = true; + initial_registration_request_stored.pack(security_mode_complete.nas_message_container.nas_message_container); + + nas_msg.hdr.security_header_type = + nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered_with_new_5G_nas_context; + nas_msg.hdr.sequence_number = ctxt.tx_count; + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack security mode complete"); + return SRSRAN_ERROR; + } + + cipher_encrypt(pdu.get()); + integrity_generate(&k_nas_int[16], + ctxt.tx_count, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[SEQ_5G_OFFSET], + pdu->N_bytes - SEQ_5G_OFFSET, + &pdu->msg[MAC_5G_OFFSET]); + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + logger.info("Sending Security Mode Complete"); + rrc_nr->write_sdu(std::move(pdu)); + ctxt.rx_count++; + + return SRSRAN_SUCCESS; +} + +int nas_5g::send_authentication_failure(const cause_5gmm_t::cause_5gmm_type_::options cause, + const uint8_t* auth_fail_param) +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + nas_5gs_msg nas_msg; + authentication_failure_t& auth_fail = nas_msg.set_authentication_failure(); + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack authentication failure."); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + logger.info("Sending Authentication Failure"); + rrc_nr->write_sdu(std::move(pdu)); + + return SRSRAN_SUCCESS; +} + +int nas_5g::send_registration_complete() +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + logger.info("Generating Registration Complete"); + + nas_5gs_msg nas_msg; + registration_complete_t& reg_comp = nas_msg.set_registration_complete(); + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack registration complete."); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + logger.info("Sending Registration Complete"); + rrc_nr->write_sdu(std::move(pdu)); + + return SRSRAN_SUCCESS; +} + +int nas_5g::write_pdu(srsran::unique_byte_buffer_t pdu) +{ + logger.info(pdu->msg, pdu->N_bytes, "DL PDU (length %d)", pdu->N_bytes); + + nas_5gs_msg nas_msg; + + if (nas_msg.unpack_outer_hdr(pdu) != SRSRAN_SUCCESS) { + logger.error("Unable to unpack outer NAS header"); + return SRSRAN_ERROR; + } + + switch (nas_msg.hdr.security_header_type) { + case nas_5gs_hdr::security_header_type_opts::plain_5gs_nas_message: + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected: + if (integrity_check(pdu.get()) == false) { + logger.error("Not handling NAS message with integrity check error"); + return SRSRAN_ERROR; + } + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered: + if (integrity_check(pdu.get()) == false) { + logger.error("Not handling NAS message with integrity check error"); + return SRSRAN_ERROR; + } else { + cipher_decrypt(pdu.get()); + } + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected_with_new_5G_nas_context: + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered_with_new_5G_nas_context: + return SRSRAN_ERROR; + default: + logger.error("Not handling NAS message with unkown security header"); + break; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + + logger.info(pdu->msg, pdu->N_bytes, "Decrypted DL PDU (length %d)", pdu->N_bytes); + + // Parse the message header + if (nas_msg.unpack(pdu) != SRSRAN_SUCCESS) { + logger.error("Unable to unpack complete NAS pdu"); + return SRSRAN_ERROR; + } + + switch (nas_msg.hdr.message_type) { + case msg_opts::options::registration_accept: + handle_registration_accept(nas_msg.registration_accept()); + break; + case msg_opts::options::registration_reject: + handle_registration_reject(nas_msg.registration_reject()); + break; + case msg_opts::options::authentication_request: + handle_authentication_request(nas_msg.authentication_request()); + break; + case msg_opts::options::identity_request: + handle_identity_request(nas_msg.identity_request()); + break; + case msg_opts::options::security_mode_command: + handle_security_mode_command(nas_msg.security_mode_command(), std::move(pdu)); + break; + case msg_opts::options::service_accept: + handle_service_accept(nas_msg.service_accept()); + break; + case msg_opts::options::service_reject: + handle_service_reject(nas_msg.service_reject()); + break; + case msg_opts::options::deregistration_accept_ue_terminated: + handle_deregistration_accept_ue_terminated(nas_msg.deregistration_accept_ue_terminated()); + break; + case msg_opts::options::deregistration_request_ue_terminated: + handle_deregistration_request_ue_terminated(nas_msg.deregistration_request_ue_terminated()); + break; + default: + logger.error( + "Not handling NAS message type: %s (0x%02x)", nas_msg.hdr.message_type.to_string(), nas_msg.hdr.message_type); + break; + } + return SRSRAN_SUCCESS; +} + +void nas_5g::fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps) +{ + if (ia5g_caps[0] == true) { + sec_caps.ia0_5g_supported = true; + } + if (ia5g_caps[1] == true) { + sec_caps.ia1_128_5g_supported = true; + } + if (ia5g_caps[2] == true) { + sec_caps.ia2_128_5g_supported = true; + } + if (ia5g_caps[3] == true) { + sec_caps.ia3_128_5g_supported = true; + } + if (ia5g_caps[4] == true) { + sec_caps.ia4_5g_supported = true; + } + if (ia5g_caps[5] == true) { + sec_caps.ia5_5g_supported = true; + } + if (ia5g_caps[6] == true) { + sec_caps.ia6_5g_supported = true; + } + if (ia5g_caps[7] == true) { + sec_caps.ia7_5g_supported = true; + } + + if (ea5g_caps[0] == true) { + sec_caps.ea0_5g_supported = true; + } + if (ea5g_caps[1] == true) { + sec_caps.ea1_128_5g_supported = true; + } + if (ea5g_caps[2] == true) { + sec_caps.ea2_128_5g_supported = true; + } + if (ea5g_caps[3] == true) { + sec_caps.ea3_128_5g_supported = true; + } + if (ea5g_caps[4] == true) { + sec_caps.ea4_5g_supported = true; + } + if (ea5g_caps[5] == true) { + sec_caps.ea5_5g_supported = true; + } + if (ea5g_caps[6] == true) { + sec_caps.ea6_5g_supported = true; + } + if (ea5g_caps[7] == true) { + sec_caps.ea7_5g_supported = true; + } +} /******************************************************************************* * UE Stack and RRC common Interface ******************************************************************************/ @@ -239,4 +589,170 @@ int nas_5g::start_service_request() return SRSRAN_SUCCESS; } +// Message handler + +int nas_5g::handle_registration_accept(registration_accept_t& registration_accept) +{ + if (state.get_state() != mm5g_state_t::state_t::registered_initiated) { + logger.warning("Not compatibale with current state %s", state.get_full_state_text()); + return SRSRAN_ERROR; + } + + bool send_reg_complete = false; + logger.info("Handling Registration Accept"); + if (registration_accept.guti_5g_present) { + guti_5g = registration_accept.guti_5g.guti_5g(); + send_reg_complete = true; + } + + if (send_reg_complete == true) { + send_registration_complete(); + } + + // TODO: reset counters and everything what is needed by the specification + t3521.set(registration_accept.t3512_value.timer_value); + registration_proc.run(); + state.set_registered(mm5g_state_t::registered_substate_t::normal_service); + return SRSRAN_SUCCESS; +} + +int nas_5g::handle_registration_reject(registration_reject_t& registration_reject) +{ + logger.info("Handling Registration Reject"); + return SRSRAN_SUCCESS; +} +int nas_5g::handle_authentication_request(authentication_request_t& authentication_request) +{ + logger.info("Handling Registration Request"); + + // Generate authentication response using RAND, AUTN & KSI-ASME + uint16 mcc, mnc; + mcc = rrc_nr->get_mcc(); + mnc = rrc_nr->get_mnc(); + plmn_id_t plmn_id; + plmn_id.from_number(mcc, mnc); + + if (authentication_request.authentication_parameter_rand_present == false) { + logger.error("authentication_parameter_rand_present is not present"); + return SRSRAN_ERROR; + } + + if (authentication_request.authentication_parameter_autn_present == false) { + logger.error("authentication_parameter_autn_present is not present"); + return SRSRAN_ERROR; + } + + uint8_t res_star[16]; + + logger.info(authentication_request.authentication_parameter_rand.rand.data(), + authentication_request.authentication_parameter_rand.rand.size(), + "Authentication request RAND"); + + logger.info(authentication_request.authentication_parameter_autn.autn.data(), + authentication_request.authentication_parameter_rand.rand.size(), + "Authentication request AUTN"); + + logger.info("Serving network name %s", plmn_id.to_serving_network_name_string().c_str()); + auth_result_t auth_result = + usim->generate_authentication_response_5g(authentication_request.authentication_parameter_rand.rand.data(), + authentication_request.authentication_parameter_autn.autn.data(), + plmn_id.to_serving_network_name_string().c_str(), + authentication_request.abba.abba_contents.data(), + authentication_request.abba.abba_contents.size(), + res_star, + ctxt_5g.k_amf); + logger.info(ctxt_5g.k_amf, 32, "Generated k_amf:"); + if (auth_result == AUTH_OK) { + logger.info("Network authentication successful"); + send_authentication_response(res_star); + logger.info(res_star, 16, "Generated res_star (%d):", 16); + + } else if (auth_result == AUTH_SYNCH_FAILURE) { + logger.error("Network authentication synchronization failure."); + // send_authentication_failure(LIBLTE_MME_EMM_CAUSE_SYNCH_FAILURE, res); + } else { + logger.warning("Network authentication failure"); + srsran::console("Warning: Network authentication failure\n"); + // send_authentication_failure(LIBLTE_MME_EMM_CAUSE_MAC_FAILURE, nullptr); + } + + return SRSRAN_SUCCESS; +} + +int nas_5g::handle_identity_request(identity_request_t& identity_request) +{ + logger.info("Handling Identity Request"); + return SRSRAN_SUCCESS; +} + +int nas_5g::handle_service_accept(srsran::nas_5g::service_accept_t& service_accept) +{ + logger.info("Handling Service Accept"); + return SRSRAN_SUCCESS; +} + +int nas_5g::handle_service_reject(srsran::nas_5g::service_reject_t& service_reject) +{ + logger.info("Handling Service Accept"); + return SRSRAN_SUCCESS; +} + +int nas_5g::handle_security_mode_command(security_mode_command_t& security_mode_command, + srsran::unique_byte_buffer_t pdu) +{ + logger.info("Handling Security Mode Command"); + ctxt.cipher_algo = + (CIPHERING_ALGORITHM_ID_ENUM)security_mode_command.selected_nas_security_algorithms.ciphering_algorithm.value; + ctxt.integ_algo = (INTEGRITY_ALGORITHM_ID_ENUM) + security_mode_command.selected_nas_security_algorithms.integrity_protection_algorithm.value; + + // Check capabilities + // TODO: Check replayed sec capabilities + if (!ea5g_caps[ctxt.cipher_algo] || !ia5g_caps[ctxt.integ_algo]) { + logger.warning("Sending Security Mode Reject due to security capabilities mismatch"); + send_security_mode_reject(cause_5gmm_t::cause_5gmm_type_::options::ue_security_capabilities_mismatch); + return SRSRAN_ERROR; + } + + initial_sec_command = false; // TODO + + if (initial_sec_command) { + ctxt.rx_count = 0; + ctxt.tx_count = 0; + initial_sec_command = false; + } + + // Generate NAS keys + logger.debug(ctxt_5g.k_amf, 32, "K AMF"); + logger.debug("cipher_algo %d, integ_algo %d", ctxt.cipher_algo, ctxt.integ_algo); + + usim->generate_nas_keys_5g(ctxt_5g.k_amf, k_nas_enc, k_nas_int, ctxt.cipher_algo, ctxt.integ_algo); + logger.info(k_nas_enc, 32, "NAS encryption key - k_nas_enc"); + logger.info(k_nas_int, 32, "NAS integrity key - k_nas_int"); + + logger.debug("Generating integrity check. integ_algo:%d, count_dl:%d", ctxt.integ_algo, ctxt.rx_count); + + if (not integrity_check(pdu.get())) { + logger.warning("Sending Security Mode Reject due to integrity check failure"); + send_security_mode_reject(cause_5gmm_t::cause_5gmm_type_::options::mac_failure); + return SRSRAN_ERROR; + } + + send_security_mode_complete(security_mode_command); + ctxt.rx_count++; + return SRSRAN_SUCCESS; +} +int nas_5g::handle_deregistration_accept_ue_terminated( + deregistration_accept_ue_terminated_t& deregistration_accept_ue_terminated) +{ + logger.info("Handling Deregistration Accept UE Terminated"); + return SRSRAN_SUCCESS; +} +int nas_5g::handle_deregistration_request_ue_terminated( + deregistration_request_ue_terminated_t& deregistration_request_ue_terminated) +{ + logger.info("Handling Deregistration Request UE Terminated"); + return SRSRAN_SUCCESS; +} + } // namespace srsue \ No newline at end of file diff --git a/srsue/src/stack/upper/nas_5g_procedures.cc b/srsue/src/stack/upper/nas_5g_procedures.cc index bf2b80e2d..577095cc4 100644 --- a/srsue/src/stack/upper/nas_5g_procedures.cc +++ b/srsue/src/stack/upper/nas_5g_procedures.cc @@ -35,4 +35,5 @@ srsran::proc_outcome_t nas_5g::registration_procedure::step() return srsran::proc_outcome_t::success; } + } // namespace srsue \ No newline at end of file From 03859803476118b2651dae3a5098226d8bf95729 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Mon, 23 Aug 2021 10:02:23 +0200 Subject: [PATCH 11/83] Fixed minor NGAP issues --- srsenb/hdr/stack/ngap/ngap_ue.h | 10 +++++----- srsenb/hdr/stack/ngap/ngap_ue_proc.h | 2 +- srsenb/src/stack/ngap/ngap_ue.cc | 19 ++++++++----------- srsenb/src/stack/ngap/ngap_ue_proc.cc | 10 +++++----- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/srsenb/hdr/stack/ngap/ngap_ue.h b/srsenb/hdr/stack/ngap/ngap_ue.h index 99f203628..77bbc626e 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue.h +++ b/srsenb/hdr/stack/ngap/ngap_ue.h @@ -44,22 +44,22 @@ public: void ue_ctxt_setup_complete(); void notify_rrc_reconf_complete(const bool reconf_complete_outcome); - srsran::proc_t initial_context_setup_proc; - srsran::proc_t ue_context_release_proc; - ngap_ue_ctxt_t ctxt = {}; uint16_t stream_id = 1; private: // args - ngap* ngap_ptr; - rrc_interface_ngap_nr* rrc_ptr; + ngap* ngap_ptr = nullptr; // state bool release_requested = false; // logger srslog::basic_logger& logger; + + // procedures + srsran::proc_t initial_context_setup_proc; + srsran::proc_t ue_context_release_proc; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/ngap/ngap_ue_proc.h b/srsenb/hdr/stack/ngap/ngap_ue_proc.h index 9464fcd8e..eeb13c5b6 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue_proc.h +++ b/srsenb/hdr/stack/ngap/ngap_ue_proc.h @@ -37,7 +37,7 @@ public: rrc_interface_ngap_nr* rrc_, ngap_ue_ctxt_t* ue_ctxt); srsran::proc_outcome_t init(const asn1::ngap_nr::init_context_setup_request_s& msg); - srsran::proc_outcome_t react(const bool security_mode_command_outcome); + srsran::proc_outcome_t react(const bool rrc_reconf_outcome); srsran::proc_outcome_t step(); static const char* name() { return "Initial Context Setup"; } diff --git a/srsenb/src/stack/ngap/ngap_ue.cc b/srsenb/src/stack/ngap/ngap_ue.cc index 59b9f4737..ac988ca45 100644 --- a/srsenb/src/stack/ngap/ngap_ue.cc +++ b/srsenb/src/stack/ngap/ngap_ue.cc @@ -26,9 +26,8 @@ namespace srsenb { ngap::ue::ue(ngap* ngap_ptr_, rrc_interface_ngap_nr* rrc_ptr_, srslog::basic_logger& logger_) : logger(logger_), ngap_ptr(ngap_ptr_), - rrc_ptr(rrc_ptr_), - initial_context_setup_proc(this, rrc_ptr, &ctxt), - ue_context_release_proc(this, rrc_ptr, &ctxt) + initial_context_setup_proc(this, rrc_ptr_, &ctxt), + ue_context_release_proc(this, rrc_ptr_, &ctxt) { ctxt.ran_ue_ngap_id = ngap_ptr->next_gnb_ue_ngap_id++; gettimeofday(&ctxt.init_timestamp, nullptr); @@ -82,6 +81,10 @@ bool ngap::ue::send_initial_ue_message(asn1::ngap_nr::rrcestablishment_cause_e c container.user_location_info.value.user_location_info_nr().tai.plmn_id = ngap_ptr->tai.plmn_id; container.user_location_info.value.user_location_info_nr().tai.tac = ngap_ptr->tai.tac; + // UE context request for setup in the NAS registration request + container.ue_context_request_present = true; + container.ue_context_request.value = asn1::ngap_nr::ue_context_request_opts::options::requested; + return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "InitialUEMessage"); } @@ -138,7 +141,7 @@ bool ngap::ue::send_initial_ctxt_setup_response() } ngap_pdu_c tx_pdu; - tx_pdu.set_init_msg().load_info_obj(ASN1_NGAP_NR_ID_INIT_CONTEXT_SETUP); + tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_NR_ID_INIT_CONTEXT_SETUP); init_context_setup_resp_s& container = tx_pdu.successful_outcome().value.init_context_setup_resp(); // AMF UE NGAP ID @@ -147,13 +150,7 @@ bool ngap::ue::send_initial_ctxt_setup_response() // RAN UE NGAP ID container.protocol_ies.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; - /* // TODO: PDU Session Resource Setup Response List - Integrate PDU Session and Bearer management into NGAP - container.protocol_ies.pdu_session_res_setup_list_cxt_res_present = true; - - // Case PDU Session Resource Failed to Setup List - container.protocol_ies.pdu_session_res_failed_to_setup_list_cxt_res_present = true; */ - - return true; + return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "InitialContextSetupResponse"); } bool ngap::ue::send_initial_ctxt_setup_failure(cause_c cause) diff --git a/srsenb/src/stack/ngap/ngap_ue_proc.cc b/srsenb/src/stack/ngap/ngap_ue_proc.cc index 8b113b098..52b0812b3 100644 --- a/srsenb/src/stack/ngap/ngap_ue_proc.cc +++ b/srsenb/src/stack/ngap/ngap_ue_proc.cc @@ -52,17 +52,17 @@ proc_outcome_t ngap_ue_initial_context_setup_proc::init(const asn1::ngap_nr::ini return proc_outcome_t::yield; }; -proc_outcome_t ngap_ue_initial_context_setup_proc::react(bool security_mode_command_outcome) +proc_outcome_t ngap_ue_initial_context_setup_proc::react(bool rrc_reconf_outcome) { - if(security_mode_command_outcome == true) { + if (rrc_reconf_outcome == true) { parent->send_initial_ctxt_setup_response(); return proc_outcome_t::success; - } - // TODO: error handling if security mode command fails + } + return proc_outcome_t::error; } -proc_outcome_t ngap_ue_initial_context_setup_proc::step() +proc_outcome_t ngap_ue_initial_context_setup_proc::step() { return proc_outcome_t::yield; } From 3712983308d9ff29d6063bc42896936242fc0065 Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Mon, 23 Aug 2021 15:28:39 +0200 Subject: [PATCH 12/83] Added PDU Session est request --- .../srsran/interfaces/ue_nas_interfaces.h | 23 + srsenb/hdr/stack/ngap/ngap.h | 2 +- srsenb/hdr/stack/ngap/ngap_ue.h | 3 + srsenb/hdr/stack/ngap/ngap_ue_proc.h | 17 + srsenb/src/stack/ngap/ngap.cc | 14 +- srsenb/src/stack/ngap/ngap_ue.cc | 12 +- srsenb/src/stack/ngap/ngap_ue_proc.cc | 37 + srsue/hdr/stack/upper/nas.h | 2 - srsue/hdr/stack/upper/nas_5g.h | 55 +- srsue/hdr/stack/upper/nas_5g_procedures.h | 26 + srsue/hdr/stack/upper/nas_base.h | 2 + srsue/hdr/stack/upper/nas_config.h | 6 +- srsue/src/stack/upper/nas_5g.cc | 745 ++++++++++++------ srsue/src/stack/upper/nas_5g_procedures.cc | 49 ++ 14 files changed, 740 insertions(+), 253 deletions(-) diff --git a/lib/include/srsran/interfaces/ue_nas_interfaces.h b/lib/include/srsran/interfaces/ue_nas_interfaces.h index 4bbe3dfba..75459dd22 100644 --- a/lib/include/srsran/interfaces/ue_nas_interfaces.h +++ b/lib/include/srsran/interfaces/ue_nas_interfaces.h @@ -13,10 +13,26 @@ #ifndef SRSRAN_UE_NAS_INTERFACES_H #define SRSRAN_UE_NAS_INTERFACES_H +#include "srsran/asn1/nas_5g_ies.h" #include "srsran/interfaces/rrc_interface_types.h" namespace srsue { +enum apn_types { + ipv4 = 0b001, + ipv6 = 0b010, + ipv4v6 = 0b011, + unstructured = 0b100, + ethernet = 0b101, +}; +class pdu_session_cfg_t +{ +public: + std::string apn_name; + apn_types apn_type; + std::string apn_user; + std::string apn_pass; +}; class nas_interface_rrc { public: @@ -49,6 +65,13 @@ class nas_5g_interface_procedures { public: virtual int send_registration_request() = 0; + virtual int send_pdu_session_establishment_request(uint32_t transaction_identity, + uint16_t pdu_session_id, + const pdu_session_cfg_t& pdu_session) = 0; + virtual int + add_pdu_session(uint16_t pdu_session_id, uint16_t pdu_session_type, srsran::nas_5g::pdu_address_t pdu_address) = 0; + + virtual uint32_t allocate_next_proc_trans_id() = 0; }; } // namespace srsue diff --git a/srsenb/hdr/stack/ngap/ngap.h b/srsenb/hdr/stack/ngap/ngap.h index 3aa3b0f39..5e1112b56 100644 --- a/srsenb/hdr/stack/ngap/ngap.h +++ b/srsenb/hdr/stack/ngap/ngap.h @@ -125,7 +125,7 @@ private: // TS 38.413 - Section 9.2.2.1 - Initial Context Setup Request bool handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg); // TS 38.413 - Section 9.2.1.1 - PDU Session Resource Setup Request - bool handle_pdu_session_resource_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg); + bool handle_ue_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg); class user_list { diff --git a/srsenb/hdr/stack/ngap/ngap_ue.h b/srsenb/hdr/stack/ngap/ngap_ue.h index 77bbc626e..cbf2550a3 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue.h +++ b/srsenb/hdr/stack/ngap/ngap_ue.h @@ -39,6 +39,8 @@ public: bool handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg); // TS 38.413 - Section 9.2.2.5 - UE Context Release Command bool handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cmd_s& msg); + // TS 38.413 - Section 9.2.1.1 - PDU Session Resource Setup Request + bool handle_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg); bool was_uectxtrelease_requested() const { return release_requested; } void ue_ctxt_setup_complete(); @@ -60,6 +62,7 @@ private: // procedures srsran::proc_t initial_context_setup_proc; srsran::proc_t ue_context_release_proc; + srsran::proc_t ue_pdu_session_res_setup_proc; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/ngap/ngap_ue_proc.h b/srsenb/hdr/stack/ngap/ngap_ue_proc.h index eeb13c5b6..a549a24d3 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue_proc.h +++ b/srsenb/hdr/stack/ngap/ngap_ue_proc.h @@ -79,6 +79,23 @@ private: ngap_interface_ngap_proc* parent; }; +class ngap_ue_pdu_session_res_setup_proc +{ +public: + explicit ngap_ue_pdu_session_res_setup_proc(ngap_interface_ngap_proc* parent_, + rrc_interface_ngap_nr* rrc_, + ngap_ue_ctxt_t* ue_ctxt); + srsran::proc_outcome_t init(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg); + srsran::proc_outcome_t step(); + static const char* name() { return "UE PDU Session Resource Setup"; } + +private: + ngap_ue_ctxt_t* ue_ctxt; + ngap_interface_ngap_proc* parent; + rrc_interface_ngap_nr* rrc = nullptr; + srslog::basic_logger& logger; +}; + } // namespace srsenb #endif \ No newline at end of file diff --git a/srsenb/src/stack/ngap/ngap.cc b/srsenb/src/stack/ngap/ngap.cc index 0f99b1973..9d99e8d3a 100644 --- a/srsenb/src/stack/ngap/ngap.cc +++ b/srsenb/src/stack/ngap/ngap.cc @@ -414,6 +414,8 @@ bool ngap::handle_initiating_message(const asn1::ngap_nr::init_msg_s& msg) return handle_initial_ctxt_setup_request(msg.value.init_context_setup_request()); case ngap_elem_procs_o::init_msg_c::types_opts::ue_context_release_cmd: return handle_ue_ctxt_release_cmd(msg.value.ue_context_release_cmd()); + case ngap_elem_procs_o::init_msg_c::types_opts::pdu_session_res_setup_request: + return handle_ue_pdu_session_res_setup_request(msg.value.pdu_session_res_setup_request()); default: logger.error("Unhandled initiating message: %s", msg.value.type().to_string()); } @@ -532,10 +534,16 @@ bool ngap::handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cm return true; } -bool ngap::handle_pdu_session_resource_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg) +bool ngap::handle_ue_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg) { - // TODO - logger.warning("Not implemented yet"); + ue* u = + handle_ngapmsg_ue_id(msg.protocol_ies.ran_ue_ngap_id.value.value, msg.protocol_ies.amf_ue_ngap_id.value.value); + if (u == nullptr) { + logger.warning("Can not find UE"); + return false; + } + + u->handle_pdu_session_res_setup_request(msg); return true; } diff --git a/srsenb/src/stack/ngap/ngap_ue.cc b/srsenb/src/stack/ngap/ngap_ue.cc index ac988ca45..26a115c10 100644 --- a/srsenb/src/stack/ngap/ngap_ue.cc +++ b/srsenb/src/stack/ngap/ngap_ue.cc @@ -27,7 +27,8 @@ ngap::ue::ue(ngap* ngap_ptr_, rrc_interface_ngap_nr* rrc_ptr_, srslog::basic_log logger(logger_), ngap_ptr(ngap_ptr_), initial_context_setup_proc(this, rrc_ptr_, &ctxt), - ue_context_release_proc(this, rrc_ptr_, &ctxt) + ue_context_release_proc(this, rrc_ptr_, &ctxt), + ue_pdu_session_res_setup_proc(this, rrc_ptr_, &ctxt) { ctxt.ran_ue_ngap_id = ngap_ptr->next_gnb_ue_ngap_id++; gettimeofday(&ctxt.init_timestamp, nullptr); @@ -202,4 +203,13 @@ bool ngap::ue::handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_releas return true; } +bool ngap::ue::handle_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg) +{ + if (not ue_pdu_session_res_setup_proc.launch(msg)) { + logger.error("Failed to start UE PDU Session Resource Setup Procedure"); + return false; + } + return true; +} + } // namespace srsenb \ No newline at end of file diff --git a/srsenb/src/stack/ngap/ngap_ue_proc.cc b/srsenb/src/stack/ngap/ngap_ue_proc.cc index 52b0812b3..739698d84 100644 --- a/srsenb/src/stack/ngap/ngap_ue_proc.cc +++ b/srsenb/src/stack/ngap/ngap_ue_proc.cc @@ -89,4 +89,41 @@ proc_outcome_t ngap_ue_ue_context_release_proc::step() return proc_outcome_t::success; } +ngap_ue_pdu_session_res_setup_proc::ngap_ue_pdu_session_res_setup_proc(ngap_interface_ngap_proc* parent_, + rrc_interface_ngap_nr* rrc_, + ngap_ue_ctxt_t* ue_ctxt_) : + logger(srslog::fetch_basic_logger("NGAP UE")) +{ + parent = parent_; + rrc = rrc_; + ue_ctxt = ue_ctxt_; +} + +proc_outcome_t ngap_ue_pdu_session_res_setup_proc::init(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg) +{ + if (msg.protocol_ies.pdu_session_res_setup_list_su_req.value.size() != 1) { + logger.error("Not handling multiple su requests"); + return proc_outcome_t::error; + } + asn1::ngap_nr::pdu_session_res_setup_item_su_req_s su_req = + msg.protocol_ies.pdu_session_res_setup_list_su_req.value[0]; + + if (su_req.pdu_session_nas_pdu_present) { + srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (pdu == nullptr) { + logger.error("Fatal Error: Couldn't allocate buffer in ngap_ue_initial_context_setup_proc::init()."); + return proc_outcome_t::error; + } + memcpy(pdu->msg, su_req.pdu_session_nas_pdu.data(), su_req.pdu_session_nas_pdu.size()); + pdu->N_bytes = su_req.pdu_session_nas_pdu.size(); + rrc->write_dl_info(ue_ctxt->rnti, std::move(pdu)); + } + return proc_outcome_t::yield; +} + +proc_outcome_t ngap_ue_pdu_session_res_setup_proc::step() +{ + return proc_outcome_t::success; +} + } // namespace srsenb \ No newline at end of file diff --git a/srsue/hdr/stack/upper/nas.h b/srsue/hdr/stack/upper/nas.h index 42d643b63..010e5978f 100644 --- a/srsue/hdr/stack/upper/nas.h +++ b/srsue/hdr/stack/upper/nas.h @@ -263,8 +263,6 @@ private: srsran::proc_manager_list_t callbacks; srsran::proc_t plmn_searcher; - - const std::string gw_setup_failure_str = "Failed to setup/configure GW interface"; }; } // namespace srsue diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 2124f5aea..4e68275e9 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -33,6 +33,9 @@ using srsran::byte_buffer_t; +#define MAX_PDU_SESSIONS 15 +#define MAX_TRANS_ID 255 + namespace srsue { /** @@ -72,7 +75,7 @@ private: bool running = false; - bool initial_sec_command = false; + bool initial_sec_command = false; srsran::nas_5g::mobile_identity_5gs_t::guti_5g_s guti_5g; srsran::nas_5g::nas_5gs_msg initial_registration_request_stored; @@ -110,20 +113,25 @@ private: // Procedures // Forward declartion class registration_procedure; + class pdu_session_establishment_procedure; - srsran::proc_t registration_proc; + srsran::proc_t registration_proc; + srsran::proc_t pdu_session_establishment_proc; // Message sender - int send_registration_request(); - int send_authentication_response(const uint8_t res[16]); - int send_security_mode_reject(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause); - int send_authentication_failure(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause, - const uint8_t* auth_fail_param); - int send_security_mode_complete(const srsran::nas_5g::security_mode_command_t& security_mode_command); - int send_registration_complete(); + int send_registration_request(); + int send_authentication_response(const uint8_t res[16]); + int send_security_mode_reject(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause); + int send_authentication_failure(const srsran::nas_5g::cause_5gmm_t::cause_5gmm_type_::options cause, + const uint8_t* auth_fail_param); + int send_security_mode_complete(const srsran::nas_5g::security_mode_command_t& security_mode_command); + int send_registration_complete(); + int send_pdu_session_establishment_request(uint32_t transaction_identity, + uint16_t pdu_session_id, + const pdu_session_cfg_t& pdu_session); void fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps); - int apply_security_config(srsran::unique_byte_buffer_t& pdu, uint8_t sec_hdr_type); + int apply_security_config(srsran::unique_byte_buffer_t& pdu, uint8_t sec_hdr_type); // message handler int handle_registration_accept(srsran::nas_5g::registration_accept_t& registration_accept); @@ -138,6 +146,33 @@ private: srsran::nas_5g::deregistration_accept_ue_terminated_t& deregistration_accept_ue_terminated); int handle_deregistration_request_ue_terminated( srsran::nas_5g::deregistration_request_ue_terminated_t& deregistration_request_ue_terminated); + int handle_dl_nas_transport(srsran::nas_5g::dl_nas_transport_t& dl_nas_transport); + + // message handler container + int handle_n1_sm_information(std::vector payload_container_contents); + + // Transaction ID management + std::array pdu_trans_ids; + uint32_t allocate_next_proc_trans_id(); + void release_proc_trans_id(uint32_t proc_id); + + int trigger_pdu_session_est(); + + // PDU Session Management + int add_pdu_session(uint16_t pdu_session_id, uint16_t pdu_session_type, srsran::nas_5g::pdu_address_t pdu_address); + int init_pdu_sessions(std::vector pdu_session_cfgs); + int configure_pdu_session(uint16_t pdu_session_id); + bool unestablished_pdu_sessions(); + int get_unestablished_pdu_session(uint16_t& pdu_session_id, pdu_session_cfg_t& pdu_session_cfg); + + struct pdu_session_t { + bool configured; + bool established; + uint16_t pdu_session_id; + pdu_session_cfg_t pdu_session_cfg; + }; + + std::array pdu_sessions; }; } // namespace srsue #endif \ No newline at end of file diff --git a/srsue/hdr/stack/upper/nas_5g_procedures.h b/srsue/hdr/stack/upper/nas_5g_procedures.h index 9d6b08e3a..742189cf7 100644 --- a/srsue/hdr/stack/upper/nas_5g_procedures.h +++ b/srsue/hdr/stack/upper/nas_5g_procedures.h @@ -36,6 +36,32 @@ public: private: nas_5g_interface_procedures* parent_nas; }; + +/** + * @brief 5G NAS (5GSM) UE-requested PDU session establishment procedure + * + * Specified in 24 501 V16.7.0 + * UE-requested 5GSM procedures + * 6.4.1 UE-requested PDU session establishment procedure + */ +class nas_5g::pdu_session_establishment_procedure +{ +public: + explicit pdu_session_establishment_procedure(nas_5g_interface_procedures* parent_nas_, srslog::basic_logger& logger_); + srsran::proc_outcome_t init(const uint16_t pdu_session_id, const pdu_session_cfg_t pdu_session); + srsran::proc_outcome_t react(const srsran::nas_5g::pdu_session_establishment_accept_t& pdu_session_est_accept); + srsran::proc_outcome_t react(const srsran::nas_5g::pdu_session_establishment_reject_t& pdu_session_est_reject); + srsran::proc_outcome_t step(); + srsran::proc_outcome_t then(); + static const char* name() { return "PDU Session Establishment Procedure"; } + +private: + srslog::basic_logger& logger; + nas_5g_interface_procedures* parent_nas; + uint32_t transaction_identity = 0; + uint16_t pdu_session_id = 0; +}; + } // namespace srsue #endif // SRSUE_NAS_5G_PROCEDURES_H_ \ No newline at end of file diff --git a/srsue/hdr/stack/upper/nas_base.h b/srsue/hdr/stack/upper/nas_base.h index 5688482d8..00b719548 100644 --- a/srsue/hdr/stack/upper/nas_base.h +++ b/srsue/hdr/stack/upper/nas_base.h @@ -73,6 +73,8 @@ protected: uint32_t mac_offset = 0; uint32_t seq_offset = 0; uint32_t bearer_id = 0; + + const std::string gw_setup_failure_str = "Failed to setup/configure GW interface"; }; } // namespace srsue diff --git a/srsue/hdr/stack/upper/nas_config.h b/srsue/hdr/stack/upper/nas_config.h index 179b0f7fa..c0444725b 100644 --- a/srsue/hdr/stack/upper/nas_config.h +++ b/srsue/hdr/stack/upper/nas_config.h @@ -13,6 +13,7 @@ #ifndef SRSUE_NAS_CONFIG_H #define SRSUE_NAS_CONFIG_H +#include "srsran/interfaces/ue_nas_interfaces.h" #include namespace srsue { @@ -34,9 +35,12 @@ public: bool force_imsi_attach; std::string eia; std::string eea; + nas_sim_args_t sim; + + // 5G args std::string ia5g; std::string ea5g; - nas_sim_args_t sim; + std::vector pdu_session_cfgs; }; } // namespace srsue diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index 2d13272b6..c6a66bfcd 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -49,7 +49,8 @@ nas_5g::nas_5g(srslog::basic_logger& logger_, srsran::task_sched_handle task_sch t3521(task_sched_.get_unique_timer()), reregistration_timer(task_sched_.get_unique_timer()), registration_proc(this), - state(logger_) + state(logger_), + pdu_session_establishment_proc(this, logger_) { // Configure timers t3502.set(t3502_duration_ms, [this](uint32_t tid) { timer_expired(tid); }); @@ -95,6 +96,10 @@ int nas_5g::init(usim_interface_nas* usim_, ea5g_caps[3] = true; } + if (init_pdu_sessions(cfg.pdu_session_cfgs) != SRSRAN_SUCCESS) { + logger.warning("Failure while configuring pdu sessions"); + } + running = true; return SRSRAN_SUCCESS; } @@ -137,6 +142,94 @@ void nas_5g::run_tti() } } +int nas_5g::write_pdu(srsran::unique_byte_buffer_t pdu) +{ + logger.info(pdu->msg, pdu->N_bytes, "DL PDU (length %d)", pdu->N_bytes); + + nas_5gs_msg nas_msg; + + if (nas_msg.unpack_outer_hdr(pdu) != SRSRAN_SUCCESS) { + logger.error("Unable to unpack outer NAS header"); + return SRSRAN_ERROR; + } + + switch (nas_msg.hdr.security_header_type) { + case nas_5gs_hdr::security_header_type_opts::plain_5gs_nas_message: + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected: + if (integrity_check(pdu.get()) == false) { + logger.error("Not handling NAS message with integrity check error"); + return SRSRAN_ERROR; + } + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered: + if (integrity_check(pdu.get()) == false) { + logger.error("Not handling NAS message with integrity check error"); + return SRSRAN_ERROR; + } else { + cipher_decrypt(pdu.get()); + } + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected_with_new_5G_nas_context: + break; + case nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered_with_new_5G_nas_context: + return SRSRAN_ERROR; + default: + logger.error("Not handling NAS message with unkown security header"); + break; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu->msg, pdu->N_bytes); + } + + logger.info(pdu->msg, pdu->N_bytes, "Decrypted DL PDU (length %d)", pdu->N_bytes); + + // Parse the message header + if (nas_msg.unpack(pdu) != SRSRAN_SUCCESS) { + logger.error("Unable to unpack complete NAS pdu"); + return SRSRAN_ERROR; + } + + switch (nas_msg.hdr.message_type) { + case msg_opts::options::registration_accept: + handle_registration_accept(nas_msg.registration_accept()); + break; + case msg_opts::options::registration_reject: + handle_registration_reject(nas_msg.registration_reject()); + break; + case msg_opts::options::authentication_request: + handle_authentication_request(nas_msg.authentication_request()); + break; + case msg_opts::options::identity_request: + handle_identity_request(nas_msg.identity_request()); + break; + case msg_opts::options::security_mode_command: + handle_security_mode_command(nas_msg.security_mode_command(), std::move(pdu)); + break; + case msg_opts::options::service_accept: + handle_service_accept(nas_msg.service_accept()); + break; + case msg_opts::options::service_reject: + handle_service_reject(nas_msg.service_reject()); + break; + case msg_opts::options::deregistration_accept_ue_terminated: + handle_deregistration_accept_ue_terminated(nas_msg.deregistration_accept_ue_terminated()); + break; + case msg_opts::options::deregistration_request_ue_terminated: + handle_deregistration_request_ue_terminated(nas_msg.deregistration_request_ue_terminated()); + break; + case msg_opts::options::dl_nas_transport: + handle_dl_nas_transport(nas_msg.dl_nas_transport()); + break; + default: + logger.error( + "Not handling NAS message type: %s (0x%02x)", nas_msg.hdr.message_type.to_string(), nas_msg.hdr.message_type); + break; + } + return SRSRAN_SUCCESS; +} + /******************************************************************************* * Senders ******************************************************************************/ @@ -199,6 +292,34 @@ int nas_5g::send_registration_request() return SRSRAN_SUCCESS; } +int nas_5g::send_registration_complete() +{ + unique_byte_buffer_t pdu = srsran::make_byte_buffer(); + if (!pdu) { + logger.error("Couldn't allocate PDU in %s().", __FUNCTION__); + return SRSRAN_ERROR; + } + + logger.info("Generating Registration Complete"); + + nas_5gs_msg nas_msg; + registration_complete_t& reg_comp = nas_msg.set_registration_complete(); + + if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack registration complete."); + return SRSRAN_ERROR; + } + + if (pcap != nullptr) { + pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); + } + + logger.info("Sending Registration Complete"); + rrc_nr->write_sdu(std::move(pdu)); + + return SRSRAN_SUCCESS; +} + int nas_5g::send_authentication_response(const uint8_t res[16]) { unique_byte_buffer_t pdu = srsran::make_byte_buffer(); @@ -224,11 +345,6 @@ int nas_5g::send_authentication_response(const uint8_t res[16]) pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); } - // if (apply_security_config(pdu, current_sec_hdr) != SRSASN_SUCCESS) { - // logger.error("Error applying NAS security."); - // return SRSRAN_ERROR; - // } - logger.info("Sending Authentication Response"); rrc_nr->write_sdu(std::move(pdu)); @@ -261,16 +377,6 @@ int nas_5g::send_security_mode_reject(const cause_5gmm_t::cause_5gmm_type_::opti return SRSRAN_SUCCESS; } -void copy_msg_to_buffer(unique_byte_buffer_t& pdu, const_byte_span msg) -{ - pdu = srsran::make_byte_buffer(); - if (pdu == nullptr) { - srslog::fetch_basic_logger("ALL").error("Couldn't allocate PDU in %s().", __FUNCTION__); - return; - } - memcpy(pdu->msg, msg.data(), msg.size()); - pdu->N_bytes = msg.size(); -} int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_command_t& security_mode_command) { @@ -339,7 +445,7 @@ int nas_5g::send_security_mode_complete(const srsran::nas_5g::security_mode_comm logger.info("Sending Security Mode Complete"); rrc_nr->write_sdu(std::move(pdu)); - ctxt.rx_count++; + ctxt.tx_count++; return SRSRAN_SUCCESS; } @@ -371,7 +477,30 @@ int nas_5g::send_authentication_failure(const cause_5gmm_t::cause_5gmm_type_::op return SRSRAN_SUCCESS; } -int nas_5g::send_registration_complete() +uint32_t nas_5g::allocate_next_proc_trans_id() +{ + uint32_t i = 0; + for (auto pdu_trans_id : pdu_trans_ids) { + i++; + if (pdu_trans_id == false) { + pdu_trans_id = true; + } + } + // TODO if Trans ID exhausted + return i; +} + +void nas_5g::release_proc_trans_id(uint32_t proc_id) +{ + if (proc_id < MAX_TRANS_ID) { + pdu_trans_ids[proc_id] = false; + } + return; +} + +int nas_5g::send_pdu_session_establishment_request(uint32_t transaction_identity, + uint16_t pdu_session_id, + const pdu_session_cfg_t& pdu_session_cfg) { unique_byte_buffer_t pdu = srsran::make_byte_buffer(); if (!pdu) { @@ -379,13 +508,64 @@ int nas_5g::send_registration_complete() return SRSRAN_ERROR; } - logger.info("Generating Registration Complete"); + logger.info("Generating PDU Session Establishment Request"); - nas_5gs_msg nas_msg; - registration_complete_t& reg_comp = nas_msg.set_registration_complete(); + nas_5gs_msg nas_msg; + nas_msg.hdr.pdu_session_identity = pdu_session_id; + nas_msg.hdr.procedure_transaction_identity = transaction_identity; - if (nas_msg.pack(pdu) != SRSASN_SUCCESS) { - logger.error("Failed to pack registration complete."); + pdu_session_establishment_request_t& pdu_ses_est_req = nas_msg.set_pdu_session_establishment_request(); + pdu_ses_est_req.integrity_protection_maximum_data_rate.max_data_rate_upip_downlink = + integrity_protection_maximum_data_rate_t::max_data_rate_UPIP_downlink_type_::options::full_data_rate; + pdu_ses_est_req.integrity_protection_maximum_data_rate.max_data_rate_upip_uplink = + integrity_protection_maximum_data_rate_t::max_data_rate_UPIP_uplink_type_::options::full_data_rate; + + pdu_ses_est_req.pdu_session_type_present = true; + pdu_ses_est_req.pdu_session_type.pdu_session_type_value = + static_cast(pdu_session_cfg.apn_type); + + pdu_ses_est_req.ssc_mode_present = true; + pdu_ses_est_req.ssc_mode.ssc_mode_value = ssc_mode_t::SSC_mode_value_type_::options::ssc_mode_1; + + // TODO set the capability and extended protocol configuration + pdu_ses_est_req.capability_5gsm_present = false; + pdu_ses_est_req.extended_protocol_configuration_options_present = false; + + // Build up the Envelope for the PDU session request + nas_5gs_msg env_nas_msg; + env_nas_msg.hdr.security_header_type = nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered; + + // TODO move that seq number setting to the security part + env_nas_msg.hdr.sequence_number = ctxt.tx_count; + + ul_nas_transport_t& ul_nas_msg = env_nas_msg.set_ul_nas_transport(); + ul_nas_msg.payload_container_type.payload_container_type.value = + payload_container_type_t::Payload_container_type_type_::options::n1_sm_information; + + // Pack the pdu session est request into the envelope + if (nas_msg.pack(ul_nas_msg.payload_container.payload_container_contents) != SRSASN_SUCCESS) { + logger.error("Failed to pack PDU Session Establishment Request."); + return SRSRAN_ERROR; + } + + ul_nas_msg.pdu_session_id_present = true; + ul_nas_msg.pdu_session_id.pdu_session_identity_2_value = pdu_session_id; + + ul_nas_msg.request_type_present = true; + ul_nas_msg.request_type.request_type_value = request_type_t::Request_type_value_type_::options::initial_request; + + ul_nas_msg.s_nssai_present = true; + ul_nas_msg.s_nssai.type = s_nssai_t::SST_type_::options::sst; + ul_nas_msg.s_nssai.sst = 1; + + ul_nas_msg.dnn_present = true; + ul_nas_msg.dnn.dnn_value.resize(pdu_session_cfg.apn_name.size() + 1); + ul_nas_msg.dnn.dnn_value.data()[0] = static_cast(pdu_session_cfg.apn_name.size()); + + memcpy(ul_nas_msg.dnn.dnn_value.data() + 1, pdu_session_cfg.apn_name.data(), pdu_session_cfg.apn_name.size()); + + if (env_nas_msg.pack(pdu) != SRSASN_SUCCESS) { + logger.error("Failed to pack UL NAS transport."); return SRSRAN_ERROR; } @@ -393,235 +573,55 @@ int nas_5g::send_registration_complete() pcap->write_nas(pdu.get()->msg, pdu.get()->N_bytes); } - logger.info("Sending Registration Complete"); + cipher_encrypt(pdu.get()); + integrity_generate(&k_nas_int[16], + ctxt.tx_count, + SECURITY_DIRECTION_UPLINK, + &pdu->msg[SEQ_5G_OFFSET], + pdu->N_bytes - SEQ_5G_OFFSET, + &pdu->msg[MAC_5G_OFFSET]); + + logger.info("Sending PDU Session Establishment Complete in UL NAS transport."); rrc_nr->write_sdu(std::move(pdu)); return SRSRAN_SUCCESS; } -int nas_5g::write_pdu(srsran::unique_byte_buffer_t pdu) +// Message handler +int nas_5g::handle_registration_accept(registration_accept_t& registration_accept) { - logger.info(pdu->msg, pdu->N_bytes, "DL PDU (length %d)", pdu->N_bytes); - - nas_5gs_msg nas_msg; - - if (nas_msg.unpack_outer_hdr(pdu) != SRSRAN_SUCCESS) { - logger.error("Unable to unpack outer NAS header"); + if (state.get_state() != mm5g_state_t::state_t::registered_initiated) { + logger.warning("Not compatibale with current state %s", state.get_full_state_text()); return SRSRAN_ERROR; } - switch (nas_msg.hdr.security_header_type) { - case nas_5gs_hdr::security_header_type_opts::plain_5gs_nas_message: - break; - case nas_5gs_hdr::security_header_type_opts::integrity_protected: - if (integrity_check(pdu.get()) == false) { - logger.error("Not handling NAS message with integrity check error"); - return SRSRAN_ERROR; - } - break; - case nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered: - if (integrity_check(pdu.get()) == false) { - logger.error("Not handling NAS message with integrity check error"); - return SRSRAN_ERROR; - } else { - cipher_decrypt(pdu.get()); - } - break; - case nas_5gs_hdr::security_header_type_opts::integrity_protected_with_new_5G_nas_context: - break; - case nas_5gs_hdr::security_header_type_opts::integrity_protected_and_ciphered_with_new_5G_nas_context: - return SRSRAN_ERROR; - default: - logger.error("Not handling NAS message with unkown security header"); - break; - } - - if (pcap != nullptr) { - pcap->write_nas(pdu->msg, pdu->N_bytes); + bool send_reg_complete = false; + logger.info("Handling Registration Accept"); + if (registration_accept.guti_5g_present) { + guti_5g = registration_accept.guti_5g.guti_5g(); + send_reg_complete = true; } - logger.info(pdu->msg, pdu->N_bytes, "Decrypted DL PDU (length %d)", pdu->N_bytes); + // TODO: reset counters and everything what is needed by the specification + t3521.set(registration_accept.t3512_value.timer_value); + registration_proc.run(); + state.set_registered(mm5g_state_t::registered_substate_t::normal_service); - // Parse the message header - if (nas_msg.unpack(pdu) != SRSRAN_SUCCESS) { - logger.error("Unable to unpack complete NAS pdu"); - return SRSRAN_ERROR; + if (send_reg_complete == true) { + send_registration_complete(); } + // TODO: use the state machine to trigger that transition + trigger_pdu_session_est(); + return SRSRAN_SUCCESS; +} - switch (nas_msg.hdr.message_type) { - case msg_opts::options::registration_accept: - handle_registration_accept(nas_msg.registration_accept()); - break; - case msg_opts::options::registration_reject: - handle_registration_reject(nas_msg.registration_reject()); - break; - case msg_opts::options::authentication_request: - handle_authentication_request(nas_msg.authentication_request()); - break; - case msg_opts::options::identity_request: - handle_identity_request(nas_msg.identity_request()); - break; - case msg_opts::options::security_mode_command: - handle_security_mode_command(nas_msg.security_mode_command(), std::move(pdu)); - break; - case msg_opts::options::service_accept: - handle_service_accept(nas_msg.service_accept()); - break; - case msg_opts::options::service_reject: - handle_service_reject(nas_msg.service_reject()); - break; - case msg_opts::options::deregistration_accept_ue_terminated: - handle_deregistration_accept_ue_terminated(nas_msg.deregistration_accept_ue_terminated()); - break; - case msg_opts::options::deregistration_request_ue_terminated: - handle_deregistration_request_ue_terminated(nas_msg.deregistration_request_ue_terminated()); - break; - default: - logger.error( - "Not handling NAS message type: %s (0x%02x)", nas_msg.hdr.message_type.to_string(), nas_msg.hdr.message_type); - break; - } +int nas_5g::handle_registration_reject(registration_reject_t& registration_reject) +{ + logger.info("Handling Registration Reject"); return SRSRAN_SUCCESS; } -void nas_5g::fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps) -{ - if (ia5g_caps[0] == true) { - sec_caps.ia0_5g_supported = true; - } - if (ia5g_caps[1] == true) { - sec_caps.ia1_128_5g_supported = true; - } - if (ia5g_caps[2] == true) { - sec_caps.ia2_128_5g_supported = true; - } - if (ia5g_caps[3] == true) { - sec_caps.ia3_128_5g_supported = true; - } - if (ia5g_caps[4] == true) { - sec_caps.ia4_5g_supported = true; - } - if (ia5g_caps[5] == true) { - sec_caps.ia5_5g_supported = true; - } - if (ia5g_caps[6] == true) { - sec_caps.ia6_5g_supported = true; - } - if (ia5g_caps[7] == true) { - sec_caps.ia7_5g_supported = true; - } - - if (ea5g_caps[0] == true) { - sec_caps.ea0_5g_supported = true; - } - if (ea5g_caps[1] == true) { - sec_caps.ea1_128_5g_supported = true; - } - if (ea5g_caps[2] == true) { - sec_caps.ea2_128_5g_supported = true; - } - if (ea5g_caps[3] == true) { - sec_caps.ea3_128_5g_supported = true; - } - if (ea5g_caps[4] == true) { - sec_caps.ea4_5g_supported = true; - } - if (ea5g_caps[5] == true) { - sec_caps.ea5_5g_supported = true; - } - if (ea5g_caps[6] == true) { - sec_caps.ea6_5g_supported = true; - } - if (ea5g_caps[7] == true) { - sec_caps.ea7_5g_supported = true; - } -} -/******************************************************************************* - * UE Stack and RRC common Interface - ******************************************************************************/ -bool nas_5g::is_registered() -{ - return state.get_state() == mm5g_state_t::state_t::registered; -} - -/******************************************************************************* - * NAS Timers - ******************************************************************************/ -void nas_5g::timer_expired(uint32_t timeout_id) -{ - // TODO -} - -/******************************************************************************* - * UE Stack Interface - ******************************************************************************/ -int nas_5g::switch_on() -{ - logger.info("Switching on"); - state.set_deregistered(mm5g_state_t::deregistered_substate_t::plmn_search); - return SRSRAN_SUCCESS; -} - -int nas_5g::switch_off() -{ - logger.info("Switching off"); - // TODO - return SRSRAN_SUCCESS; -} - -int nas_5g::enable_data() -{ - logger.info("Enabling data services"); - return switch_on(); -} - -int nas_5g::disable_data() -{ - logger.info("Disabling data services"); - // TODO - return SRSRAN_SUCCESS; -} - -int nas_5g::start_service_request() -{ - logger.info("Service Request"); - // TODO - return SRSRAN_SUCCESS; -} - -// Message handler - -int nas_5g::handle_registration_accept(registration_accept_t& registration_accept) -{ - if (state.get_state() != mm5g_state_t::state_t::registered_initiated) { - logger.warning("Not compatibale with current state %s", state.get_full_state_text()); - return SRSRAN_ERROR; - } - - bool send_reg_complete = false; - logger.info("Handling Registration Accept"); - if (registration_accept.guti_5g_present) { - guti_5g = registration_accept.guti_5g.guti_5g(); - send_reg_complete = true; - } - - if (send_reg_complete == true) { - send_registration_complete(); - } - - // TODO: reset counters and everything what is needed by the specification - t3521.set(registration_accept.t3512_value.timer_value); - registration_proc.run(); - state.set_registered(mm5g_state_t::registered_substate_t::normal_service); - return SRSRAN_SUCCESS; -} - -int nas_5g::handle_registration_reject(registration_reject_t& registration_reject) -{ - logger.info("Handling Registration Reject"); - return SRSRAN_SUCCESS; -} -int nas_5g::handle_authentication_request(authentication_request_t& authentication_request) +int nas_5g::handle_authentication_request(authentication_request_t& authentication_request) { logger.info("Handling Registration Request"); @@ -742,12 +742,14 @@ int nas_5g::handle_security_mode_command(security_mode_command_t& security_m ctxt.rx_count++; return SRSRAN_SUCCESS; } + int nas_5g::handle_deregistration_accept_ue_terminated( deregistration_accept_ue_terminated_t& deregistration_accept_ue_terminated) { logger.info("Handling Deregistration Accept UE Terminated"); return SRSRAN_SUCCESS; } + int nas_5g::handle_deregistration_request_ue_terminated( deregistration_request_ue_terminated_t& deregistration_request_ue_terminated) { @@ -755,4 +757,277 @@ int nas_5g::handle_deregistration_request_ue_terminated( return SRSRAN_SUCCESS; } +int nas_5g::handle_dl_nas_transport(srsran::nas_5g::dl_nas_transport_t& dl_nas_transport) +{ + logger.info("Handling DL NAS transport"); + switch (dl_nas_transport.payload_container_type.payload_container_type) { + case payload_container_type_t::Payload_container_type_type_::options::n1_sm_information: + return handle_n1_sm_information(dl_nas_transport.payload_container.payload_container_contents); + break; + default: + logger.warning("Not handling payload container %x", + dl_nas_transport.payload_container_type.payload_container_type.value); + break; + } + return SRSRAN_SUCCESS; +} + +int nas_5g::handle_n1_sm_information(std::vector payload_container_contents) +{ + logger.info(payload_container_contents.data(), + payload_container_contents.size(), + "Payload contents (length %d)", + payload_container_contents.size()); + + nas_5gs_msg nas_msg; + nas_msg.unpack(payload_container_contents); + + switch (nas_msg.hdr.message_type) { + case msg_opts::options::pdu_session_establishment_accept: + pdu_session_establishment_proc.trigger(nas_msg.pdu_session_establishment_accept()); + break; + case msg_opts::options::pdu_session_establishment_reject: + pdu_session_establishment_proc.trigger(nas_msg.pdu_session_establishment_reject()); + break; + default: + logger.error( + "Not handling NAS message type: %s (0x%02x)", nas_msg.hdr.message_type.to_string(), nas_msg.hdr.message_type); + break; + } + return SRSRAN_SUCCESS; +} + +/******************************************************************************* + * NAS Timers + ******************************************************************************/ +void nas_5g::timer_expired(uint32_t timeout_id) +{ + // TODO +} + +/******************************************************************************* + * UE Stack & RRC Interface + ******************************************************************************/ +bool nas_5g::is_registered() +{ + return state.get_state() == mm5g_state_t::state_t::registered; +} + +int nas_5g::switch_on() +{ + logger.info("Switching on"); + state.set_deregistered(mm5g_state_t::deregistered_substate_t::plmn_search); + return SRSRAN_SUCCESS; +} + +int nas_5g::switch_off() +{ + logger.info("Switching off"); + // TODO + return SRSRAN_SUCCESS; +} + +int nas_5g::enable_data() +{ + logger.info("Enabling data services"); + return switch_on(); +} + +int nas_5g::disable_data() +{ + logger.info("Disabling data services"); + // TODO + return SRSRAN_SUCCESS; +} + +int nas_5g::start_service_request() +{ + logger.info("Service Request"); + // TODO + return SRSRAN_SUCCESS; +} + +/******************************************************************************* + * Helpers + ******************************************************************************/ + +void nas_5g::fill_security_caps(srsran::nas_5g::ue_security_capability_t& sec_caps) +{ + if (ia5g_caps[0] == true) { + sec_caps.ia0_5g_supported = true; + } + if (ia5g_caps[1] == true) { + sec_caps.ia1_128_5g_supported = true; + } + if (ia5g_caps[2] == true) { + sec_caps.ia2_128_5g_supported = true; + } + if (ia5g_caps[3] == true) { + sec_caps.ia3_128_5g_supported = true; + } + if (ia5g_caps[4] == true) { + sec_caps.ia4_5g_supported = true; + } + if (ia5g_caps[5] == true) { + sec_caps.ia5_5g_supported = true; + } + if (ia5g_caps[6] == true) { + sec_caps.ia6_5g_supported = true; + } + if (ia5g_caps[7] == true) { + sec_caps.ia7_5g_supported = true; + } + + if (ea5g_caps[0] == true) { + sec_caps.ea0_5g_supported = true; + } + if (ea5g_caps[1] == true) { + sec_caps.ea1_128_5g_supported = true; + } + if (ea5g_caps[2] == true) { + sec_caps.ea2_128_5g_supported = true; + } + if (ea5g_caps[3] == true) { + sec_caps.ea3_128_5g_supported = true; + } + if (ea5g_caps[4] == true) { + sec_caps.ea4_5g_supported = true; + } + if (ea5g_caps[5] == true) { + sec_caps.ea5_5g_supported = true; + } + if (ea5g_caps[6] == true) { + sec_caps.ea6_5g_supported = true; + } + if (ea5g_caps[7] == true) { + sec_caps.ea7_5g_supported = true; + } +} + +/******************************************************************************* + * Helpers for Session Management + ******************************************************************************/ + +int nas_5g::trigger_pdu_session_est() +{ + if (unestablished_pdu_sessions() == true) { + pdu_session_cfg_t pdu_session_cfg; + uint16_t pdu_session_id; + get_unestablished_pdu_session(pdu_session_id, pdu_session_cfg); + pdu_session_establishment_proc.launch(pdu_session_id, pdu_session_cfg); + } + return SRSRAN_SUCCESS; +} + +int nas_5g::init_pdu_sessions(std::vector pdu_session_cfgs) +{ + uint16_t i = 0; + for (auto pdu_session_cfg : pdu_session_cfgs) { + pdu_sessions[i].configured = true; + pdu_sessions[i].pdu_session_id = i + 1; + pdu_sessions[i].pdu_session_cfg = pdu_session_cfg; + } + return SRSRAN_SUCCESS; +} + +int nas_5g::configure_pdu_session(uint16_t pdu_session_id) +{ + for (auto pdu_session : pdu_sessions) { + if (pdu_session.pdu_session_id == pdu_session_id) { + pdu_session.established = true; + } + } + return SRSRAN_SUCCESS; +} + +bool nas_5g::unestablished_pdu_sessions() +{ + for (auto pdu_session : pdu_sessions) { + if (pdu_session.configured == true && pdu_session.established == false) { + return true; + } + } + return false; +} + +int nas_5g::get_unestablished_pdu_session(uint16_t& pdu_session_id, pdu_session_cfg_t& pdu_session_cfg) +{ + for (auto pdu_session : pdu_sessions) { + if (pdu_session.configured == true && pdu_session.established == false) { + pdu_session_id = pdu_session.pdu_session_id; + pdu_session_cfg = pdu_session.pdu_session_cfg; + } + } + return SRSRAN_SUCCESS; +} + +int nas_5g::add_pdu_session(uint16_t pdu_session_id, + uint16_t pdu_session_type, + srsran::nas_5g::pdu_address_t pdu_address) +{ + char* err_str = nullptr; + + // Copy IPv4 + uint32_t ip_addr = 0; + + ip_addr |= pdu_address.ipv4.data()[0] << 24u; + ip_addr |= pdu_address.ipv4.data()[1] << 16u; + ip_addr |= pdu_address.ipv4.data()[2] << 8u; + ip_addr |= pdu_address.ipv4.data()[3]; + + // Copy IPv6 + uint8_t ipv6_if_id[8] = {}; + memcpy(ipv6_if_id, pdu_address.ipv6.data(), 8); + + if (!(pdu_session_type == LIBLTE_MME_PDN_TYPE_IPV4V6 || pdu_session_type == LIBLTE_MME_PDN_TYPE_IPV4 || + pdu_session_type == LIBLTE_MME_PDN_TYPE_IPV6)) { + logger.warning("PDU session typed expected to be of IPV4 or IPV6 or IPV4V6"); + return SRSRAN_ERROR; + } + + if (gw->setup_if_addr(pdu_session_id, pdu_session_type, ip_addr, ipv6_if_id, err_str)) { + logger.error("%s - %s", gw_setup_failure_str.c_str(), err_str ? err_str : ""); + srsran::console("%s\n", gw_setup_failure_str.c_str()); + return SRSRAN_ERROR; + } + + if (pdu_session_type == LIBLTE_MME_PDN_TYPE_IPV4V6 || pdu_session_type == LIBLTE_MME_PDN_TYPE_IPV4) { + logger.info("PDU Session Establishment successful. IP: %u.%u.%u.%u", + pdu_address.ipv4.data()[0], + pdu_address.ipv4.data()[1], + pdu_address.ipv4.data()[2], + pdu_address.ipv4.data()[3]); + + srsran::console("PDU Session Establishment successful. IP: %u.%u.%u.%u\n", + pdu_address.ipv4.data()[0], + pdu_address.ipv4.data()[1], + pdu_address.ipv4.data()[2], + pdu_address.ipv4.data()[3]); + } + + if (pdu_session_type == LIBLTE_MME_PDN_TYPE_IPV4V6 || pdu_session_type == LIBLTE_MME_PDN_TYPE_IPV6) { + logger.info("PDU Session Establishment successful. IPv6 interface id: %02x%02x:%02x%02x:%02x%02x:%02x%02x", + pdu_address.ipv6.data()[0], + pdu_address.ipv6.data()[1], + pdu_address.ipv6.data()[2], + pdu_address.ipv6.data()[3], + pdu_address.ipv6.data()[4], + pdu_address.ipv6.data()[5], + pdu_address.ipv6.data()[6], + pdu_address.ipv6.data()[7]); + + srsran::console("PDU Session Establishment successful. IPv6 interface id: %02x%02x:%02x%02x:%02x%02x:%02x%02x\n", + pdu_address.ipv6.data()[0], + pdu_address.ipv6.data()[1], + pdu_address.ipv6.data()[2], + pdu_address.ipv6.data()[3], + pdu_address.ipv6.data()[4], + pdu_address.ipv6.data()[5], + pdu_address.ipv6.data()[6], + pdu_address.ipv6.data()[7]); + } + + return SRSRAN_SUCCESS; +} + } // namespace srsue \ No newline at end of file diff --git a/srsue/src/stack/upper/nas_5g_procedures.cc b/srsue/src/stack/upper/nas_5g_procedures.cc index 577095cc4..2ce2281af 100644 --- a/srsue/src/stack/upper/nas_5g_procedures.cc +++ b/srsue/src/stack/upper/nas_5g_procedures.cc @@ -35,5 +35,54 @@ srsran::proc_outcome_t nas_5g::registration_procedure::step() return srsran::proc_outcome_t::success; } +// PDU Sessions Establishment Procedure +nas_5g::pdu_session_establishment_procedure::pdu_session_establishment_procedure( + nas_5g_interface_procedures* parent_nas_, + srslog::basic_logger& logger_) : + logger(logger_), parent_nas(parent_nas_) +{} + +srsran::proc_outcome_t nas_5g::pdu_session_establishment_procedure::init(const uint16_t pdu_session_id_, + const pdu_session_cfg_t pdu_session_cfg) +{ + // Get PDU transaction identity + transaction_identity = parent_nas->allocate_next_proc_trans_id(); + pdu_session_id = pdu_session_id_; + parent_nas->send_pdu_session_establishment_request(transaction_identity, pdu_session_id, pdu_session_cfg); + + return srsran::proc_outcome_t::yield; +} + +srsran::proc_outcome_t nas_5g::pdu_session_establishment_procedure::react( + const srsran::nas_5g::pdu_session_establishment_accept_t& pdu_session_est_accept) +{ + // TODO check the pdu session values + if (pdu_session_est_accept.dnn_present == false) { + logger.warning("Expected DNN in PDU session establishment accept"); + return proc_outcome_t::error; + } + if (pdu_session_est_accept.pdu_address_present == false) { + logger.warning("Expected PDU Address in PDU session establishment accept"); + return proc_outcome_t::error; + } + if (parent_nas->add_pdu_session(pdu_session_id, + pdu_session_est_accept.selected_pdu_session_type.pdu_session_type_value, + pdu_session_est_accept.pdu_address) != SRSRAN_SUCCESS) { + logger.warning("Adding PDU session failed\n"); + return srsran::proc_outcome_t::error; + } + return srsran::proc_outcome_t::success; +} + +srsran::proc_outcome_t nas_5g::pdu_session_establishment_procedure::react( + const srsran::nas_5g::pdu_session_establishment_reject_t& session_est_reject) +{ + return srsran::proc_outcome_t::success; +} + +srsran::proc_outcome_t nas_5g::pdu_session_establishment_procedure::step() +{ + return srsran::proc_outcome_t::success; +} } // namespace srsue \ No newline at end of file From 43915550cc5e4b93d3ff22b78da7a91d2d462db0 Mon Sep 17 00:00:00 2001 From: Bedran Karakoc Date: Wed, 8 Sep 2021 01:47:58 +0200 Subject: [PATCH 13/83] NGAP GTP Bearer Establishment --- .../srsran/interfaces/gnb_rrc_nr_interfaces.h | 14 ++- srsenb/hdr/stack/ngap/ngap.h | 4 +- srsenb/hdr/stack/ngap/ngap_interfaces.h | 6 ++ srsenb/hdr/stack/ngap/ngap_ue.h | 14 ++- .../hdr/stack/ngap/ngap_ue_bearer_manager.h | 69 ++++++++++++++ srsenb/hdr/stack/ngap/ngap_ue_proc.h | 14 ++- srsenb/hdr/stack/rrc/rrc_nr.h | 3 + srsenb/src/stack/ngap/CMakeLists.txt | 2 +- srsenb/src/stack/ngap/ngap.cc | 19 +++- srsenb/src/stack/ngap/ngap_ue.cc | 52 +++++++++- .../src/stack/ngap/ngap_ue_bearer_manager.cc | 93 ++++++++++++++++++ srsenb/src/stack/ngap/ngap_ue_proc.cc | 94 ++++++++++++++----- srsenb/src/stack/rrc/rrc_nr.cc | 14 +++ srsenb/test/ngap/ngap_test.cc | 16 +++- srsue/hdr/stack/upper/nas_5g.h | 4 + srsue/src/stack/upper/nas_5g.cc | 2 +- 16 files changed, 372 insertions(+), 48 deletions(-) create mode 100644 srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h create mode 100644 srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc diff --git a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h index fbb5062ac..8bf153fc8 100644 --- a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h @@ -19,11 +19,15 @@ namespace srsenb { class rrc_interface_ngap_nr { public: - virtual int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) = 0; - virtual int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) = 0; - virtual int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) = 0; - virtual int start_security_mode_procedure(uint16_t rnti) = 0; - virtual void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) = 0; + virtual int ue_set_security_cfg_key(uint16_t rnti, const asn1::fixed_bitstring<256, false, true>& key) = 0; + virtual int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) = 0; + virtual int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) = 0; + virtual int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) = 0; + virtual int start_security_mode_procedure(uint16_t rnti) = 0; + virtual int + establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) = 0; + virtual int allocate_lcid(uint16_t rnti) = 0; + virtual void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) = 0; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/ngap/ngap.h b/srsenb/hdr/stack/ngap/ngap.h index 5e1112b56..87f7415e1 100644 --- a/srsenb/hdr/stack/ngap/ngap.h +++ b/srsenb/hdr/stack/ngap/ngap.h @@ -28,6 +28,7 @@ #include "srsran/common/threads.h" #include "srsran/interfaces/gnb_ngap_interfaces.h" #include "srsran/interfaces/gnb_rrc_nr_interfaces.h" +#include "srsran/interfaces/enb_gtpu_interfaces.h" #include "srsran/srslog/srslog.h" #include #include @@ -42,7 +43,7 @@ public: srslog::basic_logger& logger, srsran::socket_manager_itf* rx_socket_handler); ~ngap(); - int init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_); + int init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_, gtpu_interface_rrc* gtpu_); void stop(); // RRC NR interface @@ -84,6 +85,7 @@ private: // args rrc_interface_ngap_nr* rrc = nullptr; + gtpu_interface_rrc* gtpu = nullptr; ngap_args_t args = {}; srslog::basic_logger& logger; srsran::task_sched_handle task_sched; diff --git a/srsenb/hdr/stack/ngap/ngap_interfaces.h b/srsenb/hdr/stack/ngap/ngap_interfaces.h index 4740a8c2c..44cd77425 100644 --- a/srsenb/hdr/stack/ngap/ngap_interfaces.h +++ b/srsenb/hdr/stack/ngap/ngap_interfaces.h @@ -13,11 +13,17 @@ #ifndef SRSENB_NGAP_INTERFACES_H #define SRSENB_NGAP_INTERFACES_H +#include "srsran/asn1/ngap_utils.h" + namespace srsenb { class ngap_interface_ngap_proc { public: virtual bool send_initial_ctxt_setup_response() = 0; + virtual bool + send_pdu_session_resource_setup_response(uint16_t pdu_session_id, + uint32_t teid_out, + asn1::bounded_bitstring<1, 160, true, true> transport_layer_address) = 0; }; } // namespace srsenb diff --git a/srsenb/hdr/stack/ngap/ngap_ue.h b/srsenb/hdr/stack/ngap/ngap_ue.h index cbf2550a3..3cf651b91 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue.h +++ b/srsenb/hdr/stack/ngap/ngap_ue.h @@ -13,16 +13,21 @@ #define SRSENB_NGAP_UE_H #include "ngap.h" +#include "ngap_ue_bearer_manager.h" #include "ngap_ue_proc.h" #include "ngap_ue_utils.h" #include "srsran/asn1/asn1_utils.h" #include "srsran/asn1/ngap.h" +#include "srsran/interfaces/enb_gtpu_interfaces.h" namespace srsenb { class ngap::ue : public ngap_interface_ngap_proc { public: - explicit ue(ngap* ngap_ptr_, rrc_interface_ngap_nr* rrc_ptr_, srslog::basic_logger& logger_); + explicit ue(ngap* ngap_ptr_, + rrc_interface_ngap_nr* rrc_ptr_, + gtpu_interface_rrc* gtpu_ptr_, + srslog::basic_logger& logger_); virtual ~ue(); // TS 38.413 - Section 9.2.5.1 - Initial UE Message bool send_initial_ue_message(asn1::ngap_nr::rrcestablishment_cause_e cause, @@ -35,6 +40,10 @@ public: bool send_initial_ctxt_setup_response(); // TS 38.413 - Section 9.2.2.3 - Initial Context Setup Failure bool send_initial_ctxt_setup_failure(asn1::ngap_nr::cause_c cause); + // TS 38.413 - Section 9.2.1.2 - PDU Session Resource Setup Response + bool send_pdu_session_resource_setup_response(uint16_t pdu_session_id, + uint32_t teid_out, + asn1::bounded_bitstring<1, 160, true, true> transport_layer_address); // TS 38.413 - Section 9.2.2.1 - Initial Context Setup Request bool handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg); // TS 38.413 - Section 9.2.2.5 - UE Context Release Command @@ -54,7 +63,8 @@ private: ngap* ngap_ptr = nullptr; // state - bool release_requested = false; + bool release_requested = false; + ngap_ue_bearer_manager bearer_manager; // logger srslog::basic_logger& logger; diff --git a/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h b/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h new file mode 100644 index 000000000..94031deae --- /dev/null +++ b/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h @@ -0,0 +1,69 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSENB_NGAP_UE_BEARER_MANAGER_H +#define SRSENB_NGAP_UE_BEARER_MANAGER_H + +#include "srsran/asn1/asn1_utils.h" +#include "srsran/asn1/ngap.h" +#include "srsran/config.h" +#include "srsran/interfaces/enb_gtpu_interfaces.h" +#include "srsran/interfaces/gnb_rrc_nr_interfaces.h" + +namespace srsenb { + +/** + * @brief Manages the GTPU bearers as part of the NGAP session procedures + * */ + +class ngap_ue_bearer_manager +{ +public: + struct pdu_session_t { + struct gtpu_tunnel { + uint32_t teid_out = 0; + uint32_t teid_in = 0; + asn1::bounded_bitstring<1, 160, true, true> address; + }; + uint8_t id = 0; + uint8_t lcid = 0; + asn1::ngap_nr::qos_flow_level_qos_params_s qos_params; + std::vector tunnels; + }; + + ngap_ue_bearer_manager(rrc_interface_ngap_nr* rrc_, gtpu_interface_rrc* gtpu_, srslog::basic_logger& logger_); + ~ngap_ue_bearer_manager(); + + int add_pdu_session(uint16_t rnti, + uint8_t pdu_session_id, + const asn1::ngap_nr::qos_flow_level_qos_params_s& qos, + const asn1::bounded_bitstring<1, 160, true, true>& addr, + uint32_t teid_out, + asn1::ngap_nr::cause_c& cause); + +private: + gtpu_interface_rrc* gtpu = nullptr; + rrc_interface_ngap_nr* rrc = nullptr; + std::map pdu_session_list; + srslog::basic_logger& logger; + + int add_gtpu_bearer(uint16_t rnti, + uint32_t lcid, + uint32_t pdu_session_id, + uint32_t teid_out, + asn1::bounded_bitstring<1, 160, true, true> address, + pdu_session_t::gtpu_tunnel& tunnel, // out parameter + const gtpu_interface_rrc::bearer_props* props = nullptr); + void rem_gtpu_bearer(uint16_t rnti, uint32_t pdu_session_id); +}; +} // namespace srsenb +#endif // SRSENB_NGAP_UE_BEARER_MANAGER_H \ No newline at end of file diff --git a/srsenb/hdr/stack/ngap/ngap_ue_proc.h b/srsenb/hdr/stack/ngap/ngap_ue_proc.h index a549a24d3..71ddd58a0 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue_proc.h +++ b/srsenb/hdr/stack/ngap/ngap_ue_proc.h @@ -21,6 +21,7 @@ #include "srsran/common/buffer_pool.h" #include "srsran/common/stack_procedure.h" #include "srsran/interfaces/gnb_rrc_nr_interfaces.h" +#include "srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h" #include #include @@ -35,7 +36,8 @@ class ngap_ue_initial_context_setup_proc public: explicit ngap_ue_initial_context_setup_proc(ngap_interface_ngap_proc* parent_, rrc_interface_ngap_nr* rrc_, - ngap_ue_ctxt_t* ue_ctxt); + ngap_ue_ctxt_t* ue_ctxt, + srslog::basic_logger& logger_); srsran::proc_outcome_t init(const asn1::ngap_nr::init_context_setup_request_s& msg); srsran::proc_outcome_t react(const bool rrc_reconf_outcome); srsran::proc_outcome_t step(); @@ -54,7 +56,8 @@ class ngap_ue_ue_context_release_proc public: explicit ngap_ue_ue_context_release_proc(ngap_interface_ngap_proc* parent_, rrc_interface_ngap_nr* rrc_, - ngap_ue_ctxt_t* ue_ctxt); + ngap_ue_ctxt_t* ue_ctxt, + srslog::basic_logger& logger_); srsran::proc_outcome_t init(const asn1::ngap_nr::ue_context_release_cmd_s& msg); srsran::proc_outcome_t step(); static const char* name() { return "UE Context Release"; } @@ -70,7 +73,7 @@ private: class ngap_ue_ue_context_modification_proc { public: - explicit ngap_ue_ue_context_modification_proc(ngap_interface_ngap_proc* parent_); + explicit ngap_ue_ue_context_modification_proc(ngap_interface_ngap_proc* parent_, srslog::basic_logger& logger_); srsran::proc_outcome_t init(); srsran::proc_outcome_t step(); static const char* name() { return "UE Context Modification"; } @@ -84,7 +87,9 @@ class ngap_ue_pdu_session_res_setup_proc public: explicit ngap_ue_pdu_session_res_setup_proc(ngap_interface_ngap_proc* parent_, rrc_interface_ngap_nr* rrc_, - ngap_ue_ctxt_t* ue_ctxt); + ngap_ue_ctxt_t* ue_ctxt, + ngap_ue_bearer_manager* bearer_manager, + srslog::basic_logger& logger_); srsran::proc_outcome_t init(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg); srsran::proc_outcome_t step(); static const char* name() { return "UE PDU Session Resource Setup"; } @@ -92,6 +97,7 @@ public: private: ngap_ue_ctxt_t* ue_ctxt; ngap_interface_ngap_proc* parent; + ngap_ue_bearer_manager* bearer_manager; rrc_interface_ngap_nr* rrc = nullptr; srslog::basic_logger& logger; }; diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 2b5c9932e..1531be0c9 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -90,7 +90,10 @@ public: int ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates); int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps); int start_security_mode_procedure(uint16_t rnti); + int establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid); void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu); + int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates); + int allocate_lcid(uint16_t rnti); class ue { diff --git a/srsenb/src/stack/ngap/CMakeLists.txt b/srsenb/src/stack/ngap/CMakeLists.txt index 099260995..d5654ae32 100644 --- a/srsenb/src/stack/ngap/CMakeLists.txt +++ b/srsenb/src/stack/ngap/CMakeLists.txt @@ -6,5 +6,5 @@ # the distribution. # -set(SOURCES ngap.cc ngap_ue.cc ngap_ue_proc.cc) +set(SOURCES ngap.cc ngap_ue.cc ngap_ue_proc.cc ngap_ue_bearer_manager.cc) add_library(srsgnb_ngap STATIC ${SOURCES}) diff --git a/srsenb/src/stack/ngap/ngap.cc b/srsenb/src/stack/ngap/ngap.cc index 9d99e8d3a..e3660d749 100644 --- a/srsenb/src/stack/ngap/ngap.cc +++ b/srsenb/src/stack/ngap/ngap.cc @@ -21,6 +21,13 @@ using srsran::uint32_to_uint8; #define procWarning(fmt, ...) ngap_ptr->logger.warning("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) #define procInfo(fmt, ...) ngap_ptr->logger.info("Proc \"%s\" - " fmt, name(), ##__VA_ARGS__) +#define WarnUnsupportFeature(cond, featurename) \ + do { \ + if (cond) { \ + logger.warning("Not handling feature - %s", featurename); \ + } \ + } while (0) + using namespace asn1::ngap_nr; namespace srsenb { @@ -105,10 +112,11 @@ ngap::ngap(srsran::task_sched_handle task_sched_, ngap::~ngap() {} -int ngap::init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_) +int ngap::init(const ngap_args_t& args_, rrc_interface_ngap_nr* rrc_, gtpu_interface_rrc * gtpu_) { rrc = rrc_; args = args_; + gtpu = gtpu_; build_tai_cgi(); @@ -207,7 +215,7 @@ void ngap::initial_ue(uint16_t rnti, asn1::ngap_nr::rrcestablishment_cause_e cause, srsran::unique_byte_buffer_t pdu) { - std::unique_ptr ue_ptr{new ue{this, rrc, logger}}; + std::unique_ptr ue_ptr{new ue{this, rrc, gtpu, logger}}; ue_ptr->ctxt.rnti = rnti; ue_ptr->ctxt.gnb_cc_idx = gnb_cc_idx; ue* u = users.add_user(std::move(ue_ptr)); @@ -224,7 +232,7 @@ void ngap::initial_ue(uint16_t rnti, srsran::unique_byte_buffer_t pdu, uint32_t s_tmsi) { - std::unique_ptr ue_ptr{new ue{this, rrc, logger}}; + std::unique_ptr ue_ptr{new ue{this, rrc, gtpu, logger}}; ue_ptr->ctxt.rnti = rnti; ue_ptr->ctxt.gnb_cc_idx = gnb_cc_idx; ue* u = users.add_user(std::move(ue_ptr)); @@ -536,6 +544,7 @@ bool ngap::handle_ue_ctxt_release_cmd(const asn1::ngap_nr::ue_context_release_cm bool ngap::handle_ue_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg) { + ue* u = handle_ngapmsg_ue_id(msg.protocol_ies.ran_ue_ngap_id.value.value, msg.protocol_ies.amf_ue_ngap_id.value.value); if (u == nullptr) { @@ -543,7 +552,11 @@ bool ngap::handle_ue_pdu_session_res_setup_request(const asn1::ngap_nr::pdu_sess return false; } + if (msg.protocol_ies.ue_aggregate_maximum_bit_rate_present) { + rrc->set_aggregate_max_bitrate(u->ctxt.rnti, msg.protocol_ies.ue_aggregate_maximum_bit_rate.value); + } u->handle_pdu_session_res_setup_request(msg); + return true; } diff --git a/srsenb/src/stack/ngap/ngap_ue.cc b/srsenb/src/stack/ngap/ngap_ue.cc index 26a115c10..01ee89c5e 100644 --- a/srsenb/src/stack/ngap/ngap_ue.cc +++ b/srsenb/src/stack/ngap/ngap_ue.cc @@ -23,12 +23,16 @@ namespace srsenb { /* ngap_ptr::ue Class ********************************************************************************/ -ngap::ue::ue(ngap* ngap_ptr_, rrc_interface_ngap_nr* rrc_ptr_, srslog::basic_logger& logger_) : +ngap::ue::ue(ngap* ngap_ptr_, + rrc_interface_ngap_nr* rrc_ptr_, + gtpu_interface_rrc* gtpu_ptr_, + srslog::basic_logger& logger_) : logger(logger_), ngap_ptr(ngap_ptr_), - initial_context_setup_proc(this, rrc_ptr_, &ctxt), - ue_context_release_proc(this, rrc_ptr_, &ctxt), - ue_pdu_session_res_setup_proc(this, rrc_ptr_, &ctxt) + bearer_manager(rrc_ptr_, gtpu_ptr_, logger_), + initial_context_setup_proc(this, rrc_ptr_, &ctxt, logger_), + ue_context_release_proc(this, rrc_ptr_, &ctxt, logger_), + ue_pdu_session_res_setup_proc(this, rrc_ptr_, &ctxt, &bearer_manager, logger_) { ctxt.ran_ue_ngap_id = ngap_ptr->next_gnb_ue_ngap_id++; gettimeofday(&ctxt.init_timestamp, nullptr); @@ -180,6 +184,46 @@ bool ngap::ue::send_initial_ctxt_setup_failure(cause_c cause) return true; } +bool ngap::ue::send_pdu_session_resource_setup_response( + uint16_t pdu_session_id, + uint32_t teid_out, + asn1::bounded_bitstring<1, 160, true, true> transport_layer_address) +{ + if (not ngap_ptr->amf_connected) { + logger.warning("AMF not connected"); + return false; + } + // TODO: QOS Params + ngap_pdu_c tx_pdu; + tx_pdu.set_successful_outcome().load_info_obj(ASN1_NGAP_NR_ID_PDU_SESSION_RES_SETUP); + pdu_session_res_setup_resp_s& container = tx_pdu.successful_outcome().value.pdu_session_res_setup_resp(); + container.protocol_ies.amf_ue_ngap_id.value = ctxt.amf_ue_ngap_id.value(); + container.protocol_ies.ran_ue_ngap_id.value = ctxt.ran_ue_ngap_id; + container.protocol_ies.pdu_session_res_setup_list_su_res_present = true; + pdu_session_res_setup_item_su_res_s su_res; + su_res.pdu_session_res_setup_resp_transfer.resize(512); + su_res.pdu_session_id = pdu_session_id; + pdu_session_res_setup_resp_transfer_s resp_transfer; + + gtp_tunnel_s& gtp_tunnel = resp_transfer.dlqos_flow_per_tnl_info.uptransport_layer_info.set_gtp_tunnel(); + + gtp_tunnel.gtp_teid.from_number(teid_out); + gtp_tunnel.transport_layer_address = transport_layer_address; + asn1::ngap_nr::associated_qos_flow_list_l qos_flow_list; + asn1::ngap_nr::associated_qos_flow_item_s qos_flow_item; + qos_flow_item.qos_flow_id = 1; + qos_flow_list.push_back(qos_flow_item); + resp_transfer.dlqos_flow_per_tnl_info.associated_qos_flow_list = qos_flow_list; + + asn1::bit_ref bref(su_res.pdu_session_res_setup_resp_transfer.data(), + su_res.pdu_session_res_setup_resp_transfer.size()); + resp_transfer.pack(bref); + su_res.pdu_session_res_setup_resp_transfer.resize(bref.distance_bytes()); + + container.protocol_ies.pdu_session_res_setup_list_su_res.value.push_back(su_res); + return ngap_ptr->sctp_send_ngap_pdu(tx_pdu, ctxt.rnti, "PDUSessionResourceSetupResponse"); +} + /******************************************************************************* /* NGAP message handler ********************************************************************************/ diff --git a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc new file mode 100644 index 000000000..040ff341d --- /dev/null +++ b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc @@ -0,0 +1,93 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h" + +namespace srsenb { +ngap_ue_bearer_manager::ngap_ue_bearer_manager(rrc_interface_ngap_nr* rrc_, + gtpu_interface_rrc* gtpu_, + srslog::basic_logger& logger_) : + gtpu(gtpu_), rrc(rrc_), logger(logger_) +{} +ngap_ue_bearer_manager::~ngap_ue_bearer_manager(){}; + +int ngap_ue_bearer_manager::add_pdu_session(uint16_t rnti, + uint8_t pdu_session_id, + const asn1::ngap_nr::qos_flow_level_qos_params_s& qos, + const asn1::bounded_bitstring<1, 160, true, true>& addr, + uint32_t teid_out, + asn1::ngap_nr::cause_c& cause) +{ + // RRC call for QoS parameter and lcid <-> ID mapping + int lcid = rrc->allocate_lcid(rnti); + + // Only add session if gtpu was successful + pdu_session_t::gtpu_tunnel tunnel; + + if (addr.length() > 32) { + logger.error("Only addresses with length <= 32 (IPv4) are supported"); + cause.set_radio_network().value = asn1::ngap_nr::cause_radio_network_opts::invalid_qos_combination; + return SRSRAN_ERROR; + } + + // TODO long term remove lcid and just use pdu_session_id and rnti as id for GTP tunnel + + int rtn = add_gtpu_bearer(rnti, lcid, pdu_session_id, teid_out, addr, tunnel); + if (rtn != SRSRAN_SUCCESS) { + logger.error("Adding PDU Session ID=%d to GTPU", pdu_session_id); + return SRSRAN_ERROR; + } + + pdu_session_list[pdu_session_id].id = pdu_session_id; + pdu_session_list[pdu_session_id].lcid = lcid; + pdu_session_list[pdu_session_id].qos_params = qos; + pdu_session_list[pdu_session_id].tunnels.push_back(tunnel); + return SRSRAN_SUCCESS; +} + +int ngap_ue_bearer_manager::add_gtpu_bearer(uint16_t rnti, + uint32_t lcid, + uint32_t pdu_session_id, + uint32_t teid_out, + asn1::bounded_bitstring<1, 160, true, true> address, + pdu_session_t::gtpu_tunnel& tunnel, + const gtpu_interface_rrc::bearer_props* props) +{ + // Initialize ERAB tunnel in GTPU right-away. DRBs are only created during RRC setup/reconf + srsran::expected rtn = gtpu->add_bearer(rnti, lcid, address.to_number(), teid_out, props); + if (rtn.is_error()) { + logger.error("Failed adding pdu_session_id=%d to GTPU", pdu_session_id); + return SRSRAN_ERROR; + } + tunnel.teid_out = teid_out; + tunnel.address = address; + tunnel.teid_in = rtn.value(); + + logger.info("Added GTPU tunnel for rnti %x, lcid %d, pdu_session_id=%d, address %s", + rnti, + lcid, + pdu_session_id, + address.to_string()); + return SRSRAN_SUCCESS; +} + +void ngap_ue_bearer_manager::rem_gtpu_bearer(uint16_t rnti, uint32_t pdu_session_id) +{ + auto it = pdu_session_list.find(pdu_session_id); + if (it == pdu_session_list.end()) { + logger.warning("Removing pdu_session=%d from GTPU", pdu_session_id); + return; + } + gtpu->rem_bearer(rnti, it->second.lcid); +} + +} // namespace srsenb \ No newline at end of file diff --git a/srsenb/src/stack/ngap/ngap_ue_proc.cc b/srsenb/src/stack/ngap/ngap_ue_proc.cc index 739698d84..bf9aeac2e 100644 --- a/srsenb/src/stack/ngap/ngap_ue_proc.cc +++ b/srsenb/src/stack/ngap/ngap_ue_proc.cc @@ -18,13 +18,9 @@ namespace srsenb { ngap_ue_initial_context_setup_proc::ngap_ue_initial_context_setup_proc(ngap_interface_ngap_proc* parent_, rrc_interface_ngap_nr* rrc_, - ngap_ue_ctxt_t* ue_ctxt_) : - logger(srslog::fetch_basic_logger("NGAP UE")) -{ - parent = parent_; - rrc = rrc_; - ue_ctxt = ue_ctxt_; -}; + ngap_ue_ctxt_t* ue_ctxt_, + srslog::basic_logger& logger_) : + logger(logger_), parent(parent_), rrc(rrc_), ue_ctxt(ue_ctxt_){}; proc_outcome_t ngap_ue_initial_context_setup_proc::init(const asn1::ngap_nr::init_context_setup_request_s& msg) { @@ -69,8 +65,9 @@ proc_outcome_t ngap_ue_initial_context_setup_proc::step() ngap_ue_ue_context_release_proc::ngap_ue_ue_context_release_proc(ngap_interface_ngap_proc* parent_, rrc_interface_ngap_nr* rrc_, - ngap_ue_ctxt_t* ue_ctxt_) : - logger(srslog::fetch_basic_logger("NGAP UE")) + ngap_ue_ctxt_t* ue_ctxt_, + srslog::basic_logger& logger_) : + logger(logger_) { parent = parent_; rrc = rrc_; @@ -81,6 +78,7 @@ proc_outcome_t ngap_ue_ue_context_release_proc::init(const asn1::ngap_nr::ue_con { // ue_ngap_ids_c ue_ngap_ids = msg.protocol_ies.ue_ngap_ids.value; // cause_c cause = msg.protocol_ies.cause.value; + logger.info("Started %s", name()); return proc_outcome_t::success; } @@ -91,33 +89,81 @@ proc_outcome_t ngap_ue_ue_context_release_proc::step() ngap_ue_pdu_session_res_setup_proc::ngap_ue_pdu_session_res_setup_proc(ngap_interface_ngap_proc* parent_, rrc_interface_ngap_nr* rrc_, - ngap_ue_ctxt_t* ue_ctxt_) : - logger(srslog::fetch_basic_logger("NGAP UE")) -{ - parent = parent_; - rrc = rrc_; - ue_ctxt = ue_ctxt_; -} + ngap_ue_ctxt_t* ue_ctxt_, + ngap_ue_bearer_manager* bearer_manager_, + srslog::basic_logger& logger_) : + parent(parent_), rrc(rrc_), ue_ctxt(ue_ctxt_), bearer_manager(bearer_manager_), logger(logger_) +{} proc_outcome_t ngap_ue_pdu_session_res_setup_proc::init(const asn1::ngap_nr::pdu_session_res_setup_request_s& msg) { if (msg.protocol_ies.pdu_session_res_setup_list_su_req.value.size() != 1) { - logger.error("Not handling multiple su requests"); + logger.error("Not handling zero or multiple su requests"); return proc_outcome_t::error; } + asn1::ngap_nr::pdu_session_res_setup_item_su_req_s su_req = msg.protocol_ies.pdu_session_res_setup_list_su_req.value[0]; + asn1::cbit_ref pdu_session_bref(su_req.pdu_session_res_setup_request_transfer.data(), + su_req.pdu_session_res_setup_request_transfer.size()); + + asn1::ngap_nr::pdu_session_res_setup_request_transfer_s pdu_ses_res_setup_req_trans; + + if (pdu_ses_res_setup_req_trans.unpack(pdu_session_bref) != SRSRAN_SUCCESS) { + logger.error("Unable to unpack PDU session response setup request"); + return proc_outcome_t::error; + } + + if (pdu_ses_res_setup_req_trans.protocol_ies.qos_flow_setup_request_list.value.size() != 1) { + logger.error("Expected one item in QoS flow setup request list"); + return proc_outcome_t::error; + } + + if (pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.type() != + asn1::ngap_nr::up_transport_layer_info_c::types::gtp_tunnel) { + logger.error("Expected GTP Tunnel"); + return proc_outcome_t::error; + } + asn1::ngap_nr::qos_flow_setup_request_item_s qos_flow_setup = + pdu_ses_res_setup_req_trans.protocol_ies.qos_flow_setup_request_list.value[0]; + srsran::const_span nas_pdu_dummy; + asn1::ngap_nr::cause_c cause; + uint32_t teid_out = 0; + int lcid; + + teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[0] << 24u; + teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[1] << 16u; + teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[2] << 8u; + teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[3]; + + // TODO: Check cause + + if (bearer_manager->add_pdu_session( + ue_ctxt->rnti, + su_req.pdu_session_id, + qos_flow_setup.qos_flow_level_qos_params, + pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().transport_layer_address, + teid_out, + cause) != SRSRAN_SUCCESS) { + logger.warning("Failed to add pdu session\n"); + return proc_outcome_t::error; + } + + // QoS parameter mapping in config in LTE enb + // Transport Layer Address required by the procedure for the reponse + asn1::bounded_bitstring<1, 160, true, true> transport_layer_address; + transport_layer_address = + pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().transport_layer_address; if (su_req.pdu_session_nas_pdu_present) { - srsran::unique_byte_buffer_t pdu = srsran::make_byte_buffer(); - if (pdu == nullptr) { - logger.error("Fatal Error: Couldn't allocate buffer in ngap_ue_initial_context_setup_proc::init()."); - return proc_outcome_t::error; + lcid = rrc->allocate_lcid(ue_ctxt->rnti); + if (rrc->establish_rrc_bearer(ue_ctxt->rnti, su_req.pdu_session_id, su_req.pdu_session_nas_pdu, lcid) == + SRSRAN_SUCCESS) { + parent->send_pdu_session_resource_setup_response(su_req.pdu_session_id, teid_out, transport_layer_address); + return proc_outcome_t::success; } - memcpy(pdu->msg, su_req.pdu_session_nas_pdu.data(), su_req.pdu_session_nas_pdu.size()); - pdu->N_bytes = su_req.pdu_session_nas_pdu.size(); - rrc->write_dl_info(ue_ctxt->rnti, std::move(pdu)); } + return proc_outcome_t::yield; } diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 535f8a62e..7a41bace4 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -390,6 +390,10 @@ int rrc_nr::ue_set_bitrates(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_max { return SRSRAN_SUCCESS; } +int rrc_nr::set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) +{ + return SRSRAN_SUCCESS; +} int rrc_nr::ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) { return SRSRAN_SUCCESS; @@ -398,6 +402,16 @@ int rrc_nr::start_security_mode_procedure(uint16_t rnti) { return SRSRAN_SUCCESS; } +int rrc_nr::establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) +{ + return SRSRAN_SUCCESS; +} + +int rrc_nr::allocate_lcid(uint16_t rnti) +{ + return SRSRAN_SUCCESS; +} + void rrc_nr::write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {} /******************************************************************************* diff --git a/srsenb/test/ngap/ngap_test.cc b/srsenb/test/ngap/ngap_test.cc index 834990974..117ace1bb 100644 --- a/srsenb/test/ngap/ngap_test.cc +++ b/srsenb/test/ngap/ngap_test.cc @@ -73,11 +73,20 @@ public: { return SRSRAN_SUCCESS; } + int set_aggregate_max_bitrate(uint16_t rnti, const asn1::ngap_nr::ue_aggregate_maximum_bit_rate_s& rates) + { + return SRSRAN_SUCCESS; + } int ue_set_security_cfg_capabilities(uint16_t rnti, const asn1::ngap_nr::ue_security_cap_s& caps) { return SRSRAN_SUCCESS; } - int start_security_mode_procedure(uint16_t rnti) { return SRSRAN_SUCCESS; } + int start_security_mode_procedure(uint16_t rnti) { return SRSRAN_SUCCESS; } + int establish_rrc_bearer(uint16_t rnti, uint16_t pdu_session_id, srsran::const_byte_span nas_pdu, uint32_t lcid) + { + return SRSRAN_SUCCESS; + } + int allocate_lcid(uint16_t rnti) { return SRSRAN_SUCCESS; } void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) {} }; struct dummy_socket_manager : public srsran::socket_manager_itf { @@ -162,8 +171,9 @@ int main(int argc, char** argv) args.amf_addr = "127.0.0.1"; args.gnb_name = "srsgnb01"; - rrc_nr_dummy rrc; - ngap_obj.init(args, &rrc); + rrc_nr_dummy rrc; + gtpu_interface_rrc* gtpu = nullptr; + ngap_obj.init(args, &rrc, gtpu); // Start the log backend. srsran::test_init(argc, argv); diff --git a/srsue/hdr/stack/upper/nas_5g.h b/srsue/hdr/stack/upper/nas_5g.h index 4e68275e9..27ebc2141 100644 --- a/srsue/hdr/stack/upper/nas_5g.h +++ b/srsue/hdr/stack/upper/nas_5g.h @@ -118,6 +118,9 @@ private: srsran::proc_t registration_proc; srsran::proc_t pdu_session_establishment_proc; + // Network information + srsran::nas_5g::network_name_t full_network_name; + // Message sender int send_registration_request(); int send_authentication_response(const uint8_t res[16]); @@ -146,6 +149,7 @@ private: srsran::nas_5g::deregistration_accept_ue_terminated_t& deregistration_accept_ue_terminated); int handle_deregistration_request_ue_terminated( srsran::nas_5g::deregistration_request_ue_terminated_t& deregistration_request_ue_terminated); + int handle_configuration_update_command(srsran::nas_5g::configuration_update_command_t& configuration_update_command); int handle_dl_nas_transport(srsran::nas_5g::dl_nas_transport_t& dl_nas_transport); // message handler container diff --git a/srsue/src/stack/upper/nas_5g.cc b/srsue/src/stack/upper/nas_5g.cc index c6a66bfcd..660b87600 100644 --- a/srsue/src/stack/upper/nas_5g.cc +++ b/srsue/src/stack/upper/nas_5g.cc @@ -581,7 +581,7 @@ int nas_5g::send_pdu_session_establishment_request(uint32_t tran pdu->N_bytes - SEQ_5G_OFFSET, &pdu->msg[MAC_5G_OFFSET]); - logger.info("Sending PDU Session Establishment Complete in UL NAS transport."); + logger.info("Sending PDU Session Establishment Request in UL NAS transport."); rrc_nr->write_sdu(std::move(pdu)); return SRSRAN_SUCCESS; From bd0e641633c0b2b2cd313323180e0b2ceba233ea Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Fri, 10 Sep 2021 13:00:50 +0200 Subject: [PATCH 14/83] Added GTPU PDU Session header parsing --- lib/include/srsran/upper/gtpu.h | 3 +++ lib/src/gtpu/gtpu.cc | 31 ++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/lib/include/srsran/upper/gtpu.h b/lib/include/srsran/upper/gtpu.h index f78ac17b2..ba0943bdd 100644 --- a/lib/include/srsran/upper/gtpu.h +++ b/lib/include/srsran/upper/gtpu.h @@ -58,8 +58,11 @@ namespace srsran { #define GTPU_MSG_END_MARKER 254 #define GTPU_MSG_DATA_PDU 255 +#define GTPU_EXT_NO_MORE_EXTENSION_HEADERS 0x00 #define GTPU_EXT_HEADER_PDCP_PDU_NUMBER 0b11000000 +#define GTPU_EXT_HEADER_PDU_SESSION_CONTAINER 0x85 +#define GTPU_EXT_HEADER_PDU_SESSION_CONTAINER_LEN 4 struct gtpu_header_t { uint8_t flags = 0; uint8_t message_type = 0; diff --git a/lib/src/gtpu/gtpu.cc b/lib/src/gtpu/gtpu.cc index aa616c411..9dda8ee93 100644 --- a/lib/src/gtpu/gtpu.cc +++ b/lib/src/gtpu/gtpu.cc @@ -112,17 +112,26 @@ bool gtpu_read_ext_header(srsran::byte_buffer_t* pdu, return true; } - if (header->next_ext_hdr_type == GTPU_EXT_HEADER_PDCP_PDU_NUMBER) { - pdu->msg += HEADER_PDCP_PDU_NUMBER_SIZE; - pdu->N_bytes -= HEADER_PDCP_PDU_NUMBER_SIZE; - header->ext_buffer.resize(HEADER_PDCP_PDU_NUMBER_SIZE); - for (size_t i = 0; i < HEADER_PDCP_PDU_NUMBER_SIZE; ++i) { - header->ext_buffer[i] = **ptr; - (*ptr)++; - } - } else { - logger.error("gtpu_read_header - Unhandled GTP-U Extension Header Type: 0x%x", header->next_ext_hdr_type); - return false; + // TODO: Iterate over next headers until no more extension headers + switch (header->next_ext_hdr_type) { + case GTPU_EXT_HEADER_PDCP_PDU_NUMBER: + pdu->msg += HEADER_PDCP_PDU_NUMBER_SIZE; + pdu->N_bytes -= HEADER_PDCP_PDU_NUMBER_SIZE; + header->ext_buffer.resize(HEADER_PDCP_PDU_NUMBER_SIZE); + for (size_t i = 0; i < HEADER_PDCP_PDU_NUMBER_SIZE; ++i) { + header->ext_buffer[i] = **ptr; + (*ptr)++; + } + break; + case GTPU_EXT_HEADER_PDU_SESSION_CONTAINER: + pdu->msg += GTPU_EXT_HEADER_PDU_SESSION_CONTAINER_LEN; + pdu->N_bytes -= GTPU_EXT_HEADER_PDU_SESSION_CONTAINER_LEN; + logger.warning("skip parsing of GTPU_EXT_HEADER_PDU_SESSION_CONTAINER"); + // TODO: Save Header Extension + break; + default: + logger.error("gtpu_read_header - Unhandled GTP-U Extension Header Type: 0x%x", header->next_ext_hdr_type); + return false; } return true; } From 611255aa5f953597071240fa4e2e9041b1a0314a Mon Sep 17 00:00:00 2001 From: David Rupprecht Date: Fri, 10 Sep 2021 13:04:00 +0200 Subject: [PATCH 15/83] Added GTPU bind address as output parameter --- .../srsran/interfaces/enb_gtpu_interfaces.h | 1 + srsenb/hdr/stack/ngap/ngap_ue.h | 4 +- .../hdr/stack/ngap/ngap_ue_bearer_manager.h | 6 ++- srsenb/hdr/stack/upper/gtpu.h | 1 + srsenb/src/stack/ngap/ngap_ue.cc | 11 +++-- .../src/stack/ngap/ngap_ue_bearer_manager.cc | 43 +++++++++++++------ srsenb/src/stack/ngap/ngap_ue_proc.cc | 22 ++++++---- srsenb/src/stack/rrc/rrc.cc | 4 +- srsenb/src/stack/rrc/rrc_bearer_cfg.cc | 3 +- srsenb/src/stack/upper/gtpu.cc | 17 ++++++-- srsenb/test/common/dummy_classes.h | 8 +++- srsenb/test/upper/gtpu_test.cc | 13 +++--- 12 files changed, 90 insertions(+), 43 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_gtpu_interfaces.h b/lib/include/srsran/interfaces/enb_gtpu_interfaces.h index bc6aebda0..b9ec2f364 100644 --- a/lib/include/srsran/interfaces/enb_gtpu_interfaces.h +++ b/lib/include/srsran/interfaces/enb_gtpu_interfaces.h @@ -49,6 +49,7 @@ public: uint32_t eps_bearer_id, uint32_t addr, uint32_t teid_out, + uint32_t& addr_in, 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; diff --git a/srsenb/hdr/stack/ngap/ngap_ue.h b/srsenb/hdr/stack/ngap/ngap_ue.h index 3cf651b91..77004fdc0 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue.h +++ b/srsenb/hdr/stack/ngap/ngap_ue.h @@ -42,8 +42,8 @@ public: bool send_initial_ctxt_setup_failure(asn1::ngap_nr::cause_c cause); // TS 38.413 - Section 9.2.1.2 - PDU Session Resource Setup Response bool send_pdu_session_resource_setup_response(uint16_t pdu_session_id, - uint32_t teid_out, - asn1::bounded_bitstring<1, 160, true, true> transport_layer_address); + uint32_t teid_in, + asn1::bounded_bitstring<1, 160, true, true> addr_in); // TS 38.413 - Section 9.2.2.1 - Initial Context Setup Request bool handle_initial_ctxt_setup_request(const asn1::ngap_nr::init_context_setup_request_s& msg); // TS 38.413 - Section 9.2.2.5 - UE Context Release Command diff --git a/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h b/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h index 94031deae..ed4c3bdeb 100644 --- a/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h +++ b/srsenb/hdr/stack/ngap/ngap_ue_bearer_manager.h @@ -32,7 +32,8 @@ public: struct gtpu_tunnel { uint32_t teid_out = 0; uint32_t teid_in = 0; - asn1::bounded_bitstring<1, 160, true, true> address; + asn1::bounded_bitstring<1, 160, true, true> address_out; + asn1::bounded_bitstring<1, 160, true, true> address_in; }; uint8_t id = 0; uint8_t lcid = 0; @@ -48,6 +49,9 @@ public: const asn1::ngap_nr::qos_flow_level_qos_params_s& qos, const asn1::bounded_bitstring<1, 160, true, true>& addr, uint32_t teid_out, + uint16_t& lcid, + asn1::bounded_bitstring<1, 160, true, true>& addr_in, + uint32_t& teid_in, asn1::ngap_nr::cause_c& cause); private: diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index eff0e747d..3fdb9e0a3 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -145,6 +145,7 @@ public: uint32_t eps_bearer_id, uint32_t addr, uint32_t teid_out, + uint32_t& addr_in, const bearer_props* props = nullptr) override; void set_tunnel_status(uint32_t teidin, bool dl_active) override; void rem_bearer(uint16_t rnti, uint32_t eps_bearer_id) override; diff --git a/srsenb/src/stack/ngap/ngap_ue.cc b/srsenb/src/stack/ngap/ngap_ue.cc index 01ee89c5e..5fc7f5e86 100644 --- a/srsenb/src/stack/ngap/ngap_ue.cc +++ b/srsenb/src/stack/ngap/ngap_ue.cc @@ -184,10 +184,9 @@ bool ngap::ue::send_initial_ctxt_setup_failure(cause_c cause) return true; } -bool ngap::ue::send_pdu_session_resource_setup_response( - uint16_t pdu_session_id, - uint32_t teid_out, - asn1::bounded_bitstring<1, 160, true, true> transport_layer_address) +bool ngap::ue::send_pdu_session_resource_setup_response(uint16_t pdu_session_id, + uint32_t teid_in, + asn1::bounded_bitstring<1, 160, true, true> addr_in) { if (not ngap_ptr->amf_connected) { logger.warning("AMF not connected"); @@ -207,8 +206,8 @@ bool ngap::ue::send_pdu_session_resource_setup_response( gtp_tunnel_s& gtp_tunnel = resp_transfer.dlqos_flow_per_tnl_info.uptransport_layer_info.set_gtp_tunnel(); - gtp_tunnel.gtp_teid.from_number(teid_out); - gtp_tunnel.transport_layer_address = transport_layer_address; + gtp_tunnel.gtp_teid.from_number(teid_in); + gtp_tunnel.transport_layer_address = addr_in; asn1::ngap_nr::associated_qos_flow_list_l qos_flow_list; asn1::ngap_nr::associated_qos_flow_item_s qos_flow_item; qos_flow_item.qos_flow_id = 1; diff --git a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc index 040ff341d..19c71526f 100644 --- a/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc +++ b/srsenb/src/stack/ngap/ngap_ue_bearer_manager.cc @@ -23,25 +23,27 @@ ngap_ue_bearer_manager::~ngap_ue_bearer_manager(){}; int ngap_ue_bearer_manager::add_pdu_session(uint16_t rnti, uint8_t pdu_session_id, const asn1::ngap_nr::qos_flow_level_qos_params_s& qos, - const asn1::bounded_bitstring<1, 160, true, true>& addr, + const asn1::bounded_bitstring<1, 160, true, true>& addr_out, uint32_t teid_out, + uint16_t& lcid, + asn1::bounded_bitstring<1, 160, true, true>& addr_in, + uint32_t& teid_in, asn1::ngap_nr::cause_c& cause) { // RRC call for QoS parameter and lcid <-> ID mapping - int lcid = rrc->allocate_lcid(rnti); + lcid = rrc->allocate_lcid(rnti); // Only add session if gtpu was successful pdu_session_t::gtpu_tunnel tunnel; - if (addr.length() > 32) { + if (addr_out.length() > 32) { logger.error("Only addresses with length <= 32 (IPv4) are supported"); cause.set_radio_network().value = asn1::ngap_nr::cause_radio_network_opts::invalid_qos_combination; return SRSRAN_ERROR; } - // TODO long term remove lcid and just use pdu_session_id and rnti as id for GTP tunnel - - int rtn = add_gtpu_bearer(rnti, lcid, pdu_session_id, teid_out, addr, tunnel); + // TODO: remove lcid and just use pdu_session_id and rnti as id for GTP tunnel + int rtn = add_gtpu_bearer(rnti, lcid, pdu_session_id, teid_out, addr_out, tunnel); if (rtn != SRSRAN_SUCCESS) { logger.error("Adding PDU Session ID=%d to GTPU", pdu_session_id); return SRSRAN_ERROR; @@ -51,6 +53,11 @@ int ngap_ue_bearer_manager::add_pdu_session(uint16_t pdu_session_list[pdu_session_id].lcid = lcid; pdu_session_list[pdu_session_id].qos_params = qos; pdu_session_list[pdu_session_id].tunnels.push_back(tunnel); + + // return values + teid_in = tunnel.teid_in; + addr_in = tunnel.address_in; + return SRSRAN_SUCCESS; } @@ -58,25 +65,35 @@ int ngap_ue_bearer_manager::add_gtpu_bearer(uint16_t uint32_t lcid, uint32_t pdu_session_id, uint32_t teid_out, - asn1::bounded_bitstring<1, 160, true, true> address, + asn1::bounded_bitstring<1, 160, true, true> address_out, pdu_session_t::gtpu_tunnel& tunnel, const gtpu_interface_rrc::bearer_props* props) { // Initialize ERAB tunnel in GTPU right-away. DRBs are only created during RRC setup/reconf - srsran::expected rtn = gtpu->add_bearer(rnti, lcid, address.to_number(), teid_out, props); + uint32_t addr_in; + srsran::expected rtn = gtpu->add_bearer(rnti, lcid, address_out.to_number(), teid_out, addr_in, props); if (rtn.is_error()) { logger.error("Failed adding pdu_session_id=%d to GTPU", pdu_session_id); return SRSRAN_ERROR; } - tunnel.teid_out = teid_out; - tunnel.address = address; - tunnel.teid_in = rtn.value(); - logger.info("Added GTPU tunnel for rnti %x, lcid %d, pdu_session_id=%d, address %s", + tunnel.teid_out = teid_out; + tunnel.address_out = address_out; + + logger.info("Addr in %x", addr_in); + + tunnel.address_in.from_number(addr_in); + tunnel.teid_in = rtn.value(); + + logger.info("Added GTPU tunnel rnti 0x%04x, lcid %d, pdu_session_id=%d, teid_out %d, teid_in %d, address out 0x%x, " + "address in 0x%x", rnti, lcid, pdu_session_id, - address.to_string()); + tunnel.teid_out, + tunnel.teid_in, + tunnel.address_out.to_number(), + tunnel.address_in.to_number()); return SRSRAN_SUCCESS; } diff --git a/srsenb/src/stack/ngap/ngap_ue_proc.cc b/srsenb/src/stack/ngap/ngap_ue_proc.cc index bf9aeac2e..ad61f8c6c 100644 --- a/srsenb/src/stack/ngap/ngap_ue_proc.cc +++ b/srsenb/src/stack/ngap/ngap_ue_proc.cc @@ -128,9 +128,7 @@ proc_outcome_t ngap_ue_pdu_session_res_setup_proc::init(const asn1::ngap_nr::pdu asn1::ngap_nr::qos_flow_setup_request_item_s qos_flow_setup = pdu_ses_res_setup_req_trans.protocol_ies.qos_flow_setup_request_list.value[0]; srsran::const_span nas_pdu_dummy; - asn1::ngap_nr::cause_c cause; uint32_t teid_out = 0; - int lcid; teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[0] << 24u; teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[1] << 16u; @@ -138,6 +136,10 @@ proc_outcome_t ngap_ue_pdu_session_res_setup_proc::init(const asn1::ngap_nr::pdu teid_out |= pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().gtp_teid[3]; // TODO: Check cause + asn1::ngap_nr::cause_c cause; + uint32_t teid_in; + uint16_t lcid; + asn1::bounded_bitstring<1, 160, true, true> addr_in; if (bearer_manager->add_pdu_session( ue_ctxt->rnti, @@ -145,21 +147,25 @@ proc_outcome_t ngap_ue_pdu_session_res_setup_proc::init(const asn1::ngap_nr::pdu qos_flow_setup.qos_flow_level_qos_params, pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().transport_layer_address, teid_out, + lcid, + addr_in, + teid_in, cause) != SRSRAN_SUCCESS) { logger.warning("Failed to add pdu session\n"); return proc_outcome_t::error; } + logger.info("Added PDU Session with LCID %d, teid_out %d, teid_in %d, addr_in %s", + lcid, + teid_out, + teid_in, + addr_in.to_string()); + // QoS parameter mapping in config in LTE enb - // Transport Layer Address required by the procedure for the reponse - asn1::bounded_bitstring<1, 160, true, true> transport_layer_address; - transport_layer_address = - pdu_ses_res_setup_req_trans.protocol_ies.ul_ngu_up_tnl_info.value.gtp_tunnel().transport_layer_address; if (su_req.pdu_session_nas_pdu_present) { - lcid = rrc->allocate_lcid(ue_ctxt->rnti); if (rrc->establish_rrc_bearer(ue_ctxt->rnti, su_req.pdu_session_id, su_req.pdu_session_nas_pdu, lcid) == SRSRAN_SUCCESS) { - parent->send_pdu_session_resource_setup_response(su_req.pdu_session_id, teid_out, transport_layer_address); + parent->send_pdu_session_resource_setup_response(su_req.pdu_session_id, teid_in, addr_in); return proc_outcome_t::success; } } diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index 0097f8aca..a9eff4db2 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -237,12 +237,12 @@ int rrc::add_user(uint16_t rnti, const sched_interface::ue_cfg_t& sched_ue_cfg) if (rnti == SRSRAN_MRNTI) { 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; - + uint32_t addr_in; // adding UE object to MAC for MRNTI without scheduling configuration (broadcast not part of regular scheduling) 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)); - gtpu->add_bearer(SRSRAN_MRNTI, lcid, 1, 1); + gtpu->add_bearer(SRSRAN_MRNTI, lcid, 1, 1, addr_in); } } return SRSRAN_SUCCESS; diff --git a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc index 6870d22f0..59db1a763 100644 --- a/srsenb/src/stack/rrc/rrc_bearer_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_bearer_cfg.cc @@ -385,9 +385,10 @@ srsran::expected bearer_cfg_handler::add_gtpu_bearer(uint32_t // Initialize ERAB tunnel in GTPU right-away. DRBs are only created during RRC setup/reconf erab_t& erab = it->second; erab_t::gtpu_tunnel bearer; + uint32_t addr_in; bearer.teid_out = teid_out; bearer.addr = addr; - srsran::expected teidin = gtpu->add_bearer(rnti, erab.id, addr, teid_out, props); + srsran::expected teidin = gtpu->add_bearer(rnti, erab.id, addr, teid_out, addr_in, props); if (teidin.is_error()) { logger->error("Adding erab_id=%d to GTPU", erab_id); return srsran::default_error_t(); diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index f2d42c808..658a4933e 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -476,11 +476,15 @@ void gtpu::send_pdu_to_tunnel(const gtpu_tunnel& tx_tun, srsran::unique_byte_buf } } -srsran::expected -gtpu::add_bearer(uint16_t rnti, uint32_t eps_bearer_id, uint32_t addr, uint32_t teid_out, const bearer_props* props) +srsran::expected gtpu::add_bearer(uint16_t rnti, + uint32_t eps_bearer_id, + uint32_t addr_out, + uint32_t teid_out, + uint32_t& addr_in, + const bearer_props* props) { // Allocate a TEID for the incoming tunnel - const gtpu_tunnel* new_tun = tunnels.add_tunnel(rnti, eps_bearer_id, teid_out, addr); + const gtpu_tunnel* new_tun = tunnels.add_tunnel(rnti, eps_bearer_id, teid_out, addr_out); if (new_tun == nullptr) { return default_error_t(); } @@ -504,6 +508,13 @@ gtpu::add_bearer(uint16_t rnti, uint32_t eps_bearer_id, uint32_t addr, uint32_t } } + // Return bind address for S1AP and NGAP setup + struct in_addr inaddr; + if ((inet_pton(AF_INET, gtp_bind_addr.c_str(), &inaddr)) < 1) { + logger.error("Invalid address or failure during conversion: %s\n", gtp_bind_addr.c_str()); + } + addr_in = ntohl(inaddr.s_addr); + return teid_in; } diff --git a/srsenb/test/common/dummy_classes.h b/srsenb/test/common/dummy_classes.h index e27f57dad..c3fb2598a 100644 --- a/srsenb/test/common/dummy_classes.h +++ b/srsenb/test/common/dummy_classes.h @@ -109,8 +109,12 @@ public: class gtpu_dummy : public srsenb::gtpu_interface_rrc { public: - srsran::expected - add_bearer(uint16_t rnti, uint32_t lcid, uint32_t addr, uint32_t teid_out, const bearer_props* props) override + srsran::expected add_bearer(uint16_t rnti, + uint32_t lcid, + uint32_t addr, + uint32_t teid_out, + uint32_t& addr_in, + const bearer_props* props) override { return 1; } diff --git a/srsenb/test/upper/gtpu_test.cc b/srsenb/test/upper/gtpu_test.cc index 4220de0a6..caa4fdfc8 100644 --- a/srsenb/test/upper/gtpu_test.cc +++ b/srsenb/test/upper/gtpu_test.cc @@ -244,10 +244,11 @@ int test_gtpu_direct_tunneling(tunnel_test_event event) senb_gtpu.init(gtpu_args, &senb_pdcp); gtpu_args.gtp_bind_addr = tenb_addr_str; tenb_gtpu.init(gtpu_args, &tenb_pdcp); - + uint32_t addr_in1; + uint32_t addr_in2; // create tunnels MME-SeNB and MME-TeNB - 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(); + uint32_t senb_teid_in = senb_gtpu.add_bearer(rnti, drb1_bearer_id, sgw_addr, sgw_teidout1, addr_in1).value(); + uint32_t tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1_bearer_id, sgw_addr, sgw_teidout2, addr_in2).value(); // Buffer PDUs in SeNB PDCP for (size_t sn = 6; sn < 10; ++sn) { @@ -260,11 +261,13 @@ 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_bearer_id, senb_addr, 0, &props).value(); + uint32_t addr_in3; + uint32_t dl_tenb_teid_in = tenb_gtpu.add_bearer(rnti2, drb1_bearer_id, senb_addr, 0, addr_in3, &props).value(); props = {}; props.forward_from_teidin_present = true; props.forward_from_teidin = senb_teid_in; - senb_gtpu.add_bearer(rnti, drb1_bearer_id, tenb_addr, dl_tenb_teid_in, &props); + uint32_t addr_in4; + senb_gtpu.add_bearer(rnti, drb1_bearer_id, tenb_addr, dl_tenb_teid_in, addr_in4, &props); std::vector data_vec(10); std::iota(data_vec.begin(), data_vec.end(), 0); From feec3c5905e4a7df3b291630840ebff38bc06299 Mon Sep 17 00:00:00 2001 From: faluco Date: Wed, 22 Sep 2021 14:15:40 +0200 Subject: [PATCH 16/83] Fix a data race during enb initialization. The stack unique pointer in the enb class is written while the phy workers are calling enb::tti_clock() where it is read. Avoid the read access until the whole class has been properly initialized. --- srsenb/hdr/enb.h | 8 ++++---- srsenb/src/enb.cc | 11 ++++++++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index cf5901e84..3f821f0fe 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -153,8 +153,8 @@ private: srslog::sink& log_sink; srslog::basic_logger& enb_log; - all_args_t args = {}; - bool started = false; + all_args_t args = {}; + std::atomic started = {false}; phy_cfg_t phy_cfg = {}; rrc_cfg_t rrc_cfg = {}; @@ -164,8 +164,8 @@ private: x2_adapter x2; std::unique_ptr eutra_stack = nullptr; std::unique_ptr nr_stack = nullptr; - std::unique_ptr radio = nullptr; - std::unique_ptr phy = nullptr; + std::unique_ptr radio = nullptr; + std::unique_ptr phy = nullptr; // System metrics processor. srsran::sys_metrics_processor sys_proc; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index da2bbdc2d..050168669 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -194,12 +194,15 @@ void enb::print_pool() bool enb::get_metrics(enb_metrics_t* m) { + if (!started) { + return false; + } radio->get_metrics(&m->rf); phy->get_metrics(m->phy); if (eutra_stack) { eutra_stack->get_metrics(&m->stack); } - m->running = started; + m->running = true; m->sys = sys_proc.get_metrics(); return true; } @@ -231,6 +234,9 @@ std::string enb::get_build_string() void enb::toggle_padding() { + if (!started) { + return; + } if (eutra_stack) { eutra_stack->toggle_padding(); } @@ -238,6 +244,9 @@ void enb::toggle_padding() void enb::tti_clock() { + if (!started) { + return; + } if (eutra_stack) { eutra_stack->tti_clock(); } From 802b22ac915b5275930618e5704a4ea7c93e2794 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 22 Sep 2021 11:40:17 +0200 Subject: [PATCH 17/83] enb,nsa: refactor NR RRC/cell config parsing this allows to access all cell-related params from within RRC --- .../srsran/interfaces/gnb_rrc_nr_interfaces.h | 12 ++ srsenb/hdr/enb.h | 2 +- srsenb/hdr/stack/rrc/rrc_config.h | 12 +- srsenb/hdr/stack/rrc/rrc_config_nr.h | 3 +- srsenb/src/enb.cc | 8 +- srsenb/src/enb_cfg_parser.cc | 184 ++++++++++-------- srsenb/src/enb_cfg_parser.h | 19 +- srsenb/src/stack/rrc/rrc_endc.cc | 2 +- srsenb/src/stack/rrc/rrc_nr.cc | 10 +- srsenb/src/stack/rrc/rrc_ue.cc | 3 +- srsenb/test/rrc/CMakeLists.txt | 2 +- srsenb/test/rrc/test_helpers.cc | 7 +- 12 files changed, 154 insertions(+), 110 deletions(-) diff --git a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h index 8bf153fc8..1033608b5 100644 --- a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h @@ -12,8 +12,10 @@ #ifndef SRSRAN_GNB_RRC_NR_INTERFACES_H #define SRSRAN_GNB_RRC_NR_INTERFACES_H +#include "srsenb/hdr/phy/phy_interfaces.h" #include "srsran/asn1/ngap.h" #include "srsran/common/byte_buffer.h" + namespace srsenb { class rrc_interface_ngap_nr @@ -30,6 +32,16 @@ public: virtual void write_dl_info(uint16_t rnti, srsran::unique_byte_buffer_t sdu) = 0; }; +// Cell/Sector configuration for NR cells +struct rrc_cell_cfg_nr_t { + phy_cell_cfg_nr_t phy_cell; // already contains all PHY-related parameters (i.e. RF port, PCI, etc.) + uint32_t tac; // Tracking area code + uint32_t dl_arfcn; // DL freq already included in phy_cell + uint32_t ul_arfcn; // UL freq also in phy_cell +}; + +typedef std::vector rrc_cell_list_nr_t; + } // namespace srsenb #endif // SRSRAN_GNB_RRC_NR_INTERFACES_H \ No newline at end of file diff --git a/srsenb/hdr/enb.h b/srsenb/hdr/enb.h index 3f821f0fe..25f1a5173 100644 --- a/srsenb/hdr/enb.h +++ b/srsenb/hdr/enb.h @@ -148,7 +148,7 @@ public: private: const static int ENB_POOL_SIZE = 1024 * 10; - int parse_args(const all_args_t& args_, rrc_cfg_t& rrc_cfg); + int parse_args(const all_args_t& args_, rrc_cfg_t& rrc_cfg_, rrc_nr_cfg_t& rrc_cfg_nr_); srslog::sink& log_sink; srslog::basic_logger& enb_log; diff --git a/srsenb/hdr/stack/rrc/rrc_config.h b/srsenb/hdr/stack/rrc/rrc_config.h index 676bf81be..66fdbcab0 100644 --- a/srsenb/hdr/stack/rrc/rrc_config.h +++ b/srsenb/hdr/stack/rrc/rrc_config.h @@ -64,12 +64,12 @@ struct rrc_cfg_t { bool meas_cfg_present = false; srsran_cell_t cell; cell_list_t cell_list; - cell_list_t cell_list_nr; - uint32_t max_mac_dl_kos; - uint32_t max_mac_ul_kos; - uint32_t rlf_release_timer_ms; - srb_cfg_t srb1_cfg; - srb_cfg_t srb2_cfg; + uint32_t num_nr_cells = 0; /// number of configured NR cells (used to configure RF) + uint32_t max_mac_dl_kos; + uint32_t max_mac_ul_kos; + uint32_t rlf_release_timer_ms; + srb_cfg_t srb1_cfg; + srb_cfg_t srb2_cfg; }; constexpr uint32_t UE_PCELL_CC_IDX = 0; diff --git a/srsenb/hdr/stack/rrc/rrc_config_nr.h b/srsenb/hdr/stack/rrc/rrc_config_nr.h index 469d7bfee..d08bfccf7 100644 --- a/srsenb/hdr/stack/rrc/rrc_config_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_config_nr.h @@ -14,6 +14,7 @@ #define SRSRAN_RRC_CONFIG_NR_H #include "srsran/asn1/rrc_nr.h" +#include "srsran/interfaces/gnb_rrc_nr_interfaces.h" #include "srsue/hdr/phy/phy_common.h" namespace srsenb { @@ -34,7 +35,7 @@ struct rrc_nr_cfg_t { uint32_t nof_sibs; rrc_nr_cfg_sr_t sr_cfg; rrc_cfg_cqi_t cqi_cfg; - srsran_cell_t cell; + rrc_cell_list_nr_t cell_list; std::string log_level; uint32_t log_hex_limit; diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 050168669..1ea3c114f 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -43,7 +43,7 @@ int enb::init(const all_args_t& args_) enb_log.info("%s", get_build_string().c_str()); // Validate arguments - if (parse_args(args_, rrc_cfg)) { + if (parse_args(args_, rrc_cfg, rrc_nr_cfg)) { srsran::console("Error processing arguments.\n"); return SRSRAN_ERROR; } @@ -63,7 +63,7 @@ int enb::init(const all_args_t& args_) } std::unique_ptr tmp_nr_stack; - if (not rrc_cfg.cell_list_nr.empty()) { + if (not rrc_nr_cfg.cell_list.empty()) { // add NR stack tmp_nr_stack.reset(new gnb_stack_nr(log_sink)); if (tmp_nr_stack == nullptr) { @@ -175,11 +175,11 @@ void enb::stop() } } -int enb::parse_args(const all_args_t& args_, rrc_cfg_t& _rrc_cfg) +int enb::parse_args(const all_args_t& args_, rrc_cfg_t& rrc_cfg_, rrc_nr_cfg_t& rrc_cfg_nr_) { // set member variable args = args_; - return enb_conf_sections::parse_cfg_files(&args, &_rrc_cfg, &phy_cfg); + return enb_conf_sections::parse_cfg_files(&args, &rrc_cfg_, &rrc_cfg_nr_, &phy_cfg); } void enb::start_plot() diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 030d37c16..aa8bec2b8 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -635,7 +635,7 @@ int field_qci::parse(libconfig::Setting& root) namespace rr_sections { -int parse_rr(all_args_t* args_, rrc_cfg_t* rrc_cfg_) +int parse_rr(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr_cfg_) { /* Transmission mode config section */ if (args_->enb.transmission_mode < 1 || args_->enb.transmission_mode > 4) { @@ -750,7 +750,7 @@ int parse_rr(all_args_t* args_, rrc_cfg_t* rrc_cfg_) bool nr_cell_cnfg_present = false; parser::section nr_cell_cnfg("nr_cell_list"); nr_cell_cnfg.set_optional(&nr_cell_cnfg_present); - nr_cell_cnfg.add_field(new rr_sections::nr_cell_list_section(args_, rrc_cfg_)); + nr_cell_cnfg.add_field(new rr_sections::nr_cell_list_section(args_, rrc_nr_cfg_, rrc_cfg_)); // Run parser with two sections parser p(args_->enb_files.rr_config); @@ -894,46 +894,54 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) return SRSRAN_SUCCESS; } -static int parse_nr_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) +static int parse_nr_cell_list(all_args_t* args, rrc_nr_cfg_t* rrc_cfg_nr, rrc_cfg_t* rrc_cfg_eutra, Setting& root) { for (uint32_t n = 0; n < (uint32_t)root.getLength(); ++n) { - cell_cfg_t cell_cfg = {}; + rrc_cell_cfg_nr_t cell_cfg = {}; auto& cellroot = root[n]; - parse_opt_field(cell_cfg.rf_port, cellroot, "rf_port"); - HANDLEPARSERCODE(parse_required_field(cell_cfg.cell_id, cellroot, "cell_id")); + parse_opt_field(cell_cfg.phy_cell.rf_port, cellroot, "rf_port"); + HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.carrier.pci, cellroot, "pci")); + HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.cell_id, cellroot, "cell_id")); + HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.root_seq_idx, cellroot, "root_seq_idx")); HANDLEPARSERCODE(parse_required_field(cell_cfg.tac, cellroot, "tac")); - HANDLEPARSERCODE(parse_required_field(cell_cfg.pci, cellroot, "pci")); - cell_cfg.pci = cell_cfg.pci % SRSRAN_NOF_NID_NR; - HANDLEPARSERCODE(parse_required_field(cell_cfg.dl_earfcn, cellroot, "dl_arfcn")); + + cell_cfg.phy_cell.carrier.pci = cell_cfg.phy_cell.carrier.pci % SRSRAN_NOF_NID_NR; + HANDLEPARSERCODE(parse_required_field(cell_cfg.dl_arfcn, cellroot, "dl_arfcn")); // frequencies get derived from ARFCN - // Add further cell-specific parameters + // TODO: Add further cell-specific parameters - rrc_cfg->cell_list_nr.push_back(cell_cfg); + rrc_cfg_nr->cell_list.push_back(cell_cfg); } // Configuration check - for (auto it = rrc_cfg->cell_list_nr.begin(); it != rrc_cfg->cell_list_nr.end(); ++it) { + for (auto it = rrc_cfg_nr->cell_list.begin(); it != rrc_cfg_nr->cell_list.end(); ++it) { // check against NR cells - for (auto it2 = it + 1; it2 != rrc_cfg->cell_list_nr.end(); it2++) { + for (auto it2 = it + 1; it2 != rrc_cfg_nr->cell_list.end(); it2++) { // Check RF port is not repeated - if (it->rf_port == it2->rf_port) { + if (it->phy_cell.rf_port == it2->phy_cell.rf_port) { ERROR("Repeated RF port for multiple cells"); return SRSRAN_ERROR; } - // Check cell ID is not repeated - if (it->cell_id == it2->cell_id) { + // Check cell PCI not repeated + if (it->phy_cell.carrier.pci == it2->phy_cell.carrier.pci) { + ERROR("Repeated cell PCI"); + return SRSRAN_ERROR; + } + + // Check cell PCI and cell ID is not repeated + if (it->phy_cell.cell_id == it2->phy_cell.cell_id) { ERROR("Repeated Cell identifier"); return SRSRAN_ERROR; } } // also check RF port against EUTRA cells - for (auto it_eutra = rrc_cfg->cell_list.begin(); it_eutra != rrc_cfg->cell_list.end(); ++it_eutra) { + for (auto it_eutra = rrc_cfg_eutra->cell_list.begin(); it_eutra != rrc_cfg_eutra->cell_list.end(); ++it_eutra) { // Check RF port is not repeated - if (it->rf_port == it_eutra->rf_port) { + if (it->phy_cell.rf_port == it_eutra->rf_port) { ERROR("Repeated RF port for multiple cells"); return SRSRAN_ERROR; } @@ -951,7 +959,7 @@ int cell_list_section::parse(libconfig::Setting& root) int nr_cell_list_section::parse(libconfig::Setting& root) { - HANDLEPARSERCODE(parse_nr_cell_list(args, rrc_cfg, root)); + HANDLEPARSERCODE(parse_nr_cell_list(args, nr_rrc_cfg, eutra_rrc_cfg, root)); return 0; } @@ -990,7 +998,7 @@ int parse_cell_cfg(all_args_t* args_, srsran_cell_t* cell) return SRSRAN_SUCCESS; } -int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_) +int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_nr_cfg_, phy_cfg_t* phy_cfg_) { // Parse config files srsran_cell_t cell_common_cfg = {}; @@ -1022,7 +1030,7 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_) } try { - if (rr_sections::parse_rr(args_, rrc_cfg_) != SRSRAN_SUCCESS) { + if (rr_sections::parse_rr(args_, rrc_cfg_, rrc_nr_cfg_) != SRSRAN_SUCCESS) { fprintf(stderr, "Error parsing Radio Resources configuration\n"); return SRSRAN_ERROR; } @@ -1048,7 +1056,22 @@ int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_) } // Set fields derived from others, and check for correctness of the parsed configuration - return enb_conf_sections::set_derived_args(args_, rrc_cfg_, phy_cfg_, cell_common_cfg); + if (enb_conf_sections::set_derived_args(args_, rrc_cfg_, phy_cfg_, cell_common_cfg) != SRSRAN_SUCCESS) { + fprintf(stderr, "Error deriving EUTRA cell parameters\n"); + return SRSRAN_ERROR; + } + + // do the same for NR + if (enb_conf_sections::set_derived_args_nr(args_, rrc_nr_cfg_, phy_cfg_) != SRSRAN_SUCCESS) { + fprintf(stderr, "Error deriving NR cell parameters\n"); + return SRSRAN_ERROR; + } + + // update number of NR cells + rrc_cfg_->num_nr_cells = rrc_nr_cfg_->cell_list.size(); + args_->rf.nof_carriers = rrc_cfg_->cell_list.size() + rrc_nr_cfg_->cell_list.size(); + + return SRSRAN_SUCCESS; } int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_, const srsran_cell_t& cell_cfg_) @@ -1155,59 +1178,6 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ phy_cfg_->phy_cell_cfg.push_back(phy_cell_cfg); } - // Use helper class to derive NR carrier parameters - srsran::srsran_band_helper band_helper; - - // Create NR dedicated cell configuration from RRC configuration - for (auto it = rrc_cfg_->cell_list_nr.begin(); it != rrc_cfg_->cell_list_nr.end(); ++it) { - auto& cfg = *it; - phy_cell_cfg_nr_t phy_cell_cfg = {}; - phy_cell_cfg.carrier.max_mimo_layers = cell_cfg_.nof_ports; - switch (cell_cfg_.nof_prb) { - case 25: - phy_cell_cfg.carrier.nof_prb = 25; - break; - case 50: - phy_cell_cfg.carrier.nof_prb = 52; - break; - case 100: - phy_cell_cfg.carrier.nof_prb = 106; - break; - default: - ERROR("The only accepted number of PRB is: 25, 50, 100"); - return SRSRAN_ERROR; - } - phy_cell_cfg.carrier.pci = cfg.pci; - phy_cell_cfg.cell_id = cfg.cell_id; - phy_cell_cfg.root_seq_idx = cfg.root_seq_idx; - phy_cell_cfg.rf_port = cfg.rf_port; - phy_cell_cfg.num_ra_preambles = - rrc_cfg_->sibs[1].sib2().rr_cfg_common.rach_cfg_common.preamb_info.nof_ra_preambs.to_number(); - - if (cfg.dl_freq_hz > 0) { - phy_cell_cfg.dl_freq_hz = cfg.dl_freq_hz; - } else { - phy_cell_cfg.dl_freq_hz = band_helper.nr_arfcn_to_freq(cfg.dl_earfcn); - } - - if (cfg.ul_freq_hz > 0) { - phy_cell_cfg.ul_freq_hz = cfg.ul_freq_hz; - } else { - // auto-detect UL frequency - if (cfg.ul_earfcn == 0) { - // derive UL ARFCN from given DL ARFCN - cfg.ul_earfcn = band_helper.get_ul_arfcn_from_dl_arfcn(cfg.dl_earfcn); - if (cfg.ul_earfcn == 0) { - ERROR("Can't derive UL ARFCN from DL ARFCN %d", cfg.dl_earfcn); - return SRSRAN_ERROR; - } - } - phy_cell_cfg.ul_freq_hz = band_helper.nr_arfcn_to_freq(cfg.ul_earfcn); - } - - phy_cfg_->phy_cell_cfg_nr.push_back(phy_cell_cfg); - } - if (args_->enb.transmission_mode == 1) { phy_cfg_->pdsch_cnfg.p_b = 0; // Default TM1 rrc_cfg_->sibs[1].sib2().rr_cfg_common.pdsch_cfg_common.p_b = 0; @@ -1318,7 +1288,6 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ } // Patch certain args that are not exposed yet - args_->rf.nof_carriers = rrc_cfg_->cell_list.size() + rrc_cfg_->cell_list_nr.size(); args_->rf.nof_antennas = args_->enb.nof_ports; // MAC needs to know the cell bandwidth to dimension softbuffers @@ -1344,6 +1313,69 @@ int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_ return SRSRAN_SUCCESS; } +/** + * @brief Set the derived args for the NR RRC and PHY config + * + * Mainly configures the RRC parameter based on the arguments and config files + * read. Since for NSA we are still using a commong PHY between EUTRA and NR + * the PHY configuration is also updated accordingly. + * + * @param args_ + * @param nr_rrc_cfg + * @param phy_cfg_ + * @return int + */ +int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_) +{ + // Use helper class to derive NR carrier parameters + srsran::srsran_band_helper band_helper; + + // Create NR dedicated cell configuration from RRC configuration + for (auto it = rrc_cfg_->cell_list.begin(); it != rrc_cfg_->cell_list.end(); ++it) { + auto& cfg = *it; + cfg.phy_cell.carrier.max_mimo_layers = args_->enb.nof_ports; + + // NR cells have the same bandwidth as EUTRA cells, adjust PRB sizes + switch (args_->enb.n_prb) { + case 25: + cfg.phy_cell.carrier.nof_prb = 25; + break; + case 50: + cfg.phy_cell.carrier.nof_prb = 52; + break; + case 100: + cfg.phy_cell.carrier.nof_prb = 106; + break; + default: + ERROR("The only accepted number of PRB is: 25, 50, 100"); + return SRSRAN_ERROR; + } + // phy_cell_cfg.root_seq_idx = cfg.root_seq_idx; + cfg.phy_cell.num_ra_preambles = 52; // FIXME: read from config + + if (cfg.phy_cell.dl_freq_hz == 0) { + cfg.phy_cell.dl_freq_hz = band_helper.nr_arfcn_to_freq(cfg.dl_arfcn); + } + + if (cfg.phy_cell.ul_freq_hz == 0) { + // auto-detect UL frequency + if (cfg.ul_arfcn == 0) { + // derive UL ARFCN from given DL ARFCN + cfg.ul_arfcn = band_helper.get_ul_arfcn_from_dl_arfcn(cfg.dl_arfcn); + if (cfg.ul_arfcn == 0) { + ERROR("Can't derive UL ARFCN from DL ARFCN %d", cfg.dl_arfcn); + return SRSRAN_ERROR; + } + } + cfg.phy_cell.ul_freq_hz = band_helper.nr_arfcn_to_freq(cfg.ul_arfcn); + } + + phy_cfg_->phy_cell_cfg_nr.push_back(cfg.phy_cell); + } + + return SRSRAN_SUCCESS; +} + } // namespace enb_conf_sections namespace sib_sections { diff --git a/srsenb/src/enb_cfg_parser.h b/srsenb/src/enb_cfg_parser.h index f8a9d9241..8766c260f 100644 --- a/srsenb/src/enb_cfg_parser.h +++ b/srsenb/src/enb_cfg_parser.h @@ -10,8 +10,8 @@ * */ -#ifndef ENB_CFG_PARSER_SIB1_H -#define ENB_CFG_PARSER_SIB1_H +#ifndef ENB_CFG_PARSER_H +#define ENB_CFG_PARSER_H #include "srsenb/hdr/parser.h" #include @@ -22,6 +22,7 @@ #include #include "srsenb/hdr/stack/rrc/rrc.h" +#include "srsenb/hdr/stack/rrc/rrc_config_nr.h" #include "srsran/asn1/asn1_utils.h" namespace srsenb { @@ -37,8 +38,9 @@ bool sib_is_present(const asn1::rrc::sched_info_list_l& l, asn1::rrc::sib_type_e namespace enb_conf_sections { int parse_cell_cfg(all_args_t* args_, srsran_cell_t* cell); -int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_); +int parse_cfg_files(all_args_t* args_, rrc_cfg_t* rrc_cfg_, rrc_nr_cfg_t* rrc_cfg_nr_, phy_cfg_t* phy_cfg_); int set_derived_args(all_args_t* args_, rrc_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_, const srsran_cell_t& cell_cfg_); +int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_cfg_, phy_cfg_t* phy_cfg_); } // namespace enb_conf_sections @@ -85,15 +87,18 @@ private: class nr_cell_list_section final : public parser::field_itf { public: - explicit nr_cell_list_section(all_args_t* all_args_, rrc_cfg_t* rrc_cfg_) : args(all_args_), rrc_cfg(rrc_cfg_) {} + explicit nr_cell_list_section(all_args_t* all_args_, rrc_nr_cfg_t* nr_rrc_cfg_, rrc_cfg_t* eutra_rrc_cfg_) : + args(all_args_), nr_rrc_cfg(nr_rrc_cfg_), eutra_rrc_cfg(eutra_rrc_cfg_) + {} int parse(Setting& root) override; const char* get_name() override { return "nr_cell_list"; } private: - rrc_cfg_t* rrc_cfg; - all_args_t* args; + rrc_nr_cfg_t* nr_rrc_cfg; + rrc_cfg_t* eutra_rrc_cfg; + all_args_t* args; }; } // namespace rr_sections @@ -573,4 +578,4 @@ private: }; } // namespace srsenb -#endif +#endif // ENB_CFG_PARSER_H diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index 4b16ca61b..e9465a1e3 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -169,7 +169,7 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn void rrc::ue::rrc_endc::handle_eutra_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_caps) { // skip any further checks if eNB runs without NR cells - if (rrc_enb->cfg.cell_list_nr.empty()) { + if (rrc_enb->cfg.num_nr_cells == 0) { Debug("Skipping UE capabilities. No NR cell configured."); return; } diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 7a41bace4..f5f228722 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -110,14 +110,6 @@ rrc_nr_cfg_t rrc_nr::update_default_cfg(const rrc_nr_cfg_t& current) cfg_default.mib.dmrs_type_a_position.value = mib_s::dmrs_type_a_position_opts::pos2; cfg_default.mib.sys_frame_num.from_number(0); - cfg_default.cell.nof_prb = 25; - cfg_default.cell.nof_ports = 1; - cfg_default.cell.id = 0; - cfg_default.cell.cp = SRSRAN_CP_NORM; - cfg_default.cell.frame_type = SRSRAN_FDD; - cfg_default.cell.phich_length = SRSRAN_PHICH_NORM; - cfg_default.cell.phich_resources = SRSRAN_PHICH_R_1; - // Fill SIB1 cfg_default.sib1.cell_access_related_info.plmn_id_list.resize(1); cfg_default.sib1.cell_access_related_info.plmn_id_list[0].plmn_id_list.resize(1); @@ -226,7 +218,7 @@ void rrc_nr::config_mac() logger.info("Allocating %d PRBs for PUCCH", cell_cfg.nrb_pucch); // Copy Cell configuration - cell_cfg.cell = cfg.cell; + // cell_cfg.cell = cfg.cell; // Configure MAC/scheduler mac->cell_cfg(sched_cells_cfg); diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index f9fc766b9..0a08278c4 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -377,8 +377,7 @@ void rrc::ue::parse_ul_dcch(uint32_t lcid, srsran::unique_byte_buffer_t pdu) break; case ul_dcch_msg_type_c::c1_c_::types::ue_cap_info: if (handle_ue_cap_info(&ul_dcch_msg.msg.c1().ue_cap_info()) == SRSRAN_SUCCESS) { - if (not parent->cfg.cell_list_nr.empty() && endc_handler->is_endc_supported() && - state == RRC_STATE_WAIT_FOR_UE_CAP_INFO) { + if (endc_handler != nullptr && endc_handler->is_endc_supported() && state == RRC_STATE_WAIT_FOR_UE_CAP_INFO) { // request EUTRA-NR and NR capabilities as well send_ue_cap_enquiry({asn1::rrc::rat_type_opts::options::eutra_nr, asn1::rrc::rat_type_opts::options::nr}); state = RRC_STATE_WAIT_FOR_UE_CAP_INFO_ENDC; // avoid endless loop diff --git a/srsenb/test/rrc/CMakeLists.txt b/srsenb/test/rrc/CMakeLists.txt index 2a57744b2..8b440b28c 100644 --- a/srsenb/test/rrc/CMakeLists.txt +++ b/srsenb/test/rrc/CMakeLists.txt @@ -7,7 +7,7 @@ # add_library(test_helpers test_helpers.cc) -target_link_libraries(test_helpers srsenb_rrc srsenb_common rrc_asn1 s1ap_asn1 srsran_common enb_cfg_parser ${LIBCONFIGPP_LIBRARIES}) +target_link_libraries(test_helpers srsenb_rrc srsenb_common rrc_asn1 rrc_nr_asn1 s1ap_asn1 srsran_common enb_cfg_parser ${LIBCONFIGPP_LIBRARIES}) add_executable(rrc_nr_test rrc_nr_test.cc) target_link_libraries(rrc_nr_test srsgnb_rrc srsran_common rrc_nr_asn1 ${ATOMIC_LIBS}) diff --git a/srsenb/test/rrc/test_helpers.cc b/srsenb/test/rrc/test_helpers.cc index 416fcf193..a3c890a50 100644 --- a/srsenb/test/rrc/test_helpers.cc +++ b/srsenb/test/rrc/test_helpers.cc @@ -39,7 +39,9 @@ int parse_default_cfg_phy(rrc_cfg_t* rrc_cfg, phy_cfg_t* phy_cfg, srsenb::all_ar args.general.rrc_inactivity_timer = 60000; - return enb_conf_sections::parse_cfg_files(&args, rrc_cfg, phy_cfg); + rrc_nr_cfg_t rrc_cfg_nr; + + return enb_conf_sections::parse_cfg_files(&args, rrc_cfg, &rrc_cfg_nr, phy_cfg); } int parse_default_cfg(rrc_cfg_t* rrc_cfg, srsenb::all_args_t& args) @@ -65,8 +67,9 @@ int parse_default_cfg(rrc_cfg_t* rrc_cfg, srsenb::all_args_t& args) args.general.rrc_inactivity_timer = 60000; phy_cfg_t phy_cfg; + rrc_nr_cfg_t rrc_cfg_nr; - return enb_conf_sections::parse_cfg_files(&args, rrc_cfg, &phy_cfg); + return enb_conf_sections::parse_cfg_files(&args, rrc_cfg, &rrc_cfg_nr, &phy_cfg); } int bring_rrc_to_reconf_state(srsenb::rrc& rrc, srsran::timer_handler& timers, uint16_t rnti) From faf9d2dbd85beba305d2a3233a272b1b83e19fce Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 22 Sep 2021 12:46:01 +0200 Subject: [PATCH 18/83] gnb,rrc: replace hard-coded PCI with actual value in rrc_cfg --- srsenb/hdr/stack/rrc/rrc_nr.h | 1 + srsenb/src/stack/rrc/rrc_nr.cc | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 1531be0c9..4bad93047 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -144,6 +144,7 @@ public: }; private: + static constexpr uint32_t UE_PSCELL_CC_IDX = 0; // first NR cell is always Primary Secondary Cell for UE rrc_nr_cfg_t cfg = {}; // interfaces diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index f5f228722..d424e5a3e 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -500,6 +500,8 @@ void rrc_nr::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg) // Helper for the RRC Reconfiguration sender to pack hard-coded config int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) { + auto& pscell_cfg = parent->cfg.cell_list.at(UE_PSCELL_CC_IDX); + // RLC for DRB1 (with fixed LCID) cell_group_cfg_pack.rlc_bearer_to_add_mod_list_present = true; cell_group_cfg_pack.rlc_bearer_to_add_mod_list.resize(1); @@ -845,7 +847,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dmrs_type_a_position = asn1::rrc_nr::serving_cell_cfg_common_s::dmrs_type_a_position_opts::pos2; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci_present = true; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci = 500; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci = pscell_cfg.phy_cell.carrier.pci; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing = subcarrier_spacing_opts::khz30; From 430694c72f838544ceb2e4d5a231547f7e94441f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 22 Sep 2021 14:04:44 +0200 Subject: [PATCH 19/83] gnb,dl: fix amplitude scaling use PDSCH struct to get number of PRBs to compute scaling factor. then PDCCH struct is only filled if it's encoded. --- lib/src/phy/gnb/gnb_dl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/phy/gnb/gnb_dl.c b/lib/src/phy/gnb/gnb_dl.c index b16a6bd3b..e977007f1 100644 --- a/lib/src/phy/gnb/gnb_dl.c +++ b/lib/src/phy/gnb/gnb_dl.c @@ -167,7 +167,7 @@ void srsran_gnb_dl_gen_signal(srsran_gnb_dl_t* q) return; } - float norm_factor = gnb_dl_get_norm_factor(q->pdcch.carrier.nof_prb); + float norm_factor = gnb_dl_get_norm_factor(q->pdsch.carrier.nof_prb); for (uint32_t i = 0; i < q->nof_tx_antennas; i++) { srsran_ofdm_tx_sf(&q->fft[i]); From 2b16c1b8f531b58246a6d6b2aa160f24fa030d3c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Fri, 10 Sep 2021 18:51:11 +0200 Subject: [PATCH 20/83] Do not accept a UE if n_rb_cqi=0 --- srsenb/src/stack/rrc/rrc_cell_cfg.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_cell_cfg.cc b/srsenb/src/stack/rrc/rrc_cell_cfg.cc index 5b808463b..9524725f2 100644 --- a/srsenb/src/stack/rrc/rrc_cell_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_cell_cfg.cc @@ -359,7 +359,7 @@ bool ue_cell_ded_list::alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t period) // Allocate all CQI resources for all carriers now // Find freq-time resources with least number of users - int i_min = 0, j_min = 0; + int i_min = -1, j_min = -1; uint32_t min_users = std::numeric_limits::max(); for (uint32_t i = 0; i < cfg.sibs[1].sib2().rr_cfg_common.pucch_cfg_common.nrb_cqi; i++) { for (uint32_t j = 0; j < cfg.cqi_cfg.nof_subframes; j++) { @@ -370,7 +370,7 @@ bool ue_cell_ded_list::alloc_cqi_resources(uint32_t ue_cc_idx, uint32_t period) } } } - if (pucch_res->cqi_sched.nof_users[i_min][j_min] > max_users) { + if (pucch_res->cqi_sched.nof_users[i_min][j_min] > max_users || i_min == -1 || j_min == -1) { logger.error("Not enough PUCCH resources to allocate Scheduling Request"); return false; } From 6e18bd1c71dfe64416529b6675c42c1ad68f401e Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 21 Sep 2021 11:59:59 +0200 Subject: [PATCH 21/83] Do not accept a UE if SR resources are defined --- srsenb/src/stack/rrc/rrc_cell_cfg.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_cell_cfg.cc b/srsenb/src/stack/rrc/rrc_cell_cfg.cc index 9524725f2..a922967e4 100644 --- a/srsenb/src/stack/rrc/rrc_cell_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_cell_cfg.cc @@ -460,7 +460,7 @@ bool ue_cell_ded_list::alloc_sr_resources(uint32_t period) uint32_t max_users = 12 * c / delta_pucch_shift; // Find freq-time resources with least number of users - int i_min = 0, j_min = 0; + int i_min = -1, j_min = -1; uint32_t min_users = std::numeric_limits::max(); for (uint32_t i = 0; i < cfg.sr_cfg.nof_prb; i++) { for (uint32_t j = 0; j < cfg.sr_cfg.nof_subframes; j++) { @@ -472,7 +472,7 @@ bool ue_cell_ded_list::alloc_sr_resources(uint32_t period) } } - if (pucch_res->sr_sched.nof_users[i_min][j_min] > max_users) { + if (pucch_res->sr_sched.nof_users[i_min][j_min] > max_users || i_min == -1 || j_min == -1) { logger.error("Not enough PUCCH resources to allocate Scheduling Request"); return false; } From 3bbf17314927f40c8a1f3f47969b5099c7639b95 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 21 Sep 2021 12:46:17 +0200 Subject: [PATCH 22/83] Allocate PUCCH resources on ConnectionRequest and send ConnectionReject if not available --- srsenb/hdr/stack/rrc/rrc_cell_cfg.h | 3 ++- srsenb/hdr/stack/rrc/rrc_ue.h | 3 +++ srsenb/src/stack/rrc/rrc_cell_cfg.cc | 23 ++++++++++++++++++----- srsenb/src/stack/rrc/rrc_mobility.cc | 13 ++++++++++++- srsenb/src/stack/rrc/rrc_ue.cc | 17 +++++++++++++++-- 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_cell_cfg.h b/srsenb/hdr/stack/rrc/rrc_cell_cfg.h index de72d6b9b..a35e85eb0 100644 --- a/srsenb/hdr/stack/rrc/rrc_cell_cfg.h +++ b/srsenb/hdr/stack/rrc/rrc_cell_cfg.h @@ -127,8 +127,9 @@ public: const enb_cell_common_list& enb_common_list); ~ue_cell_ded_list(); - ue_cell_ded* add_cell(uint32_t enb_cc_idx); + ue_cell_ded* add_cell(uint32_t enb_cc_idx, bool init_pucch = true); bool rem_last_cell(); + bool init_pucch_pcell(); bool set_cells(const std::vector& enb_cc_idxs); ue_cell_ded* get_ue_cc_idx(uint32_t ue_cc_idx) { return (ue_cc_idx < nof_cells()) ? &cell_list[ue_cc_idx] : nullptr; } diff --git a/srsenb/hdr/stack/rrc/rrc_ue.h b/srsenb/hdr/stack/rrc/rrc_ue.h index 40f18937b..6a3a25677 100644 --- a/srsenb/hdr/stack/rrc/rrc_ue.h +++ b/srsenb/hdr/stack/rrc/rrc_ue.h @@ -51,6 +51,9 @@ public: void protocol_failure(); void deactivate_bearers() { mac_ctrl.set_radio_bearer_state(mac_lc_ch_cfg_t::IDLE); } + // Init PUCCH resources for PCell + bool init_pucch(); + rrc_state_t get_state(); void get_metrics(rrc_ue_metrics_t& ue_metrics) const; diff --git a/srsenb/src/stack/rrc/rrc_cell_cfg.cc b/srsenb/src/stack/rrc/rrc_cell_cfg.cc index a922967e4..00b0727b8 100644 --- a/srsenb/src/stack/rrc/rrc_cell_cfg.cc +++ b/srsenb/src/stack/rrc/rrc_cell_cfg.cc @@ -170,7 +170,7 @@ const ue_cell_ded* ue_cell_ded_list::find_cell(uint32_t earfcn, uint32_t pci) co return it == cell_list.end() ? nullptr : &(*it); } -ue_cell_ded* ue_cell_ded_list::add_cell(uint32_t enb_cc_idx) +ue_cell_ded* ue_cell_ded_list::add_cell(uint32_t enb_cc_idx, bool init_pucch) { const enb_cell_common* cell_common = common_list.get_cc_idx(enb_cc_idx); if (cell_common == nullptr) { @@ -193,9 +193,11 @@ ue_cell_ded* ue_cell_ded_list::add_cell(uint32_t enb_cc_idx) cell_list.emplace_back(cell_list.size(), *cell_common); // Allocate CQI, SR, and PUCCH CS resources. If failure, do not add new cell - if (not alloc_cell_resources(ue_cc_idx)) { - rem_last_cell(); - return nullptr; + if (init_pucch) { + if (not alloc_cell_resources(ue_cc_idx)) { + rem_last_cell(); + return nullptr; + } } return &cell_list.back(); @@ -216,6 +218,17 @@ bool ue_cell_ded_list::rem_last_cell() return true; } +bool ue_cell_ded_list::init_pucch_pcell() +{ + if (not alloc_cell_resources(UE_PCELL_CC_IDX)) { + dealloc_sr_resources(); + dealloc_pucch_cs_resources(); + dealloc_cqi_resources(UE_PCELL_CC_IDX); + return false; + } + return true; +} + bool ue_cell_ded_list::alloc_cell_resources(uint32_t ue_cc_idx) { const uint32_t meas_gap_duration = 6; @@ -265,7 +278,7 @@ bool ue_cell_ded_list::alloc_cell_resources(uint32_t ue_cc_idx) } } if (not alloc_cqi_resources(ue_cc_idx, cfg.cqi_cfg.period)) { - logger.error("Failed to allocate CQIresources for cell ue_cc_idx=%d", ue_cc_idx); + logger.error("Failed to allocate CQI resources for cell ue_cc_idx=%d", ue_cc_idx); return false; } diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index 00253339f..fa71726e8 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -171,9 +171,20 @@ uint16_t rrc::start_ho_ue_resource_alloc(const asn1::s1ap::ho_request_s& } // Register new user in RRC - add_user(rnti, ue_cfg); + if (add_user(rnti, ue_cfg) != SRSRAN_SUCCESS) { + logger.error("Failed to create user"); + cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::no_radio_res_available_in_target_cell; + return SRSRAN_INVALID_RNTI; + } auto it = users.find(rnti); ue* ue_ptr = it->second.get(); + if (not ue_ptr->init_pucch()) { + rem_user(rnti); + logger.warning("Failed to allocate PUCCH resources for rnti=0x%x", rnti); + cause.set_radio_network().value = asn1::s1ap::cause_radio_network_opts::no_radio_res_available_in_target_cell; + return SRSRAN_INVALID_RNTI; + } + // Reset activity timer (Response is not expected) ue_ptr->set_activity_timeout(ue::UE_INACTIVITY_TIMEOUT); ue_ptr->set_activity(false); diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 0a08278c4..7f3b0a716 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -47,10 +47,16 @@ rrc::ue::ue(rrc* outer_rrc, uint16_t rnti_, const sched_interface::ue_cfg_t& sch rrc::ue::~ue() {} +bool rrc::ue::init_pucch() +{ + // Allocate PUCCH resources for PCell + return ue_cell_list.init_pucch_pcell(); +} + int rrc::ue::init() { - // Allocate cell and PUCCH resources - if (ue_cell_list.add_cell(mac_ctrl.get_ue_sched_cfg().supported_cc_list[0].enb_cc_idx) == nullptr) { + // Allocate cell (PUCCH resources are not allocated here) + if (ue_cell_list.add_cell(mac_ctrl.get_ue_sched_cfg().supported_cc_list[0].enb_cc_idx, false) == nullptr) { return SRSRAN_ERROR; } @@ -436,6 +442,13 @@ void rrc::ue::handle_rrc_con_req(rrc_conn_request_s* msg) return; } + // Allocate PUCCH resources and reject if not available + if (not init_pucch()) { + parent->logger.warning("Could not allocate PUCCH resources for rnti=0x%x. Sending Connection Reject", rnti); + send_connection_reject(procedure_result_code::fail_in_radio_interface_proc); + return; + } + rrc_conn_request_r8_ies_s* msg_r8 = &msg->crit_exts.rrc_conn_request_r8(); if (msg_r8->ue_id.type() == init_ue_id_c::types::s_tmsi) { From 00cc8fb8d838eb6ee0494d19480a204551d41580 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 21 Sep 2021 15:25:35 +0200 Subject: [PATCH 23/83] sched,nr: ensure PUCCH is generated for SR even if the UE doesn't have any pending ACK --- .../stack/mac/nr/sched_nr_grant_allocator.h | 2 + srsenb/hdr/stack/mac/nr/sched_nr_ue.h | 21 +-- srsenb/hdr/stack/mac/nr/sched_nr_worker.h | 1 + srsenb/src/stack/mac/nr/sched_nr_worker.cc | 133 +++++++++++------- 4 files changed, 94 insertions(+), 63 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h b/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h index 17d5d8a0c..a306fc5a6 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h @@ -33,6 +33,7 @@ using slot_coreset_list = std::array; using sched_rar_list_t = sched_nr_interface::sched_rar_list_t; +using pucch_list_t = srsran::bounded_vector; struct harq_ack_t { const srsran::phy_cfg_nr_t* phy_cfg; @@ -49,6 +50,7 @@ struct bwp_slot_grid { pdcch_dl_list_t dl_pdcchs; pdcch_ul_list_t ul_pdcchs; pdsch_list_t pdschs; + pucch_list_t pucch; sched_rar_list_t rar; slot_coreset_list coresets; pusch_list_t puschs; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h index 4b1ab12bf..ca9937e9c 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h @@ -45,16 +45,17 @@ public: int dl_pending_bytes = 0, ul_pending_bytes = 0; // UE parameters that are sector specific - const bwp_ue_cfg* cfg = nullptr; - harq_entity* harq_ent = nullptr; - slot_point pdcch_slot; - slot_point pdsch_slot; - slot_point pusch_slot; - slot_point uci_slot; - uint32_t dl_cqi = 0; - uint32_t ul_cqi = 0; - dl_harq_proc* h_dl = nullptr; - ul_harq_proc* h_ul = nullptr; + const bwp_ue_cfg* cfg = nullptr; + harq_entity* harq_ent = nullptr; + slot_point pdcch_slot; + slot_point pdsch_slot; + slot_point pusch_slot; + slot_point uci_slot; + uint32_t dl_cqi = 0; + uint32_t ul_cqi = 0; + dl_harq_proc* h_dl = nullptr; + ul_harq_proc* h_ul = nullptr; + srsran_uci_cfg_nr_t uci_cfg = {}; }; class ue_carrier diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h b/srsenb/hdr/stack/mac/nr/sched_nr_worker.h index 2dc4c8141..d87404002 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_worker.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_worker.h @@ -52,6 +52,7 @@ private: void alloc_dl_ues(); void alloc_ul_ues(); + void postprocess_decisions(); const sched_cell_params& cfg; serv_cell_manager& cell; diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index 954cc59f2..ca04ef264 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -94,6 +94,9 @@ void slot_cc_worker::run(slot_point pdcch_slot, ue_map_t& ue_db) alloc_dl_ues(); alloc_ul_ues(); + // Post-processing of scheduling decisions + postprocess_decisions(); + // Log CC scheduler result log_sched_bwp_result(logger, bwp_alloc.get_pdcch_tti(), cell.bwps[0].grid, slot_ues); @@ -118,6 +121,82 @@ void slot_cc_worker::alloc_ul_ues() cell.bwps[0].data_sched->sched_ul_users(slot_ues, bwp_alloc); } +void slot_cc_worker::postprocess_decisions() +{ + auto& bwp_slot = cell.bwps[0].grid[bwp_alloc.get_pdcch_tti()]; + srsran_slot_cfg_t slot_cfg{}; + slot_cfg.idx = bwp_alloc.get_pdcch_tti().slot_idx(); + + for (auto& ue_pair : slot_ues) { + auto& ue = ue_pair.second; + // Group pending HARQ ACKs + srsran_pdsch_ack_nr_t ack = {}; + + for (auto& h_ack : bwp_slot.pending_acks) { + if (h_ack.res.rnti == ue.rnti) { + ack.nof_cc = 1; + + srsran_harq_ack_m_t ack_m = {}; + ack_m.resource = h_ack.res; + ack_m.present = true; + srsran_harq_ack_insert_m(&ack, &ack_m); + } + } + + srsran_uci_cfg_nr_t uci_cfg = {}; + if (not ue.cfg->phy().get_uci_cfg(slot_cfg, ack, uci_cfg)) { + logger.error("Error getting UCI configuration"); + continue; + } + + if (ue.h_ul != nullptr and ue.h_ul->harq_slot_tx() == ue.pusch_slot) { + // PUSCH was allocated. Insert UCI in PUSCH + for (auto& pusch : bwp_slot.puschs) { + if (pusch.sch.grant.rnti == ue.rnti) { + // Put UCI configuration in PUSCH config + if (not ue.cfg->phy().get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { + logger.error("Error setting UCI configuration in PUSCH"); + continue; + } + break; + } + } + } else { + // If any UCI information is triggered, schedule PUCCH + if (uci_cfg.ack.count > 0 || uci_cfg.nof_csi > 0 || uci_cfg.o_sr > 0) { + bwp_slot.pucch.emplace_back(); + mac_interface_phy_nr::pucch_t& pucch = bwp_slot.pucch.back(); + + uci_cfg.pucch.rnti = ue.rnti; + pucch.candidates.emplace_back(); + pucch.candidates.back().uci_cfg = uci_cfg; + if (not ue.cfg->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { + logger.error("Error getting UCI CFG"); + continue; + } + + // If this slot has a SR opportunity and the selected PUCCH format is 1, consider positive SR. + if (uci_cfg.o_sr > 0 and uci_cfg.ack.count > 0 and + pucch.candidates.back().resource.format == SRSRAN_PUCCH_NR_FORMAT_1) { + // Set SR negative + if (uci_cfg.o_sr > 0) { + uci_cfg.sr_positive_present = false; + } + + // Append new resource + pucch.candidates.emplace_back(); + pucch.candidates.back().uci_cfg = uci_cfg; + if (not ue.cfg->phy().get_pucch_uci_cfg( + slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { + logger.error("Error getting UCI CFG"); + continue; + } + } + } + } + } +} + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// sched_worker_manager::sched_worker_manager(ue_map_t& ue_db_, @@ -255,59 +334,7 @@ bool sched_worker_manager::save_sched_result(slot_point pdcch_slot, dl_res.dl_sched.pdsch = bwp_slot.pdschs; dl_res.rar = bwp_slot.rar; ul_res.pusch = bwp_slot.puschs; - - // Group pending HARQ ACKs - srsran_pdsch_ack_nr_t ack = {}; - ack.nof_cc = not bwp_slot.pending_acks.empty(); - const srsran::phy_cfg_nr_t* phy_cfg = nullptr; - for (const harq_ack_t& pending_ack : bwp_slot.pending_acks) { - srsran_harq_ack_m_t ack_m = {}; - ack_m.resource = pending_ack.res; - ack_m.present = true; - srsran_harq_ack_insert_m(&ack, &ack_m); - phy_cfg = pending_ack.phy_cfg; - } - - if (phy_cfg != nullptr) { - srsran_slot_cfg_t slot_cfg{}; - slot_cfg.idx = pdcch_slot.slot_idx(); - srsran_uci_cfg_nr_t uci_cfg = {}; - srsran_assert(phy_cfg->get_uci_cfg(slot_cfg, ack, uci_cfg), "Error getting UCI CFG"); - - if (uci_cfg.ack.count > 0 || uci_cfg.nof_csi > 0 || uci_cfg.o_sr > 0) { - if (not ul_res.pusch.empty()) { - // Put UCI configuration in PUSCH config - bool ret = phy_cfg->get_pusch_uci_cfg(slot_cfg, uci_cfg, ul_res.pusch[0].sch); - srsran_assert(ret, "Error setting UCI configuration in PUSCH"); - } else { - // Put UCI configuration in PUCCH config - ul_res.pucch.emplace_back(); - pucch_t& pucch = ul_res.pucch.back(); - pucch.candidates.emplace_back(); - pucch.candidates.back().uci_cfg = uci_cfg; - srsran_assert(phy_cfg->get_pucch_uci_cfg( - slot_cfg, pucch.candidates.back().uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource), - "Error getting PUCCH UCI cfg"); - - // If this slot has a SR opportunity and the selected PUCCH format is 1, consider positive SR. - if (uci_cfg.sr_positive_present and uci_cfg.ack.count > 0 and - pucch.candidates.back().resource.format == SRSRAN_PUCCH_NR_FORMAT_1) { - // Set SR negative - if (uci_cfg.o_sr > 0) { - uci_cfg.sr_positive_present = false; - } - - // Append new resource - pucch.candidates.emplace_back(); - pucch.candidates.back().uci_cfg = uci_cfg; - srsran_assert( - phy_cfg->get_pucch_uci_cfg( - slot_cfg, pucch.candidates.back().uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource), - "Error getting PUCCH UCI cfg"); - } - } - } - } + ul_res.pucch = bwp_slot.pucch; // clear up BWP slot bwp_slot.reset(); From 8d30ed0721f8be50d1e143221dac05c6e1b85b7e Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 21 Sep 2021 17:27:29 +0200 Subject: [PATCH 24/83] sched,nr: ensure PUCCHs are cleared at the end of a slot --- srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index 5cb02b95b..fc16c9a25 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -46,6 +46,7 @@ void bwp_slot_grid::reset() pdschs.clear(); puschs.clear(); pending_acks.clear(); + pucch.clear(); } bwp_res_grid::bwp_res_grid(const bwp_params& bwp_cfg_) : cfg(&bwp_cfg_) From 37bdf53f42dd2010aea0f34736c444c4a37249b0 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 22 Sep 2021 16:45:23 +0200 Subject: [PATCH 25/83] sched,nr: fix SR slot derivation in scheduler --- srsenb/src/stack/mac/nr/sched_nr_worker.cc | 2 +- srsenb/src/stack/rrc/rrc_nr.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index ca04ef264..74e593c50 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -125,7 +125,7 @@ void slot_cc_worker::postprocess_decisions() { auto& bwp_slot = cell.bwps[0].grid[bwp_alloc.get_pdcch_tti()]; srsran_slot_cfg_t slot_cfg{}; - slot_cfg.idx = bwp_alloc.get_pdcch_tti().slot_idx(); + slot_cfg.idx = bwp_alloc.get_pdcch_tti().to_uint(); for (auto& ue_pair : slot_ues) { auto& ue = ue_pair.second; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index d424e5a3e..d62b6e7e4 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -500,7 +500,7 @@ void rrc_nr::ue::send_dl_ccch(dl_ccch_msg_s* dl_ccch_msg) // Helper for the RRC Reconfiguration sender to pack hard-coded config int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg_pack) { - auto& pscell_cfg = parent->cfg.cell_list.at(UE_PSCELL_CC_IDX); + auto& pscell_cfg = parent->cfg.cell_list.at(UE_PSCELL_CC_IDX); // RLC for DRB1 (with fixed LCID) cell_group_cfg_pack.rlc_bearer_to_add_mod_list_present = true; From 5a45767c73e619ca8d99bf0dacf6c0cadf56a5c7 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 22 Sep 2021 17:09:53 +0200 Subject: [PATCH 26/83] sched,nr: fix SR PUCCH resource configuration --- srsenb/src/stack/rrc/rrc_nr.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index d62b6e7e4..7079c1600 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -661,8 +661,8 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group sr_res1.sched_request_res_id = 1; sr_res1.sched_request_id = 0; sr_res1.periodicity_and_offset_present = true; - sr_res1.periodicity_and_offset.set_sl40(); - sr_res1.res_present = true; + sr_res1.periodicity_and_offset.set_sl40() = 8; + sr_res1.res_present = true; // DL data ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack_present = true; @@ -704,8 +704,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group resource_big, ul_config.init_ul_bwp.pucch_cfg.setup().res_to_add_mod_list[1], 1)) { parent->logger.warning("Failed to create >2 bit NR PUCCH resource"); } - if (not srsran::make_phy_res_config( - resource_big, ul_config.init_ul_bwp.pucch_cfg.setup().res_to_add_mod_list[2], 2)) { + if (not srsran::make_phy_res_config(resource_sr, ul_config.init_ul_bwp.pucch_cfg.setup().res_to_add_mod_list[2], 2)) { parent->logger.warning("Failed to create SR NR PUCCH resource"); } @@ -1109,9 +1108,9 @@ int rrc_nr::ue::pack_secondary_cell_group_config_tdd(asn1::dyn_octstring& packed // UL config dedicated auto& ul_config = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg; // SR resources - auto& sr_res1 = ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list[0]; + auto& sr_res1 = ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list[0]; // SR resources - sr_res1.periodicity_and_offset.sl40() = 7; + sr_res1.periodicity_and_offset.sl40() = 8; sr_res1.res_present = true; sr_res1.res = 2; // PUCCH resource for SR From aabec3d7af38520f29fd40fba2e88ac72df580fe Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 22 Sep 2021 17:33:43 +0200 Subject: [PATCH 27/83] sched,nr: forward SRs present in PUCCH from MAC to scheduler --- srsenb/src/stack/mac/nr/mac_nr.cc | 5 +++++ srsenb/src/stack/mac/nr/sched_nr_ue.cc | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 21620d240..017e45f19 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -339,6 +339,11 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg bool is_ok = (value.ack[i] == 1) and value.valid; sched.dl_ack_info(rnti, 0, ack_bit->pid, 0, is_ok); } + + // Process SR + if (value.valid and value.sr > 0) { + sched.ul_sr_info(pdsch_slot - TX_ENB_DELAY, cfg_.pucch.rnti); + } return true; } diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index 528f2d123..a3bee7584 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -119,10 +119,12 @@ void ue::new_slot(slot_point pdcch_slot) auto& cc = carriers[ue_cc_cfg.cc]; if (cc != nullptr) { // Discount UL HARQ pending bytes to BSR - for (uint32_t pid = 0; pid < cc->harq_ent.nof_dl_harqs(); ++pid) { - ul_pending_bytes -= cc->harq_ent.ul_harq(pid).tbs(); - if (last_sr_slot.valid() and cc->harq_ent.ul_harq(pid).harq_slot_tx() > last_sr_slot) { - last_sr_slot.clear(); + for (uint32_t pid = 0; pid < cc->harq_ent.nof_ul_harqs(); ++pid) { + if (not cc->harq_ent.ul_harq(pid).empty()) { + ul_pending_bytes -= cc->harq_ent.ul_harq(pid).tbs(); + if (last_sr_slot.valid() and cc->harq_ent.ul_harq(pid).harq_slot_tx() > last_sr_slot) { + last_sr_slot.clear(); + } } } } From e1a4e63ec823e7fb2020007480177779c73fcba9 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 22 Sep 2021 18:51:54 +0200 Subject: [PATCH 28/83] sched,nr: use MAC-NR as prefix for NR scheduler --- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 2 +- srsenb/src/stack/mac/nr/sched_nr.cc | 4 +++- srsenb/src/stack/mac/nr/sched_nr_cell.cc | 10 +++++++--- srsenb/src/stack/mac/nr/sched_nr_helpers.cc | 3 ++- srsenb/src/stack/mac/nr/sched_nr_worker.cc | 7 +++++-- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index b8fb7c94a..700ba7942 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -69,7 +69,7 @@ public: bool pdsch_enabled = true; bool pusch_enabled = true; bool auto_refill_buffer = false; - std::string logger_name = "MAC"; + std::string logger_name = "MAC-NR"; }; struct ue_cc_cfg_t { diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 53d541aee..b2c503f07 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -65,7 +65,9 @@ private: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -sched_nr::sched_nr(const sched_cfg_t& sched_cfg) : cfg(sched_cfg), logger(srslog::fetch_basic_logger("MAC-NR")) {} +sched_nr::sched_nr(const sched_cfg_t& sched_cfg) : + cfg(sched_cfg), logger(srslog::fetch_basic_logger(sched_cfg.logger_name)) +{} sched_nr::~sched_nr() {} diff --git a/srsenb/src/stack/mac/nr/sched_nr_cell.cc b/srsenb/src/stack/mac/nr/sched_nr_cell.cc index 7caa57e97..909263669 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cell.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_cell.cc @@ -17,7 +17,9 @@ namespace srsenb { namespace sched_nr_impl { -si_sched::si_sched(const bwp_params& bwp_cfg_) : bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger("MAC")) {} +si_sched::si_sched(const bwp_params& bwp_cfg_) : + bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger(bwp_cfg_.sched_cfg.logger_name)) +{} void si_sched::run_slot(bwp_slot_allocator& slot_alloc) { @@ -75,7 +77,9 @@ void si_sched::run_slot(bwp_slot_allocator& slot_alloc) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -ra_sched::ra_sched(const bwp_params& bwp_cfg_) : bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger("MAC")) {} +ra_sched::ra_sched(const bwp_params& bwp_cfg_) : + bwp_cfg(&bwp_cfg_), logger(srslog::fetch_basic_logger(bwp_cfg_.sched_cfg.logger_name)) +{} alloc_result ra_sched::allocate_pending_rar(bwp_slot_allocator& slot_grid, const pending_rar_t& rar, uint32_t& nof_grants_alloc) @@ -223,7 +227,7 @@ bwp_ctxt::bwp_ctxt(const bwp_params& bwp_cfg) : ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// serv_cell_manager::serv_cell_manager(const sched_cell_params& cell_cfg_) : - cfg(cell_cfg_), logger(srslog::fetch_basic_logger("MAC")) + cfg(cell_cfg_), logger(srslog::fetch_basic_logger(cell_cfg_.sched_cfg.logger_name)) { for (uint32_t bwp_id = 0; bwp_id < cfg.cell_cfg.bwps.size(); ++bwp_id) { bwps.emplace_back(cell_cfg_.bwps[bwp_id]); diff --git a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc index ddc49d081..b55b10c81 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc @@ -162,13 +162,14 @@ void log_sched_bwp_result(srslog::basic_logger& logger, if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_c) { const slot_ue& ue = slot_ues[pdcch.dci.ctx.rnti]; fmt::format_to(fmtbuf, - "SCHED: UL {}, cc={}, rnti=0x{:x}, pid={}, f={}, nrtx={}, tbs={}, tti_pusch={}", + "SCHED: UL {}, cc={}, rnti=0x{:x}, pid={}, f={}, nrtx={}, pending_bytes={}, tbs={}, tti_pusch={}", ue.h_ul->nof_retx() == 0 ? "tx" : "retx", res_grid.cfg->cc, ue.rnti, pdcch.dci.pid, srsran_dci_format_nr_string(pdcch.dci.ctx.format), ue.h_ul->nof_retx(), + ue.ul_pending_bytes, ue.h_ul->tbs(), ue.pusch_slot); } else if (pdcch.dci.ctx.rnti_type == srsran_rnti_type_tc) { diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index 74e593c50..2d560036a 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -17,7 +17,10 @@ namespace srsenb { namespace sched_nr_impl { slot_cc_worker::slot_cc_worker(serv_cell_manager& cc_sched) : - cell(cc_sched), cfg(cc_sched.cfg), bwp_alloc(cc_sched.bwps[0].grid), logger(srslog::fetch_basic_logger("MAC")) + cell(cc_sched), + cfg(cc_sched.cfg), + bwp_alloc(cc_sched.bwps[0].grid), + logger(srslog::fetch_basic_logger(cc_sched.cfg.sched_cfg.logger_name)) {} void slot_cc_worker::enqueue_cc_event(srsran::move_callback ev) @@ -202,7 +205,7 @@ void slot_cc_worker::postprocess_decisions() sched_worker_manager::sched_worker_manager(ue_map_t& ue_db_, const sched_params& cfg_, srsran::span > cells_) : - cfg(cfg_), ue_db(ue_db_), logger(srslog::fetch_basic_logger("MAC")), cells(cells_) + cfg(cfg_), ue_db(ue_db_), logger(srslog::fetch_basic_logger(cfg_.sched_cfg.logger_name)), cells(cells_) { cc_worker_list.reserve(cfg.cells.size()); for (uint32_t cc = 0; cc < cfg.cells.size(); ++cc) { From 3351e97aa2c69cca43b3db4abce12c71f2c73389 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 23 Sep 2021 13:13:21 +0200 Subject: [PATCH 29/83] nr,mac: use SR to send an UL grant after Msg3 and complete ContextResolution of UE NSA NR --- srsenb/hdr/stack/mac/nr/sched_nr.h | 2 +- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 2 +- srsenb/hdr/stack/mac/nr/sched_nr_ue.h | 3 ++- srsenb/src/stack/mac/nr/mac_nr.cc | 2 +- srsenb/src/stack/mac/nr/sched_nr.cc | 4 ++-- srsenb/src/stack/mac/nr/sched_nr_ue.cc | 2 ++ srsenb/src/stack/mac/nr/ue_nr.cc | 12 ++++-------- srsenb/src/stack/rrc/rrc_mobility.cc | 11 +++++------ 8 files changed, 18 insertions(+), 20 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr.h b/srsenb/hdr/stack/mac/nr/sched_nr.h index 9ed0debd5..6249dd9c1 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr.h @@ -47,7 +47,7 @@ public: void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) override; void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) override; - void ul_sr_info(slot_point slot_rx, uint16_t rnti) override; + void ul_sr_info(uint16_t rnti) override; void ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) override; void dl_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t newtx, uint32_t retx); diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index 700ba7942..fa9e30e26 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -125,7 +125,7 @@ public: virtual void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) = 0; virtual void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) = 0; - virtual void ul_sr_info(slot_point, uint16_t rnti) = 0; + virtual void ul_sr_info(uint16_t rnti) = 0; virtual void ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) = 0; }; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h index ca9937e9c..3887e23ff 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h @@ -92,7 +92,7 @@ public: void rlc_buffer_state(uint32_t lcid, uint32_t newtx, uint32_t retx) { buffers.dl_buffer_state(lcid, newtx, retx); } void ul_bsr(uint32_t lcg, uint32_t bsr_val) { buffers.ul_bsr(lcg, bsr_val); } - void ul_sr_info(slot_point slot_rx) { last_sr_slot = slot_rx; } + void ul_sr_info() { last_sr_slot = last_pdcch_slot - TX_ENB_DELAY; } bool has_ca() const { @@ -109,6 +109,7 @@ private: const uint16_t rnti; const sched_params& sched_cfg; + slot_point last_pdcch_slot; slot_point last_sr_slot; int ul_pending_bytes = 0, dl_pending_bytes = 0; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 017e45f19..62e68301b 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -342,7 +342,7 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg // Process SR if (value.valid and value.sr > 0) { - sched.ul_sr_info(pdsch_slot - TX_ENB_DELAY, cfg_.pucch.rnti); + sched.ul_sr_info(cfg_.pucch.rnti); } return true; } diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index b2c503f07..65df395e4 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -163,9 +163,9 @@ void sched_nr::ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) sched_workers->enqueue_cc_feedback(rnti, cc, [pid, crc](ue_carrier& ue_cc) { ue_cc.harq_ent.ul_crc_info(pid, crc); }); } -void sched_nr::ul_sr_info(slot_point slot_rx, uint16_t rnti) +void sched_nr::ul_sr_info(uint16_t rnti) { - sched_workers->enqueue_event(rnti, [this, rnti, slot_rx]() { ue_db[rnti]->ul_sr_info(slot_rx); }); + sched_workers->enqueue_event(rnti, [this, rnti]() { ue_db[rnti]->ul_sr_info(); }); } void sched_nr::ul_bsr(uint16_t rnti, uint32_t lcg_id, uint32_t bsr) diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index a3bee7584..5f9156db3 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -100,6 +100,8 @@ void ue::set_cfg(const ue_cfg_t& cfg) void ue::new_slot(slot_point pdcch_slot) { + last_pdcch_slot = pdcch_slot; + for (auto& ue_cc_cfg : ue_cfg.carriers) { auto& cc = carriers[ue_cc_cfg.cc]; if (cc != nullptr) { diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index ae45ba81d..75e89061d 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -68,7 +68,7 @@ int ue_nr::process_pdu(srsran::unique_byte_buffer_t pdu) if (logger.info.enabled()) { fmt::memory_buffer str_buffer; mac_pdu_ul.to_string(str_buffer); - logger.info("0x%x %s", rnti, srsran::to_c_str(str_buffer)); + logger.info("Rx PDU: rnti=0x%x, %s", rnti, srsran::to_c_str(str_buffer)); } for (uint32_t i = 0; i < mac_pdu_ul.get_num_subpdus(); ++i) { @@ -86,7 +86,7 @@ int ue_nr::process_pdu(srsran::unique_byte_buffer_t pdu) if (true /*sched->ue_exists(c_crnti)*/) { rrc->update_user(rnti, c_rnti); rnti = c_rnti; - sched->ul_bsr(rnti, 0, 1); // provide UL grant regardless of other BSR content for UE to complete RA + sched->ul_sr_info(rnti); // provide UL grant regardless of other BSR content for UE to complete RA } else { logger.warning("Updating user C-RNTI: rnti=0x%x already released.", c_rnti); // Disable scheduling for all bearers. The new rnti will be removed on msg3 timer expiry in the RRC @@ -99,10 +99,6 @@ int ue_nr::process_pdu(srsran::unique_byte_buffer_t pdu) case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::SHORT_TRUNC_BSR: { srsran::mac_sch_subpdu_nr::lcg_bsr_t sbsr = subpdu.get_sbsr(); uint32_t buffer_size_bytes = buff_size_field_to_bytes(sbsr.buffer_size, srsran::SHORT_BSR); - // FIXME: a UE might send a zero BSR but still needs an UL grant to finish RA procedure - if (buffer_size_bytes == 0) { - buffer_size_bytes++; - } sched->ul_bsr(rnti, sbsr.lcg_id, buffer_size_bytes); } break; case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::LONG_BSR: @@ -172,8 +168,8 @@ void ue_nr::metrics_read(mac_ue_metrics_t* metrics_) // set PCell sector id std::array cc_list; //= sched->get_enb_ue_cc_map(rnti); - auto it = std::find(cc_list.begin(), cc_list.end(), 0); - ue_metrics.cc_idx = std::distance(cc_list.begin(), it); + auto it = std::find(cc_list.begin(), cc_list.end(), 0); + ue_metrics.cc_idx = std::distance(cc_list.begin(), it); *metrics_ = ue_metrics; diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index fa71726e8..9c2ca8fe9 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -239,7 +239,6 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg, srsr } if (meas_res.meas_result_neigh_cells.type().value != meas_results_s::meas_result_neigh_cells_c_::types::meas_result_list_eutra) { - Error("MeasReports regarding non-EUTRA are not supported!"); return; } const meas_id_list& measid_list = rrc_ue->current_ue_cfg.meas_cfg.meas_id_to_add_mod_list; @@ -861,11 +860,11 @@ void rrc::ue::rrc_mobility::handle_ho_requested(idle_st& s, const ho_req_rx_ev& if (ho_req.transparent_container->erab_info_list_present) { const auto& lst = ho_req.transparent_container->erab_info_list; const auto* it = std::find_if( - lst.begin(), - lst.end(), - [&erab](const asn1::s1ap::protocol_ie_single_container_s& fwd_erab) { + lst.begin(), + lst.end(), + [&erab](const asn1::s1ap::protocol_ie_single_container_s& fwd_erab) { return fwd_erab.value.erab_info_list_item().erab_id == erab.second.id; - }); + }); if (it == lst.end()) { continue; } @@ -1044,7 +1043,7 @@ void rrc::ue::rrc_mobility::handle_status_transfer(s1_target_ho_st& s, const sta const auto& drbs = rrc_ue->bearer_list.get_established_drbs(); lte_drb drbid = lte_lcid_to_drb(erab_it->second.lcid); auto drb_it = std::find_if( - drbs.begin(), drbs.end(), [drbid](const drb_to_add_mod_s& drb) { return (lte_drb)drb.drb_id == drbid; }); + drbs.begin(), drbs.end(), [drbid](const drb_to_add_mod_s& drb) { return (lte_drb)drb.drb_id == drbid; }); if (drb_it == drbs.end()) { logger.warning("The DRB id=%d does not exist", drbid); } From af9822bede41fd49a10b57c5601a7a89af371b9c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 23 Sep 2021 10:15:07 +0200 Subject: [PATCH 30/83] srsenb: add error handling on RRC message generation --- srsenb/hdr/stack/rrc/ue_rr_cfg.h | 20 +++---- srsenb/src/stack/rrc/rrc_ue.cc | 17 ++++-- srsenb/src/stack/rrc/ue_rr_cfg.cc | 90 +++++++++++++++++++------------ 3 files changed, 78 insertions(+), 49 deletions(-) diff --git a/srsenb/hdr/stack/rrc/ue_rr_cfg.h b/srsenb/hdr/stack/rrc/ue_rr_cfg.h index 54e57d78a..4874a556c 100644 --- a/srsenb/hdr/stack/rrc/ue_rr_cfg.h +++ b/srsenb/hdr/stack/rrc/ue_rr_cfg.h @@ -45,18 +45,18 @@ class bearer_cfg_handler; struct ue_var_cfg_t; /// Fill RadioResourceConfigDedicated with data known at the RRCSetup/Reestablishment stage -void fill_rr_cfg_ded_setup(asn1::rrc::rr_cfg_ded_s& rr_cfg, - const rrc_cfg_t& enb_cfg, - const ue_cell_ded_list& ue_cell_list); +int fill_rr_cfg_ded_setup(asn1::rrc::rr_cfg_ded_s& rr_cfg, + const rrc_cfg_t& enb_cfg, + const ue_cell_ded_list& ue_cell_list); /// Apply Reconf updates and update current state -void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, - ue_var_cfg_t& current_ue_cfg, - const rrc_cfg_t& enb_cfg, - const ue_cell_ded_list& ue_cell_list, - bearer_cfg_handler& bearers, - const srsran::rrc_ue_capabilities_t& ue_caps, - bool phy_cfg_updated); +int apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, + ue_var_cfg_t& current_ue_cfg, + const rrc_cfg_t& enb_cfg, + const ue_cell_ded_list& ue_cell_list, + bearer_cfg_handler& bearers, + const srsran::rrc_ue_capabilities_t& ue_caps, + bool phy_cfg_updated); /// Apply radioResourceConfigDedicated updates to the current UE RRC configuration void apply_rr_cfg_ded_diff(asn1::rrc::rr_cfg_ded_s& current_rr_cfg_ded, diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 7f3b0a716..7b85348a1 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -485,7 +485,10 @@ void rrc::ue::send_connection_setup() rr_cfg_ded_s& rr_cfg = setup_r8.rr_cfg_ded; // Fill RR config dedicated - fill_rr_cfg_ded_setup(rr_cfg, parent->cfg, ue_cell_list); + if (fill_rr_cfg_ded_setup(rr_cfg, parent->cfg, ue_cell_list)) { + parent->logger.error("Generating ConnectionSetup. Aborting"); + return; + } // Apply ConnectionSetup Configuration to MAC scheduler mac_ctrl.handle_con_setup(setup_r8); @@ -704,7 +707,10 @@ void rrc::ue::send_connection_reest(uint8_t ncc) rr_cfg_ded_s& rr_cfg = reest_r8.rr_cfg_ded; // Fill RR config dedicated - fill_rr_cfg_ded_setup(rr_cfg, parent->cfg, ue_cell_list); + if (fill_rr_cfg_ded_setup(rr_cfg, parent->cfg, ue_cell_list)) { + parent->logger.error("Generating ConnectionReestablishment. Aborting..."); + return; + } // Set NCC reest_r8.next_hop_chaining_count = ncc; @@ -811,8 +817,11 @@ void rrc::ue::send_connection_reconf(srsran::unique_byte_buffer_t pdu, rrc_conn_recfg_r8_ies_s& recfg_r8 = rrc_conn_recfg.crit_exts.set_c1().set_rrc_conn_recfg_r8(); // Fill RR Config Ded and SCells - apply_reconf_updates( - recfg_r8, current_ue_cfg, parent->cfg, ue_cell_list, bearer_list, ue_capabilities, phy_cfg_updated); + if (apply_reconf_updates( + recfg_r8, current_ue_cfg, parent->cfg, ue_cell_list, bearer_list, ue_capabilities, phy_cfg_updated)) { + parent->logger.error("Generating ConnectionReconfiguration. Aborting..."); + return; + } // Add measConfig if (mobility_handler != nullptr) { diff --git a/srsenb/src/stack/rrc/ue_rr_cfg.cc b/srsenb/src/stack/rrc/ue_rr_cfg.cc index acad59a39..c46f3e9f4 100644 --- a/srsenb/src/stack/rrc/ue_rr_cfg.cc +++ b/srsenb/src/stack/rrc/ue_rr_cfg.cc @@ -66,11 +66,17 @@ void fill_srbs_reconf(srb_to_add_mod_list_l& srbs, const srb_to_add_mod_list_l& * SR Config *****************************/ -void fill_sr_cfg_setup(sched_request_cfg_c& sr_cfg, const ue_cell_ded_list& ue_cell_list) +int fill_sr_cfg_setup(sched_request_cfg_c& sr_cfg, const ue_cell_ded_list& ue_cell_list) { - auto& setup = sr_cfg.setup(); - setup.sr_cfg_idx = ue_cell_list.get_sr_res()->sr_I; - setup.sr_pucch_res_idx = ue_cell_list.get_sr_res()->sr_N_pucch; + if (ue_cell_list.get_sr_res()) { + auto& setup = sr_cfg.setup(); + setup.sr_cfg_idx = ue_cell_list.get_sr_res()->sr_I; + setup.sr_pucch_res_idx = ue_cell_list.get_sr_res()->sr_N_pucch; + return SRSRAN_SUCCESS; + } else { + srslog::fetch_basic_logger("RRC").error("SR resource is not configured."); + return SRSRAN_ERROR; + } } /****************************** @@ -152,11 +158,11 @@ int fill_cqi_report_setup(cqi_report_cfg_s& cqi_rep, const rrc_cfg_t& enb_cfg, c return SRSRAN_SUCCESS; } -void fill_cqi_report_reconf(cqi_report_cfg_s& cqi_rep, const rrc_cfg_t& enb_cfg, const ue_cell_ded_list& ue_cell_list) +int fill_cqi_report_reconf(cqi_report_cfg_s& cqi_rep, const rrc_cfg_t& enb_cfg, const ue_cell_ded_list& ue_cell_list) { // Get RRC setup CQI config if (fill_cqi_report_setup(cqi_rep, enb_cfg, ue_cell_list) == SRSRAN_ERROR) { - return; + return SRSRAN_ERROR; } if (cqi_rep.cqi_report_mode_aperiodic_present) { @@ -180,9 +186,11 @@ void fill_cqi_report_reconf(cqi_report_cfg_s& cqi_rep, const rrc_cfg_t& enb_cfg, cqi_setup.ri_cfg_idx = ri_idx; } else { srslog::fetch_basic_logger("RRC").warning("Warning: Configured wrong M_ri parameter."); + return SRSRAN_ERROR; } } } + return SRSRAN_SUCCESS; } /****************************** @@ -231,26 +239,33 @@ void fill_phy_cfg_ded_enb_cfg(phys_cfg_ded_s& phy_cfg, const rrc_cfg_t& enb_cfg) fill_cqi_report_enb_cfg(phy_cfg.cqi_report_cfg, enb_cfg); } -void fill_phy_cfg_ded_setup(phys_cfg_ded_s& phy_cfg, const rrc_cfg_t& enb_cfg, const ue_cell_ded_list& ue_cell_list) +int fill_phy_cfg_ded_setup(phys_cfg_ded_s& phy_cfg, const rrc_cfg_t& enb_cfg, const ue_cell_ded_list& ue_cell_list) { // Set PHYConfigDedicated base fill_phy_cfg_ded_enb_cfg(phy_cfg, enb_cfg); // Setup SR PUCCH config - fill_sr_cfg_setup(phy_cfg.sched_request_cfg, ue_cell_list); + if (fill_sr_cfg_setup(phy_cfg.sched_request_cfg, ue_cell_list)) { + return SRSRAN_ERROR; + } // Setup CQI PUCCH config - fill_cqi_report_setup(phy_cfg.cqi_report_cfg, enb_cfg, ue_cell_list); + if (fill_cqi_report_setup(phy_cfg.cqi_report_cfg, enb_cfg, ue_cell_list)) { + return SRSRAN_ERROR; + } + return SRSRAN_SUCCESS; } /// Fills ASN1 PhysicalConfigurationDedicated struct with eNB config params at RRCReconf -void fill_phy_cfg_ded_reconf(phys_cfg_ded_s& phy_cfg, - const rrc_cfg_t& enb_cfg, - const ue_cell_ded_list& ue_cell_list, - const srsran::rrc_ue_capabilities_t& ue_caps) +int fill_phy_cfg_ded_reconf(phys_cfg_ded_s& phy_cfg, + const rrc_cfg_t& enb_cfg, + const ue_cell_ded_list& ue_cell_list, + const srsran::rrc_ue_capabilities_t& ue_caps) { // Use RRCSetup as starting point - fill_phy_cfg_ded_setup(phy_cfg, enb_cfg, ue_cell_list); + if (fill_phy_cfg_ded_setup(phy_cfg, enb_cfg, ue_cell_list)) { + return SRSRAN_ERROR; + } // Antenna Configuration ant_info_ded_s& ant_info = phy_cfg.ant_info.explicit_value(); @@ -267,6 +282,7 @@ void fill_phy_cfg_ded_reconf(phys_cfg_ded_s& phy_cfg, phy_cfg.cqi_report_cfg_pcell_v1250->alt_cqi_table_r12.value = cqi_report_cfg_v1250_s::alt_cqi_table_r12_opts::all_sfs; } + return SRSRAN_SUCCESS; } /*********************************** @@ -296,9 +312,9 @@ void fill_rr_cfg_ded_enb_cfg(asn1::rrc::rr_cfg_ded_s& rr_cfg, const rrc_cfg_t& e rr_cfg.sps_cfg_present = false; } -void fill_rr_cfg_ded_setup(asn1::rrc::rr_cfg_ded_s& rr_cfg, - const rrc_cfg_t& enb_cfg, - const ue_cell_ded_list& ue_cell_list) +int fill_rr_cfg_ded_setup(asn1::rrc::rr_cfg_ded_s& rr_cfg, + const rrc_cfg_t& enb_cfg, + const ue_cell_ded_list& ue_cell_list) { // Establish default enb config fill_rr_cfg_ded_enb_cfg(rr_cfg, enb_cfg); @@ -309,16 +325,16 @@ void fill_rr_cfg_ded_setup(asn1::rrc::rr_cfg_ded_s& rr_cfg, // Setup SR/CQI configs rr_cfg.phys_cfg_ded_present = true; - fill_phy_cfg_ded_setup(rr_cfg.phys_cfg_ded, enb_cfg, ue_cell_list); + return fill_phy_cfg_ded_setup(rr_cfg.phys_cfg_ded, enb_cfg, ue_cell_list); } -void fill_rr_cfg_ded_reconf(asn1::rrc::rr_cfg_ded_s& rr_cfg, - const rr_cfg_ded_s& current_rr_cfg, - const rrc_cfg_t& enb_cfg, - const ue_cell_ded_list& ue_cell_list, - const bearer_cfg_handler& bearers, - const srsran::rrc_ue_capabilities_t& ue_caps, - bool phy_cfg_updated) +int fill_rr_cfg_ded_reconf(asn1::rrc::rr_cfg_ded_s& rr_cfg, + const rr_cfg_ded_s& current_rr_cfg, + const rrc_cfg_t& enb_cfg, + const ue_cell_ded_list& ue_cell_list, + const bearer_cfg_handler& bearers, + const srsran::rrc_ue_capabilities_t& ue_caps, + bool phy_cfg_updated) { // (Re)establish SRBs fill_srbs_reconf(rr_cfg.srb_to_add_mod_list, current_rr_cfg.srb_to_add_mod_list, enb_cfg); @@ -335,8 +351,9 @@ void fill_rr_cfg_ded_reconf(asn1::rrc::rr_cfg_ded_s& rr_cfg, // PhysCfgDed update needed if (phy_cfg_updated) { rr_cfg.phys_cfg_ded_present = true; - fill_phy_cfg_ded_reconf(rr_cfg.phys_cfg_ded, enb_cfg, ue_cell_list, ue_caps); + return fill_phy_cfg_ded_reconf(rr_cfg.phys_cfg_ded, enb_cfg, ue_cell_list, ue_caps); } + return SRSRAN_SUCCESS; } /** @@ -560,18 +577,20 @@ void apply_scells_to_add_diff(asn1::rrc::scell_to_add_mod_list_r10_l& current_sc **********************************/ /// Apply Reconf updates and update current state -void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, - ue_var_cfg_t& current_ue_cfg, - const rrc_cfg_t& enb_cfg, - const ue_cell_ded_list& ue_cell_list, - bearer_cfg_handler& bearers, - const srsran::rrc_ue_capabilities_t& ue_caps, - bool phy_cfg_updated) +int apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, + ue_var_cfg_t& current_ue_cfg, + const rrc_cfg_t& enb_cfg, + const ue_cell_ded_list& ue_cell_list, + bearer_cfg_handler& bearers, + const srsran::rrc_ue_capabilities_t& ue_caps, + bool phy_cfg_updated) { // Compute pending updates and fill reconf msg recfg_r8.rr_cfg_ded_present = true; - fill_rr_cfg_ded_reconf( - recfg_r8.rr_cfg_ded, current_ue_cfg.rr_cfg, enb_cfg, ue_cell_list, bearers, ue_caps, phy_cfg_updated); + if (fill_rr_cfg_ded_reconf( + recfg_r8.rr_cfg_ded, current_ue_cfg.rr_cfg, enb_cfg, ue_cell_list, bearers, ue_caps, phy_cfg_updated)) { + return SRSRAN_ERROR; + } fill_scells_reconf(recfg_r8, current_ue_cfg.scells, enb_cfg, ue_cell_list, ue_caps); recfg_r8.meas_cfg_present |= recfg_r8.meas_cfg.meas_gap_cfg_present; @@ -581,6 +600,7 @@ void apply_reconf_updates(asn1::rrc::rrc_conn_recfg_r8_ies_s& recfg_r8, // Update current rr_cfg_ded and scells state apply_rr_cfg_ded_diff(current_ue_cfg.rr_cfg, recfg_r8.rr_cfg_ded); apply_scells_to_add_diff(current_ue_cfg.scells, recfg_r8); + return SRSRAN_SUCCESS; } } // namespace srsenb From 1c44546c0b3d8e25d7dbe865654086bdd0161ec3 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 23 Sep 2021 10:17:11 +0200 Subject: [PATCH 31/83] srsenb: allocate pucch for new UE on reestablishment request --- srsenb/src/stack/rrc/rrc_ue.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 7b85348a1..b087727a4 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -609,6 +609,14 @@ void rrc::ue::handle_rrc_con_reest_req(rrc_conn_reest_request_s* msg) srsran::console("RRCReestablishmentReject for rnti=0x%x. Cause: MME not connected.\n", rnti); return; } + + // Allocate PUCCH resources and reject if not available + if (not init_pucch()) { + parent->logger.warning("Could not allocate PUCCH resources for rnti=0x%x. Sending RRCReestablishmentReject", rnti); + send_connection_reest_rej(procedure_result_code::fail_in_radio_interface_proc); + return; + } + parent->logger.debug("rnti=0x%x, phyid=0x%x, smac=0x%x, cause=%s", (uint32_t)msg->crit_exts.rrc_conn_reest_request_r8().ue_id.c_rnti.to_number(), msg->crit_exts.rrc_conn_reest_request_r8().ue_id.pci, From bc4388a78c37ae0855f8bfa3a4b689ca8c097b49 Mon Sep 17 00:00:00 2001 From: yagoda Date: Thu, 23 Sep 2021 00:12:31 +0100 Subject: [PATCH 32/83] -adding temp crnti removal for NR carrier attach --- .../srsran/interfaces/gnb_mac_interfaces.h | 2 ++ srsenb/hdr/stack/mac/nr/mac_nr.h | 2 +- srsenb/hdr/stack/rrc/rrc_nr.h | 1 + srsenb/src/stack/mac/nr/mac_nr.cc | 1 + srsenb/src/stack/rrc/rrc_nr.cc | 21 +++++++++++++++++-- srsenb/test/common/dummy_classes_nr.h | 2 ++ 6 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/include/srsran/interfaces/gnb_mac_interfaces.h b/lib/include/srsran/interfaces/gnb_mac_interfaces.h index 0d233824e..482909617 100644 --- a/lib/include/srsran/interfaces/gnb_mac_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_mac_interfaces.h @@ -27,6 +27,8 @@ public: virtual uint16_t reserve_rnti(uint32_t enb_cc_idx) = 0; virtual int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) = 0; + + virtual int remove_ue(uint16_t rnti) = 0; }; // NR interface is identical to EUTRA interface diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index e59d6ff97..a9cbeb0c5 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -54,6 +54,7 @@ public: uint16_t reserve_rnti(uint32_t enb_cc_idx) override; int read_pdu_bcch_bch(uint8_t* payload); int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) override; + int remove_ue(uint16_t rnti) override; // MAC interface for RLC // TODO: @@ -71,7 +72,6 @@ public: private: uint16_t add_ue_(uint32_t enb_cc_idx); uint16_t alloc_ue(uint32_t enb_cc_idx); - int remove_ue(uint16_t rnti); // internal misc helpers bool is_rnti_valid_unsafe(uint16_t rnti); diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 4bad93047..5d53332bf 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -63,6 +63,7 @@ public: rrc_nr_cfg_t update_default_cfg(const rrc_nr_cfg_t& rrc_cfg); int add_user(uint16_t rnti); + void rem_user(uint16_t rnti); int update_user(uint16_t new_rnti, uint16_t old_rnti); void config_phy(); void config_mac(); diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 62e68301b..14dd154c1 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -169,6 +169,7 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) rar_info.prach_slot = slot_point{NUMEROLOGY_IDX, rach_info.slot_index}; // TODO: fill remaining fields as required sched.dl_rach_info(enb_cc_idx, rar_info); + rrc->add_user(rnti); logger.info("RACH: slot=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x", rach_info.slot_index, diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 7079c1600..d450f196c 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -158,6 +158,24 @@ int rrc_nr::add_user(uint16_t rnti) } } +void rrc_nr::rem_user(uint16_t rnti) +{ + auto user_it = users.find(rnti); + if (user_it != users.end()) { + printf("Disconnecting rnti=0x%x.\n", rnti); + logger.info("Disconnecting rnti=0x%x.", rnti); + /* First remove MAC and GTPU to stop processing DL/UL traffic for this user + */ + mac->remove_ue(rnti); // MAC handles PHY + rlc->rem_user(rnti); + pdcp->rem_user(rnti); + users.erase(rnti); + logger.info("Removed user rnti=0x%x", rnti); + } else { + logger.error("Removing user rnti=0x%x (does not exist)", rnti); + } +} + /* Function called by MAC after the reception of a C-RNTI CE indicating that the UE still has a * valid RNTI. */ @@ -166,8 +184,7 @@ int rrc_nr::update_user(uint16_t new_rnti, uint16_t old_rnti) // Remove new_rnti auto new_ue_it = users.find(new_rnti); if (new_ue_it != users.end()) { - // TODO: cleanup new user? - return SRSRAN_ERROR; + task_sched.defer_task([this, new_rnti]() { rem_user(new_rnti); }); } // Send Reconfiguration to old_rnti if is RRC_CONNECT or RRC Release if already released here diff --git a/srsenb/test/common/dummy_classes_nr.h b/srsenb/test/common/dummy_classes_nr.h index 501f7a327..3464c878e 100644 --- a/srsenb/test/common/dummy_classes_nr.h +++ b/srsenb/test/common/dummy_classes_nr.h @@ -43,6 +43,8 @@ public: int ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) override { return SRSRAN_SUCCESS; } + int remove_ue(uint16_t rnti) override { return SRSRAN_SUCCESS; } + srsenb::sched_interface::cell_cfg_t cellcfgobj; }; From 426e876047a4afb32c3868fdad432254ad361c03 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 23 Sep 2021 16:09:36 +0200 Subject: [PATCH 33/83] enb,nr: fix GTPU handler to forward UL PDUs --- lib/include/srsran/interfaces/enb_gtpu_interfaces.h | 3 ++- lib/include/srsran/interfaces/enb_x2_interfaces.h | 4 +++- srsenb/hdr/stack/enb_stack_lte.h | 3 +++ srsenb/hdr/x2_adapter.h | 9 +++++++++ srsenb/src/stack/enb_stack_lte.cc | 6 ++++++ srsenb/src/stack/gnb_stack_nr.cc | 2 +- 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_gtpu_interfaces.h b/lib/include/srsran/interfaces/enb_gtpu_interfaces.h index b9ec2f364..b18c50520 100644 --- a/lib/include/srsran/interfaces/enb_gtpu_interfaces.h +++ b/lib/include/srsran/interfaces/enb_gtpu_interfaces.h @@ -31,7 +31,8 @@ struct gtpu_args_t { class gtpu_interface_pdcp { public: - virtual void write_pdu(uint16_t rnti, uint32_t bearer_id, srsran::unique_byte_buffer_t pdu) = 0; + // PDCP will only know LCIDs, translation to EPS bearer id will be done by gtpu_pdcp_adapter + virtual void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) = 0; }; // GTPU interface for RRC diff --git a/lib/include/srsran/interfaces/enb_x2_interfaces.h b/lib/include/srsran/interfaces/enb_x2_interfaces.h index a5b503ee3..cc0495153 100644 --- a/lib/include/srsran/interfaces/enb_x2_interfaces.h +++ b/lib/include/srsran/interfaces/enb_x2_interfaces.h @@ -10,6 +10,7 @@ * */ +#include "srsran/interfaces/enb_gtpu_interfaces.h" #include "srsran/interfaces/enb_pdcp_interfaces.h" #include "srsran/interfaces/enb_rrc_interface_types.h" @@ -93,7 +94,8 @@ public: class x2_interface : public rrc_nr_interface_rrc, public rrc_eutra_interface_rrc_nr, public stack_nr_interface_stack_eutra, - public pdcp_interface_gtpu + public pdcp_interface_gtpu, // allow GTPU to access PDCP in DL direction + public gtpu_interface_pdcp // allow PDCP to access GTPU in UL direction {}; } // namespace srsenb diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index 2ec367b67..eb4fd384d 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -119,6 +119,9 @@ public: rrc.sgnb_addition_complete(eutra_rnti, nr_rnti); } + // gtpu_interface_pdcp + void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu); + private: static const int STACK_MAIN_THREAD_PRIO = 4; // thread loop diff --git a/srsenb/hdr/x2_adapter.h b/srsenb/hdr/x2_adapter.h index 047533af8..22037945c 100644 --- a/srsenb/hdr/x2_adapter.h +++ b/srsenb/hdr/x2_adapter.h @@ -110,6 +110,15 @@ public: return nr_stack->get_buffered_pdus(rnti, lcid); } + // gtpu_interface_pdcp + void write_pdu(uint16_t rnti, uint32_t bearer_id, srsran::unique_byte_buffer_t pdu) + { + if (eutra_stack == nullptr) { + return; + } + eutra_stack->write_pdu(rnti, bearer_id, std::move(pdu)); + } + private: enb_stack_lte* eutra_stack = nullptr; gnb_stack_nr* nr_stack = nullptr; diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index ec25ad053..640857c6f 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -281,4 +281,10 @@ void enb_stack_lte::run_thread() } } +void enb_stack_lte::write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) +{ + // call GTPU adapter to map to EPS bearer + gtpu_adapter->write_pdu(rnti, lcid, std::move(pdu)); +} + } // namespace srsenb diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index fad435c01..bef8ec076 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -80,7 +80,7 @@ int gnb_stack_nr::init(const srsenb::stack_args_t& args_, } rlc.init(&pdcp, &rrc, &mac, task_sched.get_timer_handler()); - pdcp.init(&rlc, &rrc, nullptr); + pdcp.init(&rlc, &rrc, x2_); if (rrc.init(rrc_cfg_, phy, &mac, &rlc, &pdcp, nullptr, nullptr, x2_) != SRSRAN_SUCCESS) { stack_logger.error("Couldn't initialize RRC"); From 7f897d83e2e7255c433a793ce4c74ff30abdbf9d Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 23 Sep 2021 16:48:38 +0200 Subject: [PATCH 34/83] gnb,mac_nr: push DL buffer state to scheduler --- srsenb/hdr/stack/mac/nr/mac_nr.h | 3 +-- srsenb/src/stack/mac/nr/mac_nr.cc | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index a9cbeb0c5..8f66cbcbf 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -57,8 +57,7 @@ public: int remove_ue(uint16_t rnti) override; // MAC interface for RLC - // TODO: - int rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) override { return 0; } + int rlc_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t tx_queue, uint32_t retx_queue) override; // Interface for PHY void process_pdus(); diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 14dd154c1..72b31b8f9 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -131,6 +131,12 @@ int mac_nr::ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) return SRSRAN_SUCCESS; } +int mac_nr::rlc_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t tx_queue, uint32_t retx_queue) +{ + sched.dl_buffer_state(rnti, lcid, tx_queue, retx_queue); + return SRSRAN_SUCCESS; +} + uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx) { uint16_t rnti = alloc_ue(enb_cc_idx); From 12d63468e399af840758da8bd6643017e33f390e Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 24 Aug 2021 14:37:53 +0200 Subject: [PATCH 35/83] sched,lte: separated adaptive mcs learning rate argument into two arguments, one for DL and the other for UL --- srsenb/enb.conf.example | 6 ++++-- srsenb/hdr/stack/mac/sched_interface.h | 3 ++- srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h | 3 ++- srsenb/src/main.cc | 3 ++- .../src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc | 14 ++++++++------ 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index a76b90874..bbc402425 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -178,7 +178,8 @@ enable = false # target_bler: Target BLER (in decimal) to achieve via adaptive link # max_delta_dl_cqi: Maximum shift in CQI for adaptive DL link # max_delta_ul_snr: Maximum shift in UL SNR for adaptive UL link -# adaptive_link_step_size: Step size or learning rate used in adaptive link +# adaptive_dl_mcs_step_size: Step size or learning rate used in adaptive DL MCS link +# adaptive_ul_mcs_step_size: Step size or learning rate used in adaptive UL MCS link # min_tpc_tti_interval: Minimum TTI interval between TPCs different than 1 # ul_snr_avg_alpha: Exponential Average alpha coefficient used in estimation of UL SNR # init_ul_snr_value: Initial UL SNR value used for computing MCS in the first UL grant @@ -204,7 +205,8 @@ enable = false #target_bler = 0.05 #max_delta_dl_cqi = 5 #max_delta_ul_snr = 5 -#adaptive_link_step_size = 0.001 +#adaptive_dl_mcs_step_size = 0.001 +#adaptive_ul_mcs_step_size = 0.001 #min_tpc_tti_interval = 1 #ul_snr_avg_alpha=0.05 #init_ul_snr_value=5 diff --git a/srsenb/hdr/stack/mac/sched_interface.h b/srsenb/hdr/stack/mac/sched_interface.h index 4f5f166ea..0401deee4 100644 --- a/srsenb/hdr/stack/mac/sched_interface.h +++ b/srsenb/hdr/stack/mac/sched_interface.h @@ -62,7 +62,8 @@ public: float target_bler = 0.05; float max_delta_dl_cqi = 5; float max_delta_ul_snr = 5; - float adaptive_link_step_size = 0.001; + float adaptive_dl_mcs_step_size = 0.001; + float adaptive_ul_mcs_step_size = 0.001; uint32_t min_tpc_tti_interval = 1; float ul_snr_avg_alpha = 0.05; int init_ul_snr_value = 5; diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h index e71e6b8b8..b0f34d5c4 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_ue_cell.h @@ -94,7 +94,8 @@ private: cc_st cc_state_ = cc_st::idle; // CQI - float delta_inc = 0, delta_dec = 0; + float ul_delta_inc = 0, ul_delta_dec = 0; + float dl_delta_inc = 0, dl_delta_dec = 0; float dl_cqi_coeff = 0, ul_snr_coeff = 0; float max_cqi_coeff = -5, max_snr_coeff = 5; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 37647a001..da428aba8 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -156,7 +156,8 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("scheduler.target_bler", bpo::value(&args->stack.mac.sched.target_bler)->default_value(0.05), "Target BLER (in decimal) to achieve via adaptive link") ("scheduler.max_delta_dl_cqi", bpo::value(&args->stack.mac.sched.max_delta_dl_cqi)->default_value(5.0), "Maximum shift in CQI for adaptive DL link") ("scheduler.max_delta_ul_snr", bpo::value(&args->stack.mac.sched.max_delta_ul_snr)->default_value(5.0), "Maximum shift in UL SNR for adaptive UL link") - ("scheduler.adaptive_link_step_size", bpo::value(&args->stack.mac.sched.adaptive_link_step_size)->default_value(0.001), "Step size or learning rate used in adaptive link") + ("scheduler.adaptive_dl_mcs_step_size", bpo::value(&args->stack.mac.sched.adaptive_dl_mcs_step_size)->default_value(0.001), "Step size or learning rate used in adaptive DL MCS link") + ("scheduler.adaptive_ul_mcs_step_size", bpo::value(&args->stack.mac.sched.adaptive_ul_mcs_step_size)->default_value(0.001), "Step size or learning rate used in adaptive UL MCS link") ("scheduler.min_tpc_tti_interval", bpo::value(&args->stack.mac.sched.min_tpc_tti_interval)->default_value(1), "Minimum TTI interval between positive or negative TPCs") ("scheduler.ul_snr_avg_alpha", bpo::value(&args->stack.mac.sched.ul_snr_avg_alpha)->default_value(0.05), "Exponential Average alpha coefficient used in estimation of UL SNR") ("scheduler.init_ul_snr_value", bpo::value(&args->stack.mac.sched.init_ul_snr_value)->default_value(5), "Initial UL SNR value used for computing MCS in the first UL grant") diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc index 24dd95133..b29acdbba 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_ue_cell.cc @@ -51,8 +51,10 @@ sched_ue_cell::sched_ue_cell(uint16_t rnti_, const sched_cell_params_t& cell_cfg dl_cqi_ctxt(cell_cfg_.nof_prb(), 0, cell_cfg_.sched_cfg->init_dl_cqi) { float target_bler = cell_cfg->sched_cfg->target_bler; - delta_inc = cell_cfg->sched_cfg->adaptive_link_step_size; // delta_{down} of OLLA - delta_dec = (1 - target_bler) * delta_inc / target_bler; + dl_delta_inc = cell_cfg->sched_cfg->adaptive_dl_mcs_step_size; // delta_{down} of OLLA + dl_delta_dec = (1 - target_bler) * dl_delta_inc / target_bler; + ul_delta_inc = cell_cfg->sched_cfg->adaptive_ul_mcs_step_size; // delta_{down} of OLLA + ul_delta_dec = (1 - target_bler) * ul_delta_inc / target_bler; max_cqi_coeff = cell_cfg->sched_cfg->max_delta_dl_cqi; max_snr_coeff = cell_cfg->sched_cfg->max_delta_ul_snr; } @@ -202,8 +204,8 @@ int sched_ue_cell::set_ul_crc(tti_point tti_rx, bool crc_res) if (ul_harq != nullptr) { int mcs = ul_harq->get_mcs(0); // Note: Avoid keeping increasing the snr delta offset, if MCS is already is at its limit - float delta_dec_eff = mcs <= 0 ? 0 : delta_dec; - float delta_inc_eff = mcs >= (int)max_mcs_ul ? 0 : delta_inc; + float delta_dec_eff = mcs <= 0 ? 0 : ul_delta_dec; + float delta_inc_eff = mcs >= (int)max_mcs_ul ? 0 : ul_delta_inc; ul_snr_coeff += crc_res ? delta_inc_eff : -delta_dec_eff; ul_snr_coeff = std::min(std::max(-max_snr_coeff, ul_snr_coeff), max_snr_coeff); logger.info("SCHED: UL adaptive link: rnti=0x%x, snr_estim=%.2f, last_mcs=%d, snr_offset=%f", @@ -239,8 +241,8 @@ int sched_ue_cell::set_ack_info(tti_point tti_rx, uint32_t tb_idx, bool ack) if (cell_cfg->sched_cfg->target_bler > 0 and fixed_mcs_dl < 0) { int mcs = std::get<2>(p2); // Note: Avoid keeping increasing the snr delta offset, if MCS is already is at its limit - float delta_dec_eff = mcs <= 0 ? 0 : delta_dec; - float delta_inc_eff = mcs >= (int)max_mcs_dl ? 0 : delta_inc; + float delta_dec_eff = mcs <= 0 ? 0 : dl_delta_dec; + float delta_inc_eff = mcs >= (int)max_mcs_dl ? 0 : dl_delta_inc; dl_cqi_coeff += ack ? delta_inc_eff : -delta_dec_eff; dl_cqi_coeff = std::min(std::max(-max_cqi_coeff, dl_cqi_coeff), max_cqi_coeff); logger.info("SCHED: DL adaptive link: rnti=0x%x, cqi=%d, last_mcs=%d, cqi_offset=%f", From af73c57780a9bc158f004c5f3debaf19c7b41ae1 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 22 Sep 2021 17:00:25 +0200 Subject: [PATCH 36/83] rrc_endc: prepare ENDC paramter exposes some of the hard-coded params as struct. filling/parsing from file still needs to be added. --- srsenb/hdr/stack/rrc/rrc_endc.h | 12 ++++++++- srsenb/src/stack/rrc/rrc_endc.cc | 42 ++++++++++++++------------------ srsenb/src/stack/rrc/rrc_ue.cc | 3 ++- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index 842367d88..c5d747cf1 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -48,7 +48,16 @@ public: uint16_t nr_rnti; /// RNTI assigned to UE on NR carrier }; - rrc_endc(srsenb::rrc::ue* outer_ue); + // Parameter of the (NR)-carrier required for NR cell measurement handling + struct rrc_endc_cfg_t { + bool act_from_b1_event = true; // ENDC will only be activated from B1 measurment + uint32_t nr_dl_arfcn = 634176; + uint32_t nr_band = 78; + asn1::rrc::rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_e_ ssb_ssc = + asn1::rrc::rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::khz15; + }; + + rrc_endc(srsenb::rrc::ue* outer_ue, const rrc_endc_cfg_t& endc_cfg_); bool fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg); void handle_eutra_capabilities(const asn1::rrc::ue_eutra_cap_s& eutra_caps); @@ -68,6 +77,7 @@ private: // vars bool endc_supported = false; + rrc_endc_cfg_t endc_cfg = {}; asn1::rrc::rrc_conn_recfg_complete_s pending_recfg_complete; // fixed ENDC variables diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index e9465a1e3..d3d812f94 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -29,8 +29,12 @@ using namespace asn1::rrc; * rrc_endc class ************************************************************************************************/ -rrc::ue::rrc_endc::rrc_endc(rrc::ue* outer_ue) : - base_t(outer_ue->parent->logger), rrc_ue(outer_ue), rrc_enb(outer_ue->parent), logger(outer_ue->parent->logger) +rrc::ue::rrc_endc::rrc_endc(rrc::ue* outer_ue, const rrc_endc_cfg_t& endc_cfg_) : + base_t(outer_ue->parent->logger), + rrc_ue(outer_ue), + rrc_enb(outer_ue->parent), + logger(outer_ue->parent->logger), + endc_cfg(endc_cfg_) {} //! Method to add NR fields to a RRC Connection Reconfiguration Message @@ -41,7 +45,7 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn return false; } - if (not is_endc_activation_running()) { + if (not is_endc_activation_running() && endc_cfg.act_from_b1_event) { // add hard-coded measConfig conn_recfg->meas_cfg_present = true; meas_cfg_s& meas_cfg = conn_recfg->meas_cfg; @@ -50,26 +54,16 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn meas_obj_to_add_mod_s meas_obj = {}; meas_obj.meas_obj_id = meas_cfg.meas_obj_to_add_mod_list.size() + 1; - meas_obj.meas_obj.set_meas_obj_eutra(); - meas_obj.meas_obj.meas_obj_eutra().carrier_freq = 300; - meas_obj.meas_obj.meas_obj_eutra().allowed_meas_bw = allowed_meas_bw_opts::mbw50; - meas_obj.meas_obj.meas_obj_eutra().presence_ant_port1 = false; - meas_obj.meas_obj.meas_obj_eutra().neigh_cell_cfg.from_number(0b01); - meas_cfg.meas_obj_to_add_mod_list.push_back(meas_obj); - - meas_obj_to_add_mod_s meas_obj2 = {}; - meas_obj2.meas_obj_id = meas_cfg.meas_obj_to_add_mod_list.size() + 1; - meas_obj2.meas_obj.set_meas_obj_nr_r15(); - meas_obj2.meas_obj.meas_obj_nr_r15().carrier_freq_r15 = 634176; - meas_obj2.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.meas_timing_cfg_r15.periodicity_and_offset_r15.set_sf20_r15(); - meas_obj2.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.meas_timing_cfg_r15.ssb_dur_r15 = + meas_obj.meas_obj.set_meas_obj_nr_r15(); + meas_obj.meas_obj.meas_obj_nr_r15().carrier_freq_r15 = endc_cfg.nr_dl_arfcn; + meas_obj.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.meas_timing_cfg_r15.periodicity_and_offset_r15.set_sf20_r15(); + meas_obj.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.meas_timing_cfg_r15.ssb_dur_r15 = asn1::rrc::mtc_ssb_nr_r15_s::ssb_dur_r15_opts::sf1; - meas_obj2.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.subcarrier_spacing_ssb_r15 = - asn1::rrc::rs_cfg_ssb_nr_r15_s::subcarrier_spacing_ssb_r15_opts::khz30; - meas_obj2.meas_obj.meas_obj_nr_r15().ext = true; - meas_obj2.meas_obj.meas_obj_nr_r15().band_nr_r15.set_present(true); - meas_obj2.meas_obj.meas_obj_nr_r15().band_nr_r15.get()->set_setup() = 78; - meas_cfg.meas_obj_to_add_mod_list.push_back(meas_obj2); + meas_obj.meas_obj.meas_obj_nr_r15().rs_cfg_ssb_r15.subcarrier_spacing_ssb_r15 = endc_cfg.ssb_ssc; + meas_obj.meas_obj.meas_obj_nr_r15().ext = true; + meas_obj.meas_obj.meas_obj_nr_r15().band_nr_r15.set_present(true); + meas_obj.meas_obj.meas_obj_nr_r15().band_nr_r15.get()->set_setup() = endc_cfg.nr_band; + meas_cfg.meas_obj_to_add_mod_list.push_back(meas_obj); // report config meas_cfg.report_cfg_to_add_mod_list_present = true; @@ -105,8 +99,8 @@ bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn // measIdToAddModList meas_cfg.meas_id_to_add_mod_list_present = true; meas_id_to_add_mod_s meas_id = {}; - meas_id.meas_id = meas_obj.meas_obj_id; - meas_id.meas_obj_id = meas_obj2.meas_obj_id; + meas_id.meas_id = meas_cfg.meas_id_to_add_mod_list.size() + 1; + meas_id.meas_obj_id = meas_obj.meas_obj_id; meas_id.report_cfg_id = report_cfg.report_cfg_id; meas_cfg.meas_id_to_add_mod_list.push_back(meas_id); diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index b087727a4..6714e07e8 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -87,7 +87,8 @@ int rrc::ue::init() mobility_handler = make_rnti_obj(rnti, this); if (parent->rrc_nr != nullptr) { - endc_handler = make_rnti_obj(rnti, this); + rrc::ue::rrc_endc::rrc_endc_cfg_t endc_cfg = {}; // TODO: set or derive parameter in eNB config + endc_handler = make_rnti_obj(rnti, this, endc_cfg); } return SRSRAN_SUCCESS; From 59667604582b5cabb49c5874967395b615001a5e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 22 Sep 2021 17:12:44 +0200 Subject: [PATCH 37/83] rrc_endc: start SgNB addition from start if B1 events are disabled --- srsenb/hdr/stack/rrc/rrc_endc.h | 4 ++-- srsenb/src/stack/rrc/rrc_endc.cc | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_endc.h b/srsenb/hdr/stack/rrc/rrc_endc.h index c5d747cf1..949417e49 100644 --- a/srsenb/hdr/stack/rrc/rrc_endc.h +++ b/srsenb/hdr/stack/rrc/rrc_endc.h @@ -66,8 +66,8 @@ public: bool is_endc_supported(); private: - // Send SgNB addition request to gNB - bool start_sgnb_addition(); + // Send SgNB addition request to gNB (either triggered through MeasReport or upon start) + void start_sgnb_addition(); bool is_endc_activation_running() const { return not is_in_state(); } diff --git a/srsenb/src/stack/rrc/rrc_endc.cc b/srsenb/src/stack/rrc/rrc_endc.cc index d3d812f94..3f6d059f7 100644 --- a/srsenb/src/stack/rrc/rrc_endc.cc +++ b/srsenb/src/stack/rrc/rrc_endc.cc @@ -35,7 +35,12 @@ rrc::ue::rrc_endc::rrc_endc(rrc::ue* outer_ue, const rrc_endc_cfg_t& endc_cfg_) rrc_enb(outer_ue->parent), logger(outer_ue->parent->logger), endc_cfg(endc_cfg_) -{} +{ + // start SgNB activation if B1 events are disabled + if (endc_cfg.act_from_b1_event == false) { + start_sgnb_addition(); + } +} //! Method to add NR fields to a RRC Connection Reconfiguration Message bool rrc::ue::rrc_endc::fill_conn_recfg(asn1::rrc::rrc_conn_recfg_r8_ies_s* conn_recfg) @@ -237,6 +242,11 @@ void rrc::ue::rrc_endc::handle_ue_meas_report(const meas_report_s& msg) return; } + start_sgnb_addition(); +} + +void rrc::ue::rrc_endc::start_sgnb_addition() +{ // Start EN-DC activation using EPS bearer of EUTRA DRB1 rrc_nr_interface_rrc::sgnb_addition_req_params_t params = {}; params.eps_bearer_id = From 7cdb9c00c0596a710661b336bcdb42655ab60178 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 23 Sep 2021 16:21:37 +0200 Subject: [PATCH 38/83] enb,rrc: disable log error when non-EUTRA reports arrive since this will be cause an Error log for NR events --- srsenb/src/stack/rrc/rrc_mobility.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index 9c2ca8fe9..c6dfddd45 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -239,6 +239,7 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg, srsr } if (meas_res.meas_result_neigh_cells.type().value != meas_results_s::meas_result_neigh_cells_c_::types::meas_result_list_eutra) { + Debug("Skipping non-EUTRA MeasReport."); return; } const meas_id_list& measid_list = rrc_ue->current_ue_cfg.meas_cfg.meas_id_to_add_mod_list; From 8a38a896525937d523683ac15e6d54387356e8f5 Mon Sep 17 00:00:00 2001 From: faluco Date: Thu, 23 Sep 2021 10:42:28 +0200 Subject: [PATCH 39/83] Fix compiler warning: control reaches end of non-void function --- lib/src/phy/phch/regs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/src/phy/phch/regs.c b/lib/src/phy/phch/regs.c index f52829d59..c48ba8d7b 100644 --- a/lib/src/phy/phch/regs.c +++ b/lib/src/phy/phch/regs.c @@ -607,6 +607,7 @@ int regs_num_x_symbol(uint32_t symbol, uint32_t nof_port, srsran_cp_t cp) ERROR("Invalid symbol %d", symbol); return SRSRAN_ERROR; } + return SRSRAN_ERROR; } /** From a035ad144bd37a62886d1740010eab02ea8c16f6 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Mon, 20 Sep 2021 15:17:11 +0200 Subject: [PATCH 40/83] mac,nr: create sched_nr object only at mac::init() --- srsenb/hdr/stack/mac/nr/mac_nr.h | 21 +++++++++++---------- srsenb/src/stack/mac/nr/mac_nr.cc | 30 ++++++++++++++++-------------- test/phy/dummy_gnb_stack.h | 10 +++++----- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index 8f66cbcbf..5d8cdac40 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -28,16 +28,17 @@ namespace srsenb { struct mac_nr_args_t { - srsran::phy_cfg_nr_t phy_base_cfg = {}; - int fixed_dl_mcs = -1; - int fixed_ul_mcs = -1; - srsenb::pcap_args_t pcap; + srsran::phy_cfg_nr_t phy_base_cfg = {}; + int fixed_dl_mcs = -1; + int fixed_ul_mcs = -1; + sched_nr_interface::sched_cfg_t sched_cfg = {}; + srsenb::pcap_args_t pcap; }; class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, public mac_interface_rlc_nr { public: - mac_nr(srsran::task_sched_handle task_sched_, const srsenb::sched_nr_interface::sched_cfg_t& sched_cfg = {}); + explicit mac_nr(srsran::task_sched_handle task_sched_); ~mac_nr(); int init(const mac_nr_args_t& args_, @@ -83,7 +84,7 @@ private: int handle_pdu(srsran::unique_byte_buffer_t pdu); // Encoding - srsran::byte_buffer_t* assemble_rar(srsran::const_span grants); + srsran::byte_buffer_t* assemble_rar(srsran::const_span grants); srsran::unique_byte_buffer_t rar_pdu_buffer = nullptr; // Interaction with other components @@ -102,10 +103,10 @@ private: std::atomic started = {false}; - const static uint32_t NUMEROLOGY_IDX = 0; /// only 15kHz supported at this stage - srsran::slot_point pdsch_slot, pusch_slot; - srsenb::sched_nr sched; - std::vector cell_config; + const static uint32_t NUMEROLOGY_IDX = 0; /// only 15kHz supported at this stage + srsran::slot_point pdsch_slot, pusch_slot; + std::unique_ptr sched; + std::vector cell_config; // Map of active UEs pthread_rwlock_t rwlock = {}; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 72b31b8f9..a7075bd6e 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -26,10 +26,9 @@ namespace srsenb { -mac_nr::mac_nr(srsran::task_sched_handle task_sched_, const sched_nr_interface::sched_cfg_t& sched_cfg) : +mac_nr::mac_nr(srsran::task_sched_handle task_sched_) : logger(srslog::fetch_basic_logger("MAC-NR")), task_sched(task_sched_), - sched(sched_cfg), bcch_bch_payload(srsran::make_byte_buffer()), rar_pdu_buffer(srsran::make_byte_buffer()) { @@ -49,6 +48,7 @@ int mac_nr::init(const mac_nr_args_t& args_, { args = args_; + sched.reset(new sched_nr{args.sched_cfg}); phy = phy_; stack = stack_; rlc = rlc_; @@ -82,7 +82,7 @@ void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) srsran::rwlock_read_guard lock(rwlock); metrics.ues.reserve(ue_db.size()); for (auto& u : ue_db) { - if (not sched.ue_exists(u.first)) { + if (not sched->ue_exists(u.first)) { continue; } metrics.ues.emplace_back(); @@ -98,7 +98,7 @@ void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) int mac_nr::cell_cfg(const std::vector& nr_cells) { cell_config = nr_cells; - sched.cell_cfg(nr_cells); + sched->cell_cfg(nr_cells); detected_rachs.resize(nr_cells.size()); // read SIBs from RRC (SIB1 for now only) @@ -127,7 +127,7 @@ int mac_nr::cell_cfg(const std::vector& int mac_nr::ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) { - sched.ue_cfg(rnti, ue_cfg); + sched->ue_cfg(rnti, ue_cfg); return SRSRAN_SUCCESS; } @@ -148,7 +148,7 @@ uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx) srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1); ue_cfg.fixed_dl_mcs = args.fixed_dl_mcs; ue_cfg.fixed_ul_mcs = args.fixed_ul_mcs; - sched.ue_cfg(rnti, ue_cfg); + sched->ue_cfg(rnti, ue_cfg); return rnti; } @@ -174,7 +174,7 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) rar_info.ta_cmd = rach_info.time_adv; rar_info.prach_slot = slot_point{NUMEROLOGY_IDX, rach_info.slot_index}; // TODO: fill remaining fields as required - sched.dl_rach_info(enb_cc_idx, rar_info); + sched->dl_rach_info(enb_cc_idx, rar_info); rrc->add_user(rnti); logger.info("RACH: slot=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x", @@ -210,7 +210,8 @@ uint16_t mac_nr::alloc_ue(uint32_t enb_cc_idx) } // Allocate and initialize UE object - std::unique_ptr ue_ptr = std::unique_ptr(new ue_nr(rnti, enb_cc_idx, &sched, rrc, rlc, phy, logger)); + std::unique_ptr ue_ptr = + std::unique_ptr(new ue_nr(rnti, enb_cc_idx, sched.get(), rrc, rlc, phy, logger)); // Add UE to rnti map srsran::rwlock_write_guard rw_lock(rwlock); @@ -284,7 +285,7 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched } sched_nr_interface::dl_sched_res_t dl_res; - int ret = sched.get_dl_sched(pdsch_slot, 0, dl_res); + int ret = sched->get_dl_sched(pdsch_slot, 0, dl_res); if (ret != SRSRAN_SUCCESS) { return ret; } @@ -312,7 +313,7 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched } else if (pdsch.sch.grant.rnti_type == srsran_rnti_type_ra) { sched_nr_interface::sched_rar_t& rar = dl_res.rar[rar_count++]; // for RARs we could actually move the byte_buffer to the PHY, as there are no retx - pdsch.data[0] = assemble_rar(rar.grants); + pdsch.data[0] = assemble_rar(rar.grants); } } return SRSRAN_SUCCESS; @@ -326,7 +327,7 @@ int mac_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched pusch_slot++; } - return sched.get_ul_sched(pusch_slot, 0, ul_sched); + return sched->get_ul_sched(pusch_slot, 0, ul_sched); } int mac_nr::pucch_info(const srsran_slot_cfg_t& slot_cfg, const mac_interface_phy_nr::pucch_info_t& pucch_info) @@ -344,7 +345,7 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg for (uint32_t i = 0; i < cfg_.ack.count; i++) { const srsran_harq_ack_bit_t* ack_bit = &cfg_.ack.bits[i]; bool is_ok = (value.ack[i] == 1) and value.valid; - sched.dl_ack_info(rnti, 0, ack_bit->pid, 0, is_ok); + sched->dl_ack_info(rnti, 0, ack_bit->pid, 0, is_ok); } // Process SR @@ -364,7 +365,7 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: return SRSRAN_ERROR; } - sched.ul_crc_info(rnti, 0, pusch_info.pid, pusch_info.pusch_data.tb[0].crc); + sched->ul_crc_info(rnti, 0, pusch_info.pid, pusch_info.pusch_data.tb[0].crc); // process only PDUs with CRC=OK if (pusch_info.pusch_data.tb[0].crc) { @@ -418,7 +419,8 @@ srsran::byte_buffer_t* mac_nr::assemble_rar(srsran::const_span packed_ul_grant = {}; - std::copy(std::begin(dci_msg.payload), std::begin(dci_msg.payload)+SRSRAN_RAR_UL_GRANT_NBITS, packed_ul_grant.begin()); + std::copy( + std::begin(dci_msg.payload), std::begin(dci_msg.payload) + SRSRAN_RAR_UL_GRANT_NBITS, packed_ul_grant.begin()); rar_subpdu.set_ul_grant(packed_ul_grant); } diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index d487e8aa4..f134e939e 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -338,11 +338,11 @@ public: srslog::fetch_basic_logger("MAC-NR").set_level(srslog::str_to_basic_level(args.log_level)); // create sched object - srsenb::sched_nr_interface::sched_cfg_t sched_cfg{}; - sched_cfg.pdsch_enabled = args.pdsch.slots != "" and args.pdsch.slots != "none"; - sched_cfg.pusch_enabled = args.pusch.slots != "" and args.pusch.slots != "none"; - mac.reset(new srsenb::mac_nr{&task_sched, sched_cfg}); - mac->init(srsenb::mac_nr_args_t{}, nullptr, nullptr, &rlc_obj, &rrc_obj); + mac.reset(new srsenb::mac_nr{&task_sched}); + srsenb::mac_nr_args_t mac_args{}; + mac_args.sched_cfg.pdsch_enabled = args.pdsch.slots != "" and args.pdsch.slots != "none"; + mac_args.sched_cfg.pusch_enabled = args.pusch.slots != "" and args.pusch.slots != "none"; + mac->init(mac_args, nullptr, nullptr, &rlc_obj, &rrc_obj); std::vector cells_cfg = srsenb::get_default_cells_cfg(1, phy_cfg); mac->cell_cfg(cells_cfg); From 70fe48a5ab6c95412ca8259f518a89ed93a8c82b Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 23 Sep 2021 15:50:07 +0200 Subject: [PATCH 41/83] sched,nr: change NR sched configuration api --- srsenb/hdr/stack/mac/nr/mac_nr.h | 2 +- srsenb/hdr/stack/mac/nr/sched_nr.h | 6 +++--- srsenb/hdr/stack/mac/nr/sched_nr_cfg.h | 3 ++- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 14 ++++++------- srsenb/src/stack/mac/nr/mac_nr.cc | 22 +++++++++----------- srsenb/src/stack/mac/nr/sched_nr.cc | 15 ++++++------- srsenb/test/mac/nr/sched_nr_sim_ue.cc | 4 ++-- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index 5d8cdac40..fb7de2523 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -105,7 +105,7 @@ private: const static uint32_t NUMEROLOGY_IDX = 0; /// only 15kHz supported at this stage srsran::slot_point pdsch_slot, pusch_slot; - std::unique_ptr sched; + srsenb::sched_nr sched; std::vector cell_config; // Map of active UEs diff --git a/srsenb/hdr/stack/mac/nr/sched_nr.h b/srsenb/hdr/stack/mac/nr/sched_nr.h index 6249dd9c1..8608f7e00 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr.h @@ -36,9 +36,9 @@ class ul_sched_result_buffer; class sched_nr final : public sched_nr_interface { public: - explicit sched_nr(const sched_cfg_t& sched_cfg); + explicit sched_nr(); ~sched_nr() override; - int cell_cfg(srsran::const_span cell_list) override; + int config(const sched_cfg_t& sched_cfg, srsran::const_span cell_list) override; void ue_cfg(uint16_t rnti, const ue_cfg_t& cfg) override; void ue_rem(uint16_t rnti) override; bool ue_exists(uint16_t rnti) override; @@ -59,7 +59,7 @@ private: // args sched_nr_impl::sched_params cfg; - srslog::basic_logger& logger; + srslog::basic_logger* logger = nullptr; using sched_worker_manager = sched_nr_impl::sched_worker_manager; std::unique_ptr sched_workers; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h index be7e2657c..210e34921 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h @@ -93,9 +93,10 @@ struct sched_cell_params { }; struct sched_params { - const sched_cfg_t sched_cfg; + sched_cfg_t sched_cfg; std::vector cells; + sched_params() = default; explicit sched_params(const sched_cfg_t& sched_cfg_); }; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index fa9e30e26..ddf73d661 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -115,13 +115,13 @@ public: dl_sched_t dl_sched; }; - virtual ~sched_nr_interface() = default; - virtual int cell_cfg(srsran::const_span ue_cfg) = 0; - virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; - virtual void ue_rem(uint16_t rnti) = 0; - virtual bool ue_exists(uint16_t rnti) = 0; - virtual int get_dl_sched(slot_point slot_rx, uint32_t cc, dl_sched_res_t& result) = 0; - virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_sched_t& result) = 0; + virtual ~sched_nr_interface() = default; + virtual int config(const sched_cfg_t& sched_cfg, srsran::const_span ue_cfg) = 0; + virtual void ue_cfg(uint16_t rnti, const ue_cfg_t& ue_cfg) = 0; + virtual void ue_rem(uint16_t rnti) = 0; + virtual bool ue_exists(uint16_t rnti) = 0; + virtual int get_dl_sched(slot_point slot_rx, uint32_t cc, dl_sched_res_t& result) = 0; + virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_sched_t& result) = 0; virtual void dl_ack_info(uint16_t rnti, uint32_t cc, uint32_t pid, uint32_t tb_idx, bool ack) = 0; virtual void ul_crc_info(uint16_t rnti, uint32_t cc, uint32_t pid, bool crc) = 0; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index a7075bd6e..65da81474 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -48,7 +48,6 @@ int mac_nr::init(const mac_nr_args_t& args_, { args = args_; - sched.reset(new sched_nr{args.sched_cfg}); phy = phy_; stack = stack_; rlc = rlc_; @@ -82,7 +81,7 @@ void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) srsran::rwlock_read_guard lock(rwlock); metrics.ues.reserve(ue_db.size()); for (auto& u : ue_db) { - if (not sched->ue_exists(u.first)) { + if (not sched.ue_exists(u.first)) { continue; } metrics.ues.emplace_back(); @@ -98,7 +97,7 @@ void mac_nr::get_metrics(srsenb::mac_metrics_t& metrics) int mac_nr::cell_cfg(const std::vector& nr_cells) { cell_config = nr_cells; - sched->cell_cfg(nr_cells); + sched.config(args.sched_cfg, nr_cells); detected_rachs.resize(nr_cells.size()); // read SIBs from RRC (SIB1 for now only) @@ -127,7 +126,7 @@ int mac_nr::cell_cfg(const std::vector& int mac_nr::ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) { - sched->ue_cfg(rnti, ue_cfg); + sched.ue_cfg(rnti, ue_cfg); return SRSRAN_SUCCESS; } @@ -148,7 +147,7 @@ uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx) srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1); ue_cfg.fixed_dl_mcs = args.fixed_dl_mcs; ue_cfg.fixed_ul_mcs = args.fixed_ul_mcs; - sched->ue_cfg(rnti, ue_cfg); + sched.ue_cfg(rnti, ue_cfg); return rnti; } @@ -174,7 +173,7 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) rar_info.ta_cmd = rach_info.time_adv; rar_info.prach_slot = slot_point{NUMEROLOGY_IDX, rach_info.slot_index}; // TODO: fill remaining fields as required - sched->dl_rach_info(enb_cc_idx, rar_info); + sched.dl_rach_info(enb_cc_idx, rar_info); rrc->add_user(rnti); logger.info("RACH: slot=%d, cc=%d, preamble=%d, offset=%d, temp_crnti=0x%x", @@ -210,8 +209,7 @@ uint16_t mac_nr::alloc_ue(uint32_t enb_cc_idx) } // Allocate and initialize UE object - std::unique_ptr ue_ptr = - std::unique_ptr(new ue_nr(rnti, enb_cc_idx, sched.get(), rrc, rlc, phy, logger)); + std::unique_ptr ue_ptr = std::unique_ptr(new ue_nr(rnti, enb_cc_idx, &sched, rrc, rlc, phy, logger)); // Add UE to rnti map srsran::rwlock_write_guard rw_lock(rwlock); @@ -285,7 +283,7 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched } sched_nr_interface::dl_sched_res_t dl_res; - int ret = sched->get_dl_sched(pdsch_slot, 0, dl_res); + int ret = sched.get_dl_sched(pdsch_slot, 0, dl_res); if (ret != SRSRAN_SUCCESS) { return ret; } @@ -327,7 +325,7 @@ int mac_nr::get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched pusch_slot++; } - return sched->get_ul_sched(pusch_slot, 0, ul_sched); + return sched.get_ul_sched(pusch_slot, 0, ul_sched); } int mac_nr::pucch_info(const srsran_slot_cfg_t& slot_cfg, const mac_interface_phy_nr::pucch_info_t& pucch_info) @@ -345,7 +343,7 @@ bool mac_nr::handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg for (uint32_t i = 0; i < cfg_.ack.count; i++) { const srsran_harq_ack_bit_t* ack_bit = &cfg_.ack.bits[i]; bool is_ok = (value.ack[i] == 1) and value.valid; - sched->dl_ack_info(rnti, 0, ack_bit->pid, 0, is_ok); + sched.dl_ack_info(rnti, 0, ack_bit->pid, 0, is_ok); } // Process SR @@ -365,7 +363,7 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: return SRSRAN_ERROR; } - sched->ul_crc_info(rnti, 0, pusch_info.pid, pusch_info.pusch_data.tb[0].crc); + sched.ul_crc_info(rnti, 0, pusch_info.pid, pusch_info.pusch_data.tb[0].crc); // process only PDUs with CRC=OK if (pusch_info.pusch_data.tb[0].crc) { diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 65df395e4..967ef774e 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -65,14 +65,15 @@ private: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -sched_nr::sched_nr(const sched_cfg_t& sched_cfg) : - cfg(sched_cfg), logger(srslog::fetch_basic_logger(sched_cfg.logger_name)) -{} +sched_nr::sched_nr() : logger(&srslog::fetch_basic_logger("MAC-NR")) {} sched_nr::~sched_nr() {} -int sched_nr::cell_cfg(srsran::const_span cell_list) +int sched_nr::config(const sched_cfg_t& sched_cfg, srsran::const_span cell_list) { + cfg = sched_params{sched_cfg}; + logger = &srslog::fetch_basic_logger(sched_cfg.logger_name); + // Initiate Common Sched Configuration cfg.cells.reserve(cell_list.size()); for (uint32_t cc = 0; cc < cell_list.size(); ++cc) { @@ -112,9 +113,9 @@ void sched_nr::ue_cfg_impl(uint16_t rnti, const ue_cfg_t& uecfg) if (not ue_db.contains(rnti)) { auto ret = ue_db.insert(rnti, std::unique_ptr(new ue{rnti, uecfg, cfg})); if (ret.has_value()) { - logger.info("SCHED: New user rnti=0x%x, cc=%d", rnti, cfg.cells[0].cc); + logger->info("SCHED: New user rnti=0x%x, cc=%d", rnti, cfg.cells[0].cc); } else { - logger.error("SCHED: Failed to create new user rnti=0x%x", rnti); + logger->error("SCHED: Failed to create new user rnti=0x%x", rnti); } } else { ue_db[rnti]->set_cfg(uecfg); @@ -197,4 +198,4 @@ int assert_ue_cfg_valid(uint16_t rnti, const sched_nr_interface::ue_cfg_t& uecfg return SRSRAN_SUCCESS; } -} // namespace srsenb \ No newline at end of file +} // namespace srsenb diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.cc b/srsenb/test/mac/nr/sched_nr_sim_ue.cc index 89287467f..e57f61563 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.cc +++ b/srsenb/test/mac/nr/sched_nr_sim_ue.cc @@ -95,7 +95,7 @@ sched_nr_sim_base::sched_nr_sim_base(const sched_nr_interface::sched_cfg_t& std::string test_name_) : logger(srslog::fetch_basic_logger("TEST")), mac_logger(srslog::fetch_basic_logger("MAC")), - sched_ptr(new sched_nr(sched_args)), + sched_ptr(new sched_nr()), test_name(std::move(test_name_)) { logger.info("\n=========== Start %s ===========", test_name.c_str()); @@ -103,7 +103,7 @@ sched_nr_sim_base::sched_nr_sim_base(const sched_nr_interface::sched_cfg_t& for (uint32_t cc = 0; cc < cell_cfg_list.size(); ++cc) { cell_params.emplace_back(cc, cell_cfg_list[cc], sched_args); } - sched_ptr->cell_cfg(cell_cfg_list); // call parent cfg + sched_ptr->config(sched_args, cell_cfg_list); // call parent cfg TESTASSERT(cell_params.size() > 0); } From 6c91a824e2e8fdee4673e442421ae59a0ff53f44 Mon Sep 17 00:00:00 2001 From: faluco Date: Wed, 22 Sep 2021 16:43:43 +0200 Subject: [PATCH 42/83] Whitelist the TSAN lock order inversion issue in srsenb::mac::rlc_buffer_state. --- lib/include/srsran/common/tsan_options.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/include/srsran/common/tsan_options.h b/lib/include/srsran/common/tsan_options.h index 96a4f2544..397b40277 100644 --- a/lib/include/srsran/common/tsan_options.h +++ b/lib/include/srsran/common/tsan_options.h @@ -37,9 +37,12 @@ const char* __tsan_default_options() const char* __tsan_default_suppressions() { - // External uninstrumented libraries - return "called_from_lib:libzmq.so\n" - "called_from_lib:libpgm-5.2.so\n"; + return + // External uninstrumented libraries + "called_from_lib:libzmq.so\n" + "called_from_lib:libpgm-5.2.so\n" + // Lock order inversion issue in this function, ignore it as it uses rw locks in read mode + "deadlock:srsenb::mac::rlc_buffer_state\n"; } #ifdef __cplusplus From edb7342aef59a5bd2b70d766c286af126f98cf3c Mon Sep 17 00:00:00 2001 From: faluco Date: Thu, 23 Sep 2021 17:57:50 +0200 Subject: [PATCH 43/83] Fix data race in rlc UM metrics. --- lib/include/srsran/rlc/rlc_um_base.h | 1 + lib/src/rlc/rlc_um_base.cc | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/include/srsran/rlc/rlc_um_base.h b/lib/include/srsran/rlc/rlc_um_base.h index 05d0a0179..997857a8e 100644 --- a/lib/include/srsran/rlc/rlc_um_base.h +++ b/lib/include/srsran/rlc/rlc_um_base.h @@ -165,6 +165,7 @@ protected: bool tx_enabled = false; bool rx_enabled = false; + std::mutex metrics_mutex; rlc_bearer_metrics_t metrics = {}; }; diff --git a/lib/src/rlc/rlc_um_base.cc b/lib/src/rlc/rlc_um_base.cc index 26ce85370..2be81a2c7 100644 --- a/lib/src/rlc/rlc_um_base.cc +++ b/lib/src/rlc/rlc_um_base.cc @@ -82,15 +82,18 @@ void rlc_um_base::write_sdu(unique_byte_buffer_t sdu) { if (not tx_enabled || not tx) { logger.debug("%s is currently deactivated. Dropping SDU (%d B)", rb_name.c_str(), sdu->N_bytes); + std::lock_guard lock(metrics_mutex); metrics.num_lost_sdus++; return; } int sdu_bytes = sdu->N_bytes; //< Store SDU length for book-keeping if (tx->try_write_sdu(std::move(sdu)) == SRSRAN_SUCCESS) { + std::lock_guard lock(metrics_mutex); metrics.num_tx_sdus++; metrics.num_tx_sdu_bytes += sdu_bytes; } else { + std::lock_guard lock(metrics_mutex); metrics.num_lost_sdus++; } } @@ -102,6 +105,7 @@ void rlc_um_base::discard_sdu(uint32_t discard_sn) return; } tx->discard_sdu(discard_sn); + std::lock_guard lock(metrics_mutex); metrics.num_lost_sdus++; } @@ -135,6 +139,7 @@ uint32_t rlc_um_base::read_pdu(uint8_t* payload, uint32_t nof_bytes) if (tx && tx_enabled) { uint32_t len = tx->build_data_pdu(payload, nof_bytes); if (len > 0) { + std::lock_guard lock(metrics_mutex); metrics.num_tx_pdu_bytes += len; metrics.num_tx_pdus++; } @@ -146,19 +151,24 @@ uint32_t rlc_um_base::read_pdu(uint8_t* payload, uint32_t nof_bytes) void rlc_um_base::write_pdu(uint8_t* payload, uint32_t nof_bytes) { if (rx && rx_enabled) { - metrics.num_rx_pdus++; - metrics.num_rx_pdu_bytes += nof_bytes; + { + std::lock_guard lock(metrics_mutex); + metrics.num_rx_pdus++; + metrics.num_rx_pdu_bytes += nof_bytes; + } rx->handle_data_pdu(payload, nof_bytes); } } rlc_bearer_metrics_t rlc_um_base::get_metrics() { + std::lock_guard lock(metrics_mutex); return metrics; } void rlc_um_base::reset_metrics() { + std::lock_guard lock(metrics_mutex); metrics = {}; } From 7b079fe289e8b51ad1172b811fdac4d50391329e Mon Sep 17 00:00:00 2001 From: faluco Date: Thu, 23 Sep 2021 18:23:35 +0200 Subject: [PATCH 44/83] Fix a data race in rlc TM metrics. --- lib/include/srsran/rlc/rlc_tm.h | 1 + lib/src/rlc/rlc_tm.cc | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/include/srsran/rlc/rlc_tm.h b/lib/include/srsran/rlc/rlc_tm.h index 9c21720ee..f6ecd8947 100644 --- a/lib/include/srsran/rlc/rlc_tm.h +++ b/lib/include/srsran/rlc/rlc_tm.h @@ -68,6 +68,7 @@ private: std::atomic tx_enabled = {true}; + std::mutex metrics_mutex; rlc_bearer_metrics_t metrics = {}; // Thread-safe queues for MAC messages diff --git a/lib/src/rlc/rlc_tm.cc b/lib/src/rlc/rlc_tm.cc index 3a413def3..8a6c0376b 100644 --- a/lib/src/rlc/rlc_tm.cc +++ b/lib/src/rlc/rlc_tm.cc @@ -126,11 +126,13 @@ uint32_t rlc_tm::get_buffer_state() rlc_bearer_metrics_t rlc_tm::get_metrics() { + std::lock_guard lock(metrics_mutex); return metrics; } void rlc_tm::reset_metrics() { + std::lock_guard lock(metrics_mutex); metrics = {}; } @@ -156,6 +158,7 @@ uint32_t rlc_tm::read_pdu(uint8_t* payload, uint32_t nof_bytes) ul_queue.size(), ul_queue.size_bytes()); + std::lock_guard lock(metrics_mutex); metrics.num_tx_pdu_bytes += pdu_size; return pdu_size; } else { @@ -175,8 +178,11 @@ void rlc_tm::write_pdu(uint8_t* payload, uint32_t nof_bytes) memcpy(buf->msg, payload, nof_bytes); buf->N_bytes = nof_bytes; buf->set_timestamp(); - metrics.num_rx_pdu_bytes += nof_bytes; - metrics.num_rx_pdus++; + { + std::lock_guard lock(metrics_mutex); + metrics.num_rx_pdu_bytes += nof_bytes; + metrics.num_rx_pdus++; + } if (srsran::srb_to_lcid(srsran::lte_srb::srb0) == lcid) { rrc->write_pdu(lcid, std::move(buf)); } else { From bdf18856d101d2313112bf28aa346cc5be4d2eb0 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 23 Sep 2021 18:30:07 +0200 Subject: [PATCH 45/83] sched,nr: fix handling of DL BSR in NR scheduler and computation of UCI --- .../srsran/interfaces/enb_mac_interfaces.h | 3 +- lib/src/phy/phch/dci_nr.c | 2 +- srsenb/hdr/stack/mac/nr/mac_nr.h | 1 - srsenb/src/stack/mac/nr/mac_nr.cc | 6 ++ srsenb/src/stack/mac/nr/sched_nr_ue.cc | 4 ++ srsenb/src/stack/mac/nr/sched_nr_worker.cc | 67 ++++++++++--------- test/phy/dummy_gnb_stack.h | 7 ++ 7 files changed, 53 insertions(+), 37 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_mac_interfaces.h b/lib/include/srsran/interfaces/enb_mac_interfaces.h index 6ee722a1d..b3e2ef2fc 100644 --- a/lib/include/srsran/interfaces/enb_mac_interfaces.h +++ b/lib/include/srsran/interfaces/enb_mac_interfaces.h @@ -257,8 +257,7 @@ public: // Combined interface for PHY to access stack (MAC and RRC) class stack_interface_phy_lte : public mac_interface_phy_lte -{ -}; +{}; } // namespace srsenb diff --git a/lib/src/phy/phch/dci_nr.c b/lib/src/phy/phch/dci_nr.c index a37c06a4a..f18656c0e 100644 --- a/lib/src/phy/phch/dci_nr.c +++ b/lib/src/phy/phch/dci_nr.c @@ -1269,7 +1269,7 @@ static uint32_t dci_nr_format_1_0_to_str(const srsran_dci_dl_nr_t* dci, char* st // HARQ process number – 4 bits if (rnti_type == srsran_rnti_type_c || rnti_type == srsran_rnti_type_tc) { - len = srsran_print_check(str, str_len, len, "harq_id=%d ", dci->harq_feedback); + len = srsran_print_check(str, str_len, len, "harq_id=%d ", dci->pid); } // System information indicator – 1 bit diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index fb7de2523..313f6cb69 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -61,7 +61,6 @@ public: int rlc_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t tx_queue, uint32_t retx_queue) override; // Interface for PHY - void process_pdus(); int slot_indication(const srsran_slot_cfg_t& slot_cfg) override; int get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched) override; int get_ul_sched(const srsran_slot_cfg_t& slot_cfg, ul_sched_t& ul_sched) override; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 65da81474..69aa970ff 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -267,6 +267,12 @@ bool mac_nr::is_rnti_active_unsafe(uint16_t rnti) return ue_db[rnti]->is_active(); } +int mac_nr::rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) +{ + sched.dl_buffer_state(rnti, lc_id, tx_queue, retx_queue); + return SRSRAN_SUCCESS; +} + int mac_nr::slot_indication(const srsran_slot_cfg_t& slot_cfg) { return 0; diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index 5f9156db3..8453ce395 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -86,6 +86,10 @@ ue::ue(uint16_t rnti_, const ue_cfg_t& cfg, const sched_params& sched_cfg_) : rnti(rnti_), sched_cfg(sched_cfg_), buffers(srslog::fetch_basic_logger(sched_cfg_.sched_cfg.logger_name)) { set_cfg(cfg); + + mac_lc_ch_cfg_t lch{}; + lch.direction = mac_lc_ch_cfg_t::BOTH; + buffers.config_lcid(0, lch); } void ue::set_cfg(const ue_cfg_t& cfg) diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index 2d560036a..6c843b245 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -152,49 +152,50 @@ void slot_cc_worker::postprocess_decisions() continue; } - if (ue.h_ul != nullptr and ue.h_ul->harq_slot_tx() == ue.pusch_slot) { - // PUSCH was allocated. Insert UCI in PUSCH - for (auto& pusch : bwp_slot.puschs) { - if (pusch.sch.grant.rnti == ue.rnti) { - // Put UCI configuration in PUSCH config - if (not ue.cfg->phy().get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { - logger.error("Error setting UCI configuration in PUSCH"); - continue; - } - break; + if (uci_cfg.ack.count == 0 and uci_cfg.nof_csi == 0 and uci_cfg.o_sr == 0) { + continue; + } + + bool has_pusch = false; + for (auto& pusch : bwp_slot.puschs) { + if (pusch.sch.grant.rnti == ue.rnti) { + // Put UCI configuration in PUSCH config + has_pusch = true; + if (not ue.cfg->phy().get_pusch_uci_cfg(slot_cfg, uci_cfg, pusch.sch)) { + logger.error("Error setting UCI configuration in PUSCH"); + continue; } + break; } - } else { + } + if (not has_pusch) { // If any UCI information is triggered, schedule PUCCH - if (uci_cfg.ack.count > 0 || uci_cfg.nof_csi > 0 || uci_cfg.o_sr > 0) { - bwp_slot.pucch.emplace_back(); - mac_interface_phy_nr::pucch_t& pucch = bwp_slot.pucch.back(); + bwp_slot.pucch.emplace_back(); + mac_interface_phy_nr::pucch_t& pucch = bwp_slot.pucch.back(); + + uci_cfg.pucch.rnti = ue.rnti; + pucch.candidates.emplace_back(); + pucch.candidates.back().uci_cfg = uci_cfg; + if (not ue.cfg->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { + logger.error("Error getting UCI CFG"); + continue; + } + + // If this slot has a SR opportunity and the selected PUCCH format is 1, consider positive SR. + if (uci_cfg.o_sr > 0 and uci_cfg.ack.count > 0 and + pucch.candidates.back().resource.format == SRSRAN_PUCCH_NR_FORMAT_1) { + // Set SR negative + if (uci_cfg.o_sr > 0) { + uci_cfg.sr_positive_present = false; + } - uci_cfg.pucch.rnti = ue.rnti; + // Append new resource pucch.candidates.emplace_back(); pucch.candidates.back().uci_cfg = uci_cfg; if (not ue.cfg->phy().get_pucch_uci_cfg(slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { logger.error("Error getting UCI CFG"); continue; } - - // If this slot has a SR opportunity and the selected PUCCH format is 1, consider positive SR. - if (uci_cfg.o_sr > 0 and uci_cfg.ack.count > 0 and - pucch.candidates.back().resource.format == SRSRAN_PUCCH_NR_FORMAT_1) { - // Set SR negative - if (uci_cfg.o_sr > 0) { - uci_cfg.sr_positive_present = false; - } - - // Append new resource - pucch.candidates.emplace_back(); - pucch.candidates.back().uci_cfg = uci_cfg; - if (not ue.cfg->phy().get_pucch_uci_cfg( - slot_cfg, uci_cfg, pucch.pucch_cfg, pucch.candidates.back().resource)) { - logger.error("Error getting UCI CFG"); - continue; - } - } } } } diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index f134e939e..25d64fa7d 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -82,6 +82,7 @@ private: std::unique_ptr mac; srsran::slot_point pdsch_slot, pusch_slot; srslog::basic_logger& sched_logger; + bool autofill_pdsch_bsr = false; std::mutex metrics_mutex; metrics_t metrics = {}; @@ -337,6 +338,8 @@ public: sched_logger.set_level(srslog::str_to_basic_level(args.log_level)); srslog::fetch_basic_logger("MAC-NR").set_level(srslog::str_to_basic_level(args.log_level)); + autofill_pdsch_bsr = args.pdsch.slots != "" and args.pdsch.slots != "none"; + // create sched object mac.reset(new srsenb::mac_nr{&task_sched}); srsenb::mac_nr_args_t mac_args{}; @@ -444,6 +447,10 @@ public: } if (not use_dummy_sched) { + if (autofill_pdsch_bsr) { + mac->rlc_buffer_state(rnti, 0, 10000, 0); + } + int ret = mac->get_dl_sched(slot_cfg, dl_sched); for (pdsch_t& pdsch : dl_sched.pdsch) { From d1b1ef181a4bd59fb2036c340a57bb0195045762 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 23 Sep 2021 19:11:31 +0200 Subject: [PATCH 46/83] fix conflicts in rebasing --- srsenb/src/stack/mac/nr/mac_nr.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 69aa970ff..c8eff7765 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -130,12 +130,6 @@ int mac_nr::ue_cfg(uint16_t rnti, const sched_nr_interface::ue_cfg_t& ue_cfg) return SRSRAN_SUCCESS; } -int mac_nr::rlc_buffer_state(uint16_t rnti, uint32_t lcid, uint32_t tx_queue, uint32_t retx_queue) -{ - sched.dl_buffer_state(rnti, lcid, tx_queue, retx_queue); - return SRSRAN_SUCCESS; -} - uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx) { uint16_t rnti = alloc_ue(enb_cc_idx); From a952f0f62de81d832b129db0a520bc07c2169e18 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Thu, 23 Sep 2021 19:08:49 +0200 Subject: [PATCH 47/83] sched,nr: expose sched nr UE bearer configuration in sched interface --- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 4 +- srsenb/hdr/stack/rrc/rrc_nr.h | 5 +- srsenb/src/stack/mac/nr/sched_nr_ue.cc | 4 ++ srsenb/src/stack/rrc/rrc_nr.cc | 48 +++++++++++--------- srsenb/test/mac/nr/sched_nr_cfg_generators.h | 3 +- test/phy/dummy_gnb_stack.h | 1 + 6 files changed, 40 insertions(+), 25 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index ddf73d661..874ec03ee 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -30,6 +30,7 @@ const static size_t SCHED_NR_MAX_NOF_RBGS = 18; const static size_t SCHED_NR_MAX_TB = 1; const static size_t SCHED_NR_MAX_HARQ = 16; const static size_t SCHED_NR_MAX_BWP_PER_CELL = 2; +const static size_t SCHED_NR_MAX_LCID = 32; class sched_nr_interface { @@ -82,7 +83,8 @@ public: int fixed_dl_mcs = -1; int fixed_ul_mcs = -1; srsran::bounded_vector carriers; - srsran::phy_cfg_nr_t phy_cfg = {}; + std::array ue_bearers = {}; + srsran::phy_cfg_nr_t phy_cfg = {}; }; ////// RACH ////// diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 5d53332bf..31b5da4c3 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -137,6 +137,9 @@ public: asn1::rrc_nr::cell_group_cfg_s cell_group_cfg; asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg; + // MAC controller + sched_nr_interface::ue_cfg_t uecfg{}; + const uint32_t drb1_lcid = 4; // NSA specific variables @@ -146,7 +149,7 @@ public: private: static constexpr uint32_t UE_PSCELL_CC_IDX = 0; // first NR cell is always Primary Secondary Cell for UE - rrc_nr_cfg_t cfg = {}; + rrc_nr_cfg_t cfg = {}; // interfaces phy_interface_stack_nr* phy = nullptr; diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index 8453ce395..914ca0bf0 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -100,6 +100,10 @@ void ue::set_cfg(const ue_cfg_t& cfg) carriers[ue_cc_cfg.cc].reset(new ue_carrier(rnti, cfg, sched_cfg.cells[ue_cc_cfg.cc])); } } + + for (uint32_t lcid = 0; lcid < cfg.ue_bearers.size(); ++lcid) { + buffers.config_lcid(lcid, cfg.ue_bearers[lcid]); + } } void ue::new_slot(slot_point pdcch_slot) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index d450f196c..e0d667636 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -222,7 +222,7 @@ void rrc_nr::config_mac() std::vector sched_cells_cfg = {srsenb::get_default_cells_cfg(1)}; // FIXME: entire SI configuration, etc needs to be ported to NR - sched_interface::cell_cfg_t cell_cfg; + sched_interface::cell_cfg_t cell_cfg; set_sched_cell_cfg_sib1(&cell_cfg, cfg.sib1); // set SIB length @@ -470,7 +470,10 @@ int rrc_nr::sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstri Every function in UE class is called from a mutex environment thus does not need extra protection. *******************************************************************************/ -rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_) : parent(parent_), rnti(rnti_) {} +rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_) : parent(parent_), rnti(rnti_) +{ + uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; +} void rrc_nr::ue::send_connection_setup() { @@ -855,15 +858,15 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group // Reconfig with Sync cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.new_ue_id = rnti; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.t304 = recfg_with_sync_s::t304_opts::ms1000; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.t304 = recfg_with_sync_s::t304_opts::ms1000; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.n_timing_advance_offset = asn1::rrc_nr::serving_cell_cfg_common_s::n_timing_advance_offset_opts::n0; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dmrs_type_a_position = asn1::rrc_nr::serving_cell_cfg_common_s::dmrs_type_a_position_opts::pos2; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci_present = true; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci = pscell_cfg.phy_cell.carrier.pci; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci = pscell_cfg.phy_cell.carrier.pci; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing = subcarrier_spacing_opts::khz30; @@ -1033,15 +1036,14 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group // Helper for the RRC Reconfiguration sender to pack hard-coded config int rrc_nr::ue::pack_secondary_cell_group_config_fdd(asn1::dyn_octstring& packed_secondary_cell_config) { - auto& cell_group_cfg_pack = cell_group_cfg; pack_secondary_cell_group_config_common(cell_group_cfg); - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id = 0; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg_present = true; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id = 0; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg_present = true; // UL config dedicated - auto& ul_config = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg; + auto& ul_config = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg; // SR resources auto& sr_res1 = ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list[0]; sr_res1.periodicity_and_offset.sl40() = 4; @@ -1065,7 +1067,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_fdd(asn1::dyn_octstring& packed auto& nzp_csi_res_set = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list[0]; nzp_csi_res_set.nzp_csi_res_set_id = 1; - nzp_csi_res_set.nzp_csi_rs_res[0] = 1; + nzp_csi_res_set.nzp_csi_rs_res[0] = 1; // CSI report config auto& csi_report = @@ -1077,7 +1079,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_fdd(asn1::dyn_octstring& packed cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ss_pbch_block_pwr = -36; // DL config - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl.absolute_freq_ssb = 176210; // TODO: calculate from actual DL ARFCN @@ -1093,7 +1095,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_fdd(asn1::dyn_octstring& packed cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common; rach_cfg_common_pack.set_setup(); - rach_cfg_common_pack.setup().rach_cfg_generic.prach_cfg_idx = 16; + rach_cfg_common_pack.setup().rach_cfg_generic.prach_cfg_idx = 16; // SSB config (optional) cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_positions_in_burst_present = true; @@ -1115,15 +1117,14 @@ int rrc_nr::ue::pack_secondary_cell_group_config_fdd(asn1::dyn_octstring& packed // Helper for the RRC Reconfiguration sender to pack hard-coded config int rrc_nr::ue::pack_secondary_cell_group_config_tdd(asn1::dyn_octstring& packed_secondary_cell_config) { - auto& cell_group_cfg_pack = cell_group_cfg; pack_secondary_cell_group_config_common(cell_group_cfg); - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id = 1; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg_present = true; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id = 1; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg_present = true; // UL config dedicated - auto& ul_config = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg; + auto& ul_config = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg; // SR resources auto& sr_res1 = ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list[0]; // SR resources @@ -1153,7 +1154,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_tdd(asn1::dyn_octstring& packed auto& nzp_csi_res_set = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list[0]; nzp_csi_res_set.nzp_csi_res_set_id = 0; - nzp_csi_res_set.nzp_csi_rs_res[0] = 0; + nzp_csi_res_set.nzp_csi_rs_res[0] = 0; // Skip TRS info // CSI report config @@ -1168,7 +1169,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_tdd(asn1::dyn_octstring& packed cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ss_pbch_block_pwr = 0; // DL config - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl.absolute_freq_ssb = 634176; // TODO: calculate from actual DL ARFCN @@ -1180,8 +1181,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_tdd(asn1::dyn_octstring& packed auto& pdcch_cfg_common = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdcch_cfg_common; pdcch_cfg_common.set_setup(); - pdcch_cfg_common.setup().ext = false; - + pdcch_cfg_common.setup().ext = false; // RACH config cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common_present = @@ -1190,7 +1190,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_tdd(asn1::dyn_octstring& packed cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common; rach_cfg_common_pack.set_setup(); - rach_cfg_common_pack.setup().rach_cfg_generic.prach_cfg_idx = 0; + rach_cfg_common_pack.setup().rach_cfg_generic.prach_cfg_idx = 0; // SSB config (optional) cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_positions_in_burst_present = true; @@ -1392,6 +1392,10 @@ int rrc_nr::ue::add_drb() srsran::pdcp_config_t pdcp_cnfg = srsran::make_drb_pdcp_config_t(drb_item.drb_id, false, drb_item.pdcp_cfg); parent->pdcp->add_bearer(rnti, rlc.lc_ch_id, pdcp_cnfg); + // Add DRB1 to MAC + uecfg.ue_bearers[rlc.lc_ch_id].direction = mac_lc_ch_cfg_t::BOTH; + parent->mac->ue_cfg(rnti, uecfg); + return SRSRAN_SUCCESS; } diff --git a/srsenb/test/mac/nr/sched_nr_cfg_generators.h b/srsenb/test/mac/nr/sched_nr_cfg_generators.h index 683e0d060..9665a1444 100644 --- a/srsenb/test/mac/nr/sched_nr_cfg_generators.h +++ b/srsenb/test/mac/nr/sched_nr_cfg_generators.h @@ -87,7 +87,8 @@ inline sched_nr_interface::ue_cfg_t get_default_ue_cfg( uecfg.carriers[cc].cc = cc; uecfg.carriers[cc].active = true; } - uecfg.phy_cfg = phy_cfg; + uecfg.phy_cfg = phy_cfg; + uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; return uecfg; } diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index 25d64fa7d..50adf8dfe 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -356,6 +356,7 @@ public: srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1, phy_cfg); ue_cfg.fixed_dl_mcs = args.pdsch.mcs; ue_cfg.fixed_ul_mcs = args.pusch.mcs; + ue_cfg.ue_bearers[4].direction = srsenb::mac_lc_ch_cfg_t::BOTH; mac->ue_cfg(args.rnti, ue_cfg); } From 88212ed3e08eb8159f48db10f4d4e061d2c54f50 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 24 Sep 2021 14:56:59 +0200 Subject: [PATCH 48/83] fix NR sched configuration of UE generated in RRC --- srsenb/src/stack/gnb_stack_nr.cc | 2 -- srsenb/src/stack/mac/nr/mac_nr.cc | 2 -- srsenb/src/stack/rrc/rrc_nr.cc | 5 +---- srsenb/test/mac/nr/sched_nr_cfg_generators.h | 4 ++++ 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/srsenb/src/stack/gnb_stack_nr.cc b/srsenb/src/stack/gnb_stack_nr.cc index bef8ec076..d3a1fd776 100644 --- a/srsenb/src/stack/gnb_stack_nr.cc +++ b/srsenb/src/stack/gnb_stack_nr.cc @@ -70,8 +70,6 @@ int gnb_stack_nr::init(const srsenb::stack_args_t& args_, // Init all layers mac_nr_args_t mac_args = {}; - mac_args.fixed_dl_mcs = 28; - mac_args.fixed_ul_mcs = 10; mac_args.pcap = args.mac_pcap; mac_args.pcap.filename = "/tmp/enb_mac_nr.pcap"; if (mac.init(mac_args, phy, nullptr, &rlc, &rrc) != SRSRAN_SUCCESS) { diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index c8eff7765..01acff678 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -139,8 +139,6 @@ uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx) // Add new user to the scheduler so that it can RX/TX SRB0 srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1); - ue_cfg.fixed_dl_mcs = args.fixed_dl_mcs; - ue_cfg.fixed_ul_mcs = args.fixed_ul_mcs; sched.ue_cfg(rnti, ue_cfg); return rnti; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index e0d667636..305f1d34b 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -470,10 +470,7 @@ int rrc_nr::sgnb_reconfiguration_complete(uint16_t eutra_rnti, asn1::dyn_octstri Every function in UE class is called from a mutex environment thus does not need extra protection. *******************************************************************************/ -rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_) : parent(parent_), rnti(rnti_) -{ - uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; -} +rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_) : parent(parent_), rnti(rnti_), uecfg(srsenb::get_default_ue_cfg(1)) {} void rrc_nr::ue::send_connection_setup() { diff --git a/srsenb/test/mac/nr/sched_nr_cfg_generators.h b/srsenb/test/mac/nr/sched_nr_cfg_generators.h index 9665a1444..519568346 100644 --- a/srsenb/test/mac/nr/sched_nr_cfg_generators.h +++ b/srsenb/test/mac/nr/sched_nr_cfg_generators.h @@ -90,6 +90,10 @@ inline sched_nr_interface::ue_cfg_t get_default_ue_cfg( uecfg.phy_cfg = phy_cfg; uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; + // Note: dynamic MCS not yet supported + uecfg.fixed_dl_mcs = 28; + uecfg.fixed_ul_mcs = 10; + return uecfg; } From 8ba623f9547f29d16d6e8e14dd9ecd4c8aaa19a9 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 24 Sep 2021 12:13:00 +0200 Subject: [PATCH 49/83] sched,nr: remove unecessary setup of lcid=0 in scheduler --- srsenb/src/stack/mac/nr/sched_nr_ue.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index 914ca0bf0..bf7205bf8 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -86,10 +86,6 @@ ue::ue(uint16_t rnti_, const ue_cfg_t& cfg, const sched_params& sched_cfg_) : rnti(rnti_), sched_cfg(sched_cfg_), buffers(srslog::fetch_basic_logger(sched_cfg_.sched_cfg.logger_name)) { set_cfg(cfg); - - mac_lc_ch_cfg_t lch{}; - lch.direction = mac_lc_ch_cfg_t::BOTH; - buffers.config_lcid(0, lch); } void ue::set_cfg(const ue_cfg_t& cfg) From 9230bc3b231749164d341929970b43f8301910fe Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Fri, 24 Sep 2021 12:38:31 +0100 Subject: [PATCH 50/83] Demoted GTP-C logging of recieving downlink notification ack/failure when paging is not peding from warning to info --- srsepc/src/spgw/gtpc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsepc/src/spgw/gtpc.cc b/srsepc/src/spgw/gtpc.cc index 9f321f25d..9e3eac3b3 100644 --- a/srsepc/src/spgw/gtpc.cc +++ b/srsepc/src/spgw/gtpc.cc @@ -515,7 +515,7 @@ pkt_discard: bool spgw::gtpc::free_all_queued_packets(spgw_tunnel_ctx_t* tunnel_ctx) { if (!tunnel_ctx->paging_pending) { - m_logger.warning("Freeing queue with paging not pending."); + m_logger.info("Trying to free queued packets, but paging is not pending."); } while (!tunnel_ctx->paging_queue.empty()) { From 59e1bca3f55d191015c9c94ae6347aaf0ae34e8b Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 24 Sep 2021 11:29:20 +0200 Subject: [PATCH 51/83] rlc_am_lte: fix potential crash when attempting to resize tx queue under some circumstances it could happen that the RLC is configured when SDUs are already being written to the queue. The resize operation of the underlying container would fail in this case. Make sure to empty the queue before doing the resize. --- lib/include/srsran/rlc/rlc_am_lte.h | 1 + lib/src/rlc/rlc_am_lte.cc | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/include/srsran/rlc/rlc_am_lte.h b/lib/include/srsran/rlc/rlc_am_lte.h index 4d235bff2..abfe17504 100644 --- a/lib/include/srsran/rlc/rlc_am_lte.h +++ b/lib/include/srsran/rlc/rlc_am_lte.h @@ -392,6 +392,7 @@ private: void update_notification_ack_info(uint32_t rlc_sn); void debug_state(); + void empty_queue_unsafe(); int required_buffer_size(const rlc_amd_retx_t& retx); void retransmit_pdu(uint32_t sn); diff --git a/lib/src/rlc/rlc_am_lte.cc b/lib/src/rlc/rlc_am_lte.cc index 700d79265..62fc19f35 100644 --- a/lib/src/rlc/rlc_am_lte.cc +++ b/lib/src/rlc/rlc_am_lte.cc @@ -299,6 +299,7 @@ void rlc_am_lte::rlc_am_lte_tx::set_bsr_callback(bsr_callback_t callback) bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) { + std::lock_guard lock(mutex); if (cfg_.tx_queue_length > MAX_SDUS_PER_RLC_PDU) { logger.error("Configuring Tx queue length of %d PDUs too big. Maximum value is %d.", cfg_.tx_queue_length, @@ -325,6 +326,8 @@ bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) poll_retx_timer.set(static_cast(cfg.t_poll_retx), [this](uint32_t timerid) { timer_expired(timerid); }); } + // make sure Tx queue is empty before attempting to resize + empty_queue_unsafe(); tx_sdu_queue.resize(cfg_.tx_queue_length); tx_enabled = true; @@ -334,10 +337,10 @@ bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) void rlc_am_lte::rlc_am_lte_tx::stop() { - empty_queue(); - std::lock_guard lock(mutex); + empty_queue_unsafe(); + tx_enabled = false; if (parent->timers != nullptr && poll_retx_timer.is_valid()) { @@ -369,7 +372,11 @@ void rlc_am_lte::rlc_am_lte_tx::stop() void rlc_am_lte::rlc_am_lte_tx::empty_queue() { std::lock_guard lock(mutex); + empty_queue_unsafe(); +} +void rlc_am_lte::rlc_am_lte_tx::empty_queue_unsafe() +{ // deallocate all SDUs in transmit queue while (tx_sdu_queue.size() > 0) { unique_byte_buffer_t buf = tx_sdu_queue.read(); From 593d28fa4d600ad102ccdc008253ec0295e7d25e Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 24 Sep 2021 11:34:14 +0200 Subject: [PATCH 52/83] enb,stack_lte: protect access to sync queue the sync queue is only created during init so access needs to be protected --- srsenb/src/stack/enb_stack_lte.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/srsenb/src/stack/enb_stack_lte.cc b/srsenb/src/stack/enb_stack_lte.cc index 640857c6f..337a90b2e 100644 --- a/srsenb/src/stack/enb_stack_lte.cc +++ b/srsenb/src/stack/enb_stack_lte.cc @@ -203,7 +203,9 @@ int enb_stack_lte::init(const stack_args_t& args_, void enb_stack_lte::tti_clock() { - sync_task_queue.push([this]() { tti_clock_impl(); }); + if (started.load(std::memory_order_relaxed)) { + sync_task_queue.push([this]() { tti_clock_impl(); }); + } } void enb_stack_lte::tti_clock_impl() From c7e2038904e886ce6e93fdebaf135c0509327910 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Fri, 24 Sep 2021 15:20:15 +0200 Subject: [PATCH 53/83] lte: stop radio before stopping stack --- srsenb/src/enb.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/srsenb/src/enb.cc b/srsenb/src/enb.cc index 1ea3c114f..97722f5b2 100644 --- a/srsenb/src/enb.cc +++ b/srsenb/src/enb.cc @@ -148,6 +148,10 @@ void enb::stop() { if (started) { // tear down in reverse order + if (radio) { + radio->stop(); + } + if (phy) { phy->stop(); } @@ -160,10 +164,6 @@ void enb::stop() nr_stack->stop(); } - if (radio) { - radio->stop(); - } - // Now that everything is teared down, log sector stop events. const std::string& sib9_hnb_name = rrc_cfg.sibs[8].sib9().hnb_name_present ? rrc_cfg.sibs[8].sib9().hnb_name.to_string() : ""; From fa351cd285da6c5f8fe04517a6ff6bc0291a398b Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 24 Sep 2021 14:20:58 +0200 Subject: [PATCH 54/83] Rename functions that contain the unsafe word to nolock. The term "unsafe" does not clearly state that the function is not locking the shared date and it sounds "dangerous", so use a more explicit term. --- lib/include/srsran/adt/choice_type.h | 50 ++++++++++---------- lib/include/srsran/adt/pool/batch_mem_pool.h | 4 +- lib/include/srsran/common/block_queue.h | 9 ++-- lib/include/srsran/rlc/rlc_am_lte.h | 2 +- lib/src/phy/rf/rf_uhd_imp.cc | 20 ++++---- lib/src/rlc/rlc_am_lte.cc | 8 ++-- lib/test/common/choice_type_test.cc | 8 ++-- srsenb/hdr/stack/mac/nr/mac_nr.h | 4 +- srsenb/src/stack/mac/nr/mac_nr.cc | 14 +++--- srsue/hdr/phy/lte/cc_worker.h | 12 ++--- srsue/hdr/phy/lte/sf_worker.h | 10 ++-- srsue/hdr/stack/mac/dl_harq.h | 18 +++---- srsue/hdr/stack/mac/mux.h | 2 +- srsue/hdr/stack/mac/proc_ra.h | 2 +- srsue/hdr/stack/mac_nr/proc_sr_nr.h | 2 +- srsue/src/phy/lte/cc_worker.cc | 14 +++--- srsue/src/phy/lte/sf_worker.cc | 22 ++++----- srsue/src/phy/lte/worker_pool.cc | 2 +- srsue/src/phy/phy.cc | 6 +-- srsue/src/phy/sync.cc | 6 +-- srsue/src/stack/mac/dl_harq.cc | 8 ++-- srsue/src/stack/mac/mux.cc | 6 +-- srsue/src/stack/mac/proc_ra.cc | 10 ++-- srsue/src/stack/mac_nr/proc_sr_nr.cc | 8 ++-- 24 files changed, 123 insertions(+), 124 deletions(-) diff --git a/lib/include/srsran/adt/choice_type.h b/lib/include/srsran/adt/choice_type.h index 1fbfd47f0..a79ba5c35 100644 --- a/lib/include/srsran/adt/choice_type.h +++ b/lib/include/srsran/adt/choice_type.h @@ -55,7 +55,7 @@ struct choice_storage_t { } template - void destroy_unsafe() + void destroy_unchecked() { get_unchecked().~U(); }; @@ -71,7 +71,7 @@ struct CopyCtorVisitor { template void operator()(const T& t) { - c->construct_unsafe(t); + c->construct_unchecked(t); } C* c; }; @@ -82,18 +82,18 @@ struct MoveCtorVisitor { template void operator()(T&& t) { - c->construct_unsafe(std::move(t)); + c->construct_unchecked(std::move(t)); } C* c; }; template -struct DtorUnsafeVisitor { - explicit DtorUnsafeVisitor(C* c_) : c(c_) {} +struct DtorUncheckVisitor { + explicit DtorUncheckVisitor(C* c_) : c(c_) {} template void operator()(T& t) { - c->template destroy_unsafe(); + c->template destroy_unchecked(); } C* c; }; @@ -110,12 +110,12 @@ struct tagged_union_t std::size_t type_id; - using base_t::destroy_unsafe; + using base_t::destroy_unchecked; using base_t::get_buffer; using base_t::get_unchecked; template - void construct_emplace_unsafe(Args2&&... args) + void construct_emplace_unchecked(Args2&&... args) { using U2 = typename std::decay::type; static_assert(type_list_contains(), @@ -125,7 +125,7 @@ struct tagged_union_t } template - void construct_unsafe(U&& u) + void construct_unchecked(U&& u) { using U2 = typename std::decay::type; static_assert(type_list_contains(), @@ -134,11 +134,11 @@ struct tagged_union_t new (get_buffer()) U2(std::forward(u)); } - void copy_unsafe(const this_type& other) { visit(CopyCtorVisitor{this}, other); } + void copy_unchecked(const this_type& other) { visit(CopyCtorVisitor{this}, other); } - void move_unsafe(this_type&& other) { visit(MoveCtorVisitor{this}, other); } + void move_unchecked(this_type&& other) { visit(MoveCtorVisitor{this}, other); } - void dtor_unsafe() { visit(choice_details::DtorUnsafeVisitor{this}, *this); } + void dtor_unchecked() { visit(choice_details::DtorUncheckVisitor{this}, *this); } size_t get_type_idx() const { return type_id; } @@ -180,51 +180,51 @@ public: typename = typename std::enable_if::value>::type> explicit choice_t(Args2&&... args) noexcept { - base_t::template construct_emplace_unsafe(std::forward(args)...); + base_t::template construct_emplace_unchecked(std::forward(args)...); } - choice_t(const choice_t& other) noexcept { base_t::copy_unsafe(other); } + choice_t(const choice_t& other) noexcept { base_t::copy_unchecked(other); } - choice_t(choice_t&& other) noexcept { base_t::move_unsafe(std::move(other)); } + choice_t(choice_t&& other) noexcept { base_t::move_unchecked(std::move(other)); } template > choice_t(U&& u) noexcept { - base_t::construct_unsafe(std::forward(u)); + base_t::construct_unchecked(std::forward(u)); } - ~choice_t() { base_t::dtor_unsafe(); } + ~choice_t() { base_t::dtor_unchecked(); } template > choice_t& operator=(U&& u) noexcept { if (not base_t::template is()) { - base_t::dtor_unsafe(); + base_t::dtor_unchecked(); } - base_t::construct_unsafe(std::forward(u)); + base_t::construct_unchecked(std::forward(u)); return *this; } template void emplace(Args2&&... args) noexcept { - base_t::dtor_unsafe(); - base_t::template construct_emplace_unsafe(std::forward(args)...); + base_t::dtor_unchecked(); + base_t::template construct_emplace_unchecked(std::forward(args)...); } choice_t& operator=(const choice_t& other) noexcept { if (this != &other) { - base_t::dtor_unsafe(); - base_t::copy_unsafe(other); + base_t::dtor_unchecked(); + base_t::copy_unchecked(other); } return *this; } choice_t& operator=(choice_t&& other) noexcept { - base_t::dtor_unsafe(); - base_t::move_unsafe(std::move(other)); + base_t::dtor_unchecked(); + base_t::move_unchecked(std::move(other)); return *this; } diff --git a/lib/include/srsran/adt/pool/batch_mem_pool.h b/lib/include/srsran/adt/pool/batch_mem_pool.h index d54f5fff8..648ae0335 100644 --- a/lib/include/srsran/adt/pool/batch_mem_pool.h +++ b/lib/include/srsran/adt/pool/batch_mem_pool.h @@ -121,7 +121,7 @@ public: void* node = grow_pool.allocate_node(); if (grow_pool.size() < batch_threshold) { - allocate_batch_in_background_unlocked(); + allocate_batch_in_background_nolock(); } return node; } @@ -146,7 +146,7 @@ public: } private: - void allocate_batch_in_background_unlocked() + void allocate_batch_in_background_nolock() { if (state->dispatched) { // new batch allocation already ongoing diff --git a/lib/include/srsran/common/block_queue.h b/lib/include/srsran/common/block_queue.h index 479f474d2..7442c9a0b 100644 --- a/lib/include/srsran/common/block_queue.h +++ b/lib/include/srsran/common/block_queue.h @@ -35,7 +35,6 @@ namespace srsran { template class block_queue { - public: // Callback functions for mutexed operations inside pop/push methods class call_mutexed_itf @@ -107,7 +106,7 @@ public: bool full() { // queue is full? pthread_mutex_lock(&mutex); - bool ret = not check_queue_space_unlocked(false); + bool ret = not check_queue_space_nolock(false); pthread_mutex_unlock(&mutex); return ret; } @@ -163,7 +162,7 @@ private: return ret; } - bool check_queue_space_unlocked(bool block) + bool check_queue_space_nolock(bool block) { num_threads++; if (capacity > 0) { @@ -190,7 +189,7 @@ private: return std::move(value); } pthread_mutex_lock(&mutex); - bool ret = check_queue_space_unlocked(block); + bool ret = check_queue_space_nolock(block); if (ret) { if (mutexed_callback) { mutexed_callback->pushing(value); @@ -210,7 +209,7 @@ private: return false; } pthread_mutex_lock(&mutex); - bool ret = check_queue_space_unlocked(block); + bool ret = check_queue_space_nolock(block); if (ret) { if (mutexed_callback) { mutexed_callback->pushing(value); diff --git a/lib/include/srsran/rlc/rlc_am_lte.h b/lib/include/srsran/rlc/rlc_am_lte.h index abfe17504..6512d76a7 100644 --- a/lib/include/srsran/rlc/rlc_am_lte.h +++ b/lib/include/srsran/rlc/rlc_am_lte.h @@ -392,7 +392,7 @@ private: void update_notification_ack_info(uint32_t rlc_sn); void debug_state(); - void empty_queue_unsafe(); + void empty_queue_nolock(); int required_buffer_size(const rlc_amd_retx_t& retx); void retransmit_pdu(uint32_t sn); diff --git a/lib/src/phy/rf/rf_uhd_imp.cc b/lib/src/phy/rf/rf_uhd_imp.cc index be148f2f8..3525174f8 100644 --- a/lib/src/phy/rf/rf_uhd_imp.cc +++ b/lib/src/phy/rf/rf_uhd_imp.cc @@ -489,7 +489,7 @@ bool rf_uhd_rx_wait_lo_locked(void* h) return is_locked; } -static inline int rf_uhd_start_rx_stream_unsafe(rf_uhd_handler_t* handler) +static inline int rf_uhd_start_rx_stream_nolock(rf_uhd_handler_t* handler) { // Check if stream was not created or started if (not handler->uhd->is_rx_ready() or handler->rx_stream_enabled) { @@ -512,10 +512,10 @@ int rf_uhd_start_rx_stream(void* h, bool now) rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; std::unique_lock lock(handler->rx_mutex); - return rf_uhd_start_rx_stream_unsafe(handler); + return rf_uhd_start_rx_stream_nolock(handler); } -static inline int rf_uhd_stop_rx_stream_unsafe(rf_uhd_handler_t* handler) +static inline int rf_uhd_stop_rx_stream_nolock(rf_uhd_handler_t* handler) { // Check if stream was created or stream was not started if (not handler->uhd->is_rx_ready() or not handler->rx_stream_enabled) { @@ -538,7 +538,7 @@ int rf_uhd_stop_rx_stream(void* h) rf_uhd_handler_t* handler = (rf_uhd_handler_t*)h; std::unique_lock lock(handler->rx_mutex); - if (rf_uhd_stop_rx_stream_unsafe(handler) < SRSRAN_SUCCESS) { + if (rf_uhd_stop_rx_stream_nolock(handler) < SRSRAN_SUCCESS) { return SRSRAN_ERROR; } @@ -937,7 +937,7 @@ int rf_uhd_close(void* h) return SRSRAN_SUCCESS; } -static inline void rf_uhd_set_master_clock_rate_unsafe(rf_uhd_handler_t* handler, double rate) +static inline void rf_uhd_set_master_clock_rate_nolock(rf_uhd_handler_t* handler, double rate) { // Set master clock rate if it is allowed and change is required if (handler->dynamic_master_rate and handler->current_master_clock != rate) { @@ -985,14 +985,14 @@ double rf_uhd_set_rx_srate(void* h, double freq) // Stop RX streamer if (RF_UHD_IMP_PROHIBITED_STOP_START.count(handler->devname) == 0) { - if (rf_uhd_stop_rx_stream_unsafe(handler) != SRSRAN_SUCCESS) { + if (rf_uhd_stop_rx_stream_nolock(handler) != SRSRAN_SUCCESS) { return SRSRAN_ERROR; } } // Set master clock rate if (fmod(handler->current_master_clock, freq) > 0.0) { - rf_uhd_set_master_clock_rate_unsafe(handler, 4 * freq); + rf_uhd_set_master_clock_rate_nolock(handler, 4 * freq); } if (handler->nof_rx_channels > 1) { @@ -1043,7 +1043,7 @@ double rf_uhd_set_tx_srate(void* h, double freq) // Set master clock rate if (fmod(handler->current_master_clock, freq) > 0.0) { - rf_uhd_set_master_clock_rate_unsafe(handler, 4 * freq); + rf_uhd_set_master_clock_rate_nolock(handler, 4 * freq); } if (handler->nof_tx_channels > 1) { @@ -1258,7 +1258,7 @@ int rf_uhd_recv_with_time_multi(void* h, // Start stream if not started if (not handler->rx_stream_enabled) { - if (rf_uhd_start_rx_stream_unsafe(handler) != SRSRAN_SUCCESS) { + if (rf_uhd_start_rx_stream_nolock(handler) != SRSRAN_SUCCESS) { return SRSRAN_ERROR; } } @@ -1303,7 +1303,7 @@ int rf_uhd_recv_with_time_multi(void* h, if (RF_UHD_IMP_PROHIBITED_STOP_START.count(handler->devname) == 0) { // Stop Rx stream - rf_uhd_stop_rx_stream_unsafe(handler); + rf_uhd_stop_rx_stream_nolock(handler); } return -1; diff --git a/lib/src/rlc/rlc_am_lte.cc b/lib/src/rlc/rlc_am_lte.cc index 62fc19f35..3638c04b1 100644 --- a/lib/src/rlc/rlc_am_lte.cc +++ b/lib/src/rlc/rlc_am_lte.cc @@ -327,7 +327,7 @@ bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) } // make sure Tx queue is empty before attempting to resize - empty_queue_unsafe(); + empty_queue_nolock(); tx_sdu_queue.resize(cfg_.tx_queue_length); tx_enabled = true; @@ -339,7 +339,7 @@ void rlc_am_lte::rlc_am_lte_tx::stop() { std::lock_guard lock(mutex); - empty_queue_unsafe(); + empty_queue_nolock(); tx_enabled = false; @@ -372,10 +372,10 @@ void rlc_am_lte::rlc_am_lte_tx::stop() void rlc_am_lte::rlc_am_lte_tx::empty_queue() { std::lock_guard lock(mutex); - empty_queue_unsafe(); + empty_queue_nolock(); } -void rlc_am_lte::rlc_am_lte_tx::empty_queue_unsafe() +void rlc_am_lte::rlc_am_lte_tx::empty_queue_nolock() { // deallocate all SDUs in transmit queue while (tx_sdu_queue.size() > 0) { diff --git a/lib/test/common/choice_type_test.cc b/lib/test/common/choice_type_test.cc index df8c59e5f..33be694e8 100644 --- a/lib/test/common/choice_type_test.cc +++ b/lib/test/common/choice_type_test.cc @@ -80,15 +80,15 @@ int test_tagged_union() { using srsran::choice_details::tagged_union_t; tagged_union_t u; - u.construct_unsafe(5); + u.construct_unchecked(5); TESTASSERT(u.is()); TESTASSERT(u.get_unchecked() == 5); - u.destroy_unsafe(); + u.destroy_unchecked(); TESTASSERT(C::counter == 0); - u.construct_unsafe(C{}); + u.construct_unchecked(C{}); TESTASSERT(C::counter == 1); - u.destroy_unsafe(); + u.destroy_unchecked(); TESTASSERT(C::counter == 0); return SRSRAN_SUCCESS; diff --git a/srsenb/hdr/stack/mac/nr/mac_nr.h b/srsenb/hdr/stack/mac/nr/mac_nr.h index 313f6cb69..b0fed230a 100644 --- a/srsenb/hdr/stack/mac/nr/mac_nr.h +++ b/srsenb/hdr/stack/mac/nr/mac_nr.h @@ -73,8 +73,8 @@ private: uint16_t alloc_ue(uint32_t enb_cc_idx); // internal misc helpers - bool is_rnti_valid_unsafe(uint16_t rnti); - bool is_rnti_active_unsafe(uint16_t rnti); + bool is_rnti_valid_nolock(uint16_t rnti); + bool is_rnti_active_nolock(uint16_t rnti); // handle UCI data from either PUCCH or PUSCH bool handle_uci_data(const uint16_t rnti, const srsran_uci_cfg_nr_t& cfg, const srsran_uci_value_nr_t& value); diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 01acff678..44017dd9e 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -195,7 +195,7 @@ uint16_t mac_nr::alloc_ue(uint32_t enb_cc_idx) // Pre-check if rnti is valid { srsran::rwlock_read_guard read_lock(rwlock); - if (not is_rnti_valid_unsafe(rnti)) { + if (not is_rnti_valid_nolock(rnti)) { continue; } } @@ -205,7 +205,7 @@ uint16_t mac_nr::alloc_ue(uint32_t enb_cc_idx) // Add UE to rnti map srsran::rwlock_write_guard rw_lock(rwlock); - if (not is_rnti_valid_unsafe(rnti)) { + if (not is_rnti_valid_nolock(rnti)) { continue; } auto ret = ue_db.insert(rnti, std::move(ue_ptr)); @@ -223,7 +223,7 @@ uint16_t mac_nr::alloc_ue(uint32_t enb_cc_idx) int mac_nr::remove_ue(uint16_t rnti) { srsran::rwlock_write_guard lock(rwlock); - if (is_rnti_active_unsafe(rnti)) { + if (is_rnti_active_nolock(rnti)) { ue_db.erase(rnti); } else { logger.error("User rnti=0x%x not found", rnti); @@ -233,7 +233,7 @@ int mac_nr::remove_ue(uint16_t rnti) return SRSRAN_SUCCESS; } -bool mac_nr::is_rnti_valid_unsafe(uint16_t rnti) +bool mac_nr::is_rnti_valid_nolock(uint16_t rnti) { if (not started) { logger.info("RACH ignored as eNB is being shutdown"); @@ -250,7 +250,7 @@ bool mac_nr::is_rnti_valid_unsafe(uint16_t rnti) return true; } -bool mac_nr::is_rnti_active_unsafe(uint16_t rnti) +bool mac_nr::is_rnti_active_nolock(uint16_t rnti) { if (not ue_db.contains(rnti)) { logger.error("User rnti=0x%x not found", rnti); @@ -292,7 +292,7 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched for (pdsch_t& pdsch : dl_sched.pdsch) { if (pdsch.sch.grant.rnti_type == srsran_rnti_type_c) { uint16_t rnti = pdsch.sch.grant.rnti; - if (not is_rnti_active_unsafe(rnti)) { + if (not is_rnti_active_nolock(rnti)) { continue; } for (auto& tb_data : pdsch.data) { @@ -372,7 +372,7 @@ int mac_nr::pusch_info(const srsran_slot_cfg_t& slot_cfg, mac_interface_phy_nr:: auto process_pdu_task = [this, rnti](srsran::unique_byte_buffer_t& pdu) { srsran::rwlock_read_guard lock(rwlock); - if (is_rnti_active_unsafe(rnti)) { + if (is_rnti_active_nolock(rnti)) { ue_db[rnti]->process_pdu(std::move(pdu)); } else { logger.debug("Discarding PDU rnti=0x%x", rnti); diff --git a/srsue/hdr/phy/lte/cc_worker.h b/srsue/hdr/phy/lte/cc_worker.h index ada77a0c7..de43e534f 100644 --- a/srsue/hdr/phy/lte/cc_worker.h +++ b/srsue/hdr/phy/lte/cc_worker.h @@ -32,16 +32,16 @@ public: uint32_t get_buffer_len(); void set_tti(uint32_t tti); - void set_cfo_unlocked(float cfo); + void set_cfo_nolock(float cfo); float get_ref_cfo() const; // Functions to set configuration. // Warning: all these functions are unlocked and must be called while the worker is not processing data - void reset_cell_unlocked(); - bool set_cell_unlocked(srsran_cell_t cell_); - void set_tdd_config_unlocked(srsran_tdd_config_t config); - void set_config_unlocked(const srsran::phy_cfg_t& phy_cfg); - void upd_config_dci_unlocked(const srsran_dci_cfg_t& dci_cfg); + void reset_cell_nolock(); + bool set_cell_nolock(srsran_cell_t cell_); + void set_tdd_config_nolock(srsran_tdd_config_t config); + void set_config_nolock(const srsran::phy_cfg_t& phy_cfg); + void upd_config_dci_nolock(const srsran_dci_cfg_t& dci_cfg); void set_uci_periodic_cqi(srsran_uci_data_t* uci_data); diff --git a/srsue/hdr/phy/lte/sf_worker.h b/srsue/hdr/phy/lte/sf_worker.h index 3f1c48db6..98694ecf4 100644 --- a/srsue/hdr/phy/lte/sf_worker.h +++ b/srsue/hdr/phy/lte/sf_worker.h @@ -36,18 +36,18 @@ public: sf_worker(uint32_t max_prb, phy_common* phy_, srslog::basic_logger& logger); virtual ~sf_worker(); - void reset_cell_unlocked(uint32_t cc_idx); - bool set_cell_unlocked(uint32_t cc_idx, srsran_cell_t cell_); + void reset_cell_nolock(uint32_t cc_idx); + bool set_cell_nolock(uint32_t cc_idx, srsran_cell_t cell_); /* Functions used by main PHY thread */ cf_t* get_buffer(uint32_t cc_idx, uint32_t antenna_idx); uint32_t get_buffer_len(); void set_context(const srsran::phy_common_interface::worker_context_t& w_ctx); void set_prach(cf_t* prach_ptr, float prach_power); - void set_cfo_unlocked(const uint32_t& cc_idx, float cfo); + void set_cfo_nolock(const uint32_t& cc_idx, float cfo); - void set_tdd_config_unlocked(srsran_tdd_config_t config); - void set_config_unlocked(uint32_t cc_idx, const srsran::phy_cfg_t& phy_cfg); + void set_tdd_config_nolock(srsran_tdd_config_t config); + void set_config_nolock(uint32_t cc_idx, const srsran::phy_cfg_t& phy_cfg); ///< Methods for plotting called from GUI thread int read_ce_abs(float* ce_abs, uint32_t tx_antenna, uint32_t rx_antenna); diff --git a/srsue/hdr/stack/mac/dl_harq.h b/srsue/hdr/stack/mac/dl_harq.h index 0ca4cc60c..7def18c4c 100644 --- a/srsue/hdr/stack/mac/dl_harq.h +++ b/srsue/hdr/stack/mac/dl_harq.h @@ -76,7 +76,7 @@ private: bool calc_is_new_transmission(mac_interface_phy_lte::mac_grant_dl_t grant); // Internal function to reset process, caller must hold the mutex - void reset_unsafe(); + void reset_nolock(); std::mutex mutex; @@ -109,14 +109,14 @@ private: dl_sps dl_sps_assig; - std::vector proc; - dl_harq_process bcch_proc; - demux* demux_unit = nullptr; - srslog::basic_logger& logger; - srsran::mac_pcap* pcap = nullptr; - ue_rnti* rntis = nullptr; - uint16_t last_temporal_crnti = 0; - int si_window_start = 0; + std::vector proc; + dl_harq_process bcch_proc; + demux* demux_unit = nullptr; + srslog::basic_logger& logger; + srsran::mac_pcap* pcap = nullptr; + ue_rnti* rntis = nullptr; + uint16_t last_temporal_crnti = 0; + int si_window_start = 0; std::mutex retx_cnt_mutex = {}; diff --git a/srsue/hdr/stack/mac/mux.h b/srsue/hdr/stack/mac/mux.h index 46f8a322c..589bccb7f 100644 --- a/srsue/hdr/stack/mac/mux.h +++ b/srsue/hdr/stack/mac/mux.h @@ -57,7 +57,7 @@ public: void print_logical_channel_state(const std::string& info); private: - uint8_t* pdu_get_unsafe(srsran::byte_buffer_t* payload, uint32_t pdu_sz); + uint8_t* pdu_get_nolock(srsran::byte_buffer_t* payload, uint32_t pdu_sz); bool pdu_move_to_msg3(uint32_t pdu_sz); uint32_t allocate_sdu(uint32_t lcid, srsran::sch_pdu* pdu, int max_sdu_sz); bool sched_sdu(srsran::logical_channel_config_t* ch, int* sdu_space, int max_sdu_sz); diff --git a/srsue/hdr/stack/mac/proc_ra.h b/srsue/hdr/stack/mac/proc_ra.h index 46ba9b4df..0d1844333 100644 --- a/srsue/hdr/stack/mac/proc_ra.h +++ b/srsue/hdr/stack/mac/proc_ra.h @@ -78,7 +78,7 @@ private: void response_error(); void complete(); - bool contention_resolution_id_received_unsafe(uint64_t rx_contention_id); + bool contention_resolution_id_received_nolock(uint64_t rx_contention_id); // Buffer to receive RAR PDU static const uint32_t MAX_RAR_PDU_LEN = 2048; diff --git a/srsue/hdr/stack/mac_nr/proc_sr_nr.h b/srsue/hdr/stack/mac_nr/proc_sr_nr.h index ab57b0a5e..894cb2ea5 100644 --- a/srsue/hdr/stack/mac_nr/proc_sr_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_sr_nr.h @@ -40,7 +40,7 @@ public: bool sr_opportunity(uint32_t tti, uint32_t sr_id, bool meas_gap, bool ul_sch_tx); private: - void reset_unsafe(); + void reset_nolock(); int sr_counter = 0; bool is_pending_sr = false; diff --git a/srsue/src/phy/lte/cc_worker.cc b/srsue/src/phy/lte/cc_worker.cc index bf2352d34..bc788d8c7 100644 --- a/srsue/src/phy/lte/cc_worker.cc +++ b/srsue/src/phy/lte/cc_worker.cc @@ -112,15 +112,15 @@ void cc_worker::reset() { // constructor sets defaults srsran::phy_cfg_t empty_cfg; - set_config_unlocked(empty_cfg); + set_config_nolock(empty_cfg); } -void cc_worker::reset_cell_unlocked() +void cc_worker::reset_cell_nolock() { cell_initiated = false; } -bool cc_worker::set_cell_unlocked(srsran_cell_t cell_) +bool cc_worker::set_cell_nolock(srsran_cell_t cell_) { if (cell.id != cell_.id || !cell_initiated) { cell = cell_; @@ -171,7 +171,7 @@ void cc_worker::set_tti(uint32_t tti) sf_cfg_ul.shortened = false; } -void cc_worker::set_cfo_unlocked(float cfo) +void cc_worker::set_cfo_nolock(float cfo) { ue_ul_cfg.cfo_value = cfo; } @@ -181,7 +181,7 @@ float cc_worker::get_ref_cfo() const return ue_dl.chest_res.cfo; } -void cc_worker::set_tdd_config_unlocked(srsran_tdd_config_t config) +void cc_worker::set_tdd_config_nolock(srsran_tdd_config_t config) { sf_cfg_dl.tdd_config = config; sf_cfg_ul.tdd_config = config; @@ -874,7 +874,7 @@ void cc_worker::set_uci_ack(srsran_uci_data_t* uci_data, /* Translates RRC structs into PHY structs */ -void cc_worker::set_config_unlocked(const srsran::phy_cfg_t& phy_cfg) +void cc_worker::set_config_nolock(const srsran::phy_cfg_t& phy_cfg) { // Save configuration ue_dl_cfg.cfg = phy_cfg.dl_cfg; @@ -883,7 +883,7 @@ void cc_worker::set_config_unlocked(const srsran::phy_cfg_t& phy_cfg) phy->set_pdsch_cfg(&ue_dl_cfg.cfg.pdsch); } -void cc_worker::upd_config_dci_unlocked(const srsran_dci_cfg_t& dci_cfg) +void cc_worker::upd_config_dci_nolock(const srsran_dci_cfg_t& dci_cfg) { ue_dl_cfg.cfg.dci = dci_cfg; } diff --git a/srsue/src/phy/lte/sf_worker.cc b/srsue/src/phy/lte/sf_worker.cc index 9627b063e..fd14e896e 100644 --- a/srsue/src/phy/lte/sf_worker.cc +++ b/srsue/src/phy/lte/sf_worker.cc @@ -64,15 +64,15 @@ sf_worker::~sf_worker() } } -void sf_worker::reset_cell_unlocked(uint32_t cc_idx) +void sf_worker::reset_cell_nolock(uint32_t cc_idx) { - cc_workers[cc_idx]->reset_cell_unlocked(); + cc_workers[cc_idx]->reset_cell_nolock(); } -bool sf_worker::set_cell_unlocked(uint32_t cc_idx, srsran_cell_t cell_) +bool sf_worker::set_cell_nolock(uint32_t cc_idx, srsran_cell_t cell_) { if (cc_idx < cc_workers.size()) { - if (!cc_workers[cc_idx]->set_cell_unlocked(cell_)) { + if (!cc_workers[cc_idx]->set_cell_nolock(cell_)) { Error("Setting cell for cc=%d", cc_idx); return false; } @@ -120,26 +120,26 @@ void sf_worker::set_prach(cf_t* prach_ptr_, float prach_power_) prach_power = prach_power_; } -void sf_worker::set_cfo_unlocked(const uint32_t& cc_idx, float cfo) +void sf_worker::set_cfo_nolock(const uint32_t& cc_idx, float cfo) { - cc_workers[cc_idx]->set_cfo_unlocked(cfo); + cc_workers[cc_idx]->set_cfo_nolock(cfo); } -void sf_worker::set_tdd_config_unlocked(srsran_tdd_config_t config) +void sf_worker::set_tdd_config_nolock(srsran_tdd_config_t config) { for (auto& cc_worker : cc_workers) { - cc_worker->set_tdd_config_unlocked(config); + cc_worker->set_tdd_config_nolock(config); } tdd_config = config; } -void sf_worker::set_config_unlocked(uint32_t cc_idx, const srsran::phy_cfg_t& phy_cfg) +void sf_worker::set_config_nolock(uint32_t cc_idx, const srsran::phy_cfg_t& phy_cfg) { if (cc_idx < cc_workers.size()) { - cc_workers[cc_idx]->set_config_unlocked(phy_cfg); + cc_workers[cc_idx]->set_config_nolock(phy_cfg); if (cc_idx > 0) { // Update DCI config for PCell - cc_workers[0]->upd_config_dci_unlocked(phy_cfg.dl_cfg.dci); + cc_workers[0]->upd_config_dci_nolock(phy_cfg.dl_cfg.dci); } } else { Error("Setting config for cc=%d; Invalid cc_idx", cc_idx); diff --git a/srsue/src/phy/lte/worker_pool.cc b/srsue/src/phy/lte/worker_pool.cc index f65bc9b0a..c130e3c71 100644 --- a/srsue/src/phy/lte/worker_pool.cc +++ b/srsue/src/phy/lte/worker_pool.cc @@ -78,7 +78,7 @@ sf_worker* worker_pool::wait_worker(uint32_t tti) uint32_t worker_id = w->get_id(); for (uint32_t cc_idx = 0; cc_idx < SRSRAN_MAX_CARRIERS; cc_idx++) { if (phy_cfg_stash[cc_idx].is_pending(worker_id)) { - w->set_config_unlocked(cc_idx, phy_cfg_stash[cc_idx].get_cfg(worker_id)); + w->set_config_nolock(cc_idx, phy_cfg_stash[cc_idx].get_cfg(worker_id)); } } diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 94672b253..4e917a0e8 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -527,10 +527,10 @@ bool phy::set_scell(srsran_cell_t cell_info, uint32_t cc_idx, uint32_t earfcn) if (w) { // Reset secondary serving cell configuration, this needs to be done when the sf_worker is reserved to prevent // resetting the cell while it is working - w->reset_cell_unlocked(cc_idx); + w->reset_cell_nolock(cc_idx); // Set the new cell - w->set_cell_unlocked(cc_idx, cell_info); + w->set_cell_nolock(cc_idx, cell_info); // Release the new worker, it should not start processing until the SCell state is set to configured w->release(); @@ -578,7 +578,7 @@ void phy::set_config_tdd(srsran_tdd_config_t& tdd_config_) // set_tdd_config is not protected so run when worker is finished lte::sf_worker* w = lte_workers.wait_worker_id(i); if (w) { - w->set_tdd_config_unlocked(tdd_config); + w->set_tdd_config_nolock(tdd_config); w->release(); } } diff --git a/srsue/src/phy/sync.cc b/srsue/src/phy/sync.cc index 4acf03daf..4209edeba 100644 --- a/srsue/src/phy/sync.cc +++ b/srsue/src/phy/sync.cc @@ -517,7 +517,7 @@ void sync::run_camping_in_sync_state(lte::sf_worker* lte_worker, // Set CFO for all Carriers for (uint32_t cc = 0; cc < worker_com->args->nof_lte_carriers; cc++) { - lte_worker->set_cfo_unlocked(cc, get_tx_cfo()); + lte_worker->set_cfo_nolock(cc, get_tx_cfo()); worker_com->update_cfo_measurement(cc, cfo); } @@ -853,14 +853,14 @@ bool sync::set_cell(float cfo_in) // Reset cell configuration for (uint32_t i = 0; i < worker_com->args->nof_phy_threads; i++) { - (*lte_worker_pool)[i]->reset_cell_unlocked(0); + (*lte_worker_pool)[i]->reset_cell_nolock(0); } bool success = true; for (uint32_t i = 0; i < worker_com->args->nof_phy_threads; i++) { lte::sf_worker* w = lte_worker_pool->wait_worker_id(i); if (w) { - success &= w->set_cell_unlocked(0, cell.get()); + success &= w->set_cell_nolock(0, cell.get()); w->release(); } } diff --git a/srsue/src/stack/mac/dl_harq.cc b/srsue/src/stack/mac/dl_harq.cc index 900cfe4b8..7d2484b94 100644 --- a/srsue/src/stack/mac/dl_harq.cc +++ b/srsue/src/stack/mac/dl_harq.cc @@ -207,10 +207,10 @@ bool dl_harq_entity::dl_harq_process::dl_tb_process::init(int pid, dl_harq_entit void dl_harq_entity::dl_harq_process::dl_tb_process::reset() { std::lock_guard lock(mutex); - reset_unsafe(); + reset_nolock(); } -void dl_harq_entity::dl_harq_process::dl_tb_process::reset_unsafe() +void dl_harq_entity::dl_harq_process::dl_tb_process::reset_nolock() { bzero(&cur_grant, sizeof(mac_interface_phy_lte::mac_grant_dl_t)); is_first_tb = true; @@ -300,7 +300,7 @@ void dl_harq_entity::dl_harq_process::dl_tb_process::new_grant_dl(mac_interface_ n_retx > RESET_DUPLICATE_TIMEOUT ? "yes" : "no"); if (n_retx > RESET_DUPLICATE_TIMEOUT) { // reset without trying to acquire the mutex again - reset_unsafe(); + reset_nolock(); } } @@ -360,7 +360,7 @@ void dl_harq_entity::dl_harq_process::dl_tb_process::tb_decoded(mac_interface_ph if (ack && is_bcch) { // reset without trying to acquire the mutex again - reset_unsafe(); + reset_nolock(); } mutex.unlock(); diff --git a/srsue/src/stack/mac/mux.cc b/srsue/src/stack/mac/mux.cc index 654f329e5..6cc7d1b1f 100644 --- a/srsue/src/stack/mac/mux.cc +++ b/srsue/src/stack/mac/mux.cc @@ -99,11 +99,11 @@ srsran::ul_sch_lcid bsr_format_convert(bsr_proc::bsr_format_t format) uint8_t* mux::pdu_get(srsran::byte_buffer_t* payload, uint32_t pdu_sz) { std::lock_guard lock(mutex); - return pdu_get_unsafe(payload, pdu_sz); + return pdu_get_nolock(payload, pdu_sz); } // Multiplexing and logical channel priorization as defined in Section 5.4.3 -uint8_t* mux::pdu_get_unsafe(srsran::byte_buffer_t* payload, uint32_t pdu_sz) +uint8_t* mux::pdu_get_nolock(srsran::byte_buffer_t* payload, uint32_t pdu_sz) { // Logical Channel Procedure payload->clear(); @@ -363,7 +363,7 @@ uint8_t* mux::msg3_get(srsran::byte_buffer_t* payload, uint32_t pdu_sz) std::lock_guard lock(mutex); if (pdu_sz < msg3_buff.get_tailroom()) { if (msg3_is_empty()) { - if (!pdu_get_unsafe(&msg3_buff, pdu_sz)) { + if (!pdu_get_nolock(&msg3_buff, pdu_sz)) { Error("Moving PDU from Mux unit to Msg3 buffer"); return NULL; } diff --git a/srsue/src/stack/mac/proc_ra.cc b/srsue/src/stack/mac/proc_ra.cc index 902b09b58..d58f1ef7a 100644 --- a/srsue/src/stack/mac/proc_ra.cc +++ b/srsue/src/stack/mac/proc_ra.cc @@ -152,9 +152,9 @@ void ra_proc::state_pdcch_setup() rInfo("seq=%d, ra-rnti=0x%x, ra-tti=%d, f_id=%d", sel_preamble.load(), ra_rnti, info.tti_ra, info.f_id); srsran::console( "Random Access Transmission: seq=%d, tti=%d, ra-rnti=0x%x\n", sel_preamble.load(), info.tti_ra, ra_rnti); - rar_window_st = ra_tti + 3; + rar_window_st = ra_tti + 3; rntis->set_rar_rnti(ra_rnti); - state = RESPONSE_RECEPTION; + state = RESPONSE_RECEPTION; } else { rDebug("preamble not yet transmitted"); } @@ -219,7 +219,7 @@ void ra_proc::initialization() transmitted_contention_id = 0; preambleTransmissionCounter = 1; mux_unit->msg3_flush(); - backoff_param_ms = 0; + backoff_param_ms = 0; transmitted_crnti = 0; resource_selection(); } @@ -536,14 +536,14 @@ void ra_proc::timer_expired(uint32_t timer_id) */ bool ra_proc::contention_resolution_id_received(uint64_t rx_contention_id) { - task_queue.push([this, rx_contention_id]() { contention_resolution_id_received_unsafe(rx_contention_id); }); + task_queue.push([this, rx_contention_id]() { contention_resolution_id_received_nolock(rx_contention_id); }); return (transmitted_contention_id == rx_contention_id); } /* * Performs the actions defined in 5.1.5 for Temporal C-RNTI Contention Resolution */ -bool ra_proc::contention_resolution_id_received_unsafe(uint64_t rx_contention_id) +bool ra_proc::contention_resolution_id_received_nolock(uint64_t rx_contention_id) { bool uecri_successful = false; diff --git a/srsue/src/stack/mac_nr/proc_sr_nr.cc b/srsue/src/stack/mac_nr/proc_sr_nr.cc index e68b0483b..a5fc7a513 100644 --- a/srsue/src/stack/mac_nr/proc_sr_nr.cc +++ b/srsue/src/stack/mac_nr/proc_sr_nr.cc @@ -35,10 +35,10 @@ int32_t proc_sr_nr::init(mac_interface_sr_nr* mac_, phy_interface_mac_nr* phy_, void proc_sr_nr::reset() { std::lock_guard lock(mutex); - reset_unsafe(); + reset_nolock(); } -void proc_sr_nr::reset_unsafe() +void proc_sr_nr::reset_nolock() { is_pending_sr = false; } @@ -92,7 +92,7 @@ void proc_sr_nr::step(uint32_t tti) // 2> initiate a Random Access procedure (see clause 5.1) on the SpCell and cancel the pending SR. logger.info("SR: PUCCH not configured. Starting RA procedure"); mac->start_ra(); - reset_unsafe(); + reset_nolock(); return; } @@ -110,7 +110,7 @@ void proc_sr_nr::step(uint32_t tti) // ... TODO mac->start_ra(); - reset_unsafe(); + reset_nolock(); } } From 1c77998df58c59720a92d5b86b5425a9744d4209 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 22 Sep 2021 12:03:29 +0200 Subject: [PATCH 55/83] Stop PDCP for data bearers before initiating HO --- lib/include/srsran/interfaces/enb_pdcp_interfaces.h | 1 + lib/include/srsran/interfaces/ue_pdcp_interfaces.h | 1 + lib/include/srsran/upper/pdcp.h | 1 + lib/include/srsran/upper/pdcp_entity_base.h | 1 + lib/src/pdcp/pdcp.cc | 9 +++++++++ lib/src/pdcp/pdcp_entity_lte.cc | 10 ++++++++++ srsenb/hdr/stack/upper/pdcp.h | 1 + srsenb/src/stack/rrc/rrc_mobility.cc | 5 ++++- srsenb/src/stack/upper/pdcp.cc | 7 +++++++ srsenb/test/common/dummy_classes_common.h | 1 + srsue/src/stack/rrc/test/ue_rrc_nr_test.cc | 1 + 11 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/include/srsran/interfaces/enb_pdcp_interfaces.h b/lib/include/srsran/interfaces/enb_pdcp_interfaces.h index e49604591..5b5a907c2 100644 --- a/lib/include/srsran/interfaces/enb_pdcp_interfaces.h +++ b/lib/include/srsran/interfaces/enb_pdcp_interfaces.h @@ -31,6 +31,7 @@ public: class pdcp_interface_rrc { public: + virtual void set_enabled(uint16_t rnti, uint32_t lcid, bool enable) = 0; virtual void reset(uint16_t rnti) = 0; virtual void add_user(uint16_t rnti) = 0; virtual void rem_user(uint16_t rnti) = 0; diff --git a/lib/include/srsran/interfaces/ue_pdcp_interfaces.h b/lib/include/srsran/interfaces/ue_pdcp_interfaces.h index bdcf4c40f..65d825cfc 100644 --- a/lib/include/srsran/interfaces/ue_pdcp_interfaces.h +++ b/lib/include/srsran/interfaces/ue_pdcp_interfaces.h @@ -24,6 +24,7 @@ public: virtual void reestablish() = 0; virtual void reestablish(uint32_t lcid) = 0; virtual void reset() = 0; + virtual void set_enabled(uint32_t lcid, bool enabled) = 0; virtual void write_sdu(uint32_t lcid, srsran::unique_byte_buffer_t sdu, int sn = -1) = 0; virtual int add_bearer(uint32_t lcid, srsran::pdcp_config_t cnfg) = 0; virtual void del_bearer(uint32_t lcid) = 0; diff --git a/lib/include/srsran/upper/pdcp.h b/lib/include/srsran/upper/pdcp.h index d7e1ff918..88ebf3ca5 100644 --- a/lib/include/srsran/upper/pdcp.h +++ b/lib/include/srsran/upper/pdcp.h @@ -36,6 +36,7 @@ public: void reestablish() override; void reestablish(uint32_t lcid) override; void reset() override; + void set_enabled(uint32_t lcid, bool enabled) override; void write_sdu(uint32_t lcid, unique_byte_buffer_t sdu, int sn = -1) override; void write_sdu_mch(uint32_t lcid, unique_byte_buffer_t sdu); int add_bearer(uint32_t lcid, pdcp_config_t cnfg) override; diff --git a/lib/include/srsran/upper/pdcp_entity_base.h b/lib/include/srsran/upper/pdcp_entity_base.h index 75bb8f0b8..837b370fd 100644 --- a/lib/include/srsran/upper/pdcp_entity_base.h +++ b/lib/include/srsran/upper/pdcp_entity_base.h @@ -60,6 +60,7 @@ public: virtual void reset() = 0; virtual void reestablish() = 0; + void set_enabled(bool enabled) { active = enabled; } bool is_active() { return active; } bool is_srb() { return cfg.rb_type == PDCP_RB_IS_SRB; } bool is_drb() { return cfg.rb_type == PDCP_RB_IS_DRB; } diff --git a/lib/src/pdcp/pdcp.cc b/lib/src/pdcp/pdcp.cc index 993e65c04..0e03df711 100644 --- a/lib/src/pdcp/pdcp.cc +++ b/lib/src/pdcp/pdcp.cc @@ -63,6 +63,15 @@ void pdcp::reset() pdcp_array.clear(); } +void pdcp::set_enabled(uint32_t lcid, bool enabled) +{ + if (valid_lcid(lcid)) { + pdcp_array.at(lcid)->set_enabled(enabled); + } else { + logger.warning("LCID %d doesn't exist while setting enabled", lcid); + } +} + /******************************************************************************* RRC/GW interface *******************************************************************************/ diff --git a/lib/src/pdcp/pdcp_entity_lte.cc b/lib/src/pdcp/pdcp_entity_lte.cc index d616fb0cb..d4be424e1 100644 --- a/lib/src/pdcp/pdcp_entity_lte.cc +++ b/lib/src/pdcp/pdcp_entity_lte.cc @@ -134,6 +134,11 @@ void pdcp_entity_lte::reset() // GW/RRC interface void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn) { + if (!active) { + logger.warning("Dropping %s SDU due to inactive bearer", rrc->get_rb_name(lcid)); + return; + } + if (rlc->sdu_queue_is_full(lcid)) { logger.info(sdu->msg, sdu->N_bytes, "Dropping %s SDU due to full queue", rrc->get_rb_name(lcid)); return; @@ -216,6 +221,11 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn) // RLC interface void pdcp_entity_lte::write_pdu(unique_byte_buffer_t pdu) { + if (!active) { + logger.warning("Dropping %s PDU due to inactive bearer", rrc->get_rb_name(lcid)); + return; + } + // Handle control PDUs if (is_drb() && is_control_pdu(pdu)) { logger.info("Handling PDCP control PDU"); diff --git a/srsenb/hdr/stack/upper/pdcp.h b/srsenb/hdr/stack/upper/pdcp.h index 4bc74f75d..aa43919ce 100644 --- a/srsenb/hdr/stack/upper/pdcp.h +++ b/srsenb/hdr/stack/upper/pdcp.h @@ -44,6 +44,7 @@ public: void write_pdu_mch(uint32_t lcid, srsran::unique_byte_buffer_t sdu) {} // pdcp_interface_rrc + void set_enabled(uint16_t rnti, uint32_t lcid, bool enabled) override; void reset(uint16_t rnti) override; void add_user(uint16_t rnti) override; void rem_user(uint16_t rnti) override; diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index c6dfddd45..d0d35c6e7 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -700,7 +700,10 @@ void rrc::ue::rrc_mobility::s1_source_ho_st::handle_ho_cmd(wait_ho_cmd& s, const /* Enter Handover Execution */ // TODO: Do anything with MeasCfg info within the Msg (e.g. update ue_var_meas)? - // Disable DRBs in the MAC, while Reconfiguration is taking place. + // Disable DRBs in the MAC and PDCP, while Reconfiguration is taking place. + for (const drb_to_add_mod_s& drb : rrc_ue->bearer_list.get_established_drbs()) { + rrc_ue->parent->pdcp->set_enabled(rrc_ue->rnti, drb_to_lcid((lte_drb)drb.drb_id), false); + } rrc_ue->mac_ctrl.set_drb_activation(false); rrc_ue->mac_ctrl.update_mac(mac_controller::proc_stage_t::other); diff --git a/srsenb/src/stack/upper/pdcp.cc b/srsenb/src/stack/upper/pdcp.cc index 7bf37ba12..4b9c8baaf 100644 --- a/srsenb/src/stack/upper/pdcp.cc +++ b/srsenb/src/stack/upper/pdcp.cc @@ -86,6 +86,13 @@ void pdcp::del_bearer(uint16_t rnti, uint32_t lcid) } } +void pdcp::set_enabled(uint16_t rnti, uint32_t lcid, bool enabled) +{ + if (users.count(rnti)) { + users[rnti].pdcp->set_enabled(lcid, enabled); + } +} + void pdcp::reset(uint16_t rnti) { if (users.count(rnti)) { diff --git a/srsenb/test/common/dummy_classes_common.h b/srsenb/test/common/dummy_classes_common.h index f376f672b..966166fe8 100644 --- a/srsenb/test/common/dummy_classes_common.h +++ b/srsenb/test/common/dummy_classes_common.h @@ -39,6 +39,7 @@ public: class pdcp_dummy : public pdcp_interface_rrc, public pdcp_interface_gtpu { public: + void set_enabled(uint16_t rnti, uint32_t lcid, bool enabled) override {} void reset(uint16_t rnti) override {} void add_user(uint16_t rnti) override {} void rem_user(uint16_t rnti) override {} diff --git a/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc b/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc index 1f382e78c..c58dc050e 100644 --- a/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc +++ b/srsue/src/stack/rrc/test/ue_rrc_nr_test.cc @@ -62,6 +62,7 @@ class dummy_rlc : public rlc_interface_rrc class dummy_pdcp : public pdcp_interface_rrc { + void set_enabled(uint32_t lcid, bool enabled) {}; void reestablish(){}; void reestablish(uint32_t lcid){}; void reset(){}; From 1eaca0d3432843d04c5da11dd5fc2c6caa72d360 Mon Sep 17 00:00:00 2001 From: faluco Date: Tue, 21 Sep 2021 13:34:08 +0200 Subject: [PATCH 56/83] Escape asn1 message strings that get printed in the enb event json report. --- lib/src/common/enb_events.cc | 49 +++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/lib/src/common/enb_events.cc b/lib/src/common/enb_events.cc index f2d7b9119..30f19ac33 100644 --- a/lib/src/common/enb_events.cc +++ b/lib/src/common/enb_events.cc @@ -64,6 +64,46 @@ static double get_time_stamp() return std::chrono::duration_cast(tp).count() * 1e-3; } +/// Escapes the input string. +static std::string escape_string(const std::string& s) +{ + fmt::memory_buffer buff; + for (auto c : s) { + switch (c) { + case ' ': + break; + case '"': + fmt::format_to(buff, "\\\""); + break; + case '\\': + fmt::format_to(buff, "\\\\"); + break; + case '\b': + fmt::format_to(buff, "\\b"); + break; + case '\f': + fmt::format_to(buff, "\\f"); + break; + case '\n': + fmt::format_to(buff, "\\n"); + break; + case '\r': + fmt::format_to(buff, "\\r"); + break; + case '\t': + fmt::format_to(buff, "\\t"); + break; + default: + if ('\x00' <= c && c <= '\x1f') { + fmt::format_to(buff, "\\u{:04x}", c); + } else { + buff.push_back(c); + } + } + } + return fmt::to_string(buff); +} + namespace { /// Common metrics to all events. @@ -191,7 +231,8 @@ public: { rrc_event_t ctx(""); - const std::string& asn1 = (asn1_format == event_logger::asn1_output_format::octets) ? asn1_oct_str : asn1_txt_str; + const std::string& asn1 = + (asn1_format == event_logger::asn1_output_format::octets) ? asn1_oct_str : escape_string(asn1_txt_str); ctx.write("event"); ctx.write(get_time_stamp()); @@ -275,7 +316,8 @@ public: { meas_report_event_t ctx(""); - const std::string& asn1 = (asn1_format == event_logger::asn1_output_format::octets) ? asn1_oct_str : asn1_txt_str; + const std::string& asn1 = + (asn1_format == event_logger::asn1_output_format::octets) ? asn1_oct_str : escape_string(asn1_txt_str); ctx.write("event"); ctx.write(get_time_stamp()); @@ -295,7 +337,8 @@ public: { rlf_report_event_t ctx(""); - const std::string& asn1 = (asn1_format == event_logger::asn1_output_format::octets) ? asn1_oct_str : asn1_txt_str; + const std::string& asn1 = + (asn1_format == event_logger::asn1_output_format::octets) ? asn1_oct_str : escape_string(asn1_txt_str); ctx.write("event"); ctx.write(get_time_stamp()); From cbb709d4e373d3ee675c87a3d8dda24c76516b3f Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Mon, 27 Sep 2021 12:29:01 +0200 Subject: [PATCH 57/83] sched,nr: function to log UEs buffer status before scheduling decision, fix const_iterator of circular_map --- lib/include/srsran/adt/circular_map.h | 7 ++++++- srsenb/hdr/stack/mac/nr/sched_nr_helpers.h | 6 ++++++ srsenb/src/stack/mac/nr/mac_nr.cc | 1 + srsenb/src/stack/mac/nr/sched_nr_helpers.cc | 21 +++++++++++++++++++++ srsenb/src/stack/mac/nr/sched_nr_worker.cc | 3 +++ 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/lib/include/srsran/adt/circular_map.h b/lib/include/srsran/adt/circular_map.h index a7744f0fa..47b8ecd5f 100644 --- a/lib/include/srsran/adt/circular_map.h +++ b/lib/include/srsran/adt/circular_map.h @@ -90,7 +90,12 @@ public: { public: const_iterator() = default; - const_iterator(const static_circular_map* map, size_t idx_) : ptr(map), idx(idx_) {} + const_iterator(const static_circular_map* map, size_t idx_) : ptr(map), idx(idx_) + { + if (idx < ptr->capacity() and not ptr->present[idx]) { + ++(*this); + } + } const_iterator& operator++() { diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_helpers.h b/srsenb/hdr/stack/mac/nr/sched_nr_helpers.h index 4241fcf96..ab450d04a 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_helpers.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_helpers.h @@ -43,6 +43,12 @@ void fill_ul_dci_ue_fields(const slot_ue& ue, srsran_dci_location_t dci_pos, srsran_dci_ul_nr_t& dci); +/// Log UE state for slot being scheduled +void log_sched_slot_ues(srslog::basic_logger& logger, + slot_point pdcch_slot, + uint32_t cc, + const slot_ue_map_t& slot_ues); + /// Log Scheduling Result for a given BWP and slot void log_sched_bwp_result(srslog::basic_logger& logger, slot_point pdcch_slot, diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 44017dd9e..0b45e3c65 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -139,6 +139,7 @@ uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx) // Add new user to the scheduler so that it can RX/TX SRB0 srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1); + ue_cfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::IDLE; sched.ue_cfg(rnti, ue_cfg); return rnti; diff --git a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc index b55b10c81..a73c0bfbb 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_helpers.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_helpers.cc @@ -112,6 +112,27 @@ void fill_ul_dci_ue_fields(const slot_ue& ue, fill_dci_common(ue, bwp_cfg, dci); } +void log_sched_slot_ues(srslog::basic_logger& logger, slot_point pdcch_slot, uint32_t cc, const slot_ue_map_t& slot_ues) +{ + if (not logger.info.enabled() or slot_ues.empty()) { + return; + } + + fmt::memory_buffer fmtbuf; + fmt::format_to(fmtbuf, "SCHED: UE candidates, pdcch_tti={}, cc={}: [", pdcch_slot, cc); + + const char* use_comma = ""; + for (const auto& ue_pair : slot_ues) { + auto& ue = ue_pair->second; + + fmt::format_to( + fmtbuf, "{}{{rnti=0x{:x}, dl_bs={}, ul_bs={}}}", use_comma, ue.rnti, ue.dl_pending_bytes, ue.ul_pending_bytes); + use_comma = ", "; + } + + logger.info("%s]", srsran::to_c_str(fmtbuf)); +} + void log_sched_bwp_result(srslog::basic_logger& logger, slot_point pdcch_slot, const bwp_res_grid& res_grid, diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index 6c843b245..57b1d40ad 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -90,6 +90,9 @@ void slot_cc_worker::run(slot_point pdcch_slot, ue_map_t& ue_db) // Create an BWP allocator object that will passed along to RA, SI, Data schedulers bwp_alloc.new_slot(slot_rx + TX_ENB_DELAY, slot_ues); + // Log UEs state for slot + log_sched_slot_ues(logger, bwp_alloc.get_pdcch_tti(), cfg.cc, slot_ues); + // Allocate pending RARs cell.bwps[0].ra.run_slot(bwp_alloc); From 31192141240f55412b55b8b84c64ea5a76bbdd8f Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Mon, 27 Sep 2021 12:49:48 +0200 Subject: [PATCH 58/83] nr,rrc: defer drb activation in NR to when the C-RNTI is received --- srsenb/src/stack/mac/nr/mac_nr.cc | 1 - srsenb/src/stack/rrc/rrc_nr.cc | 10 +++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 0b45e3c65..44017dd9e 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -139,7 +139,6 @@ uint16_t mac_nr::reserve_rnti(uint32_t enb_cc_idx) // Add new user to the scheduler so that it can RX/TX SRB0 srsenb::sched_nr_interface::ue_cfg_t ue_cfg = srsenb::get_default_ue_cfg(1); - ue_cfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::IDLE; sched.ue_cfg(rnti, ue_cfg); return rnti; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 305f1d34b..5ffa439b6 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -1309,6 +1309,12 @@ void rrc_nr::ue::crnti_ce_received() if (endc) { // send SgNB addition complete for ENDC users parent->rrc_eutra->sgnb_addition_complete(eutra_rnti, rnti); + + // Add DRB1 to MAC + for (auto& drb : cell_group_cfg.rlc_bearer_to_add_mod_list) { + uecfg.ue_bearers[drb.lc_ch_id].direction = mac_lc_ch_cfg_t::BOTH; + } + parent->mac->ue_cfg(rnti, uecfg); } } @@ -1389,9 +1395,7 @@ int rrc_nr::ue::add_drb() srsran::pdcp_config_t pdcp_cnfg = srsran::make_drb_pdcp_config_t(drb_item.drb_id, false, drb_item.pdcp_cfg); parent->pdcp->add_bearer(rnti, rlc.lc_ch_id, pdcp_cnfg); - // Add DRB1 to MAC - uecfg.ue_bearers[rlc.lc_ch_id].direction = mac_lc_ch_cfg_t::BOTH; - parent->mac->ue_cfg(rnti, uecfg); + // Note: DRB1 is only activated in the MAC when the C-RNTI CE is received return SRSRAN_SUCCESS; } From 698eff29f476a770dfdcb3359ecda62399dec6a3 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Mon, 27 Sep 2021 13:08:45 +0200 Subject: [PATCH 59/83] sched,nr: avoid ul pending bytes of each UE becoming negative --- srsenb/src/stack/mac/nr/sched_nr_ue.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index bf7205bf8..476019230 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -135,6 +135,7 @@ void ue::new_slot(slot_point pdcch_slot) } } } + ul_pending_bytes = std::max(0, ul_pending_bytes); if (ul_pending_bytes == 0 and last_sr_slot.valid()) { // If unanswered SR is pending ul_pending_bytes = 512; From 9cefddd7393472be7784451f089c1404916bb7e6 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 27 Sep 2021 14:58:34 +0200 Subject: [PATCH 60/83] enb,mac_nr: remove user from scheduler when removed from MAC --- srsenb/src/stack/mac/nr/mac_nr.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 44017dd9e..27dc4d49c 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -224,6 +224,7 @@ int mac_nr::remove_ue(uint16_t rnti) { srsran::rwlock_write_guard lock(rwlock); if (is_rnti_active_nolock(rnti)) { + sched.ue_rem(rnti); ue_db.erase(rnti); } else { logger.error("User rnti=0x%x not found", rnti); From 6054e1229b43862735ab2070c8ea247aa345f315 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 24 Sep 2021 17:37:51 +0200 Subject: [PATCH 61/83] enb,rrc,rrc_nr: fix logging when removing user each action should only be logged once --- srsenb/src/stack/rrc/rrc.cc | 8 +++----- srsenb/src/stack/rrc/rrc_nr.cc | 8 ++++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index a9eff4db2..283e76a3b 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -651,11 +651,7 @@ void rrc::rem_user(uint16_t rnti) { auto user_it = users.find(rnti); if (user_it != users.end()) { - srsran::console("Disconnecting rnti=0x%x.\n", rnti); - logger.info("Disconnecting rnti=0x%x.", rnti); - - /* First remove MAC and GTPU to stop processing DL/UL traffic for this user - */ + // First remove MAC and GTPU to stop processing DL/UL traffic for this user mac->ue_rem(rnti); // MAC handles PHY gtpu->rem_user(rnti); @@ -665,6 +661,8 @@ void rrc::rem_user(uint16_t rnti) pdcp->rem_user(rnti); users.erase(rnti); + + srsran::console("Disconnecting rnti=0x%x.\n", rnti); logger.info("Removed user rnti=0x%x", rnti); } else { logger.error("Removing user rnti=0x%x (does not exist)", rnti); diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 5ffa439b6..ad3229995 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -16,6 +16,7 @@ #include "srsran/asn1/rrc_nr_utils.h" #include "srsran/common/common_nr.h" #include "srsran/common/phy_cfg_nr_default.h" +#include "srsran/common/standard_streams.h" using namespace asn1::rrc_nr; @@ -162,14 +163,13 @@ void rrc_nr::rem_user(uint16_t rnti) { auto user_it = users.find(rnti); if (user_it != users.end()) { - printf("Disconnecting rnti=0x%x.\n", rnti); - logger.info("Disconnecting rnti=0x%x.", rnti); - /* First remove MAC and GTPU to stop processing DL/UL traffic for this user - */ + // First remove MAC and GTPU to stop processing DL/UL traffic for this user mac->remove_ue(rnti); // MAC handles PHY rlc->rem_user(rnti); pdcp->rem_user(rnti); users.erase(rnti); + + srsran::console("Disconnecting rnti=0x%x.\n", rnti); logger.info("Removed user rnti=0x%x", rnti); } else { logger.error("Removing user rnti=0x%x (does not exist)", rnti); From bed4cfb5e50719d275f81d8a485bd17452c5a6e5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 27 Sep 2021 12:39:24 +0200 Subject: [PATCH 62/83] ue,mac_nr: fix generation of padding BSRs * in Msg3 don't add explicit SBSR (rely on padding BSR to add) * fix padding BSR generation to always use padding bytes to add it --- srsue/hdr/stack/mac_nr/mac_nr.h | 1 + srsue/hdr/stack/mac_nr/mac_nr_interfaces.h | 6 ++++ srsue/hdr/stack/mac_nr/proc_bsr_nr.h | 2 +- srsue/src/stack/mac_nr/mac_nr.cc | 5 ++++ srsue/src/stack/mac_nr/mux_nr.cc | 33 ++++++++++++++-------- srsue/src/stack/mac_nr/proc_bsr_nr.cc | 20 ++++++------- 6 files changed, 44 insertions(+), 23 deletions(-) diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h index 883011dc3..d22955a95 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -98,6 +98,7 @@ public: /// Interface for MUX srsran::mac_sch_subpdu_nr::lcg_bsr_t generate_sbsr(); + void set_padding_bytes(uint32_t nof_bytes); void msg3_flush() { mux.msg3_flush(); } bool msg3_is_transmitted() { return mux.msg3_is_transmitted(); } diff --git a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h index 0e265beab..9d0302122 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h +++ b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h @@ -54,11 +54,17 @@ public: class mac_interface_mux_nr { public: + // MUX can ask MAC if a C-RNTI is present + virtual bool has_crnti() = 0; + // MUX can query MAC for current C-RNTI for Msg3 transmission virtual uint16_t get_crnti() = 0; // MUX queries MAC to return LCG state for SBSR virtual srsran::mac_sch_subpdu_nr::lcg_bsr_t generate_sbsr() = 0; + + // MUX informs MAC about padding bytes so BSR proc can decide whether to create BSR or not + virtual void set_padding_bytes(uint32_t nof_bytes) = 0; }; /** diff --git a/srsue/hdr/stack/mac_nr/proc_bsr_nr.h b/srsue/hdr/stack/mac_nr/proc_bsr_nr.h index da2e88c6f..a0aa7e6ce 100644 --- a/srsue/hdr/stack/mac_nr/proc_bsr_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_bsr_nr.h @@ -69,7 +69,7 @@ public: /// MUX interface for BSR generation srsran::mac_sch_subpdu_nr::lcg_bsr_t generate_sbsr(); - bool generate_padding_bsr(uint32_t nof_padding_bytes); + void set_padding_bytes(uint32_t nof_bytes); private: const static int QUEUE_STATUS_PERIOD_MS = 1000; diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index 07191e613..d98e1a15c 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -209,6 +209,11 @@ srsran::mac_sch_subpdu_nr::lcg_bsr_t mac_nr::generate_sbsr() return proc_bsr.generate_sbsr(); } +void mac_nr::set_padding_bytes(uint32_t nof_bytes) +{ + proc_bsr.set_padding_bytes(nof_bytes); +} + void mac_nr::bch_decoded_ok(uint32_t tti, srsran::unique_byte_buffer_t payload) { // Send MIB to RLC diff --git a/srsue/src/stack/mac_nr/mux_nr.cc b/srsue/src/stack/mac_nr/mux_nr.cc index eb9bfbe6f..0c7da9923 100644 --- a/srsue/src/stack/mac_nr/mux_nr.cc +++ b/srsue/src/stack/mac_nr/mux_nr.cc @@ -63,14 +63,15 @@ srsran::unique_byte_buffer_t mux_nr::get_pdu(uint32_t max_pdu_len) tx_pdu.init_tx(phy_tx_pdu.get(), max_pdu_len, true); if (msg3_is_pending()) { - // If Msg3 is pending, pack it - // Use the CRNTI which is provided in the RRC reconfiguration (only for DC mode maybe other) - tx_pdu.add_crnti_ce(mac.get_crnti()); - tx_pdu.add_sbsr_ce(mac.generate_sbsr()); + // only C-RNTI or CCCH SDU can be transmitted in Msg3 + if (mac.has_crnti()) { + tx_pdu.add_crnti_ce(mac.get_crnti()); + } + // TODO: add CCCH check msg3_transmitted(); } else { // Pack normal UL data PDU - int32_t remaining_len = tx_pdu.get_remaing_len(); // local variable to reserv space for CEs + int32_t remaining_len = tx_pdu.get_remaing_len(); // local variable to reserve space for CEs if (add_bsr_ce == sbsr_ce) { // reserve space for SBSR @@ -115,16 +116,26 @@ srsran::unique_byte_buffer_t mux_nr::get_pdu(uint32_t max_pdu_len) } } } + } - // Second add fixed-sized MAC CEs (e.g. SBSR) - if (add_bsr_ce == sbsr_ce) { - tx_pdu.add_sbsr_ce(mac.generate_sbsr()); - add_bsr_ce = no_bsr; - } + // check if + if (add_bsr_ce == no_bsr) { + // tell BSR proc we still have space in PDU and let it decide to create a padding BSR + mac.set_padding_bytes(tx_pdu.get_remaing_len()); + } - // Lastly, add variable-sized MAC CEs + // Second add fixed-sized MAC CEs (e.g. SBSR) + if (add_bsr_ce == sbsr_ce) { + tx_pdu.add_sbsr_ce(mac.generate_sbsr()); + add_bsr_ce = no_bsr; + } else if (add_bsr_ce == lbsr_ce) { + // TODO: implement LBSR support + tx_pdu.add_sbsr_ce(mac.generate_sbsr()); + add_bsr_ce = no_bsr; } + // Lastly, add variable-sized MAC CEs + // Pack PDU tx_pdu.pack(); diff --git a/srsue/src/stack/mac_nr/proc_bsr_nr.cc b/srsue/src/stack/mac_nr/proc_bsr_nr.cc index 1fd3387ab..391264be7 100644 --- a/srsue/src/stack/mac_nr/proc_bsr_nr.cc +++ b/srsue/src/stack/mac_nr/proc_bsr_nr.cc @@ -209,8 +209,8 @@ void proc_bsr_nr::new_grant_ul(uint32_t grant_size) sr->reset(); } -// This function is called by MUX only if Regular BSR has not been triggered before -bool proc_bsr_nr::generate_padding_bsr(uint32_t nof_padding_bytes) +// This function is called by MUX only if no BSR has been triggered before +void proc_bsr_nr::set_padding_bytes(uint32_t nof_bytes) { std::lock_guard lock(mutex); @@ -219,16 +219,14 @@ bool proc_bsr_nr::generate_padding_bsr(uint32_t nof_padding_bytes) const uint32_t LBSR_CE_SUBHEADER_LEN = 1; // if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller // than the size of the Long BSR plus its subheader - if (nof_padding_bytes >= SBSR_CE_SUBHEADER_LEN + srsran::mac_sch_subpdu_nr::sizeof_ce(SHORT_BSR, true) && - nof_padding_bytes <= LBSR_CE_SUBHEADER_LEN + srsran::mac_sch_subpdu_nr::sizeof_ce(LONG_BSR, true)) { - // generate padding BSR - set_trigger(PADDING); - // generate_bsr(bsr, nof_padding_bytes); - set_trigger(NONE); - return true; + if (nof_bytes >= SBSR_CE_SUBHEADER_LEN + srsran::mac_sch_subpdu_nr::sizeof_ce(SHORT_BSR, true) && + nof_bytes < LBSR_CE_SUBHEADER_LEN + srsran::mac_sch_subpdu_nr::sizeof_ce(LONG_BSR, true)) { + // generate short padding BSR + mux->generate_bsr_mac_ce(SHORT_BSR); + } else if (nof_bytes >= LBSR_CE_SUBHEADER_LEN + srsran::mac_sch_subpdu_nr::sizeof_ce(LONG_BSR, true)) { + // report Long BSR if more than one LCG has data to send + mux->generate_bsr_mac_ce(LONG_BSR); } - - return false; } int proc_bsr_nr::setup_lcid(uint32_t lcid, uint32_t new_lcg, uint32_t priority) From ca6ea55cb6899c37fc0f32f700c6e7bf9d0750fd Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 27 Sep 2021 12:40:37 +0200 Subject: [PATCH 63/83] mac_nr_test: fix test vector after making padding BSR work --- srsue/src/stack/mac_nr/test/mac_nr_test.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/srsue/src/stack/mac_nr/test/mac_nr_test.cc b/srsue/src/stack/mac_nr/test/mac_nr_test.cc index b7899bb10..35baa845f 100644 --- a/srsue/src/stack/mac_nr/test/mac_nr_test.cc +++ b/srsue/src/stack/mac_nr/test/mac_nr_test.cc @@ -211,10 +211,12 @@ int mac_nr_ul_logical_channel_prioritization_test1() // PDU layout (20B in total) // - 2 B MAC subheader for SCH LCID=4 // - 10 B sduPDU + // - 1 B subheader SBRS (padding BSR) + // - 1 B SBSR (BSR will report bytes to transmit because BSR state isn't updated after packing PDU yet) // - 1 B subheader padding - // - 7 B padding + // - 5 B padding const uint8_t tv[] = {0x04, 0x0a, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + 0x04, 0x04, 0x3d, 0xc1, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00}; // dummy layers dummy_phy phy; From 8b2514ded35e591f469565602dc750a77e6d2ff3 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 23 Sep 2021 19:19:59 +0200 Subject: [PATCH 64/83] Added NZP-CSI-RS signals in gNb --- lib/include/srsran/phy/gnb/gnb_dl.h | 5 +++++ lib/src/phy/gnb/gnb_dl.c | 16 ++++++++++++++++ srsenb/src/phy/nr/slot_worker.cc | 7 +++++-- test/phy/dummy_gnb_stack.h | 14 ++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/lib/include/srsran/phy/gnb/gnb_dl.h b/lib/include/srsran/phy/gnb/gnb_dl.h index 77f0b07d0..909a42a03 100644 --- a/lib/include/srsran/phy/gnb/gnb_dl.h +++ b/lib/include/srsran/phy/gnb/gnb_dl.h @@ -13,6 +13,7 @@ #ifndef SRSRAN_GNB_DL_H #define SRSRAN_GNB_DL_H +#include "srsran/phy/ch_estimation/csi_rs.h" #include "srsran/phy/common/phy_common_nr.h" #include "srsran/phy/dft/ofdm.h" #include "srsran/phy/phch/pdcch_cfg_nr.h" @@ -78,4 +79,8 @@ srsran_gnb_dl_pdcch_dl_info(const srsran_gnb_dl_t* q, const srsran_dci_dl_nr_t* SRSRAN_API int srsran_gnb_dl_pdcch_ul_info(const srsran_gnb_dl_t* q, const srsran_dci_ul_nr_t* dci, char* str, uint32_t str_len); +SRSRAN_API int srsran_gnb_dl_nzp_csi_rs_put(srsran_gnb_dl_t* q, + const srsran_slot_cfg_t* slot_cfg, + const srsran_csi_rs_nzp_resource_t* resource); + #endif // SRSRAN_GNB_DL_H diff --git a/lib/src/phy/gnb/gnb_dl.c b/lib/src/phy/gnb/gnb_dl.c index e977007f1..f9554dac1 100644 --- a/lib/src/phy/gnb/gnb_dl.c +++ b/lib/src/phy/gnb/gnb_dl.c @@ -309,3 +309,19 @@ int srsran_gnb_dl_pdcch_ul_info(const srsran_gnb_dl_t* q, const srsran_dci_ul_nr return len; } + +int srsran_gnb_dl_nzp_csi_rs_put(srsran_gnb_dl_t* q, + const srsran_slot_cfg_t* slot_cfg, + const srsran_csi_rs_nzp_resource_t* resource) +{ + if (q == NULL) { + return SRSRAN_ERROR_INVALID_INPUTS; + } + + if (srsran_csi_rs_nzp_put_resource(&q->carrier, slot_cfg, resource, q->sf_symbols[0]) < SRSRAN_SUCCESS) { + ERROR("Error putting NZP-CSI-RS resource"); + return SRSRAN_ERROR; + } + + return SRSRAN_SUCCESS; +} diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index 2600940c0..cf49708f2 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -330,8 +330,11 @@ bool slot_worker::work_dl() } // Put NZP-CSI-RS - for (srsran_csi_rs_nzp_resource_t& pdsch : dl_sched.nzp_csi_rs) { - // ... + for (srsran_csi_rs_nzp_resource_t& nzp_csi_rs : dl_sched.nzp_csi_rs) { + if (srsran_gnb_dl_nzp_csi_rs_put(&gnb_dl, &dl_slot_cfg, &nzp_csi_rs) < SRSRAN_SUCCESS) { + logger.error("NZP-CSI-RS: Error putting signal"); + return false; + } } // Generate baseband signal diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index 50adf8dfe..a71b5589a 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -484,6 +484,20 @@ public: return SRSRAN_ERROR; } + // Schedule NZP-CSI-RS, iterate all NZP-CSI-RS sets + for (const srsran_csi_rs_nzp_set_t& set : phy_cfg.pdsch.nzp_csi_rs_sets) { + // For each NZP-CSI-RS resource available in the set + for (uint32_t i = 0; i < set.count; i++) { + // Select resource + const srsran_csi_rs_nzp_resource_t& nzp_csi_resource = set.data[i]; + + // Check if the resource is scheduled for this slot + if (srsran_csi_rs_send(&nzp_csi_resource.periodicity, &slot_cfg)) { + dl_sched.nzp_csi_rs.push_back(nzp_csi_resource); + } + } + } + return SRSRAN_SUCCESS; } From 315057d11c8ffdb09d8ce12a234826380955eacf Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Mon, 27 Sep 2021 21:29:56 +0200 Subject: [PATCH 65/83] enb: signal user activity to EUTRA RRC when doing NR DL traffic to avoid releasing the UE when only NR DL traffic is done. similar to the EUTRA solution. --- .../srsran/interfaces/enb_x2_interfaces.h | 7 +++++++ lib/include/srsran/interfaces/gnb_interfaces.h | 5 +++-- srsenb/hdr/stack/enb_stack_lte.h | 1 + srsenb/hdr/stack/rrc/rrc_nr.h | 10 +++++++--- srsenb/hdr/x2_adapter.h | 8 ++++++++ srsenb/src/stack/mac/nr/ue_nr.cc | 6 ++++++ srsenb/src/stack/rrc/rrc_nr.cc | 16 ++++++++++++++++ srsenb/test/common/dummy_classes_nr.h | 9 +++++---- 8 files changed, 53 insertions(+), 9 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_x2_interfaces.h b/lib/include/srsran/interfaces/enb_x2_interfaces.h index cc0495153..a19da0b6a 100644 --- a/lib/include/srsran/interfaces/enb_x2_interfaces.h +++ b/lib/include/srsran/interfaces/enb_x2_interfaces.h @@ -81,6 +81,13 @@ public: * @param nr_rnti The RNTI that has been assigned to the UE on the SgNB */ virtual void sgnb_addition_complete(uint16_t eutra_rnti, uint16_t nr_rnti) = 0; + + /** + * @brief Signal user activity (i.e. DL/UL traffic) for given RNTI + * + * @param eutra_rnti The RNTI that the EUTRA RRC uses + */ + virtual void set_activity_user(uint16_t eutra_rnti) = 0; }; class stack_nr_interface_stack_eutra diff --git a/lib/include/srsran/interfaces/gnb_interfaces.h b/lib/include/srsran/interfaces/gnb_interfaces.h index fb07f4303..12a3f4f39 100644 --- a/lib/include/srsran/interfaces/gnb_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_interfaces.h @@ -134,8 +134,9 @@ public: virtual int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) = 0; /// User management - virtual int add_user(uint16_t rnti) = 0; - virtual int update_user(uint16_t new_rnti, uint16_t old_rnti) = 0; + virtual int add_user(uint16_t rnti) = 0; + virtual int update_user(uint16_t new_rnti, uint16_t old_rnti) = 0; + virtual void set_activity_user(uint16_t rnti) = 0; }; // NR interface is almost identical to EUTRA version diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index eb4fd384d..93960db86 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -118,6 +118,7 @@ public: { rrc.sgnb_addition_complete(eutra_rnti, nr_rnti); } + void set_activity_user(uint16_t eutra_rnti) final { rrc.set_activity_user(eutra_rnti); } // gtpu_interface_pdcp void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu); diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 31b5da4c3..3e0c0ad21 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -62,15 +62,18 @@ public: void get_metrics(srsenb::rrc_metrics_t& m); rrc_nr_cfg_t update_default_cfg(const rrc_nr_cfg_t& rrc_cfg); - int add_user(uint16_t rnti); - void rem_user(uint16_t rnti); - int update_user(uint16_t new_rnti, uint16_t old_rnti); void config_phy(); void config_mac(); int32_t generate_sibs(); int read_pdu_bcch_bch(const uint32_t tti, srsran::unique_byte_buffer_t& buffer) final; int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) final; + /// User manegement + int add_user(uint16_t rnti); + void rem_user(uint16_t rnti); + int update_user(uint16_t new_rnti, uint16_t old_rnti); + void set_activity_user(uint16_t rnti); + // RLC interface // TODO void read_pdu_pcch(uint8_t* payload, uint32_t payload_size) {} @@ -112,6 +115,7 @@ public: bool is_idle() { return state == rrc_nr_state_t::RRC_IDLE; } bool is_inactive() { return state == rrc_nr_state_t::RRC_INACTIVE; } bool is_endc() { return endc; } + uint16_t get_eutra_rnti() { return eutra_rnti; } // setters diff --git a/srsenb/hdr/x2_adapter.h b/srsenb/hdr/x2_adapter.h index 22037945c..87f817edc 100644 --- a/srsenb/hdr/x2_adapter.h +++ b/srsenb/hdr/x2_adapter.h @@ -85,6 +85,14 @@ public: eutra_stack->sgnb_addition_complete(eutra_rnti, nr_rnti); } + void set_activity_user(uint16_t eutra_rnti) + { + if (eutra_stack == nullptr) { + return; + } + eutra_stack->set_activity_user(eutra_rnti); + } + // stack_nr_interface_stack_eutra void tti_clock() { diff --git a/srsenb/src/stack/mac/nr/ue_nr.cc b/srsenb/src/stack/mac/nr/ue_nr.cc index 75e89061d..f084fe6ca 100644 --- a/srsenb/src/stack/mac/nr/ue_nr.cc +++ b/srsenb/src/stack/mac/nr/ue_nr.cc @@ -143,6 +143,12 @@ int ue_nr::generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size) // add to MAC PDU and pack mac_pdu_dl.add_sdu(lcid, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes); + + // Indicate DRB activity in DL to RRC + if (lcid > 3) { + rrc->set_activity_user(rnti); + logger.debug("DL activity rnti=0x%x, n_bytes=%d", rnti, ue_rlc_buffer->N_bytes); + } } mac_pdu_dl.pack(); diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index ad3229995..b6b131beb 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -201,6 +201,22 @@ int rrc_nr::update_user(uint16_t new_rnti, uint16_t old_rnti) return SRSRAN_SUCCESS; } +void rrc_nr::set_activity_user(uint16_t rnti) +{ + auto it = users.find(rnti); + if (it == users.end()) { + logger.info("rnti=0x%x not found. Can't set activity", rnti); + return; + } + ue* ue_ptr = it->second.get(); + + // inform EUTRA RRC about user activity + if (ue_ptr->is_endc()) { + // inform EUTRA RRC about user activity + rrc_eutra->set_activity_user(ue_ptr->get_eutra_rnti()); + } +} + void rrc_nr::config_phy() { static const srsran::phy_cfg_nr_t default_phy_cfg = diff --git a/srsenb/test/common/dummy_classes_nr.h b/srsenb/test/common/dummy_classes_nr.h index 3464c878e..1fb094db4 100644 --- a/srsenb/test/common/dummy_classes_nr.h +++ b/srsenb/test/common/dummy_classes_nr.h @@ -21,10 +21,11 @@ namespace srsenb { class rrc_nr_dummy : public rrc_interface_mac_nr { public: - int read_pdu_bcch_bch(const uint32_t tti, srsran::unique_byte_buffer_t& buffer) { return SRSRAN_SUCCESS; } - int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) { return SRSRAN_SUCCESS; } - int add_user(uint16_t rnti) { return SRSRAN_SUCCESS; } - int update_user(uint16_t new_rnti, uint16_t old_rnti) { return SRSRAN_SUCCESS; } + int read_pdu_bcch_bch(const uint32_t tti, srsran::unique_byte_buffer_t& buffer) { return SRSRAN_SUCCESS; } + int read_pdu_bcch_dlsch(uint32_t sib_index, srsran::unique_byte_buffer_t& buffer) { return SRSRAN_SUCCESS; } + int add_user(uint16_t rnti) { return SRSRAN_SUCCESS; } + int update_user(uint16_t new_rnti, uint16_t old_rnti) { return SRSRAN_SUCCESS; } + void set_activity_user(uint16_t rnti) {} }; class rlc_nr_dummy : public rlc_interface_mac_nr From 17e015df62edf3b1d9f7653cf22de7e4618942dd Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 28 Sep 2021 16:51:11 +0200 Subject: [PATCH 66/83] rrc,nr: fix PUCCH Resource CSI configuration to avoid collisions with SR --- srsenb/src/stack/rrc/rrc_nr.cc | 64 ++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index b6b131beb..d1de70c57 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -181,6 +181,11 @@ void rrc_nr::rem_user(uint16_t rnti) */ int rrc_nr::update_user(uint16_t new_rnti, uint16_t old_rnti) { + if (new_rnti == old_rnti) { + logger.error("rnti=0x%x received MAC CRNTI CE with same rnti"); + return SRSRAN_ERROR; + } + // Remove new_rnti auto new_ue_it = users.find(new_rnti); if (new_ue_it != users.end()) { @@ -588,43 +593,42 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group // PDCCH config cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg_present = true; auto& pdcch_cfg_dedicated = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdcch_cfg; - pdcch_cfg_dedicated.set_setup(); - pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list_present = true; - pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list.resize(1); - pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list[0].ctrl_res_set_id = 2; - pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list[0].freq_domain_res.from_number( + auto& pdcch_ded_setup = pdcch_cfg_dedicated.set_setup(); + pdcch_ded_setup.ctrl_res_set_to_add_mod_list_present = true; + pdcch_ded_setup.ctrl_res_set_to_add_mod_list.resize(1); + pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].ctrl_res_set_id = 2; + pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].freq_domain_res.from_number( 0b111111110000000000000000000000000000000000000); - pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list[0].dur = 1; - pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list[0].cce_reg_map_type.set_non_interleaved(); - pdcch_cfg_dedicated.setup().ctrl_res_set_to_add_mod_list[0].precoder_granularity = + pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].dur = 1; + pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].cce_reg_map_type.set_non_interleaved(); + pdcch_ded_setup.ctrl_res_set_to_add_mod_list[0].precoder_granularity = asn1::rrc_nr::ctrl_res_set_s::precoder_granularity_opts::same_as_reg_bundle; // search spaces - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list_present = true; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list.resize(1); - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].search_space_id = 2; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].ctrl_res_set_id_present = true; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].ctrl_res_set_id = 2; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].monitoring_slot_periodicity_and_offset_present = true; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].monitoring_slot_periodicity_and_offset.set_sl1(); - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].monitoring_symbols_within_slot_present = true; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].monitoring_symbols_within_slot.from_number( - 0b10000000000000); - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].nrof_candidates_present = true; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level1 = + pdcch_ded_setup.search_spaces_to_add_mod_list_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list.resize(1); + pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_id = 2; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].ctrl_res_set_id_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].ctrl_res_set_id = 2; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_slot_periodicity_and_offset_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_slot_periodicity_and_offset.set_sl1(); + pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_symbols_within_slot_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].monitoring_symbols_within_slot.from_number(0b10000000000000); + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level1 = asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level1_opts::n0; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level2 = + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level2 = asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level2_opts::n2; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level4 = + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level4 = asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level4_opts::n1; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level8 = + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level8 = asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level8_opts::n0; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level16 = + pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level16 = asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level16_opts::n0; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].search_space_type_present = true; - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].search_space_type.set_ue_specific(); - pdcch_cfg_dedicated.setup().search_spaces_to_add_mod_list[0].search_space_type.ue_specific().dci_formats = asn1:: - rrc_nr::search_space_s::search_space_type_c_::ue_specific_s_::dci_formats_opts::formats0_minus0_and_minus1_minus0; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_type_present = true; + pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_type.set_ue_specific(); + pdcch_ded_setup.search_spaces_to_add_mod_list[0].search_space_type.ue_specific().dci_formats = asn1::rrc_nr:: + search_space_s::search_space_type_c_::ue_specific_s_::dci_formats_opts::formats0_minus0_and_minus1_minus0; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg_present = true; auto& pdsch_cfg_dedicated = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.init_dl_bwp.pdsch_cfg; @@ -852,7 +856,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group csi_report.report_cfg_type.periodic().report_slot_cfg.set_slots80(); csi_report.report_cfg_type.periodic().pucch_csi_res_list.resize(1); csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].ul_bw_part_id = 0; - csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].pucch_res = 0; // was 17 in orig PCAP + csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].pucch_res = 1; // was 17 in orig PCAP csi_report.report_quant.set_cri_ri_pmi_cqi(); // Report freq config (optional) csi_report.report_freq_cfg_present = true; @@ -1173,7 +1177,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_tdd(asn1::dyn_octstring& packed // CSI report config auto& csi_report = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list[0]; - csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 8; + csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 7; // Reconfig with Sync cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.smtc.release(); From a8f58f503c11ae1b396f21da9760f50cdd8a50a1 Mon Sep 17 00:00:00 2001 From: faluco Date: Wed, 29 Sep 2021 11:40:29 +0200 Subject: [PATCH 67/83] - Fix arm compiler warning. GCC treats chars as unsigned in this arch. - Fix race condition in json metrics. --- lib/src/common/enb_events.cc | 3 ++- srsenb/hdr/metrics_json.h | 3 +-- srsenb/src/main.cc | 3 +-- srsenb/src/metrics_json.cc | 5 ----- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/lib/src/common/enb_events.cc b/lib/src/common/enb_events.cc index 30f19ac33..54276527e 100644 --- a/lib/src/common/enb_events.cc +++ b/lib/src/common/enb_events.cc @@ -94,7 +94,8 @@ static std::string escape_string(const std::string& s) fmt::format_to(buff, "\\t"); break; default: - if ('\x00' <= c && c <= '\x1f') { + // Cast to signed char for machines that treat chars as an unsigned type. + if ((signed char)c >= '\x00' && (signed char)c <= '\x1f') { fmt::format_to(buff, "\\u{:04x}", c); } else { buff.push_back(c); diff --git a/srsenb/hdr/metrics_json.h b/srsenb/hdr/metrics_json.h index 4692de03b..5d9388413 100644 --- a/srsenb/hdr/metrics_json.h +++ b/srsenb/hdr/metrics_json.h @@ -26,10 +26,9 @@ namespace srsenb { class metrics_json : public srsran::metrics_listener { public: - metrics_json(srslog::log_channel& c) : log_c(c) {} + metrics_json(srslog::log_channel& c, enb_metrics_interface* enb_) : log_c(c), enb(enb_) {} void set_metrics(const enb_metrics_t& m, const uint32_t period_usec) override; - void set_handle(enb_metrics_interface* enb_); void stop() override {} private: diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index da428aba8..6c80cb8a0 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -607,10 +607,9 @@ int main(int argc, char* argv[]) metrics_file.set_handle(enb.get()); } - srsenb::metrics_json json_metrics(json_channel); + srsenb::metrics_json json_metrics(json_channel, enb.get()); if (args.general.report_json_enable) { metricshub.add_listener(&json_metrics); - json_metrics.set_handle(enb.get()); } // create input thread diff --git a/srsenb/src/metrics_json.cc b/srsenb/src/metrics_json.cc index b706836d6..b88027534 100644 --- a/srsenb/src/metrics_json.cc +++ b/srsenb/src/metrics_json.cc @@ -15,11 +15,6 @@ using namespace srsenb; -void metrics_json::set_handle(enb_metrics_interface* enb_) -{ - enb = enb_; -} - namespace { /// Bearer container metrics. From d927b779dc2220ee3acb969dc3ff9265529e14a0 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Tue, 28 Sep 2021 11:57:45 +0200 Subject: [PATCH 68/83] sched,nr: implement methods to fill nzp csi-rs in scheduler --- srsenb/hdr/stack/mac/nr/sched_nr_cfg.h | 8 ++- .../stack/mac/nr/sched_nr_grant_allocator.h | 4 +- srsenb/hdr/stack/mac/nr/sched_nr_signalling.h | 36 ++++++++++++ srsenb/src/stack/mac/nr/CMakeLists.txt | 3 +- .../src/stack/mac/nr/sched_nr_signalling.cc | 55 +++++++++++++++++++ srsenb/src/stack/mac/nr/sched_nr_worker.cc | 7 +++ 6 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 srsenb/hdr/stack/mac/nr/sched_nr_signalling.h create mode 100644 srsenb/src/stack/mac/nr/sched_nr_signalling.cc diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h index 210e34921..0839b523e 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h @@ -30,12 +30,16 @@ const static size_t MAX_GRANTS = sched_nr_interface::MAX_GRANTS; using pdcch_dl_t = mac_interface_phy_nr::pdcch_dl_t; using pdcch_ul_t = mac_interface_phy_nr::pdcch_ul_t; +using pdsch_t = mac_interface_phy_nr::pdsch_t; +using pusch_t = mac_interface_phy_nr::pusch_t; +using pucch_t = mac_interface_phy_nr::pucch_t; using pdcch_dl_list_t = srsran::bounded_vector; using pdcch_ul_list_t = srsran::bounded_vector; -using pucch_t = mac_interface_phy_nr::pucch_t; using pucch_list_t = srsran::bounded_vector; -using pusch_t = mac_interface_phy_nr::pusch_t; using pusch_list_t = srsran::bounded_vector; +using nzp_csi_rs_list = srsran::bounded_vector; +using ssb_t = mac_interface_phy_nr::ssb_t; +using ssb_list = srsran::bounded_vector; using sched_cfg_t = sched_nr_interface::sched_cfg_t; using cell_cfg_t = sched_nr_interface::cell_cfg_t; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h b/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h index a306fc5a6..9f49a22bd 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_grant_allocator.h @@ -23,6 +23,7 @@ namespace srsenb { namespace sched_nr_impl { +// typedefs using dl_sched_rar_info_t = sched_nr_interface::dl_sched_rar_info_t; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -30,7 +31,6 @@ using dl_sched_rar_info_t = sched_nr_interface::dl_sched_rar_info_t; const static size_t MAX_CORESET_PER_BWP = 3; using slot_coreset_list = std::array, MAX_CORESET_PER_BWP>; -using pdsch_t = mac_interface_phy_nr::pdsch_t; using pdsch_list_t = srsran::bounded_vector; using sched_rar_list_t = sched_nr_interface::sched_rar_list_t; using pucch_list_t = srsran::bounded_vector; @@ -47,6 +47,8 @@ struct bwp_slot_grid { bwp_rb_bitmap dl_prbs; bwp_rb_bitmap ul_prbs; + ssb_list ssb; + nzp_csi_rs_list nzp_csi_rs; pdcch_dl_list_t dl_pdcchs; pdcch_ul_list_t ul_pdcchs; pdsch_list_t pdschs; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_signalling.h b/srsenb/hdr/stack/mac/nr/sched_nr_signalling.h new file mode 100644 index 000000000..e7bc59f96 --- /dev/null +++ b/srsenb/hdr/stack/mac/nr/sched_nr_signalling.h @@ -0,0 +1,36 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#ifndef SRSRAN_SCHED_NR_SIGNALLING_H +#define SRSRAN_SCHED_NR_SIGNALLING_H + +#include "sched_nr_cfg.h" +#include "sched_nr_interface.h" + +namespace srsenb { +namespace sched_nr_impl { + +/// Schedule NZP-CSI-RS resources for given slot +void sched_nzp_csi_rs(srsran::const_span nzp_csi_rs_sets, + const srsran_slot_cfg_t& slot_cfg, + nzp_csi_rs_list& csi_rs_list); + +/// For a given BWP and slot, schedule SSB, NZP CSI RS and SIBs +void sched_dl_signalling(const bwp_params& bwp_params, + slot_point sl_pdcch, + ssb_list& ssb_list, + nzp_csi_rs_list& nzp_csi_rs); + +} // namespace sched_nr_impl +} // namespace srsenb + +#endif // SRSRAN_SCHED_NR_SIGNALLING_H diff --git a/srsenb/src/stack/mac/nr/CMakeLists.txt b/srsenb/src/stack/mac/nr/CMakeLists.txt index 51e8d57eb..4e7c859ef 100644 --- a/srsenb/src/stack/mac/nr/CMakeLists.txt +++ b/srsenb/src/stack/mac/nr/CMakeLists.txt @@ -19,7 +19,8 @@ set(SOURCES mac_nr.cc sched_nr_cell.cc sched_nr_rb.cc sched_nr_time_rr.cc - harq_softbuffer.cc) + harq_softbuffer.cc + sched_nr_signalling.cc) add_library(srsgnb_mac STATIC ${SOURCES}) target_link_libraries(srsgnb_mac srsenb_mac_common) diff --git a/srsenb/src/stack/mac/nr/sched_nr_signalling.cc b/srsenb/src/stack/mac/nr/sched_nr_signalling.cc new file mode 100644 index 000000000..f7c0e9b9e --- /dev/null +++ b/srsenb/src/stack/mac/nr/sched_nr_signalling.cc @@ -0,0 +1,55 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2021 Software Radio Systems Limited + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the distribution. + * + */ + +#include "srsenb/hdr/stack/mac/nr/sched_nr_signalling.h" + +namespace srsenb { +namespace sched_nr_impl { + +void sched_nzp_csi_rs(srsran::const_span nzp_csi_rs_sets_cfg, + const srsran_slot_cfg_t& slot_cfg, + nzp_csi_rs_list& csi_rs_list) +{ + for (const srsran_csi_rs_nzp_set_t& set : nzp_csi_rs_sets_cfg) { + // For each NZP-CSI-RS resource available in the set + for (uint32_t i = 0; i < set.count; ++i) { + // Select resource + const srsran_csi_rs_nzp_resource_t& nzp_csi_resource = set.data[i]; + + // Check if the resource is scheduled for this slot + if (srsran_csi_rs_send(&nzp_csi_resource.periodicity, &slot_cfg)) { + csi_rs_list.push_back(nzp_csi_resource); + } + } + } +} + +void sched_dl_signalling(const bwp_params& bwp_params, + slot_point sl_pdcch, + ssb_list& ssb_list, + nzp_csi_rs_list& nzp_csi_rs) +{ + srsran_slot_cfg_t cfg; + cfg.idx = sl_pdcch.to_uint(); + + // Schedule SSB + // TODO + + // Schedule NZP-CSI-RS + sched_nzp_csi_rs(bwp_params.cfg.pdsch.nzp_csi_rs_sets, cfg, nzp_csi_rs); + + // Schedule SIBs + // TODO +} + +} // namespace sched_nr_impl +} // namespace srsenb diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index 57b1d40ad..f003d1783 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -11,6 +11,7 @@ */ #include "srsenb/hdr/stack/mac/nr/sched_nr_worker.h" +#include "srsenb/hdr/stack/mac/nr/sched_nr_signalling.h" #include "srsran/common/string_helpers.h" namespace srsenb { @@ -255,6 +256,12 @@ void sched_worker_manager::update_ue_db(slot_point slot_tx, bool locked_context) void sched_worker_manager::run_slot(slot_point slot_tx, uint32_t cc, dl_sched_res_t& dl_res, ul_sched_t& ul_res) { + // Fill DL signalling messages that do not depend on UEs state + serv_cell_manager& serv_cell = *cells[cc]; + bwp_slot_grid& bwp_slot = serv_cell.bwps[0].grid[slot_tx]; + sched_dl_signalling(*serv_cell.bwps[0].cfg, slot_tx, bwp_slot.ssb, bwp_slot.nzp_csi_rs); + + // Synchronization point between CC workers, to avoid concurrency in UE state access srsran::bounded_vector waiting_cvars; { std::unique_lock lock(slot_mutex); From c45c3ec95cec2e112460113c6a3c02434a9a85ec Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 29 Sep 2021 12:21:33 +0200 Subject: [PATCH 69/83] sched,nr: ensure the SSB and NZP CSI RS allocations are cleared at the end of every slot --- .../src/stack/mac/nr/sched_nr_grant_allocator.cc | 2 ++ srsenb/src/stack/mac/nr/sched_nr_worker.cc | 14 ++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc index fc16c9a25..819273469 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -47,6 +47,8 @@ void bwp_slot_grid::reset() puschs.clear(); pending_acks.clear(); pucch.clear(); + ssb.clear(); + nzp_csi_rs.clear(); } bwp_res_grid::bwp_res_grid(const bwp_params& bwp_cfg_) : cfg(&bwp_cfg_) diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index f003d1783..091aba845 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -343,12 +343,14 @@ bool sched_worker_manager::save_sched_result(slot_point pdcch_slot, // NOTE: Unlocked region auto& bwp_slot = cells[cc]->bwps[0].grid[pdcch_slot]; - dl_res.dl_sched.pdcch_dl = bwp_slot.dl_pdcchs; - dl_res.dl_sched.pdcch_ul = bwp_slot.ul_pdcchs; - dl_res.dl_sched.pdsch = bwp_slot.pdschs; - dl_res.rar = bwp_slot.rar; - ul_res.pusch = bwp_slot.puschs; - ul_res.pucch = bwp_slot.pucch; + dl_res.dl_sched.pdcch_dl = bwp_slot.dl_pdcchs; + dl_res.dl_sched.pdcch_ul = bwp_slot.ul_pdcchs; + dl_res.dl_sched.pdsch = bwp_slot.pdschs; + dl_res.rar = bwp_slot.rar; + dl_res.dl_sched.ssb = bwp_slot.ssb; + dl_res.dl_sched.nzp_csi_rs = bwp_slot.nzp_csi_rs; + ul_res.pusch = bwp_slot.puschs; + ul_res.pucch = bwp_slot.pucch; // clear up BWP slot bwp_slot.reset(); From 2d0be776606c1c09ffb35d875ef9c5dbf80b11aa Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 29 Sep 2021 13:39:51 +0200 Subject: [PATCH 70/83] Add helper functions for abs freq point a. --- lib/include/srsran/common/band_helper.h | 112 +++++++++++++----------- lib/src/common/band_helper.cc | 14 +++ 2 files changed, 75 insertions(+), 51 deletions(-) diff --git a/lib/include/srsran/common/band_helper.h b/lib/include/srsran/common/band_helper.h index 7729dc34d..de777d79e 100644 --- a/lib/include/srsran/common/band_helper.h +++ b/lib/include/srsran/common/band_helper.h @@ -105,6 +105,15 @@ public: */ double get_ul_center_freq(const srsran_carrier_nr_t& carrier); + /** + * @brief Compute the absolute frequency point A for a arfcn + * + * @param nof_prb Number of PRBs. + * @param arfcn Given ARFCN. + * @return frequency point A in arfcn notation. + */ + uint32_t get_abs_freq_point_a_arfcn(uint32_t nof_prb, uint32_t arfcn); + class sync_raster_t { protected: @@ -139,6 +148,8 @@ private: // internal helper double get_center_freq_from_abs_freq_point_a(uint32_t nof_prb, uint32_t freq_point_a_arfcn); + double get_abs_freq_point_a_from_center_freq(uint32_t nof_prb, double center_freq); + // Elements of TS 38.101-1 Table 5.2-1: NR operating bands in FR1 struct nr_operating_band { uint16_t band; @@ -240,22 +251,22 @@ private: {1, KHZ_100, 384000, 20, 396000, 422000, 20, 434000}, {2, KHZ_100, 370000, 20, 382000, 386000, 20, 398000}, {3, KHZ_100, 342000, 20, 357000, 361000, 20, 376000}, - + {5, KHZ_100, 164800, 20, 169800, 173800, 20, 178800}, {7, KHZ_100, 500000, 20, 514000, 524000, 20, 538000}, {8, KHZ_100, 176000, 20, 183000, 185000, 20, 192000}, - + {12, KHZ_100, 139800, 20, 143200, 145800, 20, 149200}, - + {20, KHZ_100, 166400, 20, 172400, 158200, 20, 164200}, {25, KHZ_100, 370000, 20, 383000, 386000, 20, 399000}, {28, KHZ_100, 140600, 20, 149600, 151600, 20, 160600}, - + {34, KHZ_100, 402000, 20, 405000, 402000, 20, 405000}, {38, KHZ_100, 514000, 20, 524000, 514000, 20, 524000}, {39, KHZ_100, 376000, 20, 384000, 376000, 20, 384000}, - + {40, KHZ_100, 460000, 20, 480000, 460000, 20, 480000}, {41, KHZ_15, 499200, 3, 537999, 499200, 3, 537999}, @@ -263,13 +274,13 @@ private: {50, KHZ_100, 286400, 20, 303400, 286400, 20, 303400}, {51, KHZ_100, 285400, 20, 286400, 285400, 20, 286400}, - + {66, KHZ_100, 342000, 20, 356000, 422000, 20, 440000}, - + {70, KHZ_100, 339000, 20, 342000, 399000, 20, 404000}, {71, KHZ_100, 132600, 20, 139600, 123400, 20, 130400}, {74, KHZ_100, 285400, 20, 294000, 295000, 20, 303600}, - + {75, KHZ_100, 0, 0, 0, 286400, 20, 303400}, {76, KHZ_100, 0, 0, 0, 285400, 20, 286400}, @@ -288,23 +299,22 @@ private: {83, KHZ_100, 140600, 20, 149600, 0, 0, 0}, {84, KHZ_100, 384000, 20, 396000, 0, 0, 0}, {86, KHZ_100, 342000, 20, 356000, 0, 0, 0} - // clang-format on + // clang-format on }}; static const uint32_t nof_nr_bands_fr2 = 8; - static constexpr std::array nr_band_table_fr2 = {{ - {257, KHZ_60, 2054166, 1, 2104165, 2054166, 1, 2104165}, - {257, KHZ_120, 2054167, 2, 2104165, 2054167, 20, 2104165}, - - {258, KHZ_60, 2016667, 1, 2070832, 2016667, 1, 2070832}, - {258, KHZ_120, 2016667, 2, 2070831, 2016667, 2, 2070832}, - - {260, KHZ_60, 2229166, 1, 2279165, 2229166, 1, 2279165}, - {260, KHZ_120, 2229167, 2, 2279165, 2229167, 2, 2279165}, - - {261, KHZ_60, 2070833, 1, 2084999, 2070833, 1, 2084999}, - {261, KHZ_120, 2070833, 2, 2084999, 2070833, 2, 2084999} - }}; + static constexpr std::array nr_band_table_fr2 = { + {{257, KHZ_60, 2054166, 1, 2104165, 2054166, 1, 2104165}, + {257, KHZ_120, 2054167, 2, 2104165, 2054167, 20, 2104165}, + + {258, KHZ_60, 2016667, 1, 2070832, 2016667, 1, 2070832}, + {258, KHZ_120, 2016667, 2, 2070831, 2016667, 2, 2070832}, + + {260, KHZ_60, 2229166, 1, 2279165, 2229166, 1, 2279165}, + {260, KHZ_120, 2229167, 2, 2279165, 2229167, 2, 2279165}, + + {261, KHZ_60, 2070833, 1, 2084999, 2070833, 1, 2084999}, + {261, KHZ_120, 2070833, 2, 2084999, 2070833, 2, 2084999}}}; // Elements of TS 38.101-1 Table 5.4.3.3-1 : Applicable SS raster entries per operating band struct nr_band_ss_raster { @@ -317,35 +327,35 @@ private: }; static const uint32_t nof_nr_band_ss_raster = 29; static constexpr std::array nr_band_ss_raster_table = {{ - {1, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 5279, 1, 5419}, - {2, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 4829, 1, 4969}, - {3, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 4517, 1, 4693}, - {5, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 2177, 1, 2230}, - {5, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_B, 2183, 1, 2224}, - {7, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 6554, 1, 6718}, - {8, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 2318, 1, 2395}, - {12, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 1828, 1, 1858}, - {20, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 1982, 1, 2047}, - {25, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 4829, 1, 4981}, - {28, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 1901, 1, 2002}, - {34, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 5030, 1, 5056}, - {38, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 6431, 1, 6544}, - {39, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 4706, 1, 4795}, - {40, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 5756, 1, 5995}, - {41, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 6246, 3, 6717}, - {41, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_C, 6252, 3, 6714}, - {50, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 3584, 1, 3787}, - {51, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 3572, 1, 3574}, - {66, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 5279, 1, 5494}, - {66, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_B, 5285, 1, 5488}, - {70, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 4993, 1, 5044}, - {71, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 1547, 1, 1624}, - {74, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 3692, 1, 3790}, - {75, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 3584, 1, 3787}, - {76, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 3572, 1, 3574}, - {77, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_C, 7711, 1, 8329}, - {78, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_C, 7711, 1, 8051}, - {79, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_C, 8480, 16, 8880}, + {1, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 5279, 1, 5419}, + {2, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 4829, 1, 4969}, + {3, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 4517, 1, 4693}, + {5, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 2177, 1, 2230}, + {5, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_B, 2183, 1, 2224}, + {7, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 6554, 1, 6718}, + {8, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 2318, 1, 2395}, + {12, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 1828, 1, 1858}, + {20, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 1982, 1, 2047}, + {25, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 4829, 1, 4981}, + {28, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 1901, 1, 2002}, + {34, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 5030, 1, 5056}, + {38, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 6431, 1, 6544}, + {39, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 4706, 1, 4795}, + {40, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 5756, 1, 5995}, + {41, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 6246, 3, 6717}, + {41, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_C, 6252, 3, 6714}, + {50, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 3584, 1, 3787}, + {51, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 3572, 1, 3574}, + {66, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 5279, 1, 5494}, + {66, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_B, 5285, 1, 5488}, + {70, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 4993, 1, 5044}, + {71, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 1547, 1, 1624}, + {74, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 3692, 1, 3790}, + {75, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 3584, 1, 3787}, + {76, srsran_subcarrier_spacing_15kHz, SRSRAN_SSB_PATTERN_A, 3572, 1, 3574}, + {77, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_C, 7711, 1, 8329}, + {78, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_C, 7711, 1, 8051}, + {79, srsran_subcarrier_spacing_30kHz, SRSRAN_SSB_PATTERN_C, 8480, 16, 8880}, }}; }; diff --git a/lib/src/common/band_helper.cc b/lib/src/common/band_helper.cc index ec31770a1..968e94916 100644 --- a/lib/src/common/band_helper.cc +++ b/lib/src/common/band_helper.cc @@ -129,6 +129,20 @@ double srsran_band_helper::get_center_freq_from_abs_freq_point_a(uint32_t nof_pr SRSRAN_NRE); } +uint32_t srsran_band_helper::get_abs_freq_point_a_arfcn(uint32_t nof_prb, uint32_t arfcn) +{ + return freq_to_nr_arfcn(get_abs_freq_point_a_from_center_freq(nof_prb, nr_arfcn_to_freq(arfcn))); +} + +double srsran_band_helper::get_abs_freq_point_a_from_center_freq(uint32_t nof_prb, double center_freq) +{ + // for FR1 unit of resources blocks for freq calc is always 180kHz regardless for actual SCS of carrier + // TODO: add offset_to_carrier + return center_freq - + (nof_prb / 2 * SRSRAN_SUBC_SPACING_NR(srsran_subcarrier_spacing_t::srsran_subcarrier_spacing_15kHz) * + SRSRAN_NRE); +} + srsran_ssb_patern_t srsran_band_helper::get_ssb_pattern(uint16_t band, srsran_subcarrier_spacing_t scs) const { // Look for the given band and SCS From 9b1d7838120adadfa1b32f42f88003ad35c9482b Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 29 Sep 2021 15:09:32 +0200 Subject: [PATCH 71/83] Code formatting. --- test/phy/nr_phy_test.cc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/test/phy/nr_phy_test.cc b/test/phy/nr_phy_test.cc index ce5b97f40..2e7959e99 100644 --- a/test/phy/nr_phy_test.cc +++ b/test/phy/nr_phy_test.cc @@ -40,7 +40,7 @@ test_bench::args_t::args_t(int argc, char** argv) ("rnti", bpo::value(&rnti)->default_value(rnti), "UE RNTI") ("duration", bpo::value(&durations_slots)->default_value(durations_slots), "Test duration in slots") ("lib.log.level", bpo::value(&phy_lib_log_level)->default_value(phy_lib_log_level), "PHY librray log level") - ("reference", bpo::value(&reference_cfg_str)->default_value(reference_cfg_str), "Reference PHY configuration arguments") + ("reference", bpo::value(&reference_cfg_str)->default_value(reference_cfg_str), "Reference PHY configuration arguments") ; options_gnb_stack.add_options() @@ -60,25 +60,25 @@ test_bench::args_t::args_t(int argc, char** argv) ; options_gnb_phy.add_options() - ("gnb.phy.nof_threads", bpo::value(&gnb_phy.nof_phy_threads)->default_value(1), "Number of threads") - ("gnb.phy.log.level", bpo::value(&gnb_phy.log.phy_level)->default_value("warning"), "gNb PHY log level") - ("gnb.phy.log.hex_limit", bpo::value(&gnb_phy.log.phy_hex_limit)->default_value(0), "gNb PHY log hex limit") - ("gnb.phy.log.id_preamble", bpo::value(&gnb_phy.log.id_preamble)->default_value("GNB/"), "gNb PHY log ID preamble") - ("gnb.phy.pusch.max_iter", bpo::value(&gnb_phy.pusch_max_nof_iter)->default_value(10), "PUSCH LDPC max number of iterations") - ; + ("gnb.phy.nof_threads", bpo::value(&gnb_phy.nof_phy_threads)->default_value(1), "Number of threads") + ("gnb.phy.log.level", bpo::value(&gnb_phy.log.phy_level)->default_value("warning"), "gNb PHY log level") + ("gnb.phy.log.hex_limit", bpo::value(&gnb_phy.log.phy_hex_limit)->default_value(0), "gNb PHY log hex limit") + ("gnb.phy.log.id_preamble", bpo::value(&gnb_phy.log.id_preamble)->default_value("GNB/"), "gNb PHY log ID preamble") + ("gnb.phy.pusch.max_iter", bpo::value(&gnb_phy.pusch_max_nof_iter)->default_value(10), "PUSCH LDPC max number of iterations") + ; options_ue_phy.add_options() - ("ue.phy.nof_threads", bpo::value(&ue_phy.nof_phy_threads)->default_value(1), "Number of threads") - ("ue.phy.log.level", bpo::value(&ue_phy.log.phy_level)->default_value("warning"), "UE PHY log level") - ("ue.phy.log.hex_limit", bpo::value(&ue_phy.log.phy_hex_limit)->default_value(0), "UE PHY log hex limit") - ("ue.phy.log.id_preamble", bpo::value(&ue_phy.log.id_preamble)->default_value(" UE/"), "UE PHY log ID preamble") - ; + ("ue.phy.nof_threads", bpo::value(&ue_phy.nof_phy_threads)->default_value(1), "Number of threads") + ("ue.phy.log.level", bpo::value(&ue_phy.log.phy_level)->default_value("warning"), "UE PHY log level") + ("ue.phy.log.hex_limit", bpo::value(&ue_phy.log.phy_hex_limit)->default_value(0), "UE PHY log hex limit") + ("ue.phy.log.id_preamble", bpo::value(&ue_phy.log.id_preamble)->default_value(" UE/"), "UE PHY log ID preamble") + ; options_ue_stack.add_options() - ("ue.stack.sr.period", bpo::value(&ue_stack.sr_period)->default_value(ue_stack.sr_period), "SR period in number of opportunities. Set 0 to disable and 1 for all.") - ("ue.stack.prach.period", bpo::value(&ue_stack.prach_period)->default_value(ue_stack.prach_period), "PRACH period in SFN. Set 0 to disable and 1 for all.") - ("ue.stack.prach.preamble", bpo::value(&ue_stack.prach_preamble)->default_value(ue_stack.prach_preamble), "PRACH preamble. Set 0 to disable and 1 for all.") - ; + ("ue.stack.sr.period", bpo::value(&ue_stack.sr_period)->default_value(ue_stack.sr_period), "SR period in number of opportunities. Set 0 to disable and 1 for all.") + ("ue.stack.prach.period", bpo::value(&ue_stack.prach_period)->default_value(ue_stack.prach_period), "PRACH period in SFN. Set 0 to disable and 1 for all.") + ("ue.stack.prach.preamble", bpo::value(&ue_stack.prach_preamble)->default_value(ue_stack.prach_preamble), "PRACH preamble. Set 0 to disable and 1 for all.") + ; options.add(options_gnb_stack).add(options_gnb_phy).add(options_ue_stack).add(options_ue_phy).add_options() ("help", "Show this message") From 8830c2796f8fe801e147b8f8f05f598deb023016 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 29 Sep 2021 15:14:48 +0200 Subject: [PATCH 72/83] Add support for NSA FDD on band n3, n5 and n7. --- .../srsran/interfaces/gnb_interfaces.h | 1 + .../srsran/interfaces/gnb_rrc_nr_interfaces.h | 10 +- lib/include/srsran/phy/phch/prach.h | 11 +- lib/src/asn1/rrc_nr_utils.cc | 2 + lib/src/common/phy_cfg_nr_default.cc | 2 + lib/src/phy/phch/prach.c | 100 +++++- lib/src/phy/phch/prach_tables.h | 33 +- lib/test/asn1/srsran_asn1_rrc_nr_test.cc | 153 ++++++++-- srsenb/src/enb_cfg_parser.cc | 9 +- srsenb/src/phy/nr/worker_pool.cc | 1 + srsenb/src/stack/rrc/rrc_nr.cc | 285 +++++++++++++----- srsue/hdr/stack/rrc/rrc.h | 1 + srsue/hdr/stack/rrc/rrc_nr.h | 8 +- srsue/src/phy/nr/sf_worker.cc | 2 +- srsue/src/phy/nr/worker_pool.cc | 1 + srsue/src/phy/phy.cc | 4 +- srsue/src/stack/rrc/rrc.cc | 8 +- srsue/src/stack/rrc/rrc_nr.cc | 35 +-- srsue/src/ue.cc | 1 + test/phy/CMakeLists.txt | 15 +- test/phy/test_bench.h | 1 + 21 files changed, 523 insertions(+), 160 deletions(-) diff --git a/lib/include/srsran/interfaces/gnb_interfaces.h b/lib/include/srsran/interfaces/gnb_interfaces.h index 12a3f4f39..ec4d23f52 100644 --- a/lib/include/srsran/interfaces/gnb_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_interfaces.h @@ -161,6 +161,7 @@ public: srsran_carrier_nr_t carrier; srsran_pdcch_cfg_nr_t pdcch; srsran_prach_cfg_t prach; + srsran_duplex_mode_t duplex_mode; }; virtual int set_common_cfg(const common_cfg_t& common_cfg) = 0; diff --git a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h index 1033608b5..f880a4fc8 100644 --- a/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_rrc_nr_interfaces.h @@ -34,10 +34,12 @@ public: // Cell/Sector configuration for NR cells struct rrc_cell_cfg_nr_t { - phy_cell_cfg_nr_t phy_cell; // already contains all PHY-related parameters (i.e. RF port, PCI, etc.) - uint32_t tac; // Tracking area code - uint32_t dl_arfcn; // DL freq already included in phy_cell - uint32_t ul_arfcn; // UL freq also in phy_cell + phy_cell_cfg_nr_t phy_cell; // already contains all PHY-related parameters (i.e. RF port, PCI, etc.) + uint32_t tac; // Tracking area code + uint32_t dl_arfcn; // DL freq already included in phy_cell + uint32_t ul_arfcn; // UL freq also in phy_cell + uint32_t band; + srsran_duplex_mode_t duplex_mode; }; typedef std::vector rrc_cell_list_nr_t; diff --git a/lib/include/srsran/phy/phch/prach.h b/lib/include/srsran/phy/phch/prach.h index 942c5aad5..9857b8d0a 100644 --- a/lib/include/srsran/phy/phch/prach.h +++ b/lib/include/srsran/phy/phch/prach.h @@ -23,6 +23,7 @@ #include "srsran/config.h" #include "srsran/phy/common/phy_common.h" +#include "srsran/phy/common/phy_common_nr.h" #include "srsran/phy/dft/dft.h" #include #include @@ -117,7 +118,7 @@ typedef struct SRSRAN_API { } srsran_prach_sf_config_t; ///@brief Maximum number of subframe number candidates for PRACH NR configuration -#define PRACH_NR_CFG_MAX_NOF_SF 5 +#define PRACH_NR_CFG_MAX_NOF_SF 10 /** * @brief PRACH configuration for NR as described in TS 38.211 Tables 6.3.3.2-2, 6.3.3.2-3 and 6.3.3.2-4 @@ -177,11 +178,17 @@ SRSRAN_API bool srsran_prach_tti_opportunity_config_tdd(uint32_t config_idx, uint32_t current_tti, uint32_t* prach_idx); +SRSRAN_API const prach_nr_config_t* srsran_prach_nr_get_cfg_fr1_paired(uint32_t config_idx); + +SRSRAN_API bool srsran_prach_nr_tti_opportunity_fr1_paired(uint32_t config_idx, uint32_t current_tti); + +SRSRAN_API uint32_t srsran_prach_nr_start_symbol_fr1_paired(uint32_t config_idx); + SRSRAN_API const prach_nr_config_t* srsran_prach_nr_get_cfg_fr1_unpaired(uint32_t config_idx); SRSRAN_API bool srsran_prach_nr_tti_opportunity_fr1_unpaired(uint32_t config_idx, uint32_t current_tti); -SRSRAN_API uint32_t srsran_prach_nr_start_symbol_fr1_unpaired(uint32_t config_idx); +SRSRAN_API uint32_t srsran_prach_nr_start_symbol(uint32_t config_idx, srsran_duplex_mode_t duplex_mode); SRSRAN_API uint32_t srsran_prach_f_ra_tdd(uint32_t config_idx, uint32_t tdd_ul_dl_config, diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index 6d8e4d82a..f24e5653d 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -274,6 +274,8 @@ bool make_phy_tdd_cfg(const tdd_ul_dl_cfg_common_s& tdd_ul_dl_cfg_common, srsran_duplex_config_nr_t* in_srsran_duplex_config_nr) { srsran_duplex_config_nr_t srsran_duplex_config_nr = {}; + srsran_duplex_config_nr.mode = SRSRAN_DUPLEX_MODE_TDD; + switch (tdd_ul_dl_cfg_common.pattern1.dl_ul_tx_periodicity) { case tdd_ul_dl_pattern_s::dl_ul_tx_periodicity_opts::ms1: srsran_duplex_config_nr.tdd.pattern1.period_ms = 1; diff --git a/lib/src/common/phy_cfg_nr_default.cc b/lib/src/common/phy_cfg_nr_default.cc index 487c92e73..809e30f48 100644 --- a/lib/src/common/phy_cfg_nr_default.cc +++ b/lib/src/common/phy_cfg_nr_default.cc @@ -457,6 +457,8 @@ phy_cfg_nr_default_t::phy_cfg_nr_default_t(const reference_cfg_t& reference_cfg) make_prach_default_lte(prach); break; } + + prach.tdd_config.configured = (duplex.mode == SRSRAN_DUPLEX_MODE_TDD); } } // namespace srsran diff --git a/lib/src/phy/phch/prach.c b/lib/src/phy/phch/prach.c index bfbd84e0d..6c6a954bf 100644 --- a/lib/src/phy/phch/prach.c +++ b/lib/src/phy/phch/prach.c @@ -15,6 +15,7 @@ #include #include "srsran/phy/common/phy_common.h" +#include "srsran/phy/common/phy_common_nr.h" #include "srsran/phy/phch/prach.h" #include "srsran/phy/utils/debug.h" #include "srsran/phy/utils/vector.h" @@ -118,16 +119,20 @@ bool srsran_prach_tti_opportunity(srsran_prach_t* p, uint32_t current_tti, int a return false; } - if (p->is_nr) { - return srsran_prach_nr_tti_opportunity_fr1_unpaired(p->config_idx, current_tti); - } - uint32_t config_idx = p->config_idx; - if (!p->tdd_config.configured) { - return srsran_prach_tti_opportunity_config_fdd(config_idx, current_tti, allowed_subframe); + if (p->tdd_config.configured) { + if (p->is_nr) { + return srsran_prach_nr_tti_opportunity_fr1_unpaired(p->config_idx, current_tti); + } else { + return srsran_prach_tti_opportunity_config_tdd( + config_idx, p->tdd_config.sf_config, current_tti, &p->current_prach_idx); + } } else { - return srsran_prach_tti_opportunity_config_tdd( - config_idx, p->tdd_config.sf_config, current_tti, &p->current_prach_idx); + if (p->is_nr) { + return srsran_prach_nr_tti_opportunity_fr1_paired(p->config_idx, current_tti); + } else { + return srsran_prach_tti_opportunity_config_fdd(config_idx, current_tti, allowed_subframe); + } } } @@ -281,6 +286,66 @@ void srsran_prach_sf_config(uint32_t config_idx, srsran_prach_sf_config_t* sf_co memcpy(sf_config, &prach_sf_config[config_idx % 16], sizeof(srsran_prach_sf_config_t)); } +const prach_nr_config_t* srsran_prach_nr_get_cfg_fr1_paired(uint32_t config_idx) +{ + if (config_idx < PRACH_NR_CFG_FR1_PAIRED_NOF_CFG) { + return &prach_nr_cfg_fr1_paired[config_idx]; + } + + ERROR("Invalid configuration index %d", config_idx); + return NULL; +} + +bool srsran_prach_nr_tti_opportunity_fr1_paired(uint32_t config_idx, uint32_t current_tti) +{ + uint32_t sfn = current_tti / SRSRAN_NOF_SF_X_FRAME; + uint32_t sf_idx = current_tti % SRSRAN_NOF_SF_X_FRAME; + + // Get configuration + const prach_nr_config_t* cfg = srsran_prach_nr_get_cfg_fr1_paired(config_idx); + if (cfg == NULL) { + return false; + } + + // Protect zero division + if (cfg->x == 0) { + ERROR("Invalid Zero value"); + return false; + } + + // Check for System Frame Number match + if (sfn % cfg->x != cfg->y) { + return false; + } + + // Protect subframe number vector access + if (cfg->nof_subframe_number > PRACH_NR_CFG_MAX_NOF_SF) { + ERROR("Invalid number of subframes (%d)", cfg->nof_subframe_number); + return false; + } + + // Check for subframe number match + for (uint32_t i = 0; i < cfg->nof_subframe_number; i++) { + if (cfg->subframe_number[i] == sf_idx) { + return true; + } + } + + // If reached here, no opportunity + return false; +} + +uint32_t srsran_prach_nr_start_symbol_fr1_paired(uint32_t config_idx) +{ + // Get configuration + const prach_nr_config_t* cfg = srsran_prach_nr_get_cfg_fr1_paired(config_idx); + if (cfg == NULL) { + return 0; + } + + return cfg->starting_symbol; +} + const prach_nr_config_t* srsran_prach_nr_get_cfg_fr1_unpaired(uint32_t config_idx) { if (config_idx < PRACH_NR_CFG_FR1_UNPAIRED_NOF_CFG) { @@ -330,12 +395,21 @@ bool srsran_prach_nr_tti_opportunity_fr1_unpaired(uint32_t config_idx, uint32_t return false; } -uint32_t srsran_prach_nr_start_symbol_fr1_unpaired(uint32_t config_idx) +uint32_t srsran_prach_nr_start_symbol(uint32_t config_idx, srsran_duplex_mode_t duplex_mode) { - // Get configuration - const prach_nr_config_t* cfg = srsran_prach_nr_get_cfg_fr1_unpaired(config_idx); - if (cfg == NULL) { - return false; + const prach_nr_config_t* cfg; + if (duplex_mode == SRSRAN_DUPLEX_MODE_TDD) { + // Get configuration + cfg = srsran_prach_nr_get_cfg_fr1_unpaired(config_idx); + if (cfg == NULL) { + return 0; + } + } else { + // Get configuration + cfg = srsran_prach_nr_get_cfg_fr1_paired(config_idx); + if (cfg == NULL) { + return 0; + } } return cfg->starting_symbol; diff --git a/lib/src/phy/phch/prach_tables.h b/lib/src/phy/phch/prach_tables.h index 902be2599..13009b857 100644 --- a/lib/src/phy/phch/prach_tables.h +++ b/lib/src/phy/phch/prach_tables.h @@ -446,10 +446,29 @@ static const prach_nr_config_t prach_nr_cfg_fr1_unpaired[PRACH_NR_CFG_FR1_UNPAIR {0, 1, 0, {8}, 1, 0}, {0, 1, 0, {7}, 1, 0}, {0, 1, 0, {6}, 1, 0}, {0, 1, 0, {5}, 1, 0}, {0, 1, 0, {4}, 1, 0}, {0, 1, 0, {3}, 1, 0}, - {0, 1, 0, {2}, 1, 0}, {0, 1, 0, {1, 6}, 1, 0}, - {0, 1, 0, {1, 6}, 1, 7}, {0, 1, 0, {4, 9}, 1, 0}, - {0, 1, 0, {3, 8}, 1, 0}, {0, 1, 0, {2, 7}, 1, 0}, - {0, 1, 0, {8, 9}, 1, 0}, {0, 1, 0, {4, 8, 9}, 1, 0}, - {0, 1, 0, {3, 4, 9}, 1, 0}, {0, 1, 0, {7, 8, 9}, 1, 0}, - {0, 1, 0, {3, 4, 8, 9}, 1, 0}, {0, 1, 0, {6, 7, 8, 9}, 1, 0}, - {0, 1, 0, {1, 4, 6, 9}, 1, 0}, {0, 1, 0, {1, 3, 5, 7, 9}, 1, 0}}; + {0, 1, 0, {2}, 1, 0}, {0, 1, 0, {1, 6}, 2, 0}, + {0, 1, 0, {1, 6}, 2, 7}, {0, 1, 0, {4, 9}, 2, 0}, + {0, 1, 0, {3, 8}, 2, 0}, {0, 1, 0, {2, 7}, 2, 0}, + {0, 1, 0, {8, 9}, 2, 0}, {0, 1, 0, {4, 8, 9}, 3, 0}, + {0, 1, 0, {3, 4, 9}, 3, 0}, {0, 1, 0, {7, 8, 9}, 3, 0}, + {0, 1, 0, {3, 4, 8, 9}, 4, 0}, {0, 1, 0, {6, 7, 8, 9}, 4, 0}, + {0, 1, 0, {1, 4, 6, 9}, 4, 0}, {0, 1, 0, {1, 3, 5, 7, 9}, 5, 0}}; + +#define PRACH_NR_CFG_FR1_PAIRED_NOF_CFG 28 + +// Table 6.3.3.2-2: Random access configurations for FR1 and paired spectrum. +static const prach_nr_config_t prach_nr_cfg_fr1_paired[PRACH_NR_CFG_FR1_PAIRED_NOF_CFG] = { + {0, 16, 1, {1}, 1, 0}, {0, 16, 1, {4}, 1, 0}, + {0, 16, 1, {7}, 1, 0}, {0, 16, 1, {9}, 1, 0}, + {0, 8, 1, {1}, 1, 0}, {0, 8, 1, {4}, 1, 0}, + {0, 8, 1, {7}, 1, 0}, {0, 8, 1, {9}, 1, 0}, + {0, 4, 1, {1}, 1, 0}, {0, 4, 1, {4}, 1, 0}, + {0, 4, 1, {7}, 1, 0}, {0, 4, 1, {9}, 1, 0}, + {0, 2, 1, {1}, 1, 0}, {0, 2, 1, {4}, 1, 0}, + {0, 2, 1, {7}, 1, 0}, {0, 2, 1, {9}, 1, 0}, + {0, 1, 0, {1}, 1, 0}, {0, 1, 0, {4}, 1, 0}, + {0, 1, 0, {7}, 1, 0}, {0, 1, 0, {1, 6}, 2, 0}, + {0, 1, 0, {2, 7}, 2, 0}, {0, 1, 0, {3, 8}, 2, 0}, + {0, 1, 0, {1, 4, 7}, 3, 0}, {0, 1, 0, {2, 5, 8}, 3, 0}, + {0, 1, 0, {3, 6, 9}, 3, 0}, {0, 1, 0, {0, 2, 4, 6, 8}, 5, 0}, + {0, 1, 0, {1, 3, 5, 7, 9}, 5, 0}, {0, 1, 0, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 10, 0}}; \ No newline at end of file diff --git a/lib/test/asn1/srsran_asn1_rrc_nr_test.cc b/lib/test/asn1/srsran_asn1_rrc_nr_test.cc index c02864b28..c3ac76c36 100644 --- a/lib/test/asn1/srsran_asn1_rrc_nr_test.cc +++ b/lib/test/asn1/srsran_asn1_rrc_nr_test.cc @@ -1221,43 +1221,142 @@ int test_cell_group_config_fdd() cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg_present = true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.set_setup(); - //TODO? // nzp-CSI-RS Resource cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list_present = true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list.resize(1); + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list.resize(5); auto& nzp_csi_res = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list[0]; - nzp_csi_res.nzp_csi_rs_res_id = 0; - nzp_csi_res.res_map.freq_domain_alloc.set_row2(); - nzp_csi_res.res_map.freq_domain_alloc.row2().from_number(0b100000000000); - nzp_csi_res.res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; - nzp_csi_res.res_map.first_ofdm_symbol_in_time_domain = 4; - nzp_csi_res.res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; - nzp_csi_res.res_map.density.set_one(); - nzp_csi_res.res_map.freq_band.start_rb = 0; - nzp_csi_res.res_map.freq_band.nrof_rbs = 52; - nzp_csi_res.pwr_ctrl_offset = 0; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup(); + // item 0 + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].nzp_csi_rs_res_id = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.set_row2(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.row2().from_number(0b100000000000); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.nrof_ports = + asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.cdm_type = + asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.density.set_one(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.start_rb = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].pwr_ctrl_offset = 0; // Skip pwr_ctrl_offset_ss_present - nzp_csi_res.scrambling_id = 500; - nzp_csi_res.periodicity_and_offset_present = true; - nzp_csi_res.periodicity_and_offset.set_slots80(); - nzp_csi_res.periodicity_and_offset.slots80() = 1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].scrambling_id = 500; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset.set_slots80(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset.slots80() = 1; // optional - nzp_csi_res.qcl_info_periodic_csi_rs_present = true; - nzp_csi_res.qcl_info_periodic_csi_rs = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].qcl_info_periodic_csi_rs = 0; + // item 1 + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].nzp_csi_rs_res_id = 1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.freq_domain_alloc.set_row1(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.freq_domain_alloc.row1().from_number(0b0001); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.nrof_ports = + asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.cdm_type = + asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.density.set_three(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.freq_band.start_rb = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].scrambling_id = 500; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].periodicity_and_offset_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].periodicity_and_offset.set_slots40(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].periodicity_and_offset.slots40() = 11; + // optional + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].qcl_info_periodic_csi_rs = 0; + // item 2 + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].nzp_csi_rs_res_id = 2; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.freq_domain_alloc.set_row1(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.freq_domain_alloc.row1().from_number(0b0001); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.nrof_ports = + asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.first_ofdm_symbol_in_time_domain = 8; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.cdm_type = + asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.density.set_three(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.freq_band.start_rb = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].scrambling_id = 500; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].periodicity_and_offset_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].periodicity_and_offset.set_slots40(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].periodicity_and_offset.slots40() = 11; + // optional + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].qcl_info_periodic_csi_rs = 0; + // item 3 + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].nzp_csi_rs_res_id = 3; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.freq_domain_alloc.set_row1(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.freq_domain_alloc.row1().from_number(0b0001); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.nrof_ports = + asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.cdm_type = + asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.density.set_three(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.freq_band.start_rb = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].scrambling_id = 500; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].periodicity_and_offset_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].periodicity_and_offset.set_slots40(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].periodicity_and_offset.slots40() = 12; + // optional + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].qcl_info_periodic_csi_rs = 0; + // item 4 + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].nzp_csi_rs_res_id = 4; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.freq_domain_alloc.set_row1(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.freq_domain_alloc.row1().from_number(0b0001); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.nrof_ports = + asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.first_ofdm_symbol_in_time_domain = 8; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.cdm_type = + asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.density.set_three(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.freq_band.start_rb = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].scrambling_id = 500; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].periodicity_and_offset_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].periodicity_and_offset.set_slots40(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].periodicity_and_offset.slots40() = 12; + // optional + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].qcl_info_periodic_csi_rs = 0; - //TODO? // nzp-CSI-RS ResourceSet cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list_present = true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list.resize(1); + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list.resize(2); auto& nzp_csi_res_set = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list[0]; - nzp_csi_res_set.nzp_csi_res_set_id = 1; - nzp_csi_res_set.nzp_csi_rs_res.resize(1); - nzp_csi_res_set.nzp_csi_rs_res[0] = 1; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup(); + // item 0 + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[0].nzp_csi_res_set_id = 0; + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[0].nzp_csi_rs_res.resize(1); + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[0].nzp_csi_rs_res[0] = 0; + // item 1 + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_res_set_id = 1; + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_rs_res.resize(4); + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_rs_res[0] = 1; + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_rs_res[1] = 2; + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_rs_res[2] = 3; + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_rs_res[3] = 4; // Skip TRS info + // CSI IM config + // TODO: add csi im config + + // CSI resource config + // TODO: add csi resource config + // CSI report config cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list_present = true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list.resize(1); @@ -1387,6 +1486,10 @@ int test_cell_group_config_fdd() cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.dummy = time_align_timer_opts::ms500; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul.freq_band_list + .push_back(5); + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul.absolute_freq_point_a = + 166364; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul .scs_specific_carrier_list.resize(1); auto& ul_carrier = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index aa8bec2b8..66eee24c4 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -898,7 +898,7 @@ static int parse_nr_cell_list(all_args_t* args, rrc_nr_cfg_t* rrc_cfg_nr, rrc_cf { for (uint32_t n = 0; n < (uint32_t)root.getLength(); ++n) { rrc_cell_cfg_nr_t cell_cfg = {}; - auto& cellroot = root[n]; + auto& cellroot = root[n]; parse_opt_field(cell_cfg.phy_cell.rf_port, cellroot, "rf_port"); HANDLEPARSERCODE(parse_required_field(cell_cfg.phy_cell.carrier.pci, cellroot, "pci")); @@ -908,6 +908,7 @@ static int parse_nr_cell_list(all_args_t* args, rrc_nr_cfg_t* rrc_cfg_nr, rrc_cf cell_cfg.phy_cell.carrier.pci = cell_cfg.phy_cell.carrier.pci % SRSRAN_NOF_NID_NR; HANDLEPARSERCODE(parse_required_field(cell_cfg.dl_arfcn, cellroot, "dl_arfcn")); + parse_opt_field(cell_cfg.ul_arfcn, cellroot, "ul_arfcn"); // frequencies get derived from ARFCN // TODO: Add further cell-specific parameters @@ -1370,6 +1371,12 @@ int set_derived_args_nr(all_args_t* args_, rrc_nr_cfg_t* rrc_cfg_, phy_cfg_t* ph cfg.phy_cell.ul_freq_hz = band_helper.nr_arfcn_to_freq(cfg.ul_arfcn); } + // band + cfg.band = band_helper.get_band_from_dl_arfcn(cfg.dl_arfcn); + + // duplex mode + cfg.duplex_mode = band_helper.get_duplex_mode(cfg.band); + phy_cfg_->phy_cell_cfg_nr.push_back(cfg.phy_cell); } diff --git a/srsenb/src/phy/nr/worker_pool.cc b/srsenb/src/phy/nr/worker_pool.cc index b23eed3e2..e79d9aef2 100644 --- a/srsenb/src/phy/nr/worker_pool.cc +++ b/srsenb/src/phy/nr/worker_pool.cc @@ -132,6 +132,7 @@ int worker_pool::set_common_cfg(const phy_interface_rrc_nr::common_cfg_t& common } prach_cfg.freq_offset -= lte_nr_prach_offset; prach_cfg.is_nr = true; + prach_cfg.tdd_config.configured = (common_cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD); // Set the PRACH configuration prach.init(0, cell, prach_cfg, &prach_stack_adaptor, logger, 0, nof_prach_workers); diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index d1de70c57..9ef11696d 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -14,6 +14,7 @@ #include "srsenb/hdr/common/common_enb.h" #include "srsenb/test/mac/nr/sched_nr_cfg_generators.h" #include "srsran/asn1/rrc_nr_utils.h" +#include "srsran/common/band_helper.h" #include "srsran/common/common_nr.h" #include "srsran/common/phy_cfg_nr_default.h" #include "srsran/common/standard_streams.h" @@ -540,6 +541,8 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group { auto& pscell_cfg = parent->cfg.cell_list.at(UE_PSCELL_CC_IDX); + srsran::srsran_band_helper band_helper; + // RLC for DRB1 (with fixed LCID) cell_group_cfg_pack.rlc_bearer_to_add_mod_list_present = true; cell_group_cfg_pack.rlc_bearer_to_add_mod_list.resize(1); @@ -698,8 +701,8 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group sr_res1.sched_request_res_id = 1; sr_res1.sched_request_id = 0; sr_res1.periodicity_and_offset_present = true; - sr_res1.periodicity_and_offset.set_sl40() = 8; - sr_res1.res_present = true; + sr_res1.res_present = true; + sr_res1.res = 2; // PUCCH resource for SR // DL data ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack_present = true; @@ -812,37 +815,6 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg_present = true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.set_setup(); - // nzp-CSI-RS Resource - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list_present = true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list.resize(1); - auto& nzp_csi_res = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list[0]; - nzp_csi_res.nzp_csi_rs_res_id = 0; - nzp_csi_res.res_map.freq_domain_alloc.set_row2(); - nzp_csi_res.res_map.freq_domain_alloc.row2().from_number(0b100000000000); - nzp_csi_res.res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; - nzp_csi_res.res_map.first_ofdm_symbol_in_time_domain = 4; - nzp_csi_res.res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; - nzp_csi_res.res_map.density.set_one(); - nzp_csi_res.res_map.freq_band.start_rb = 0; - nzp_csi_res.res_map.freq_band.nrof_rbs = 52; - nzp_csi_res.pwr_ctrl_offset = 0; - // Skip pwr_ctrl_offset_ss_present - nzp_csi_res.periodicity_and_offset_present = true; - nzp_csi_res.periodicity_and_offset.set_slots80(); - // optional - nzp_csi_res.qcl_info_periodic_csi_rs_present = true; - nzp_csi_res.qcl_info_periodic_csi_rs = 0; - - // nzp-CSI-RS ResourceSet - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list_present = - true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list.resize(1); - auto& nzp_csi_res_set = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list[0]; - nzp_csi_res_set.nzp_csi_rs_res.resize(1); - // Skip TRS info - // CSI report config cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list_present = true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list.resize(1); @@ -877,7 +849,8 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.new_ue_id = rnti; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.t304 = recfg_with_sync_s::t304_opts::ms1000; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ss_pbch_block_pwr = 0; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.n_timing_advance_offset = asn1::rrc_nr::serving_cell_cfg_common_s::n_timing_advance_offset_opts::n0; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dmrs_type_a_position = @@ -885,12 +858,15 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.pci = pscell_cfg.phy_cell.carrier.pci; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing_present = true; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing = - subcarrier_spacing_opts::khz30; // DL config cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl.freq_band_list + .push_back(parent->cfg.cell_list[0].band); + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl.absolute_freq_point_a = + band_helper.get_abs_freq_point_a_arfcn(parent->cfg.cell_list[0].phy_cell.carrier.nof_prb, + parent->cfg.cell_list[0].dl_arfcn); cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl .absolute_freq_ssb_present = true; @@ -972,6 +948,12 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.dummy = time_align_timer_opts::ms500; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul_present = true; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul.freq_band_list + .push_back(parent->cfg.cell_list[0].band); + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul.absolute_freq_point_a = + band_helper.get_abs_freq_point_a_arfcn(parent->cfg.cell_list[0].phy_cell.carrier.nof_prb, + parent->cfg.cell_list[0].ul_arfcn); + ; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul .scs_specific_carrier_list.resize(1); auto& ul_carrier = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.freq_info_ul @@ -1056,35 +1038,166 @@ int rrc_nr::ue::pack_secondary_cell_group_config_fdd(asn1::dyn_octstring& packed auto& cell_group_cfg_pack = cell_group_cfg; pack_secondary_cell_group_config_common(cell_group_cfg); + uint32_t absolute_freq_ssb; + + if (parent->cfg.cell_list[0].band == 3) { // band n3 + absolute_freq_ssb = 367930; + } else if (parent->cfg.cell_list[0].band == 5) { // band n5 + absolute_freq_ssb = 176210; + } else if (parent->cfg.cell_list[0].band == 7) { // band n7 + absolute_freq_ssb = 529470; + } else { + parent->logger.error("Unsupported dl_arfcn."); + return SRSRAN_ERROR; + } + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.first_active_dl_bwp_id = 0; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg_present = true; // UL config dedicated auto& ul_config = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.ul_cfg; // SR resources - auto& sr_res1 = ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list[0]; - sr_res1.periodicity_and_offset.sl40() = 4; - sr_res1.res_present = true; - sr_res1.res = 16; // PUCCH resource for SR + auto& sr_res1 = ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list[0]; + sr_res1.periodicity_and_offset.set_sl40() = 8; + sr_res1.res = 2; // PUCCH resource for SR // DL data - ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack_present = true; ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack.resize(1); ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack[0] = 4; // nzp-CSI-RS Resource - auto& nzp_csi_res = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list[0]; - nzp_csi_res.scrambling_id = 500; - nzp_csi_res.periodicity_and_offset_present = true; - nzp_csi_res.periodicity_and_offset.set_slots80(); - nzp_csi_res.periodicity_and_offset.slots80() = 1; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list_present = true; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list.resize(5); + auto& nzp_csi_res = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup(); + // item 0 + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].nzp_csi_rs_res_id = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.set_row2(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.freq_domain_alloc.row2().from_number(0b100000000000); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.nrof_ports = + asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.cdm_type = + asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.density.set_one(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.start_rb = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].scrambling_id = parent->cfg.cell_list[0].phy_cell.cell_id; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset.set_slots80(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].periodicity_and_offset.slots80() = 1; + // optional + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[0].qcl_info_periodic_csi_rs = 0; + // item 1 + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].nzp_csi_rs_res_id = 1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.freq_domain_alloc.set_row1(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.freq_domain_alloc.row1().from_number(0b0001); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.nrof_ports = + asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.cdm_type = + asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.density.set_three(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.freq_band.start_rb = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].scrambling_id = parent->cfg.cell_list[0].phy_cell.cell_id; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].periodicity_and_offset_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].periodicity_and_offset.set_slots40(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].periodicity_and_offset.slots40() = 11; + // optional + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[1].qcl_info_periodic_csi_rs = 0; + // item 2 + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].nzp_csi_rs_res_id = 2; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.freq_domain_alloc.set_row1(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.freq_domain_alloc.row1().from_number(0b0001); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.nrof_ports = + asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.first_ofdm_symbol_in_time_domain = 8; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.cdm_type = + asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.density.set_three(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.freq_band.start_rb = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].scrambling_id = parent->cfg.cell_list[0].phy_cell.cell_id; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].periodicity_and_offset_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].periodicity_and_offset.set_slots40(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].periodicity_and_offset.slots40() = 11; + // optional + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[2].qcl_info_periodic_csi_rs = 0; + // item 3 + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].nzp_csi_rs_res_id = 3; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.freq_domain_alloc.set_row1(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.freq_domain_alloc.row1().from_number(0b0001); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.nrof_ports = + asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.cdm_type = + asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.density.set_three(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.freq_band.start_rb = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].scrambling_id = parent->cfg.cell_list[0].phy_cell.cell_id; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].periodicity_and_offset_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].periodicity_and_offset.set_slots40(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].periodicity_and_offset.slots40() = 12; + // optional + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[3].qcl_info_periodic_csi_rs = 0; + // item 4 + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].nzp_csi_rs_res_id = 4; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.freq_domain_alloc.set_row1(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.freq_domain_alloc.row1().from_number(0b0001); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.nrof_ports = + asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.first_ofdm_symbol_in_time_domain = 8; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.cdm_type = + asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.density.set_three(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.freq_band.start_rb = 0; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].res_map.freq_band.nrof_rbs = 52; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].scrambling_id = parent->cfg.cell_list[0].phy_cell.cell_id; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].periodicity_and_offset_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].periodicity_and_offset.set_slots40(); + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].periodicity_and_offset.slots40() = 12; + // optional + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].qcl_info_periodic_csi_rs_present = true; + nzp_csi_res.nzp_csi_rs_res_to_add_mod_list[4].qcl_info_periodic_csi_rs = 0; // nzp-CSI-RS ResourceSet - auto& nzp_csi_res_set = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list[0]; - nzp_csi_res_set.nzp_csi_res_set_id = 1; - nzp_csi_res_set.nzp_csi_rs_res[0] = 1; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list_present = + true; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list.resize(2); + auto& nzp_csi_res_set = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup(); + // item 0 + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[0].nzp_csi_res_set_id = 0; + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[0].nzp_csi_rs_res.resize(1); + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[0].nzp_csi_rs_res[0] = 0; + // item 1 + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_res_set_id = 1; + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_rs_res.resize(4); + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_rs_res[0] = 1; + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_rs_res[1] = 2; + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_rs_res[2] = 3; + nzp_csi_res_set.nzp_csi_rs_res_set_to_add_mod_list[1].nzp_csi_rs_res[3] = 4; + // Skip TRS info + + // CSI IM config + // TODO: add csi im config + + // CSI resource config + // TODO: add csi resource config // CSI report config auto& csi_report = @@ -1092,18 +1205,13 @@ int rrc_nr::ue::pack_secondary_cell_group_config_fdd(asn1::dyn_octstring& packed csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 5; // Reconfig with Sync - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common_present = true; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ss_pbch_block_pwr = -36; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing = + subcarrier_spacing_opts::khz15; // DL config cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl.absolute_freq_ssb = - 176210; // TODO: calculate from actual DL ARFCN - - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl.freq_band_list - .push_back(5); - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl.absolute_freq_point_a = - 175364; // TODO: calculate from actual DL ARFCN + absolute_freq_ssb; // TODO: calculate from actual DL ARFCN // RACH config cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ul_cfg_common.init_ul_bwp.rach_cfg_common_present = @@ -1145,12 +1253,10 @@ int rrc_nr::ue::pack_secondary_cell_group_config_tdd(asn1::dyn_octstring& packed // SR resources auto& sr_res1 = ul_config.init_ul_bwp.pucch_cfg.setup().sched_request_res_to_add_mod_list[0]; // SR resources - sr_res1.periodicity_and_offset.sl40() = 8; - sr_res1.res_present = true; - sr_res1.res = 2; // PUCCH resource for SR + sr_res1.periodicity_and_offset.set_sl40() = 8; + sr_res1.res = 2; // PUCCH resource for SR // DL data - ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack_present = true; ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack.resize(6); ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack[0] = 6; ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack[1] = 5; @@ -1160,18 +1266,37 @@ int rrc_nr::ue::pack_secondary_cell_group_config_tdd(asn1::dyn_octstring& packed ul_config.init_ul_bwp.pucch_cfg.setup().dl_data_to_ul_ack[5] = 4; // nzp-CSI-RS Resource + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list_present = true; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list.resize(1); auto& nzp_csi_res = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_to_add_mod_list[0]; - nzp_csi_res.scrambling_id = 0; - nzp_csi_res.periodicity_and_offset_present = true; - nzp_csi_res.periodicity_and_offset.set_slots80(); - nzp_csi_res.periodicity_and_offset.slots80() = 0; + nzp_csi_res.nzp_csi_rs_res_id = 0; + nzp_csi_res.res_map.freq_domain_alloc.set_row2(); + nzp_csi_res.res_map.freq_domain_alloc.row2().from_number(0b100000000000); + nzp_csi_res.res_map.nrof_ports = asn1::rrc_nr::csi_rs_res_map_s::nrof_ports_opts::p1; + nzp_csi_res.res_map.first_ofdm_symbol_in_time_domain = 4; + nzp_csi_res.res_map.cdm_type = asn1::rrc_nr::csi_rs_res_map_s::cdm_type_opts::no_cdm; + nzp_csi_res.res_map.density.set_one(); + nzp_csi_res.res_map.freq_band.start_rb = 0; + nzp_csi_res.res_map.freq_band.nrof_rbs = 52; + nzp_csi_res.pwr_ctrl_offset = 0; + // Skip pwr_ctrl_offset_ss_present + nzp_csi_res.scrambling_id = 0; + nzp_csi_res.periodicity_and_offset_present = true; + nzp_csi_res.periodicity_and_offset.set_slots80() = 0; + // optional + nzp_csi_res.qcl_info_periodic_csi_rs_present = true; + nzp_csi_res.qcl_info_periodic_csi_rs = 0; // nzp-CSI-RS ResourceSet + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list_present = + true; + cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list.resize(1); auto& nzp_csi_res_set = cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().nzp_csi_rs_res_set_to_add_mod_list[0]; nzp_csi_res_set.nzp_csi_res_set_id = 0; - nzp_csi_res_set.nzp_csi_rs_res[0] = 0; + nzp_csi_res_set.nzp_csi_rs_res.resize(1); + nzp_csi_res_set.nzp_csi_rs_res[0] = 0; // Skip TRS info // CSI report config @@ -1181,20 +1306,14 @@ int rrc_nr::ue::pack_secondary_cell_group_config_tdd(asn1::dyn_octstring& packed // Reconfig with Sync cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.smtc.release(); - - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common_present = true; - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ss_pbch_block_pwr = 0; + cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing = + subcarrier_spacing_opts::khz30; // DL config cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common_present = true; cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl.absolute_freq_ssb = 634176; // TODO: calculate from actual DL ARFCN - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl.freq_band_list - .push_back(78); - cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.freq_info_dl.absolute_freq_point_a = - 633928; // TODO: calculate from actual DL ARFCN - auto& pdcch_cfg_common = cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.dl_cfg_common.init_dl_bwp.pdcch_cfg_common; pdcch_cfg_common.set_setup(); @@ -1245,9 +1364,17 @@ int rrc_nr::ue::pack_rrc_reconfiguraiton(asn1::dyn_octstring& packed_rrc_reconfi // add secondary cell group config recfg_ies.secondary_cell_group_present = true; - if (pack_secondary_cell_group_config_tdd(recfg_ies.secondary_cell_group) == SRSRAN_ERROR) { - parent->logger.error("Failed to pack TDD RRC Reconfiguration"); - return SRSRAN_ERROR; + + if (parent->cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_FDD) { + if (pack_secondary_cell_group_config_fdd(recfg_ies.secondary_cell_group) == SRSRAN_ERROR) { + parent->logger.error("Failed to pack TDD RRC Reconfiguration"); + return SRSRAN_ERROR; + } + } else { + if (pack_secondary_cell_group_config_tdd(recfg_ies.secondary_cell_group) == SRSRAN_ERROR) { + parent->logger.error("Failed to pack TDD RRC Reconfiguration"); + return SRSRAN_ERROR; + } } // now pack .. diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index b7ebe69e4..a6806f45c 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -45,6 +45,7 @@ typedef struct { uint32_t release; uint32_t feature_group; std::array supported_bands; + std::vector supported_bands_nr; uint32_t nof_supported_bands; bool support_ca; int mbms_service_id; diff --git a/srsue/hdr/stack/rrc/rrc_nr.h b/srsue/hdr/stack/rrc/rrc_nr.h index 642bdbf4f..11774dcd7 100644 --- a/srsue/hdr/stack/rrc/rrc_nr.h +++ b/srsue/hdr/stack/rrc/rrc_nr.h @@ -13,6 +13,7 @@ #ifndef SRSUE_RRC_NR_H #define SRSUE_RRC_NR_H +#include "srsran/adt/circular_map.h" #include "srsran/asn1/rrc_nr.h" #include "srsran/asn1/rrc_nr_utils.h" #include "srsran/common/block_queue.h" @@ -185,10 +186,9 @@ private: std::map drb_eps_bearer_id; // Map of drb id to eps_bearer_id // temporary maps for building the pucch nr resources - std::map res_list; - std::map res_list_present; - std::map csi_rs_zp_res; - std::map csi_rs_nzp_res; + srsran::static_circular_map pucch_res_list; + std::map csi_rs_zp_res; + std::map csi_rs_nzp_res; bool apply_cell_group_cfg(const asn1::rrc_nr::cell_group_cfg_s& cell_group_cfg); bool apply_radio_bearer_cfg(const asn1::rrc_nr::radio_bearer_cfg_s& radio_bearer_cfg); diff --git a/srsue/src/phy/nr/sf_worker.cc b/srsue/src/phy/nr/sf_worker.cc index a83bf5f3a..c64be5f0d 100644 --- a/srsue/src/phy/nr/sf_worker.cc +++ b/srsue/src/phy/nr/sf_worker.cc @@ -90,7 +90,7 @@ void sf_worker::work_imp() // Notify MAC about PRACH transmission phy_state.stack->prach_sent(TTI_TX(tti_rx), - srsran_prach_nr_start_symbol_fr1_unpaired(phy_state.cfg.prach.config_idx), + srsran_prach_nr_start_symbol(phy_state.cfg.prach.config_idx, phy_state.cfg.duplex.mode), SRSRAN_SLOT_NR_MOD(phy_state.cfg.carrier.scs, TTI_TX(tti_rx)), 0, 0); diff --git a/srsue/src/phy/nr/worker_pool.cc b/srsue/src/phy/nr/worker_pool.cc index 2c8b62493..d65ef9941 100644 --- a/srsue/src/phy/nr/worker_pool.cc +++ b/srsue/src/phy/nr/worker_pool.cc @@ -172,6 +172,7 @@ bool worker_pool::set_config(const srsran::phy_cfg_nr_t& cfg) return false; } prach_cfg.freq_offset -= lte_nr_prach_offset; + prach_cfg.tdd_config.configured = (cfg.duplex.mode == SRSRAN_DUPLEX_MODE_TDD); // Set the PRACH configuration if (not prach_buffer->set_cell(cell, prach_cfg)) { diff --git a/srsue/src/phy/phy.cc b/srsue/src/phy/phy.cc index 4e917a0e8..adc3b889c 100644 --- a/srsue/src/phy/phy.cc +++ b/srsue/src/phy/phy.cc @@ -664,9 +664,9 @@ bool phy::set_config(const srsran::phy_cfg_nr_t& cfg) // tune radio for (uint32_t i = 0; i < common.args->nof_nr_carriers; i++) { - logger_phy.info("Tuning Rx channel %d to %.2f GHz", i + common.args->nof_lte_carriers, dl_freq_hz / 1e6); + logger_phy.info("Tuning Rx channel %d to %.2f MHz", i + common.args->nof_lte_carriers, dl_freq_hz / 1e6); radio->set_rx_freq(i + common.args->nof_lte_carriers, dl_freq_hz); - logger_phy.info("Tuning Tx channel %d to %.2f GHz", i + common.args->nof_lte_carriers, ul_freq_hz / 1e6); + logger_phy.info("Tuning Tx channel %d to %.2f MHz", i + common.args->nof_lte_carriers, ul_freq_hz / 1e6); radio->set_tx_freq(i + common.args->nof_lte_carriers, ul_freq_hz); } diff --git a/srsue/src/stack/rrc/rrc.cc b/srsue/src/stack/rrc/rrc.cc index 0ce979318..6a6e3b6c6 100644 --- a/srsue/src/stack/rrc/rrc.cc +++ b/srsue/src/stack/rrc/rrc.cc @@ -2110,10 +2110,12 @@ void rrc::handle_ue_capability_enquiry(const ue_cap_enquiry_s& enquiry) irat_params_nr_r15.en_dc_r15_present = true; irat_params_nr_r15.supported_band_list_en_dc_r15_present = true; - supported_band_nr_r15_s supported_band_nr_r15; - supported_band_nr_r15.band_nr_r15 = 78; + uint32_t nof_supported_nr_bands = args.supported_bands_nr.size(); + irat_params_nr_r15.supported_band_list_en_dc_r15.resize(nof_supported_nr_bands); + for (uint32_t k = 0; k < nof_supported_nr_bands; k++) { + irat_params_nr_r15.supported_band_list_en_dc_r15[k].band_nr_r15 = args.supported_bands_nr[k]; + } - irat_params_nr_r15.supported_band_list_en_dc_r15.push_back(supported_band_nr_r15); ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext.irat_params_nr_r15_present = true; ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext.irat_params_nr_r15 = irat_params_nr_r15; ue_eutra_cap_v1450_ies->non_crit_ext.non_crit_ext.non_crit_ext_present = true; diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index cc7d8a14b..d33b4f9d1 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -703,8 +703,8 @@ bool rrc_nr::apply_res_csi_report_cfg(const asn1::rrc_nr::csi_report_cfg_s& csi_ uint32_t res_id = csi_report_cfg.report_cfg_type.periodic() .pucch_csi_res_list[0] .pucch_res; // TODO: support and check more items - if (res_list_present[res_id] == true) { - phy_cfg.csi.reports[report_cfg_id].periodic.resource = res_list[res_id]; + if (pucch_res_list.contains(res_id)) { + phy_cfg.csi.reports[report_cfg_id].periodic.resource = pucch_res_list[res_id]; } else { logger.error("Resources set not present for assigning pucch sets (res_id %d)", res_id); return false; @@ -753,7 +753,7 @@ bool rrc_nr::apply_csi_meas_cfg(const asn1::rrc_nr::csi_meas_cfg_s& csi_meas_cfg uint8_t res = csi_meas_cfg.nzp_csi_rs_res_set_to_add_mod_list[i].nzp_csi_rs_res[j]; // use temporally stored values to assign if (csi_rs_nzp_res.find(res) == csi_rs_nzp_res.end()) { - logger.warning("Can not find p_zp_csi_rs_res in temporally stored csi_rs_zp_res"); + logger.warning("Can not find nzp_csi_rs_res in temporally stored csi_rs_nzp_res"); return false; } phy_cfg.pdsch.nzp_csi_rs_sets[set_id].data[j] = csi_rs_nzp_res[res]; @@ -1002,9 +1002,8 @@ bool rrc_nr::apply_sp_cell_ded_ul_pucch(const asn1::rrc_nr::pucch_cfg_s& pucch_c if (pucch_cfg.res_to_add_mod_list_present) { for (uint32_t i = 0; i < pucch_cfg.res_to_add_mod_list.size(); i++) { uint32_t res_id = pucch_cfg.res_to_add_mod_list[i].pucch_res_id; - if (make_phy_res_config(pucch_cfg.res_to_add_mod_list[i], format_2_max_code_rate, &res_list[res_id]) == true) { - res_list_present[res_id] = true; - } else { + pucch_res_list.insert(res_id, {}); + if (!make_phy_res_config(pucch_cfg.res_to_add_mod_list[i], format_2_max_code_rate, &pucch_res_list[res_id])) { logger.warning("Warning while building pucch_nr_resource structure"); return false; } @@ -1022,8 +1021,8 @@ bool rrc_nr::apply_sp_cell_ded_ul_pucch(const asn1::rrc_nr::pucch_cfg_s& pucch_c phy_cfg.pucch.sets[set_id].nof_resources = pucch_cfg.res_set_to_add_mod_list[i].res_list.size(); for (uint32_t j = 0; j < pucch_cfg.res_set_to_add_mod_list[i].res_list.size(); j++) { uint32_t res_id = pucch_cfg.res_set_to_add_mod_list[i].res_list[j]; - if (res_list_present[res_id] == true) { - phy_cfg.pucch.sets[set_id].resources[j] = res_list[res_id]; + if (pucch_res_list.contains(res_id)) { + phy_cfg.pucch.sets[set_id].resources[j] = pucch_res_list[res_id]; } else { logger.error( "Resources set not present for assign pucch sets (res_id %d, setid %d, j %d)", res_id, set_id, j); @@ -1034,24 +1033,26 @@ bool rrc_nr::apply_sp_cell_ded_ul_pucch(const asn1::rrc_nr::pucch_cfg_s& pucch_c if (pucch_cfg.sched_request_res_to_add_mod_list_present) { for (uint32_t i = 0; i < pucch_cfg.sched_request_res_to_add_mod_list.size(); i++) { - uint32_t res_id = pucch_cfg.sched_request_res_to_add_mod_list[i].sched_request_res_id; + uint32_t sr_res_id = pucch_cfg.sched_request_res_to_add_mod_list[i].sched_request_res_id; srsran_pucch_nr_sr_resource_t srsran_pucch_nr_sr_resource; if (make_phy_sr_resource(pucch_cfg.sched_request_res_to_add_mod_list[i], &srsran_pucch_nr_sr_resource) == true) { // TODO: fix that if indexing is solved - phy_cfg.pucch.sr_resources[res_id] = srsran_pucch_nr_sr_resource; + phy_cfg.pucch.sr_resources[sr_res_id] = srsran_pucch_nr_sr_resource; // Set PUCCH resource if (pucch_cfg.sched_request_res_to_add_mod_list[i].res_present) { uint32_t pucch_res_id = pucch_cfg.sched_request_res_to_add_mod_list[i].res; - if (res_list_present[res_id]) { - phy_cfg.pucch.sr_resources[res_id].resource = res_list[pucch_res_id]; + if (pucch_res_list.contains(pucch_res_id)) { + phy_cfg.pucch.sr_resources[sr_res_id].resource = pucch_res_list[pucch_res_id]; } else { - logger.warning("Warning SR's PUCCH resource is invalid (%d)", pucch_res_id); - phy_cfg.pucch.sr_resources[res_id].configured = false; + logger.warning("Warning SR (%d) PUCCH resource is invalid (%d)", sr_res_id, pucch_res_id); + phy_cfg.pucch.sr_resources[sr_res_id].configured = false; + return false; } } else { logger.warning("Warning SR resource is present but no PUCCH resource is assigned to it"); - phy_cfg.pucch.sr_resources[res_id].configured = false; + phy_cfg.pucch.sr_resources[sr_res_id].configured = false; + return false; } } else { @@ -1193,6 +1194,7 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) } if (recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common_present) { + logger.info("TDD UL DL config present, using TDD"); srsran_duplex_config_nr_t duplex; if (make_phy_tdd_cfg(recfg_with_sync.sp_cell_cfg_common.tdd_ul_dl_cfg_common, &duplex) == true) { phy_cfg.duplex = duplex; @@ -1201,8 +1203,7 @@ bool rrc_nr::apply_sp_cell_cfg(const sp_cell_cfg_s& sp_cell_cfg) return false; } } else { - logger.warning("TDD UL DL config not present"); - return false; + logger.info("TDD UL DL config not present, using FDD"); } } } else { diff --git a/srsue/src/ue.cc b/srsue/src/ue.cc index d2ef6e5d0..6f2056daf 100644 --- a/srsue/src/ue.cc +++ b/srsue/src/ue.cc @@ -219,6 +219,7 @@ int ue::parse_args(const all_args_t& args_) if (not args.stack.rrc_nr.supported_bands_nr_str.empty()) { // Populates supported bands srsran::string_parse_list(args.stack.rrc_nr.supported_bands_nr_str, ',', args.stack.rrc_nr.supported_bands_nr); + args.stack.rrc.supported_bands_nr = args.stack.rrc_nr.supported_bands_nr; } else { logger.error("Error: rat.nr.bands list is empty"); srsran::console("Error: rat.nr.bands list is empty\n"); diff --git a/test/phy/CMakeLists.txt b/test/phy/CMakeLists.txt index 3edbc0afc..d2141bada 100644 --- a/test/phy/CMakeLists.txt +++ b/test/phy/CMakeLists.txt @@ -94,8 +94,19 @@ if (RF_FOUND AND ENABLE_SRSUE AND ENABLE_SRSENB) ) # Test PRACH transmission and detection - add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_prach nr_phy_test - --reference=carrier=${NR_PHY_TEST_BW} + add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_prach_fdd nr_phy_test + --reference=carrier=${NR_PHY_TEST_BW},duplex=FDD + --duration=1000 # 1000 slots + --gnb.stack.pdsch.slots=none # No PDSCH + --gnb.stack.pusch.slots=none # No PUSCH + --gnb.phy.nof_threads=${NR_PHY_TEST_GNB_NOF_THREADS} + --ue.stack.prach.period=30 # Transmit PRACH every 30 radio frames + --ue.stack.prach.preamble=10 # Use preamble 10 + --ue.phy.nof_threads=${NR_PHY_TEST_UE_NOF_THREADS} + ) + + add_nr_test(nr_phy_test_${NR_PHY_TEST_BW}_prach_tdd nr_phy_test + --reference=carrier=${NR_PHY_TEST_BW},duplex=6D+4U --duration=1000 # 1000 slots --gnb.stack.pdsch.slots=none # No PDSCH --gnb.stack.pusch.slots=none # No PUSCH diff --git a/test/phy/test_bench.h b/test/phy/test_bench.h index e12402787..b35e0b264 100644 --- a/test/phy/test_bench.h +++ b/test/phy/test_bench.h @@ -82,6 +82,7 @@ public: common_cfg.carrier = args.phy_cfg.carrier; common_cfg.pdcch = args.phy_cfg.pdcch; common_cfg.prach = args.phy_cfg.prach; + common_cfg.duplex_mode = args.phy_cfg.duplex.mode; if (gnb_phy.set_common_cfg(common_cfg) < SRSRAN_SUCCESS) { return; From c09f09b7be91e1f2d19371fe0fbb522f20e60d7c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 22 Sep 2021 16:18:03 +0200 Subject: [PATCH 73/83] Move rrc_common from srsue to lib --- .../stack => lib/include/srsran}/rrc/rrc_common.h | 12 ++---------- lib/src/common/CMakeLists.txt | 1 + .../src/stack/rrc => lib/src/common}/rrc_common.cc | 6 +++--- srsue/hdr/stack/rrc/rrc.h | 2 +- srsue/hdr/stack/rrc/rrc_metrics.h | 9 ++++++++- srsue/src/stack/rrc/CMakeLists.txt | 2 +- srsue/src/stack/rrc/rrc_rlf_report.cc | 10 +++++----- 7 files changed, 21 insertions(+), 21 deletions(-) rename {srsue/hdr/stack => lib/include/srsran}/rrc/rrc_common.h (67%) rename {srsue/src/stack/rrc => lib/src/common}/rrc_common.cc (91%) diff --git a/srsue/hdr/stack/rrc/rrc_common.h b/lib/include/srsran/rrc/rrc_common.h similarity index 67% rename from srsue/hdr/stack/rrc/rrc_common.h rename to lib/include/srsran/rrc/rrc_common.h index db11de7bf..c70aa4b93 100644 --- a/srsue/hdr/stack/rrc/rrc_common.h +++ b/lib/include/srsran/rrc/rrc_common.h @@ -13,23 +13,15 @@ #ifndef SRSUE_RRC_COMMON_H #define SRSUE_RRC_COMMON_H -namespace srsue { +namespace srsran { #include -// RRC states (3GPP 36.331 v10.0.0) -typedef enum { - RRC_STATE_IDLE = 0, - RRC_STATE_CONNECTED, - RRC_STATE_N_ITEMS, -} rrc_state_t; -static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", "CONNECTED"}; - enum quant_s { quant_rsrp, quant_rsrq }; uint8_t rrc_value_to_range(quant_s quant, const float value); float rrc_range_to_value(quant_s quant, const uint8_t range); -} // namespace srsue +} // namespace srsran #endif // SRSUE_RRC_COMMON_H diff --git a/lib/src/common/CMakeLists.txt b/lib/src/common/CMakeLists.txt index dce6eaf2b..2cb75a650 100644 --- a/lib/src/common/CMakeLists.txt +++ b/lib/src/common/CMakeLists.txt @@ -24,6 +24,7 @@ set(SOURCES arch_select.cc pcap.c phy_cfg_nr.cc phy_cfg_nr_default.cc + rrc_common.cc rlc_pcap.cc s1ap_pcap.cc security.cc diff --git a/srsue/src/stack/rrc/rrc_common.cc b/lib/src/common/rrc_common.cc similarity index 91% rename from srsue/src/stack/rrc/rrc_common.cc rename to lib/src/common/rrc_common.cc index 9c1f5a8bb..fdf255c04 100644 --- a/srsue/src/stack/rrc/rrc_common.cc +++ b/lib/src/common/rrc_common.cc @@ -10,9 +10,9 @@ * */ -#include "srsue/hdr/stack/rrc/rrc_common.h" +#include "srsran/rrc/rrc_common.h" -namespace srsue { +namespace srsran { uint8_t rrc_value_to_range(quant_s quant, const float value) { @@ -48,4 +48,4 @@ float rrc_range_to_value(quant_s quant, const uint8_t range) return val; } -} // namespace srsue \ No newline at end of file +} // namespace srsran \ No newline at end of file diff --git a/srsue/hdr/stack/rrc/rrc.h b/srsue/hdr/stack/rrc/rrc.h index a6806f45c..8d2ebbcf7 100644 --- a/srsue/hdr/stack/rrc/rrc.h +++ b/srsue/hdr/stack/rrc/rrc.h @@ -14,7 +14,6 @@ #define SRSUE_RRC_H #include "rrc_cell.h" -#include "rrc_common.h" #include "rrc_metrics.h" #include "rrc_rlf_report.h" #include "srsran/asn1/rrc_utils.h" @@ -26,6 +25,7 @@ #include "srsran/common/security.h" #include "srsran/common/stack_procedure.h" #include "srsran/interfaces/ue_interfaces.h" +#include "srsran/rrc/rrc_common.h" #include "srsran/srslog/srslog.h" #include diff --git a/srsue/hdr/stack/rrc/rrc_metrics.h b/srsue/hdr/stack/rrc/rrc_metrics.h index 34e01e486..791bdc3b9 100644 --- a/srsue/hdr/stack/rrc/rrc_metrics.h +++ b/srsue/hdr/stack/rrc/rrc_metrics.h @@ -13,11 +13,18 @@ #ifndef SRSUE_RRC_METRICS_H #define SRSUE_RRC_METRICS_H -#include "rrc_common.h" #include "srsran/interfaces/phy_interface_types.h" namespace srsue { +// RRC states (3GPP 36.331 v10.0.0) +typedef enum { + RRC_STATE_IDLE = 0, + RRC_STATE_CONNECTED, + RRC_STATE_N_ITEMS, +} rrc_state_t; +static const char rrc_state_text[RRC_STATE_N_ITEMS][100] = {"IDLE", "CONNECTED"}; + struct rrc_metrics_t { rrc_state_t state; std::vector neighbour_cells; diff --git a/srsue/src/stack/rrc/CMakeLists.txt b/srsue/src/stack/rrc/CMakeLists.txt index aa31cd9a6..88a66feab 100644 --- a/srsue/src/stack/rrc/CMakeLists.txt +++ b/srsue/src/stack/rrc/CMakeLists.txt @@ -8,7 +8,7 @@ add_subdirectory(test) -set(SOURCES rrc.cc rrc_procedures.cc rrc_meas.cc rrc_cell.cc rrc_common.cc rrc_rlf_report.cc phy_controller.cc) +set(SOURCES rrc.cc rrc_procedures.cc rrc_meas.cc rrc_cell.cc rrc_rlf_report.cc phy_controller.cc) add_library(srsue_rrc STATIC ${SOURCES}) set(SOURCES rrc_nr.cc) diff --git a/srsue/src/stack/rrc/rrc_rlf_report.cc b/srsue/src/stack/rrc/rrc_rlf_report.cc index c4930af9c..372ed4e15 100644 --- a/srsue/src/stack/rrc/rrc_rlf_report.cc +++ b/srsue/src/stack/rrc/rrc_rlf_report.cc @@ -11,7 +11,7 @@ */ #include "srsue/hdr/stack/rrc/rrc_rlf_report.h" -#include "srsue/hdr/stack/rrc/rrc_common.h" +#include "srsran/rrc/rrc_common.h" namespace srsue { @@ -39,9 +39,9 @@ void rrc_rlf_report::set_failure(meas_cell_list& meas_cells, fa // set the measResultLastServCell to include the RSRP and RSRQ, if available, of the PCell based on // measurements collected up to the moment the UE detected radio link failure rlf_report.meas_result_last_serv_cell_r9.rsrp_result_r9 = - rrc_value_to_range(quant_rsrp, meas_cells.serving_cell().get_rsrp()); + rrc_value_to_range(srsran::quant_rsrp, meas_cells.serving_cell().get_rsrp()); rlf_report.meas_result_last_serv_cell_r9.rsrq_result_r9 = - rrc_value_to_range(quant_rsrq, meas_cells.serving_cell().get_rsrq()); + rrc_value_to_range(srsran::quant_rsrq, meas_cells.serving_cell().get_rsrq()); rlf_report.meas_result_last_serv_cell_r9.rsrq_result_r9_present = true; // set the measResultNeighCells to include the best measured cells, other than the PCell, ordered such that @@ -61,8 +61,8 @@ void rrc_rlf_report::set_failure(meas_cell_list& meas_cells, fa meas.pci = f->get_pci(); meas.meas_result.rsrp_result_present = true; meas.meas_result.rsrq_result_present = true; - meas.meas_result.rsrp_result = rrc_value_to_range(quant_rsrp, f->get_rsrp()); - meas.meas_result.rsrq_result = rrc_value_to_range(quant_rsrq, f->get_rsrq()); + meas.meas_result.rsrp_result = rrc_value_to_range(srsran::quant_rsrp, f->get_rsrp()); + meas.meas_result.rsrq_result = rrc_value_to_range(srsran::quant_rsrq, f->get_rsrq()); meas2.meas_result_list_r9.push_back(meas); rlf_report.meas_result_neigh_cells_r9.meas_result_list_eutra_r9.push_back(meas2); } From 04db8c6bbf439374fca1900bdf24be82fb15d234 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 22 Sep 2021 16:20:39 +0200 Subject: [PATCH 74/83] Log measurementReport before checking if it's valid --- srsenb/src/stack/rrc/rrc_mobility.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_mobility.cc b/srsenb/src/stack/rrc/rrc_mobility.cc index d0d35c6e7..ad35042d1 100644 --- a/srsenb/src/stack/rrc/rrc_mobility.cc +++ b/srsenb/src/stack/rrc/rrc_mobility.cc @@ -227,6 +227,14 @@ bool rrc::ue::rrc_mobility::fill_conn_recfg_no_ho_cmd(asn1::rrc::rrc_conn_recfg_ //! Method called whenever the eNB receives a MeasReport from the UE. In normal situations, an HO procedure is started void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg, srsran::unique_byte_buffer_t pdu) { + asn1::json_writer json_writer; + msg.to_json(json_writer); + event_logger::get().log_measurement_report( + rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx, + asn1::octstring_to_string(pdu->msg, pdu->N_bytes), + json_writer.to_string(), + rrc_ue->rnti); + if (not is_in_state()) { Info("Received a MeasReport while UE is performing Handover. Ignoring..."); return; @@ -234,7 +242,7 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg, srsr // Check if meas_id is valid const meas_results_s& meas_res = msg.crit_exts.c1().meas_report_r8().meas_results; if (not meas_res.meas_result_neigh_cells_present) { - Info("Received a MeasReport, but the UE did not detect any cell."); + Debug("Received a MeasReport, but the UE did not detect any cell."); return; } if (meas_res.meas_result_neigh_cells.type().value != @@ -279,14 +287,6 @@ void rrc::ue::rrc_mobility::handle_ue_meas_report(const meas_report_s& msg, srsr break; } } - - asn1::json_writer json_writer; - msg.to_json(json_writer); - event_logger::get().log_measurement_report( - rrc_ue->ue_cell_list.get_ue_cc_idx(UE_PCELL_CC_IDX)->cell_common->enb_cc_idx, - asn1::octstring_to_string(pdu->msg, pdu->N_bytes), - json_writer.to_string(), - rrc_ue->rnti); } /** From ada05ea0c827bd258cca190464b23a9b621850ab Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Wed, 22 Sep 2021 17:13:35 +0200 Subject: [PATCH 75/83] Add A1, A2 and A4 measurement Reports event triggers --- srsenb/rr.conf.example | 27 ++++--- srsenb/src/enb_cfg_parser.cc | 107 ++++++++++++++++++++++------ srsenb/src/stack/rrc/ue_meas_cfg.cc | 20 +++++- srsenb/test/rrc/rrc_meascfg_test.cc | 2 +- 4 files changed, 122 insertions(+), 34 deletions(-) diff --git a/srsenb/rr.conf.example b/srsenb/rr.conf.example index cfb984a7f..6e6417080 100644 --- a/srsenb/rr.conf.example +++ b/srsenb/rr.conf.example @@ -87,14 +87,25 @@ cell_list = } ); - // ReportCfg (only A3 supported) - meas_report_desc = { - a3_report_type = "RSRP"; - a3_offset = 6; - a3_hysteresis = 0; - a3_time_to_trigger = 480; - rsrq_config = 4; - }; + // Select measurement triggers (A3 and A4 events are all mapped to all cells in meas_cell_list) + meas_report_desc = + ( + { + eventA = 3 + a3_offset = 6; + hysteresis = 0; + time_to_trigger = 480; + trigger_quant = "RSRP"; + max_report_cells = 1; + report_interv = 120; + report_amount = 1; + } + ); + meas_quant_desc = { + // averaging filter coefficient + rsrq_config = 4; + rsrp_config = 4; + }; } // Add here more cells ); diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 66eee24c4..01a2dfbb7 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -16,6 +16,7 @@ #include "srsran/common/band_helper.h" #include "srsran/common/multiqueue.h" #include "srsran/phy/common/phy_common.h" +#include "srsran/rrc/rrc_common.h" #include #define HANDLEPARSERCODE(cond) \ @@ -778,30 +779,92 @@ static int parse_meas_cell_list(rrc_meas_cfg_t* meas_cfg, Setting& root) return 0; } -static int parse_meas_report_desc(rrc_meas_cfg_t* meas_cfg, Setting& root) +static int parse_meas_report_desc(rrc_meas_cfg_t* meas_cfg, Setting& cellroot) { - // NOTE: For now, only support one meas_report for all cells. - // TODO: for a1 - // TODO: for a2 - // meas report parsing - meas_cfg->meas_reports.resize(1); - asn1::rrc::report_cfg_eutra_s& meas_item = meas_cfg->meas_reports[0]; - HANDLEPARSERCODE(asn1_parsers::str_to_enum(meas_item.trigger_quant, root["a3_report_type"])); - auto& event = meas_item.trigger_type.set_event(); - event.event_id.set_event_a3().report_on_leave = false; - event.event_id.event_a3().a3_offset = (int)root["a3_offset"]; - event.hysteresis = (int)root["a3_hysteresis"]; - meas_item.max_report_cells = 1; // TODO: parse - meas_item.report_amount.value = report_cfg_eutra_s::report_amount_e_::r1; // TODO: parse - meas_item.report_interv.value = report_interv_e::ms120; // TODO: parse - meas_item.report_quant.value = report_cfg_eutra_s::report_quant_opts::both; // TODO: parse + // NOTE: Events A1, A2, A3 and A4 are supported. A3 and A4 will be configured for all neighbour cells + + Setting& root = cellroot["meas_report_desc"]; + + meas_cfg->meas_reports.resize(root.getLength()); + for (int i = 0; i < root.getLength(); i++) { + asn1::rrc::report_cfg_eutra_s& meas_item = meas_cfg->meas_reports[i]; + + // Parse trigger quantity before event + HANDLEPARSERCODE(asn1_parsers::str_to_enum(meas_item.trigger_quant, root[i]["trigger_quant"])); + + auto& event = meas_item.trigger_type.set_event(); + + // Configure event + switch ((int)root[i]["eventA"]) { + case 1: + if (!root[i].exists("a1_thresh")) { + ERROR("Missing a1_thresh field for A1 event\n"); + return SRSRAN_ERROR; + } + if (meas_item.trigger_quant == report_cfg_eutra_s::trigger_quant_opts::rsrp) { + event.event_id.set_event_a1().a1_thres.set_thres_rsrp() = + rrc_value_to_range(srsran::quant_rsrp, (int)root[i]["a1_thresh"]); + } else { + event.event_id.set_event_a1().a1_thres.set_thres_rsrq() = + rrc_value_to_range(srsran::quant_rsrq, (int)root[i]["a1_thresh"]); + } + break; + case 2: + if (!root[i].exists("a2_thresh")) { + ERROR("Missing a2_thresh field for A2 event\n"); + return SRSRAN_ERROR; + } + if (meas_item.trigger_quant == report_cfg_eutra_s::trigger_quant_opts::rsrp) { + event.event_id.set_event_a2().a2_thres.set_thres_rsrp() = + rrc_value_to_range(srsran::quant_rsrp, (int)root[i]["a2_thresh"]); + } else { + event.event_id.set_event_a2().a2_thres.set_thres_rsrq() = + rrc_value_to_range(srsran::quant_rsrq, (int)root[i]["a2_thresh"]); + } + break; + case 3: + if (!root[i].exists("a3_offset")) { + ERROR("Missing a3_offset field for A3 event\n"); + return SRSRAN_ERROR; + } + event.event_id.set_event_a3().report_on_leave = false; + event.event_id.event_a3().a3_offset = (int)root[i]["a3_offset"]; + break; + case 4: + if (!root[i].exists("a4_thresh")) { + ERROR("Missing a4_thresh field for A4 event\n"); + return SRSRAN_ERROR; + } + if (meas_item.trigger_quant == report_cfg_eutra_s::trigger_quant_opts::rsrp) { + event.event_id.set_event_a4().a4_thres.set_thres_rsrp() = + rrc_value_to_range(srsran::quant_rsrp, (int)root[i]["a4_thresh"]); + } else { + event.event_id.set_event_a4().a4_thres.set_thres_rsrq() = + rrc_value_to_range(srsran::quant_rsrq, (int)root[i]["a4_thresh"]); + } + break; + default: + ERROR("Invalid or unsupported event A%d in meas_report_desc (only A1-A4 are supported)\n", + (int)root[i]["eventA"]); + return SRSRAN_ERROR; + } + + // Configure common variables + event.hysteresis = (int)root[i]["hysteresis"]; + HANDLEPARSERCODE(asn1_parsers::number_to_enum(event.time_to_trigger, root[i]["time_to_trigger"])); + meas_item.report_quant.value = report_cfg_eutra_s::report_quant_opts::both; // TODO: parse + meas_item.max_report_cells = (int)root[i]["max_report_cells"]; + HANDLEPARSERCODE(asn1_parsers::number_to_enum(meas_item.report_interv, root[i]["report_interv"])); + HANDLEPARSERCODE(asn1_parsers::number_to_enum(meas_item.report_amount, root[i]["report_amount"])); + } + // quant coeff parsing auto& quant = meas_cfg->quant_cfg; - HANDLEPARSERCODE(asn1_parsers::number_to_enum(event.time_to_trigger, root["a3_time_to_trigger"])); - HANDLEPARSERCODE( - asn1_parsers::opt_number_to_enum(quant.filt_coef_rsrp, quant.filt_coef_rsrp_present, root, "rsrp_config")); - HANDLEPARSERCODE( - asn1_parsers::opt_number_to_enum(quant.filt_coef_rsrq, quant.filt_coef_rsrq_present, root, "rsrq_config")); + + HANDLEPARSERCODE(asn1_parsers::opt_number_to_enum( + quant.filt_coef_rsrp, quant.filt_coef_rsrp_present, cellroot["meas_quant_desc"], "rsrp_config")); + HANDLEPARSERCODE(asn1_parsers::opt_number_to_enum( + quant.filt_coef_rsrq, quant.filt_coef_rsrq_present, cellroot["meas_quant_desc"], "rsrq_config")); return SRSRAN_SUCCESS; } @@ -864,7 +927,7 @@ static int parse_cell_list(all_args_t* args, rrc_cfg_t* rrc_cfg, Setting& root) ERROR("PARSER ERROR: \"ho_active\" is set to true, but field \"meas_report_desc\" doesn't exist.\n"); return SRSRAN_ERROR; } - HANDLEPARSERCODE(parse_meas_report_desc(&cell_cfg.meas_cfg, cellroot["meas_report_desc"])); + HANDLEPARSERCODE(parse_meas_report_desc(&cell_cfg.meas_cfg, cellroot)); } if (cellroot.exists("scell_list")) { diff --git a/srsenb/src/stack/rrc/ue_meas_cfg.cc b/srsenb/src/stack/rrc/ue_meas_cfg.cc index 106795cf6..ea7c166eb 100644 --- a/srsenb/src/stack/rrc/ue_meas_cfg.cc +++ b/srsenb/src/stack/rrc/ue_meas_cfg.cc @@ -351,11 +351,25 @@ bool fill_meascfg_enb_cfg(meas_cfg_s& meascfg, const ue_cell_ded_list& ue_cell_l meascfg.quant_cfg.quant_cfg_eutra = pcell_meascfg.quant_cfg; // Insert all measIds - // TODO: add this to the parser + // TODO: add this to the parser. Now we map all neighbours to all A3/A4 events and Pcell to A1/A2 if (meascfg.report_cfg_to_add_mod_list.size() > 0) { for (const auto& measobj : meascfg.meas_obj_to_add_mod_list) { - add_measid_cfg( - meascfg.meas_id_to_add_mod_list, measobj.meas_obj_id, meascfg.report_cfg_to_add_mod_list[0].report_cfg_id); + std::array events; + if (measobj.meas_obj.meas_obj_eutra().carrier_freq == pcell->get_dl_earfcn()) { + events[0] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a1; + events[1] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a2; + } else { + events[0] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a3; + events[1] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a4; + } + for (const auto& measrep : meascfg.report_cfg_to_add_mod_list) { + for (const auto& event : events) { + if (measrep.report_cfg.report_cfg_eutra().trigger_type.event().event_id.type().value == event) { + add_measid_cfg(meascfg.meas_id_to_add_mod_list, measobj.meas_obj_id, measrep.report_cfg_id); + break; + } + } + } } } diff --git a/srsenb/test/rrc/rrc_meascfg_test.cc b/srsenb/test/rrc/rrc_meascfg_test.cc index 69f9b0cb5..728e385a0 100644 --- a/srsenb/test/rrc/rrc_meascfg_test.cc +++ b/srsenb/test/rrc/rrc_meascfg_test.cc @@ -258,7 +258,7 @@ int test_correct_meascfg_calculation() cfg.cell_list[0].meas_cfg.meas_reports[0]); TESTASSERT(cell_meas_cfg.meas_id_to_add_mod_list_present); const auto& measid = cell_meas_cfg.meas_id_to_add_mod_list[0]; - TESTASSERT(measid.meas_id == 1 and measid.meas_obj_id == 1 and measid.report_cfg_id == 1); + TESTASSERT(measid.meas_id == 1 and measid.meas_obj_id == 2 and measid.report_cfg_id == 1); meas_cfg_s cell_meas_cfg2; ue_cell_list.set_cells({1}); From 7bc8bb8500d4e57322dfd34356bb59e2c07fb526 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Mon, 27 Sep 2021 19:09:08 +0200 Subject: [PATCH 76/83] combine all report configuration with all measurement objects --- srsenb/rr.conf.example | 2 +- srsenb/src/stack/rrc/ue_meas_cfg.cc | 17 ++--------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/srsenb/rr.conf.example b/srsenb/rr.conf.example index 6e6417080..e5d6fd02c 100644 --- a/srsenb/rr.conf.example +++ b/srsenb/rr.conf.example @@ -87,7 +87,7 @@ cell_list = } ); - // Select measurement triggers (A3 and A4 events are all mapped to all cells in meas_cell_list) + // Select measurement report configuration (all reports are combined with all measurement objects) meas_report_desc = ( { diff --git a/srsenb/src/stack/rrc/ue_meas_cfg.cc b/srsenb/src/stack/rrc/ue_meas_cfg.cc index ea7c166eb..7a30949eb 100644 --- a/srsenb/src/stack/rrc/ue_meas_cfg.cc +++ b/srsenb/src/stack/rrc/ue_meas_cfg.cc @@ -351,24 +351,11 @@ bool fill_meascfg_enb_cfg(meas_cfg_s& meascfg, const ue_cell_ded_list& ue_cell_l meascfg.quant_cfg.quant_cfg_eutra = pcell_meascfg.quant_cfg; // Insert all measIds - // TODO: add this to the parser. Now we map all neighbours to all A3/A4 events and Pcell to A1/A2 + // TODO: add this to the parser. Now we combine all reports with all objects if (meascfg.report_cfg_to_add_mod_list.size() > 0) { for (const auto& measobj : meascfg.meas_obj_to_add_mod_list) { - std::array events; - if (measobj.meas_obj.meas_obj_eutra().carrier_freq == pcell->get_dl_earfcn()) { - events[0] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a1; - events[1] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a2; - } else { - events[0] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a3; - events[1] = asn1::rrc::eutra_event_s::event_id_c_::types_opts::event_a4; - } for (const auto& measrep : meascfg.report_cfg_to_add_mod_list) { - for (const auto& event : events) { - if (measrep.report_cfg.report_cfg_eutra().trigger_type.event().event_id.type().value == event) { - add_measid_cfg(meascfg.meas_id_to_add_mod_list, measobj.meas_obj_id, measrep.report_cfg_id); - break; - } - } + add_measid_cfg(meascfg.meas_id_to_add_mod_list, measobj.meas_obj_id, measrep.report_cfg_id); } } } From 91401ae3a403cc67ca6d15d48ad48e9443ef7be0 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 28 Sep 2021 17:57:37 +0200 Subject: [PATCH 77/83] Fix meascfg test --- srsenb/test/rrc/rrc_meascfg_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/test/rrc/rrc_meascfg_test.cc b/srsenb/test/rrc/rrc_meascfg_test.cc index 728e385a0..69f9b0cb5 100644 --- a/srsenb/test/rrc/rrc_meascfg_test.cc +++ b/srsenb/test/rrc/rrc_meascfg_test.cc @@ -258,7 +258,7 @@ int test_correct_meascfg_calculation() cfg.cell_list[0].meas_cfg.meas_reports[0]); TESTASSERT(cell_meas_cfg.meas_id_to_add_mod_list_present); const auto& measid = cell_meas_cfg.meas_id_to_add_mod_list[0]; - TESTASSERT(measid.meas_id == 1 and measid.meas_obj_id == 2 and measid.report_cfg_id == 1); + TESTASSERT(measid.meas_id == 1 and measid.meas_obj_id == 1 and measid.report_cfg_id == 1); meas_cfg_s cell_meas_cfg2; ue_cell_list.set_cells({1}); From 7f7cfe687df7c7fc324793f85a4ece92f73da526 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 29 Sep 2021 20:18:57 +0200 Subject: [PATCH 78/83] fix calculation. --- lib/src/common/band_helper.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/common/band_helper.cc b/lib/src/common/band_helper.cc index 968e94916..e5a3be222 100644 --- a/lib/src/common/band_helper.cc +++ b/lib/src/common/band_helper.cc @@ -41,7 +41,7 @@ uint32_t srsran_band_helper::freq_to_nr_arfcn(double freq) if (not is_valid_raster_param(params)) { return 0; } - return (((freq + params.F_REF_Offs_MHz * 1e6) / 1e3 / params.delta_F_global_kHz) + params.N_REF_Offs); + return (((freq - params.F_REF_Offs_MHz * 1e6) / 1e3 / params.delta_F_global_kHz) + params.N_REF_Offs); } // Implements 5.4.2.1 in TS 38.104 From 077f9cd03e28bd4903f763312d32897500b72c35 Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 29 Sep 2021 20:19:48 +0200 Subject: [PATCH 79/83] Add test for get_abs_freq_point_a_arfcn. --- lib/src/common/test/band_helper_test.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/common/test/band_helper_test.cc b/lib/src/common/test/band_helper_test.cc index 3dfc8d4cc..69be8668f 100644 --- a/lib/src/common/test/band_helper_test.cc +++ b/lib/src/common/test/band_helper_test.cc @@ -77,6 +77,9 @@ int bands_test_nr() TESTASSERT(band_vector.at(0) == 77); TESTASSERT(band_vector.at(1) == 78); + // n78 + TESTASSERT(bands.get_abs_freq_point_a_arfcn(52, 634240) == 633928); + // Invalid configs // For 30 kHz, 620001 is not a valid ARFCN, only every 2nd band_vector = bands.get_bands_nr(620001, srsran::srsran_band_helper::KHZ_30); From e02218e4ab33f2edc6a3e9a8c067f6f76cbd541a Mon Sep 17 00:00:00 2001 From: Fabian Eckermann Date: Wed, 29 Sep 2021 21:05:18 +0200 Subject: [PATCH 80/83] configure phy to be tdd by default (currently static). --- srsenb/src/phy/nr/worker_pool.cc | 2 +- srsenb/src/phy/phy.cc | 11 +++++++---- srsenb/src/stack/rrc/rrc_nr.cc | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/srsenb/src/phy/nr/worker_pool.cc b/srsenb/src/phy/nr/worker_pool.cc index e79d9aef2..ebe9237ad 100644 --- a/srsenb/src/phy/nr/worker_pool.cc +++ b/srsenb/src/phy/nr/worker_pool.cc @@ -131,7 +131,7 @@ int worker_pool::set_common_cfg(const phy_interface_rrc_nr::common_cfg_t& common return SRSRAN_ERROR; } prach_cfg.freq_offset -= lte_nr_prach_offset; - prach_cfg.is_nr = true; + prach_cfg.is_nr = true; prach_cfg.tdd_config.configured = (common_cfg.duplex_mode == SRSRAN_DUPLEX_MODE_TDD); // Set the PRACH configuration diff --git a/srsenb/src/phy/phy.cc b/srsenb/src/phy/phy.cc index a466b8b99..12713b940 100644 --- a/srsenb/src/phy/phy.cc +++ b/srsenb/src/phy/phy.cc @@ -10,6 +10,10 @@ * */ +#include "srsenb/hdr/phy/phy.h" +#include "srsran/common/band_helper.h" +#include "srsran/common/phy_cfg_nr_default.h" +#include "srsran/common/threads.h" #include #include #include @@ -17,10 +21,6 @@ #include #include -#include "srsenb/hdr/phy/phy.h" -#include "srsran/common/phy_cfg_nr_default.h" -#include "srsran/common/threads.h" - #define Error(fmt, ...) \ if (SRSRAN_DEBUG_ENABLED) \ phy_log.error(fmt, ##__VA_ARGS__) @@ -339,6 +339,8 @@ int phy::init_nr(const phy_args_t& args, const phy_cfg_t& cfg, stack_interface_p tx_rx.set_nr_workers(nr_workers.get()); + srsran::srsran_band_helper band_helper; + // perform initial config of PHY (during RRC init PHY isn't running yet) static const srsran::phy_cfg_nr_t default_phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{}}; @@ -346,6 +348,7 @@ int phy::init_nr(const phy_args_t& args, const phy_cfg_t& cfg, stack_interface_p common_cfg.carrier = default_phy_cfg.carrier; common_cfg.pdcch = default_phy_cfg.pdcch; common_cfg.prach = default_phy_cfg.prach; + common_cfg.duplex_mode = SRSRAN_DUPLEX_MODE_TDD; // TODO: make dynamic if (set_common_cfg(common_cfg) < SRSRAN_SUCCESS) { phy_log.error("Couldn't set common PHY config"); return SRSRAN_ERROR; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 9ef11696d..04beff37c 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -231,6 +231,7 @@ void rrc_nr::config_phy() common_cfg.carrier = default_phy_cfg.carrier; common_cfg.pdcch = default_phy_cfg.pdcch; common_cfg.prach = default_phy_cfg.prach; + common_cfg.duplex_mode = SRSRAN_DUPLEX_MODE_TDD; // TODO: make dynamic if (phy->set_common_cfg(common_cfg) < SRSRAN_SUCCESS) { logger.error("Couldn't set common PHY config"); return; From bf2606f94e4ade5e511321c54d8b9d5a7277209f Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Wed, 29 Sep 2021 21:38:01 +0200 Subject: [PATCH 81/83] ue,mac_nr: fix race condition by using thread-safe RNTI class --- srsue/hdr/stack/mac_nr/mac_nr.h | 3 +-- srsue/src/stack/mac_nr/mac_nr.cc | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h index d22955a95..40a5ed772 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -148,8 +148,7 @@ private: std::atomic started = {false}; - uint16_t c_rnti = SRSRAN_INVALID_RNTI; - uint64_t contention_id = 0; + ue_rnti rntis; // thread-safe helper to store RNTIs, contention ID, etc std::array metrics = {}; diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index d98e1a15c..11cc1c4ce 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -146,7 +146,7 @@ void mac_nr::update_buffer_states() mac_interface_phy_nr::sched_rnti_t mac_nr::get_ul_sched_rnti_nr(const uint32_t tti) { - return {c_rnti, srsran_rnti_type_c}; + return {rntis.get_crnti(), srsran_rnti_type_c}; } bool mac_nr::is_si_opportunity() @@ -191,12 +191,12 @@ mac_interface_phy_nr::sched_rnti_t mac_nr::get_dl_sched_rnti_nr(const uint32_t t bool mac_nr::has_crnti() { - return c_rnti != SRSRAN_INVALID_RNTI; + return rntis.get_crnti() != SRSRAN_INVALID_RNTI; } uint16_t mac_nr::get_crnti() { - return c_rnti; + return rntis.get_crnti(); } uint16_t mac_nr::get_temp_crnti() @@ -332,7 +332,7 @@ void mac_nr::new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, *action = {}; // if proc ra is in contention resolution and c_rnti == grant.c_rnti resolve contention resolution - if (proc_ra.is_contention_resolution() && grant.rnti == c_rnti) { + if (proc_ra.is_contention_resolution() && grant.rnti == get_crnti()) { proc_ra.pdcch_to_crnti(); } @@ -432,14 +432,14 @@ void mac_nr::set_config(const srsran::rach_nr_cfg_t& rach_cfg) void mac_nr::set_contention_id(uint64_t ue_identity) { - contention_id = ue_identity; + rntis.set_contention_id(ue_identity); } bool mac_nr::set_crnti(const uint16_t c_rnti_) { if (is_valid_crnti(c_rnti_)) { logger.info("Setting C-RNTI to 0x%X", c_rnti_); - c_rnti = c_rnti_; + rntis.set_crnti(c_rnti_); return true; } else { logger.warning("Failed to set C-RNTI, 0x%X is not valid.", c_rnti_); From a64750e1be3c95d5c8bee5045917337a1723ec72 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 29 Sep 2021 16:49:02 +0200 Subject: [PATCH 82/83] rrc,nr,gnb: fix number of PDCCH candidates in search space --- srsenb/src/stack/rrc/rrc_nr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 04beff37c..e3bb045ee 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -624,7 +624,7 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level2 = asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level2_opts::n2; pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level4 = - asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level4_opts::n1; + asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level4_opts::n2; pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level8 = asn1::rrc_nr::search_space_s::nrof_candidates_s_::aggregation_level8_opts::n0; pdcch_ded_setup.search_spaces_to_add_mod_list[0].nrof_candidates.aggregation_level16 = From 78dad52cc8091924799c1284ef44dbfed9631635 Mon Sep 17 00:00:00 2001 From: Francisco Paisana Date: Wed, 29 Sep 2021 16:51:04 +0200 Subject: [PATCH 83/83] rrc,nr,gnb: disable CQI configuration in gNB until gNB PHY supports it --- srsenb/src/stack/rrc/rrc_nr.cc | 77 ++++++++++++++++++---------------- srsue/src/stack/rrc/rrc_nr.cc | 3 -- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index e3bb045ee..6788a033c 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -816,34 +816,37 @@ int rrc_nr::ue::pack_secondary_cell_group_config_common(asn1::rrc_nr::cell_group cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg_present = true; cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.set_setup(); - // CSI report config - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list_present = true; - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list.resize(1); - auto& csi_report = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list[0]; - csi_report.report_cfg_id = 0; - csi_report.res_for_ch_meas = 0; - csi_report.csi_im_res_for_interference_present = true; - csi_report.csi_im_res_for_interference = 1; - csi_report.report_cfg_type.set_periodic(); - csi_report.report_cfg_type.periodic().report_slot_cfg.set_slots80(); - csi_report.report_cfg_type.periodic().pucch_csi_res_list.resize(1); - csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].ul_bw_part_id = 0; - csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].pucch_res = 1; // was 17 in orig PCAP - csi_report.report_quant.set_cri_ri_pmi_cqi(); - // Report freq config (optional) - csi_report.report_freq_cfg_present = true; - csi_report.report_freq_cfg.cqi_format_ind_present = true; - csi_report.report_freq_cfg.cqi_format_ind = - asn1::rrc_nr::csi_report_cfg_s::report_freq_cfg_s_::cqi_format_ind_opts::wideband_cqi; - csi_report.time_restrict_for_ch_meass = asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_ch_meass_opts::not_cfgured; - csi_report.time_restrict_for_interference_meass = - asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_interference_meass_opts::not_cfgured; - csi_report.group_based_beam_report.set_disabled(); - // Skip CQI table (optional) - csi_report.cqi_table_present = true; - csi_report.cqi_table = asn1::rrc_nr::csi_report_cfg_s::cqi_table_opts::table2; - csi_report.subband_size = asn1::rrc_nr::csi_report_cfg_s::subband_size_opts::value1; + // NOTE: Disable CQI configuration until srsENB NR PHY supports it + // // CSI report config + // cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list_present = + // true; + // cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list.resize(1); + // auto& csi_report = + // cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list[0]; + // csi_report.report_cfg_id = 0; + // csi_report.res_for_ch_meas = 0; + // csi_report.csi_im_res_for_interference_present = true; + // csi_report.csi_im_res_for_interference = 1; + // csi_report.report_cfg_type.set_periodic(); + // csi_report.report_cfg_type.periodic().report_slot_cfg.set_slots80(); + // csi_report.report_cfg_type.periodic().pucch_csi_res_list.resize(1); + // csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].ul_bw_part_id = 0; + // csi_report.report_cfg_type.periodic().pucch_csi_res_list[0].pucch_res = 1; // was 17 in orig PCAP + // csi_report.report_quant.set_cri_ri_pmi_cqi(); + // // Report freq config (optional) + // csi_report.report_freq_cfg_present = true; + // csi_report.report_freq_cfg.cqi_format_ind_present = true; + // csi_report.report_freq_cfg.cqi_format_ind = + // asn1::rrc_nr::csi_report_cfg_s::report_freq_cfg_s_::cqi_format_ind_opts::wideband_cqi; + // csi_report.time_restrict_for_ch_meass = + // asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_ch_meass_opts::not_cfgured; + // csi_report.time_restrict_for_interference_meass = + // asn1::rrc_nr::csi_report_cfg_s::time_restrict_for_interference_meass_opts::not_cfgured; + // csi_report.group_based_beam_report.set_disabled(); + // // Skip CQI table (optional) + // csi_report.cqi_table_present = true; + // csi_report.cqi_table = asn1::rrc_nr::csi_report_cfg_s::cqi_table_opts::table2; + // csi_report.subband_size = asn1::rrc_nr::csi_report_cfg_s::subband_size_opts::value1; // Reconfig with Sync cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync_present = true; @@ -1200,10 +1203,11 @@ int rrc_nr::ue::pack_secondary_cell_group_config_fdd(asn1::dyn_octstring& packed // CSI resource config // TODO: add csi resource config - // CSI report config - auto& csi_report = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list[0]; - csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 5; + // NOTE: Disable CQI configuration until srsENB NR PHY supports it + // // CSI report config + // auto& csi_report = + // cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list[0]; + // csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 5; // Reconfig with Sync cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.sp_cell_cfg_common.ssb_subcarrier_spacing = @@ -1300,10 +1304,11 @@ int rrc_nr::ue::pack_secondary_cell_group_config_tdd(asn1::dyn_octstring& packed nzp_csi_res_set.nzp_csi_rs_res[0] = 0; // Skip TRS info - // CSI report config - auto& csi_report = - cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list[0]; - csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 7; + // NOTE: Disable CQI configuration until srsENB NR PHY supports it + // // CSI report config + // auto& csi_report = + // cell_group_cfg_pack.sp_cell_cfg.sp_cell_cfg_ded.csi_meas_cfg.setup().csi_report_cfg_to_add_mod_list[0]; + // csi_report.report_cfg_type.periodic().report_slot_cfg.slots80() = 7; // Reconfig with Sync cell_group_cfg_pack.sp_cell_cfg.recfg_with_sync.smtc.release(); diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index d33b4f9d1..156dc9513 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -725,9 +725,6 @@ bool rrc_nr::apply_csi_meas_cfg(const asn1::rrc_nr::csi_meas_cfg_s& csi_meas_cfg return false; } } - } else { - logger.warning("Option csi_report_cfg_to_add_mod_list not present"); - return false; } if (csi_meas_cfg.nzp_csi_rs_res_to_add_mod_list_present) {