diff --git a/srsue/hdr/stack/mac_nr/demux_nr.h b/srsue/hdr/stack/mac_nr/demux_nr.h index 8d896a1da..72ca75dc2 100644 --- a/srsue/hdr/stack/mac_nr/demux_nr.h +++ b/srsue/hdr/stack/mac_nr/demux_nr.h @@ -20,6 +20,12 @@ namespace srsue { +class mac_nr_interface_demux +{ +public: + virtual bool received_contention_id(uint64_t id) = 0; +}; + /** * @brief Logical Channel Demultiplexing and MAC CE dissassemble according to TS 38.321 * @@ -36,25 +42,26 @@ public: demux_nr(srslog::basic_logger& logger_); ~demux_nr(); - int32_t init(rlc_interface_mac* rlc_, phy_interface_mac_nr* phy_); + int32_t init(rlc_interface_mac* rlc_, phy_interface_mac_nr* phy_, mac_nr_interface_demux* mac_); void process_pdus(); /// Called by MAC to process received PDUs // HARQ interface - void push_bcch(srsran::unique_byte_buffer_t pdu); - void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti); - void push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tti); - uint64_t get_received_crueid(); + void push_bcch(srsran::unique_byte_buffer_t pdu); + void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti); + void push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tti); + bool get_uecrid_successful(); private: // internal helpers void handle_pdu(srsran::mac_sch_pdu_nr& pdu_buffer, srsran::unique_byte_buffer_t pdu); - srslog::basic_logger& logger; - rlc_interface_mac* rlc = nullptr; - phy_interface_mac_nr* phy = nullptr; + srslog::basic_logger& logger; + rlc_interface_mac* rlc = nullptr; + phy_interface_mac_nr* phy = nullptr; + mac_nr_interface_demux* mac = nullptr; - uint64_t received_crueid = 0; + bool is_uecrid_successful = false; ///< currently only DCH & BCH PDUs supported (add PCH, etc) srsran::block_queue pdu_queue; diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h index 637d5ea41..8f503ba8e 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -39,7 +39,8 @@ class mac_nr final : public mac_interface_phy_nr, public mac_interface_proc_ra_nr, public mac_interface_sr_nr, public mac_interface_mux_nr, - public mac_interface_harq_nr + public mac_interface_harq_nr, + public mac_nr_interface_demux { public: mac_nr(srsran::ext_task_sched_handle task_sched_); @@ -88,7 +89,6 @@ public: void start_ra_procedure(); /// Interface for internal procedures (RA, MUX, HARQ) - bool received_contention_id(uint64_t rx_contention_id); uint16_t get_crnti(); uint16_t get_temp_crnti(); uint16_t get_csrnti() { return SRSRAN_INVALID_RNTI; }; // SPS not supported @@ -102,6 +102,9 @@ public: srsran::mac_sch_subpdu_nr::lcg_bsr_t generate_sbsr(); void set_padding_bytes(uint32_t nof_bytes); + /// Interface for DEMUX + bool received_contention_id(uint64_t rx_contention_id); + void msg3_flush() { mux.msg3_flush(); } bool msg3_is_transmitted() { return mux.msg3_is_transmitted(); } void msg3_prepare() { mux.msg3_prepare(); } diff --git a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h index 15f21b2dd..82b0adf31 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h +++ b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h @@ -24,8 +24,8 @@ class mac_interface_proc_ra_nr { public: // Functions for identity handling, e.g., contention id and c-rnti - virtual uint16_t get_crnti() = 0; - virtual bool set_crnti(uint16_t c_rnti) = 0; + virtual uint16_t get_crnti() = 0; + virtual bool set_crnti(uint16_t c_rnti) = 0; virtual void set_temp_crnti(uint16_t c_rnti) = 0; virtual void set_crnti_to_temp() = 0; @@ -81,9 +81,6 @@ public: // MAC also provides Temp C-RNTI (through RA proc) virtual uint16_t get_temp_crnti() = 0; - // HARQ can query MAC for current C-RNTI - virtual bool received_contention_id(uint64_t rx_contention_id) = 0; - // MAC provides the Currently Scheduled RNTI (for SPS) virtual uint16_t get_csrnti() = 0; }; @@ -95,10 +92,10 @@ class demux_interface_harq_nr { public: /// Inform demux unit about a newly decoded TB. - virtual void push_bcch(srsran::unique_byte_buffer_t pdu) = 0; - virtual void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti) = 0; - virtual void push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tti) = 0; - virtual uint64_t get_received_crueid() = 0; + virtual void push_bcch(srsran::unique_byte_buffer_t pdu) = 0; + virtual void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti) = 0; + virtual void push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tti) = 0; + virtual bool get_uecrid_successful() = 0; }; } // namespace srsue diff --git a/srsue/hdr/stack/mac_nr/proc_ra_nr.h b/srsue/hdr/stack/mac_nr/proc_ra_nr.h index 238c90bbe..44807c109 100644 --- a/srsue/hdr/stack/mac_nr/proc_ra_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_ra_nr.h @@ -113,7 +113,7 @@ private: void ra_resource_selection(); void ra_preamble_transmission(); void ra_response_reception(const mac_interface_phy_nr::tb_action_dl_result_t& tb); - void ra_contention_resolution(bool received_con_res_matches_ue_id); + void ra_contention_resolution(bool is_successful, bool is_ul_grant); void ra_completion(); void ra_error(); }; diff --git a/srsue/src/stack/mac_nr/demux_nr.cc b/srsue/src/stack/mac_nr/demux_nr.cc index f7adcfcf8..ee0fdf5d9 100644 --- a/srsue/src/stack/mac_nr/demux_nr.cc +++ b/srsue/src/stack/mac_nr/demux_nr.cc @@ -21,16 +21,17 @@ demux_nr::demux_nr(srslog::basic_logger& logger_) : logger(logger_) {} demux_nr::~demux_nr() {} -int32_t demux_nr::init(rlc_interface_mac* rlc_, phy_interface_mac_nr* phy_) +int32_t demux_nr::init(rlc_interface_mac* rlc_, phy_interface_mac_nr* phy_, mac_nr_interface_demux* mac_) { rlc = rlc_; phy = phy_; + mac = mac_; return SRSRAN_SUCCESS; } -uint64_t demux_nr::get_received_crueid() +bool demux_nr::get_uecrid_successful() { - return received_crueid; + return is_uecrid_successful; } // Enqueues PDU and returns quickly @@ -55,7 +56,7 @@ void demux_nr::push_bcch(srsran::unique_byte_buffer_t pdu) */ void demux_nr::push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tti) { - received_crueid = 0; + is_uecrid_successful = false; handle_pdu(rx_pdu_tcrnti, std::move(pdu)); } @@ -90,6 +91,7 @@ void demux_nr::handle_pdu(srsran::mac_sch_pdu_nr& pdu_buffer, srsran::unique_byt logger.info("%s", srsran::to_c_str(str_buffer)); } + bool con_res_rxed = false; for (uint32_t i = 0; i < pdu_buffer.get_num_subpdus(); ++i) { srsran::mac_sch_subpdu_nr subpdu = pdu_buffer.get_subpdu(i); logger.debug("Handling subPDU %d/%d: rnti=0x%x lcid=%d, sdu_len=%d", @@ -99,7 +101,7 @@ void demux_nr::handle_pdu(srsran::mac_sch_pdu_nr& pdu_buffer, srsran::unique_byt subpdu.get_lcid(), subpdu.get_sdu_length()); - // Handle Timing Advance CE + // Handle Contention Resolution UE ID and Timing Advance CE switch (subpdu.get_lcid()) { case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::DRX_CMD: logger.info("DRX CE not implemented."); @@ -109,12 +111,17 @@ void demux_nr::handle_pdu(srsran::mac_sch_pdu_nr& pdu_buffer, srsran::unique_byt phy->set_timeadv(0, subpdu.get_ta().ta_command); break; case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CON_RES_ID: - received_crueid = subpdu.get_ue_con_res_id_ce_packed(); + con_res_rxed = true; logger.info("Received Contention Resolution ID 0x%lx", subpdu.get_ue_con_res_id_ce_packed()); + if (!is_uecrid_successful) { + is_uecrid_successful = mac->received_contention_id(subpdu.get_ue_con_res_id_ce_packed()); + } break; default: - if (subpdu.is_sdu()) { - rlc->write_pdu(subpdu.get_lcid(), subpdu.get_sdu(), subpdu.get_sdu_length()); + if (!con_res_rxed or (con_res_rxed and is_uecrid_successful)) { + if (subpdu.is_sdu()) { + rlc->write_pdu(subpdu.get_lcid(), subpdu.get_sdu(), subpdu.get_sdu_length()); + } } } } diff --git a/srsue/src/stack/mac_nr/dl_harq_nr.cc b/srsue/src/stack/mac_nr/dl_harq_nr.cc index 68f077fc9..cf3e0fd27 100644 --- a/srsue/src/stack/mac_nr/dl_harq_nr.cc +++ b/srsue/src/stack/mac_nr/dl_harq_nr.cc @@ -235,7 +235,10 @@ void dl_harq_entity_nr::dl_harq_process_nr::tb_decoded(const mac_nr_grant_dl_t& logger.debug("Delivering PDU=%d bytes to Dissassemble and Demux unit (Temporal C-RNTI) not implemented", grant.tbs); harq_entity->demux_unit->push_pdu_temp_crnti(std::move(result.payload), grant.tti); - result.ack = harq_entity->mac->received_contention_id(harq_entity->demux_unit->get_received_crueid()); + result.ack = harq_entity->demux_unit->get_uecrid_successful(); + if (not result.ack) { + reset(); + } } else { logger.debug("Delivering PDU=%d bytes to Dissassemble and Demux unit", grant.tbs); harq_entity->demux_unit->push_pdu(std::move(result.payload), grant.tti); diff --git a/srsue/src/stack/mac_nr/mac_nr.cc b/srsue/src/stack/mac_nr/mac_nr.cc index e9c4a3b23..4481c96b1 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -65,7 +65,7 @@ int mac_nr::init(const mac_nr_args_t& args_, return SRSRAN_ERROR; } - if (demux.init(rlc, phy) != SRSRAN_SUCCESS) { + if (demux.init(rlc, phy, this) != SRSRAN_SUCCESS) { logger.error("Couldn't initialize demux unit."); return SRSRAN_ERROR; } @@ -349,11 +349,6 @@ void mac_nr::tb_decoded(const uint32_t cc_idx, const mac_nr_grant_dl_t& grant, t dl_harq.at(cc_idx)->tb_decoded(grant, std::move(result)); } - - // If proc ra is in contention resolution (RA connection request procedure) - if (proc_ra.is_contention_resolution() && grant.rnti == rntis.get_temp_rnti()) { - proc_ra.received_contention_resolution(contention_res_successful); - } } void mac_nr::new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, tb_action_ul_t* action) @@ -566,6 +561,7 @@ void mac_nr::process_pdus() bool mac_nr::received_contention_id(uint64_t rx_contention_id) { contention_res_successful = rntis.get_contention_id() == rx_contention_id; + proc_ra.received_contention_resolution(contention_res_successful); return contention_res_successful; } diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index 34a7710bb..c56923fdf 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -122,7 +122,7 @@ bool proc_ra_nr::has_rar_rnti() void proc_ra_nr::received_contention_resolution(bool is_successful) { std::lock_guard lock(mutex); - ra_contention_resolution(is_successful); + ra_contention_resolution(is_successful, false); } void proc_ra_nr::timer_expired(uint32_t timer_id) @@ -196,8 +196,6 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_ return; } - // Stop rar timer - rar_timeout_timer.stop(); if (tb.ack && tb.payload != nullptr) { srsran::mac_rar_pdu_nr pdu; if (!pdu.unpack(tb.payload->msg, tb.payload->N_bytes)) { @@ -211,6 +209,9 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_ for (auto& subpdu : pdu.get_subpdus()) { if (subpdu.has_rapid() && subpdu.get_rapid() == preamble_index) { + // Stop rar timer + rar_timeout_timer.stop(); + logger.debug("PROC RA NR: Setting UL grant and prepare Msg3"); mac.set_temp_crnti(subpdu.get_temp_crnti()); @@ -231,18 +232,20 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_ } else { preamble_backoff = 0; } + + contention_resolution_timer.set(rach_cfg.ra_ContentionResolutionTimer, + [this](uint32_t tid) { timer_expired(tid); }); + contention_resolution_timer.run(); + logger.debug("Waiting for Contention Resolution"); + state = WAITING_FOR_CONTENTION_RESOLUTION; } } } - contention_resolution_timer.set(rach_cfg.ra_ContentionResolutionTimer, [this](uint32_t tid) { timer_expired(tid); }); - contention_resolution_timer.run(); - logger.debug("Waiting for Contention Resolution"); - state = WAITING_FOR_CONTENTION_RESOLUTION; } // TS 38.321 Section 5.1.5 2 ways to resolve contention resolution // if the C-RNTI MAC CE was included in Msg3: (only this one is implemented) -void proc_ra_nr::ra_contention_resolution(bool received_con_res_matches_ue_id) +void proc_ra_nr::ra_contention_resolution(bool is_successful, bool is_ul_grant) { if (state != WAITING_FOR_CONTENTION_RESOLUTION) { logger.warning( @@ -251,15 +254,20 @@ void proc_ra_nr::ra_contention_resolution(bool received_con_res_matches_ue_id) srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, WAITING_FOR_CONTENTION_RESOLUTION)); return; } - if (started_by == initiators_t::RRC || started_by == initiators_t::MAC || received_con_res_matches_ue_id) { - if (received_con_res_matches_ue_id) { - logger.info("Received CONRES ID matches transmitted UE ID"); + if (started_by == initiators_t::RRC || started_by == initiators_t::MAC || is_successful) { + if (is_successful) { + if (is_ul_grant) { + logger.info("PDCCH to C-RNTI received with a new UL grant of transmission"); + } else { + logger.info("Received CONRES ID matches transmitted UE ID"); + } + contention_resolution_timer.stop(); + state = WAITING_FOR_COMPLETION; + ra_completion(); } else { - logger.info("PDCCH to C-RNTI received with a new UL grant of transmission"); + logger.info("Received CONRES ID DOES NOT match transmitted UE ID"); + mac.set_temp_crnti(SRSRAN_INVALID_RNTI); } - contention_resolution_timer.stop(); - state = WAITING_FOR_COMPLETION; - ra_completion(); } else { logger.error("Not started by the correct initiator MAC or RRC"); } @@ -375,7 +383,7 @@ void proc_ra_nr::handle_rar_pdu(mac_interface_phy_nr::tb_action_dl_result_t& res // Called from PHY thread, defer actions therefore. void proc_ra_nr::pdcch_to_crnti() { - task_queue.push([this]() { ra_contention_resolution(false); }); + task_queue.push([this]() { ra_contention_resolution(true, true); }); } bool proc_ra_nr::is_contention_resolution()