Add checks for existence of retx buffer and remove from queue if not

This commit is contained in:
Ismael Gomez 2017-11-10 12:39:28 +01:00
parent e983987563
commit 05973790ba
1 changed files with 46 additions and 7 deletions

View File

@ -201,8 +201,14 @@ uint32_t rlc_am::get_total_buffer_state()
rlc_amd_retx_t retx = retx_queue.front();
log->debug("Buffer state - retx - SN: %d, Segment: %s, %d:%d\n", retx.sn, retx.is_segment ? "true" : "false", retx.so_start, retx.so_end);
if(tx_window.end() != tx_window.find(retx.sn)) {
n_bytes += required_buffer_size(retx);
int req_bytes = required_buffer_size(retx);
if (req_bytes < 0) {
log->error("In get_total_buffer_state(): Removing retx.sn=%d from queue\n", retx.sn);
retx_queue.pop_front();
} else {
n_bytes += req_bytes;
log->debug("Buffer state - retx: %d bytes\n", n_bytes);
}
}
}
@ -250,7 +256,13 @@ uint32_t rlc_am::get_buffer_state()
rlc_amd_retx_t retx = retx_queue.front();
log->debug("Buffer state - retx - SN: %d, Segment: %s, %d:%d\n", retx.sn, retx.is_segment ? "true" : "false", retx.so_start, retx.so_end);
if(tx_window.end() != tx_window.find(retx.sn)) {
n_bytes = required_buffer_size(retx);
int req_bytes = required_buffer_size(retx);
if (req_bytes < 0) {
log->error("In get_buffer_state(): Removing retx.sn=%d from queue\n", retx.sn);
retx_queue.pop_front();
goto unlock_and_return;
}
n_bytes = (uint32_t) req_bytes;
log->debug("Buffer state - retx: %d bytes\n", n_bytes);
goto unlock_and_return;
}
@ -439,16 +451,33 @@ int rlc_am::build_status_pdu(uint8_t *payload, uint32_t nof_bytes)
int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes)
{
// Check there is at least 1 element before calling front()
if (retx_queue.empty()) {
log->error("In build_retx_pdu(): retx_queue is empty\n");
return -1;
}
rlc_amd_retx_t retx = retx_queue.front();
// Sanity check - drop any retx SNs not present in tx_window
while(tx_window.end() == tx_window.find(retx.sn)) {
retx_queue.pop_front();
retx = retx_queue.front();
if (!retx_queue.empty()) {
retx = retx_queue.front();
} else {
log->error("In build_retx_pdu(): retx_queue is empty during sanity check\n");
return -1;
}
}
// Is resegmentation needed?
if(retx.is_segment || required_buffer_size(retx) > (int)nof_bytes) {
int req_size = required_buffer_size(retx);
if (req_size < 0) {
log->error("In build_retx_pdu(): Removing retx.sn=%d from queue\n", retx.sn);
retx_queue.pop_front();
return -1;
}
if(retx.is_segment || req_size > (int)nof_bytes) {
log->debug("%s build_retx_pdu - resegmentation required\n", rrc->get_rb_name(lcid).c_str());
return build_segment(payload, nof_bytes, retx);
}
@ -482,6 +511,10 @@ int rlc_am::build_retx_pdu(uint8_t *payload, uint32_t nof_bytes)
int rlc_am::build_segment(uint8_t *payload, uint32_t nof_bytes, rlc_amd_retx_t retx)
{
if (!tx_window[retx.sn].buf) {
log->error("In build_segment: retx.sn=%d has null buffer\n", retx.sn);
return 0;
}
if(!retx.is_segment){
retx.so_start = 0;
retx.so_end = tx_window[retx.sn].buf->N_bytes;
@ -1149,10 +1182,16 @@ int rlc_am::required_buffer_size(rlc_amd_retx_t retx)
{
if(!retx.is_segment){
if (tx_window.count(retx.sn)) {
return rlc_am_packed_length(&tx_window[retx.sn].header) + tx_window[retx.sn].buf->N_bytes;
if (tx_window[retx.sn].buf) {
return rlc_am_packed_length(&tx_window[retx.sn].header) + tx_window[retx.sn].buf->N_bytes;
} else {
log->console("retx.sn=%d has null ptr\n", retx.sn);
log->warning("retx.sn=%d has null ptr in required_buffer_size()\n", retx.sn);
return -1;
}
} else {
log->console("retx.sn=%d does not exist\n");
log->warning("retx.sn=%d does not exist in required_buffer_size()\n");
log->console("retx.sn=%d does not exist\n", retx.sn);
log->warning("retx.sn=%d does not exist in required_buffer_size()\n", retx.sn);
return -1;
}
}