lib,rlc_am_nr: Passing bool to get_pdu_poll() to differentiate the

behaviour between RETX and non-RETX PDUs.
This commit is contained in:
Pedro Alvarez 2022-03-08 17:55:03 +00:00
parent b52a102021
commit eaa8fff6a0
2 changed files with 35 additions and 19 deletions

View File

@ -122,7 +122,7 @@ public:
uint32_t build_status_pdu(byte_buffer_t* payload, uint32_t nof_bytes); uint32_t build_status_pdu(byte_buffer_t* payload, uint32_t nof_bytes);
// Polling // Polling
uint8_t get_pdu_poll(); uint8_t get_pdu_poll(bool is_retx);
void stop() final; void stop() final;
@ -146,13 +146,13 @@ private:
* Tx state variables * Tx state variables
* Ref: 3GPP TS 38.322 version 16.2.0 Section 7.1 * Ref: 3GPP TS 38.322 version 16.2.0 Section 7.1
***************************************************************************/ ***************************************************************************/
struct rlc_am_nr_tx_state_t st = {}; struct rlc_am_nr_tx_state_t st = {};
std::unique_ptr<rlc_ringbuffer_base<rlc_amd_tx_pdu_nr> > tx_window; std::unique_ptr<rlc_ringbuffer_base<rlc_amd_tx_pdu_nr> > tx_window;
// Queues, buffers and container // Queues, buffers and container
std::unique_ptr<pdu_retx_queue_base<rlc_amd_retx_nr_t> > retx_queue; std::unique_ptr<pdu_retx_queue_base<rlc_amd_retx_nr_t> > retx_queue;
uint32_t sdu_under_segmentation_sn = INVALID_RLC_SN; // SN of the SDU currently being segmented. uint32_t sdu_under_segmentation_sn = INVALID_RLC_SN; // SN of the SDU currently being segmented.
pdcp_sn_vector_t notify_info_vec; pdcp_sn_vector_t notify_info_vec;
rlc_am_nr_status_pdu_t tx_status; rlc_am_nr_status_pdu_t tx_status;
// Helper constants // Helper constants
@ -168,8 +168,8 @@ private:
public: public:
// Getters/Setters // Getters/Setters
void set_tx_state(const rlc_am_nr_tx_state_t& st_) { st = st_; } // This should only be used for testing. void set_tx_state(const rlc_am_nr_tx_state_t& st_) { st = st_; } // This should only be used for testing.
rlc_am_nr_tx_state_t get_tx_state() { return st; } // This should only be used for testing. rlc_am_nr_tx_state_t get_tx_state() { return st; } // This should only be used for testing.
uint32_t get_tx_window_size() { return tx_window->size(); } // This should only be used for testing. uint32_t get_tx_window_size() { return tx_window->size(); } // This should only be used for testing.
// Debug Helper // Debug Helper
@ -283,8 +283,8 @@ private:
public: public:
// Getters/Setters // Getters/Setters
void set_rx_state(const rlc_am_nr_rx_state_t& st_) { st = st_; } // This should only be used for testing. void set_rx_state(const rlc_am_nr_rx_state_t& st_) { st = st_; } // This should only be used for testing.
rlc_am_nr_rx_state_t get_rx_state() { return st; } // This should only be used for testing. rlc_am_nr_rx_state_t get_rx_state() { return st; } // This should only be used for testing.
uint32_t get_rx_window_size() { return rx_window->size(); } // This should only be used for testing. uint32_t get_rx_window_size() { return rx_window->size(); } // This should only be used for testing.
}; };

View File

@ -195,7 +195,7 @@ uint32_t rlc_am_nr_tx::build_new_pdu(uint8_t* payload, uint32_t nof_bytes)
// Prepare header // Prepare header
rlc_am_nr_pdu_header_t hdr = {}; rlc_am_nr_pdu_header_t hdr = {};
hdr.dc = RLC_DC_FIELD_DATA_PDU; hdr.dc = RLC_DC_FIELD_DATA_PDU;
hdr.p = get_pdu_poll(); hdr.p = get_pdu_poll(false);
hdr.si = rlc_nr_si_field_t::full_sdu; hdr.si = rlc_nr_si_field_t::full_sdu;
hdr.sn_size = cfg.tx_sn_field_length; hdr.sn_size = cfg.tx_sn_field_length;
hdr.sn = st.tx_next; hdr.sn = st.tx_next;
@ -252,7 +252,7 @@ uint32_t rlc_am_nr_tx::build_new_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint8_t*
// Prepare header // Prepare header
rlc_am_nr_pdu_header_t hdr = {}; rlc_am_nr_pdu_header_t hdr = {};
hdr.dc = RLC_DC_FIELD_DATA_PDU; hdr.dc = RLC_DC_FIELD_DATA_PDU;
hdr.p = get_pdu_poll(); hdr.p = get_pdu_poll(false);
hdr.si = rlc_nr_si_field_t::first_segment; hdr.si = rlc_nr_si_field_t::first_segment;
hdr.sn_size = cfg.tx_sn_field_length; hdr.sn_size = cfg.tx_sn_field_length;
hdr.sn = st.tx_next; hdr.sn = st.tx_next;
@ -354,7 +354,7 @@ uint32_t rlc_am_nr_tx::build_continuation_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu,
// Prepare header // Prepare header
rlc_am_nr_pdu_header_t hdr = {}; rlc_am_nr_pdu_header_t hdr = {};
hdr.dc = RLC_DC_FIELD_DATA_PDU; hdr.dc = RLC_DC_FIELD_DATA_PDU;
hdr.p = get_pdu_poll(); hdr.p = get_pdu_poll(false);
hdr.si = si; hdr.si = si;
hdr.sn_size = cfg.tx_sn_field_length; hdr.sn_size = cfg.tx_sn_field_length;
hdr.sn = st.tx_next; hdr.sn = st.tx_next;
@ -505,7 +505,7 @@ rlc_am_nr_tx::build_retx_pdu_without_segmentation(rlc_amd_retx_nr_t& retx, uint8
current_so = retx.current_so; current_so = retx.current_so;
} }
rlc_am_nr_pdu_header_t new_header = tx_pdu.header; rlc_am_nr_pdu_header_t new_header = tx_pdu.header;
new_header.p = 0; new_header.p = get_pdu_poll(true);
new_header.si = si; new_header.si = si;
new_header.so = current_so; new_header.so = current_so;
uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(new_header, payload); uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(new_header, payload);
@ -598,6 +598,7 @@ uint32_t rlc_am_nr_tx::build_retx_pdu_with_segmentation(rlc_amd_retx_nr_t& retx,
// Write header // Write header
rlc_am_nr_pdu_header_t hdr = tx_pdu.header; rlc_am_nr_pdu_header_t hdr = tx_pdu.header;
hdr.p = get_pdu_poll(true);
hdr.so = retx.current_so; hdr.so = retx.current_so;
hdr.si = si; hdr.si = si;
uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(hdr, payload); uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(hdr, payload);
@ -900,17 +901,32 @@ void rlc_am_nr_tx::get_buffer_state(uint32_t& n_bytes_new, uint32_t& n_bytes_pri
} }
} }
uint8_t rlc_am_nr_tx::get_pdu_poll() /*
* Check whether the polling bit needs to be set, as specified in
* TS 38.322, section 5.3.3.2
*/
uint8_t rlc_am_nr_tx::get_pdu_poll(bool is_retx)
{ {
uint8_t poll = 0; uint8_t poll = 0;
if (cfg.poll_pdu > 0) { if (!is_retx) {
if (st.pdu_without_poll >= (uint32_t)cfg.poll_pdu) { if (cfg.poll_pdu > 0) {
poll = 1; if (st.pdu_without_poll >= (uint32_t)cfg.poll_pdu) {
st.pdu_without_poll = 0; poll = 1;
} else { st.pdu_without_poll = 0;
st.pdu_without_poll++; } else {
st.pdu_without_poll++;
}
} }
} }
/*
* - if both the transmission buffer and the retransmission buffer becomes empty (excluding transmitted RLC SDUs
or RLC SDU segments awaiting acknowledgements) after the transmission of the AMD PDU; or
* - if no new RLC SDU can be transmitted after the transmission of the AMD PDU (e.g. due to window stalling);
* - include a poll in the AMD PDU as described below.
*/
if (tx_sdu_queue.is_empty() && retx_queue->empty()) {
poll = 1;
}
return poll; return poll;
} }