diff --git a/lib/include/srsran/interfaces/mac_interface_types.h b/lib/include/srsran/interfaces/mac_interface_types.h index 1e15f136ca..b5d79c29c8 100644 --- a/lib/include/srsran/interfaces/mac_interface_types.h +++ b/lib/include/srsran/interfaces/mac_interface_types.h @@ -140,6 +140,7 @@ struct rach_cfg_nr_t { uint32_t powerRampingStep; uint32_t ra_responseWindow; uint32_t ra_ContentionResolutionTimer; + uint32_t nof_preambles; rach_cfg_nr_t() { reset(); } void reset() @@ -149,6 +150,7 @@ struct rach_cfg_nr_t { powerRampingStep = 0; preambleTransMax = 0; ra_responseWindow = 0; + nof_preambles = 0; } }; diff --git a/lib/src/asn1/rrc_nr_utils.cc b/lib/src/asn1/rrc_nr_utils.cc index b2f9d104fa..d552d890b7 100644 --- a/lib/src/asn1/rrc_nr_utils.cc +++ b/lib/src/asn1/rrc_nr_utils.cc @@ -106,6 +106,10 @@ void make_mac_rach_cfg(const rach_cfg_common_s& asn1_type, rach_cfg_nr_t* rach_c rach_cfg_nr->PreambleReceivedTargetPower = asn1_type.rach_cfg_generic.preamb_rx_target_pwr; rach_cfg_nr->preambleTransMax = asn1_type.rach_cfg_generic.preamb_trans_max.to_number(); rach_cfg_nr->ra_ContentionResolutionTimer = asn1_type.ra_contention_resolution_timer.to_number(); + + if (asn1_type.total_nof_ra_preambs_present) { + rach_cfg_nr->nof_preambles = asn1_type.total_nof_ra_preambs; + } }; int make_rlc_config_t(const rlc_cfg_c& asn1_type, uint8_t bearer_id, rlc_config_t* cfg_out) diff --git a/lib/src/mac/mac_rar_pdu_nr.cc b/lib/src/mac/mac_rar_pdu_nr.cc index ecfd056419..5074227304 100644 --- a/lib/src/mac/mac_rar_pdu_nr.cc +++ b/lib/src/mac/mac_rar_pdu_nr.cc @@ -290,22 +290,24 @@ bool mac_rar_pdu_nr::unpack(const uint8_t* payload, const uint32_t& len) bool ret = false; bool have_more_subpdus = false; uint32_t offset = 0; + bool success = false; remaining_len = len; do { mac_rar_subpdu_nr rar_subpdu(this); - ret = rar_subpdu.read_subpdu(payload + offset); + success = rar_subpdu.read_subpdu(payload + offset); have_more_subpdus = rar_subpdu.has_more_subpdus(); offset += rar_subpdu.get_total_length(); remaining_len -= rar_subpdu.get_total_length(); // only append if subPDU could be read successfully - if (ret == true) { + if (success == true) { subpdus.push_back(rar_subpdu); } + ret |= success; // continue reading as long as subPDUs can be extracted ok and we are not overrunning the PDU length - } while (ret && have_more_subpdus && offset <= len); + } while (success && have_more_subpdus && offset <= len); return ret; } diff --git a/srsue/hdr/stack/mac_nr/demux_nr.h b/srsue/hdr/stack/mac_nr/demux_nr.h index 5a579902d1..d45e4675da 100644 --- a/srsue/hdr/stack/mac_nr/demux_nr.h +++ b/srsue/hdr/stack/mac_nr/demux_nr.h @@ -29,6 +29,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 * @@ -45,25 +51,26 @@ class demux_nr : public demux_interface_harq_nr 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 27577eaa1c..5223bd0d83 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -48,7 +48,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_); @@ -97,7 +98,6 @@ class mac_nr final : public mac_interface_phy_nr, 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 @@ -111,6 +111,9 @@ class mac_nr final : public mac_interface_phy_nr, 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 d9f20d9afa..a7d8da8c47 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h +++ b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h @@ -33,8 +33,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; @@ -90,9 +90,6 @@ class mac_interface_harq_nr // 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; }; @@ -104,10 +101,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/mux_nr.h b/srsue/hdr/stack/mac_nr/mux_nr.h index 0e99bc4bfd..bc034dc428 100644 --- a/srsue/hdr/stack/mac_nr/mux_nr.h +++ b/srsue/hdr/stack/mac_nr/mux_nr.h @@ -48,6 +48,7 @@ class mux_nr final : mux_base, public mux_interface_bsr_nr bool msg3_is_transmitted(); bool msg3_is_pending(); bool msg3_is_empty(); + srsran::unique_byte_buffer_t get_msg3(uint32_t max_pdu_len); // MAC interface int setup_lcid(const srsran::logical_channel_config_t& config); @@ -60,6 +61,7 @@ class mux_nr final : mux_base, public mux_interface_bsr_nr private: // internal helper methods + srsran::unique_byte_buffer_t pdu_get_nolock(uint32_t max_pdu_len); // ctor configured members mac_interface_mux_nr& mac; diff --git a/srsue/hdr/stack/mac_nr/proc_ra_nr.h b/srsue/hdr/stack/mac_nr/proc_ra_nr.h index 252fba994b..37338df42c 100644 --- a/srsue/hdr/stack/mac_nr/proc_ra_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_ra_nr.h @@ -38,7 +38,7 @@ class proc_ra_nr { public: proc_ra_nr(mac_interface_proc_ra_nr& mac_, srslog::basic_logger& logger_); - ~proc_ra_nr(){}; + ~proc_ra_nr() { srsran_random_free(random_gen); }; void init(phy_interface_mac_nr* phy_h_, srsran::ext_task_sched_handle* task_sched_); void set_config(const srsran::rach_cfg_nr_t& rach_cfg_nr); @@ -66,8 +66,10 @@ class proc_ra_nr 16 * 10; ///< Limited from frame system number opportunity period in TS 38.211 tables 6.3.3.2-2, 6.3.3.2-3 ///< and 6.3.3.2-4 - mac_interface_proc_ra_nr& mac; - srslog::basic_logger& logger; + mac_interface_proc_ra_nr& mac; + srslog::basic_logger& logger; + srsran_random_t random_gen; + phy_interface_mac_nr* phy = nullptr; srsran::ext_task_sched_handle* task_sched = nullptr; srsran::task_multiqueue::queue_handle task_queue; @@ -120,7 +122,7 @@ class proc_ra_nr 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/hdr/stack/rrc_nr/rrc_nr.h b/srsue/hdr/stack/rrc_nr/rrc_nr.h index 80e8936193..09ca1e5006 100644 --- a/srsue/hdr/stack/rrc_nr/rrc_nr.h +++ b/srsue/hdr/stack/rrc_nr/rrc_nr.h @@ -175,6 +175,8 @@ class rrc_nr final : public rrc_interface_phy_nr, bool running = false; srsran::block_queue cmd_q; + srsran_random_t random_gen; + // PHY config srsran::phy_cfg_nr_t phy_cfg = {}; diff --git a/srsue/src/phy/nr/cc_worker.cc b/srsue/src/phy/nr/cc_worker.cc index 4c69d5dc52..46e059054e 100644 --- a/srsue/src/phy/nr/cc_worker.cc +++ b/srsue/src/phy/nr/cc_worker.cc @@ -247,6 +247,11 @@ bool cc_worker::decode_pdsch_dl() mac_dl_grant.tti = dl_slot_cfg.idx; phy.stack->new_grant_dl(0, mac_dl_grant, &dl_action); + // check if RA-RNTI, if true reset HARQ buffers + if (pdsch_cfg.grant.rnti_type == srsran_rnti_type_ra && dl_action.tb.softbuffer != nullptr) { + srsran_softbuffer_rx_reset(dl_action.tb.softbuffer); + } + // Abort if MAC says it doesn't need the TB if (not dl_action.tb.enabled) { // Force positive ACK diff --git a/srsue/src/stack/mac_nr/demux_nr.cc b/srsue/src/stack/mac_nr/demux_nr.cc index d691dc5f27..4d4dcf3137 100644 --- a/srsue/src/stack/mac_nr/demux_nr.cc +++ b/srsue/src/stack/mac_nr/demux_nr.cc @@ -30,16 +30,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 @@ -64,7 +65,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)); } @@ -99,6 +100,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", @@ -108,7 +110,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."); @@ -118,12 +120,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 ee3e172c65..5a5a93882c 100644 --- a/srsue/src/stack/mac_nr/dl_harq_nr.cc +++ b/srsue/src/stack/mac_nr/dl_harq_nr.cc @@ -244,7 +244,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 5de14005a8..2b7f2e1e5a 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -74,7 +74,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; } @@ -358,11 +358,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) @@ -575,6 +570,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/mux_nr.cc b/srsue/src/stack/mac_nr/mux_nr.cc index 78eef7ee58..221c8518ae 100644 --- a/srsue/src/stack/mac_nr/mux_nr.cc +++ b/srsue/src/stack/mac_nr/mux_nr.cc @@ -56,11 +56,8 @@ int mux_nr::setup_lcid(const srsran::logical_channel_config_t& config) return mux_base::setup_lcid(config); } -srsran::unique_byte_buffer_t mux_nr::get_pdu(uint32_t max_pdu_len) +srsran::unique_byte_buffer_t mux_nr::pdu_get_nolock(uint32_t max_pdu_len) { - // Lock MAC PDU from current access from PHY workers (will be moved to UL HARQ) - std::lock_guard lock(mutex); - // initialize MAC PDU srsran::unique_byte_buffer_t phy_tx_pdu = srsran::make_byte_buffer(); if (phy_tx_pdu == nullptr) { @@ -199,6 +196,35 @@ bool mux_nr::msg3_is_empty() return msg3_buff->N_bytes == 0; } +srsran::unique_byte_buffer_t mux_nr::get_pdu(uint32_t max_pdu_len) +{ + // Lock MAC PDU from current access from PHY workers (will be moved to UL HARQ) + std::lock_guard lock(mutex); + return pdu_get_nolock(max_pdu_len); +} + +srsran::unique_byte_buffer_t mux_nr::get_msg3(uint32_t max_pdu_len) +{ + // Lock MAC PDU from current access from PHY workers (will be moved to UL HARQ) + std::lock_guard lock(mutex); + srsran::unique_byte_buffer_t phy_tx_pdu = srsran::make_byte_buffer(); + + if (max_pdu_len < msg3_buff->get_tailroom()) { + if (msg3_is_empty()) { + msg3_buff = pdu_get_nolock(max_pdu_len); + if (msg3_buff == nullptr) { + logger.error("Moving PDU from Mux unit to Msg3 buffer"); + return NULL; + } + } + *phy_tx_pdu = *msg3_buff; + return phy_tx_pdu; + } else { + logger.error("Msg3 size exceeds buffer"); + return nullptr; + } +} + void mux_nr::generate_bsr_mac_ce(const srsran::bsr_format_nr_t& format) { switch (format) { diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index f94489d81d..7e327d9eb1 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -50,6 +50,10 @@ void proc_ra_nr::init(phy_interface_mac_nr* phy_, srsran::ext_task_sched_handle* rar_timeout_timer = task_sched->get_unique_timer(); contention_resolution_timer = task_sched->get_unique_timer(); backoff_timer = task_sched->get_unique_timer(); + + struct timeval tv; + gettimeofday(&tv, NULL); + random_gen = srsran_random_init(tv.tv_usec); } /* Sets a new configuration. The configuration is applied by initialization() function */ @@ -127,7 +131,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) @@ -175,7 +179,11 @@ void proc_ra_nr::ra_preamble_transmission() preamble_received_target_power = rach_cfg.PreambleReceivedTargetPower + delta_preamble + (preamble_transmission_counter - 1) * rach_cfg.powerRampingStep + power_offset_2step_ra; - preamble_index = 0; + if (rach_cfg.nof_preambles) { + preamble_index = srsran_random_uniform_int_dist(random_gen, 0, rach_cfg.nof_preambles); + } else { + preamble_index = 0; + } prach_occasion = 0; // instruct the physical layer to transmit the Random Access Preamble using the selected PRACH occasion, corresponding // RA-RNTI (if available), PREAMBLE_INDEX, and PREAMBLE_RECEIVED_TARGET_POWER. @@ -197,8 +205,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)) { @@ -212,6 +218,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()); @@ -232,18 +241,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( @@ -252,15 +263,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"); } @@ -376,7 +392,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() diff --git a/srsue/src/stack/mac_nr/ul_harq_nr.cc b/srsue/src/stack/mac_nr/ul_harq_nr.cc index 4b1963c7dd..b0331237d5 100644 --- a/srsue/src/stack/mac_nr/ul_harq_nr.cc +++ b/srsue/src/stack/mac_nr/ul_harq_nr.cc @@ -198,8 +198,13 @@ void ul_harq_entity_nr::ul_harq_process_nr::new_grant_ul(const mac_interface_phy ) { // new transmission - // generate new PDU (Msg3 or normal UL) - harq_buffer = harq_entity->mux->get_pdu(grant.tbs); + if (grant.is_rar_grant) { + // generate new PDU (Msg3) + harq_buffer = harq_entity->mux->get_msg3(grant.tbs); + } else { + // generate new PDU (normal UL) + harq_buffer = harq_entity->mux->get_pdu(grant.tbs); + } // 3> if a MAC PDU to transmit has been obtained if (harq_buffer != nullptr) { diff --git a/srsue/src/stack/rrc_nr/rrc_nr.cc b/srsue/src/stack/rrc_nr/rrc_nr.cc index 325ee70adb..f1cc386294 100644 --- a/srsue/src/stack/rrc_nr/rrc_nr.cc +++ b/srsue/src/stack/rrc_nr/rrc_nr.cc @@ -45,10 +45,16 @@ rrc_nr::rrc_nr(srsran::task_sched_handle task_sched_) : cell_selector(*this), meas_cells(task_sched_) { + struct timeval tv; + gettimeofday(&tv, NULL); + random_gen = srsran_random_init(tv.tv_usec); set_phy_default_config(); } -rrc_nr::~rrc_nr() = default; +rrc_nr::~rrc_nr() +{ + srsran_random_free(random_gen); +} int rrc_nr::init(phy_interface_rrc_nr* phy_, mac_interface_rrc_nr* mac_, @@ -610,8 +616,7 @@ void rrc_nr::send_setup_request(srsran::nr_establishment_cause_t cause) // TODO: implement ng_minus5_g_s_tmsi_part1 rrc_setup_req->ue_id.set_random_value(); - // TODO use proper RNG - uint64_t random_id = 0; + uint64_t random_id = srsran_random_uniform_int_dist(random_gen, 0, 12345); for (uint i = 0; i < 5; i++) { // fill random ID bytewise, 40 bits = 5 bytes random_id |= ((uint64_t)rand() & 0xFF) << i * 8; }