diff --git a/lib/include/srsran/interfaces/enb_mac_interfaces.h b/lib/include/srsran/interfaces/enb_mac_interfaces.h index a0b72ce8e..aa6e4e45c 100644 --- a/lib/include/srsran/interfaces/enb_mac_interfaces.h +++ b/lib/include/srsran/interfaces/enb_mac_interfaces.h @@ -28,7 +28,8 @@ namespace srsenb { struct mac_args_t { - uint32_t nof_prb; ///< Needed to dimension MAC softbuffers for all cells + uint32_t nof_prb; ///< Needed to dimension MAC softbuffers for all cells + uint32_t prach_bi; ///< Backoff Indicator to prevent UE from PRACHing too fast sched_interface::sched_args_t sched; int lcid_padding; uint32_t nof_prealloc_ues; ///< Number of UE resources to pre-allocate at eNB startup diff --git a/lib/include/srsran/interfaces/ue_mac_interfaces.h b/lib/include/srsran/interfaces/ue_mac_interfaces.h index 38b2a9f11..0ba7ac57b 100644 --- a/lib/include/srsran/interfaces/ue_mac_interfaces.h +++ b/lib/include/srsran/interfaces/ue_mac_interfaces.h @@ -103,10 +103,7 @@ public: virtual void bch_decoded_ok(uint32_t cc_idx, uint8_t* payload, uint32_t len) = 0; /* Indicate successful decoding of MCH TB through PMCH */ - virtual void mch_decoded(uint32_t len, bool crc) = 0; - - /* Obtain action for a new MCH subframe. */ - virtual void new_mch_dl(const srsran_pdsch_grant_t& phy_grant, tb_action_dl_t* action) = 0; + virtual void mch_decoded(uint32_t len, bool crc, uint8_t* payload) = 0; /* Communicate the number of mbsfn services available */ virtual void set_mbsfn_config(uint32_t nof_mbsfn_services) = 0; diff --git a/lib/src/common/threads.c b/lib/src/common/threads.c index f6955e052..a590690c3 100644 --- a/lib/src/common/threads.c +++ b/lib/src/common/threads.c @@ -155,18 +155,17 @@ bool threads_new_rt_cpu(pthread_t* thread, void* (*start_routine)(void*), void* int err = pthread_create(thread, attr_enable ? &attr : NULL, start_routine, arg); if (err) { if (EPERM == err) { - // Join failed thread for avoiding memory leak from previous trial - pthread_join(*thread, NULL); - - perror("Warning: Failed to create thread with real-time priority. Creating it with normal priority"); + fprintf(stderr, + "Warning: Failed to create thread with real-time priority. Creating it with normal priority: %s\n", + strerror(err)); err = pthread_create(thread, NULL, start_routine, arg); if (err) { - perror("pthread_create"); + fprintf(stderr, "Error: Failed to create thread with normal priority: %s\n", strerror(err)); } else { ret = true; } } else { - perror("pthread_create"); + fprintf(stderr, "Error: Failed to create thread with real-time priority: %s\n", strerror(err)); } } else { ret = true; diff --git a/lib/test/asn1/srsran_asn1_nas_test.cc b/lib/test/asn1/srsran_asn1_nas_test.cc index 871975260..b3ff4c243 100644 --- a/lib/test/asn1/srsran_asn1_nas_test.cc +++ b/lib/test/asn1/srsran_asn1_nas_test.cc @@ -132,7 +132,7 @@ int downlink_generic_nas_transport_packing_test() uint8_t nas_message[] = { 0x27, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x68, 0x01, 0x00, 0x06, 0xf0, 0x00, 0x00, 0x00, 0x08, 0x70}; uint8_t generic_msg_cont[] = {0xf0, 0x00, 0x00, 0x00, 0x08, 0x70}; - LIBLTE_BYTE_MSG_STRUCT buf; + LIBLTE_BYTE_MSG_STRUCT buf = {}; LIBLTE_MME_DOWNLINK_GENERIC_NAS_TRANSPORT_MSG_STRUCT dl_generic_nas_transport; LIBLTE_ERROR_ENUM err; @@ -176,7 +176,7 @@ int downlink_generic_nas_transport_with_add_info_packing_test() 0xf0, 0x00, 0x00, 0x00, 0x08, 0x70, 0x65, 0x02, 0x11, 0x11}; uint8_t generic_msg_cont[] = {0xf0, 0x00, 0x00, 0x00, 0x08, 0x70}; uint8_t add_info[] = {0x11, 0x11}; - LIBLTE_BYTE_MSG_STRUCT buf; + LIBLTE_BYTE_MSG_STRUCT buf = {}; LIBLTE_MME_DOWNLINK_GENERIC_NAS_TRANSPORT_MSG_STRUCT dl_generic_nas_transport; LIBLTE_ERROR_ENUM err; diff --git a/srsenb/enb.conf.example b/srsenb/enb.conf.example index 505771a05..fe830507b 100644 --- a/srsenb/enb.conf.example +++ b/srsenb/enb.conf.example @@ -424,3 +424,4 @@ nr_pdsch_mcs=28 #rlf_min_ul_snr_estim = -2 #s1_setup_max_retries = -1 #rx_gain_offset = 62 +#mac_prach_bi = 0 diff --git a/srsenb/hdr/phy/phy_common.h b/srsenb/hdr/phy/phy_common.h index 64f8dfdb5..c6f5fc1cd 100644 --- a/srsenb/hdr/phy/phy_common.h +++ b/srsenb/hdr/phy/phy_common.h @@ -309,8 +309,8 @@ private: std::mutex cell_gain_mutex; bool have_mtch_stop = false; - pthread_mutex_t mtch_mutex = {}; - pthread_cond_t mtch_cvar = {}; + std::mutex mtch_mutex; + std::condition_variable mtch_cvar; srsran::phy_cfg_mbsfn_t mbsfn = {}; bool sib13_configured = false; bool mcch_configured = false; diff --git a/srsenb/src/main.cc b/srsenb/src/main.cc index 46d39baad..2e7153296 100644 --- a/srsenb/src/main.cc +++ b/srsenb/src/main.cc @@ -269,6 +269,7 @@ void parse_args(all_args_t* args, int argc, char* argv[]) ("expert.rlf_min_ul_snr_estim", bpo::value(&args->stack.mac.rlf_min_ul_snr_estim)->default_value(-2), "SNR threshold in dB below which the eNB is notified with rlf ko.") ("expert.max_s1_setup_retries", bpo::value(&args->stack.s1ap.max_s1_setup_retries)->default_value(-1), "Max S1 setup retries") ("expert.rx_gain_offset", bpo::value(&args->phy.rx_gain_offset)->default_value(62), "RX Gain offset to add to rx_gain to calibrate RSRP readings") + ("expert.mac_prach_bi", bpo::value(&args->stack.mac.prach_bi)->default_value(0), "Backoff Indicator to reduce contention in the PRACH channel") // eMBMS section ("embms.enable", bpo::value(&args->stack.embms.enable)->default_value(false), "Enables MBMS in the eNB") diff --git a/srsenb/src/phy/phy_common.cc b/srsenb/src/phy/phy_common.cc index 7b1746e29..6282e13ef 100644 --- a/srsenb/src/phy/phy_common.cc +++ b/srsenb/src/phy/phy_common.cc @@ -50,8 +50,6 @@ bool phy_common::init(const phy_cell_cfg_list_t& cell_list_, cell_list_lte = cell_list_; cell_list_nr = cell_list_nr_; - pthread_mutex_init(&mtch_mutex, nullptr); - pthread_cond_init(&mtch_cvar, nullptr); // Instantiate DL channel emulator if (params.dl_channel_args.enable) { @@ -171,11 +169,10 @@ void phy_common::worker_end(const worker_context_t& w_ctx, const bool& tx_enable void phy_common::set_mch_period_stop(uint32_t stop) { - pthread_mutex_lock(&mtch_mutex); + std::lock_guard lock(mtch_mutex); have_mtch_stop = true; mch_period_stop = stop; - pthread_cond_signal(&mtch_cvar); - pthread_mutex_unlock(&mtch_mutex); + mtch_cvar.notify_one(); } void phy_common::configure_mbsfn(srsran::phy_cfg_mbsfn_t* cfg) @@ -295,9 +292,11 @@ bool phy_common::is_mch_subframe(srsran_mbsfn_cfg_t* cfg, uint32_t phy_tti) uint32_t mbsfn_per_frame = mbsfn.mcch.pmch_info_list[0].sf_alloc_end / +enum_to_number(mbsfn.mcch.pmch_info_list[0].mch_sched_period); uint32_t sf_alloc_idx = frame_alloc_idx * mbsfn_per_frame + ((sf < 4) ? sf - 1 : sf - 3); + std::unique_lock lock(mtch_mutex); while (!have_mtch_stop) { - pthread_cond_wait(&mtch_cvar, &mtch_mutex); + mtch_cvar.wait(lock); } + lock.unlock(); for (uint32_t i = 0; i < mbsfn.mcch.nof_pmch_info; i++) { if (sf_alloc_idx <= mch_period_stop) { cfg->mbsfn_mcs = mbsfn.mcch.pmch_info_list[i].data_mcs; diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index d3014c73b..9d61f1c83 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -933,6 +933,9 @@ uint8_t* mac::assemble_rar(sched_interface::dl_sched_rar_grant_t* grants, srsran::rar_pdu* pdu = &rar_pdu_msg[rar_idx]; rar_payload[enb_cc_idx][rar_idx].clear(); pdu->init_tx(&rar_payload[enb_cc_idx][rar_idx], pdu_len); + if (args.prach_bi > 0 and args.prach_bi <= 12) { + pdu->set_backoff(args.prach_bi); + } for (uint32_t i = 0; i < nof_grants; i++) { srsran_dci_rar_pack(&grants[i].grant, grant_buffer); if (pdu->new_subh()) { diff --git a/srsgnb/src/stack/mac/sched_nr.cc b/srsgnb/src/stack/mac/sched_nr.cc index 2a4425f33..eb2e48bcd 100644 --- a/srsgnb/src/stack/mac/sched_nr.cc +++ b/srsgnb/src/stack/mac/sched_nr.cc @@ -44,11 +44,12 @@ public: struct logger { explicit logger(int cc_, srslog::basic_logger& logger_) : log_enabled(logger_.debug.enabled()), cc(cc_), sched_logger(logger_) - {} - logger(const logger&) = delete; - logger(logger&&) = delete; + { + } + logger(const logger&) = delete; + logger(logger&&) = delete; logger& operator=(const logger&) = delete; - logger& operator=(logger&&) = delete; + logger& operator=(logger&&) = delete; ~logger() { if (log_enabled and event_fmtbuf.size() > 0) { @@ -80,7 +81,8 @@ public: explicit event_manager(sched_params_t& params) : sched_logger(srslog::fetch_basic_logger(params.sched_cfg.logger_name)), carriers(params.cells.size()) - {} + { + } /// Enqueue an event that does not map into a ue method (e.g. rem_user, add_user) void enqueue_event(const char* event_name, srsran::move_callback ev) @@ -185,7 +187,8 @@ private: srsran::move_callback callback; event_t(const char* event_name_, srsran::move_callback c) : event_name(event_name_), callback(std::move(c)) - {} + { + } }; struct ue_event_t { uint16_t rnti; @@ -193,7 +196,8 @@ private: srsran::move_callback callback; ue_event_t(uint16_t rnti_, const char* event_name_, srsran::move_callback c) : rnti(rnti_), event_name(event_name_), callback(std::move(c)) - {} + { + } }; struct ue_cc_event_t { uint16_t rnti; @@ -205,14 +209,15 @@ private: const char* event_name_, srsran::move_callback c) : rnti(rnti_), cc(cc_), event_name(event_name_), callback(std::move(c)) - {} + { + } }; srslog::basic_logger& sched_logger; - std::mutex event_mutex; - srsran::deque next_slot_events, current_slot_events; - srsran::deque next_slot_ue_events, current_slot_ue_events; + std::mutex event_mutex; + std::deque next_slot_events, current_slot_events; + std::deque next_slot_ue_events, current_slot_ue_events; struct cc_events { std::mutex event_cc_mutex; srsran::deque next_slot_ue_events, current_slot_ue_events; diff --git a/srsue/hdr/phy/lte/cc_worker.h b/srsue/hdr/phy/lte/cc_worker.h index 20ff287eb..37a572a49 100644 --- a/srsue/hdr/phy/lte/cc_worker.h +++ b/srsue/hdr/phy/lte/cc_worker.h @@ -84,7 +84,7 @@ private: mac_interface_phy_lte::tb_action_dl_t* action, bool acks[SRSRAN_MAX_CODEWORDS]); int decode_pmch(mac_interface_phy_lte::tb_action_dl_t* action, srsran_mbsfn_cfg_t* mbsfn_cfg); - + void new_mch_dl(mac_interface_phy_lte::tb_action_dl_t*); /* Methods for UL */ bool encode_uplink(mac_interface_phy_lte::tb_action_ul_t* action, srsran_uci_data_t* uci_data); void set_uci_sr(srsran_uci_data_t* uci_data); @@ -100,11 +100,14 @@ private: srsran_dl_sf_cfg_t sf_cfg_dl = {}; srsran_ul_sf_cfg_t sf_cfg_ul = {}; - uint32_t cc_idx = 0; - bool cell_initiated = false; - cf_t* signal_buffer_rx[SRSRAN_MAX_PORTS] = {}; - cf_t* signal_buffer_tx[SRSRAN_MAX_PORTS] = {}; - uint32_t signal_buffer_max_samples = 0; + uint32_t cc_idx = 0; + bool cell_initiated = false; + cf_t* signal_buffer_rx[SRSRAN_MAX_PORTS] = {}; + cf_t* signal_buffer_tx[SRSRAN_MAX_PORTS] = {}; + uint32_t signal_buffer_max_samples = 0; + const static uint32_t mch_payload_buffer_sz = SRSRAN_MAX_BUFFER_SIZE_BYTES; + uint8_t mch_payload_buffer[mch_payload_buffer_sz]; + srsran_softbuffer_rx_t mch_softbuffer; /* Objects for DL */ srsran_ue_dl_t ue_dl = {}; diff --git a/srsue/hdr/stack/mac/mac.h b/srsue/hdr/stack/mac/mac.h index 989bab5c8..a562aa204 100644 --- a/srsue/hdr/stack/mac/mac.h +++ b/srsue/hdr/stack/mac/mac.h @@ -59,13 +59,12 @@ public: /* see mac_interface.h for comments */ void new_grant_ul(uint32_t cc_idx, mac_grant_ul_t grant, tb_action_ul_t* action); void new_grant_dl(uint32_t cc_idx, mac_grant_dl_t grant, tb_action_dl_t* action); - void new_mch_dl(const srsran_pdsch_grant_t& phy_grant, tb_action_dl_t* action); void tb_decoded(uint32_t cc_idx, mac_grant_dl_t grant, bool ack[SRSRAN_MAX_CODEWORDS]); void bch_decoded_ok(uint32_t cc_idx, uint8_t* payload, uint32_t len); uint16_t get_dl_sched_rnti(uint32_t tti); uint16_t get_ul_sched_rnti(uint32_t tti); - void mch_decoded(uint32_t len, bool crc); + void mch_decoded(uint32_t len, bool crc, uint8_t* payload); void process_mch_pdu(uint32_t len); void set_mbsfn_config(uint32_t nof_mbsfn_services); diff --git a/srsue/hdr/stack/ue_stack_lte.h b/srsue/hdr/stack/ue_stack_lte.h index 553583d56..0c64f3195 100644 --- a/srsue/hdr/stack/ue_stack_lte.h +++ b/srsue/hdr/stack/ue_stack_lte.h @@ -145,12 +145,7 @@ public: mac.bch_decoded_ok(cc_idx, payload, len); } - void mch_decoded(uint32_t len, bool crc) final { mac.mch_decoded(len, crc); } - - void new_mch_dl(const srsran_pdsch_grant_t& phy_grant, mac_interface_phy_lte::tb_action_dl_t* action) final - { - mac.new_mch_dl(phy_grant, action); - } + void mch_decoded(uint32_t len, bool crc, uint8_t* payload) final { mac.mch_decoded(len, crc, payload); } void set_mbsfn_config(uint32_t nof_mbsfn_services) final { mac.set_mbsfn_config(nof_mbsfn_services); } diff --git a/srsue/src/phy/lte/cc_worker.cc b/srsue/src/phy/lte/cc_worker.cc index e1f23b998..520a55b12 100644 --- a/srsue/src/phy/lte/cc_worker.cc +++ b/srsue/src/phy/lte/cc_worker.cc @@ -101,6 +101,7 @@ cc_worker::cc_worker(uint32_t cc_idx_, uint32_t max_prb, srsue::phy_common* phy_ chest_default_cfg = ue_dl_cfg.chest_cfg; + srsran_softbuffer_rx_init(&mch_softbuffer, 100); // Set default PHY params reset(); @@ -120,6 +121,7 @@ cc_worker::~cc_worker() free(signal_buffer_rx[i]); } } + srsran_softbuffer_rx_free(&mch_softbuffer); srsran_ue_dl_free(&ue_dl); srsran_ue_ul_free(&ue_ul); } @@ -353,12 +355,12 @@ bool cc_worker::work_dl_mbsfn(srsran_mbsfn_cfg_t mbsfn_cfg) srsran_ra_dl_compute_nof_re(&cell, &sf_cfg_dl, &pmch_cfg.pdsch_cfg.grant); // Send grant to MAC and get action for this TB, then call tb_decoded to unlock MAC - phy->stack->new_mch_dl(pmch_cfg.pdsch_cfg.grant, &dl_action); + new_mch_dl(&dl_action); bool mch_decoded = true; if (!decode_pmch(&dl_action, &mbsfn_cfg)) { mch_decoded = false; } - phy->stack->mch_decoded((uint32_t)pmch_cfg.pdsch_cfg.grant.tb[0].tbs / 8, mch_decoded); + phy->stack->mch_decoded((uint32_t)pmch_cfg.pdsch_cfg.grant.tb[0].tbs / 8, mch_decoded, mch_payload_buffer); } else if (mbsfn_cfg.is_mcch) { // release lock in phy_common phy->set_mch_period_stop(0); @@ -929,5 +931,14 @@ int cc_worker::read_pdsch_d(cf_t* pdsch_d) return ue_dl_cfg.cfg.pdsch.grant.nof_re; } +void cc_worker::new_mch_dl(mac_interface_phy_lte::tb_action_dl_t* action) +{ + action->generate_ack = false; + action->tb[0].enabled = true; + action->tb[0].payload = mch_payload_buffer; + action->tb[0].softbuffer.rx = &mch_softbuffer; + srsran_softbuffer_rx_reset_cb(&mch_softbuffer, 1); +} + } // namespace lte } // namespace srsue diff --git a/srsue/src/phy/test/ue_phy_test.cc b/srsue/src/phy/test/ue_phy_test.cc index 970d7c4dc..c94aff79f 100644 --- a/srsue/src/phy/test/ue_phy_test.cc +++ b/srsue/src/phy/test/ue_phy_test.cc @@ -111,8 +111,7 @@ private: } void tb_decoded(uint32_t cc_idx, mac_grant_dl_t grant, bool* ack) override {} void bch_decoded_ok(uint32_t cc_idx, uint8_t* payload, uint32_t len) override {} - void mch_decoded(uint32_t len, bool crc) override {} - void new_mch_dl(const srsran_pdsch_grant_t& phy_grant, tb_action_dl_t* action) override {} + void mch_decoded(uint32_t len, bool crc, uint8_t* payload) override {} void set_mbsfn_config(uint32_t nof_mbsfn_services) override {} void run_tti(const uint32_t tti, const uint32_t tti_jump) override { diff --git a/srsue/src/stack/mac/mac.cc b/srsue/src/stack/mac/mac.cc index 5555ab814..5b44fe3e9 100644 --- a/srsue/src/stack/mac/mac.cc +++ b/srsue/src/stack/mac/mac.cc @@ -50,7 +50,6 @@ mac::mac(const char* logname, ext_task_sched_handle task_sched_) : dl_harq.at(PCELL_CC_IDX) = dl_harq_entity_ptr(new dl_harq_entity(PCELL_CC_IDX)); srsran_softbuffer_rx_init(&pch_softbuffer, 100); - srsran_softbuffer_rx_init(&mch_softbuffer, 100); // Keep initialising members bzero(&metrics, sizeof(mac_metrics_t)); @@ -62,7 +61,6 @@ mac::~mac() stop(); srsran_softbuffer_rx_free(&pch_softbuffer); - srsran_softbuffer_rx_free(&mch_softbuffer); } bool mac::init(phy_interface_mac_lte* phy, rlc_interface_mac* rlc, rrc_interface_mac* rrc) @@ -333,12 +331,12 @@ void mac::bch_decoded_ok(uint32_t cc_idx, uint8_t* payload, uint32_t len) } } -void mac::mch_decoded(uint32_t len, bool crc) +void mac::mch_decoded(uint32_t len, bool crc, uint8_t* payload) { // Parse MAC header if (crc) { mch_msg.init_rx(len); - mch_msg.parse_packet(mch_payload_buffer); + mch_msg.parse_packet(payload); while (mch_msg.next()) { for (uint32_t i = 0; i < phy_mbsfn_cfg.nof_mbsfn_services; i++) { if (srsran::mch_lcid::MCH_SCHED_INFO == mch_msg.get()->mch_ce_type()) { @@ -352,11 +350,11 @@ void mac::mch_decoded(uint32_t len, bool crc) } } - demux_unit.push_pdu_mch(mch_payload_buffer, len); + demux_unit.push_pdu_mch(payload, len); process_pdus(); if (pcap) { - pcap->write_dl_mch(mch_payload_buffer, len, true, phy_h->get_current_tti(), 0); + pcap->write_dl_mch(payload, len, true, phy_h->get_current_tti(), 0); } std::lock_guard lock(metrics_mutex); @@ -530,14 +528,6 @@ void mac::new_grant_ul(uint32_t cc_idx, } // end of holding metrics mutex } -void mac::new_mch_dl(const srsran_pdsch_grant_t& phy_grant, tb_action_dl_t* action) -{ - action->generate_ack = false; - action->tb[0].enabled = true; - action->tb[0].payload = mch_payload_buffer; - action->tb[0].softbuffer.rx = &mch_softbuffer; - srsran_softbuffer_rx_reset_cb(&mch_softbuffer, 1); -} void mac::setup_timers(int time_alignment_timer) {