mirror of https://github.com/PentHertz/srsLTE.git
Adding t_reassembly to RLC AM NR
This commit is contained in:
parent
f09020e57f
commit
3f000f0472
|
@ -98,7 +98,7 @@ struct rlc_am_nr_config_t {
|
|||
|
||||
// Timers Ref: 3GPP TS 38.322 Section 7.3
|
||||
int32_t t_poll_retx; // Poll retx timeout (ms)
|
||||
int32_t t_reassambly; // Timer used by rx to detect PDU loss (ms)
|
||||
int32_t t_reassembly; // Timer used by rx to detect PDU loss (ms)
|
||||
int32_t t_status_prohibit; // Timer used by rx to prohibit tx of status PDU (ms)
|
||||
|
||||
// Configurable Parameters. Ref: 3GPP TS 38.322 Section 7.4
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
void empty_queue() final;
|
||||
bool has_data() final;
|
||||
uint32_t get_buffer_state() final;
|
||||
void get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue);
|
||||
void get_buffer_state(uint32_t& tx_queue, uint32_t& prio_tx_queue) final;
|
||||
|
||||
bool do_status();
|
||||
uint32_t build_status_pdu(byte_buffer_t* payload, uint32_t nof_bytes);
|
||||
|
@ -103,9 +103,6 @@ public:
|
|||
void stop();
|
||||
void reestablish();
|
||||
|
||||
uint32_t get_sdu_rx_latency_ms();
|
||||
uint32_t get_rx_buffered_bytes();
|
||||
|
||||
// Status PDU
|
||||
bool get_do_status();
|
||||
uint32_t get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t len);
|
||||
|
@ -115,6 +112,10 @@ public:
|
|||
void handle_data_pdu_full(uint8_t* payload, uint32_t nof_bytes, rlc_am_nr_pdu_header_t& header);
|
||||
bool inside_rx_window(uint32_t sn);
|
||||
|
||||
// Metrics
|
||||
uint32_t get_sdu_rx_latency_ms() final;
|
||||
uint32_t get_rx_buffered_bytes() final;
|
||||
|
||||
// Timers
|
||||
void timer_expired(uint32_t timeout_id);
|
||||
|
||||
|
@ -132,18 +133,6 @@ private:
|
|||
// Mutexes
|
||||
std::mutex mutex;
|
||||
|
||||
/****************************************************************************
|
||||
* Rx timers
|
||||
* Ref: 3GPP TS 38.322 v10.0.0 Section 7.3
|
||||
***************************************************************************/
|
||||
srsran::timer_handler::unique_timer status_prohibit_timer;
|
||||
|
||||
/****************************************************************************
|
||||
* Configurable parameters
|
||||
* Ref: 3GPP TS 38.322 v10.0.0 Section 7.4
|
||||
***************************************************************************/
|
||||
rlc_am_nr_config_t cfg = {};
|
||||
|
||||
/****************************************************************************
|
||||
* State Variables
|
||||
* Ref: 3GPP TS 38.322 v10.0.0 Section 7.1
|
||||
|
@ -166,9 +155,22 @@ private:
|
|||
uint32_t rx_highest_status = 0;
|
||||
/*
|
||||
* RX_Next_Highest: This state variable holds the value of the SN following the SN of the RLC SDU with the
|
||||
* highest SN among received *RLC SDUs. It is initially set to 0.
|
||||
* highest SN among received RLC SDUs. It is initially set to 0.
|
||||
*/
|
||||
uint32_t rx_next_highest = 0;
|
||||
|
||||
/****************************************************************************
|
||||
* Rx timers
|
||||
* Ref: 3GPP TS 38.322 v10.0.0 Section 7.3
|
||||
***************************************************************************/
|
||||
srsran::timer_handler::unique_timer status_prohibit_timer;
|
||||
srsran::timer_handler::unique_timer reassembly_timer;
|
||||
|
||||
/****************************************************************************
|
||||
* Configurable parameters
|
||||
* Ref: 3GPP TS 38.322 v10.0.0 Section 7.4
|
||||
***************************************************************************/
|
||||
rlc_am_nr_config_t cfg = {};
|
||||
};
|
||||
|
||||
} // namespace srsran
|
||||
|
|
|
@ -50,6 +50,12 @@ struct rlc_amd_rx_pdu_nr {
|
|||
explicit rlc_amd_rx_pdu_nr(uint32_t rlc_sn_) : rlc_sn(rlc_sn_) {}
|
||||
};
|
||||
|
||||
struct rlc_amd_rx_sdu_t {
|
||||
uint32_t rlc_sn = 0;
|
||||
bool fully_received = false;
|
||||
std::list<rlc_amd_rx_pdu_nr> segments;
|
||||
};
|
||||
|
||||
///< AM NR Status PDU header (perhaps merge with LTE version)
|
||||
typedef struct {
|
||||
rlc_am_nr_control_pdu_type_t cpt;
|
||||
|
|
|
@ -241,12 +241,17 @@ bool rlc_am_nr_rx::configure(const rlc_config_t& cfg_)
|
|||
{
|
||||
cfg = cfg_.am_nr;
|
||||
|
||||
// configure timers
|
||||
// Configure status prohibit timer
|
||||
if (cfg.t_status_prohibit > 0) {
|
||||
status_prohibit_timer.set(static_cast<uint32_t>(cfg.t_status_prohibit),
|
||||
[this](uint32_t timerid) { timer_expired(timerid); });
|
||||
}
|
||||
|
||||
// Configure t_reassembly timer
|
||||
if (cfg.t_reassembly > 0) {
|
||||
reassembly_timer.set(static_cast<uint32_t>(cfg.t_reassembly), [this](uint32_t timerid) { timer_expired(timerid); });
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -405,11 +410,10 @@ uint32_t rlc_am_nr_rx::get_status_pdu(rlc_am_nr_status_pdu_t* status, uint32_t m
|
|||
}
|
||||
|
||||
status->N_nack = 0;
|
||||
status->ack_sn = rx_next; // start with lower edge of the rx window
|
||||
status->ack_sn = rx_highest_status; // ACK RX_Highest_Status
|
||||
byte_buffer_t tmp_buf;
|
||||
uint32_t len;
|
||||
|
||||
// We don't use segment NACKs - just NACK the full PDU
|
||||
uint32_t i = status->ack_sn;
|
||||
while (RX_MOD_BASE_NR(i) <= RX_MOD_BASE_NR(rx_highest_status)) {
|
||||
if (rx_window.has_sn(i) || i == rx_highest_status) {
|
||||
|
@ -445,8 +449,42 @@ bool rlc_am_nr_rx::get_do_status()
|
|||
void rlc_am_nr_rx::timer_expired(uint32_t timeout_id)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
|
||||
// Status Prohibit
|
||||
if (status_prohibit_timer.is_valid() && status_prohibit_timer.id() == timeout_id) {
|
||||
logger->debug("%s Status prohibit timer expired after %dms", parent->rb_name, status_prohibit_timer.duration());
|
||||
return;
|
||||
}
|
||||
|
||||
// Reassembly
|
||||
if (reassembly_timer.is_valid() && reassembly_timer.id() == timeout_id) {
|
||||
logger->debug("%s Reassembly timer expired after %dms", parent->rb_name, reassembly_timer.duration());
|
||||
/*
|
||||
* 5.2.3.2.4 Actions when t-Reassembly expires:
|
||||
* - update RX_Highest_Status to the SN of the first RLC SDU with SN >= RX_Next_Status_Trigger for which not
|
||||
* all bytes have been received;
|
||||
* - if RX_Next_Highest> RX_Highest_Status +1: or
|
||||
* - if RX_Next_Highest = RX_Highest_Status + 1 and there is at least one missing byte segment of the SDU
|
||||
* associated with SN = RX_Highest_Status before the last byte of all received segments of this SDU:
|
||||
* - start t-Reassembly;
|
||||
* - set RX_Next_Status_Trigger to RX_Next_Highest.
|
||||
*/
|
||||
for (uint32_t tmp_sn = rx_next_status_trigger; tmp_sn < rx_next_status_trigger + RLC_AM_WINDOW_SIZE; tmp_sn++) {
|
||||
if (not rx_window.has_sn(tmp_sn) /*|| rx_window[tmp_sn].fully_received*/) {
|
||||
rx_highest_status = tmp_sn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool restart_reassembly_timer = false;
|
||||
if (rx_next_highest > rx_highest_status + 1) {
|
||||
restart_reassembly_timer = true;
|
||||
}
|
||||
if (rx_next_highest == rx_highest_status + 1) {
|
||||
restart_reassembly_timer = true;
|
||||
}
|
||||
if (restart_reassembly_timer) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ int basic_test()
|
|||
int len = rlc2.read_pdu(status_buf.msg, 3);
|
||||
status_buf.N_bytes = len;
|
||||
|
||||
// TESTASSERT(0 == rlc2.get_buffer_state());
|
||||
TESTASSERT(0 == rlc2.get_buffer_state());
|
||||
|
||||
// Assert status is correct
|
||||
rlc_am_nr_status_pdu_t status_check = {};
|
||||
|
|
Loading…
Reference in New Issue