fix undelivered PDCP SNs buffers in RLC AM to handle SN=-1 case

master
Francisco 4 years ago committed by Francisco Paisana
parent bad2302e31
commit 2a65bf9636

@ -123,33 +123,39 @@ private:
struct buffered_pdcp_pdu_list { struct buffered_pdcp_pdu_list {
public: public:
const static size_t max_pdcp_sn = 262144; explicit buffered_pdcp_pdu_list();
void resize(size_t size);
void clear(); void clear();
void add_pdcp_sdu(uint32_t sn) void add_pdcp_sdu(uint32_t sn)
{ {
assert(not has_pdcp_sn(sn)); assert(not has_pdcp_sn(sn));
buffered_pdus[sn].sn = sn; uint32_t sn_idx = get_idx(sn);
buffered_pdus[sn_idx].sn = sn_idx;
count++; count++;
} }
void clear_pdcp_sdu(uint32_t sn) void clear_pdcp_sdu(uint32_t sn)
{ {
buffered_pdus[sn].rlc_sn_info_list.clear(); uint32_t sn_idx = get_idx(sn);
buffered_pdus[sn].sn = -1; buffered_pdus[sn_idx].rlc_sn_info_list.clear();
buffered_pdus[sn_idx].sn = -1;
count--; count--;
} }
pdcp_sdu_info_t& operator[](size_t sn) pdcp_sdu_info_t& operator[](uint32_t sn)
{ {
assert(has_pdcp_sn(sn)); assert(has_pdcp_sn(sn));
return buffered_pdus[sn]; uint32_t sn_idx = get_idx(sn);
return buffered_pdus[sn_idx];
} }
bool has_pdcp_sn(uint32_t pdcp_sn) const { return buffered_pdus[pdcp_sn].sn < max_pdcp_sn; } bool has_pdcp_sn(uint32_t pdcp_sn) const { return buffered_pdus[get_idx(pdcp_sn)].sn < max_pdcp_sn; }
uint32_t nof_sdus() const { return count; } uint32_t nof_sdus() const { return count; }
private: private:
// TODO: Set size based on PDCP config
const static size_t max_pdcp_sn = 262143;
uint32_t get_idx(uint32_t sn) const { return std::min(sn, static_cast<uint32_t>(buffered_pdus.size() - 1)); }
std::vector<pdcp_sdu_info_t> buffered_pdus; std::vector<pdcp_sdu_info_t> buffered_pdus;
uint32_t count = 0; uint32_t count = 0;
}; };

@ -189,9 +189,6 @@ bool rlc_am_lte::rlc_am_lte_tx::configure(const rlc_config_t& cfg_)
// TODO: add config checks // TODO: add config checks
cfg = cfg_.am; cfg = cfg_.am;
// TODO: Set size based on PDCP config
undelivered_sdu_info_queue.resize(buffered_pdcp_pdu_list::max_pdcp_sn);
// check timers // check timers
if (not poll_retx_timer.is_valid() or not status_prohibit_timer.is_valid()) { if (not poll_retx_timer.is_valid() or not status_prohibit_timer.is_valid()) {
logger.error("Configuring RLC AM TX: timers not configured"); logger.error("Configuring RLC AM TX: timers not configured");
@ -1093,11 +1090,10 @@ void rlc_am_lte::rlc_am_lte_tx::handle_control_pdu(uint8_t* payload, uint32_t no
// Remove all SDUs that were fully acked // Remove all SDUs that were fully acked
for (uint32_t acked_pdcp_sn : notify_info_vec) { for (uint32_t acked_pdcp_sn : notify_info_vec) {
logger.debug("Erasing SDU info: PDCP_SN=%d", acked_pdcp_sn); logger.debug("Erasing SDU info: PDCP_SN=%d", acked_pdcp_sn);
if (undelivered_sdu_info_queue.has_pdcp_sn(acked_pdcp_sn)) { if (not undelivered_sdu_info_queue.has_pdcp_sn(acked_pdcp_sn)) {
undelivered_sdu_info_queue.clear_pdcp_sdu(acked_pdcp_sn);
} else {
logger.error("Could not find info to erase: SN=%d", acked_pdcp_sn); logger.error("Could not find info to erase: SN=%d", acked_pdcp_sn);
} }
undelivered_sdu_info_queue.clear_pdcp_sdu(acked_pdcp_sn);
} }
} }
@ -2017,11 +2013,9 @@ void rlc_am_lte::rlc_am_lte_rx::debug_state()
logger.debug("%s vr_r = %d, vr_mr = %d, vr_x = %d, vr_ms = %d, vr_h = %d", RB_NAME, vr_r, vr_mr, vr_x, vr_ms, vr_h); logger.debug("%s vr_r = %d, vr_mr = %d, vr_x = %d, vr_ms = %d, vr_h = %d", RB_NAME, vr_r, vr_mr, vr_x, vr_ms, vr_h);
} }
void buffered_pdcp_pdu_list::resize(size_t size) buffered_pdcp_pdu_list::buffered_pdcp_pdu_list() : buffered_pdus(max_pdcp_sn + 2)
{ {
size_t old_size = buffered_pdus.size(); for (size_t i = 0; i < buffered_pdus.size(); ++i) {
buffered_pdus.resize(size);
for (size_t i = old_size; i < buffered_pdus.size(); ++i) {
buffered_pdus[i].sn = -1; buffered_pdus[i].sn = -1;
buffered_pdus[i].rlc_sn_info_list.reserve(5); buffered_pdus[i].rlc_sn_info_list.reserve(5);
} }

Loading…
Cancel
Save