diff --git a/lib/include/srsran/mac/mac_sch_pdu_nr.h b/lib/include/srsran/mac/mac_sch_pdu_nr.h index 6264a8ec2..9229df5a3 100644 --- a/lib/include/srsran/mac/mac_sch_pdu_nr.h +++ b/lib/include/srsran/mac/mac_sch_pdu_nr.h @@ -98,6 +98,7 @@ public: static const uint8_t ue_con_res_id_len = 6; typedef std::array ue_con_res_id_t; ue_con_res_id_t get_ue_con_res_id_ce(); + uint64_t get_ue_con_res_id_ce_packed(); // setters void set_sdu(const uint32_t lcid_, const uint8_t* payload_, const uint32_t len_); diff --git a/lib/src/mac/mac_sch_pdu_nr.cc b/lib/src/mac/mac_sch_pdu_nr.cc index ba93f8024..b606e9d38 100644 --- a/lib/src/mac/mac_sch_pdu_nr.cc +++ b/lib/src/mac/mac_sch_pdu_nr.cc @@ -332,6 +332,17 @@ mac_sch_subpdu_nr::ue_con_res_id_t mac_sch_subpdu_nr::get_ue_con_res_id_ce() return id; } +uint64_t mac_sch_subpdu_nr::get_ue_con_res_id_ce_packed() +{ + if (!parent->is_ulsch() && lcid == CON_RES_ID) { + const uint8_t* payload = sdu.ptr(); + return le64toh(((uint64_t)payload[5]) | (((uint64_t)payload[4]) << 8) | (((uint64_t)payload[3]) << 16) | + (((uint64_t)payload[2]) << 24) | (((uint64_t)payload[1]) << 32) | (((uint64_t)payload[0]) << 40)); + } else { + return 0; + } +} + uint32_t mac_sch_subpdu_nr::sizeof_ce(uint32_t lcid, bool is_ul) { if (is_ul) { diff --git a/srsue/hdr/stack/mac_nr/demux_nr.h b/srsue/hdr/stack/mac_nr/demux_nr.h index 533a4b616..aae7259e1 100644 --- a/srsue/hdr/stack/mac_nr/demux_nr.h +++ b/srsue/hdr/stack/mac_nr/demux_nr.h @@ -40,19 +40,24 @@ public: void process_pdus(); /// Called by MAC to process received PDUs // HARQ interface - void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti); + 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(); private: // internal helpers - void handle_pdu(srsran::unique_byte_buffer_t pdu); + 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; + uint64_t received_crueid = 0; + ///< currently only DCH PDUs supported (add BCH, PCH, etc) srsran::block_queue pdu_queue; srsran::mac_sch_pdu_nr rx_pdu; + srsran::mac_sch_pdu_nr rx_pdu_tcrnti; }; } // namespace srsue diff --git a/srsue/hdr/stack/mac_nr/mac_nr.h b/srsue/hdr/stack/mac_nr/mac_nr.h index 9eb944b1a..415b64ca6 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr.h +++ b/srsue/hdr/stack/mac_nr/mac_nr.h @@ -88,7 +88,7 @@ public: void start_ra_procedure(); /// Interface for internal procedures (RA, MUX, HARQ) - uint64_t get_contention_id(); + 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 @@ -150,6 +150,7 @@ private: std::atomic started = {false}; ue_rnti rntis; // thread-safe helper to store RNTIs, contention ID, etc + bool contention_res_successful; std::array metrics = {}; diff --git a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h index 6421dcd7d..b894e6509 100644 --- a/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h +++ b/srsue/hdr/stack/mac_nr/mac_nr_interfaces.h @@ -24,7 +24,6 @@ class mac_interface_proc_ra_nr { public: // Functions for identity handling, e.g., contention id and c-rnti - virtual uint64_t get_contention_id() = 0; virtual uint16_t get_crnti() = 0; virtual bool set_crnti(uint16_t c_rnti) = 0; @@ -80,6 +79,9 @@ 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; }; @@ -91,7 +93,9 @@ class demux_interface_harq_nr { public: /// Inform demux unit about a newly decoded TB. - virtual void push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti) = 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; }; } // 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 0e8ee707f..bf3fdb3b5 100644 --- a/srsue/hdr/stack/mac_nr/proc_ra_nr.h +++ b/srsue/hdr/stack/mac_nr/proc_ra_nr.h @@ -40,6 +40,7 @@ public: uint16_t get_rar_rnti(); bool has_temp_crnti(); uint16_t get_temp_crnti(); + void received_contention_resolution(bool is_successful); // PHY interfaces void prach_sent(uint32_t tti, uint32_t s_id, uint32_t t_id, uint32_t f_id, uint32_t ul_carrier_id); @@ -64,6 +65,7 @@ private: int ra_window_length = -1, ra_window_start = -1; uint16_t rar_rnti = SRSRAN_INVALID_RNTI; uint16_t temp_crnti = SRSRAN_INVALID_RNTI; + uint16_t transmitted_crnti = SRSRAN_INVALID_RNTI; std::mutex mutex; srsran::rach_nr_cfg_t rach_cfg = {}; @@ -110,8 +112,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(); - void ra_contention_resolution(uint64_t rx_contention_id); + void ra_contention_resolution(bool received_con_res_matches_ue_id); void ra_completion(); void ra_error(); }; diff --git a/srsue/src/phy/sync_sa.cc b/srsue/src/phy/sync_sa.cc index 022ffe5a4..e554a05a1 100644 --- a/srsue/src/phy/sync_sa.cc +++ b/srsue/src/phy/sync_sa.cc @@ -225,8 +225,6 @@ void sync_sa::run_state_cell_select() void sync_sa::run_state_cell_camping() { - last_rx_time.add(FDD_HARQ_DELAY_DL_MS * 1e-3); - nr::sf_worker* nr_worker = nullptr; nr_worker = workers.wait_worker(tti); if (nr_worker == nullptr) { @@ -242,12 +240,11 @@ void sync_sa::run_state_cell_camping() logger.error("SYNC: receiving from radio\n"); } - printf("sync_tti=%d, power=%f\n", tti, srsran_vec_avg_power_cf(rf_buffer.get(0), 11520)); - srsran::phy_common_interface::worker_context_t context; context.sf_idx = tti; context.worker_ptr = nr_worker; context.last = true; // Set last if standalone + last_rx_time.add(FDD_HARQ_DELAY_DL_MS * 1e-3); context.tx_time.copy(last_rx_time); nr_worker->set_context(context); @@ -302,9 +299,7 @@ void sync_sa::worker_end(const srsran::phy_common_interface::worker_context_t& w // Check if any worker had a transmission if (tx_enable) { // Actual baseband transmission -#ifdef useradio radio->tx(tx_buffer, tx_time); -#endif } else { if (radio->is_continuous_tx()) { if (is_pending_tx_end) { diff --git a/srsue/src/stack/mac_nr/demux_nr.cc b/srsue/src/stack/mac_nr/demux_nr.cc index 62e7cb7f0..f13780257 100644 --- a/srsue/src/stack/mac_nr/demux_nr.cc +++ b/srsue/src/stack/mac_nr/demux_nr.cc @@ -27,41 +27,61 @@ int32_t demux_nr::init(rlc_interface_mac* rlc_) return SRSRAN_SUCCESS; } +uint64_t demux_nr::get_received_crueid() +{ + return received_crueid; +} + // Enqueues PDU and returns quickly void demux_nr::push_pdu(srsran::unique_byte_buffer_t pdu, uint32_t tti) { pdu_queue.push(std::move(pdu)); } +/* Demultiplexing of MAC PDU associated with a Temporal C-RNTI. The PDU will + * remain in buffer until demultiplex_pending_pdu() is called. + * This features is provided to enable the Random Access Procedure to decide + * whether the PDU shall pass to upper layers or not, which depends on the + * Contention Resolution result. + * + * Warning: this function does some processing here assuming ACK deadline is not an + * issue here because Temp C-RNTI messages have small payloads + */ +void demux_nr::push_pdu_temp_crnti(srsran::unique_byte_buffer_t pdu, uint32_t tti) +{ + received_crueid = 0; + handle_pdu(rx_pdu_tcrnti, std::move(pdu)); +} + void demux_nr::process_pdus() { while (not pdu_queue.empty()) { srsran::unique_byte_buffer_t pdu = pdu_queue.wait_pop(); - handle_pdu(std::move(pdu)); + handle_pdu(rx_pdu, std::move(pdu)); } } /// Handling of DLSCH PDUs only -void demux_nr::handle_pdu(srsran::unique_byte_buffer_t pdu) +void demux_nr::handle_pdu(srsran::mac_sch_pdu_nr& pdu_buffer, srsran::unique_byte_buffer_t pdu) { logger.debug(pdu->msg, pdu->N_bytes, "Handling MAC PDU (%d B)", pdu->N_bytes); - rx_pdu.init_rx(); - if (rx_pdu.unpack(pdu->msg, pdu->N_bytes) != SRSRAN_SUCCESS) { + pdu_buffer.init_rx(); + if (pdu_buffer.unpack(pdu->msg, pdu->N_bytes) != SRSRAN_SUCCESS) { return; } if (logger.info.enabled()) { fmt::memory_buffer str_buffer; - rx_pdu.to_string(str_buffer); + pdu_buffer.to_string(str_buffer); logger.info("%s", srsran::to_c_str(str_buffer)); } - for (uint32_t i = 0; i < rx_pdu.get_num_subpdus(); ++i) { - srsran::mac_sch_subpdu_nr subpdu = rx_pdu.get_subpdu(i); + 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", i + 1, - rx_pdu.get_num_subpdus(), + pdu_buffer.get_num_subpdus(), subpdu.get_c_rnti(), subpdu.get_lcid(), subpdu.get_sdu_length()); @@ -75,7 +95,8 @@ void demux_nr::handle_pdu(srsran::unique_byte_buffer_t pdu) logger.info("Timing Advance CE not implemented."); break; case srsran::mac_sch_subpdu_nr::nr_lcid_sch_t::CON_RES_ID: - logger.info("Contention Resolution CE not implemented."); + received_crueid = subpdu.get_ue_con_res_id_ce_packed(); + logger.info("Received Contention Resolution ID 0x%lx\n", subpdu.get_ue_con_res_id_ce_packed()); break; default: if (subpdu.is_sdu()) { diff --git a/srsue/src/stack/mac_nr/dl_harq_nr.cc b/srsue/src/stack/mac_nr/dl_harq_nr.cc index b1bfd9d70..174fdf26f 100644 --- a/srsue/src/stack/mac_nr/dl_harq_nr.cc +++ b/srsue/src/stack/mac_nr/dl_harq_nr.cc @@ -225,6 +225,8 @@ void dl_harq_entity_nr::dl_harq_process_nr::tb_decoded(const mac_nr_grant_dl_t& if (grant.rnti == harq_entity->mac->get_temp_crnti()) { 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()); } 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 7cf4c3ea7..84acec2ce 100644 --- a/srsue/src/stack/mac_nr/mac_nr.cc +++ b/srsue/src/stack/mac_nr/mac_nr.cc @@ -321,6 +321,11 @@ 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 == get_temp_crnti()) { + 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) @@ -338,7 +343,7 @@ void mac_nr::new_grant_ul(const uint32_t cc_idx, const mac_nr_grant_ul_t& grant, // Clear UL action *action = {}; - // if proc ra is in contention resolution and c_rnti == grant.c_rnti resolve contention resolution + // if proc ra is in contention resolution and c_rnti == grant.c_rnti (RA connection resume procedure) if (proc_ra.is_contention_resolution() && grant.rnti == get_crnti()) { proc_ra.pdcch_to_crnti(); } @@ -525,9 +530,10 @@ void mac_nr::process_pdus() demux.process_pdus(); } -uint64_t mac_nr::get_contention_id() +bool mac_nr::received_contention_id(uint64_t rx_contention_id) { - return 0xdeadbeef; // TODO when rebased on PR + contention_res_successful = rntis.get_contention_id() == rx_contention_id; + return contention_res_successful; } // TODO same function as for mac_eutra diff --git a/srsue/src/stack/mac_nr/mux_nr.cc b/srsue/src/stack/mac_nr/mux_nr.cc index 3fd79f01f..24bea2afd 100644 --- a/srsue/src/stack/mac_nr/mux_nr.cc +++ b/srsue/src/stack/mac_nr/mux_nr.cc @@ -68,59 +68,60 @@ srsran::unique_byte_buffer_t mux_nr::get_pdu(uint32_t max_pdu_len) logger.debug("Building new MAC PDU (%d B)", max_pdu_len); tx_pdu.init_tx(phy_tx_pdu.get(), max_pdu_len, true); - if (msg3_is_pending()) { - // 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 + if (msg3_is_pending() && mac.has_crnti()) { msg3_transmitted(); - } else { - // Pack normal UL data PDU - 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 - remaining_len -= 2; - } - - // First add MAC SDUs - for (const auto& lc : logical_channels) { - // TODO: Add proper priority handling - logger.debug("Adding SDUs for LCID=%d (max %d B)", lc.lcid, remaining_len); - while (remaining_len >= MIN_RLC_PDU_LEN) { - // read RLC PDU - rlc_buff->clear(); - uint8_t* rd = rlc_buff->msg; + } - // Determine space for RLC - int32_t subpdu_header_len = (remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2); + // Pack normal UL data PDU + int32_t remaining_len = tx_pdu.get_remaing_len(); // local variable to reserve space for CEs - // Read PDU from RLC (account for subPDU header) - int pdu_len = rlc->read_pdu(lc.lcid, rd, remaining_len - subpdu_header_len); + if (add_bsr_ce == sbsr_ce) { + // reserve space for SBSR + remaining_len -= 2; + } - 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) { - rlc_buff->N_bytes = pdu_len; - logger.debug(rlc_buff->msg, rlc_buff->N_bytes, "Read %d B from RLC", rlc_buff->N_bytes); - - // add to MAC PDU and pack - if (tx_pdu.add_sdu(lc.lcid, rlc_buff->msg, rlc_buff->N_bytes) != SRSRAN_SUCCESS) { - logger.error("Error packing MAC PDU"); - break; - } - } else { - // couldn't read PDU from RLC + // First add MAC SDUs + for (const auto& lc : logical_channels) { + // TODO: Add proper priority handling + logger.debug("Adding SDUs for LCID=%d (max %d B)", lc.lcid, remaining_len); + while (remaining_len >= MIN_RLC_PDU_LEN) { + // read RLC PDU + rlc_buff->clear(); + uint8_t* rd = rlc_buff->msg; + + // Determine space for RLC + int32_t subpdu_header_len = (remaining_len >= srsran::mac_sch_subpdu_nr::MAC_SUBHEADER_LEN_THRESHOLD ? 3 : 2); + + // Read PDU from RLC (account for subPDU header) + int pdu_len = rlc->read_pdu(lc.lcid, rd, remaining_len - subpdu_header_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) { + rlc_buff->N_bytes = pdu_len; + logger.debug(rlc_buff->msg, rlc_buff->N_bytes, "Read %d B from RLC", rlc_buff->N_bytes); + + // add to MAC PDU and pack + if (tx_pdu.add_sdu(lc.lcid, rlc_buff->msg, rlc_buff->N_bytes) != SRSRAN_SUCCESS) { + logger.error("Error packing MAC PDU"); break; } - remaining_len -= (pdu_len + subpdu_header_len); - logger.debug("%d B remaining PDU", remaining_len); + if (lc.lcid == 0 && msg3_is_pending()) { + // TODO: + msg3_transmitted(); + } + + } else { + // couldn't read PDU from RLC + break; } + + remaining_len -= (pdu_len + subpdu_header_len); + logger.debug("%d B remaining PDU", remaining_len); } } } diff --git a/srsue/src/stack/mac_nr/proc_ra_nr.cc b/srsue/src/stack/mac_nr/proc_ra_nr.cc index 301845c6c..aad015b77 100644 --- a/srsue/src/stack/mac_nr/proc_ra_nr.cc +++ b/srsue/src/stack/mac_nr/proc_ra_nr.cc @@ -127,6 +127,12 @@ uint16_t proc_ra_nr::get_temp_crnti() return temp_crnti; } +void proc_ra_nr::received_contention_resolution(bool is_successful) +{ + std::lock_guard lock(mutex); + ra_contention_resolution(is_successful); +} + void proc_ra_nr::timer_expired(uint32_t timer_id) { if (prach_send_timer.id() == timer_id) { @@ -212,6 +218,9 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_ logger.debug("PROC RA NR: Setting UL grant and prepare Msg3"); temp_crnti = subpdu.get_temp_crnti(); + // Save transmitted C-RNTI (if any) + transmitted_crnti = mac.get_crnti(); + // Set Temporary-C-RNTI if provided, otherwise C-RNTI is ok phy->set_rar_grant(tb.rx_slot_idx, subpdu.get_ul_grant(), temp_crnti, srsran_rnti_type_ra); @@ -237,7 +246,7 @@ void proc_ra_nr::ra_response_reception(const mac_interface_phy_nr::tb_action_dl_ // 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() +void proc_ra_nr::ra_contention_resolution(bool received_con_res_matches_ue_id) { if (state != WAITING_FOR_CONTENTION_RESOLUTION) { logger.warning( @@ -246,8 +255,12 @@ void proc_ra_nr::ra_contention_resolution() 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) { - logger.info("PDCCH to C-RNTI received with a new UL grant of transmission"); + 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\n"); + } else { + logger.info("PDCCH to C-RNTI received with a new UL grant of transmission"); + } contention_resolution_timer.stop(); state = WAITING_FOR_COMPLETION; ra_completion(); @@ -256,22 +269,8 @@ void proc_ra_nr::ra_contention_resolution() } } -// or else if the CCCH SDU was included in Msg3 and the PDCCH transmission is addressed to its TEMPORARY_C-RNTI: -void proc_ra_nr::ra_contention_resolution(uint64_t rx_contention_id) -{ - if (state != WAITING_FOR_CONTENTION_RESOLUTION) { - logger.warning( - "Wrong state for ra contention resolution by phy %s (expected state %s)", - srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state), - srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, WAITING_FOR_CONTENTION_RESOLUTION)); - return; - } - // TODO -} - void proc_ra_nr::ra_completion() { - std::lock_guard lock(mutex); if (state != WAITING_FOR_COMPLETION) { logger.warning("Wrong state for ra completion by phy %s (expected state %s)", srsran::enum_to_text(state_str_nr, (uint32_t)ra_state_t::MAX_RA_STATES, state), @@ -280,6 +279,9 @@ void proc_ra_nr::ra_completion() } srsran::console("Random Access Complete. c-rnti=0x%x, ta=%d\n", mac.get_crnti(), current_ta); logger.info("Random Access Complete. c-rnti=0x%x, ta=%d", mac.get_crnti(), current_ta); + if (!transmitted_crnti) { + mac.set_crnti(temp_crnti); + } temp_crnti = SRSRAN_INVALID_RNTI; mac.rrc_ra_completed(); reset(); @@ -372,7 +374,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(); }); + task_queue.push([this]() { ra_contention_resolution(false); }); } bool proc_ra_nr::is_contention_resolution() @@ -387,6 +389,7 @@ void proc_ra_nr::reset() prach_send_timer.stop(); rar_timeout_timer.stop(); contention_resolution_timer.stop(); + transmitted_crnti = SRSRAN_INVALID_RNTI; } } // namespace srsue diff --git a/srsue/src/stack/rrc_nr/rrc_nr.cc b/srsue/src/stack/rrc_nr/rrc_nr.cc index 1ea42be79..85ba9a648 100644 --- a/srsue/src/stack/rrc_nr/rrc_nr.cc +++ b/srsue/src/stack/rrc_nr/rrc_nr.cc @@ -206,7 +206,10 @@ void rrc_nr::out_of_sync() {} void rrc_nr::run_tti(uint32_t tti) {} // PDCP interface -void rrc_nr::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) {} +void rrc_nr::write_pdu(uint32_t lcid, srsran::unique_byte_buffer_t pdu) +{ + printf("RRC received PDU\n"); +} void rrc_nr::write_pdu_bcch_bch(srsran::unique_byte_buffer_t pdu) {} void rrc_nr::write_pdu_bcch_dlsch(srsran::unique_byte_buffer_t pdu) {} void rrc_nr::write_pdu_pcch(srsran::unique_byte_buffer_t pdu) {} @@ -238,11 +241,86 @@ int rrc_nr::connection_request(srsran::nr_establishment_cause_t cause, srsran::u cfg.duplex = srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; phy_cfg = srsran::phy_cfg_nr_default_t{srsran::phy_cfg_nr_default_t::reference_cfg_t{cfg}}; + // Carrier configuration phy_cfg.ssb.periodicity_ms = 10; phy_cfg.carrier.ssb_center_freq_hz = 1842.05e6; phy_cfg.carrier.dl_center_frequency_hz = 1842.5e6; phy_cfg.carrier.ul_center_frequency_hz = 1747.5e6; + // PRACH configuration + phy_cfg.prach.num_ra_preambles = 8; + phy_cfg.prach.config_idx = 0; + phy_cfg.prach.root_seq_idx = 1; + phy_cfg.prach.zero_corr_zone = 0; + phy_cfg.prach.is_nr = true; + phy_cfg.prach.freq_offset = 1; + + srsran::rach_nr_cfg_t rach_cfg = {}; + rach_cfg.prach_ConfigurationIndex = 0; + rach_cfg.preambleTransMax = 7; + rach_cfg.ra_responseWindow = 10; + rach_cfg.ra_ContentionResolutionTimer = 64; + mac->set_config(rach_cfg); + + srsran::dl_harq_cfg_nr_t harq_cfg = {}; + harq_cfg.nof_procs = 8; + mac->set_config(harq_cfg); + + // Setup SRB0, 1 and 2 + for (int i = 0; i < 3; i++) { + logical_channel_config_t lch = {}; + lch.lcid = i; + lch.priority = i + 1; + mac->setup_lcid(lch); + } + + // Coreset0 configuration + // Get pointA and SSB absolute frequencies + double pointA_abs_freq_Hz = phy_cfg.carrier.dl_center_frequency_hz - + phy_cfg.carrier.nof_prb * SRSRAN_NRE * SRSRAN_SUBC_SPACING_NR(phy_cfg.carrier.scs) / 2; + double ssb_abs_freq_Hz = phy_cfg.carrier.ssb_center_freq_hz; + // Calculate integer SSB to pointA frequency offset in Hz + uint32_t ssb_pointA_freq_offset_Hz = + (ssb_abs_freq_Hz > pointA_abs_freq_Hz) ? (uint32_t)(ssb_abs_freq_Hz - pointA_abs_freq_Hz) : 0; + + if (srsran_coreset_zero(phy_cfg.carrier.pci, + ssb_pointA_freq_offset_Hz, + phy_cfg.ssb.scs, + phy_cfg.carrier.scs, + 6, + &phy_cfg.pdcch.coreset[0])) { + fprintf(stderr, "Error generating coreset0\n"); + } + phy_cfg.pdcch.coreset_present[0] = true; + + // RAR SS + phy_cfg.pdcch.ra_search_space_present = true; + phy_cfg.pdcch.ra_search_space.coreset_id = 0; + phy_cfg.pdcch.ra_search_space.duration = 1; + phy_cfg.pdcch.ra_search_space.type = srsran_search_space_type_common_1; + phy_cfg.pdcch.ra_search_space.nof_formats = 1; + phy_cfg.pdcch.ra_search_space.formats[1] = srsran_dci_format_nr_1_0; + phy_cfg.pdcch.ra_search_space.nof_candidates[0] = 0; + phy_cfg.pdcch.ra_search_space.nof_candidates[1] = 0; + phy_cfg.pdcch.ra_search_space.nof_candidates[2] = 1; + phy_cfg.pdcch.ra_search_space.nof_candidates[3] = 0; + phy_cfg.pdcch.ra_search_space.nof_candidates[4] = 0; + + // common1 SS + phy_cfg.pdcch.search_space_present[0] = true; + phy_cfg.pdcch.search_space[0].coreset_id = 0; + phy_cfg.pdcch.search_space[0].duration = 1; + phy_cfg.pdcch.search_space[0].nof_candidates[0] = 0; + phy_cfg.pdcch.search_space[0].nof_candidates[1] = 0; + phy_cfg.pdcch.search_space[0].nof_candidates[2] = 1; + phy_cfg.pdcch.search_space[0].nof_candidates[3] = 0; + phy_cfg.pdcch.search_space[0].nof_candidates[4] = 0; + phy_cfg.pdcch.search_space[0].type = srsran_search_space_type_common_1; + phy_cfg.pdcch.search_space[0].nof_formats = 2; + phy_cfg.pdcch.search_space[0].formats[0] = srsran_dci_format_nr_0_0; + phy_cfg.pdcch.search_space[0].formats[1] = srsran_dci_format_nr_1_0; + phy_cfg.pdcch.search_space_present[1] = false; + if (not setup_req_proc.launch(cause, std::move(dedicated_info_nas_))) { logger.error("Failed to initiate setup request procedure"); return SRSRAN_ERROR; @@ -1627,9 +1705,7 @@ void rrc_nr::protocol_failure() {} // MAC interface void rrc_nr::ra_completed() { - logger.info("RA completed. Applying remaining CSI configuration."); - phy->set_config(phy_cfg); - phy_cfg_state = PHY_CFG_STATE_RA_COMPLETED; + logger.info("RA completed"); } void rrc_nr::ra_problem() diff --git a/srsue/src/stack/rrc_nr/rrc_nr_procedures.cc b/srsue/src/stack/rrc_nr/rrc_nr_procedures.cc index b369e3417..495e843da 100644 --- a/srsue/src/stack/rrc_nr/rrc_nr_procedures.cc +++ b/srsue/src/stack/rrc_nr/rrc_nr_procedures.cc @@ -213,9 +213,6 @@ proc_outcome_t rrc_nr::setup_request_proc::step() if (state == state_t::config_serving_cell) { // TODO: start serving cell config and start T300 - srsran::rach_nr_cfg_t rach_cfg = {}; - rrc_handle.mac->set_config(rach_cfg); - rrc_handle.phy_cfg_state = PHY_CFG_STATE_APPLY_SP_CELL; rrc_handle.phy->set_config(rrc_handle.phy_cfg); @@ -317,18 +314,18 @@ proc_outcome_t rrc_nr::cell_selection_proc::init() { init_serv_cell = meas_cells.serving_cell().phy_cell; - // Skip cell selection if serving cell is suitable and there are no stronger neighbours in same earfcn - if (is_serv_cell_suitable()) { - Debug("Skipping cell selection procedure as there are no stronger neighbours in same EARFCN."); - return set_proc_complete(); - } - // TODO: add full cell selection phy_interface_rrc_nr::cell_select_args_t cell_cfg = {}; cell_cfg.carrier = rrc_handle.phy_cfg.carrier; cell_cfg.ssb_cfg = rrc_handle.phy_cfg.get_ssb_cfg(); rrc_handle.phy->start_cell_select(cell_cfg); + // Skip cell selection if serving cell is suitable and there are no stronger neighbours in same earfcn + if (is_serv_cell_suitable()) { + Debug("Skipping cell selection procedure as there are no stronger neighbours in same EARFCN."); + return set_proc_complete(); + } + return set_proc_complete(); }