From 8ddc344cdb390b4b3da5f0eb56a583c6552d9f79 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Tue, 23 Nov 2021 15:00:30 +0100 Subject: [PATCH] gnb,mac: rework DL MAC PDU packing and add ConRes handling * store Msg3 when UL-CCCH is received * add ConRes CE in DL-SCH when indicated by scheduler * remove fixed LCID for packing SDUs --- .../srsran/interfaces/gnb_interfaces.h | 11 +++ srsgnb/hdr/stack/mac/mac_nr.h | 8 +- srsgnb/hdr/stack/mac/ue_nr.h | 3 + srsgnb/src/stack/mac/mac_nr.cc | 41 +++++++-- srsgnb/src/stack/mac/ue_nr.cc | 87 ++++++++++++------- 5 files changed, 111 insertions(+), 39 deletions(-) diff --git a/lib/include/srsran/interfaces/gnb_interfaces.h b/lib/include/srsran/interfaces/gnb_interfaces.h index 1864d8f3a..631fdba54 100644 --- a/lib/include/srsran/interfaces/gnb_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_interfaces.h @@ -121,6 +121,17 @@ public: virtual void write_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu) = 0; }; +/***************************** + * MAC internal INTERFACES + ****************************/ + +class mac_interface_pdu_demux_nr +{ +public: + // Called by PDU handler from Stack thread to store Msg3 content (According to O-RAN WG8 v3.0, Sec. 9.2.2.3.5 MAC) + virtual void store_msg3(uint16_t rnti, srsran::unique_byte_buffer_t pdu) = 0; +}; + /***************************** * RRC INTERFACES ****************************/ diff --git a/srsgnb/hdr/stack/mac/mac_nr.h b/srsgnb/hdr/stack/mac/mac_nr.h index 8137e43f6..17e4aff3a 100644 --- a/srsgnb/hdr/stack/mac/mac_nr.h +++ b/srsgnb/hdr/stack/mac/mac_nr.h @@ -37,7 +37,10 @@ struct mac_nr_args_t { class sched_nr; class mac_nr_rx; -class mac_nr final : public mac_interface_phy_nr, public mac_interface_rrc_nr, public mac_interface_rlc_nr +class mac_nr final : public mac_interface_phy_nr, + public mac_interface_rrc_nr, + public mac_interface_rlc_nr, + public mac_interface_pdu_demux_nr { public: explicit mac_nr(srsran::task_sched_handle task_sched_); @@ -71,6 +74,9 @@ public: int pusch_info(const srsran_slot_cfg_t& slot_cfg, pusch_info_t& pusch_info) override; void rach_detected(const rach_info_t& rach_info) override; + // MAC-internal interface + void store_msg3(uint16_t rnti, srsran::unique_byte_buffer_t pdu) override; + // Test interface void ul_bsr(uint16_t rnti, uint32_t lcid, uint32_t bsr); diff --git a/srsgnb/hdr/stack/mac/ue_nr.h b/srsgnb/hdr/stack/mac/ue_nr.h index cb2f126ce..542d03516 100644 --- a/srsgnb/hdr/stack/mac/ue_nr.h +++ b/srsgnb/hdr/stack/mac/ue_nr.h @@ -48,6 +48,7 @@ public: uint16_t get_rnti() const { return rnti; } void set_active(bool active) { active_state.store(active, std::memory_order_relaxed); } bool is_active() const { return active_state.load(std::memory_order_relaxed); } + void store_msg3(srsran::unique_byte_buffer_t pdu); int generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size, srsran::const_span subpdu_lcids); @@ -98,6 +99,8 @@ private: ue_rx_pdu_queue; ///< currently only DCH PDUs supported (add BCH, PCH, etc) srsran::unique_byte_buffer_t ue_rlc_buffer; + srsran::unique_byte_buffer_t last_msg3; ///< holds UE ID received in Msg3 for ConRes CE + static constexpr int32_t MIN_RLC_PDU_LEN = 5; ///< minimum bytes that need to be available in a MAC PDU for attempting to add another RLC SDU diff --git a/srsgnb/src/stack/mac/mac_nr.cc b/srsgnb/src/stack/mac/mac_nr.cc index 09b87eb76..cff026b5c 100644 --- a/srsgnb/src/stack/mac/mac_nr.cc +++ b/srsgnb/src/stack/mac/mac_nr.cc @@ -24,15 +24,28 @@ namespace srsenb { +/** + * @brief Handles UL PDU processing + * + * This class implements the demuxing of UL PDUs received at the MAC layer. + * When the PHY decodes a valid PUSCH it passes the PDU to the MAC which + * in turn puts them in a thread-safe task queue to return to the calling + * thread as quick as possible. + * + * The demuxing of the PDUs for all users takes place on the Stack thread + * which calls RLC and RRC for SDUs, or the MAC/scheduler for control elements. + * + */ class mac_nr_rx { public: - explicit mac_nr_rx(rlc_interface_mac* rlc_, - rrc_interface_mac_nr* rrc_, - srsran::task_queue_handle& stack_task_queue_, - sched_nr_interface* sched_, - srslog::basic_logger& logger_) : - task_queue(stack_task_queue_), rlc(rlc_), rrc(rrc_), sched(sched_), logger(logger_) + explicit mac_nr_rx(rlc_interface_mac* rlc_, + rrc_interface_mac_nr* rrc_, + srsran::task_queue_handle& stack_task_queue_, + sched_nr_interface* sched_, + mac_interface_pdu_demux_nr& mac_, + srslog::basic_logger& logger_) : + task_queue(stack_task_queue_), rlc(rlc_), rrc(rrc_), sched(sched_), mac(mac_), logger(logger_) {} void handle_pdu(uint16_t rnti, srsran::unique_byte_buffer_t pdu) @@ -91,6 +104,9 @@ private: case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CCCH_SIZE_64: { srsran::mac_sch_subpdu_nr& ccch_subpdu = const_cast(subpdu); rlc->write_pdu(rnti, 0, ccch_subpdu.get_sdu(), ccch_subpdu.get_sdu_length()); + // store content for ConRes CE + mac.store_msg3(rnti, + srsran::make_byte_buffer(ccch_subpdu.get_sdu(), ccch_subpdu.get_sdu_length(), __FUNCTION__)); } break; case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CRNTI: { uint16_t ce_crnti = subpdu.get_c_rnti(); @@ -170,6 +186,7 @@ private: rlc_interface_mac* rlc; rrc_interface_mac_nr* rrc; sched_nr_interface* sched; + mac_interface_pdu_demux_nr& mac; srslog::basic_logger& logger; srsran::task_queue_handle& task_queue; @@ -279,7 +296,7 @@ int mac_nr::cell_cfg(const std::vector& bcch_dlsch_payload.push_back(std::move(sib)); } - rx.reset(new mac_nr_rx{rlc, rrc, stack_task_queue, sched.get(), logger}); + rx.reset(new mac_nr_rx{rlc, rrc, stack_task_queue, sched.get(), *this, logger}); srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{}; ref_args.duplex = cell_config[0].duplex.mode == SRSRAN_DUPLEX_MODE_TDD @@ -459,6 +476,16 @@ int mac_nr::slot_indication(const srsran_slot_cfg_t& slot_cfg) return 0; } +void mac_nr::store_msg3(uint16_t rnti, srsran::unique_byte_buffer_t pdu) +{ + srsran::rwlock_read_guard rw_lock(rwmutex); + if (is_rnti_active_nolock(rnti)) { + ue_db[rnti]->store_msg3(std::move(pdu)); + } else { + logger.error("User rnti=0x%x not found. Can't store Msg3.", rnti); + } +} + mac_nr::dl_sched_t* mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg) { slot_point pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; diff --git a/srsgnb/src/stack/mac/ue_nr.cc b/srsgnb/src/stack/mac/ue_nr.cc index 3956c8846..bc7b3372f 100644 --- a/srsgnb/src/stack/mac/ue_nr.cc +++ b/srsgnb/src/stack/mac/ue_nr.cc @@ -74,46 +74,64 @@ int ue_nr::generate_pdu(srsran::byte_buffer_t* pdu, uint32_t grant_size, srsran: } bool drb_activity = false; // inform RRC about user activity if true - int lcid = 4; // only supporting single DRB right now int32_t remaining_len = mac_pdu_dl.get_remaing_len(); - logger.debug("Adding MAC PDU for RNTI=%d (max %d B)", rnti, remaining_len); - while (remaining_len >= MIN_RLC_PDU_LEN) { - // clear read buffer - ue_rlc_buffer->clear(); + logger.debug("0x%x Generating MAC PDU (%d B)", rnti, remaining_len); + + // First, add CEs as indicated by scheduler + for (const auto& lcid : subpdu_lcids) { + logger.debug("adding lcid=%d", lcid); + if (lcid == srsran::mac_sch_subpdu_nr::CON_RES_ID) { + if (last_msg3 != nullptr) { + srsran::mac_sch_subpdu_nr::ue_con_res_id_t id; + memcpy(id.data(), last_msg3->msg, id.size()); + if (mac_pdu_dl.add_ue_con_res_id_ce(id) != SRSRAN_SUCCESS) { + logger.error("0x%x Failed to add ConRes CE.", rnti); + } + last_msg3 = nullptr; // don't use this Msg3 again + } else { + logger.warning("0x%x Can't add ConRes CE. No Msg3 stored.", rnti); + } + } else { + // add SDUs for given LCID + while (remaining_len >= MIN_RLC_PDU_LEN) { + // clear read buffer + ue_rlc_buffer->clear(); - // Determine space for RLC - remaining_len -= remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2; + // Determine space for RLC + remaining_len -= remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2; - // read RLC PDU - int pdu_len = rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, remaining_len); + // read RLC PDU + int pdu_len = rlc->read_pdu(rnti, lcid, ue_rlc_buffer->msg, remaining_len); - if (pdu_len > remaining_len) { - logger.error("Can't add SDU of %d B. Available space %d B", pdu_len, remaining_len); - break; - } else { - // Add SDU if RLC has something to tx - if (pdu_len > 0) { - ue_rlc_buffer->N_bytes = pdu_len; - logger.debug(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC", ue_rlc_buffer->N_bytes); - - // add to MAC PDU and pack - if (mac_pdu_dl.add_sdu(lcid, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes) != SRSRAN_SUCCESS) { - logger.error("Error packing MAC PDU"); + if (pdu_len > remaining_len) { + logger.error("Can't add SDU of %d B. Available space %d B", pdu_len, remaining_len); break; + } else { + // Add SDU if RLC has something to tx + if (pdu_len > 0) { + ue_rlc_buffer->N_bytes = pdu_len; + logger.debug(ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes, "Read %d B from RLC", ue_rlc_buffer->N_bytes); + + // add to MAC PDU and pack + if (mac_pdu_dl.add_sdu(lcid, ue_rlc_buffer->msg, ue_rlc_buffer->N_bytes) != SRSRAN_SUCCESS) { + logger.error("Error packing MAC PDU"); + break; + } + + // set DRB activity flag but only notify RRC once + if (lcid > 3) { + drb_activity = true; + } + } else { + break; + } + + remaining_len -= pdu_len; + logger.debug("%d B remaining PDU", remaining_len); } - - // set DRB activity flag but only notify RRC once - if (lcid > 3) { - drb_activity = true; - } - } else { - break; } - - remaining_len -= pdu_len; - logger.debug("%d B remaining PDU", remaining_len); } } @@ -236,4 +254,11 @@ void ue_nr::metrics_pusch_sinr(float sinr) } } +// Called from Stack thread when demuxing UL PDUs +void ue_nr::store_msg3(srsran::unique_byte_buffer_t pdu) +{ + std::lock_guard lock(mutex); + last_msg3 = std::move(pdu); +} + } // namespace srsenb