From 515f2099be476c6793c273c689656bbb09ca3eea Mon Sep 17 00:00:00 2001 From: Pedro Alvarez Date: Mon, 14 Mar 2022 17:50:20 +0000 Subject: [PATCH] lib,rlc_am_nr: added SN to get pdu poll function. Setting POLL_SN now. --- lib/include/srsran/rlc/rlc_am_nr.h | 2 +- lib/src/rlc/rlc_am_nr.cc | 34 ++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/include/srsran/rlc/rlc_am_nr.h b/lib/include/srsran/rlc/rlc_am_nr.h index d64aabc27..7e5d97873 100644 --- a/lib/include/srsran/rlc/rlc_am_nr.h +++ b/lib/include/srsran/rlc/rlc_am_nr.h @@ -124,7 +124,7 @@ public: uint32_t build_status_pdu(byte_buffer_t* payload, uint32_t nof_bytes); // Polling - uint8_t get_pdu_poll(bool is_retx, uint32_t sdu_bytes); + uint8_t get_pdu_poll(uint32_t sn, bool is_retx, uint32_t sdu_bytes); // Timers void timer_expired(uint32_t timeout_id); diff --git a/lib/src/rlc/rlc_am_nr.cc b/lib/src/rlc/rlc_am_nr.cc index ebee6b6be..41ea9ad5d 100644 --- a/lib/src/rlc/rlc_am_nr.cc +++ b/lib/src/rlc/rlc_am_nr.cc @@ -214,7 +214,7 @@ uint32_t rlc_am_nr_tx::build_new_pdu(uint8_t* payload, uint32_t nof_bytes) // Prepare header rlc_am_nr_pdu_header_t hdr = {}; hdr.dc = RLC_DC_FIELD_DATA_PDU; - hdr.p = get_pdu_poll(false, tx_sdu->N_bytes); + hdr.p = get_pdu_poll(st.tx_next, false, tx_sdu->N_bytes); hdr.si = rlc_nr_si_field_t::full_sdu; hdr.sn_size = cfg.tx_sn_field_length; hdr.sn = st.tx_next; @@ -273,7 +273,7 @@ uint32_t rlc_am_nr_tx::build_new_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, uint8_t* // Prepare header rlc_am_nr_pdu_header_t hdr = {}; hdr.dc = RLC_DC_FIELD_DATA_PDU; - hdr.p = get_pdu_poll(false, segment_payload_len); + hdr.p = get_pdu_poll(st.tx_next, false, segment_payload_len); hdr.si = rlc_nr_si_field_t::first_segment; hdr.sn_size = cfg.tx_sn_field_length; hdr.sn = st.tx_next; @@ -374,7 +374,7 @@ uint32_t rlc_am_nr_tx::build_continuation_sdu_segment(rlc_amd_tx_pdu_nr& tx_pdu, // Prepare header rlc_am_nr_pdu_header_t hdr = {}; hdr.dc = RLC_DC_FIELD_DATA_PDU; - hdr.p = get_pdu_poll(false, segment_payload_len); + hdr.p = get_pdu_poll(st.tx_next, false, segment_payload_len); hdr.si = si; hdr.sn_size = cfg.tx_sn_field_length; hdr.sn = st.tx_next; @@ -542,7 +542,7 @@ rlc_am_nr_tx::build_retx_pdu_without_segmentation(const rlc_amd_retx_nr_t retx, rlc_am_nr_pdu_header_t new_header = tx_pdu.header; new_header.si = si; new_header.so = retx.current_so; - new_header.p = get_pdu_poll(true, 0); + new_header.p = get_pdu_poll(retx.sn, true, 0); uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(new_header, payload); // Write SDU/SDU segment to payload @@ -624,7 +624,7 @@ uint32_t rlc_am_nr_tx::build_retx_pdu_with_segmentation(rlc_amd_retx_nr_t& retx, // Write header rlc_am_nr_pdu_header_t hdr = tx_pdu.header; - hdr.p = get_pdu_poll(true, 0); + hdr.p = get_pdu_poll(retx.sn, true, 0); hdr.so = retx.current_so; hdr.si = si; uint32_t hdr_len = rlc_am_nr_write_data_pdu_header(hdr, payload); @@ -1051,7 +1051,7 @@ void rlc_am_nr_tx::get_buffer_state(uint32_t& n_bytes_new, uint32_t& n_bytes_pri * 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, uint32_t sdu_bytes) +uint8_t rlc_am_nr_tx::get_pdu_poll(uint32_t sn, bool is_retx, uint32_t sdu_bytes) { /* For each AMD PDU or AMD PDU segment that has not been previoulsy tranmitted: * - increment PDU_WITHOUT_POLL by one; @@ -1093,6 +1093,18 @@ uint8_t rlc_am_nr_tx::get_pdu_poll(bool is_retx, uint32_t sdu_bytes) if (poll == 1) { st.pdu_without_poll = 0; st.byte_without_poll = 0; + /* + * - set POLL_SN to the highest SN of the AMD PDU among the AMD PDUs submitted to lower layer; + * - if t-PollRetransmit is not running: + * - start t-PollRetransmit. + * - else: + * - restart t-PollRetransmit. + */ + if (sn > st.poll_sn) { + st.poll_sn = sn; + poll_retransmit_timer.stop(); + poll_retransmit_timer.run(); + } } return poll; } @@ -1143,21 +1155,21 @@ void rlc_am_nr_tx::timer_expired(uint32_t timeout_id) * - consider any RLC SDU which has not been positively acknowledged for retransmission. * - include a poll in an AMD PDU as described in section 5.3.3.2. */ - if ((tx_sdu_queue.is_empty() && retx_queue.empty()) || tx_window.full()) { - if (tx_window.empty()) { + if ((tx_sdu_queue.is_empty() && retx_queue->empty()) || tx_window->full()) { + if (tx_window->empty()) { // Nothing to RETX return; } // Fully RETX first RLC SDU that has not been acked - if (tx_window.has_sn(st.tx_next_ack)) { + if (tx_window->has_sn(st.tx_next_ack)) { RlcError("TX window not empty, but TX_NEXT_ACK not in TX_WINDOW"); return; } - rlc_amd_retx_nr_t& retx = retx_queue.push(); + rlc_amd_retx_nr_t& retx = retx_queue->push(); retx.sn = st.tx_next_ack; retx.is_segment = false; retx.so_start = 0; - retx.segment_length = tx_window[st.tx_next_ack].sdu_buf->N_bytes; + retx.segment_length = (*tx_window)[st.tx_next_ack].sdu_buf->N_bytes; retx.current_so = 0; } return;