diff --git a/srsue/hdr/stack/mac/proc_bsr.h b/srsue/hdr/stack/mac/proc_bsr.h index f64c65ea8..d7624be60 100644 --- a/srsue/hdr/stack/mac/proc_bsr.h +++ b/srsue/hdr/stack/mac/proc_bsr.h @@ -50,6 +50,9 @@ public: /* MUX calls BSR to let it generate a padding BSR if there is space in PDU */ virtual bool generate_padding_bsr(uint32_t nof_padding_bytes, bsr_t* bsr) = 0; + + /* MUX calls BSR to update buffer state of each LCG after all PDUs for this TTI have been packed */ + virtual void update_bsr_tti_end(const bsr_t* bsr) = 0; }; class bsr_proc : public srslte::timer_callback, public bsr_interface_mux @@ -67,6 +70,7 @@ public: uint32_t get_buffer_state(); bool need_to_send_bsr_on_ul_grant(uint32_t grant_size, uint32_t total_data, bsr_t* bsr); bool generate_padding_bsr(uint32_t nof_padding_bytes, bsr_t* bsr); + void update_bsr_tti_end(const bsr_t* bsr); private: const static int QUEUE_STATUS_PERIOD_MS = 1000; @@ -99,7 +103,7 @@ private: void print_state(); void set_trigger(triggered_bsr_type_t new_trigger); void update_new_data(); - void update_buffer_state(); + void update_old_buffer(); bool check_highest_channel(); bool check_new_data(); bool check_any_channel(); diff --git a/srsue/src/stack/mac/mux.cc b/srsue/src/stack/mac/mux.cc index 30fe7c9bd..cb75b3617 100644 --- a/srsue/src/stack/mac/mux.cc +++ b/srsue/src/stack/mac/mux.cc @@ -293,6 +293,9 @@ uint8_t* mux::pdu_get(srslte::byte_buffer_t* payload, uint32_t pdu_sz) } } + // Update buffers in BSR procedure after packing entire TTI + bsr_procedure->update_bsr_tti_end(&bsr); + // Generate MAC PDU and save to buffer uint8_t* ret = pdu_msg.write_packet(log_h); Info("%s\n", pdu_msg.to_string().c_str()); diff --git a/srsue/src/stack/mac/proc_bsr.cc b/srsue/src/stack/mac/proc_bsr.cc index 99dadfe68..b15f2a6d1 100644 --- a/srsue/src/stack/mac/proc_bsr.cc +++ b/srsue/src/stack/mac/proc_bsr.cc @@ -198,7 +198,7 @@ void bsr_proc::update_new_data() } } -void bsr_proc::update_buffer_state() +void bsr_proc::update_old_buffer() { for (int i = 0; i < NOF_LCG; i++) { for (std::map::iterator iter = lcgs[i].begin(); iter != lcgs[i].end(); ++iter) { @@ -269,6 +269,24 @@ bool bsr_proc::generate_bsr(bsr_t* bsr, uint32_t pdu_space) return send_bsr; } +/* After packing all UL PDUs for this TTI, the internal buffer state of the BSR procedure needs to be updated with what + * has actually been transmitted in each LCG. We don't ask RLC again as new SDUs could have queued up again. Currently + * we just get the updates per LCG. Since we are only interested when zero outstanding data has been reported, we + * currently just reset the buffer for each LCID of the LCG. + */ +void bsr_proc::update_bsr_tti_end(const bsr_t* bsr) +{ + std::lock_guard lock(mutex); + for (uint32_t i = 0; i < NOF_LCG; i++) { + if (bsr->buff_size[i] == 0) { + for (std::map::iterator iter = lcgs[i].begin(); iter != lcgs[i].end(); ++iter) { + // Reset buffer state for all LCIDs of that the LCG for which we reported no further data to transmit + iter->second.old_buffer = 0; + } + } + } +} + // Checks if Regular BSR must be assembled, as defined in 5.4.5 // Padding BSR is assembled when called by mux_unit when UL dci is received // Periodic BSR is triggered by the expiration of the timers @@ -288,7 +306,7 @@ void bsr_proc::step(uint32_t tti) set_trigger(REGULAR); } - update_buffer_state(); + update_old_buffer(); } char* bsr_proc::bsr_type_tostring(triggered_bsr_type_t type)