diff --git a/lib/include/srslte/interfaces/enb_interfaces.h b/lib/include/srslte/interfaces/enb_interfaces.h index 84d96cf01..1b614713b 100644 --- a/lib/include/srslte/interfaces/enb_interfaces.h +++ b/lib/include/srslte/interfaces/enb_interfaces.h @@ -160,6 +160,9 @@ public: /** * Informs MAC about a received PUSCH transmission for given RNTI, TTI and eNb Cell/carrier. * + * This function does not deallocate the uplink buffer. The function push_pdu() must be called after this + * to inform the MAC that the uplink buffer can be discarded or pushed to the stack + * * @param tti the given TTI * @param rnti the UE identifier in the eNb * @param cc_idx the eNb Cell/Carrier identifier @@ -169,6 +172,18 @@ public: */ virtual int crc_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t nof_bytes, bool crc_res) = 0; + /** + * Pushes an uplink PDU through the stack if crc_res==true or discards it if crc_res==false + * + * @param tti the given TTI + * @param rnti the UE identifier in the eNb + * @param pdu_ptr pointer to the uplink buffer + * @param nof_bytes the number of grants carrierd by the PUSCH message + * @param crc_res the CRC check, set to true if the message was decoded succesfully + * @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs + */ + virtual int push_pdu(uint32_t tti_rx, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) = 0; + virtual int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) = 0; virtual int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) = 0; virtual int get_ul_sched(uint32_t tti, ul_sched_list_t& ul_sched_res) = 0; diff --git a/lib/include/srslte/mac/pdu_queue.h b/lib/include/srslte/mac/pdu_queue.h index 89c9bfa39..0bf94f9ae 100644 --- a/lib/include/srslte/mac/pdu_queue.h +++ b/lib/include/srslte/mac/pdu_queue.h @@ -37,8 +37,8 @@ public: void init(process_callback* callback, log_ref log_h_); uint8_t* request(uint32_t len); - void deallocate(uint8_t* pdu); - void push(uint8_t* ptr, uint32_t len, channel_t channel = DCH); + void deallocate(const uint8_t* pdu); + void push(const uint8_t* ptr, uint32_t len, channel_t channel = DCH); bool process_pdus(); diff --git a/lib/src/mac/pdu_queue.cc b/lib/src/mac/pdu_queue.cc index 6d90ceed7..bd8628b0e 100644 --- a/lib/src/mac/pdu_queue.cc +++ b/lib/src/mac/pdu_queue.cc @@ -42,7 +42,7 @@ uint8_t* pdu_queue::request(uint32_t len) return pdu->ptr; } -void pdu_queue::deallocate(uint8_t* pdu) +void pdu_queue::deallocate(const uint8_t* pdu) { if (!pool.deallocate((pdu_t*)pdu)) { log_h->warning("Error deallocating from buffer pool in deallocate(): buffer not created in this pool.\n"); @@ -53,7 +53,7 @@ void pdu_queue::deallocate(uint8_t* pdu) * This function enqueues the packet and returns quicly because ACK * deadline is important here. */ -void pdu_queue::push(uint8_t* ptr, uint32_t len, channel_t channel) +void pdu_queue::push(const uint8_t* ptr, uint32_t len, channel_t channel) { if (ptr) { pdu_t* pdu = (pdu_t*)ptr; diff --git a/srsenb/hdr/stack/enb_stack_lte.h b/srsenb/hdr/stack/enb_stack_lte.h index 719b835b7..cd0c88cf6 100644 --- a/srsenb/hdr/stack/enb_stack_lte.h +++ b/srsenb/hdr/stack/enb_stack_lte.h @@ -81,6 +81,10 @@ public: { return mac.crc_info(tti, rnti, enb_cc_idx, nof_bytes, crc_res); } + int push_pdu(uint32_t tti, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) final + { + return mac.push_pdu(tti, rnti, pdu_ptr, nof_bytes, crc_res); + } int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) final { return mac.get_dl_sched(tti, dl_sched_res); } int get_mch_sched(uint32_t tti, bool is_mcch, dl_sched_list_t& dl_sched_res) final { diff --git a/srsenb/hdr/stack/mac/mac.h b/srsenb/hdr/stack/mac/mac.h index e3e4beaf1..06b4b4619 100644 --- a/srsenb/hdr/stack/mac/mac.h +++ b/srsenb/hdr/stack/mac/mac.h @@ -56,6 +56,7 @@ public: int ta_info(uint32_t tti, uint16_t rnti, float ta_us) override; int ack_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t tb_idx, bool ack) override; int crc_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t nof_bytes, bool crc_res) override; + int push_pdu(uint32_t tti, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) override; int get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res) override; int get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res) override; diff --git a/srsenb/hdr/stack/mac/ue.h b/srsenb/hdr/stack/mac/ue.h index 7127c088b..f8e9b7b9f 100644 --- a/srsenb/hdr/stack/mac/ue.h +++ b/srsenb/hdr/stack/mac/ue.h @@ -71,10 +71,10 @@ public: srslte_softbuffer_rx_t* get_rx_softbuffer(const uint32_t ue_cc_idx, const uint32_t tti); bool process_pdus(); - uint8_t* request_buffer(const uint32_t ue_cc_idx, const uint32_t tti, const uint32_t len); + uint8_t* request_buffer(const uint32_t len); void process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channel_t channel) override; - void push_pdu(const uint32_t ue_cc_idx, const uint32_t tti, uint32_t len); - void deallocate_pdu(const uint32_t ue_cc_idx, const uint32_t tti); + void push_pdu(const uint8_t* pdu_ptr, uint32_t len); + void deallocate_pdu(const uint8_t* pdu_ptr); void metrics_read(mac_ue_metrics_t* metrics_); void metrics_rx(bool crc, uint32_t tbs); @@ -118,9 +118,6 @@ private: cc_softbuffer_rx_list_t; ///< List of Rx softbuffers for all HARQ processes of one carrier std::vector softbuffer_rx; ///< List of softbuffer lists for Rx - typedef std::vector cc_buffer_ptr_t; ///< List of buffer pointers for RX HARQ processes of one carrier - std::vector pending_buffers; ///< List of buffer pointer list for Rx - // One buffer per TB per HARQ process and per carrier is needed for each UE. std::vector, SRSLTE_FDD_NOF_HARQ> > tx_payload_buffer; diff --git a/srsenb/src/phy/lte/cc_worker.cc b/srsenb/src/phy/lte/cc_worker.cc index b72197248..0c568d39b 100644 --- a/srsenb/src/phy/lte/cc_worker.cc +++ b/srsenb/src/phy/lte/cc_worker.cc @@ -373,7 +373,8 @@ void cc_worker::decode_pusch(stack_interface_phy_lte::ul_sched_grant_t* grants, if (ul_grant.data != nullptr) { // Inform MAC about the CRC result phy->stack->crc_info(tti_rx, rnti, cc_idx, ul_cfg.pusch.grant.tb.tbs / 8, pusch_res.crc); - + // Push PDU buffer + phy->stack->push_pdu(tti_rx, rnti, grants[i].data, ul_cfg.pusch.grant.tb.tbs / 8, pusch_res.crc); // Logging if (log_h->get_level() >= srslte::LOG_LEVEL_INFO) { char str[512]; diff --git a/srsenb/src/stack/mac/mac.cc b/srsenb/src/stack/mac/mac.cc index 0d6d9fb98..d7ce68e09 100644 --- a/srsenb/src/stack/mac/mac.cc +++ b/srsenb/src/stack/mac/mac.cc @@ -320,24 +320,28 @@ int mac::crc_info(uint32_t tti_rx, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ue_db[rnti]->set_tti(tti_rx); ue_db[rnti]->metrics_rx(crc, nof_bytes); - std::array enb_ue_cc_map = scheduler.get_enb_ue_cc_map(rnti); - if (enb_ue_cc_map[enb_cc_idx] < 0) { - Error("User rnti=0x%x is not activated for carrier %d\n", rnti, enb_cc_idx); + // Scheduler uses eNB's CC mapping + return scheduler.ul_crc_info(tti_rx, rnti, enb_cc_idx, crc); +} + +int mac::push_pdu(uint32_t tti_rx, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc) +{ + srslte::rwlock_read_guard lock(rwlock); + + if (not check_ue_exists(rnti)) { return SRSLTE_ERROR; } - uint32_t ue_cc_idx = enb_ue_cc_map[enb_cc_idx]; // push the pdu through the queue if received correctly if (crc) { Info("Pushing PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes); - ue_db[rnti]->push_pdu(ue_cc_idx, tti_rx, nof_bytes); + ue_db[rnti]->push_pdu(pdu_ptr, nof_bytes); stack_task_queue.push([this]() { process_pdus(); }); } else { - ue_db[rnti]->deallocate_pdu(ue_cc_idx, tti_rx); + Debug("Discarting PDU rnti=0x%x, tti_rx=%d, nof_bytes=%d\n", rnti, tti_rx, nof_bytes); + ue_db[rnti]->deallocate_pdu(pdu_ptr); } - - // Scheduler uses eNB's CC mapping - return scheduler.ul_crc_info(tti_rx, rnti, enb_cc_idx, crc); + return SRSLTE_SUCCESS; } int mac::ri_info(uint32_t tti, uint16_t rnti, uint32_t enb_cc_idx, uint32_t ri_value) @@ -894,8 +898,7 @@ int mac::get_ul_sched(uint32_t tti_tx_ul, ul_sched_list_t& ul_sched_res_list) if (sched_result.pusch[n].current_tx_nb == 0) { srslte_softbuffer_rx_reset_tbs(phy_ul_sched_res->pusch[n].softbuffer_rx, sched_result.pusch[i].tbs * 8); } - phy_ul_sched_res->pusch[n].data = - ue_db[rnti]->request_buffer(sched_result.pusch[i].dci.ue_cc_idx, tti_tx_ul, sched_result.pusch[i].tbs); + phy_ul_sched_res->pusch[n].data = ue_db[rnti]->request_buffer(sched_result.pusch[i].tbs); phy_ul_sched_res->nof_grants++; n++; } else { diff --git a/srsenb/src/stack/mac/ue.cc b/srsenb/src/stack/mac/ue.cc index 44ae26200..d0e99c2a9 100644 --- a/srsenb/src/stack/mac/ue.cc +++ b/srsenb/src/stack/mac/ue.cc @@ -94,15 +94,6 @@ void ue::reset() srslte_softbuffer_tx_reset(&buffer); } } - - for (auto& cc_buffers : pending_buffers) { - for (auto& harq_buffer : cc_buffers) { - if (harq_buffer) { - pdus.deallocate(harq_buffer); - harq_buffer = nullptr; - } - } - } } /** @@ -123,12 +114,6 @@ uint32_t ue::allocate_cc_buffers(const uint32_t num_cc) srslte_softbuffer_rx_init(&buffer, nof_prb); } - pending_buffers.emplace_back(); - pending_buffers.back().resize(nof_rx_harq_proc); - for (auto& buffer : pending_buffers.back()) { - buffer = nullptr; - } - // Create and init Tx buffers for Pcell softbuffer_tx.emplace_back(); softbuffer_tx.back().resize(nof_tx_harq_proc); @@ -176,20 +161,14 @@ ue::get_tx_softbuffer(const uint32_t ue_cc_idx, const uint32_t harq_process, con return &softbuffer_tx.at(ue_cc_idx).at((harq_process * SRSLTE_MAX_TB + tb_idx) % nof_tx_harq_proc); } -uint8_t* ue::request_buffer(const uint32_t ue_cc_idx, const uint32_t tti, const uint32_t len) +uint8_t* ue::request_buffer(const uint32_t len) { - uint8_t* ret = nullptr; if (len > 0) { - if (!pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc)) { - ret = pdus.request(len); - pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc) = ret; - } else { - log_h->error("Requesting buffer for pid %d, not pushed yet\n", tti % nof_rx_harq_proc); - } + return pdus.request(len); } else { log_h->warning("Requesting buffer for zero bytes\n"); + return nullptr; } - return ret; } bool ue::process_pdus() @@ -314,25 +293,21 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe Debug("MAC PDU processed\n"); } -void ue::deallocate_pdu(const uint32_t ue_cc_idx, const uint32_t tti) +void ue::deallocate_pdu(const uint8_t* pdu_ptr) { - if (pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc)) { - pdus.deallocate(pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc)); - pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc) = nullptr; + if (pdu_ptr) { + pdus.deallocate(pdu_ptr); } else { - srslte::console( - "Error deallocating buffer for ue_cc_idx=%d, pid=%d. Not requested\n", ue_cc_idx, tti % nof_rx_harq_proc); + Error("Error deallocating PDU: null ptr\n"); } } -void ue::push_pdu(const uint32_t ue_cc_idx, const uint32_t tti, uint32_t len) +void ue::push_pdu(const uint8_t* pdu_ptr, uint32_t len) { - if (pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc)) { - pdus.push(pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc), len); - pending_buffers.at(ue_cc_idx).at(tti % nof_rx_harq_proc) = nullptr; + if (pdu_ptr && len > 0) { + pdus.push(pdu_ptr, len); } else { - srslte::console( - "Error pushing buffer for ue_cc_idx=%d, pid=%d. Not requested\n", ue_cc_idx, tti % nof_rx_harq_proc); + Error("Error pushing PDU: ptr=%p, len=%d\n", pdu_ptr, len); } } diff --git a/srsenb/test/phy/enb_phy_test.cc b/srsenb/test/phy/enb_phy_test.cc index 402102c9c..eee341fe8 100644 --- a/srsenb/test/phy/enb_phy_test.cc +++ b/srsenb/test/phy/enb_phy_test.cc @@ -289,6 +289,7 @@ private: CALLBACK(ta_info); CALLBACK(ack_info); CALLBACK(crc_info); + CALLBACK(push_pdu); CALLBACK(get_dl_sched); CALLBACK(get_mch_sched); CALLBACK(get_ul_sched); @@ -492,6 +493,13 @@ public: return 0; } + int push_pdu(uint32_t tti, uint16_t rnti, const uint8_t* pdu_ptr, uint32_t nof_bytes, bool crc_res) override + { + log_h.info("Received push_pdu tti=%d; rnti=0x%x; ack=%d;\n", tti, rnti, crc_res); + notify_push_pdu(); + + return 0; + } int get_dl_sched(uint32_t tti, dl_sched_list_t& dl_sched_res) override { // Notify test engine