From 4a58c10f30efffa3e8a7695791aa171ce95a67f7 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 19 Oct 2021 17:47:59 +0100 Subject: [PATCH 01/60] lte,enb,rlc: compute and forward to scheduler the number of bytes pending for retx and status pdu in RLC AM bearer --- lib/include/srsran/rlc/rlc_am_lte.h | 1 + lib/src/rlc/rlc_am_lte.cc | 39 +++++++++------ .../hdr/stack/mac/common/ue_buffer_manager.h | 14 +++--- srsenb/hdr/stack/mac/sched.h | 2 +- srsenb/hdr/stack/mac/sched_interface.h | 48 +++++++++---------- .../hdr/stack/mac/sched_ue_ctrl/sched_lch.h | 6 +-- .../src/stack/mac/common/ue_buffer_manager.cc | 12 ++--- srsenb/src/stack/mac/sched.cc | 4 +- .../src/stack/mac/sched_ue_ctrl/sched_lch.cc | 22 ++++----- srsenb/test/mac/sched_lc_ch_test.cc | 14 +++--- 10 files changed, 86 insertions(+), 76 deletions(-) diff --git a/lib/include/srsran/rlc/rlc_am_lte.h b/lib/include/srsran/rlc/rlc_am_lte.h index 6512d76a7..f032cd6b3 100644 --- a/lib/include/srsran/rlc/rlc_am_lte.h +++ b/lib/include/srsran/rlc/rlc_am_lte.h @@ -375,6 +375,7 @@ private: bool has_data(); uint32_t get_buffer_state(); + void get_buffer_state(uint32_t& new_tx, uint32_t& prio_tx); // Timeout callback interface void timer_expired(uint32_t timeout_id); diff --git a/lib/src/rlc/rlc_am_lte.cc b/lib/src/rlc/rlc_am_lte.cc index 3638c04b1..133b5ff1a 100644 --- a/lib/src/rlc/rlc_am_lte.cc +++ b/lib/src/rlc/rlc_am_lte.cc @@ -436,9 +436,18 @@ void rlc_am_lte::rlc_am_lte_tx::check_sn_reached_max_retx(uint32_t sn) uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() { + uint32_t newtx = 0, priotx = 0; + get_buffer_state(newtx, priotx); + return newtx + priotx; +} + +void rlc_am_lte::rlc_am_lte_tx::get_buffer_state(uint32_t& n_bytes_newtx, uint32_t& n_bytes_prio) +{ + n_bytes_newtx = 0; + n_bytes_prio = 0; + uint32_t n_sdus = 0; + std::lock_guard lock(mutex); - uint32_t n_bytes = 0; - uint32_t n_sdus = 0; logger.debug("%s Buffer state - do_status=%s, status_prohibit_running=%s (%d/%d)", RB_NAME, @@ -449,8 +458,8 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() // Bytes needed for status report if (do_status() && not status_prohibit_timer.is_running()) { - n_bytes += parent->rx.get_status_pdu_length(); - logger.debug("%s Buffer state - total status report: %d bytes", RB_NAME, n_bytes); + n_bytes_prio += parent->rx.get_status_pdu_length(); + logger.debug("%s Buffer state - total status report: %d bytes", RB_NAME, n_bytes_prio); } // Bytes needed for retx @@ -468,8 +477,8 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() logger.error("In get_buffer_state(): Removing retx.sn=%d from queue", retx.sn); retx_queue.pop(); } else { - n_bytes += req_bytes; - logger.debug("Buffer state - retx: %d bytes", n_bytes); + n_bytes_prio += req_bytes; + logger.debug("Buffer state - retx: %d bytes", n_bytes_prio); } } } @@ -477,25 +486,23 @@ uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() // Bytes needed for tx SDUs if (tx_window.size() < 1024) { n_sdus = tx_sdu_queue.get_n_sdus(); - n_bytes += tx_sdu_queue.size_bytes(); + n_bytes_newtx += tx_sdu_queue.size_bytes(); if (tx_sdu != NULL) { n_sdus++; - n_bytes += tx_sdu->N_bytes; + n_bytes_newtx += tx_sdu->N_bytes; } } // Room needed for header extensions? (integer rounding) if (n_sdus > 1) { - n_bytes += ((n_sdus - 1) * 1.5) + 0.5; + n_bytes_newtx += ((n_sdus - 1) * 1.5) + 0.5; } // Room needed for fixed header of data PDUs - if (n_bytes > 0 && n_sdus > 0) { - n_bytes += 2; // Two bytes for fixed header with SN length = 10 - logger.debug("%s Total buffer state - %d SDUs (%d B)", RB_NAME, n_sdus, n_bytes); + if (n_bytes_newtx > 0 && n_sdus > 0) { + n_bytes_newtx += 2; // Two bytes for fixed header with SN length = 10 + logger.debug("%s Total buffer state - %d SDUs (%d B)", RB_NAME, n_sdus, n_bytes_newtx); } - - return n_bytes; } int rlc_am_lte::rlc_am_lte_tx::write_sdu(unique_byte_buffer_t sdu) @@ -613,7 +620,9 @@ void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id) lock.unlock(); if (bsr_callback) { - bsr_callback(parent->lcid, get_buffer_state(), 0); + uint32_t newtx = 0, priotx = 0; + get_buffer_state(newtx, priotx); + bsr_callback(parent->lcid, newtx, priotx); } } diff --git a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h b/srsenb/hdr/stack/mac/common/ue_buffer_manager.h index 3e9e828f0..14261ba43 100644 --- a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h +++ b/srsenb/hdr/stack/mac/common/ue_buffer_manager.h @@ -43,7 +43,7 @@ public: // Buffer Status update void ul_bsr(uint32_t lcg_id, uint32_t val); - void dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t retx_queue); + void dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue); // Configuration getters bool is_bearer_active(uint32_t lcid) const { return get_cfg(lcid).is_active(); } @@ -58,13 +58,13 @@ public: /// DL newtx buffer status for given LCID (no RLC overhead included) int get_dl_tx(uint32_t lcid) const { return is_bearer_dl(lcid) ? channels[lcid].buf_tx : 0; } - /// DL retx buffer status for given LCID (no RLC overhead included) - int get_dl_retx(uint32_t lcid) const { return is_bearer_dl(lcid) ? channels[lcid].buf_retx : 0; } + /// DL high prio tx buffer status for given LCID (no RLC overhead included) + int get_dl_prio_tx(uint32_t lcid) const { return is_bearer_dl(lcid) ? channels[lcid].buf_prio_tx : 0; } - /// Sum of DL RLC newtx and retx buffer status for given LCID (no RLC overhead included) - int get_dl_tx_total(uint32_t lcid) const { return get_dl_tx(lcid) + get_dl_retx(lcid); } + /// Sum of DL RLC newtx and high prio tx buffer status for given LCID (no RLC overhead included) + int get_dl_tx_total(uint32_t lcid) const { return get_dl_tx(lcid) + get_dl_prio_tx(lcid); } - /// Sum of DL RLC newtx and retx buffer status for all LCIDS + /// Sum of DL RLC newtx and high prio buffer status for all LCIDS int get_dl_tx_total() const; // UL BSR methods @@ -82,7 +82,7 @@ protected: struct logical_channel { mac_lc_ch_cfg_t cfg; int buf_tx = 0; - int buf_retx = 0; + int buf_prio_tx = 0; int Bj = 0; int bucket_size = 0; }; diff --git a/srsenb/hdr/stack/mac/sched.h b/srsenb/hdr/stack/mac/sched.h index 36fa3f8a6..4e0ab9c68 100644 --- a/srsenb/hdr/stack/mac/sched.h +++ b/srsenb/hdr/stack/mac/sched.h @@ -53,7 +53,7 @@ public: uint32_t get_ul_buffer(uint16_t rnti) final; uint32_t get_dl_buffer(uint16_t rnti) final; - int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) final; + int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t prio_tx_queue) final; int dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code, uint32_t nof_cmds = 1) final; int dl_ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) final; diff --git a/srsenb/hdr/stack/mac/sched_interface.h b/srsenb/hdr/stack/mac/sched_interface.h index 0401deee4..7e40e0a9a 100644 --- a/srsenb/hdr/stack/mac/sched_interface.h +++ b/srsenb/hdr/stack/mac/sched_interface.h @@ -46,30 +46,30 @@ public: } cell_cfg_sib_t; struct sched_args_t { - std::string sched_policy = "time_pf"; - std::string sched_policy_args = "2"; - int pdsch_mcs = -1; - int pdsch_max_mcs = 28; - int pusch_mcs = -1; - int pusch_max_mcs = 28; - uint32_t min_nof_ctrl_symbols = 1; - uint32_t max_nof_ctrl_symbols = 3; - int min_aggr_level = 0; - int max_aggr_level = 3; - bool adaptive_aggr_level = false; - bool pucch_mux_enabled = false; - int pucch_harq_max_rb = 0; - float target_bler = 0.05; - float max_delta_dl_cqi = 5; - float max_delta_ul_snr = 5; + std::string sched_policy = "time_pf"; + std::string sched_policy_args = "2"; + int pdsch_mcs = -1; + int pdsch_max_mcs = 28; + int pusch_mcs = -1; + int pusch_max_mcs = 28; + uint32_t min_nof_ctrl_symbols = 1; + uint32_t max_nof_ctrl_symbols = 3; + int min_aggr_level = 0; + int max_aggr_level = 3; + bool adaptive_aggr_level = false; + bool pucch_mux_enabled = false; + int pucch_harq_max_rb = 0; + float target_bler = 0.05; + float max_delta_dl_cqi = 5; + float max_delta_ul_snr = 5; 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; - int init_dl_cqi = 5; - float max_sib_coderate = 0.8; - int pdcch_cqi_offset = 0; + uint32_t min_tpc_tti_interval = 1; + float ul_snr_avg_alpha = 0.05; + int init_ul_snr_value = 5; + int init_dl_cqi = 5; + float max_sib_coderate = 0.8; + int pdcch_cqi_offset = 0; }; struct cell_cfg_t { @@ -267,10 +267,10 @@ public: * @param rnti user rnti * @param lc_id logical channel id for which the buffer update is concerned * @param tx_queue number of pending bytes for new DL RLC transmissions - * @param retx_queue number of pending bytes concerning RLC retransmissions + * @param prio_tx_queue number of pending bytes concerning RLC retransmissions and status PDUs * @return error code */ - virtual int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) = 0; + virtual int dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t prio_tx_queue) = 0; /** * Enqueue MAC CEs for DL transmission diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h index c4ce54b77..0892bf8d9 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h @@ -35,7 +35,7 @@ public: using base_type::dl_buffer_state; using base_type::get_bsr; using base_type::get_bsr_state; - using base_type::get_dl_retx; + using base_type::get_dl_prio_tx; using base_type::get_dl_tx; using base_type::get_dl_tx_total; using base_type::is_bearer_active; @@ -51,7 +51,7 @@ public: bool has_pending_dl_txs() const; int get_dl_tx_total_with_overhead(uint32_t lcid) const; int get_dl_tx_with_overhead(uint32_t lcid) const; - int get_dl_retx_with_overhead(uint32_t lcid) const; + int get_dl_prio_tx_with_overhead(uint32_t lcid) const; int get_bsr_with_overhead(uint32_t lcid) const; int get_max_prio_lcid() const; @@ -61,7 +61,7 @@ public: srsran::deque pending_ces; private: - int alloc_retx_bytes(uint8_t lcid, int rem_bytes); + int alloc_prio_tx_bytes(uint8_t lcid, int rem_bytes); int alloc_tx_bytes(uint8_t lcid, int rem_bytes); size_t prio_idx = 0; diff --git a/srsenb/src/stack/mac/common/ue_buffer_manager.cc b/srsenb/src/stack/mac/common/ue_buffer_manager.cc index c0a2cdcae..9bf260230 100644 --- a/srsenb/src/stack/mac/common/ue_buffer_manager.cc +++ b/srsenb/src/stack/mac/common/ue_buffer_manager.cc @@ -112,20 +112,20 @@ void ue_buffer_manager::ul_bsr(uint32_t lcg_id, uint32_t val) } template -void ue_buffer_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t retx_queue) +void ue_buffer_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue) { if (not is_lcid_valid(lcid)) { logger.warning("The provided lcid=%d is not valid", lcid); return; } if (lcid <= MAX_SRB_LC_ID and - (channels[lcid].buf_tx != (int)tx_queue or channels[lcid].buf_retx != (int)retx_queue)) { - logger.info("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, retx_queue); + (channels[lcid].buf_tx != (int)tx_queue or channels[lcid].buf_prio_tx != (int)prio_tx_queue)) { + logger.info("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, prio_tx_queue); } else { - logger.debug("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, retx_queue); + logger.debug("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, prio_tx_queue); } - channels[lcid].buf_retx = retx_queue; - channels[lcid].buf_tx = tx_queue; + channels[lcid].buf_prio_tx = prio_tx_queue; + channels[lcid].buf_tx = tx_queue; } // Explicit instantiation diff --git a/srsenb/src/stack/mac/sched.cc b/srsenb/src/stack/mac/sched.cc index f01a209fe..d836fdbd2 100644 --- a/srsenb/src/stack/mac/sched.cc +++ b/srsenb/src/stack/mac/sched.cc @@ -165,9 +165,9 @@ uint32_t sched::get_ul_buffer(uint16_t rnti) return ret; } -int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t retx_queue) +int sched::dl_rlc_buffer_state(uint16_t rnti, uint32_t lc_id, uint32_t tx_queue, uint32_t prio_tx_queue) { - return ue_db_access_locked(rnti, [&](sched_ue& ue) { ue.dl_buffer_state(lc_id, tx_queue, retx_queue); }); + return ue_db_access_locked(rnti, [&](sched_ue& ue) { ue.dl_buffer_state(lc_id, tx_queue, prio_tx_queue); }); } int sched::dl_mac_buffer_state(uint16_t rnti, uint32_t ce_code, uint32_t nof_cmds) diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc index 3bd85f603..be2f492fe 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc @@ -94,9 +94,9 @@ int lch_ue_manager::get_max_prio_lcid() const { int min_prio_val = std::numeric_limits::max(), prio_lcid = -1; - // Prioritize retxs + // Prioritized Txs first (e.g. Retxs, status PDUs) for (uint32_t lcid = 0; is_lcid_valid(lcid); ++lcid) { - if (get_dl_retx(lcid) > 0 and channels[lcid].cfg.priority < min_prio_val) { + if (get_dl_prio_tx(lcid) > 0 and channels[lcid].cfg.priority < min_prio_val) { min_prio_val = channels[lcid].cfg.priority; prio_lcid = lcid; } @@ -147,10 +147,10 @@ int lch_ue_manager::alloc_rlc_pdu(sched_interface::dl_sched_pdu_t* rlc_pdu, int return alloc_bytes; } - // try first to allocate retxs - alloc_bytes = alloc_retx_bytes(lcid, rem_bytes); + // try first to allocate high priority txs (e.g. retxs, status pdus) + alloc_bytes = alloc_prio_tx_bytes(lcid, rem_bytes); - // if no retx alloc, try newtx + // if no prio tx alloc, try newtx if (alloc_bytes == 0) { alloc_bytes = alloc_tx_bytes(lcid, rem_bytes); } @@ -168,15 +168,15 @@ int lch_ue_manager::alloc_rlc_pdu(sched_interface::dl_sched_pdu_t* rlc_pdu, int return alloc_bytes; } -int lch_ue_manager::alloc_retx_bytes(uint8_t lcid, int rem_bytes) +int lch_ue_manager::alloc_prio_tx_bytes(uint8_t lcid, int rem_bytes) { const int rlc_overhead = (lcid == 0) ? 0 : RLC_MAX_HEADER_SIZE_NO_LI; if (rem_bytes <= rlc_overhead) { return 0; } int rem_bytes_no_header = rem_bytes - rlc_overhead; - int alloc = std::min(rem_bytes_no_header, get_dl_retx(lcid)); - channels[lcid].buf_retx -= alloc; + int alloc = std::min(rem_bytes_no_header, get_dl_prio_tx(lcid)); + channels[lcid].buf_prio_tx -= alloc; return alloc + (alloc > 0 ? rlc_overhead : 0); } @@ -211,7 +211,7 @@ bool lch_ue_manager::has_pending_dl_txs() const int lch_ue_manager::get_dl_tx_total_with_overhead(uint32_t lcid) const { - return get_dl_retx_with_overhead(lcid) + get_dl_tx_with_overhead(lcid); + return get_dl_prio_tx_with_overhead(lcid) + get_dl_tx_with_overhead(lcid); } int lch_ue_manager::get_dl_tx_with_overhead(uint32_t lcid) const @@ -219,9 +219,9 @@ int lch_ue_manager::get_dl_tx_with_overhead(uint32_t lcid) const return get_dl_mac_sdu_size_with_overhead(lcid, get_dl_tx(lcid)); } -int lch_ue_manager::get_dl_retx_with_overhead(uint32_t lcid) const +int lch_ue_manager::get_dl_prio_tx_with_overhead(uint32_t lcid) const { - return get_dl_mac_sdu_size_with_overhead(lcid, get_dl_retx(lcid)); + return get_dl_mac_sdu_size_with_overhead(lcid, get_dl_prio_tx(lcid)); } int lch_ue_manager::get_bsr_with_overhead(uint32_t lcg) const diff --git a/srsenb/test/mac/sched_lc_ch_test.cc b/srsenb/test/mac/sched_lc_ch_test.cc index d321bb144..106d38581 100644 --- a/srsenb/test/mac/sched_lc_ch_test.cc +++ b/srsenb/test/mac/sched_lc_ch_test.cc @@ -44,7 +44,7 @@ int test_pdu_alloc_successful(srsenb::lch_ue_manager& lch_handler, int test_retx_until_empty(srsenb::lch_ue_manager& lch_handler, int lcid, uint32_t rlc_payload_size) { - int start_rlc_bytes = lch_handler.get_dl_retx(lcid); + int start_rlc_bytes = lch_handler.get_dl_prio_tx(lcid); int nof_pdus = ceil(static_cast(start_rlc_bytes) / static_cast(rlc_payload_size)); int rem_rlc_bytes = start_rlc_bytes; @@ -53,7 +53,7 @@ int test_retx_until_empty(srsenb::lch_ue_manager& lch_handler, int lcid, uint32_ uint32_t expected_payload_size = std::min(rlc_payload_size, (uint32_t)rem_rlc_bytes); TESTASSERT(test_pdu_alloc_successful(lch_handler, pdu, lcid, expected_payload_size) == SRSRAN_SUCCESS); rem_rlc_bytes -= expected_payload_size; - TESTASSERT(lch_handler.get_dl_retx(lcid) == rem_rlc_bytes); + TESTASSERT(lch_handler.get_dl_prio_tx(lcid) == rem_rlc_bytes); } return start_rlc_bytes; } @@ -97,15 +97,15 @@ int test_lc_ch_pbr_infinity() lch_handler.dl_buffer_state(drb_to_lcid(lte_drb::drb2), 5000, 10000); // TEST1 - retx of SRB1 is prioritized. Do not transmit other bearers until there are no SRB1 retxs - int nof_pending_bytes = lch_handler.get_dl_retx(srb_to_lcid(lte_srb::srb1)); + int nof_pending_bytes = lch_handler.get_dl_prio_tx(srb_to_lcid(lte_srb::srb1)); TESTASSERT(test_retx_until_empty(lch_handler, srb_to_lcid(lte_srb::srb1), 500) == nof_pending_bytes); // TEST2 - the DRB2 has lower prio level than SRB1, but has retxs - nof_pending_bytes = lch_handler.get_dl_retx(drb_to_lcid(lte_drb::drb2)); + nof_pending_bytes = lch_handler.get_dl_prio_tx(drb_to_lcid(lte_drb::drb2)); TESTASSERT(test_retx_until_empty(lch_handler, drb_to_lcid(lte_drb::drb2), 500) == nof_pending_bytes); // TEST3 - the DRB1 has lower prio level, but has retxs - nof_pending_bytes = lch_handler.get_dl_retx(drb_to_lcid(lte_drb::drb1)); + nof_pending_bytes = lch_handler.get_dl_prio_tx(drb_to_lcid(lte_drb::drb1)); TESTASSERT(test_retx_until_empty(lch_handler, drb_to_lcid(lte_drb::drb1), 500) == nof_pending_bytes); // TEST4 - The SRB1 newtx buffer is emptied before other bearers newtxs @@ -154,11 +154,11 @@ int test_lc_ch_pbr_finite() lch_handler.dl_buffer_state(drb_to_lcid(lte_drb::drb2), 50000, 0); // TEST1 - SRB1 retxs are emptied first - int nof_pending_bytes = lch_handler.get_dl_retx(srb_to_lcid(lte_srb::srb1)); + int nof_pending_bytes = lch_handler.get_dl_prio_tx(srb_to_lcid(lte_srb::srb1)); TESTASSERT(test_retx_until_empty(lch_handler, srb_to_lcid(lte_srb::srb1), 500) == nof_pending_bytes); // TEST2 - DRB1 retxs are emptied - nof_pending_bytes = lch_handler.get_dl_retx(drb_to_lcid(lte_drb::drb1)); + nof_pending_bytes = lch_handler.get_dl_prio_tx(drb_to_lcid(lte_drb::drb1)); TESTASSERT(test_retx_until_empty(lch_handler, drb_to_lcid(lte_drb::drb1), 500) == nof_pending_bytes); // TEST3 - SRB1 newtxs are emptied (PBR==infinity) From 7aa5f731ced5e3412b4cc7fedba4f0c4bb4e0f24 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 19 Oct 2021 21:12:21 +0100 Subject: [PATCH 02/60] lte,enb,rlc: push to scheduler pending prioritized bytes both in case of RLC timer expiry or in case of new buffer state detection --- lib/include/srsran/rlc/rlc.h | 1 + lib/include/srsran/rlc/rlc_am_lte.h | 1 + lib/include/srsran/rlc/rlc_common.h | 7 ++++--- lib/include/srsran/rlc/rlc_tm.h | 1 + lib/include/srsran/rlc/rlc_um_base.h | 1 + lib/src/rlc/rlc.cc | 22 +++++++++++++--------- lib/src/rlc/rlc_am_lte.cc | 5 +++++ lib/src/rlc/rlc_tm.cc | 6 ++++++ lib/src/rlc/rlc_um_base.cc | 6 ++++++ srsenb/src/stack/upper/rlc.cc | 6 +++--- 10 files changed, 41 insertions(+), 15 deletions(-) diff --git a/lib/include/srsran/rlc/rlc.h b/lib/include/srsran/rlc/rlc.h index ef62f3bbe..bd48b9051 100644 --- a/lib/include/srsran/rlc/rlc.h +++ b/lib/include/srsran/rlc/rlc.h @@ -59,6 +59,7 @@ public: // MAC interface bool has_data_locked(const uint32_t lcid); uint32_t get_buffer_state(const uint32_t lcid); + void get_buffer_state(uint32_t lcid, uint32_t& tx_queue, uint32_t& prio_tx_queue); uint32_t get_total_mch_buffer_state(uint32_t lcid); uint32_t read_pdu(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes); uint32_t read_pdu_mch(uint32_t lcid, uint8_t* payload, uint32_t nof_bytes); diff --git a/lib/include/srsran/rlc/rlc_am_lte.h b/lib/include/srsran/rlc/rlc_am_lte.h index f032cd6b3..0c3f53c18 100644 --- a/lib/include/srsran/rlc/rlc_am_lte.h +++ b/lib/include/srsran/rlc/rlc_am_lte.h @@ -346,6 +346,7 @@ public: // MAC interface bool has_data(); uint32_t get_buffer_state(); + void get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue); uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes); void write_pdu(uint8_t* payload, uint32_t nof_bytes); diff --git a/lib/include/srsran/rlc/rlc_common.h b/lib/include/srsran/rlc/rlc_common.h index a9b3b3b4a..c15c915ae 100644 --- a/lib/include/srsran/rlc/rlc_common.h +++ b/lib/include/srsran/rlc/rlc_common.h @@ -272,9 +272,10 @@ public: // MAC interface virtual bool has_data() = 0; bool is_suspended() { return suspended; }; - virtual uint32_t get_buffer_state() = 0; - virtual uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) = 0; - virtual void write_pdu(uint8_t* payload, uint32_t nof_bytes) = 0; + virtual uint32_t get_buffer_state() = 0; + virtual void get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue) = 0; + virtual uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) = 0; + virtual void write_pdu(uint8_t* payload, uint32_t nof_bytes) = 0; virtual void set_bsr_callback(bsr_callback_t callback) = 0; diff --git a/lib/include/srsran/rlc/rlc_tm.h b/lib/include/srsran/rlc/rlc_tm.h index f6ecd8947..26c77b926 100644 --- a/lib/include/srsran/rlc/rlc_tm.h +++ b/lib/include/srsran/rlc/rlc_tm.h @@ -54,6 +54,7 @@ public: // MAC interface bool has_data() override; uint32_t get_buffer_state() override; + void get_buffer_state(uint32_t& newtx_queue, uint32_t& prio_tx_queue) override; uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes) override; void write_pdu(uint8_t* payload, uint32_t nof_bytes) override; diff --git a/lib/include/srsran/rlc/rlc_um_base.h b/lib/include/srsran/rlc/rlc_um_base.h index 997857a8e..cfdbaf0ab 100644 --- a/lib/include/srsran/rlc/rlc_um_base.h +++ b/lib/include/srsran/rlc/rlc_um_base.h @@ -58,6 +58,7 @@ public: // MAC interface bool has_data(); uint32_t get_buffer_state(); + void get_buffer_state(uint32_t& newtx_queue, uint32_t& prio_tx_queue); uint32_t read_pdu(uint8_t* payload, uint32_t nof_bytes); void write_pdu(uint8_t* payload, uint32_t nof_bytes); int get_increment_sequence_num(); diff --git a/lib/src/rlc/rlc.cc b/lib/src/rlc/rlc.cc index e46fcc0a6..fc541be60 100644 --- a/lib/src/rlc/rlc.cc +++ b/lib/src/rlc/rlc.cc @@ -239,20 +239,24 @@ bool rlc::has_data_locked(const uint32_t lcid) return has_data(lcid); } -uint32_t rlc::get_buffer_state(uint32_t lcid) +void rlc::get_buffer_state(uint32_t lcid, uint32_t& tx_queue, uint32_t& prio_tx_queue) { - uint32_t ret = 0; - rwlock_read_guard lock(rwlock); if (valid_lcid(lcid)) { if (rlc_array.at(lcid)->is_suspended()) { - ret = 0; + tx_queue = 0; + prio_tx_queue = 0; } else { - ret = rlc_array.at(lcid)->get_buffer_state(); + rlc_array.at(lcid)->get_buffer_state(tx_queue, prio_tx_queue); } } +} - return ret; +uint32_t rlc::get_buffer_state(uint32_t lcid) +{ + uint32_t tx_queue, prio_tx_queue; + get_buffer_state(lcid, tx_queue, prio_tx_queue); + return tx_queue + prio_tx_queue; } uint32_t rlc::get_total_mch_buffer_state(uint32_t lcid) @@ -592,9 +596,9 @@ bool rlc::valid_lcid_mrb(uint32_t lcid) void rlc::update_bsr(uint32_t lcid) { if (bsr_callback) { - uint32_t tx_queue = get_buffer_state(lcid); - uint32_t retx_queue = 0; // todo: separate tx_queue and retx_queue - bsr_callback(lcid, tx_queue, retx_queue); + uint32_t tx_queue = 0, prio_tx_queue = 0; + get_buffer_state(lcid, tx_queue, prio_tx_queue); + bsr_callback(lcid, tx_queue, prio_tx_queue); } } diff --git a/lib/src/rlc/rlc_am_lte.cc b/lib/src/rlc/rlc_am_lte.cc index 133b5ff1a..d12850a23 100644 --- a/lib/src/rlc/rlc_am_lte.cc +++ b/lib/src/rlc/rlc_am_lte.cc @@ -258,6 +258,11 @@ uint32_t rlc_am_lte::get_buffer_state() return tx.get_buffer_state(); } +void rlc_am_lte::get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue) +{ + tx.get_buffer_state(tx_queue, prio_tx_queue); +} + uint32_t rlc_am_lte::read_pdu(uint8_t* payload, uint32_t nof_bytes) { uint32_t read_bytes = tx.read_pdu(payload, nof_bytes); diff --git a/lib/src/rlc/rlc_tm.cc b/lib/src/rlc/rlc_tm.cc index 8a6c0376b..ce7cf4d40 100644 --- a/lib/src/rlc/rlc_tm.cc +++ b/lib/src/rlc/rlc_tm.cc @@ -124,6 +124,12 @@ uint32_t rlc_tm::get_buffer_state() return ul_queue.size_bytes(); } +void rlc_tm::get_buffer_state(uint32_t& newtx_queue, uint32_t& prio_tx_queue) +{ + newtx_queue = get_buffer_state(); + prio_tx_queue = 0; +} + rlc_bearer_metrics_t rlc_tm::get_metrics() { std::lock_guard lock(metrics_mutex); diff --git a/lib/src/rlc/rlc_um_base.cc b/lib/src/rlc/rlc_um_base.cc index 2be81a2c7..e0d614621 100644 --- a/lib/src/rlc/rlc_um_base.cc +++ b/lib/src/rlc/rlc_um_base.cc @@ -134,6 +134,12 @@ uint32_t rlc_um_base::get_buffer_state() return 0; } +void rlc_um_base::get_buffer_state(uint32_t& newtx_queue, uint32_t& prio_tx_queue) +{ + newtx_queue = get_buffer_state(); + prio_tx_queue = 0; +} + uint32_t rlc_um_base::read_pdu(uint8_t* payload, uint32_t nof_bytes) { if (tx && tx_enabled) { diff --git a/srsenb/src/stack/upper/rlc.cc b/srsenb/src/stack/upper/rlc.cc index bfb2130f1..25d3c1678 100644 --- a/srsenb/src/stack/upper/rlc.cc +++ b/srsenb/src/stack/upper/rlc.cc @@ -173,10 +173,10 @@ void rlc::reestablish(uint16_t rnti) // In the eNodeB, there is no polling for buffer state from the scheduler. // This function is called by UE RLC instance every time the tx/retx buffers are updated -void rlc::update_bsr(uint32_t rnti, uint32_t lcid, uint32_t tx_queue, uint32_t retx_queue) +void rlc::update_bsr(uint32_t rnti, uint32_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue) { - logger.debug("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d", rnti, lcid, tx_queue); - mac->rlc_buffer_state(rnti, lcid, tx_queue, retx_queue); + logger.debug("Buffer state: rnti=0x%x, lcid=%d, tx_queue=%d, prio_tx_queue=%d", rnti, lcid, tx_queue, prio_tx_queue); + mac->rlc_buffer_state(rnti, lcid, tx_queue, prio_tx_queue); } int rlc::read_pdu(uint16_t rnti, uint32_t lcid, uint8_t* payload, uint32_t nof_bytes) From d60950d0f31efcfbea5f0e6c0a551d6b2571b50b Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 20 Oct 2021 14:46:46 +0100 Subject: [PATCH 03/60] lte,enb,rlc: change new_tx and prio_tx variable names to snake_case and ensure they are zero initialized --- lib/src/rlc/rlc.cc | 2 +- lib/src/rlc/rlc_am_lte.cc | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/src/rlc/rlc.cc b/lib/src/rlc/rlc.cc index fc541be60..987a19c0a 100644 --- a/lib/src/rlc/rlc.cc +++ b/lib/src/rlc/rlc.cc @@ -254,7 +254,7 @@ void rlc::get_buffer_state(uint32_t lcid, uint32_t& tx_queue, uint32_t& prio_tx_ uint32_t rlc::get_buffer_state(uint32_t lcid) { - uint32_t tx_queue, prio_tx_queue; + uint32_t tx_queue = 0, prio_tx_queue = 0; get_buffer_state(lcid, tx_queue, prio_tx_queue); return tx_queue + prio_tx_queue; } diff --git a/lib/src/rlc/rlc_am_lte.cc b/lib/src/rlc/rlc_am_lte.cc index d12850a23..b32f910c6 100644 --- a/lib/src/rlc/rlc_am_lte.cc +++ b/lib/src/rlc/rlc_am_lte.cc @@ -441,9 +441,9 @@ void rlc_am_lte::rlc_am_lte_tx::check_sn_reached_max_retx(uint32_t sn) uint32_t rlc_am_lte::rlc_am_lte_tx::get_buffer_state() { - uint32_t newtx = 0, priotx = 0; - get_buffer_state(newtx, priotx); - return newtx + priotx; + uint32_t new_tx_queue = 0, prio_tx_queue = 0; + get_buffer_state(new_tx_queue, prio_tx_queue); + return new_tx_queue + prio_tx_queue; } void rlc_am_lte::rlc_am_lte_tx::get_buffer_state(uint32_t& n_bytes_newtx, uint32_t& n_bytes_prio) @@ -625,9 +625,9 @@ void rlc_am_lte::rlc_am_lte_tx::timer_expired(uint32_t timeout_id) lock.unlock(); if (bsr_callback) { - uint32_t newtx = 0, priotx = 0; - get_buffer_state(newtx, priotx); - bsr_callback(parent->lcid, newtx, priotx); + uint32_t new_tx_queue = 0, prio_tx_queue = 0; + get_buffer_state(new_tx_queue, prio_tx_queue); + bsr_callback(parent->lcid, new_tx_queue, prio_tx_queue); } } From f2818d05040358beff72d7e0177ecaafadf0f8ea Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 19 Oct 2021 19:49:06 +0100 Subject: [PATCH 04/60] enb,sched: improve sched ue buffer manager to show rnti in logs --- .../hdr/stack/mac/common/ue_buffer_manager.h | 4 +++- .../hdr/stack/mac/sched_ue_ctrl/sched_lch.h | 2 +- .../src/stack/mac/common/ue_buffer_manager.cc | 19 +++++++++++-------- srsenb/src/stack/mac/nr/sched_nr_ue.cc | 2 +- srsenb/src/stack/mac/sched_ue.cc | 2 +- .../src/stack/mac/sched_ue_ctrl/sched_lch.cc | 9 ++++++--- srsenb/test/mac/sched_lc_ch_test.cc | 4 ++-- 7 files changed, 25 insertions(+), 17 deletions(-) diff --git a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h b/srsenb/hdr/stack/mac/common/ue_buffer_manager.h index 14261ba43..42ea47039 100644 --- a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h +++ b/srsenb/hdr/stack/mac/common/ue_buffer_manager.h @@ -36,7 +36,7 @@ protected: constexpr static uint32_t pbr_infinity = -1; public: - explicit ue_buffer_manager(srslog::basic_logger& logger_); + explicit ue_buffer_manager(uint16_t rnti, srslog::basic_logger& logger_); // Bearer configuration void config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg); @@ -46,6 +46,7 @@ public: void dl_buffer_state(uint8_t lcid, uint32_t tx_queue, uint32_t prio_tx_queue); // Configuration getters + uint16_t get_rnti() const { return rnti; } bool is_bearer_active(uint32_t lcid) const { return get_cfg(lcid).is_active(); } bool is_bearer_ul(uint32_t lcid) const { return get_cfg(lcid).is_ul(); } bool is_bearer_dl(uint32_t lcid) const { return get_cfg(lcid).is_dl(); } @@ -78,6 +79,7 @@ public: protected: srslog::basic_logger& logger; + uint16_t rnti; struct logical_channel { mac_lc_ch_cfg_t cfg; diff --git a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h index 0892bf8d9..d3de3f571 100644 --- a/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h +++ b/srsenb/hdr/stack/mac/sched_ue_ctrl/sched_lch.h @@ -26,7 +26,7 @@ class lch_ue_manager : private ue_buffer_manager using base_type = ue_buffer_manager; public: - lch_ue_manager() : ue_buffer_manager(srslog::fetch_basic_logger("MAC")) {} + explicit lch_ue_manager(uint16_t rnti) : ue_buffer_manager(rnti, srslog::fetch_basic_logger("MAC")) {} void set_cfg(const sched_interface::ue_cfg_t& cfg_); void new_tti(); diff --git a/srsenb/src/stack/mac/common/ue_buffer_manager.cc b/srsenb/src/stack/mac/common/ue_buffer_manager.cc index 9bf260230..cf205e35f 100644 --- a/srsenb/src/stack/mac/common/ue_buffer_manager.cc +++ b/srsenb/src/stack/mac/common/ue_buffer_manager.cc @@ -18,7 +18,7 @@ namespace srsenb { template -ue_buffer_manager::ue_buffer_manager(srslog::basic_logger& logger_) : logger(logger_) +ue_buffer_manager::ue_buffer_manager(uint16_t rnti_, srslog::basic_logger& logger_) : logger(logger_), rnti(rnti_) { std::fill(lcg_bsr.begin(), lcg_bsr.end(), 0); } @@ -27,11 +27,12 @@ template void ue_buffer_manager::config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg) { if (not is_lcid_valid(lcid)) { - logger.warning("Configuring bearer with invalid logical channel id=%d", lcid); + logger.warning("SCHED: Configuring rnti=0x%x bearer with invalid lcid=%d", rnti, lcid); return; } if (not is_lcg_valid(bearer_cfg.group)) { - logger.warning("Configuring bearer with invalid logical channel group id=%d", bearer_cfg.group); + logger.warning( + "SCHED: Configuring rnti=0x%x bearer with invalid logical channel group id=%d", rnti, bearer_cfg.group); return; } @@ -45,7 +46,8 @@ void ue_buffer_manager::config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& channels[lcid].bucket_size = channels[lcid].cfg.bsd * channels[lcid].cfg.pbr; channels[lcid].Bj = 0; } - logger.info("SCHED: bearer configured: lcid=%d, mode=%s, prio=%d, lcg=%d", + logger.info("SCHED: rnti=0x%x bearer configured: lcid=%d, mode=%s, prio=%d, lcg=%d", + rnti, lcid, to_string(channels[lcid].cfg.direction), channels[lcid].cfg.priority, @@ -99,7 +101,7 @@ template void ue_buffer_manager::ul_bsr(uint32_t lcg_id, uint32_t val) { if (not is_lcg_valid(lcg_id)) { - logger.warning("The provided logical channel group id=%d is not valid", lcg_id); + logger.warning("SCHED: The provided lcg_id=%d for rnti=0x%x is not valid", lcg_id, rnti); return; } lcg_bsr[lcg_id] = val; @@ -107,7 +109,8 @@ void ue_buffer_manager::ul_bsr(uint32_t lcg_id, uint32_t val) if (logger.debug.enabled()) { fmt::memory_buffer str_buffer; fmt::format_to(str_buffer, "{}", lcg_bsr); - logger.debug("SCHED: lcg_id=%d, bsr=%d. Current state=%s", lcg_id, val, srsran::to_c_str(str_buffer)); + logger.debug( + "SCHED: rnti=0x%x, lcg_id=%d, bsr=%d. Current state=%s", rnti, lcg_id, val, srsran::to_c_str(str_buffer)); } } @@ -120,9 +123,9 @@ void ue_buffer_manager::dl_buffer_state(uint8_t lcid, uint32_t tx_queue, u } if (lcid <= MAX_SRB_LC_ID and (channels[lcid].buf_tx != (int)tx_queue or channels[lcid].buf_prio_tx != (int)prio_tx_queue)) { - logger.info("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, prio_tx_queue); + logger.info("SCHED: rnti=0x%x DL lcid=%d buffer_state=%d,%d", rnti, lcid, tx_queue, prio_tx_queue); } else { - logger.debug("SCHED: DL lcid=%d buffer_state=%d,%d", lcid, tx_queue, prio_tx_queue); + logger.debug("SCHED: rnti=0x%x DL lcid=%d buffer_state=%d,%d", rnti, lcid, tx_queue, prio_tx_queue); } channels[lcid].buf_prio_tx = prio_tx_queue; channels[lcid].buf_tx = tx_queue; diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index 054342294..f1cb233dd 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -78,7 +78,7 @@ slot_ue ue_carrier::try_reserve(slot_point pdcch_slot, uint32_t dl_pending_bytes /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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)) + rnti(rnti_), sched_cfg(sched_cfg_), buffers(rnti_, srslog::fetch_basic_logger(sched_cfg_.sched_cfg.logger_name)) { set_cfg(cfg); } diff --git a/srsenb/src/stack/mac/sched_ue.cc b/srsenb/src/stack/mac/sched_ue.cc index fd9031323..fb4d15d3f 100644 --- a/srsenb/src/stack/mac/sched_ue.cc +++ b/srsenb/src/stack/mac/sched_ue.cc @@ -33,7 +33,7 @@ namespace srsenb { *******************************************************/ sched_ue::sched_ue(uint16_t rnti_, const std::vector& cell_list_params_, const ue_cfg_t& cfg_) : - logger(srslog::fetch_basic_logger("MAC")), rnti(rnti_) + logger(srslog::fetch_basic_logger("MAC")), rnti(rnti_), lch_handler(rnti_) { cells.reserve(cell_list_params_.size()); for (auto& c : cell_list_params_) { diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc index be2f492fe..40681bb04 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc @@ -78,15 +78,18 @@ void lch_ue_manager::new_tti() void lch_ue_manager::ul_buffer_add(uint8_t lcid, uint32_t bytes) { if (lcid >= sched_interface::MAX_LC) { - logger.warning("The provided lcid=%d is not valid", lcid); + logger.warning("SCHED: The provided lcid=%d for rnti=0x%x is not valid", lcid, rnti); return; } lcg_bsr[channels[lcid].cfg.group] += bytes; if (logger.debug.enabled()) { fmt::memory_buffer str_buffer; fmt::format_to(str_buffer, "{}", get_bsr_state()); - logger.debug( - "SCHED: UL buffer update=%d, lcg_id=%d, bsr=%s", bytes, channels[lcid].cfg.group, srsran::to_c_str(str_buffer)); + logger.debug("SCHED: rnti=0x%x UL buffer update=%d, lcg_id=%d, bsr=%s", + rnti, + bytes, + channels[lcid].cfg.group, + srsran::to_c_str(str_buffer)); } } diff --git a/srsenb/test/mac/sched_lc_ch_test.cc b/srsenb/test/mac/sched_lc_ch_test.cc index 106d38581..5cda87108 100644 --- a/srsenb/test/mac/sched_lc_ch_test.cc +++ b/srsenb/test/mac/sched_lc_ch_test.cc @@ -76,7 +76,7 @@ int test_newtx_until_empty(srsenb::lch_ue_manager& lch_handler, int lcid, uint32 int test_lc_ch_pbr_infinity() { - srsenb::lch_ue_manager lch_handler; + srsenb::lch_ue_manager lch_handler{0x46}; srsenb::sched_interface::ue_cfg_t ue_cfg = generate_default_ue_cfg(); ue_cfg = generate_setup_ue_cfg(ue_cfg); @@ -125,7 +125,7 @@ int test_lc_ch_pbr_infinity() int test_lc_ch_pbr_finite() { - srsenb::lch_ue_manager lch_handler; + srsenb::lch_ue_manager lch_handler{0x46}; sched_interface::dl_sched_pdu_t pdu; srsenb::sched_interface::ue_cfg_t ue_cfg = generate_default_ue_cfg(); From f0a48d47b3c7cc8be855bcbcd60ba40587a177d5 Mon Sep 17 00:00:00 2001 From: Francisco Date: Tue, 19 Oct 2021 20:17:04 +0100 Subject: [PATCH 05/60] enb,sched: log lcid configurations in scheduler in a single log line --- .../hdr/stack/mac/common/ue_buffer_manager.h | 4 ++ .../src/stack/mac/common/ue_buffer_manager.cc | 56 ++++++++++++++++--- srsenb/src/stack/mac/nr/sched_nr_ue.cc | 4 +- .../src/stack/mac/sched_ue_ctrl/sched_lch.cc | 4 +- 4 files changed, 54 insertions(+), 14 deletions(-) diff --git a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h b/srsenb/hdr/stack/mac/common/ue_buffer_manager.h index 42ea47039..73054f15f 100644 --- a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h +++ b/srsenb/hdr/stack/mac/common/ue_buffer_manager.h @@ -14,6 +14,7 @@ #define SRSRAN_UE_BUFFER_MANAGER_H #include "sched_config.h" +#include "srsran/adt/span.h" #include "srsran/common/common_lte.h" #include "srsran/common/common_nr.h" #include "srsran/srslog/srslog.h" @@ -39,6 +40,7 @@ public: explicit ue_buffer_manager(uint16_t rnti, srslog::basic_logger& logger_); // Bearer configuration + void config_lcids(srsran::const_span bearer_cfg_list); void config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg); // Buffer Status update @@ -78,6 +80,8 @@ public: static bool is_lcg_valid(uint32_t lcg) { return lcg <= MAX_LCG_ID; } protected: + bool config_lcid_internal(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg); + srslog::basic_logger& logger; uint16_t rnti; diff --git a/srsenb/src/stack/mac/common/ue_buffer_manager.cc b/srsenb/src/stack/mac/common/ue_buffer_manager.cc index cf205e35f..efe0ed5ab 100644 --- a/srsenb/src/stack/mac/common/ue_buffer_manager.cc +++ b/srsenb/src/stack/mac/common/ue_buffer_manager.cc @@ -11,6 +11,7 @@ */ #include "srsenb/hdr/stack/mac/common/ue_buffer_manager.h" +#include "srsran/adt/bounded_vector.h" #include "srsran/common/string_helpers.h" #include "srsran/srslog/bundled/fmt/format.h" #include "srsran/srslog/bundled/fmt/ranges.h" @@ -23,17 +24,60 @@ ue_buffer_manager::ue_buffer_manager(uint16_t rnti_, srslog::basic_logger& std::fill(lcg_bsr.begin(), lcg_bsr.end(), 0); } +template +void ue_buffer_manager::config_lcids(srsran::const_span bearer_cfg_list) +{ + bool log_enabled = logger.info.enabled(); + srsran::bounded_vector changed_list; + + for (uint32_t lcid = 0; is_lcid_valid(lcid); ++lcid) { + if (log_enabled and config_lcid_internal(lcid, bearer_cfg_list[lcid])) { + changed_list.push_back(lcid); + } + } + + // Log changed LCID configurations + if (not changed_list.empty()) { + fmt::memory_buffer fmtbuf; + for (uint32_t i = 0; i < changed_list.size(); ++i) { + uint32_t lcid = changed_list[i]; + fmt::format_to(fmtbuf, + "{}{{lcid={}, mode={}, prio={}, lcg={}}}", + i > 0 ? ", " : "", + lcid, + to_string(channels[lcid].cfg.direction), + channels[lcid].cfg.priority, + channels[lcid].cfg.group); + } + logger.info("SCHED: rnti=0x%x, new lcid configuration: [%s]", rnti, srsran::to_c_str(fmtbuf)); + } +} + template void ue_buffer_manager::config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg) +{ + bool cfg_changed = config_lcid_internal(lcid, bearer_cfg); + if (cfg_changed) { + logger.info("SCHED: rnti=0x%x, lcid=%d configured: mode=%s, prio=%d, lcg=%d", + rnti, + lcid, + to_string(channels[lcid].cfg.direction), + channels[lcid].cfg.priority, + channels[lcid].cfg.group); + } +} + +template +bool ue_buffer_manager::config_lcid_internal(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg) { if (not is_lcid_valid(lcid)) { logger.warning("SCHED: Configuring rnti=0x%x bearer with invalid lcid=%d", rnti, lcid); - return; + return false; } if (not is_lcg_valid(bearer_cfg.group)) { logger.warning( "SCHED: Configuring rnti=0x%x bearer with invalid logical channel group id=%d", rnti, bearer_cfg.group); - return; + return false; } // update bearer config @@ -46,13 +90,9 @@ void ue_buffer_manager::config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& channels[lcid].bucket_size = channels[lcid].cfg.bsd * channels[lcid].cfg.pbr; channels[lcid].Bj = 0; } - logger.info("SCHED: rnti=0x%x bearer configured: lcid=%d, mode=%s, prio=%d, lcg=%d", - rnti, - lcid, - to_string(channels[lcid].cfg.direction), - channels[lcid].cfg.priority, - channels[lcid].cfg.group); + return true; } + return false; } template diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index f1cb233dd..f48a47ad2 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -96,9 +96,7 @@ void ue::set_cfg(const ue_cfg_t& cfg) } } - for (uint32_t lcid = 0; lcid < cfg.ue_bearers.size(); ++lcid) { - buffers.config_lcid(lcid, cfg.ue_bearers[lcid]); - } + buffers.config_lcids(cfg.ue_bearers); } void ue::new_slot(slot_point pdcch_slot) diff --git a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc index 40681bb04..59ac8c621 100644 --- a/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc +++ b/srsenb/src/stack/mac/sched_ue_ctrl/sched_lch.cc @@ -57,9 +57,7 @@ uint32_t get_ul_mac_sdu_size_with_overhead(uint32_t rlc_pdu_bytes) void lch_ue_manager::set_cfg(const sched_interface::ue_cfg_t& cfg) { - for (uint32_t lcid = 0; is_lcid_valid(lcid); lcid++) { - config_lcid(lcid, cfg.ue_bearers[lcid]); - } + config_lcids(cfg.ue_bearers); } void lch_ue_manager::new_tti() From a3dbc857d44469c2b91f3ac334cad64856fe341b Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 20 Oct 2021 14:57:27 +0100 Subject: [PATCH 06/60] gnb,sched: fix lcid configuration in scheduler --- srsenb/src/stack/mac/common/ue_buffer_manager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/common/ue_buffer_manager.cc b/srsenb/src/stack/mac/common/ue_buffer_manager.cc index efe0ed5ab..fd50dc2cd 100644 --- a/srsenb/src/stack/mac/common/ue_buffer_manager.cc +++ b/srsenb/src/stack/mac/common/ue_buffer_manager.cc @@ -31,7 +31,7 @@ void ue_buffer_manager::config_lcids(srsran::const_span b srsran::bounded_vector changed_list; for (uint32_t lcid = 0; is_lcid_valid(lcid); ++lcid) { - if (log_enabled and config_lcid_internal(lcid, bearer_cfg_list[lcid])) { + if (config_lcid_internal(lcid, bearer_cfg_list[lcid]) and log_enabled) { changed_list.push_back(lcid); } } From e26be3732cea3d592d90f26b045de4bdc0c65b9e Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 21 Oct 2021 00:20:12 +0100 Subject: [PATCH 07/60] lte,enb,sched: add comments to ue_buffer_manager explaining the logic for logging --- srsenb/src/stack/mac/common/ue_buffer_manager.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/common/ue_buffer_manager.cc b/srsenb/src/stack/mac/common/ue_buffer_manager.cc index fd50dc2cd..7a948866d 100644 --- a/srsenb/src/stack/mac/common/ue_buffer_manager.cc +++ b/srsenb/src/stack/mac/common/ue_buffer_manager.cc @@ -32,11 +32,12 @@ void ue_buffer_manager::config_lcids(srsran::const_span b for (uint32_t lcid = 0; is_lcid_valid(lcid); ++lcid) { if (config_lcid_internal(lcid, bearer_cfg_list[lcid]) and log_enabled) { + // add to the changed_list the lcids that have been updated with new parameters changed_list.push_back(lcid); } } - // Log changed LCID configurations + // Log configurations of the LCIDs for which there were param updates if (not changed_list.empty()) { fmt::memory_buffer fmtbuf; for (uint32_t i = 0; i < changed_list.size(); ++i) { @@ -67,6 +68,11 @@ void ue_buffer_manager::config_lcid(uint32_t lcid, const mac_lc_ch_cfg_t& } } +/** + * @brief configure MAC logical channel. The function checks if the configuration is valid + * and whether there was any change compared to previous value + * @return true if the lcid was updated with new parameters. False in case of case of error or no update. + */ template bool ue_buffer_manager::config_lcid_internal(uint32_t lcid, const mac_lc_ch_cfg_t& bearer_cfg) { From 329544961974ce5cd4fa4e2b7a3a742233096663 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 21 Oct 2021 11:49:04 +0100 Subject: [PATCH 08/60] nr,gnb,sched: fix crash in debug mode due to incorrect is_lcid_valid check --- srsenb/hdr/stack/mac/common/ue_buffer_manager.h | 2 +- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 3 ++- srsenb/src/stack/mac/common/ue_buffer_manager.cc | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h b/srsenb/hdr/stack/mac/common/ue_buffer_manager.h index 73054f15f..5fa9fc3eb 100644 --- a/srsenb/hdr/stack/mac/common/ue_buffer_manager.h +++ b/srsenb/hdr/stack/mac/common/ue_buffer_manager.h @@ -29,7 +29,7 @@ template class ue_buffer_manager { protected: - const static uint32_t MAX_LC_ID = isNR ? srsran::MAX_NR_NOF_BEARERS : srsran::MAX_LTE_LCID; + const static uint32_t MAX_LC_ID = isNR ? (srsran::MAX_NR_NOF_BEARERS - 1) : srsran::MAX_LTE_LCID; const static uint32_t MAX_LCG_ID = isNR ? 7 : 3; // Should import from sched_interface and sched_nr_interface const static uint32_t MAX_SRB_LC_ID = isNR ? srsran::MAX_NR_SRB_ID : srsran::MAX_LTE_SRB_ID; const static uint32_t MAX_NOF_LCIDS = MAX_LC_ID + 1; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index 46f70270f..36d806905 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -17,6 +17,7 @@ #include "srsran/adt/bounded_vector.h" #include "srsran/adt/optional.h" #include "srsran/adt/span.h" +#include "srsran/common/common_nr.h" #include "srsran/common/phy_cfg_nr.h" #include "srsran/common/slot_point.h" #include "srsran/interfaces/gnb_interfaces.h" @@ -30,7 +31,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 = SRSRAN_DEFAULT_HARQ_PROC_DL_NR; const static size_t SCHED_NR_MAX_BWP_PER_CELL = 2; -const static size_t SCHED_NR_MAX_LCID = 32; +const static size_t SCHED_NR_MAX_LCID = srsran::MAX_NR_NOF_BEARERS; const static size_t SCHED_NR_MAX_LC_GROUP = 7; struct sched_nr_ue_cc_cfg_t { diff --git a/srsenb/src/stack/mac/common/ue_buffer_manager.cc b/srsenb/src/stack/mac/common/ue_buffer_manager.cc index 7a948866d..51024fe1f 100644 --- a/srsenb/src/stack/mac/common/ue_buffer_manager.cc +++ b/srsenb/src/stack/mac/common/ue_buffer_manager.cc @@ -27,8 +27,8 @@ ue_buffer_manager::ue_buffer_manager(uint16_t rnti_, srslog::basic_logger& template void ue_buffer_manager::config_lcids(srsran::const_span bearer_cfg_list) { - bool log_enabled = logger.info.enabled(); - srsran::bounded_vector changed_list; + bool log_enabled = logger.info.enabled(); + srsran::bounded_vector changed_list; for (uint32_t lcid = 0; is_lcid_valid(lcid); ++lcid) { if (config_lcid_internal(lcid, bearer_cfg_list[lcid]) and log_enabled) { From e9a7e6dbae366e8acb2b66420dd8358510117199 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 22 Sep 2021 17:23:46 +0100 Subject: [PATCH 09/60] Getting rid of sctp_init_client function. The only thing it does is call the sctp_init_socket function. --- lib/include/srsran/common/network_utils.h | 2 +- lib/test/common/network_utils_test.cc | 4 ++-- srsenb/src/stack/ngap/ngap.cc | 2 +- srsenb/src/stack/s1ap/s1ap.cc | 3 ++- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/include/srsran/common/network_utils.h b/lib/include/srsran/common/network_utils.h index d9f4fc93d..2bd86a2d7 100644 --- a/lib/include/srsran/common/network_utils.h +++ b/lib/include/srsran/common/network_utils.h @@ -86,7 +86,7 @@ protected: namespace net_utils { -bool sctp_init_client(unique_socket* socket, net_utils::socket_type socktype, const char* bind_addr_str, int bind_port); +bool sctp_init_socket(unique_socket* socket, net_utils::socket_type socktype, const char* bind_addr_str, int bind_port); bool sctp_init_server(unique_socket* socket, net_utils::socket_type socktype, const char* bind_addr_str, int port); } // namespace net_utils diff --git a/lib/test/common/network_utils_test.cc b/lib/test/common/network_utils_test.cc index 3e36508fa..709799a45 100644 --- a/lib/test/common/network_utils_test.cc +++ b/lib/test/common/network_utils_test.cc @@ -55,8 +55,8 @@ int test_socket_handler() TESTASSERT(sctp_init_server(&server_socket, socket_type::seqpacket, server_addr, server_port)); logger.info("Listening from fd=%d", server_socket.fd()); - TESTASSERT(sctp_init_client(&client_socket, socket_type::seqpacket, "127.0.0.1", 0)); - TESTASSERT(sctp_init_client(&client_socket2, socket_type::seqpacket, "127.0.0.2", 0)); + TESTASSERT(sctp_init_socket(&client_socket, socket_type::seqpacket, "127.0.0.1", 0)); + TESTASSERT(sctp_init_socket(&client_socket2, socket_type::seqpacket, "127.0.0.2", 0)); TESTASSERT(client_socket.connect_to(server_addr, server_port)); TESTASSERT(client_socket2.connect_to(server_addr, server_port)); diff --git a/srsenb/src/stack/ngap/ngap.cc b/srsenb/src/stack/ngap/ngap.cc index 3b3d604bb..6ab2041a1 100644 --- a/srsenb/src/stack/ngap/ngap.cc +++ b/srsenb/src/stack/ngap/ngap.cc @@ -611,7 +611,7 @@ bool ngap::connect_amf() logger.info("Connecting to AMF %s:%d", args.amf_addr.c_str(), int(AMF_PORT)); // Init SCTP socket and bind it - if (not sctp_init_client(&amf_socket, socket_type::seqpacket, args.ngc_bind_addr.c_str(), 0)) { + if (not sctp_init_socket(&amf_socket, socket_type::seqpacket, args.ngc_bind_addr.c_str(), 0)) { return false; } logger.info("SCTP socket opened. fd=%d", amf_socket.fd()); diff --git a/srsenb/src/stack/s1ap/s1ap.cc b/srsenb/src/stack/s1ap/s1ap.cc index 16fd551a2..fea2eb22b 100644 --- a/srsenb/src/stack/s1ap/s1ap.cc +++ b/srsenb/src/stack/s1ap/s1ap.cc @@ -479,7 +479,8 @@ bool s1ap::connect_mme() logger.info("Connecting to MME %s:%d", args.mme_addr.c_str(), int(MME_PORT)); // Init SCTP socket and bind it - if (not sctp_init_client(&mme_socket, socket_type::seqpacket, args.s1c_bind_addr.c_str(), args.s1c_bind_port)) { + if (not srsran::net_utils::sctp_init_socket( + &mme_socket, socket_type::seqpacket, args.s1c_bind_addr.c_str(), args.s1c_bind_port)) { return false; } logger.info("SCTP socket opened. fd=%d", mme_socket.fd()); From e721504f8e558eaba46f113acf2e09af07cf5918 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 22 Sep 2021 18:58:27 +0100 Subject: [PATCH 10/60] Removed the sctp_init_server for consistency. Added listen method to unique_socket class. --- lib/include/srsran/common/network_utils.h | 2 +- lib/src/common/network_utils.cc | 61 ++++++++++++----------- lib/test/common/network_utils_test.cc | 16 +++++- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/lib/include/srsran/common/network_utils.h b/lib/include/srsran/common/network_utils.h index 2bd86a2d7..9ec7a19c9 100644 --- a/lib/include/srsran/common/network_utils.h +++ b/lib/include/srsran/common/network_utils.h @@ -76,6 +76,7 @@ public: bool bind_addr(const char* bind_addr_str, int port); bool connect_to(const char* dest_addr_str, int dest_port, sockaddr_in* dest_sockaddr = nullptr); + bool start_listen(); bool open_socket(net_utils::addr_family ip, net_utils::socket_type socket_type, net_utils::protocol_type protocol); int get_socket() const { return sockfd; }; @@ -87,7 +88,6 @@ protected: namespace net_utils { bool sctp_init_socket(unique_socket* socket, net_utils::socket_type socktype, const char* bind_addr_str, int bind_port); -bool sctp_init_server(unique_socket* socket, net_utils::socket_type socktype, const char* bind_addr_str, int port); } // namespace net_utils diff --git a/lib/src/common/network_utils.cc b/lib/src/common/network_utils.cc index 232c091ea..5d829b70b 100644 --- a/lib/src/common/network_utils.cc +++ b/lib/src/common/network_utils.cc @@ -236,6 +236,22 @@ bool connect_to(int fd, const char* dest_addr_str, int dest_port, sockaddr_in* d return true; } +bool start_listen(int fd) +{ + if (fd < 0) { + srslog::fetch_basic_logger(LOGSERVICE).error("Tried to listen for connections with an invalid socket."); + return false; + } + + // Listen for connections + if (listen(fd, SOMAXCONN) != 0) { + srslog::fetch_basic_logger(LOGSERVICE).error("Failed to listen to incoming SCTP connections"); + perror("listen()"); + return false; + } + return true; +} + } // namespace net_utils /******************************************** @@ -260,6 +276,18 @@ unique_socket& unique_socket::operator=(unique_socket&& other) noexcept return *this; } +bool unique_socket::open_socket(net_utils::addr_family ip_type, + net_utils::socket_type socket_type, + net_utils::protocol_type protocol) +{ + if (is_open()) { + srslog::fetch_basic_logger(LOGSERVICE).error("Socket is already open."); + return false; + } + sockfd = net_utils::open_socket(ip_type, socket_type, protocol); + return is_open(); +} + void unique_socket::close() { if (sockfd >= 0) { @@ -279,16 +307,9 @@ bool unique_socket::connect_to(const char* dest_addr_str, int dest_port, sockadd return net_utils::connect_to(sockfd, dest_addr_str, dest_port, dest_sockaddr); } -bool unique_socket::open_socket(net_utils::addr_family ip_type, - net_utils::socket_type socket_type, - net_utils::protocol_type protocol) +bool unique_socket::start_listen() { - if (is_open()) { - srslog::fetch_basic_logger(LOGSERVICE).error("Socket is already open."); - return false; - } - sockfd = net_utils::open_socket(ip_type, socket_type, protocol); - return is_open(); + return net_utils::start_listen(sockfd); } /*********************************************************************** @@ -297,36 +318,18 @@ bool unique_socket::open_socket(net_utils::addr_family ip_type, namespace net_utils { -bool sctp_init_socket(unique_socket* socket, net_utils::socket_type socktype, const char* bind_addr_str, int port) +bool sctp_init_socket(unique_socket* socket, net_utils::socket_type socktype, const char* bind_addr_str, int bind_port) { if (not socket->open_socket(net_utils::addr_family::ipv4, socktype, net_utils::protocol_type::SCTP)) { return false; } - if (not socket->bind_addr(bind_addr_str, port)) { + if (not socket->bind_addr(bind_addr_str, bind_port)) { socket->close(); return false; } return true; } -bool sctp_init_client(unique_socket* socket, net_utils::socket_type socktype, const char* bind_addr_str, int bind_port) -{ - return sctp_init_socket(socket, socktype, bind_addr_str, bind_port); -} - -bool sctp_init_server(unique_socket* socket, net_utils::socket_type socktype, const char* bind_addr_str, int port) -{ - if (not sctp_init_socket(socket, socktype, bind_addr_str, port)) { - return false; - } - // Listen for connections - if (listen(socket->fd(), SOMAXCONN) != 0) { - srslog::fetch_basic_logger(LOGSERVICE).error("Failed to listen to incoming SCTP connections"); - return false; - } - return true; -} - } // namespace net_utils /*************************************************************** diff --git a/lib/test/common/network_utils_test.cc b/lib/test/common/network_utils_test.cc index 709799a45..c63fd97e3 100644 --- a/lib/test/common/network_utils_test.cc +++ b/lib/test/common/network_utils_test.cc @@ -52,7 +52,8 @@ int test_socket_handler() const char* server_addr = "127.0.100.1"; using namespace srsran::net_utils; - TESTASSERT(sctp_init_server(&server_socket, socket_type::seqpacket, server_addr, server_port)); + TESTASSERT(sctp_init_socket(&server_socket, socket_type::seqpacket, server_addr, server_port)); + TESTASSERT(server_socket.start_listen()); logger.info("Listening from fd=%d", server_socket.fd()); TESTASSERT(sctp_init_socket(&client_socket, socket_type::seqpacket, "127.0.0.1", 0)); @@ -114,6 +115,18 @@ int test_socket_handler() return 0; } +int test_sctp_bind_error() +{ + srsran::unique_socket sock; + TESTASSERT(not srsran::net_utils::sctp_init_socket( + &sock, srsran::net_utils::socket_type::seqpacket, "1.1.1.1", 8000)); // Bogus IP address + // should not be able to bind + TESTASSERT(srsran::net_utils::sctp_init_socket( + &sock, srsran::net_utils::socket_type::seqpacket, "127.0.0.1", 8000)); // Bogus IP address + // should not be able to bind + return SRSRAN_SUCCESS; +} + int main() { auto& logger = srslog::fetch_basic_logger("S1AP", false); @@ -123,6 +136,7 @@ int main() srslog::init(); TESTASSERT(test_socket_handler() == 0); + TESTASSERT(test_sctp_bind_error() == 0); return 0; } From 0b948d40987ba3d15d9640d6c4ed2fed449c20dd Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Wed, 22 Sep 2021 19:00:04 +0100 Subject: [PATCH 11/60] Make sure that bind returns error if it cannot bind. Added test for SCTP bind error/success. --- lib/src/common/network_utils.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/src/common/network_utils.cc b/lib/src/common/network_utils.cc index 5d829b70b..e6dc6a97b 100644 --- a/lib/src/common/network_utils.cc +++ b/lib/src/common/network_utils.cc @@ -195,6 +195,8 @@ bool bind_addr(int fd, const sockaddr_in& addr_in) perror("bind()"); return false; } + srslog::fetch_basic_logger(LOGSERVICE) + .debug("Successfully bound to address %s:%d", get_ip(addr_in).c_str(), get_port(addr_in)); return true; } @@ -206,7 +208,11 @@ bool bind_addr(int fd, const char* bind_addr_str, int port, sockaddr_in* addr_re .error("Failed to convert IP address (%s) to sockaddr_in struct", bind_addr_str); return false; } - bind_addr(fd, addr_tmp); + + if (not bind_addr(fd, addr_tmp)) { + return false; + } + if (addr_result != nullptr) { *addr_result = addr_tmp; } From 7155de91cacb4e986d0eb5a3a44e1ada4dd71194 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 23 Sep 2021 10:13:18 +0100 Subject: [PATCH 12/60] Added command to forcefully flush the buffers on srsenb and srsue. --- srsenb/src/main.cc | 8 ++++++++ srsue/src/main.cc | 3 +++ 2 files changed, 11 insertions(+) diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index ab7f1485a..fa8199aa3 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -495,6 +495,13 @@ static void execute_cmd(metrics_stdout* metrics, srsenb::enb_command_interface* // Set cell gain control->cmd_cell_gain(cell_id, gain_db); + } else if (cmd[0] == "flush") { + if (cmd.size() != 1) { + cout << "Usage: " << cmd[0] << endl; + return; + } + srslog::flush(); + cout << "Flushed log file buffers" << endl; } else { cout << "Available commands: " << endl; cout << " t: starts console trace" << endl; @@ -502,6 +509,7 @@ static void execute_cmd(metrics_stdout* metrics, srsenb::enb_command_interface* cout << " cell_gain: set relative cell gain" << endl; cout << " sleep: pauses the commmand line operation for a given time in seconds" << endl; cout << " p: starts MAC padding" << endl; + cout << " flush: flushes the buffers for the log file" << endl; cout << endl; } } diff --git a/srsue/src/main.cc b/srsue/src/main.cc index b80f8a292..4fcee9c0a 100644 --- a/srsue/src/main.cc +++ b/srsue/src/main.cc @@ -645,6 +645,9 @@ static void* input_loop(void*) } else if (key == "rlf") { simulate_rlf.store(true, std::memory_order_relaxed); cout << "Sending Radio Link Failure" << endl; + } else if (key == "flush") { + srslog::flush(); + cout << "Flushed log file buffers" << endl; } else if (key == "q") { // let the signal handler do the job raise(SIGTERM); From 65a2b35f09539b17cd5a9367492a014aa3c59a94 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Thu, 23 Sep 2021 14:13:07 +0100 Subject: [PATCH 13/60] Fix not checking initialization of S11 in MME. Fixed typo. --- lib/test/common/network_utils_test.cc | 4 ++-- srsepc/src/mme/s1ap.cc | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/test/common/network_utils_test.cc b/lib/test/common/network_utils_test.cc index c63fd97e3..31fbe2b4c 100644 --- a/lib/test/common/network_utils_test.cc +++ b/lib/test/common/network_utils_test.cc @@ -122,8 +122,8 @@ int test_sctp_bind_error() &sock, srsran::net_utils::socket_type::seqpacket, "1.1.1.1", 8000)); // Bogus IP address // should not be able to bind TESTASSERT(srsran::net_utils::sctp_init_socket( - &sock, srsran::net_utils::socket_type::seqpacket, "127.0.0.1", 8000)); // Bogus IP address - // should not be able to bind + &sock, srsran::net_utils::socket_type::seqpacket, "127.0.0.1", 8000)); // Good IP address + // should be able to bind return SRSRAN_SUCCESS; } diff --git a/srsepc/src/mme/s1ap.cc b/srsepc/src/mme/s1ap.cc index b652198c0..9b901ddf8 100644 --- a/srsepc/src/mme/s1ap.cc +++ b/srsepc/src/mme/s1ap.cc @@ -78,8 +78,12 @@ int s1ap::init(const s1ap_args_t& s1ap_args) // Get pointer to GTP-C class m_mme_gtpc = mme_gtpc::get_instance(); + // Initialize S1-MME m_s1mme = enb_listen(); + if (m_s1mme == SRSRAN_ERROR) { + return SRSRAN_ERROR; + } // Init PCAP m_pcap_enable = s1ap_args.pcap_enable; From c6226b0d9485d4b518a13e89aa587c3d95bf8385 Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 20 Oct 2021 11:40:13 +0100 Subject: [PATCH 14/60] lte,enb,rrc: parse cellIndividualOffset in rr.conf and propagate it to measConfig sent to UE --- .../interfaces/enb_rrc_interface_types.h | 12 +++---- srsenb/rr.conf.example | 1 + srsenb/src/enb_cfg_parser.cc | 11 +++--- srsenb/src/stack/rrc/ue_meas_cfg.cc | 4 +-- srsenb/test/rrc/rrc_meascfg_test.cc | 34 +++++++++---------- srsenb/test/rrc/test_helpers.cc | 10 +++--- 6 files changed, 37 insertions(+), 35 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_rrc_interface_types.h b/lib/include/srsran/interfaces/enb_rrc_interface_types.h index 443c873f0..998dfc8ea 100644 --- a/lib/include/srsran/interfaces/enb_rrc_interface_types.h +++ b/lib/include/srsran/interfaces/enb_rrc_interface_types.h @@ -28,12 +28,12 @@ struct scell_cfg_t { // Cell to measure for Handover struct meas_cell_cfg_t { - uint32_t earfcn; - uint16_t pci; - uint32_t eci; - float q_offset; - uint32_t allowed_meas_bw; - bool direct_forward_path_available; + uint32_t earfcn; + uint16_t pci; + uint32_t eci; + asn1::rrc::q_offset_range_e cell_individual_offset; + uint32_t allowed_meas_bw; + bool direct_forward_path_available; }; // neigh measurement Cell info diff --git a/srsenb/rr.conf.example b/srsenb/rr.conf.example index e5d6fd02c..78b2df154 100644 --- a/srsenb/rr.conf.example +++ b/srsenb/rr.conf.example @@ -84,6 +84,7 @@ cell_list = pci = 2; //direct_forward_path_available = false; //allowed_meas_bw = 6; + //cell_individual_offset = 0; } ); diff --git a/srsenb/src/enb_cfg_parser.cc b/srsenb/src/enb_cfg_parser.cc index 1bcd57b4c..2897f333e 100644 --- a/srsenb/src/enb_cfg_parser.cc +++ b/srsenb/src/enb_cfg_parser.cc @@ -767,13 +767,14 @@ static int parse_meas_cell_list(rrc_meas_cfg_t* meas_cfg, Setting& root) { meas_cfg->meas_cells.resize(root.getLength()); for (uint32_t i = 0; i < meas_cfg->meas_cells.size(); ++i) { - auto& cell = meas_cfg->meas_cells[i]; - cell.earfcn = root[i]["dl_earfcn"]; - cell.pci = (unsigned int)root[i]["pci"] % SRSRAN_NUM_PCI; - cell.eci = (unsigned int)root[i]["eci"]; - cell.q_offset = 0; // LIBLTE_RRC_Q_OFFSET_RANGE_DB_0; // TODO + auto& cell = meas_cfg->meas_cells[i]; + cell.earfcn = root[i]["dl_earfcn"]; + cell.pci = (unsigned int)root[i]["pci"] % SRSRAN_NUM_PCI; + cell.eci = (unsigned int)root[i]["eci"]; parse_default_field(cell.direct_forward_path_available, root[i], "direct_forward_path_available", false); parse_default_field(cell.allowed_meas_bw, root[i], "allowed_meas_bw", 6u); + asn1_parsers::default_number_to_enum( + cell.cell_individual_offset, root[i], "cell_individual_offset", asn1::rrc::q_offset_range_opts::db0); srsran_assert(srsran::is_lte_cell_nof_prb(cell.allowed_meas_bw), "Invalid measurement Bandwidth"); } return 0; diff --git a/srsenb/src/stack/rrc/ue_meas_cfg.cc b/srsenb/src/stack/rrc/ue_meas_cfg.cc index 7a30949eb..f5fc06d4a 100644 --- a/srsenb/src/stack/rrc/ue_meas_cfg.cc +++ b/srsenb/src/stack/rrc/ue_meas_cfg.cc @@ -84,8 +84,8 @@ std::tuple add_cell_enb_cfg(meas_obj_lis bool inserted_flag = true; cells_to_add_mod_s new_cell; - asn1::number_to_enum(new_cell.cell_individual_offset, (uint8_t)cellcfg.q_offset); - new_cell.pci = cellcfg.pci; + new_cell.cell_individual_offset = cellcfg.cell_individual_offset; + new_cell.pci = cellcfg.pci; std::pair ret = find_cell(meas_obj_list, cellcfg.earfcn, cellcfg.pci); diff --git a/srsenb/test/rrc/rrc_meascfg_test.cc b/srsenb/test/rrc/rrc_meascfg_test.cc index 69f9b0cb5..2443946c2 100644 --- a/srsenb/test/rrc/rrc_meascfg_test.cc +++ b/srsenb/test/rrc/rrc_meascfg_test.cc @@ -31,14 +31,14 @@ namespace srsenb { */ int test_correct_meascfg_insertion() { - meas_cell_cfg_t cell1 = generate_cell1(), cell2{}, cell3{}, cell4{}; - cell2 = cell1; - cell2.pci = 2; - cell2.eci = 0x19C02; - cell3 = cell1; - cell3.earfcn = 2850; - cell4 = cell1; - cell4.q_offset = 1; + meas_cell_cfg_t cell1 = generate_cell1(), cell2{}, cell3{}, cell4{}; + cell2 = cell1; + cell2.pci = 2; + cell2.eci = 0x19C02; + cell3 = cell1; + cell3.earfcn = 2850; + cell4 = cell1; + cell1.cell_individual_offset = asn1::rrc::q_offset_range_opts::db1; report_cfg_eutra_s rep1 = generate_rep1(); @@ -108,13 +108,13 @@ int test_correct_meascfg_calculation() meas_cfg_s src_var{}, target_var{}; meas_cell_cfg_t cell1{}, cell2{}; - cell1.earfcn = 3400; - cell1.pci = 1; - cell1.q_offset = 0; - cell1.eci = 0x19C01; - cell2 = cell1; - cell2.pci = 2; - cell2.eci = 0x19C02; + cell1.earfcn = 3400; + cell1.pci = 1; + cell1.cell_individual_offset = asn1::rrc::q_offset_range_opts::db0; + cell1.eci = 0x19C01; + cell2 = cell1; + cell2.pci = 2; + cell2.eci = 0x19C02; report_cfg_eutra_s rep1 = generate_rep1(), rep2{}, rep3{}; rep2 = rep1; @@ -169,8 +169,8 @@ int test_correct_meascfg_calculation() TESTASSERT(result_meascfg.report_cfg_to_add_mod_list.size() == 0); // TEST 3: Cell is added to cellsToAddModList if just a field was updated - cell1.q_offset = 5; - src_var = target_var; + cell1.cell_individual_offset = asn1::rrc::q_offset_range_opts::db5; + src_var = target_var; add_cell_enb_cfg(target_var.meas_obj_to_add_mod_list, cell1); TESTASSERT(compute_diff_meascfg(src_var, target_var, result_meascfg)); TESTASSERT(result_meascfg.meas_obj_to_add_mod_list_present); diff --git a/srsenb/test/rrc/test_helpers.cc b/srsenb/test/rrc/test_helpers.cc index 0af028974..e9756c188 100644 --- a/srsenb/test/rrc/test_helpers.cc +++ b/srsenb/test/rrc/test_helpers.cc @@ -173,10 +173,10 @@ namespace srsenb { meas_cell_cfg_t generate_cell1() { meas_cell_cfg_t cell1{}; - cell1.earfcn = 3400; - cell1.pci = 1; - cell1.q_offset = 0; - cell1.eci = 0x19C01; + cell1.earfcn = 3400; + cell1.pci = 1; + cell1.cell_individual_offset = asn1::rrc::q_offset_range_opts::db0; + cell1.eci = 0x19C01; return cell1; } @@ -198,7 +198,7 @@ report_cfg_eutra_s generate_rep1() bool is_cell_cfg_equal(const meas_cell_cfg_t& cfg, const cells_to_add_mod_s& cell) { - return cfg.pci == cell.pci and cell.cell_individual_offset.to_number() == (int8_t)round(cfg.q_offset); + return cfg.pci == cell.pci and cell.cell_individual_offset == cell.cell_individual_offset; } } // namespace srsenb From fd998dac150e8c8e1e6f116cadf92b94eebf520c Mon Sep 17 00:00:00 2001 From: Francisco Date: Wed, 20 Oct 2021 12:15:50 +0100 Subject: [PATCH 15/60] lte,enb,rrc: fix rrc_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 2443946c2..4f39d1980 100644 --- a/srsenb/test/rrc/rrc_meascfg_test.cc +++ b/srsenb/test/rrc/rrc_meascfg_test.cc @@ -38,7 +38,7 @@ int test_correct_meascfg_insertion() cell3 = cell1; cell3.earfcn = 2850; cell4 = cell1; - cell1.cell_individual_offset = asn1::rrc::q_offset_range_opts::db1; + cell4.cell_individual_offset = asn1::rrc::q_offset_range_opts::db1; report_cfg_eutra_s rep1 = generate_rep1(); From 95b4a92f5f77be659b2a582305a999812b720ee3 Mon Sep 17 00:00:00 2001 From: faluco Date: Thu, 14 Oct 2021 20:07:37 +0200 Subject: [PATCH 16/60] Clarify the error messages printed when trying to open a RF device. --- lib/src/phy/rf/rf_imp.c | 39 ++++++++++++++++++++++++++----------- lib/src/phy/rf/rf_zmq_imp.c | 4 +++- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/lib/src/phy/rf/rf_imp.c b/lib/src/phy/rf/rf_imp.c index f7b55a502..119dda93b 100644 --- a/lib/src/phy/rf/rf_imp.c +++ b/lib/src/phy/rf/rf_imp.c @@ -94,6 +94,14 @@ int srsran_rf_open_devname(srsran_rf_t* rf, const char* devname, char* args, uin { rf->thread_gain_run = false; + bool no_rf_devs_detected = true; + printf("Available RF device list:"); + for (unsigned int i = 0; available_devices[i]; i++) { + no_rf_devs_detected = false; + printf(" %s ", available_devices[i]->name); + } + printf("%s\n", no_rf_devs_detected ? " " : ""); + // Try to open the device if name is provided if (devname && devname[0] != '\0') { int i = 0; @@ -104,21 +112,30 @@ int srsran_rf_open_devname(srsran_rf_t* rf, const char* devname, char* args, uin } i++; } + + ERROR("RF device '%s' not found. Please check the available srsRAN CMAKE options to verify if this device is being " + "detected in your system", + devname); // provided device not found, abort return SRSRAN_ERROR; - } else { - // auto-mode, try to open in order of apperance in available_devices[] array - int i = 0; - while (available_devices[i] != NULL) { - if (!available_devices[i]->srsran_rf_open_multi(args, &rf->handler, nof_channels)) { - rf->dev = available_devices[i]; - return SRSRAN_SUCCESS; - } - i++; - } } - ERROR("No compatible RF frontend found"); + // auto-mode, try to open in order of apperance in available_devices[] array + int i = 0; + while (available_devices[i] != NULL) { + printf("Trying to open RF device '%s'\n", available_devices[i]->name); + if (!available_devices[i]->srsran_rf_open_multi(args, &rf->handler, nof_channels)) { + rf->dev = available_devices[i]; + printf("RF device '%s' successfully opened\n", available_devices[i]->name); + return SRSRAN_SUCCESS; + } + printf("Unable to open RF device '%s'\n", available_devices[i]->name); + i++; + } + + ERROR( + "Failed to open a RF frontend device. Please check the available srsRAN CMAKE options to verify what RF frontend " + "devices have been detected in your system"); return SRSRAN_ERROR; } diff --git a/lib/src/phy/rf/rf_zmq_imp.c b/lib/src/phy/rf/rf_zmq_imp.c index 582f47a3b..6e8f748a8 100644 --- a/lib/src/phy/rf/rf_zmq_imp.c +++ b/lib/src/phy/rf/rf_zmq_imp.c @@ -278,7 +278,9 @@ int rf_zmq_open_multi(char* args, void** h, uint32_t nof_channels) } } } else { - fprintf(stderr, "[zmq] Error: RF device args are required for ZMQ no-RF module\n"); + fprintf(stderr, + "[zmq] Error: No device 'args' option has been set. Please make sure to set this option to be able to " + "use the ZMQ no-RF module\n"); goto clean_exit; } From cfec29548c6ed705c090cb484f00d4aa7225415d Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 19 Oct 2021 14:20:51 +0200 Subject: [PATCH 17/60] Do not reset MAC UE object during C-RNTI update --- srsenb/src/stack/mac/mac.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 88c919f8f..489ae8af9 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -218,7 +218,7 @@ int mac::ue_set_crnti(uint16_t temp_crnti, uint16_t crnti, const sched_interface srsran::rwlock_read_guard lock(rwlock); if (temp_crnti != crnti) { // if C-RNTI is changed, it corresponds to older user. Handover scenario. - ue_db[crnti]->reset(); + // ue_db[crnti]->reset(); } else { // Schedule ConRes Msg4 scheduler.dl_mac_buffer_state(crnti, (uint32_t)srsran::dl_sch_lcid::CON_RES_ID); From 42392229093a6e6fdf281a654456a00b9c6af206 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 19 Oct 2021 14:21:13 +0200 Subject: [PATCH 18/60] Do not abort tsan --- lib/include/srsran/common/tsan_options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srsran/common/tsan_options.h b/lib/include/srsran/common/tsan_options.h index 18e5bace0..0c4eb2ff1 100644 --- a/lib/include/srsran/common/tsan_options.h +++ b/lib/include/srsran/common/tsan_options.h @@ -31,7 +31,7 @@ extern "C" { const char* __tsan_default_options() { - return "halt_on_error=1:abort_on_error=1:report_signal_unsafe=0" + return "halt_on_error=0:abort_on_error=0:report_signal_unsafe=0" ":allocator_may_return_null=1"; } From c479a1e51e8580b2fe1f044acfa1fb8d04bba66f Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 19 Oct 2021 14:56:19 +0200 Subject: [PATCH 19/60] srsenb: Handle error in decode_pusch to avoid logging PUSCH with 0 rnti --- srsenb/hdr/phy/lte/cc_worker.h | 2 +- srsenb/src/phy/lte/cc_worker.cc | 19 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/srsenb/hdr/phy/lte/cc_worker.h b/srsenb/hdr/phy/lte/cc_worker.h index d04b0b269..2edbe6547 100644 --- a/srsenb/hdr/phy/lte/cc_worker.h +++ b/srsenb/hdr/phy/lte/cc_worker.h @@ -60,7 +60,7 @@ private: int encode_pdsch(stack_interface_phy_lte::dl_sched_grant_t* grants, uint32_t nof_grants); int encode_pmch(stack_interface_phy_lte::dl_sched_grant_t* grant, srsran_mbsfn_cfg_t* mbsfn_cfg); - void decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_grant, + bool decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_grant, srsran_ul_cfg_t& ul_cfg, srsran_pusch_res_t& pusch_res); void decode_pusch(stack_interface_phy_lte::ul_sched_grant_t* grants, uint32_t nof_pusch); diff --git a/srsenb/src/phy/lte/cc_worker.cc b/srsenb/src/phy/lte/cc_worker.cc index 1f817fe4e..5a7478b7c 100644 --- a/srsenb/src/phy/lte/cc_worker.cc +++ b/srsenb/src/phy/lte/cc_worker.cc @@ -253,7 +253,7 @@ void cc_worker::work_dl(const srsran_dl_sf_cfg_t& dl_sf_cfg, } } -void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_grant, +bool cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_grant, srsran_ul_cfg_t& ul_cfg, srsran_pusch_res_t& pusch_res) { @@ -261,19 +261,19 @@ void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_ // Invalid RNTI if (rnti == SRSRAN_INVALID_RNTI) { - return; + return false; } // RNTI does not exist if (ue_db.count(rnti) == 0) { - return; + return false; } // Get UE configuration if (phy->ue_db.get_ul_config(rnti, cc_idx, ul_cfg) < SRSRAN_SUCCESS) { // It could happen that the UL configuration is missing due to intra-enb HO which is not an error Info("Failed retrieving UL configuration for cc=%d rnti=0x%x", cc_idx, rnti); - return; + return false; } // Fill UCI configuration @@ -284,7 +284,7 @@ void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_ srsran_pusch_grant_t& grant = ul_cfg.pusch.grant; if (srsran_ra_ul_dci_to_grant(&enb_ul.cell, &ul_sf, &ul_cfg.hopping, &ul_grant.dci, &grant)) { Error("Computing PUSCH dci for RNTI %x", rnti); - return; + return false; } // Handle Format0 adaptive retx @@ -293,7 +293,7 @@ void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_ int rv_idx = grant.tb.rv; if (phy->ue_db.get_last_ul_tb(rnti, cc_idx, ul_grant.pid, grant.tb) < SRSRAN_SUCCESS) { Error("Error retrieving last UL TB for RNTI %x, CC %d, PID %d", rnti, cc_idx, ul_grant.pid); - return; + return false; } grant.tb.rv = rv_idx; Info("Adaptive retx: rnti=0x%x, pid=%d, rv_idx=%d, mcs=%d, old_tbs=%d", @@ -314,7 +314,7 @@ void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_ if (pusch_res.data) { if (srsran_enb_ul_get_pusch(&enb_ul, &ul_sf, &ul_cfg.pusch, &pusch_res)) { Error("Decoding PUSCH for RNTI %x", rnti); - return; + return false; } } // Save PHICH scheduling for this user. Each user can have just 1 PUSCH dci per TTI @@ -344,6 +344,7 @@ void cc_worker::decode_pusch_rnti(stack_interface_phy_lte::ul_sched_grant_t& ul_ // Save metrics stats ue_db[rnti]->metrics_ul(ul_grant.dci.tb.mcs_idx, 0, enb_ul.chest_res.snr_db, pusch_res.avg_iterations_block); } + return true; } void cc_worker::decode_pusch(stack_interface_phy_lte::ul_sched_grant_t* grants, uint32_t nof_pusch) @@ -358,7 +359,9 @@ void cc_worker::decode_pusch(stack_interface_phy_lte::ul_sched_grant_t* grants, srsran_ul_cfg_t ul_cfg = {}; // Decodes PUSCH for the given grant - decode_pusch_rnti(ul_grant, ul_cfg, pusch_res); + if (!decode_pusch_rnti(ul_grant, ul_cfg, pusch_res)) { + return; + } // Notify MAC new received data and HARQ Indication value if (ul_grant.data != nullptr) { From 2aeb32533f6518f5baf60f76822da674b17550bc Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 19 Oct 2021 15:05:00 +0200 Subject: [PATCH 20/60] Print error setting ul grant --- srsenb/src/phy/phy_ue_db.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsenb/src/phy/phy_ue_db.cc b/srsenb/src/phy/phy_ue_db.cc index a5fa379e9..9e86a60d1 100644 --- a/srsenb/src/phy/phy_ue_db.cc +++ b/srsenb/src/phy/phy_ue_db.cc @@ -784,6 +784,7 @@ int phy_ue_db::set_ul_grant_available(uint32_t tti, const stack_interface_phy_lt // Check that eNb Cell/Carrier is active for the given RNTI if (_assert_active_enb_cc(rnti, enb_cc_idx) != SRSRAN_SUCCESS) { ret = SRSRAN_ERROR; + srslog::fetch_basic_logger("RRC-NR").error("Error setting grant for rnti=0x%x, cc=%d\n", rnti, enb_cc_idx); continue; } // Rise Grant available flag From 0de984d12f9010b8c1f1d56313c6a14de81a2230 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 19 Oct 2021 16:42:12 +0200 Subject: [PATCH 21/60] srsue: protect access to phy common shared measurement --- srsue/src/phy/phy_common.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index 18248166a..a3c7618eb 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -888,8 +888,11 @@ void phy_common::reset() reset_radio(); sr.reset(); - cur_pathloss = 0; - cur_pusch_power = 0; + { + std::unique_lock lock(meas_mutex); + cur_pathloss = 0; + cur_pusch_power = 0; + } last_ri = 0; // Reset all measurements From bf566fbd29ba8ec6afb7bc6709c9da25e92eecb4 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 19 Oct 2021 17:02:29 +0200 Subject: [PATCH 22/60] radio: protect concurrent access from tx_end and tx --- lib/include/srsran/radio/radio.h | 3 +++ lib/src/radio/radio.cc | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/include/srsran/radio/radio.h b/lib/include/srsran/radio/radio.h index ca1e7bcab..c17fe2b3b 100644 --- a/lib/include/srsran/radio/radio.h +++ b/lib/include/srsran/radio/radio.h @@ -173,6 +173,9 @@ private: */ bool tx_dev(const uint32_t& device_idx, rf_buffer_interface& buffer, const srsran_timestamp_t& tx_time_); + // private unprotected tx_end implementation + void tx_end_nolock(); + /** * Helper method for receiving over a single RF device. This function maps automatically the logical receive buffers * to the physical RF buffers for the given device. diff --git a/lib/src/radio/radio.cc b/lib/src/radio/radio.cc index a1b2e2952..29a32e5ff 100644 --- a/lib/src/radio/radio.cc +++ b/lib/src/radio/radio.cc @@ -539,7 +539,7 @@ bool radio::tx_dev(const uint32_t& device_idx, rf_buffer_interface& buffer, cons // if the gap is bigger than TX_MAX_GAP_ZEROS, stop burst if (fabs(srsran_timestamp_real(&ts_overlap)) > tx_max_gap_zeros) { logger.info("Detected RF gap of %.1f us. Sending end-of-burst.", srsran_timestamp_real(&ts_overlap) * 1.0e6); - tx_end(); + tx_end_nolock(); } else { logger.debug("Detected RF gap of %.1f us. Tx'ing zeroes.", srsran_timestamp_real(&ts_overlap) * 1.0e6); // Otherwise, transmit zeros @@ -592,6 +592,12 @@ bool radio::tx_dev(const uint32_t& device_idx, rf_buffer_interface& buffer, cons } void radio::tx_end() +{ + std::unique_lock lock(tx_mutex); + tx_end_nolock(); +} + +void radio::tx_end_nolock() { if (!is_initialized) { return; From 80c48a8b01d79403b9a5c7fdac9123d815356d3c Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 19 Oct 2021 17:06:43 +0200 Subject: [PATCH 23/60] rlc: protect access to tx_enabled --- lib/include/srsran/rlc/rlc_am_lte.h | 2 ++ lib/src/rlc/rlc_am_lte.cc | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/include/srsran/rlc/rlc_am_lte.h b/lib/include/srsran/rlc/rlc_am_lte.h index 0c3f53c18..fb6489530 100644 --- a/lib/include/srsran/rlc/rlc_am_lte.h +++ b/lib/include/srsran/rlc/rlc_am_lte.h @@ -387,6 +387,8 @@ private: void set_bsr_callback(bsr_callback_t callback); private: + void stop_nolock(); + int build_status_pdu(uint8_t* payload, uint32_t nof_bytes); int build_retx_pdu(uint8_t* payload, uint32_t nof_bytes); int build_segment(uint8_t* payload, uint32_t nof_bytes, rlc_amd_retx_t retx); diff --git a/lib/src/rlc/rlc_am_lte.cc b/lib/src/rlc/rlc_am_lte.cc index b32f910c6..b4fc46321 100644 --- a/lib/src/rlc/rlc_am_lte.cc +++ b/lib/src/rlc/rlc_am_lte.cc @@ -343,7 +343,11 @@ bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_) void rlc_am_lte::rlc_am_lte_tx::stop() { std::lock_guard lock(mutex); + stop_nolock(); +} +void rlc_am_lte::rlc_am_lte_tx::stop_nolock() +{ empty_queue_nolock(); tx_enabled = false; @@ -396,7 +400,8 @@ void rlc_am_lte::rlc_am_lte_tx::empty_queue_nolock() void rlc_am_lte::rlc_am_lte_tx::reestablish() { - stop(); + std::lock_guard lock(mutex); + stop_nolock(); tx_enabled = true; } From 09cec9ca5ca7d1c3f49fd88f422cace6eedf4ac9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 19 Oct 2021 17:22:31 +0200 Subject: [PATCH 24/60] srsenb,phy: do not get reference to ul_grants, do a copy instead to protect concurrent access --- srsenb/hdr/phy/phy_common.h | 2 +- srsenb/src/phy/phy_common.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/hdr/phy/phy_common.h b/srsenb/hdr/phy/phy_common.h index 07e81fde3..aab5675c3 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -227,7 +227,7 @@ public: void set_mch_period_stop(uint32_t stop); // Getters and setters for ul grants which need to be shared between workers - const stack_interface_phy_lte::ul_sched_list_t& get_ul_grants(uint32_t tti); + const stack_interface_phy_lte::ul_sched_list_t get_ul_grants(uint32_t tti); void set_ul_grants(uint32_t tti, const stack_interface_phy_lte::ul_sched_list_t& ul_grants); void clear_grants(uint16_t rnti); diff --git a/srsenb/src/phy/phy_common.cc b/srsenb/src/phy/phy_common.cc index 1cc6c7f80..89d67190e 100644 --- a/srsenb/src/phy/phy_common.cc +++ b/srsenb/src/phy/phy_common.cc @@ -85,7 +85,7 @@ void phy_common::clear_grants(uint16_t rnti) } } -const stack_interface_phy_lte::ul_sched_list_t& phy_common::get_ul_grants(uint32_t tti) +const stack_interface_phy_lte::ul_sched_list_t phy_common::get_ul_grants(uint32_t tti) { std::lock_guard lock(grant_mutex); return ul_grants[tti]; From 7920e084b889c5791f4f9ec7556005d71fa0d69a Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 19 Oct 2021 21:48:28 +0200 Subject: [PATCH 25/60] Revert "Do not abort tsan" This reverts commit e8e1d101c553912f733070e71d020a33ec895280. --- lib/include/srsran/common/tsan_options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srsran/common/tsan_options.h b/lib/include/srsran/common/tsan_options.h index 0c4eb2ff1..18e5bace0 100644 --- a/lib/include/srsran/common/tsan_options.h +++ b/lib/include/srsran/common/tsan_options.h @@ -31,7 +31,7 @@ extern "C" { const char* __tsan_default_options() { - return "halt_on_error=0:abort_on_error=0:report_signal_unsafe=0" + return "halt_on_error=1:abort_on_error=1:report_signal_unsafe=0" ":allocator_may_return_null=1"; } From 6bdefa33e40455a23927e5ea5bc9d6db3c7a0a04 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Tue, 19 Oct 2021 21:49:49 +0200 Subject: [PATCH 26/60] fix minor issues --- srsenb/src/phy/phy_ue_db.cc | 2 +- srsenb/src/stack/mac/mac.cc | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/srsenb/src/phy/phy_ue_db.cc b/srsenb/src/phy/phy_ue_db.cc index 9e86a60d1..9d6761a8f 100644 --- a/srsenb/src/phy/phy_ue_db.cc +++ b/srsenb/src/phy/phy_ue_db.cc @@ -784,7 +784,7 @@ int phy_ue_db::set_ul_grant_available(uint32_t tti, const stack_interface_phy_lt // Check that eNb Cell/Carrier is active for the given RNTI if (_assert_active_enb_cc(rnti, enb_cc_idx) != SRSRAN_SUCCESS) { ret = SRSRAN_ERROR; - srslog::fetch_basic_logger("RRC-NR").error("Error setting grant for rnti=0x%x, cc=%d\n", rnti, enb_cc_idx); + srslog::fetch_basic_logger("PHY").error("Error setting grant for rnti=0x%x, cc=%d\n", rnti, enb_cc_idx); continue; } // Rise Grant available flag diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 489ae8af9..ebf520449 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -216,10 +216,7 @@ int mac::ue_rem(uint16_t rnti) int mac::ue_set_crnti(uint16_t temp_crnti, uint16_t crnti, const sched_interface::ue_cfg_t& cfg) { srsran::rwlock_read_guard lock(rwlock); - if (temp_crnti != crnti) { - // if C-RNTI is changed, it corresponds to older user. Handover scenario. - // ue_db[crnti]->reset(); - } else { + if (temp_crnti == crnti) { // Schedule ConRes Msg4 scheduler.dl_mac_buffer_state(crnti, (uint32_t)srsran::dl_sch_lcid::CON_RES_ID); } From 39bfcf4a5cd7aee21431aeb7ffe7fd55c8a6d6d8 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 20 Oct 2021 11:20:46 +0200 Subject: [PATCH 27/60] Add UCI valid in NR PUSCH info --- lib/src/phy/phch/pusch_nr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index c7ab719d7..090706664 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -1054,11 +1054,12 @@ uint32_t srsran_pusch_nr_rx_info(const srsran_pusch_nr_t* q, len += pusch_nr_grant_info(q, cfg, grant, res, &str[len], str_len - len); if (res != NULL && srsran_uci_nr_total_bits(&cfg->uci) > 0) { - len = srsran_print_check(str, str_len, len, "UCI: "); srsran_uci_data_nr_t uci_data = {}; uci_data.cfg = cfg->uci; uci_data.value = res->uci; len += srsran_uci_nr_info(&uci_data, &str[len], str_len - len); + + len = srsran_print_check(str, str_len, len, "valid=%c ", res->uci.valid ? 'y' : 'n'); } if (q->meas_time_en) { From 96e49980c64d13ac091a5ec0b3076cd295f951aa Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 20 Oct 2021 11:21:12 +0200 Subject: [PATCH 28/60] Fix gNb dummy stack process ID selection --- test/phy/dummy_gnb_stack.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/phy/dummy_gnb_stack.h b/test/phy/dummy_gnb_stack.h index cbc88d002..4c86daf24 100644 --- a/test/phy/dummy_gnb_stack.h +++ b/test/phy/dummy_gnb_stack.h @@ -276,7 +276,7 @@ private: // Set softbuffer pusch_cfg.grant.tb[0].softbuffer.rx = - &rx_harq_proc[slot_cfg.idx].get_softbuffer(dci.ndi, pusch_cfg.grant.tb[0].tbs); + &rx_harq_proc[dci.pid].get_softbuffer(dci.ndi, pusch_cfg.grant.tb[0].tbs); // Push scheduling results dl_sched.pdcch_ul.push_back(pdcch); From eace81d6138bbbbbcf416ced59867bd1df816948 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Wed, 20 Oct 2021 17:12:36 +0200 Subject: [PATCH 29/60] Fix UCI multiplexing for NR PUSCH --- lib/src/common/phy_cfg_nr_default.cc | 12 ++++--- lib/src/phy/phch/pusch_nr.c | 50 +++++++++++++++++----------- 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/lib/src/common/phy_cfg_nr_default.cc b/lib/src/common/phy_cfg_nr_default.cc index d457aa6cd..0cd507c7a 100644 --- a/lib/src/common/phy_cfg_nr_default.cc +++ b/lib/src/common/phy_cfg_nr_default.cc @@ -272,10 +272,14 @@ void phy_cfg_nr_default_t::make_pusch_default(srsran_sch_hl_cfg_nr_t& pusch) // Setup PUSCH DMRS type A position pusch.typeA_pos = srsran_dmrs_sch_typeA_pos_2; - pusch.scaling = 1.0f; - pusch.beta_offsets.fix_ack = 12.625f; - pusch.beta_offsets.fix_csi1 = 2.25f; - pusch.beta_offsets.fix_csi2 = 2.25f; + pusch.scaling = 1.0f; + pusch.beta_offsets.ack_index1 = 9; + pusch.beta_offsets.ack_index2 = 9; + pusch.beta_offsets.ack_index3 = 9; + pusch.beta_offsets.csi1_index1 = 6; + pusch.beta_offsets.csi1_index2 = 6; + pusch.beta_offsets.csi2_index1 = 6; + pusch.beta_offsets.csi2_index2 = 6; } void phy_cfg_nr_default_t::make_pucch_custom_one(srsran_pucch_nr_hl_cfg_t& pucch) diff --git a/lib/src/phy/phch/pusch_nr.c b/lib/src/phy/phch/pusch_nr.c index 090706664..775f6c4b0 100644 --- a/lib/src/phy/phch/pusch_nr.c +++ b/lib/src/phy/phch/pusch_nr.c @@ -378,13 +378,11 @@ static int pusch_nr_gen_mux_uci(srsran_pusch_nr_t* q, const srsran_uci_cfg_nr_t* // the number of reserved resource elements for potential HARQ-ACK transmission is calculated according to Clause // 6.3.2.4.2.1, by setting O_ACK = 2 ; G_ack_rvd = srsran_uci_nr_pusch_ack_nof_bits(&cfg->pusch, 2); - - // Disable non reserved HARQ-ACK bits - G_ack = 0; } // Counters uint32_t m_ack_count = 0; + uint32_t m_rvd_count = 0; uint32_t m_csi1_count = 0; uint32_t m_csi2_count = 0; uint32_t m_ulsch_count = 0; @@ -411,15 +409,26 @@ static int pusch_nr_gen_mux_uci(srsran_pusch_nr_t* q, const srsran_uci_cfg_nr_t* // Compute HARQ-ACK bits multiplexing uint32_t ack_d = 0; uint32_t ack_m_re_count = 0; + uint32_t rvd_d = 0; + uint32_t rvd_m_re_count = 0; if (l >= l1) { - if (cfg->ack.count <= 2 && m_ack_count < G_ack_rvd) { - ack_d = 1; - ack_m_re_count = M_ulsch_sc; - if (G_ack_rvd - m_ack_count < M_uci_sc * Nl * Qm) { - ack_d = (M_uci_sc * Nl * Qm) / (G_ack_rvd - m_ack_count); - ack_m_re_count = SRSRAN_CEIL(G_ack_rvd - m_ack_count, Nl * Qm); + if (cfg->ack.count <= 2 && m_rvd_count < G_ack_rvd) { + rvd_d = 1; + rvd_m_re_count = M_ulsch_sc; + if (G_ack_rvd - m_rvd_count < M_uci_sc * Nl * Qm) { + rvd_d = (M_uci_sc * Nl * Qm) / (G_ack_rvd - m_rvd_count); + rvd_m_re_count = SRSRAN_CEIL(G_ack_rvd - m_rvd_count, Nl * Qm); + } + M_uci_rvd = rvd_m_re_count; + + if (m_ack_count < G_ack) { + ack_d = 1; + ack_m_re_count = M_uci_rvd; + if (G_ack - m_ack_count < M_uci_rvd * Nl * Qm) { + ack_d = (M_uci_rvd * Nl * Qm) / (G_ack - m_ack_count); + ack_m_re_count = SRSRAN_CEIL(G_ack - m_ack_count, Nl * Qm); + } } - M_uci_rvd = ack_m_re_count; } else if (m_ack_count < G_ack) { ack_d = 1; ack_m_re_count = M_ulsch_sc; @@ -460,14 +469,14 @@ static int pusch_nr_gen_mux_uci(srsran_pusch_nr_t* q, const srsran_uci_cfg_nr_t* // Leave the rest for UL-SCH uint32_t ulsch_m_re_count = M_uci_sc; - for (uint32_t i = 0, csi1_i = 0, csi2_i = 0; i < cfg->pusch.M_pusch_sc[l]; i++) { - // Check if RE is reserved for ACK + for (uint32_t i = 0, csi1_i = 0, csi2_i = 0, rvd_i = 0; i < cfg->pusch.M_pusch_sc[l]; i++) { + // Check if RE is reserved bool reserved = false; - if (ack_m_re_count != 0 && i % ack_d == 0 && m_ack_count < G_ack_rvd) { + if (rvd_m_re_count != 0 && i % rvd_d == 0 && m_rvd_count < G_ack_rvd) { reserved = true; } - if (ack_m_re_count != 0 && i % ack_d == 0 && m_ack_count < G_ack) { + if (G_ack_rvd == 0 && ack_m_re_count != 0 && i % ack_d == 0 && m_ack_count < G_ack) { for (uint32_t j = 0; j < Nl * Qm; j++) { pos_ack[m_ack_count++] = m_all_count + j; } @@ -498,14 +507,15 @@ static int pusch_nr_gen_mux_uci(srsran_pusch_nr_t* q, const srsran_uci_cfg_nr_t* // Set reserved bits only if there are ACK bits if (reserved) { - if (cfg->ack.count > 0) { + if (ack_m_re_count != 0 && rvd_i % ack_d == 0 && m_ack_count < G_ack) { for (uint32_t j = 0; j < Nl * Qm; j++) { pos_ack[m_ack_count++] = m_all_count + j; } - } else { - m_ack_count += Nl * Qm; + ack_m_re_count--; } - ack_m_re_count--; + m_rvd_count += Nl * Qm; + rvd_m_re_count--; + rvd_i++; } // Increment all bit counter @@ -531,8 +541,8 @@ static int pusch_nr_gen_mux_uci(srsran_pusch_nr_t* q, const srsran_uci_cfg_nr_t* q->G_ulsch = m_ulsch_count; // Assert Number of bits - if (G_ack_rvd != 0 && G_ack_rvd != m_ack_count && cfg->ack.count > 0) { - ERROR("Not matched %d!=%d", G_ack_rvd, m_ack_count); + if (G_ack_rvd != 0 && G_ack_rvd != m_rvd_count && cfg->ack.count <= 2) { + ERROR("Not matched %d!=%d", G_ack_rvd, m_rvd_count); } if (G_ack != 0 && G_ack != m_ack_count) { ERROR("Not matched %d!=%d", G_ack, m_ack_count); From c096270fc7c680245401a93f6bf516d46ecaddc9 Mon Sep 17 00:00:00 2001 From: Ismael Gomez Date: Thu, 21 Oct 2021 12:40:52 +0200 Subject: [PATCH 30/60] ue,nr: ignore NDI if received on T-CRNTI or RAR --- srsue/hdr/stack/mac_nr/ul_harq_nr.h | 4 ++++ srsue/src/stack/mac_nr/ul_harq_nr.cc | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/srsue/hdr/stack/mac_nr/ul_harq_nr.h b/srsue/hdr/stack/mac_nr/ul_harq_nr.h index 4bb5ac21a..605daa194 100644 --- a/srsue/hdr/stack/mac_nr/ul_harq_nr.h +++ b/srsue/hdr/stack/mac_nr/ul_harq_nr.h @@ -88,6 +88,8 @@ private: std::unique_ptr harq_buffer = nullptr; + void save_grant(const mac_interface_phy_nr::mac_nr_grant_ul_t& grant); + void generate_tx(mac_interface_phy_nr::tb_action_ul_t* action); void generate_new_tx(const mac_interface_phy_nr::mac_nr_grant_ul_t& grant, mac_interface_phy_nr::tb_action_ul_t* action); @@ -104,6 +106,8 @@ private: srsran::ul_harq_cfg_t harq_cfg = {}; ul_harq_metrics_t metrics = {}; std::mutex metrics_mutex; + + const static uint8_t NDI_NOT_SET = 100; }; typedef std::unique_ptr ul_harq_entity_nr_ptr; diff --git a/srsue/src/stack/mac_nr/ul_harq_nr.cc b/srsue/src/stack/mac_nr/ul_harq_nr.cc index 1f4ae8c49..a27eb5f5d 100644 --- a/srsue/src/stack/mac_nr/ul_harq_nr.cc +++ b/srsue/src/stack/mac_nr/ul_harq_nr.cc @@ -144,11 +144,12 @@ void ul_harq_entity_nr::ul_harq_process_nr::reset() nof_retx = 0; harq_buffer = nullptr; current_grant = {}; + reset_ndi(); } void ul_harq_entity_nr::ul_harq_process_nr::reset_ndi() { - current_grant.ndi = false; + current_grant.ndi = NDI_NOT_SET; } uint8_t ul_harq_entity_nr::ul_harq_process_nr::get_ndi() @@ -226,11 +227,21 @@ int ul_harq_entity_nr::ul_harq_process_nr::get_current_tbs() return current_grant.tbs; } +void ul_harq_entity_nr::ul_harq_process_nr::save_grant(const mac_interface_phy_nr::mac_nr_grant_ul_t& grant) +{ + current_grant = grant; + // When determining if NDI has been toggled compared to the value in the previous transmission the MAC entity shall + // ignore NDI received in all uplink grants on PDCCH for its Temporary C-RNTI. + if (grant.is_rar_grant || grant.rnti == harq_entity->mac->get_temp_crnti()) { + reset_ndi(); + } +} + // New transmission (Section 5.4.2.2) void ul_harq_entity_nr::ul_harq_process_nr::generate_new_tx(const mac_interface_phy_nr::mac_nr_grant_ul_t& grant, mac_interface_phy_nr::tb_action_ul_t* action) { - current_grant = grant; + save_grant(grant); nof_retx = 0; logger.info("UL %d: New TX%s, rv=%d, tbs=%d", @@ -252,7 +263,7 @@ void ul_harq_entity_nr::ul_harq_process_nr::generate_retx(const mac_interface_ph logger.info("UL %d: Retx=%d, rv=%d, tbs=%d", pid, nof_retx, grant.rv, grant.tbs); // overwrite original grant - current_grant = grant; + save_grant(grant); generate_tx(action); From 284207dad602ab0b7465f9dd5d5e0766f8abdbc1 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Tue, 19 Oct 2021 13:12:05 +0200 Subject: [PATCH 31/60] WIP: fixing collision in the the users_map Signed-off-by: Carlo Galiotto --- lib/include/srsran/common/bearer_manager.h | 3 ++- lib/src/common/bearer_manager.cc | 7 ++++--- srsenb/hdr/stack/upper/gtpu.h | 4 +++- srsenb/src/stack/upper/gtpu.cc | 21 +++++++++++++-------- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/lib/include/srsran/common/bearer_manager.h b/lib/include/srsran/common/bearer_manager.h index 04cf72bff..4ec7bff81 100644 --- a/lib/include/srsran/common/bearer_manager.h +++ b/lib/include/srsran/common/bearer_manager.h @@ -18,6 +18,7 @@ #include "srsran/common/rwlock_guard.h" #include "srsran/srslog/srslog.h" #include +#include #include namespace srsran { @@ -150,7 +151,7 @@ public: private: srslog::basic_logger& logger; - srsenb::rnti_map_t users_map; + std::unordered_map users_map; }; } // namespace srsenb diff --git a/lib/src/common/bearer_manager.cc b/lib/src/common/bearer_manager.cc index 2c58dac58..d41da94ff 100644 --- a/lib/src/common/bearer_manager.cc +++ b/lib/src/common/bearer_manager.cc @@ -118,12 +118,13 @@ void enb_bearer_manager::add_eps_bearer(uint16_t rnti, uint8_t eps_bearer_id, sr auto user_it = users_map.find(rnti); if (user_it == users_map.end()) { // add empty bearer map - auto p = users_map.insert(rnti, srsran::detail::ue_bearer_manager_impl{}); - if (!p) { + // users_map.emplace( ) returns pair + auto p = users_map.emplace( rnti, srsran::detail::ue_bearer_manager_impl{}); + if (!p.second) { logger.error("Bearers: Unable to add a new bearer map for rnti=0x%x", rnti); return; } - user_it = p.value(); + user_it = p.first; } if (user_it->second.add_eps_bearer(eps_bearer_id, rat, lcid)) { diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index 3fdb9e0a3..7d718f6bc 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -11,6 +11,7 @@ */ #include +#include #include #include "srsenb/hdr/common/common_enb.h" @@ -122,7 +123,8 @@ private: pdcp_interface_gtpu* pdcp = nullptr; srslog::basic_logger& logger; - rnti_map_t ue_teidin_db; + std::unordered_map ue_teidin_db; + rnti_map_t ue_teidin_db_1; tunnel_list_t tunnels; }; diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index e221311e8..10cd9d067 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -50,10 +50,8 @@ const gtpu_tunnel_manager::tunnel* gtpu_tunnel_manager::find_tunnel(uint32_t tei gtpu_tunnel_manager::ue_bearer_tunnel_list* gtpu_tunnel_manager::find_rnti_tunnels(uint16_t rnti) { - if (not ue_teidin_db.contains(rnti)) { - return nullptr; - } - return &ue_teidin_db[rnti]; + auto it = ue_teidin_db.find(rnti); + return it != ue_teidin_db.end() ? &ue_teidin_db[rnti] : nullptr; } srsran::span @@ -92,12 +90,18 @@ gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t eps_bearer_id, uint32_t tun->teid_out = teidout; tun->spgw_addr = spgw_addr; - if (not ue_teidin_db.contains(rnti)) { - auto ret = ue_teidin_db.insert(rnti, ue_bearer_tunnel_list()); + if (ue_teidin_db.find(rnti) != ue_teidin_db.end()) { + auto ret = ue_teidin_db.emplace(rnti, ue_bearer_tunnel_list()); + if (!ret.second) { + logger.error("Failed to allocate rnti=0x%x", rnti); + return nullptr; + } +#if 0 if (ret.is_error()) { logger.error("Failed to allocate rnti=0x%x", rnti); return nullptr; } +#endif } auto& ue_tunnels = ue_teidin_db[rnti]; @@ -133,7 +137,7 @@ bool gtpu_tunnel_manager::update_rnti(uint16_t old_rnti, uint16_t new_rnti) logger.info("Modifying bearer rnti. Old rnti: 0x%x, new rnti: 0x%x", old_rnti, new_rnti); // create new RNTI and update TEIDs of old rnti to reflect new rnti - if (new_rnti_ptr == nullptr and not ue_teidin_db.insert(new_rnti, ue_bearer_tunnel_list())) { + if (new_rnti_ptr == nullptr and not ue_teidin_db.insert({new_rnti, ue_bearer_tunnel_list()}).second) { logger.error("Failure to create new rnti=0x%x", new_rnti); return false; } @@ -186,7 +190,8 @@ bool gtpu_tunnel_manager::remove_tunnel(uint32_t teidin) bool gtpu_tunnel_manager::remove_rnti(uint16_t rnti) { - if (not ue_teidin_db.contains(rnti)) { + auto it = ue_teidin_db.find(rnti); + if (it == ue_teidin_db.end()) { logger.warning("Removing rnti. rnti=0x%x not found.", rnti); return false; } From b9f0b4a5584c7cefda590349f3143c0dddef9d77 Mon Sep 17 00:00:00 2001 From: Francisco Date: Thu, 21 Oct 2021 18:16:42 +0100 Subject: [PATCH 32/60] lte,enb,gtpu: fix failing gtpu_test --- srsenb/src/stack/upper/gtpu.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/srsenb/src/stack/upper/gtpu.cc b/srsenb/src/stack/upper/gtpu.cc index 10cd9d067..41ee99d97 100644 --- a/srsenb/src/stack/upper/gtpu.cc +++ b/srsenb/src/stack/upper/gtpu.cc @@ -90,18 +90,12 @@ gtpu_tunnel_manager::add_tunnel(uint16_t rnti, uint32_t eps_bearer_id, uint32_t tun->teid_out = teidout; tun->spgw_addr = spgw_addr; - if (ue_teidin_db.find(rnti) != ue_teidin_db.end()) { + if (ue_teidin_db.find(rnti) == ue_teidin_db.end()) { auto ret = ue_teidin_db.emplace(rnti, ue_bearer_tunnel_list()); if (!ret.second) { logger.error("Failed to allocate rnti=0x%x", rnti); return nullptr; } -#if 0 - if (ret.is_error()) { - logger.error("Failed to allocate rnti=0x%x", rnti); - return nullptr; - } -#endif } auto& ue_tunnels = ue_teidin_db[rnti]; From e3267c9dfdfedc4c20cae07dcc61d589e4de9afd Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 21 Oct 2021 22:46:12 +0200 Subject: [PATCH 33/60] gtpu: remove unused local variable Signed-off-by: Carlo Galiotto --- srsenb/hdr/stack/upper/gtpu.h | 1 - 1 file changed, 1 deletion(-) diff --git a/srsenb/hdr/stack/upper/gtpu.h b/srsenb/hdr/stack/upper/gtpu.h index 7d718f6bc..2eb1c9046 100644 --- a/srsenb/hdr/stack/upper/gtpu.h +++ b/srsenb/hdr/stack/upper/gtpu.h @@ -124,7 +124,6 @@ private: srslog::basic_logger& logger; std::unordered_map ue_teidin_db; - rnti_map_t ue_teidin_db_1; tunnel_list_t tunnels; }; From 904d05d4c4a5520a905a15fba9d8d4d9cd6f8863 Mon Sep 17 00:00:00 2001 From: faluco Date: Wed, 20 Oct 2021 17:42:11 +0200 Subject: [PATCH 34/60] Fix data race in bsr_proc::print_state(). While there, early exit if the log info channel is disabled to avoid formatting a string that will not be used. --- srsue/src/stack/mac/proc_bsr.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/srsue/src/stack/mac/proc_bsr.cc b/srsue/src/stack/mac/proc_bsr.cc index 4ac7a688b..6ebef5427 100644 --- a/srsue/src/stack/mac/proc_bsr.cc +++ b/srsue/src/stack/mac/proc_bsr.cc @@ -41,6 +41,12 @@ void bsr_proc::init(sr_proc* sr_, rlc_interface_mac* rlc_, srsran::ext_task_sche void bsr_proc::print_state() { + if (!logger.info.enabled()) { + return; + } + + std::lock_guard lock(mutex); + char str[128]; str[0] = '\0'; int n = 0; From d9bdc3f83e634d646fc46d5906b3da4ffec0e4bd Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Thu, 21 Oct 2021 11:58:09 +0200 Subject: [PATCH 35/60] Add CSI resource information and fix segmentation fault --- .../srsran/phy/ch_estimation/csi_rs_cfg.h | 6 +- lib/src/phy/ch_estimation/csi_rs.c | 104 +++++++++++++++++- 2 files changed, 105 insertions(+), 5 deletions(-) diff --git a/lib/include/srsran/phy/ch_estimation/csi_rs_cfg.h b/lib/include/srsran/phy/ch_estimation/csi_rs_cfg.h index 1be7edf90..b63ba7403 100644 --- a/lib/include/srsran/phy/ch_estimation/csi_rs_cfg.h +++ b/lib/include/srsran/phy/ch_estimation/csi_rs_cfg.h @@ -128,6 +128,10 @@ typedef struct SRSRAN_API { uint32_t count; ///< Number of resources in the set } srsran_csi_rs_zp_set_t; -SRSRAN_API bool srsran_csi_rs_resource_mapping_is_valid(const srsran_csi_rs_resource_mapping_t *res); +SRSRAN_API bool srsran_csi_rs_resource_mapping_is_valid(const srsran_csi_rs_resource_mapping_t* res); + +SRSRAN_API uint32_t srsran_csi_rs_resource_mapping_info(const srsran_csi_rs_resource_mapping_t* res, + char* str, + uint32_t str_len); #endif // SRSRAN_CSI_RS_CFG_H diff --git a/lib/src/phy/ch_estimation/csi_rs.c b/lib/src/phy/ch_estimation/csi_rs.c index c4a77c78d..e6ea23c0c 100644 --- a/lib/src/phy/ch_estimation/csi_rs.c +++ b/lib/src/phy/ch_estimation/csi_rs.c @@ -28,6 +28,13 @@ */ #define CSI_RS_MAX_SYMBOLS_SLOT 4 +#define RESOURCE_ERROR(R) \ + do { \ + char res_info_str[256]; \ + srsran_csi_rs_resource_mapping_info(R, res_info_str, (uint32_t)sizeof(res_info_str)); \ + ERROR("Unhandled configuration %s", res_info_str); \ + } while (false) + static int csi_rs_location_f(const srsran_csi_rs_resource_mapping_t* resource, uint32_t i) { uint32_t count = 0; @@ -60,7 +67,8 @@ static int csi_rs_location_f(const srsran_csi_rs_resource_mapping_t* resource, u } } - ERROR("Unhandled configuration"); + // Inform about an unhandled configuration + RESOURCE_ERROR(resource); return SRSRAN_ERROR; } @@ -113,7 +121,8 @@ static int csi_rs_location_get_k_list(const srsran_csi_rs_resource_mapping_t* re } } - ERROR("Unhandled configuration"); + // Inform about an unhandled configuration + RESOURCE_ERROR(resource); return SRSRAN_ERROR; } @@ -163,7 +172,8 @@ static int csi_rs_location_get_l_list(const srsran_csi_rs_resource_mapping_t* re } } - ERROR("Unhandled configuration"); + // Inform about an unhandled configuration + RESOURCE_ERROR(resource); return SRSRAN_ERROR; } @@ -216,7 +226,8 @@ static int csi_rs_nof_cdm_groups(const srsran_csi_rs_resource_mapping_t* resourc return 2; } - ERROR("Unhandled configuration"); + // Inform about an unhandled configuration + RESOURCE_ERROR(resource); return SRSRAN_ERROR; } @@ -243,6 +254,89 @@ bool srsran_csi_rs_resource_mapping_is_valid(const srsran_csi_rs_resource_mappin return true; } +uint32_t srsran_csi_rs_resource_mapping_info(const srsran_csi_rs_resource_mapping_t* res, char* str, uint32_t str_len) +{ + uint32_t len = 0; + + const char* row_str = "invalid"; + uint32_t nof_freq_domain = 0; + switch (res->row) { + case srsran_csi_rs_resource_mapping_row_1: + row_str = "1"; + nof_freq_domain = SRSRAN_CSI_RS_NOF_FREQ_DOMAIN_ALLOC_ROW1; + break; + case srsran_csi_rs_resource_mapping_row_2: + row_str = "2"; + nof_freq_domain = SRSRAN_CSI_RS_NOF_FREQ_DOMAIN_ALLOC_ROW2; + break; + case srsran_csi_rs_resource_mapping_row_4: + row_str = "4"; + nof_freq_domain = SRSRAN_CSI_RS_NOF_FREQ_DOMAIN_ALLOC_ROW4; + break; + case srsran_csi_rs_resource_mapping_row_other: + row_str = "other"; + nof_freq_domain = SRSRAN_CSI_RS_NOF_FREQ_DOMAIN_ALLOC_OTHER; + break; + } + + const char* cdm_str = "invalid"; + switch (res->cdm) { + case srsran_csi_rs_cdm_nocdm: + cdm_str = "nocdm"; + break; + case srsran_csi_rs_cdm_fd_cdm2: + cdm_str = "FD-CDM2"; + break; + case srsran_csi_rs_cdm_cdm4_fd2_td2: + cdm_str = "CDM4-FD2-TD2"; + break; + case srsran_csi_rs_cdm_cdm8_fd2_td4: + cdm_str = "CDM8-FD2-TD4"; + break; + } + + const char* density_str = "invalid"; + switch (res->density) { + case srsran_csi_rs_resource_mapping_density_three: + density_str = "3"; + break; + case srsran_csi_rs_resource_mapping_density_dot5_even: + density_str = ".5 (even)"; + break; + case srsran_csi_rs_resource_mapping_density_dot5_odd: + density_str = ".5 (odd)"; + break; + case srsran_csi_rs_resource_mapping_density_one: + density_str = "1"; + break; + case srsran_csi_rs_resource_mapping_density_spare: + density_str = "spare"; + break; + } + + char frequency_domain_alloc[SRSRAN_CSI_RS_NOF_FREQ_DOMAIN_ALLOC_MAX + 1]; + srsran_vec_sprint_bin(frequency_domain_alloc, + SRSRAN_CSI_RS_NOF_FREQ_DOMAIN_ALLOC_MAX + 1, + (uint8_t*)res->frequency_domain_alloc, + nof_freq_domain); + + len = srsran_print_check(str, + str_len, + len, + "row=%s freq=%s nof_ports=%d fist_symb=%d fist_symb2=%d cdm=%s density=%s rb=(%d:%d)", + row_str, + frequency_domain_alloc, + res->nof_ports, + res->first_symbol_idx, + res->first_symbol_idx2, + cdm_str, + density_str, + res->freq_band.start_rb, + res->freq_band.start_rb + res->freq_band.nof_rb - 1); + + return len; +} + uint32_t csi_rs_count(srsran_csi_rs_density_t density, uint32_t nprb) { switch (density) { @@ -668,6 +762,7 @@ int srsran_csi_rs_nzp_measure_trs(const srsran_carrier_nr_t* carrier, int ret = csi_rs_nzp_measure_set(carrier, slot_cfg, set, grid, measurements); if (ret < SRSRAN_SUCCESS) { ERROR("Error performing measurements"); + return SRSRAN_ERROR; } uint32_t count = (uint32_t)ret; @@ -763,6 +858,7 @@ int srsran_csi_rs_nzp_measure_channel(const srsran_carrier_nr_t* carrier int ret = csi_rs_nzp_measure_set(carrier, slot_cfg, set, grid, measurements); if (ret < SRSRAN_SUCCESS) { ERROR("Error performing measurements"); + return SRSRAN_ERROR; } uint32_t count = (uint32_t)ret; From 9daa32e5912c118e19010a5f86e0988ab1304a5c Mon Sep 17 00:00:00 2001 From: Alejandro Leal Conejos Date: Fri, 22 Oct 2021 12:10:48 +0200 Subject: [PATCH 36/60] Configure the term timeout using the cmake definition EXTRA_TERM_TIMEOUT_S --- CMakeLists.txt | 19 ++++++++++++------- lib/src/support/signal_handler.cc | 2 ++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c6a934fc0..0eb8df40e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,10 +63,10 @@ option(ENABLE_SOAPYSDR "Enable SoapySDR" ON) option(ENABLE_SKIQ "Enable Sidekiq SDK" ON) option(ENABLE_ZEROMQ "Enable ZeroMQ" ON) option(ENABLE_HARDSIM "Enable support for SIM cards" ON) - + option(ENABLE_TTCN3 "Enable TTCN3 test binaries" OFF) option(ENABLE_ZMQ_TEST "Enable ZMQ based E2E tests" OFF) - + option(BUILD_STATIC "Attempt to statically link external deps" OFF) option(RPATH "Enable RPATH" OFF) option(ENABLE_ASAN "Enable gcc/clang address sanitizer" OFF) @@ -74,12 +74,12 @@ option(ENABLE_GCOV "Enable gcc/clang address sanitizer" OFF) option(ENABLE_MSAN "Enable clang memory sanitizer" OFF) option(ENABLE_TSAN "Enable clang thread sanitizer" OFF) option(ENABLE_TIDY "Enable clang tidy" OFF) - + option(USE_LTE_RATES "Use standard LTE sampling rates" OFF) option(USE_MKL "Use MKL instead of fftw" OFF) - + option(ENABLE_TIMEPROF "Enable time profiling" ON) - + option(FORCE_32BIT "Add flags to force 32 bit compilation" OFF) option(ENABLE_SRSLOG_TRACING "Enable event tracing using srslog" OFF) @@ -93,7 +93,7 @@ option(ENABLE_ALL_TEST "Enable all unit/component test" OFF) # it automatically so it is necessary to use the gcc wrappers of the compiler # (gcc-ar, gcc-nm, ...). option(BUILD_WITH_LTO "Enable LTO (experimental)" OFF) - + if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") set(GCC_ARCH armv8-a CACHE STRING "GCC compile for specific architecture.") message(STATUS "Detected aarch64 processor") @@ -378,7 +378,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") ADD_C_COMPILER_FLAG_IF_AVAILABLE("-march=${GCC_ARCH}" HAVE_MARCH_${GCC_ARCH}) ADD_CXX_COMPILER_FLAG_IF_AVAILABLE("-march=${GCC_ARCH}" HAVE_MARCH_${GCC_ARCH}) - + if (HAVE_AVX2) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=sse -mavx2 -DLV_HAVE_AVX2 -DLV_HAVE_AVX -DLV_HAVE_SSE") else (HAVE_AVX2) @@ -537,6 +537,11 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --param large-function-growth=1600") endif(CMAKE_C_COMPILER_ID MATCHES "GNU") +if (EXTRA_TERM_TIMEOUT_S) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSRSRAN_TERM_TIMEOUT_S=${EXTRA_TERM_TIMEOUT_S}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSRSRAN_TERM_TIMEOUT_S=${EXTRA_TERM_TIMEOUT_S}") +endif (EXTRA_TERM_TIMEOUT_S) + message(STATUS "CMAKE_C_FLAGS is ${CMAKE_C_FLAGS}") message(STATUS "CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}") diff --git a/lib/src/support/signal_handler.cc b/lib/src/support/signal_handler.cc index 33620d6cc..59554044a 100644 --- a/lib/src/support/signal_handler.cc +++ b/lib/src/support/signal_handler.cc @@ -17,7 +17,9 @@ #include #include +#ifndef SRSRAN_TERM_TIMEOUT_S #define SRSRAN_TERM_TIMEOUT_S (5) +#endif /// Handler called after the user interrupts the program. static std::atomic user_handler; From fbcffb84bdbe9eea46e56904b78036d9caacbf40 Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Tue, 19 Oct 2021 12:41:46 +0100 Subject: [PATCH 37/60] Check if RLC is suspended before transmiting PDCP SDU. This was done to avoid integrity issues, when the UE's RRC erroneously sent measurement reports while the re-establishment was already in progress. As errously sending PDCP PDUs on DRBs can cause issues as well, this was disabled too. --- lib/include/srsran/interfaces/enb_pdcp_interfaces.h | 2 +- lib/include/srsran/interfaces/enb_rlc_interfaces.h | 2 ++ lib/include/srsran/interfaces/ue_rlc_interfaces.h | 2 ++ lib/src/pdcp/pdcp_entity_lte.cc | 6 +++++- lib/test/pdcp/pdcp_base_test.h | 2 ++ srsenb/hdr/stack/upper/pdcp.h | 1 + srsenb/hdr/stack/upper/rlc.h | 1 + srsenb/src/stack/upper/pdcp.cc | 5 +++++ srsenb/src/stack/upper/rlc.cc | 11 +++++++++++ srsenb/test/common/dummy_classes_common.h | 1 + srsue/src/test/ttcn3/hdr/ttcn3_syssim.h | 2 ++ srsue/src/test/ttcn3/src/ttcn3_syssim.cc | 5 +++++ 12 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/include/srsran/interfaces/enb_pdcp_interfaces.h b/lib/include/srsran/interfaces/enb_pdcp_interfaces.h index 5b5a907c2..3e832f833 100644 --- a/lib/include/srsran/interfaces/enb_pdcp_interfaces.h +++ b/lib/include/srsran/interfaces/enb_pdcp_interfaces.h @@ -31,7 +31,7 @@ public: class pdcp_interface_rrc { public: - virtual void set_enabled(uint16_t rnti, uint32_t lcid, bool enable) = 0; + 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/enb_rlc_interfaces.h b/lib/include/srsran/interfaces/enb_rlc_interfaces.h index f2f3cddb2..ff0e6dec5 100644 --- a/lib/include/srsran/interfaces/enb_rlc_interfaces.h +++ b/lib/include/srsran/interfaces/enb_rlc_interfaces.h @@ -41,6 +41,7 @@ public: virtual void discard_sdu(uint16_t rnti, uint32_t lcid, uint32_t sn) = 0; virtual bool rb_is_um(uint16_t rnti, uint32_t lcid) = 0; virtual bool sdu_queue_is_full(uint16_t rnti, uint32_t lcid) = 0; + virtual bool is_suspended(uint16_t rnti, uint32_t lcid) = 0; }; // RLC interface for RRC @@ -56,6 +57,7 @@ public: virtual void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) = 0; virtual bool has_bearer(uint16_t rnti, uint32_t lcid) = 0; virtual bool suspend_bearer(uint16_t rnti, uint32_t lcid) = 0; + virtual bool is_suspended(uint16_t rnti, uint32_t lcid) = 0; virtual bool resume_bearer(uint16_t rnti, uint32_t lcid) = 0; virtual void reestablish(uint16_t rnti) = 0; }; diff --git a/lib/include/srsran/interfaces/ue_rlc_interfaces.h b/lib/include/srsran/interfaces/ue_rlc_interfaces.h index bf937cd9c..5c32d1678 100644 --- a/lib/include/srsran/interfaces/ue_rlc_interfaces.h +++ b/lib/include/srsran/interfaces/ue_rlc_interfaces.h @@ -51,6 +51,8 @@ public: ///< Allow PDCP to query SDU queue status virtual bool sdu_queue_is_full(uint32_t lcid) = 0; + + virtual bool is_suspended(const uint32_t lcid) = 0; }; class rlc_interface_mac : public srsran::read_pdu_interface diff --git a/lib/src/pdcp/pdcp_entity_lte.cc b/lib/src/pdcp/pdcp_entity_lte.cc index 017b45123..af5663735 100644 --- a/lib/src/pdcp/pdcp_entity_lte.cc +++ b/lib/src/pdcp/pdcp_entity_lte.cc @@ -139,6 +139,11 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn) return; } + if (rlc->is_suspended(lcid)) { + logger.warning("Trying to send SDU while re-establishment is in progress. Dropping SDU. LCID=%d", 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; @@ -166,7 +171,6 @@ void pdcp_entity_lte::write_sdu(unique_byte_buffer_t sdu, int upper_sn) return; } } - // check for pending security config in transmit direction if (enable_security_tx_sn != -1 && enable_security_tx_sn == static_cast(tx_count)) { enable_integrity(DIRECTION_TX); diff --git a/lib/test/pdcp/pdcp_base_test.h b/lib/test/pdcp/pdcp_base_test.h index 19c1a86bb..2ad9ce1d3 100644 --- a/lib/test/pdcp/pdcp_base_test.h +++ b/lib/test/pdcp/pdcp_base_test.h @@ -55,6 +55,8 @@ public: logger.info("Discard_count=%" PRIu64 "", discard_count); } + bool is_suspended(uint32_t lcid) { return false; } + uint64_t rx_count = 0; uint64_t discard_count = 0; diff --git a/srsenb/hdr/stack/upper/pdcp.h b/srsenb/hdr/stack/upper/pdcp.h index aa43919ce..5a19f2ad9 100644 --- a/srsenb/hdr/stack/upper/pdcp.h +++ b/srsenb/hdr/stack/upper/pdcp.h @@ -77,6 +77,7 @@ private: void discard_sdu(uint32_t lcid, uint32_t discard_sn); bool rb_is_um(uint32_t lcid); bool sdu_queue_is_full(uint32_t lcid); + bool is_suspended(uint32_t lcid); }; class user_interface_gtpu : public srsue::gw_interface_pdcp diff --git a/srsenb/hdr/stack/upper/rlc.h b/srsenb/hdr/stack/upper/rlc.h index a635de684..55526b0aa 100644 --- a/srsenb/hdr/stack/upper/rlc.h +++ b/srsenb/hdr/stack/upper/rlc.h @@ -53,6 +53,7 @@ public: bool has_bearer(uint16_t rnti, uint32_t lcid); bool suspend_bearer(uint16_t rnti, uint32_t lcid); bool resume_bearer(uint16_t rnti, uint32_t lcid); + bool is_suspended(uint16_t rnti, uint32_t lcid); void reestablish(uint16_t rnti) final; // rlc_interface_pdcp diff --git a/srsenb/src/stack/upper/pdcp.cc b/srsenb/src/stack/upper/pdcp.cc index 4b9c8baaf..1f460f43e 100644 --- a/srsenb/src/stack/upper/pdcp.cc +++ b/srsenb/src/stack/upper/pdcp.cc @@ -217,6 +217,11 @@ bool pdcp::user_interface_rlc::rb_is_um(uint32_t lcid) return rlc->rb_is_um(rnti, lcid); } +bool pdcp::user_interface_rlc::is_suspended(uint32_t lcid) +{ + return rlc->is_suspended(rnti, lcid); +} + bool pdcp::user_interface_rlc::sdu_queue_is_full(uint32_t lcid) { return rlc->sdu_queue_is_full(rnti, lcid); diff --git a/srsenb/src/stack/upper/rlc.cc b/srsenb/src/stack/upper/rlc.cc index 25d3c1678..38ccd6a35 100644 --- a/srsenb/src/stack/upper/rlc.cc +++ b/srsenb/src/stack/upper/rlc.cc @@ -150,6 +150,17 @@ bool rlc::suspend_bearer(uint16_t rnti, uint32_t lcid) return result; } +bool rlc::is_suspended(uint16_t rnti, uint32_t lcid) +{ + pthread_rwlock_rdlock(&rwlock); + bool result = false; + if (users.count(rnti)) { + result = users[rnti].rlc->is_suspended(lcid); + } + pthread_rwlock_unlock(&rwlock); + return result; +} + bool rlc::resume_bearer(uint16_t rnti, uint32_t lcid) { pthread_rwlock_rdlock(&rwlock); diff --git a/srsenb/test/common/dummy_classes_common.h b/srsenb/test/common/dummy_classes_common.h index 966166fe8..54db6c90a 100644 --- a/srsenb/test/common/dummy_classes_common.h +++ b/srsenb/test/common/dummy_classes_common.h @@ -30,6 +30,7 @@ public: void write_sdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t sdu) override { last_sdu = std::move(sdu); } bool has_bearer(uint16_t rnti, uint32_t lcid) override { return false; } bool suspend_bearer(uint16_t rnti, uint32_t lcid) override { return true; } + bool is_suspended(uint16_t rnti, uint32_t lcid) override { return false; } bool resume_bearer(uint16_t rnti, uint32_t lcid) override { return true; } void reestablish(uint16_t rnti) override {} diff --git a/srsue/src/test/ttcn3/hdr/ttcn3_syssim.h b/srsue/src/test/ttcn3/hdr/ttcn3_syssim.h index 667ae210d..6f673407e 100644 --- a/srsue/src/test/ttcn3/hdr/ttcn3_syssim.h +++ b/srsue/src/test/ttcn3/hdr/ttcn3_syssim.h @@ -170,6 +170,8 @@ public: bool sdu_queue_is_full(uint32_t lcid); + bool is_suspended(uint32_t lcid); + void set_as_security(const ttcn3_helpers::timing_info_t timing, const std::string cell_name, std::array k_rrc_enc_, diff --git a/srsue/src/test/ttcn3/src/ttcn3_syssim.cc b/srsue/src/test/ttcn3/src/ttcn3_syssim.cc index 6c689345e..f792617eb 100644 --- a/srsue/src/test/ttcn3/src/ttcn3_syssim.cc +++ b/srsue/src/test/ttcn3/src/ttcn3_syssim.cc @@ -1191,6 +1191,11 @@ bool ttcn3_syssim::sdu_queue_is_full(uint32_t lcid) return false; } +bool ttcn3_syssim::is_suspended(uint32_t lcid) +{ + return false; +} + void ttcn3_syssim::set_as_security(const ttcn3_helpers::timing_info_t timing, const std::string cell_name, std::array k_rrc_enc_, From 327687cbc2c4d3e970a9cb842fe701f7f3e1b7e9 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 22 Oct 2021 13:59:34 +0100 Subject: [PATCH 38/60] nr,sched: auto clear HARQs that exceeded maxretx, after the feedback has been processed --- srsenb/hdr/stack/mac/nr/sched_nr_harq.h | 7 +++++-- srsenb/hdr/stack/mac/nr/sched_nr_ue.h | 6 +++++- srsenb/src/stack/mac/nr/sched_nr_harq.cc | 17 ++++++++++++----- srsenb/src/stack/mac/nr/sched_nr_ue.cc | 20 +++++++------------- srsenb/src/stack/mac/nr/sched_nr_worker.cc | 5 ++++- srsenb/test/mac/nr/sched_nr_rar_test.cc | 1 + 6 files changed, 34 insertions(+), 22 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_harq.h b/srsenb/hdr/stack/mac/nr/sched_nr_harq.h index 8af07e9b7..5ab33d932 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_harq.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_harq.h @@ -46,7 +46,7 @@ public: int ack_info(uint32_t tb_idx, bool ack); - void new_slot(slot_point slot_rx); + bool clear_if_maxretx(slot_point slot_rx); void reset(); bool new_tx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant, uint32_t mcs, uint32_t max_retx); bool new_retx(slot_point slot_tx, slot_point slot_ack, const prb_grant& grant); @@ -112,7 +112,7 @@ private: class harq_entity { public: - explicit harq_entity(uint32_t nprb, uint32_t nof_harq_procs = SCHED_NR_MAX_HARQ); + explicit harq_entity(uint16_t rnti, uint32_t nprb, uint32_t nof_harq_procs, srslog::basic_logger& logger); void new_slot(slot_point slot_rx_); int dl_ack_info(uint32_t pid, uint32_t tb_idx, bool ack) { return dl_harqs[pid].ack_info(tb_idx, ack); } @@ -154,6 +154,9 @@ private: return (it == ul_harqs.end()) ? nullptr : &(*it); } + uint16_t rnti; + srslog::basic_logger& logger; + slot_point slot_rx; std::vector dl_harqs; std::vector ul_harqs; diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h index 21076a204..2f056a985 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_ue.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_ue.h @@ -63,7 +63,11 @@ class ue_carrier { public: ue_carrier(uint16_t rnti, const ue_cfg_t& cfg, const cell_params_t& cell_params_); - void set_cfg(const ue_cfg_t& ue_cfg); + void set_cfg(const ue_cfg_t& ue_cfg); + + /// Called after CC Feedback has been processed + void new_slot(slot_point slot_tx); + slot_ue try_reserve(slot_point pdcch_slot, uint32_t dl_harq_bytes, uint32_t ul_harq_bytes); const uint16_t rnti; diff --git a/srsenb/src/stack/mac/nr/sched_nr_harq.cc b/srsenb/src/stack/mac/nr/sched_nr_harq.cc index 6019190fa..396f73031 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_harq.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_harq.cc @@ -28,11 +28,13 @@ int harq_proc::ack_info(uint32_t tb_idx, bool ack) return ack ? tb[tb_idx].tbs : 0; } -void harq_proc::new_slot(slot_point slot_rx) +bool harq_proc::clear_if_maxretx(slot_point slot_rx) { - if (has_pending_retx(slot_rx) and nof_retx() + 1 >= max_nof_retx()) { + if (has_pending_retx(slot_rx) and nof_retx() + 1 > max_nof_retx()) { tb[0].active = false; + return true; } + return false; } void harq_proc::reset() @@ -127,7 +129,8 @@ bool dl_harq_proc::new_tx(slot_point slot_tx, return false; } -harq_entity::harq_entity(uint32_t nprb, uint32_t nof_harq_procs) +harq_entity::harq_entity(uint16_t rnti_, uint32_t nprb, uint32_t nof_harq_procs, srslog::basic_logger& logger_) : + rnti(rnti_), logger(logger_) { // Create HARQs dl_harqs.reserve(nof_harq_procs); @@ -142,10 +145,14 @@ void harq_entity::new_slot(slot_point slot_rx_) { slot_rx = slot_rx_; for (harq_proc& dl_h : dl_harqs) { - dl_h.new_slot(slot_rx); + if (dl_h.clear_if_maxretx(slot_rx)) { + logger.info("SCHED: discarding rnti=0x%x, DL TB pid=%d. Cause: Maximum number of retx exceeded (%d)"); + } } for (harq_proc& ul_h : ul_harqs) { - ul_h.new_slot(slot_rx); + if (ul_h.clear_if_maxretx(slot_rx)) { + logger.info("SCHED: discarding rnti=0x%x, UL TB pid=%d. Cause: Maximum number of retx exceeded (%d)"); + } } } diff --git a/srsenb/src/stack/mac/nr/sched_nr_ue.cc b/srsenb/src/stack/mac/nr/sched_nr_ue.cc index f48a47ad2..0079c9eaf 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_ue.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_ue.cc @@ -26,7 +26,7 @@ ue_carrier::ue_carrier(uint16_t rnti_, const ue_cfg_t& uecfg_, const cell_params cc(cell_params_.cc), bwp_cfg(rnti_, cell_params_.bwps[0], uecfg_), cell_params(cell_params_), - harq_ent(cell_params_.nof_prb()) + harq_ent(rnti_, cell_params_.nof_prb(), SCHED_NR_MAX_HARQ, cell_params_.bwps[0].logger) {} void ue_carrier::set_cfg(const ue_cfg_t& ue_cfg) @@ -34,6 +34,11 @@ void ue_carrier::set_cfg(const ue_cfg_t& ue_cfg) bwp_cfg = bwp_ue_cfg(rnti, cell_params.bwps[0], ue_cfg); } +void ue_carrier::new_slot(slot_point slot_tx) +{ + harq_ent.new_slot(slot_tx - TX_ENB_DELAY); +} + slot_ue ue_carrier::try_reserve(slot_point pdcch_slot, uint32_t dl_pending_bytes, uint32_t ul_pending_bytes) { slot_point slot_rx = pdcch_slot - TX_ENB_DELAY; @@ -103,14 +108,6 @@ 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) { - // Update CC HARQ state - cc->harq_ent.new_slot(pdcch_slot - TX_ENB_DELAY); - } - } - // Compute pending DL/UL bytes for {rnti, pdcch_slot} if (sched_cfg.sched_cfg.auto_refill_buffer) { dl_pending_bytes = 1000000; @@ -142,10 +139,7 @@ void ue::new_slot(slot_point pdcch_slot) slot_ue ue::try_reserve(slot_point pdcch_slot, uint32_t cc) { - if (carriers[cc] == nullptr) { - return slot_ue(); - } - + srsran_assert(carriers[cc] != nullptr, "try_reserve() called for inexistent rnti=0x%x,cc=%d", rnti, cc); return carriers[cc]->try_reserve(pdcch_slot, dl_pending_bytes, ul_pending_bytes); } diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index 871e31117..ecc0b6215 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -80,6 +80,9 @@ void slot_cc_worker::run(slot_point pdcch_slot, ue_map_t& ue_db) continue; } + // Update UE CC state + u.carriers[cfg.cc]->new_slot(pdcch_slot); + // info for a given UE on a slot to be process slot_ues.insert(rnti, u.try_reserve(pdcch_slot, cfg.cc)); if (slot_ues[rnti].empty()) { @@ -374,7 +377,7 @@ void sched_worker_manager::get_metrics_nolocking(mac_metrics_t& metrics) { for (mac_ue_metrics_t& ue_metric : metrics.ues) { if (ue_db.contains(ue_metric.rnti) and ue_db[ue_metric.rnti]->carriers[0] != nullptr) { - auto& ue_cc = *ue_db[ue_metric.rnti]->carriers[0]; + auto& ue_cc = *ue_db[ue_metric.rnti]->carriers[0]; std::lock_guard lock(ue_cc.metrics_mutex); ue_metric.tx_brate = ue_cc.metrics.tx_brate; ue_metric.tx_errors = ue_cc.metrics.tx_errors; diff --git a/srsenb/test/mac/nr/sched_nr_rar_test.cc b/srsenb/test/mac/nr/sched_nr_rar_test.cc index b9acd4a6c..27622c318 100644 --- a/srsenb/test/mac/nr/sched_nr_rar_test.cc +++ b/srsenb/test/mac/nr/sched_nr_rar_test.cc @@ -57,6 +57,7 @@ void test_single_prach() auto run_slot = [&alloc, &rasched, &pdcch_slot, &slot_ues, &u]() -> const bwp_slot_grid* { mac_logger.set_context(pdcch_slot.to_uint()); u.new_slot(pdcch_slot); + u.carriers[0]->new_slot(pdcch_slot); slot_ues.clear(); slot_ue sfu = u.try_reserve(pdcch_slot, 0); if (not sfu.empty()) { From ceec108831028baacb3596e8884adad1fef3e37b Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 22 Oct 2021 14:12:25 +0100 Subject: [PATCH 39/60] nr,sched: fix fmt string in sched nr harq --- srsenb/src/stack/mac/nr/sched_nr_harq.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_harq.cc b/srsenb/src/stack/mac/nr/sched_nr_harq.cc index 396f73031..f8496c721 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_harq.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_harq.cc @@ -146,12 +146,18 @@ void harq_entity::new_slot(slot_point slot_rx_) slot_rx = slot_rx_; for (harq_proc& dl_h : dl_harqs) { if (dl_h.clear_if_maxretx(slot_rx)) { - logger.info("SCHED: discarding rnti=0x%x, DL TB pid=%d. Cause: Maximum number of retx exceeded (%d)"); + logger.info("SCHED: discarding rnti=0x%x, DL TB pid=%d. Cause: Maximum number of retx exceeded (%d)", + rnti, + dl_h.pid, + dl_h.max_nof_retx()); } } for (harq_proc& ul_h : ul_harqs) { if (ul_h.clear_if_maxretx(slot_rx)) { - logger.info("SCHED: discarding rnti=0x%x, UL TB pid=%d. Cause: Maximum number of retx exceeded (%d)"); + logger.info("SCHED: discarding rnti=0x%x, UL TB pid=%d. Cause: Maximum number of retx exceeded (%d)", + rnti, + ul_h.pid, + ul_h.max_nof_retx()); } } } From 4f6905363fce6a862cc02c763f2c9f644d5365d5 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Thu, 21 Oct 2021 15:39:40 +0200 Subject: [PATCH 40/60] rrc,nr: add MSG3 activity timer to rrc_nr Signed-off-by: Carlo Galiotto --- srsenb/hdr/stack/rrc/rrc_nr.h | 34 ++++++++++- srsenb/src/stack/rrc/rrc_nr.cc | 101 +++++++++++++++++++++++++++++++-- 2 files changed, 129 insertions(+), 6 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index 4935e0cbb..a8d58937a 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -104,7 +104,27 @@ public: class ue { public: - ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg); + enum activity_timeout_type_t { + MSG3_RX_TIMEOUT = 0, ///< Msg3 has its own timeout to quickly remove fake UEs from random PRACHs + UE_INACTIVITY_TIMEOUT, ///< (currently unused) UE inactivity timeout (usually bigger than reestablishment timeout) + MSG5_RX_TIMEOUT, ///< (currently unused) for receiving RRCConnectionSetupComplete/RRCReestablishmentComplete + nulltype + }; + + /// List of results a RRC procedure may produce. + enum class procedure_result_code { + none, + activity_timeout, + error_mme_not_connected, + error_unknown_rnti, + radio_conn_with_ue_lost, + msg3_timeout, + fail_in_radio_interface_proc, + unspecified + }; + + /// @param [in] triggered_by_rach: indicates whether the UE is created as part of a RACH process + ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg, bool triggered_by_rach = false); void send_connection_setup(); void send_dl_ccch(asn1::rrc_nr::dl_ccch_msg_s* dl_dcch_msg); @@ -119,14 +139,23 @@ public: bool is_endc() { return endc; } uint16_t get_eutra_rnti() { return eutra_rnti; } void get_metrics(rrc_ue_metrics_t& ue_metrics) { ue_metrics = {}; /*TODO fill RRC metrics*/ }; + // setters int pack_rrc_reconfiguration(); void deactivate_bearers(); + /// methods to handle activity timer + std::string to_string(const activity_timeout_type_t& type); + void set_activity_timeout(activity_timeout_type_t type); + void set_activity(bool enabled = true); + void activity_timer_expired(const activity_timeout_type_t type); + private: rrc_nr* parent = nullptr; uint16_t rnti = SRSRAN_INVALID_RNTI; + /// for basic DL/UL activity timeout + srsran::unique_timer activity_timer; int pack_rrc_reconfiguration(asn1::dyn_octstring& packed_rrc_reconfig); int pack_secondary_cell_group_cfg(asn1::dyn_octstring& packed_secondary_cell_config); @@ -179,6 +208,9 @@ public: rrc_nr_state_t state = rrc_nr_state_t::RRC_IDLE; uint8_t transaction_id = 0; + /// Connection release result. + procedure_result_code con_release_result = procedure_result_code::none; + // RRC configs for UEs asn1::rrc_nr::cell_group_cfg_s cell_group_cfg; asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index f89ee463b..439bfa6ca 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -161,7 +161,8 @@ rrc_nr_cfg_t rrc_nr::update_default_cfg(const rrc_nr_cfg_t& current) int rrc_nr::add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg) { if (users.count(rnti) == 0) { - users.insert(std::make_pair(rnti, std::unique_ptr(new ue(this, rnti, uecfg)))); + // in the ue ctor, "triggered_by_rach" is set to true so as to start the MSG3 RX TIMEOUT when we create the ue + users.insert(std::make_pair(rnti, std::unique_ptr(new ue(this, rnti, uecfg, true)))); rlc->add_user(rnti); pdcp->add_user(rnti); logger.info("Added new user rnti=0x%x", rnti); @@ -494,9 +495,9 @@ void rrc_nr::sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_ uecfg.carriers[0].cc = 0; uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{}; - ref_args.duplex = cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_TDD - ? srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4 - : srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; + ref_args.duplex = cfg.cell_list[0].duplex_mode == SRSRAN_DUPLEX_MODE_TDD + ? srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4 + : srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{ref_args}; uecfg.phy_cfg.csi = {}; // disable CSI until RA is complete @@ -545,11 +546,95 @@ void rrc_nr::sgnb_release_request(uint16_t nr_rnti) 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_, const sched_nr_ue_cfg_t& uecfg_) : +rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg_, bool triggered_by_rach) : parent(parent_), rnti(rnti_), uecfg(uecfg_) { // Derive UE cfg from rrc_cfg_nr_t uecfg.phy_cfg.pdcch = parent->cfg.cell_list[0].phy_cell.pdcch; + + // Set timer for MSG3_RX_TIMEOUT or UE_INACTIVITY_TIMEOUT + activity_timer = parent->task_sched.get_unique_timer(); + triggered_by_rach ? set_activity_timeout(MSG3_RX_TIMEOUT) : set_activity_timeout(UE_INACTIVITY_TIMEOUT); +} + +void rrc_nr::ue::set_activity_timeout(activity_timeout_type_t type) +{ + uint32_t deadline_ms = 0; + + switch (type) { + case MSG3_RX_TIMEOUT: + // TODO: Retrieve the parameters from somewhere(RRC?) - Currently hardcoded to 100ms + deadline_ms = 100; + break; + case UE_INACTIVITY_TIMEOUT: + // TODO: Add a value for the inactivity timeout - currently no activity set this case + return; + default: + parent->logger.error("Unknown timeout type %d", type); + return; + } + + // Currently we only set the timer for the MSG3_RX_TIMEOUT case + activity_timer.set(deadline_ms, [this, type](uint32_t tid) { activity_timer_expired(type); }); + parent->logger.debug("Setting timer for %s for rnti=0x%x to %dms", to_string(type).c_str(), rnti, deadline_ms); + + set_activity(); +} + +void rrc_nr::ue::set_activity(bool enabled) +{ + if (rnti == SRSRAN_MRNTI) { + return; + } + if (not enabled) { + if (activity_timer.is_running()) { + parent->logger.debug("Inactivity timer interrupted for rnti=0x%x", rnti); + } + activity_timer.stop(); + return; + } + + // re-start activity timer with current timeout value + activity_timer.run(); + parent->logger.debug("Activity registered for rnti=0x%x (timeout_value=%dms)", rnti, activity_timer.duration()); +} + +void rrc_nr::ue::activity_timer_expired(const activity_timeout_type_t type) +{ + parent->logger.info("Activity timer for rnti=0x%x expired after %d ms", rnti, activity_timer.time_elapsed()); + + // TODO: Insert a check to ensure the RNTI exists +#if 0 + if (parent->s1ap->user_exists(rnti)) { +#endif + switch (type) { + case UE_INACTIVITY_TIMEOUT: + // TODO: Add action to be executed + break; + case MSG3_RX_TIMEOUT: + // MSG3 timeout, no need to notify S1AP, just remove UE + parent->rem_user(rnti); + con_release_result = procedure_result_code::msg3_timeout; + break; + default: + // Unhandled activity timeout, just remove UE and log an error + parent->rem_user(rnti); + con_release_result = procedure_result_code::activity_timeout; + parent->logger.error( + "Unhandled reason for activity timer expiration. rnti=0x%x, cause %d", rnti, static_cast(type)); + } +#if 0 + } else { + parent->rem_user_thread(rnti); + } +#endif + state = rrc_nr_state_t::RRC_IDLE; +} + +std::string rrc_nr::ue::to_string(const activity_timeout_type_t& type) +{ + constexpr static const char* options[] = {"Msg3 reception", "UE inactivity", "UE reestablishment"}; + return srsran::enum_to_text(options, (uint32_t)activity_timeout_type_t::nulltype, (uint32_t)type); } void rrc_nr::ue::send_connection_setup() @@ -1289,6 +1374,10 @@ int rrc_nr::ue::handle_sgnb_addition_request(uint16_t eutra_rnti_, const sgnb_ad ack_params.eps_bearer_id = req_params.eps_bearer_id; parent->rrc_eutra->sgnb_addition_ack(eutra_rnti_, ack_params); + // stop activity timer for msg3 + activity_timer.stop(); + parent->logger.debug("SgNB addition req. - Stopping MSG3 activity timer for rnti=0x%x", rnti); + // recognize RNTI as ENDC user endc = true; eutra_rnti = eutra_rnti_; @@ -1302,6 +1391,8 @@ 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); + activity_timer.stop(); + parent->logger.debug("Received MAC CE-RNTI for 0x%x - stopping MSG3 timer", rnti); // Add DRB1 to MAC for (auto& drb : cell_group_cfg.rlc_bearer_to_add_mod_list) { From ebaab9b1d0a6d4ee56985681b71b5c173fbb4995 Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Fri, 22 Oct 2021 17:42:56 +0200 Subject: [PATCH 41/60] rrc,nr: add private fnc to overload public method... ... and propagate input to calling function Signed-off-by: Carlo Galiotto --- srsenb/hdr/stack/rrc/rrc_nr.h | 21 +++------------- srsenb/src/stack/rrc/rrc_nr.cc | 46 ++++++++++++++++------------------ 2 files changed, 26 insertions(+), 41 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index a8d58937a..a74f2e909 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -111,20 +111,8 @@ public: nulltype }; - /// List of results a RRC procedure may produce. - enum class procedure_result_code { - none, - activity_timeout, - error_mme_not_connected, - error_unknown_rnti, - radio_conn_with_ue_lost, - msg3_timeout, - fail_in_radio_interface_proc, - unspecified - }; - /// @param [in] triggered_by_rach: indicates whether the UE is created as part of a RACH process - ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg, bool triggered_by_rach = false); + ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg, bool triggered_by_rach = true); void send_connection_setup(); void send_dl_ccch(asn1::rrc_nr::dl_ccch_msg_s* dl_dcch_msg); @@ -208,9 +196,6 @@ public: rrc_nr_state_t state = rrc_nr_state_t::RRC_IDLE; uint8_t transaction_id = 0; - /// Connection release result. - procedure_result_code con_release_result = procedure_result_code::none; - // RRC configs for UEs asn1::rrc_nr::cell_group_cfg_s cell_group_cfg; asn1::rrc_nr::radio_bearer_cfg_s radio_bearer_cfg; @@ -254,8 +239,10 @@ private: uint32_t nof_si_messages = 0; - // Private Methods + /// Private Methods void handle_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu); + /// This gets called by rrc_nr::sgnb_addition_request and WILL NOT TRIGGER the RX MSG3 activity timer + int add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg, bool triggered_by_rach = false); // logging typedef enum { Rx = 0, Tx } direction_t; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 439bfa6ca..6a666c8ae 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -157,12 +157,15 @@ rrc_nr_cfg_t rrc_nr::update_default_cfg(const rrc_nr_cfg_t& current) return cfg_default; } -// This function is called from PRACH worker (can wait) -int rrc_nr::add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg) +/* @brief PRIVATE function, gets called by sgnb_addition_request + * + * This function WILL NOT TRIGGER the RX MSG3 activity timer + */ +int rrc_nr::add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg, bool triggered_by_rach) { if (users.count(rnti) == 0) { - // in the ue ctor, "triggered_by_rach" is set to true so as to start the MSG3 RX TIMEOUT when we create the ue - users.insert(std::make_pair(rnti, std::unique_ptr(new ue(this, rnti, uecfg, true)))); + // If in the ue ctor, "triggered_by_rach" is set to true, this will start the MSG3 RX TIMEOUT at ue creation + users.insert(std::make_pair(rnti, std::unique_ptr(new ue(this, rnti, uecfg, triggered_by_rach)))); rlc->add_user(rnti); pdcp->add_user(rnti); logger.info("Added new user rnti=0x%x", rnti); @@ -173,6 +176,16 @@ int rrc_nr::add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg) } } +/* @brief PUBLIC function, gets called by mac_nr::rach_detected + * + * This function is called from PRACH worker (can wait) and WILL TRIGGER the RX MSG3 activity timer + */ +int rrc_nr::add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg) +{ + // Set "triggered_by_rach" to true to start the MSG3 RX TIMEOUT + return add_user(rnti, uecfg, true); +} + void rrc_nr::rem_user(uint16_t rnti) { auto user_it = users.find(rnti); @@ -508,7 +521,7 @@ void rrc_nr::sgnb_addition_request(uint16_t eutra_rnti, const sgnb_addition_req_ return; } - if (add_user(nr_rnti, uecfg) != SRSRAN_SUCCESS) { + if (add_user(nr_rnti, uecfg, false) != SRSRAN_SUCCESS) { logger.error("Failed to allocate RNTI at RRC"); rrc_eutra->sgnb_addition_reject(eutra_rnti); return; @@ -583,9 +596,6 @@ void rrc_nr::ue::set_activity_timeout(activity_timeout_type_t type) void rrc_nr::ue::set_activity(bool enabled) { - if (rnti == SRSRAN_MRNTI) { - return; - } if (not enabled) { if (activity_timer.is_running()) { parent->logger.debug("Inactivity timer interrupted for rnti=0x%x", rnti); @@ -603,31 +613,21 @@ void rrc_nr::ue::activity_timer_expired(const activity_timeout_type_t type) { parent->logger.info("Activity timer for rnti=0x%x expired after %d ms", rnti, activity_timer.time_elapsed()); - // TODO: Insert a check to ensure the RNTI exists -#if 0 - if (parent->s1ap->user_exists(rnti)) { -#endif switch (type) { case UE_INACTIVITY_TIMEOUT: // TODO: Add action to be executed break; case MSG3_RX_TIMEOUT: - // MSG3 timeout, no need to notify S1AP, just remove UE + // MSG3 timeout, no need to notify NGAP or LTE stack. Just remove UE parent->rem_user(rnti); - con_release_result = procedure_result_code::msg3_timeout; break; default: // Unhandled activity timeout, just remove UE and log an error parent->rem_user(rnti); - con_release_result = procedure_result_code::activity_timeout; parent->logger.error( "Unhandled reason for activity timer expiration. rnti=0x%x, cause %d", rnti, static_cast(type)); } -#if 0 - } else { - parent->rem_user_thread(rnti); - } -#endif + state = rrc_nr_state_t::RRC_IDLE; } @@ -1374,10 +1374,6 @@ int rrc_nr::ue::handle_sgnb_addition_request(uint16_t eutra_rnti_, const sgnb_ad ack_params.eps_bearer_id = req_params.eps_bearer_id; parent->rrc_eutra->sgnb_addition_ack(eutra_rnti_, ack_params); - // stop activity timer for msg3 - activity_timer.stop(); - parent->logger.debug("SgNB addition req. - Stopping MSG3 activity timer for rnti=0x%x", rnti); - // recognize RNTI as ENDC user endc = true; eutra_rnti = eutra_rnti_; @@ -1391,6 +1387,8 @@ 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); + + // stop RX MSG3 activity timer on MAC CE RNTI reception activity_timer.stop(); parent->logger.debug("Received MAC CE-RNTI for 0x%x - stopping MSG3 timer", rnti); From 0c35045543d6baedd74ef5e0b254592518e007eb Mon Sep 17 00:00:00 2001 From: Carlo Galiotto Date: Fri, 22 Oct 2021 19:05:02 +0200 Subject: [PATCH 42/60] rrc,nr: remove default value from input arg + ... change input arg name Signed-off-by: Carlo Galiotto --- srsenb/hdr/stack/rrc/rrc_nr.h | 6 +++--- srsenb/src/stack/rrc/rrc_nr.cc | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/srsenb/hdr/stack/rrc/rrc_nr.h b/srsenb/hdr/stack/rrc/rrc_nr.h index a74f2e909..6d8a47d1a 100644 --- a/srsenb/hdr/stack/rrc/rrc_nr.h +++ b/srsenb/hdr/stack/rrc/rrc_nr.h @@ -111,8 +111,8 @@ public: nulltype }; - /// @param [in] triggered_by_rach: indicates whether the UE is created as part of a RACH process - ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg, bool triggered_by_rach = true); + /// @param [in] start_msg3_timer: indicates whether the UE is created as part of a RACH process + ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg, bool start_msg3_timer = true); void send_connection_setup(); void send_dl_ccch(asn1::rrc_nr::dl_ccch_msg_s* dl_dcch_msg); @@ -242,7 +242,7 @@ private: /// Private Methods void handle_pdu(uint16_t rnti, uint32_t lcid, srsran::unique_byte_buffer_t pdu); /// This gets called by rrc_nr::sgnb_addition_request and WILL NOT TRIGGER the RX MSG3 activity timer - int add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg, bool triggered_by_rach = false); + int add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg, bool start_msg3_timer); // logging typedef enum { Rx = 0, Tx } direction_t; diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 6a666c8ae..7315a88d7 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -161,11 +161,11 @@ rrc_nr_cfg_t rrc_nr::update_default_cfg(const rrc_nr_cfg_t& current) * * This function WILL NOT TRIGGER the RX MSG3 activity timer */ -int rrc_nr::add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg, bool triggered_by_rach) +int rrc_nr::add_user(uint16_t rnti, const sched_nr_ue_cfg_t& uecfg, bool start_msg3_timer) { if (users.count(rnti) == 0) { - // If in the ue ctor, "triggered_by_rach" is set to true, this will start the MSG3 RX TIMEOUT at ue creation - users.insert(std::make_pair(rnti, std::unique_ptr(new ue(this, rnti, uecfg, triggered_by_rach)))); + // If in the ue ctor, "start_msg3_timer" is set to true, this will start the MSG3 RX TIMEOUT at ue creation + users.insert(std::make_pair(rnti, std::unique_ptr(new ue(this, rnti, uecfg, start_msg3_timer)))); rlc->add_user(rnti); pdcp->add_user(rnti); logger.info("Added new user rnti=0x%x", rnti); @@ -559,7 +559,7 @@ void rrc_nr::sgnb_release_request(uint16_t nr_rnti) 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_, const sched_nr_ue_cfg_t& uecfg_, bool triggered_by_rach) : +rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg_, bool start_msg3_timer) : parent(parent_), rnti(rnti_), uecfg(uecfg_) { // Derive UE cfg from rrc_cfg_nr_t @@ -567,7 +567,7 @@ rrc_nr::ue::ue(rrc_nr* parent_, uint16_t rnti_, const sched_nr_ue_cfg_t& uecfg_, // Set timer for MSG3_RX_TIMEOUT or UE_INACTIVITY_TIMEOUT activity_timer = parent->task_sched.get_unique_timer(); - triggered_by_rach ? set_activity_timeout(MSG3_RX_TIMEOUT) : set_activity_timeout(UE_INACTIVITY_TIMEOUT); + start_msg3_timer ? set_activity_timeout(MSG3_RX_TIMEOUT) : set_activity_timeout(UE_INACTIVITY_TIMEOUT); } void rrc_nr::ue::set_activity_timeout(activity_timeout_type_t type) From 0663594aa171fc329a70fb9c0a52556624f3a272 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 22 Oct 2021 23:16:41 +0100 Subject: [PATCH 43/60] nr,gnb,sched: add extra checks to sched to ensure the max nof grants is not exceeded --- srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h | 8 ++++---- srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc | 11 +++++++++++ srsenb/src/stack/mac/nr/sched_nr_pdcch.cc | 5 +++-- srsenb/src/stack/mac/nr/sched_nr_signalling.cc | 8 ++++++++ srsenb/src/stack/mac/nr/sched_nr_worker.cc | 4 ++++ 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h b/srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h index c151a8465..68dfec3d3 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_pdcch.h @@ -72,9 +72,9 @@ private: pdcch_grant_type_t alloc_type; slot_ue* ue; }; - srsran::bounded_vector dci_list; - pdcch_dl_list_t& pdcch_dl_list; - pdcch_ul_list_t& pdcch_ul_list; + srsran::bounded_vector dci_list; + pdcch_dl_list_t& pdcch_dl_list; + pdcch_ul_list_t& pdcch_ul_list; // DFS decision tree of PDCCH grants struct tree_node { @@ -85,7 +85,7 @@ private: /// Accumulation of all PDCCH masks for the current solution (DFS path) coreset_bitmap total_mask, current_mask; }; - using alloc_tree_dfs_t = srsran::bounded_vector; + using alloc_tree_dfs_t = std::vector; alloc_tree_dfs_t dfs_tree, saved_dfs_tree; srsran::span get_cce_loc_table(const alloc_record& record) const; 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 6982a5726..61ffe8df8 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_grant_allocator.cc @@ -110,6 +110,13 @@ alloc_result bwp_slot_allocator::alloc_rar_and_msg3(uint16_t if (ret != alloc_result::success) { return ret; } + if (bwp_pdcch_slot.rar.full()) { + return alloc_result::no_grant_space; + } + if (pending_rars.size() > MAX_GRANTS) { + logger.error("SCHED: Trying to allocate too many Msg3 grants in a single slot (%zd)", pending_rars.size()); + return alloc_result::invalid_grant_params; + } // Check DL RB collision if (bwp_pdcch_slot.dl_prbs.collides(interv)) { @@ -209,6 +216,10 @@ alloc_result bwp_slot_allocator::alloc_pdsch(slot_ue& ue, const prb_grant& dl_gr if (result != alloc_result::success) { return result; } + if (bwp_uci_slot.pending_acks.full()) { + logger.warning("SCHED: PDSCH allocation for rnti=0x%x failed due to lack of space for respective ACK", ue.rnti); + return alloc_result::no_grant_space; + } if (bwp_pdsch_slot.dl_prbs.collides(dl_grant)) { return alloc_result::sch_collision; } diff --git a/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc b/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc index 2d54546d0..c6098b80d 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_pdcch.cc @@ -56,6 +56,7 @@ bool coreset_region::alloc_dci(pdcch_grant_type_t alloc_type, srsran_assert((user == nullptr) xor (alloc_type == pdcch_grant_type_t::dl_data or alloc_type == pdcch_grant_type_t::ul_data), "UE should be only provided for DL or UL data allocations"); + srsran_assert(not dci_list.full(), "SCHED: Unable to allocate DCI"); saved_dfs_tree.clear(); alloc_record record; @@ -80,13 +81,13 @@ bool coreset_region::alloc_dci(pdcch_grant_type_t alloc_type, dci_list.push_back(record); return true; } - if (dfs_tree.empty()) { + if (saved_dfs_tree.empty()) { saved_dfs_tree = dfs_tree; } } while (get_next_dfs()); // Revert steps to initial state, before dci record allocation was attempted - dfs_tree = saved_dfs_tree; + dfs_tree.swap(saved_dfs_tree); if (record.alloc_type == pdcch_grant_type_t::ul_data) { pdcch_ul_list.pop_back(); } else { diff --git a/srsenb/src/stack/mac/nr/sched_nr_signalling.cc b/srsenb/src/stack/mac/nr/sched_nr_signalling.cc index a3b310be7..5d125b5e8 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_signalling.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_signalling.cc @@ -34,6 +34,10 @@ void sched_nzp_csi_rs(srsran::const_span nzp_csi_rs_set // Check if the resource is scheduled for this slot if (srsran_csi_rs_send(&nzp_csi_resource.periodicity, &slot_cfg)) { + if (csi_rs_list.full()) { + srslog::fetch_basic_logger("MAC-NR").error("SCHED: Failed to allocate NZP-CSI RS"); + return; + } csi_rs_list.push_back(nzp_csi_resource); } } @@ -42,6 +46,10 @@ void sched_nzp_csi_rs(srsran::const_span nzp_csi_rs_set void sched_ssb_basic(const slot_point& sl_point, uint32_t ssb_periodicity, ssb_list& ssb_list) { + if (ssb_list.full()) { + srslog::fetch_basic_logger("MAC-NR").error("SCHED: Failed to allocate SSB"); + return; + } // If the periodicity is 0, it means that the parameter was not passed by the upper layers. // In that case, we use default value of 5ms (see Clause 4.1, TS 38.213) if (ssb_periodicity == 0) { diff --git a/srsenb/src/stack/mac/nr/sched_nr_worker.cc b/srsenb/src/stack/mac/nr/sched_nr_worker.cc index ecc0b6215..6bba51151 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_worker.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_worker.cc @@ -183,6 +183,10 @@ void slot_cc_worker::postprocess_decisions() } if (not has_pusch) { // If any UCI information is triggered, schedule PUCCH + if (bwp_slot.pucch.full()) { + logger.warning("SCHED: Cannot fit pending UCI into PUCCH"); + continue; + } bwp_slot.pucch.emplace_back(); mac_interface_phy_nr::pucch_t& pucch = bwp_slot.pucch.back(); From 905b9dcb3755230923d9d6f01ced5c47c91af00c Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Thu, 20 May 2021 10:42:01 +0200 Subject: [PATCH 44/60] update mailing list link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55e6e51a4..3ac88667b 100644 --- a/README.md +++ b/README.md @@ -21,4 +21,4 @@ For license details, see LICENSE file. Support ======= -Mailing list: http://www.srs.io/mailman/listinfo/srslte-users +Mailing list: https://lists.softwareradiosystems.com/mailman/listinfo/srslte-users \ No newline at end of file From 7ab4da9d1136342d31c79e6a93c7a979a4f81624 Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Sun, 3 Oct 2021 09:39:17 +0100 Subject: [PATCH 45/60] Update mailing list --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3ac88667b..f8e9792a4 100644 --- a/README.md +++ b/README.md @@ -21,4 +21,4 @@ For license details, see LICENSE file. Support ======= -Mailing list: https://lists.softwareradiosystems.com/mailman/listinfo/srslte-users \ No newline at end of file +Mailing list: https://lists.srsran.com/mailman/listinfo/srsran-users From bbacd47e02ac3b4aba0a5bc7d54324b24369925d Mon Sep 17 00:00:00 2001 From: Paul Sutton Date: Sun, 3 Oct 2021 09:56:09 +0100 Subject: [PATCH 46/60] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 976786810..b2cdc030b 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,6 +1,6 @@ ## Issue Description ## From 95bf85b3d3bbaa0564c1a3f12e1645924911fb2b Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 22 Oct 2021 13:00:07 +0200 Subject: [PATCH 47/60] Reduced maximum number of CSI reports --- lib/include/srsran/phy/phch/csi.h | 6 +++--- lib/include/srsran/phy/phch/csi_cfg.h | 14 +++++--------- lib/include/srsran/phy/phch/uci_cfg_nr.h | 16 ++++++++-------- lib/src/phy/phch/csi.c | 17 ++++++++++++----- 4 files changed, 28 insertions(+), 25 deletions(-) diff --git a/lib/include/srsran/phy/phch/csi.h b/lib/include/srsran/phy/phch/csi.h index 0bbfe0e24..5801f94ad 100644 --- a/lib/include/srsran/phy/phch/csi.h +++ b/lib/include/srsran/phy/phch/csi.h @@ -39,7 +39,7 @@ srsran_csi_new_nzp_csi_rs_measurement(const srsran_csi_hl_resource_cfg_t csi_res */ SRSRAN_API int srsran_csi_reports_generate(const srsran_csi_hl_cfg_t* cfg, const srsran_slot_cfg_t* slot_cfg, - srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT]); + srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_SLOT_MAX_NOF_REPORT]); /** * @brief Quantifies a given set of CSI reports from the given set of measurements @@ -49,9 +49,9 @@ SRSRAN_API int srsran_csi_reports_generate(const srsran_csi_hl_cfg_t* cfg, * @return The number CSI reports for transmission if the provided data is valid, SRSRAN_ERROR code otherwise */ SRSRAN_API int -srsran_csi_reports_quantify(const srsran_csi_report_cfg_t reports[SRSRAN_CSI_MAX_NOF_REPORT], +srsran_csi_reports_quantify(const srsran_csi_report_cfg_t reports[SRSRAN_CSI_SLOT_MAX_NOF_REPORT], const srsran_csi_channel_measurements_t measurements[SRSRAN_CSI_MAX_NOF_RESOURCES], - srsran_csi_report_value_t report_value[SRSRAN_CSI_MAX_NOF_REPORT]); + srsran_csi_report_value_t report_value[SRSRAN_CSI_SLOT_MAX_NOF_REPORT]); /** * @brief Compute number of CSI bits necessary to transmit all the CSI reports for a PUCCH transmission diff --git a/lib/include/srsran/phy/phch/csi_cfg.h b/lib/include/srsran/phy/phch/csi_cfg.h index 6471c9fc8..a43e554f5 100644 --- a/lib/include/srsran/phy/phch/csi_cfg.h +++ b/lib/include/srsran/phy/phch/csi_cfg.h @@ -22,6 +22,11 @@ */ #define SRSRAN_CSI_MAX_NOF_REPORT 48 +/** + * @brief Maximum number of supported simultaneous CSI reports in a single slot transmission + */ +#define SRSRAN_CSI_SLOT_MAX_NOF_REPORT 2 + /** * @brief Maximum number of CSI-RS resources defined in TS 38.331 maxNrofCSI-ResourceConfigurations */ @@ -193,13 +198,4 @@ typedef struct SRSRAN_API { }; } srsran_csi_report_value_t; -/** - * @brief Complete report configuration and value - */ -typedef struct SRSRAN_API { - srsran_csi_report_cfg_t cfg[SRSRAN_CSI_MAX_NOF_REPORT]; ///< Configuration ready for encoding - srsran_csi_report_value_t value[SRSRAN_CSI_MAX_NOF_REPORT]; ///< Quantified values - uint32_t nof_reports; ///< Total number of reports to transmit -} srsran_csi_reports_t; - #endif // SRSRAN_CSI_CFG_H diff --git a/lib/include/srsran/phy/phch/uci_cfg_nr.h b/lib/include/srsran/phy/phch/uci_cfg_nr.h index dd4e3a410..7be80b72e 100644 --- a/lib/include/srsran/phy/phch/uci_cfg_nr.h +++ b/lib/include/srsran/phy/phch/uci_cfg_nr.h @@ -68,11 +68,11 @@ typedef struct { */ typedef struct SRSRAN_API { /// Common Parameters - srsran_harq_ack_cfg_t ack; ///< HARQ-ACK configuration - uint32_t o_sr; ///< Number of SR bits - bool sr_positive_present; ///< Set to true if there is at least one positive SR - srsran_csi_report_cfg_t csi[SRSRAN_CSI_MAX_NOF_REPORT]; ///< CSI report configuration - uint32_t nof_csi; ///< Number of CSI reports + srsran_harq_ack_cfg_t ack; ///< HARQ-ACK configuration + uint32_t o_sr; ///< Number of SR bits + bool sr_positive_present; ///< Set to true if there is at least one positive SR + srsran_csi_report_cfg_t csi[SRSRAN_CSI_SLOT_MAX_NOF_REPORT]; ///< CSI report configuration + uint32_t nof_csi; ///< Number of CSI reports union { srsran_uci_nr_pucch_cfg_t pucch; ///< Configuration for transmission in PUCCH srsran_uci_nr_pusch_cfg_t pusch; ///< Configuration for transmission in PUSCH @@ -83,9 +83,9 @@ typedef struct SRSRAN_API { * @brief Uplink Control Information (UCI) message packed information */ typedef struct SRSRAN_API { - uint8_t ack[SRSRAN_HARQ_ACK_MAX_NOF_BITS]; ///< HARQ ACK feedback bits - uint32_t sr; ///< Number of positive SR - srsran_csi_report_value_t csi[SRSRAN_CSI_MAX_NOF_REPORT]; ///< Packed CSI report values + uint8_t ack[SRSRAN_HARQ_ACK_MAX_NOF_BITS]; ///< HARQ ACK feedback bits + uint32_t sr; ///< Number of positive SR + srsran_csi_report_value_t csi[SRSRAN_CSI_SLOT_MAX_NOF_REPORT]; ///< Packed CSI report values bool valid; ///< Indicates whether the message has been decoded successfully, ignored in the transmitter } srsran_uci_value_nr_t; diff --git a/lib/src/phy/phch/csi.c b/lib/src/phy/phch/csi.c index 412aec709..79f38485a 100644 --- a/lib/src/phy/phch/csi.c +++ b/lib/src/phy/phch/csi.c @@ -179,7 +179,7 @@ int srsran_csi_new_nzp_csi_rs_measurement( int srsran_csi_reports_generate(const srsran_csi_hl_cfg_t* cfg, const srsran_slot_cfg_t* slot_cfg, - srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_MAX_NOF_REPORT]) + srsran_csi_report_cfg_t report_cfg[SRSRAN_CSI_SLOT_MAX_NOF_REPORT]) { uint32_t count = 0; @@ -189,7 +189,7 @@ int srsran_csi_reports_generate(const srsran_csi_hl_cfg_t* cfg, } // Make sure report configuration is initialised to zero - SRSRAN_MEM_ZERO(report_cfg, srsran_csi_report_cfg_t, SRSRAN_CSI_MAX_NOF_REPORT); + SRSRAN_MEM_ZERO(report_cfg, srsran_csi_report_cfg_t, SRSRAN_CSI_SLOT_MAX_NOF_REPORT); // Iterate every possible configured CSI report for (uint32_t i = 0; i < SRSRAN_CSI_MAX_NOF_REPORT; i++) { @@ -198,6 +198,13 @@ int srsran_csi_reports_generate(const srsran_csi_hl_cfg_t* cfg, continue; } + if (count >= SRSRAN_CSI_SLOT_MAX_NOF_REPORT) { + ERROR("The number of CSI reports in the slot (%d) exceeds the maximum (%d)", + count++, + SRSRAN_CSI_SLOT_MAX_NOF_REPORT); + return SRSRAN_ERROR; + } + // Configure report report_cfg[count].cfg = cfg->reports[i]; report_cfg[count].nof_ports = 1; @@ -209,9 +216,9 @@ int srsran_csi_reports_generate(const srsran_csi_hl_cfg_t* cfg, return (int)count; } -int srsran_csi_reports_quantify(const srsran_csi_report_cfg_t reports[SRSRAN_CSI_MAX_NOF_REPORT], +int srsran_csi_reports_quantify(const srsran_csi_report_cfg_t reports[SRSRAN_CSI_SLOT_MAX_NOF_REPORT], const srsran_csi_channel_measurements_t measurements[SRSRAN_CSI_MAX_NOF_RESOURCES], - srsran_csi_report_value_t report_value[SRSRAN_CSI_MAX_NOF_REPORT]) + srsran_csi_report_value_t report_value[SRSRAN_CSI_SLOT_MAX_NOF_REPORT]) { uint32_t count = 0; @@ -221,7 +228,7 @@ int srsran_csi_reports_quantify(const srsran_csi_report_cfg_t reports[ } // Iterate every possible configured CSI report - for (uint32_t i = 0; i < SRSRAN_CSI_MAX_NOF_REPORT; i++) { + for (uint32_t i = 0; i < SRSRAN_CSI_SLOT_MAX_NOF_REPORT; i++) { // If the report is the last one, break if (reports->cfg.type == SRSRAN_CSI_REPORT_TYPE_NONE) { break; From b54d4ad8e29aa58c9cc0b8f232265ed5314f3271 Mon Sep 17 00:00:00 2001 From: Xavier Arteaga Date: Fri, 22 Oct 2021 16:26:52 +0200 Subject: [PATCH 48/60] Avoid copying gNb common configuration in slot basis --- srsenb/hdr/phy/nr/worker_pool.h | 6 ---- srsenb/src/phy/nr/worker_pool.cc | 52 ++++++++++++++------------------ 2 files changed, 22 insertions(+), 36 deletions(-) diff --git a/srsenb/hdr/phy/nr/worker_pool.h b/srsenb/hdr/phy/nr/worker_pool.h index fe543f3a7..b3cfd9317 100644 --- a/srsenb/hdr/phy/nr/worker_pool.h +++ b/srsenb/hdr/phy/nr/worker_pool.h @@ -90,12 +90,6 @@ private: uint32_t nof_prach_workers = 0; double srate_hz = 0.0; ///< Current sampling rate in Hz - // Current configuration - std::mutex common_cfg_mutex; - srsran_carrier_nr_t carrier = {}; - srsran_pdcch_cfg_nr_t pdcch_cfg = {}; - srsran_ssb_cfg_t ssb_cfg = {}; - public: struct args_t { double srate_hz = 0.0; diff --git a/srsenb/src/phy/nr/worker_pool.cc b/srsenb/src/phy/nr/worker_pool.cc index 0e9bf6172..8f3f775b1 100644 --- a/srsenb/src/phy/nr/worker_pool.cc +++ b/srsenb/src/phy/nr/worker_pool.cc @@ -89,27 +89,6 @@ slot_worker* worker_pool::wait_worker(uint32_t tti) { slot_worker* w = (slot_worker*)pool.wait_worker(tti); - // Only if a worker was available - if (w != nullptr) { - srsran_carrier_nr_t carrier_; - srsran_pdcch_cfg_nr_t pdcch_cfg_; - srsran_ssb_cfg_t ssb_cfg_; - - // Copy configuration - { - std::unique_lock lock(common_cfg_mutex); - carrier_ = carrier; - pdcch_cfg_ = pdcch_cfg; - ssb_cfg_ = ssb_cfg; - } - - // Set worker configuration - if (not w->set_common_cfg(carrier_, pdcch_cfg_, ssb_cfg_)) { - logger.error("Error setting common config"); - return nullptr; - } - } - // Save current TTI current_tti = tti; @@ -153,15 +132,28 @@ int worker_pool::set_common_cfg(const phy_interface_rrc_nr::common_cfg_t& common prach.init(0, cell, prach_cfg, &prach_stack_adaptor, logger, 0, nof_prach_workers); prach.set_max_prach_offset_us(1000); - // Save current configuration - { - std::unique_lock lock(common_cfg_mutex); - carrier = common_cfg.carrier; - pdcch_cfg = common_cfg.pdcch; - ssb_cfg = common_cfg.ssb; - ssb_cfg.srate_hz = srate_hz; - ssb_cfg.scaling = - srsran_convert_dB_to_amplitude(srsran_gnb_dl_get_maximum_signal_power_dBfs(common_cfg.carrier.nof_prb)); + // Setup SSB sampling rate and scaling + srsran_ssb_cfg_t ssb_cfg = common_cfg.ssb; + ssb_cfg.srate_hz = srate_hz; + ssb_cfg.scaling = + srsran_convert_dB_to_amplitude(srsran_gnb_dl_get_maximum_signal_power_dBfs(common_cfg.carrier.nof_prb)); + + // For each worker set configuration + for (uint32_t i = 0; i < pool.get_nof_workers(); i++) { + // Reserve worker from pool + slot_worker* w = (slot_worker*)pool.wait_worker_id(i); + if (w == nullptr) { + // Skip worker if invalid pointer + continue; + } + + // Setup worker common configuration + if (not w->set_common_cfg(common_cfg.carrier, common_cfg.pdcch, ssb_cfg)) { + return SRSRAN_ERROR; + } + + // Release worker + w->release(); } return SRSRAN_SUCCESS; From 2cee65bb889dd890fb3571d69f1de349341b2e55 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 22 Oct 2021 10:31:19 +0200 Subject: [PATCH 49/60] enb,slot_worker: skip UL signal demod if scheduler returns empty results --- srsenb/src/phy/nr/slot_worker.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/srsenb/src/phy/nr/slot_worker.cc b/srsenb/src/phy/nr/slot_worker.cc index bbe96fca7..a5453e47a 100644 --- a/srsenb/src/phy/nr/slot_worker.cc +++ b/srsenb/src/phy/nr/slot_worker.cc @@ -148,6 +148,11 @@ bool slot_worker::work_ul() return false; } + if (ul_sched.pucch.empty() && ul_sched.pusch.empty()) { + // early exit if nothing has been scheduled + return true; + } + // Demodulate if (srsran_gnb_ul_fft(&gnb_ul) < SRSRAN_SUCCESS) { logger.error("Error in demodulation"); From cf4b6d0beabbfd385f2569e0924bb2473debb459 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 22 Oct 2021 11:30:06 +0200 Subject: [PATCH 50/60] sched_nr_interface: make PHY results a reference to avoid copying --- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 3 ++- srsenb/src/stack/mac/nr/mac_nr.cc | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index 36d806905..372ae7951 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -119,7 +119,8 @@ public: using sched_rar_list_t = srsran::bounded_vector; struct dl_sched_res_t { sched_rar_list_t rar; - dl_sched_t dl_sched; + dl_sched_t& dl_sched; + dl_sched_res_t(dl_sched_t& dl_sched_) : dl_sched(dl_sched_) {} }; virtual ~sched_nr_interface() = default; diff --git a/srsenb/src/stack/mac/nr/mac_nr.cc b/srsenb/src/stack/mac/nr/mac_nr.cc index 00d710dae..8ac80aef4 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -296,14 +296,13 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched logger.set_context(slot_cfg.idx - TX_ENB_DELAY); slot_point pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; - sched_nr_interface::dl_sched_res_t dl_res; + sched_nr_interface::dl_sched_res_t dl_res(dl_sched); // Run Scheduler int ret = sched.run_slot(pdsch_slot, 0, dl_res); if (ret != SRSRAN_SUCCESS) { return ret; } - dl_sched = dl_res.dl_sched; uint32_t rar_count = 0; srsran::rwlock_read_guard rw_lock(rwmutex); From 8294724aad6243e26ee772aaec0dae7f57e803b5 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 22 Oct 2021 10:35:00 +0200 Subject: [PATCH 51/60] gnb_interface: reduce MAX_GRANTS to 4 this significantly reduces data copies when providing the PHY with scheduler results. --- lib/include/srsran/interfaces/gnb_interfaces.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/include/srsran/interfaces/gnb_interfaces.h b/lib/include/srsran/interfaces/gnb_interfaces.h index c3c5bc3f1..7a26cbc47 100644 --- a/lib/include/srsran/interfaces/gnb_interfaces.h +++ b/lib/include/srsran/interfaces/gnb_interfaces.h @@ -194,7 +194,7 @@ class mac_interface_phy_nr { public: const static int MAX_SSB = 4; - const static int MAX_GRANTS = 64; + const static int MAX_GRANTS = 32; const static int MAX_PUCCH_MSG = 64; const static int MAX_PUCCH_CANDIDATES = 2; const static int MAX_NZP_CSI_RS = 4; From 87459bad17c37cc2e6ce7c9a565fbafec03095c1 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 22 Oct 2021 12:41:26 +0100 Subject: [PATCH 52/60] nr,sched: avoid resetting Tx softbuffer every time a new DL HARQ proc is allocated --- srsenb/src/stack/mac/nr/sched_nr_harq.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/srsenb/src/stack/mac/nr/sched_nr_harq.cc b/srsenb/src/stack/mac/nr/sched_nr_harq.cc index f8496c721..b4160a61f 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_harq.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_harq.cc @@ -122,7 +122,6 @@ bool dl_harq_proc::new_tx(slot_point slot_tx, uint32_t max_retx) { if (harq_proc::new_tx(slot_tx, slot_ack, grant, mcs, max_retx)) { - softbuffer->reset(); pdu->clear(); return true; } From be388aa53fde3d02e4f8ead5c4578648f8ab0f60 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Sat, 23 Oct 2021 16:24:14 +0200 Subject: [PATCH 53/60] rrc_nr: temporary fix of heap-use-after free see https://github.com/softwareradiosystems/srsLTE/issues/3545 --- srsenb/src/stack/rrc/rrc_nr.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsenb/src/stack/rrc/rrc_nr.cc b/srsenb/src/stack/rrc/rrc_nr.cc index 7315a88d7..1d6d0c70e 100644 --- a/srsenb/src/stack/rrc/rrc_nr.cc +++ b/srsenb/src/stack/rrc/rrc_nr.cc @@ -613,6 +613,8 @@ void rrc_nr::ue::activity_timer_expired(const activity_timeout_type_t type) { parent->logger.info("Activity timer for rnti=0x%x expired after %d ms", rnti, activity_timer.time_elapsed()); + state = rrc_nr_state_t::RRC_IDLE; + switch (type) { case UE_INACTIVITY_TIMEOUT: // TODO: Add action to be executed @@ -627,8 +629,6 @@ void rrc_nr::ue::activity_timer_expired(const activity_timeout_type_t type) parent->logger.error( "Unhandled reason for activity timer expiration. rnti=0x%x, cause %d", rnti, static_cast(type)); } - - state = rrc_nr_state_t::RRC_IDLE; } std::string rrc_nr::ue::to_string(const activity_timeout_type_t& type) From e4247517d093fd463ef53657aab98f01bd7d6056 Mon Sep 17 00:00:00 2001 From: Francisco Date: Fri, 22 Oct 2021 12:37:38 +0100 Subject: [PATCH 54/60] nr,sched: update sched_nr_test to support the new DL sched no-copy api --- srsenb/hdr/stack/mac/nr/sched_nr.h | 4 +-- srsenb/hdr/stack/mac/nr/sched_nr_cfg.h | 4 +-- srsenb/hdr/stack/mac/nr/sched_nr_interface.h | 14 +++++----- srsenb/src/stack/mac/nr/mac_nr.cc | 13 +++++---- srsenb/src/stack/mac/nr/sched_nr.cc | 6 ++--- srsenb/src/stack/mac/nr/sched_nr_cell.cc | 2 +- srsenb/test/mac/nr/sched_nr_sim_ue.cc | 25 +++++++++-------- srsenb/test/mac/nr/sched_nr_sim_ue.h | 27 ++++++++++++------- srsenb/test/mac/nr/sched_nr_test.cc | 20 +++++++++----- .../test/mac/nr/sched_nr_ue_ded_test_suite.cc | 2 +- 10 files changed, 67 insertions(+), 50 deletions(-) diff --git a/srsenb/hdr/stack/mac/nr/sched_nr.h b/srsenb/hdr/stack/mac/nr/sched_nr.h index 5e3e79de7..2fc654873 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr.h @@ -50,8 +50,8 @@ public: 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); - int run_slot(slot_point pdsch_tti, uint32_t cc, dl_sched_res_t& result) override; - int get_ul_sched(slot_point pusch_tti, uint32_t cc, ul_sched_t& result) override; + int run_slot(slot_point pdsch_tti, uint32_t cc, dl_res_t& result) override; + int get_ul_sched(slot_point pusch_tti, uint32_t cc, ul_res_t& result) override; void get_metrics(mac_metrics_t& metrics); diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h index eba8a0631..4cd1e69d3 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_cfg.h @@ -48,8 +48,8 @@ using ue_cc_cfg_t = sched_nr_interface::ue_cc_cfg_t; using pdcch_cce_pos_list = srsran::bounded_vector; using bwp_cce_pos_list = std::array, SRSRAN_NOF_SF_X_FRAME>; using dl_sched_t = sched_nr_interface::dl_sched_t; -using ul_sched_t = sched_nr_interface::ul_sched_t; -using dl_sched_res_t = sched_nr_interface::dl_sched_res_t; +using ul_sched_t = sched_nr_interface::ul_res_t; +using dl_sched_res_t = sched_nr_interface::dl_res_t; /// Generate list of CCE locations for UE based on coreset and search space configurations void get_dci_locs(const srsran_coreset_t& coreset, diff --git a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h index 372ae7951..6b247f227 100644 --- a/srsenb/hdr/stack/mac/nr/sched_nr_interface.h +++ b/srsenb/hdr/stack/mac/nr/sched_nr_interface.h @@ -114,13 +114,13 @@ public: ///// Sched Result ///// using dl_sched_t = mac_interface_phy_nr::dl_sched_t; - using ul_sched_t = mac_interface_phy_nr::ul_sched_t; + using ul_res_t = mac_interface_phy_nr::ul_sched_t; using sched_rar_list_t = srsran::bounded_vector; - struct dl_sched_res_t { - sched_rar_list_t rar; - dl_sched_t& dl_sched; - dl_sched_res_t(dl_sched_t& dl_sched_) : dl_sched(dl_sched_) {} + struct dl_res_t { + sched_rar_list_t& rar; + dl_sched_t& dl_sched; + dl_res_t(sched_rar_list_t& rar_, dl_sched_t& dl_sched_) : rar(rar_), dl_sched(dl_sched_) {} }; virtual ~sched_nr_interface() = default; @@ -128,8 +128,8 @@ public: 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 run_slot(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 int run_slot(slot_point slot_rx, uint32_t cc, dl_res_t& result) = 0; + virtual int get_ul_sched(slot_point slot_rx, uint32_t cc, ul_res_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 8ac80aef4..18ddb266a 100644 --- a/srsenb/src/stack/mac/nr/mac_nr.cc +++ b/srsenb/src/stack/mac/nr/mac_nr.cc @@ -167,9 +167,9 @@ void mac_nr::rach_detected(const rach_info_t& rach_info) uecfg.carriers[0].cc = 0; uecfg.ue_bearers[0].direction = mac_lc_ch_cfg_t::BOTH; srsran::phy_cfg_nr_default_t::reference_cfg_t ref_args{}; - ref_args.duplex = cell_config[0].duplex.mode == SRSRAN_DUPLEX_MODE_TDD - ? srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4 - : srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; + ref_args.duplex = cell_config[0].duplex.mode == SRSRAN_DUPLEX_MODE_TDD + ? srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_TDD_CUSTOM_6_4 + : srsran::phy_cfg_nr_default_t::reference_cfg_t::R_DUPLEX_FDD; uecfg.phy_cfg = srsran::phy_cfg_nr_default_t{ref_args}; uecfg.phy_cfg.csi = {}; // disable CSI until RA is complete @@ -295,15 +295,18 @@ int mac_nr::get_dl_sched(const srsran_slot_cfg_t& slot_cfg, dl_sched_t& dl_sched { logger.set_context(slot_cfg.idx - TX_ENB_DELAY); - slot_point pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; - sched_nr_interface::dl_sched_res_t dl_res(dl_sched); + slot_point pdsch_slot = srsran::slot_point{NUMEROLOGY_IDX, slot_cfg.idx}; // Run Scheduler + sched_nr_interface::sched_rar_list_t rar_list; + sched_nr_interface::dl_res_t dl_res(rar_list, dl_sched); + int ret = sched.run_slot(pdsch_slot, 0, dl_res); if (ret != SRSRAN_SUCCESS) { return ret; } + // Generate MAC DL PDUs uint32_t rar_count = 0; srsran::rwlock_read_guard rw_lock(rwmutex); for (pdsch_t& pdsch : dl_sched.pdsch) { diff --git a/srsenb/src/stack/mac/nr/sched_nr.cc b/srsenb/src/stack/mac/nr/sched_nr.cc index 89b1dcf02..f33f00f89 100644 --- a/srsenb/src/stack/mac/nr/sched_nr.cc +++ b/srsenb/src/stack/mac/nr/sched_nr.cc @@ -131,10 +131,10 @@ void sched_nr::ue_cfg_impl(uint16_t rnti, const ue_cfg_t& uecfg) } /// Generate {pdcch_slot,cc} scheduling decision -int sched_nr::run_slot(slot_point slot_dl, uint32_t cc, dl_sched_res_t& result) +int sched_nr::run_slot(slot_point slot_dl, uint32_t cc, dl_res_t& result) { // Copy UL results to intermediate buffer - ul_sched_t& ul_res = pending_results->add_ul_result(slot_dl, cc); + ul_res_t& ul_res = pending_results->add_ul_result(slot_dl, cc); // Generate {slot_idx,cc} result sched_workers->run_slot(slot_dl, cc, result, ul_res); @@ -143,7 +143,7 @@ int sched_nr::run_slot(slot_point slot_dl, uint32_t cc, dl_sched_res_t& result) } /// Fetch {ul_slot,cc} UL scheduling decision -int sched_nr::get_ul_sched(slot_point slot_ul, uint32_t cc, ul_sched_t& result) +int sched_nr::get_ul_sched(slot_point slot_ul, uint32_t cc, ul_res_t& result) { if (not pending_results->has_ul_result(slot_ul, cc)) { // sched result hasn't been generated diff --git a/srsenb/src/stack/mac/nr/sched_nr_cell.cc b/srsenb/src/stack/mac/nr/sched_nr_cell.cc index 0881d2144..80cd0b73a 100644 --- a/srsenb/src/stack/mac/nr/sched_nr_cell.cc +++ b/srsenb/src/stack/mac/nr/sched_nr_cell.cc @@ -133,7 +133,7 @@ void ra_sched::run_slot(bwp_slot_allocator& slot_alloc) if (pdcch_slot >= rar.rar_win.stop()) { fmt::memory_buffer str_buffer; fmt::format_to(str_buffer, - "SCHED: Could not transmit RAR within the window Window={}, PRACH={}, RAR={}", + "SCHED: Could not transmit RAR within the window={}, PRACH={}, RAR={}", rar.rar_win, rar.prach_slot, pdcch_slot); diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.cc b/srsenb/test/mac/nr/sched_nr_sim_ue.cc index 1f4ba8b3b..b3a21fc9f 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.cc +++ b/srsenb/test/mac/nr/sched_nr_sim_ue.cc @@ -42,8 +42,8 @@ int sched_nr_ue_sim::update(const sched_nr_cc_result_view& cc_out) { update_dl_harqs(cc_out); - for (uint32_t i = 0; i < cc_out.dl_cc_result->dl_sched.pdcch_dl.size(); ++i) { - const auto& data = cc_out.dl_cc_result->dl_sched.pdcch_dl[i]; + for (uint32_t i = 0; i < cc_out.dl_cc_result.dl_sched.pdcch_dl.size(); ++i) { + const auto& data = cc_out.dl_cc_result.dl_sched.pdcch_dl[i]; if (data.dci.ctx.rnti != ctxt.rnti) { continue; } @@ -64,8 +64,8 @@ int sched_nr_ue_sim::update(const sched_nr_cc_result_view& cc_out) void sched_nr_ue_sim::update_dl_harqs(const sched_nr_cc_result_view& cc_out) { uint32_t cc = cc_out.cc; - for (uint32_t i = 0; i < cc_out.dl_cc_result->dl_sched.pdcch_dl.size(); ++i) { - const auto& data = cc_out.dl_cc_result->dl_sched.pdcch_dl[i]; + for (uint32_t i = 0; i < cc_out.dl_cc_result.dl_sched.pdcch_dl.size(); ++i) { + const auto& data = cc_out.dl_cc_result.dl_sched.pdcch_dl[i]; if (data.dci.ctx.rnti != ctxt.rnti) { continue; } @@ -207,7 +207,9 @@ void sched_nr_base_tester::run_slot(slot_point slot_tx) void sched_nr_base_tester::generate_cc_result(uint32_t cc) { // Run scheduler - sched_ptr->run_slot(current_slot_tx, cc, cc_results[cc].dl_res); + sched_nr_interface::dl_res_t dl_sched(cc_results[cc].rar, cc_results[cc].dl_res); + sched_ptr->run_slot(current_slot_tx, cc, dl_sched); + cc_results[cc].rar = dl_sched.rar; sched_ptr->get_ul_sched(current_slot_tx, cc, cc_results[cc].ul_res); auto tp2 = std::chrono::steady_clock::now(); cc_results[cc].cc_latency_ns = std::chrono::duration_cast(tp2 - slot_start_tp); @@ -229,17 +231,14 @@ void sched_nr_base_tester::process_results() // Derived class-defined tests process_slot_result(slot_ctxt, cc_results); - sched_nr_cc_result_view cc_out; - cc_out.slot = current_slot_tx; for (uint32_t cc = 0; cc < cell_params.size(); ++cc) { - cc_out.cc = cc; - cc_out.dl_cc_result = &cc_results[cc].dl_res; - cc_out.ul_cc_result = &cc_results[cc].ul_res; + sched_nr_cc_result_view cc_out{ + current_slot_tx, cc, cc_results[cc].rar, cc_results[cc].dl_res, cc_results[cc].ul_res}; // Run common tests - test_dl_pdcch_consistency(cc_out.dl_cc_result->dl_sched.pdcch_dl); - test_pdsch_consistency(cc_out.dl_cc_result->dl_sched.pdsch); - test_ssb_scheduled_grant(cc_out.slot, cell_params[cc_out.cc].cfg, cc_out.dl_cc_result->dl_sched.ssb); + test_dl_pdcch_consistency(cc_out.dl_cc_result.dl_sched.pdcch_dl); + test_pdsch_consistency(cc_out.dl_cc_result.dl_sched.pdsch); + test_ssb_scheduled_grant(cc_out.slot, cell_params[cc_out.cc].cfg, cc_out.dl_cc_result.dl_sched.ssb); // Run UE-dedicated tests test_dl_sched_result(slot_ctxt, cc_out); diff --git a/srsenb/test/mac/nr/sched_nr_sim_ue.h b/srsenb/test/mac/nr/sched_nr_sim_ue.h index 1c62b20e5..054a90ee7 100644 --- a/srsenb/test/mac/nr/sched_nr_sim_ue.h +++ b/srsenb/test/mac/nr/sched_nr_sim_ue.h @@ -39,10 +39,18 @@ struct ue_nr_harq_ctxt_t { slot_point last_slot_tx, first_slot_tx, last_slot_ack; }; struct sched_nr_cc_result_view { - slot_point slot; - uint32_t cc; - const sched_nr_interface::dl_sched_res_t* dl_cc_result; - const sched_nr_interface::ul_sched_t* ul_cc_result; + slot_point slot; + uint32_t cc; + const sched_nr_interface::dl_res_t dl_cc_result; + const sched_nr_interface::ul_res_t* ul_cc_result; + + sched_nr_cc_result_view(slot_point slot_, + uint32_t cc_, + sched_nr_interface::sched_rar_list_t& rar, + sched_nr_interface::dl_sched_t& dl_res, + sched_nr_interface::ul_res_t& ul_res) : + slot(slot_), cc(cc_), dl_cc_result(rar, dl_res), ul_cc_result(&ul_res) + {} }; struct ue_nr_cc_ctxt_t { @@ -108,11 +116,12 @@ class sched_nr_base_tester { public: struct cc_result_t { - slot_point slot_tx; - uint32_t cc; - sched_nr_interface::dl_sched_res_t dl_res; - sched_nr_interface::ul_sched_t ul_res; - std::chrono::nanoseconds cc_latency_ns; + slot_point slot_tx; + uint32_t cc; + sched_nr_interface::dl_sched_t dl_res; + sched_nr_interface::sched_rar_list_t rar; + sched_nr_interface::ul_res_t ul_res; + std::chrono::nanoseconds cc_latency_ns; }; sched_nr_base_tester(const sched_nr_interface::sched_args_t& sched_args, diff --git a/srsenb/test/mac/nr/sched_nr_test.cc b/srsenb/test/mac/nr/sched_nr_test.cc index 0f36b9c42..44d8c4cec 100644 --- a/srsenb/test/mac/nr/sched_nr_test.cc +++ b/srsenb/test/mac/nr/sched_nr_test.cc @@ -36,12 +36,17 @@ public: })->cc_latency_ns.count(); for (auto& cc_out : cc_list) { - pdsch_count += cc_out.dl_res.dl_sched.pdcch_dl.size(); + pdsch_count += cc_out.dl_res.pdcch_dl.size(); cc_res_count++; - TESTASSERT(cc_out.dl_res.dl_sched.pdcch_dl.size() <= 1); - if (srsran_duplex_nr_is_dl(&cell_params[cc_out.cc].cfg.duplex, 0, current_slot_tx.slot_idx())) { - TESTASSERT(cc_out.dl_res.dl_sched.pdcch_dl.size() == 1 or not cc_out.dl_res.dl_sched.ssb.empty()); + bool is_dl_slot = srsran_duplex_nr_is_dl(&cell_params[cc_out.cc].cfg.duplex, 0, current_slot_tx.slot_idx()); + + if (is_dl_slot) { + if (cc_out.dl_res.ssb.empty()) { + TESTASSERT(slot_ctxt.ue_db.empty() or cc_out.dl_res.pdcch_dl.size() == 1); + } else { + TESTASSERT(cc_out.dl_res.pdcch_dl.size() == 0); + } } } } @@ -76,12 +81,13 @@ void run_sched_nr_test(uint32_t nof_workers) } sched_nr_tester tester(cfg, cells_cfg, test_name, nof_workers); - sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(nof_sectors); - tester.add_user(rnti, uecfg, slot_point{0, 0}, 0); - for (uint32_t nof_slots = 0; nof_slots < max_nof_ttis; ++nof_slots) { slot_point slot_rx(0, nof_slots % 10240); slot_point slot_tx = slot_rx + TX_ENB_DELAY; + if (slot_rx.to_uint() == 9) { + sched_nr_interface::ue_cfg_t uecfg = get_default_ue_cfg(nof_sectors); + tester.add_user(rnti, uecfg, slot_rx, 0); + } tester.run_slot(slot_tx); } diff --git a/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.cc b/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.cc index 22d33e251..ca7df7cc1 100644 --- a/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.cc +++ b/srsenb/test/mac/nr/sched_nr_ue_ded_test_suite.cc @@ -21,7 +21,7 @@ using namespace srsenb::sched_nr_impl; void test_dl_sched_result(const sim_nr_enb_ctxt_t& enb_ctxt, const sched_nr_cc_result_view& cc_out) { slot_point pdcch_slot = cc_out.slot; - const pdcch_dl_list_t& pdcchs = cc_out.dl_cc_result->dl_sched.pdcch_dl; + const pdcch_dl_list_t& pdcchs = cc_out.dl_cc_result.dl_sched.pdcch_dl; // Iterate over UE PDCCH allocations for (const pdcch_dl_t& pdcch : pdcchs) { From dd5eda04e3a3a6e5e5fc72b7bb4919951a9d9154 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Sat, 23 Oct 2021 17:10:39 +0200 Subject: [PATCH 55/60] ue,rrc_nr: clear DRB to LCID lookup during RRC release --- srsue/src/stack/rrc/rrc_nr.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/srsue/src/stack/rrc/rrc_nr.cc b/srsue/src/stack/rrc/rrc_nr.cc index f1be64467..3f668883e 100644 --- a/srsue/src/stack/rrc/rrc_nr.cc +++ b/srsue/src/stack/rrc/rrc_nr.cc @@ -367,6 +367,7 @@ void rrc_nr::rrc_release() rlc->reset(); pdcp->reset(); mac->reset(); + lcid_drb.clear(); } int rrc_nr::get_nr_capabilities(srsran::byte_buffer_t* nr_caps_pdu) From 5f93ff6ed0f1acbef2df0c56f7bc5aa2c5015ad8 Mon Sep 17 00:00:00 2001 From: faluco Date: Thu, 21 Oct 2021 16:51:57 +0200 Subject: [PATCH 56/60] Batch of data race fixes in the following classes: RLC AM, Intra measure, UL HARQ, PHY common. --- srsue/hdr/phy/scell/intra_measure_lte.h | 5 +++-- srsue/hdr/stack/mac/ul_harq.h | 12 ++++++------ srsue/src/phy/phy_common.cc | 8 +++++--- srsue/src/phy/scell/intra_measure_lte.cc | 17 +++++++++++++---- srsue/src/stack/mac/ul_harq.cc | 4 ++-- 5 files changed, 29 insertions(+), 17 deletions(-) diff --git a/srsue/hdr/phy/scell/intra_measure_lte.h b/srsue/hdr/phy/scell/intra_measure_lte.h index 7a1b7a931..69fc93cc0 100644 --- a/srsue/hdr/phy/scell/intra_measure_lte.h +++ b/srsue/hdr/phy/scell/intra_measure_lte.h @@ -73,8 +73,9 @@ private: bool measure_rat(measure_context_t context, std::vector& buffer, float rx_gain_offset) override; srslog::basic_logger& logger; - srsran_cell_t serving_cell = {}; ///< Current serving cell in the EARFCN, to avoid reporting it - uint32_t current_earfcn = 0; ///< Current EARFCN + srsran_cell_t serving_cell = {}; ///< Current serving cell in the EARFCN, to avoid reporting it + std::atomic current_earfcn = {0}; ///< Current EARFCN + std::mutex mutex; /// LTE-based measuring objects scell_recv scell_rx; ///< Secondary cell searcher diff --git a/srsue/hdr/stack/mac/ul_harq.h b/srsue/hdr/stack/mac/ul_harq.h index 182f15672..de55b241f 100644 --- a/srsue/hdr/stack/mac/ul_harq.h +++ b/srsue/hdr/stack/mac/ul_harq.h @@ -117,12 +117,12 @@ private: }; lockable_grant cur_grant; - uint32_t pid; - uint32_t current_tx_nb; - uint32_t current_irv; - bool harq_feedback; - bool is_grant_configured; - bool is_initiated; + uint32_t pid; + std::atomic current_tx_nb = {0}; + uint32_t current_irv; + bool harq_feedback; + bool is_grant_configured; + bool is_initiated; srslog::basic_logger& logger; ul_harq_entity* harq_entity; diff --git a/srsue/src/phy/phy_common.cc b/srsue/src/phy/phy_common.cc index a3c7618eb..f44c57e9e 100644 --- a/srsue/src/phy/phy_common.cc +++ b/srsue/src/phy/phy_common.cc @@ -306,12 +306,14 @@ bool phy_common::is_any_ul_pending_ack() #define tti_pusch_hi(sf) \ (sf->tti + \ (cell.frame_type == SRSRAN_FDD ? FDD_HARQ_DELAY_UL_MS \ - : I_phich ? 7 : k_pusch[sf->tdd_config.sf_config][sf->tti % 10]) + \ + : I_phich ? 7 \ + : k_pusch[sf->tdd_config.sf_config][sf->tti % 10]) + \ (FDD_HARQ_DELAY_DL_MS - FDD_HARQ_DELAY_UL_MS)) #define tti_pusch_gr(sf) \ (sf->tti + \ (cell.frame_type == SRSRAN_FDD ? FDD_HARQ_DELAY_UL_MS \ - : dci->ul_idx == 1 ? 7 : k_pusch[sf->tdd_config.sf_config][sf->tti % 10]) + \ + : dci->ul_idx == 1 ? 7 \ + : k_pusch[sf->tdd_config.sf_config][sf->tti % 10]) + \ (FDD_HARQ_DELAY_DL_MS - FDD_HARQ_DELAY_UL_MS)) // SF->TTI is at which Format0 dci is received @@ -893,7 +895,7 @@ void phy_common::reset() cur_pathloss = 0; cur_pusch_power = 0; } - last_ri = 0; + last_ri = 0; // Reset all measurements reset_measurements(SRSRAN_MAX_CARRIERS); diff --git a/srsue/src/phy/scell/intra_measure_lte.cc b/srsue/src/phy/scell/intra_measure_lte.cc index 7719a42c1..b31cda61d 100644 --- a/srsue/src/phy/scell/intra_measure_lte.cc +++ b/srsue/src/phy/scell/intra_measure_lte.cc @@ -42,8 +42,11 @@ void intra_measure_lte::init(uint32_t cc_idx, const args_t& args) void intra_measure_lte::set_primary_cell(uint32_t earfcn, srsran_cell_t cell) { + { + std::lock_guard lock(mutex); + serving_cell = cell; + } current_earfcn = earfcn; - serving_cell = cell; set_current_sf_len((uint32_t)SRSRAN_SF_LEN_PRB(cell.nof_prb)); } @@ -51,8 +54,14 @@ bool intra_measure_lte::measure_rat(measure_context_t context, std::vector { std::set cells_to_measure = context.active_pci; + srsran_cell_t serving_cell_copy{}; + { + std::lock_guard lock(mutex); + serving_cell_copy = serving_cell; + } + // Detect new cells using PSS/SSS - scell_rx.find_cells(buffer.data(), serving_cell, context.meas_len_ms, cells_to_measure); + scell_rx.find_cells(buffer.data(), serving_cell_copy, context.meas_len_ms, cells_to_measure); // Initialise empty neighbour cell list std::vector neighbour_cells = {}; @@ -62,10 +71,10 @@ bool intra_measure_lte::measure_rat(measure_context_t context, std::vector // Use Cell Reference signal to measure cells in the time domain for all known active PCI for (const uint32_t& id : cells_to_measure) { // Do not measure serving cell here since it's measured by workers - if (id == serving_cell.id) { + if (id == serving_cell_copy.id) { continue; } - srsran_cell_t cell = serving_cell; + srsran_cell_t cell = serving_cell_copy; cell.id = id; if (srsran_refsignal_dl_sync_set_cell(&refsignal_dl_sync, cell) < SRSRAN_SUCCESS) { diff --git a/srsue/src/stack/mac/ul_harq.cc b/srsue/src/stack/mac/ul_harq.cc index c97eb4a11..47c53f452 100644 --- a/srsue/src/stack/mac/ul_harq.cc +++ b/srsue/src/stack/mac/ul_harq.cc @@ -317,7 +317,7 @@ void ul_harq_entity::ul_harq_process::generate_retx(mac_interface_phy_lte::mac_g Info("UL %d: Adaptive retx=%d, RV=%d, TBS=%d, HI=%s, ndi=%d, prev_ndi=%d", pid, - current_tx_nb, + current_tx_nb.load(), get_rv(), grant.tb.tbs, harq_feedback ? "ACK" : "NACK", @@ -337,7 +337,7 @@ void ul_harq_entity::ul_harq_process::generate_retx(mac_interface_phy_lte::mac_g // Non-adaptive retx are only sent if HI=NACK. If HI=ACK but no dci was received do not reset PID Info("UL %d: Non-Adaptive retx=%d, RV=%d, TBS=%d, HI=%s", pid, - current_tx_nb, + current_tx_nb.load(), get_rv(), cur_grant.get_tbs(), harq_feedback ? "ACK" : "NACK"); From a1b2f3915d18ccb71f7328c8bff35ccc145a2945 Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 22 Oct 2021 13:30:00 +0200 Subject: [PATCH 57/60] Whitelist lock order inversion tsan issue in srsenb::rlc::rb_is_um. --- lib/include/srsran/common/tsan_options.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/include/srsran/common/tsan_options.h b/lib/include/srsran/common/tsan_options.h index 18e5bace0..421e4ee31 100644 --- a/lib/include/srsran/common/tsan_options.h +++ b/lib/include/srsran/common/tsan_options.h @@ -50,7 +50,8 @@ const char* __tsan_default_suppressions() // Lock order inversion issues in these functions, ignore it as it uses rw locks in read mode "deadlock:srsenb::mac::rlc_buffer_state\n" "deadlock:srsenb::mac::snr_info\n" - "deadlock:srsenb::mac::ack_info\n"; + "deadlock:srsenb::mac::ack_info\n" + "deadlock:srsenb::rlc::rb_is_um\n"; } #ifdef __cplusplus From 3ecc8bb4c6029df35bfd9fb57ec4347b14b39784 Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 22 Oct 2021 13:35:33 +0200 Subject: [PATCH 58/60] Fix data race in gw::deactivate_eps_bearer. --- srsue/src/stack/upper/gw.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/srsue/src/stack/upper/gw.cc b/srsue/src/stack/upper/gw.cc index 57c400cff..7ae6c8cbb 100644 --- a/srsue/src/stack/upper/gw.cc +++ b/srsue/src/stack/upper/gw.cc @@ -210,6 +210,8 @@ int gw::setup_if_addr(uint32_t eps_bearer_id, uint8_t pdn_type, uint32_t ip_addr int gw::deactivate_eps_bearer(const uint32_t eps_bearer_id) { + std::lock_guard lock(gw_mutex); + // only deactivation of default bearer if (eps_bearer_id == static_cast(default_eps_bearer_id)) { logger.debug("Deactivating EPS bearer %d", eps_bearer_id); @@ -467,8 +469,10 @@ int gw::setup_if_addr4(uint32_t ip_addr, char* err_str) close(tun_fd); return SRSRAN_ERROR_CANT_START; } - ifr.ifr_netmask.sa_family = AF_INET; - if (inet_pton(ifr.ifr_netmask.sa_family, args.tun_dev_netmask.c_str(), &((struct sockaddr_in*)&ifr.ifr_netmask)->sin_addr.s_addr) != 1) { + ifr.ifr_netmask.sa_family = AF_INET; + if (inet_pton(ifr.ifr_netmask.sa_family, + args.tun_dev_netmask.c_str(), + &((struct sockaddr_in*)&ifr.ifr_netmask)->sin_addr.s_addr) != 1) { logger.error("Invalid tun_dev_netmask: %s", args.tun_dev_netmask.c_str()); srsran::console("Invalid tun_dev_netmask: %s\n", args.tun_dev_netmask.c_str()); perror("inet_pton"); From 0ada9a01ec6d8f59913dd4631b298509c5b03f85 Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 22 Oct 2021 13:49:46 +0200 Subject: [PATCH 59/60] Whitelist TSAN issue in srsenb::mac::sr_detected. --- lib/include/srsran/common/tsan_options.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/include/srsran/common/tsan_options.h b/lib/include/srsran/common/tsan_options.h index 421e4ee31..dd6fbe23d 100644 --- a/lib/include/srsran/common/tsan_options.h +++ b/lib/include/srsran/common/tsan_options.h @@ -51,7 +51,8 @@ const char* __tsan_default_suppressions() "deadlock:srsenb::mac::rlc_buffer_state\n" "deadlock:srsenb::mac::snr_info\n" "deadlock:srsenb::mac::ack_info\n" - "deadlock:srsenb::rlc::rb_is_um\n"; + "deadlock:srsenb::rlc::rb_is_um\n" + "deadlock:srsenb::mac::sr_detected\n"; } #ifdef __cplusplus From 28887a43841df415329c8e597cce861f85b83b5a Mon Sep 17 00:00:00 2001 From: faluco Date: Fri, 22 Oct 2021 14:23:26 +0200 Subject: [PATCH 60/60] Relax memory ordering for atomic load for the ul_harq::current_tx_nb member. --- srsue/src/stack/mac/ul_harq.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srsue/src/stack/mac/ul_harq.cc b/srsue/src/stack/mac/ul_harq.cc index 47c53f452..e2bcbeb0f 100644 --- a/srsue/src/stack/mac/ul_harq.cc +++ b/srsue/src/stack/mac/ul_harq.cc @@ -317,7 +317,7 @@ void ul_harq_entity::ul_harq_process::generate_retx(mac_interface_phy_lte::mac_g Info("UL %d: Adaptive retx=%d, RV=%d, TBS=%d, HI=%s, ndi=%d, prev_ndi=%d", pid, - current_tx_nb.load(), + current_tx_nb.load(std::memory_order_relaxed), get_rv(), grant.tb.tbs, harq_feedback ? "ACK" : "NACK", @@ -337,7 +337,7 @@ void ul_harq_entity::ul_harq_process::generate_retx(mac_interface_phy_lte::mac_g // Non-adaptive retx are only sent if HI=NACK. If HI=ACK but no dci was received do not reset PID Info("UL %d: Non-Adaptive retx=%d, RV=%d, TBS=%d, HI=%s", pid, - current_tx_nb.load(), + current_tx_nb.load(std::memory_order_relaxed), get_rv(), cur_grant.get_tbs(), harq_feedback ? "ACK" : "NACK");