Skip to content
Snippets Groups Projects
Commit 0ce73b4d authored by fnabet's avatar fnabet
Browse files

RLC AM Rx PDU Segment fixes

parent 7f60e38f
No related branches found
No related tags found
2 merge requests!168Develop integration w13,!167Bugfix 189 rlc am fixes
...@@ -298,9 +298,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -298,9 +298,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
/*****************************************************/ /*****************************************************/
// 1) Find previous cursor to the PDU to insert // 1) Find previous cursor to the PDU to insert
/*****************************************************/ /*****************************************************/
previous_cursor_p = cursor_p;
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
pdu_info_previous_cursor_p = pdu_info_cursor_p;
while (cursor_p != NULL) { while (cursor_p != NULL) {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
...@@ -320,11 +318,10 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -320,11 +318,10 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
// First case : cursor_p is NULL or its SN is different from the received one, it means the SN is received for the first time // First case : cursor_p is NULL or its SN is different from the received one, it means the SN is received for the first time
// Insert PDU after previous_cursor_p // Insert PDU after previous_cursor_p
if ((cursor_p == NULL) || (pdu_info_cursor_p->sn != pdu_rx_info_p->sn)) { if ((cursor_p == NULL) || (pdu_info_cursor_p->sn != pdu_rx_info_p->sn)) {
rlc_usn_t sn_prev = pdu_info_previous_cursor_p->sn; if (previous_cursor_p != NULL) {
if (RLC_AM_DIFF_SN(sn_prev,rlc_pP->vr_r) < RLC_AM_DIFF_SN(pdu_rx_info_p->sn,rlc_pP->vr_r)) {
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d] PDU SEGMENT INSERTED AFTER PDU SN=%d\n", LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d] PDU SEGMENT INSERTED AFTER PDU SN=%d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn, PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn,
sn_prev); pdu_info_previous_cursor_p->sn);
list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer);
} }
else { /* SN of head of Rx PDU list is higher than received PDU SN */ else { /* SN of head of Rx PDU list is higher than received PDU SN */
...@@ -337,6 +334,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -337,6 +334,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
return RLC_AM_DATA_PDU_STATUS_OK; return RLC_AM_DATA_PDU_STATUS_OK;
} }
/* Now handle case cursor->sn = received SN */
// Filter out SN duplicate // Filter out SN duplicate
rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data); rlc_am_rx_pdu_management_t * pdu_cursor_mgnt_p = (rlc_am_rx_pdu_management_t *) (cursor_p->data);
...@@ -362,29 +360,29 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -362,29 +360,29 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
} }
/* if not previously inserted, it will be put after the last segment if it was not LSF*/ /* if not previously inserted, it will be put after the last segment if it was not LSF*/
if ((!prev_segment_found) && (pdu_info_previous_cursor_p->lsf == 0)) { if (!prev_segment_found) {
prev_segment_found = TRUE; if (pdu_info_previous_cursor_p->lsf == 0) {
next_segment_found = TRUE; // no more segment after the PDU prev_segment_found = TRUE;
next_cursor_p = cursor_p; next_segment_found = TRUE; // no more segment after the PDU
AssertFatal(previous_cursor_p->next == next_cursor_p,"AM Rx PDU Segment store at the end error, SN=%d \n",pdu_rx_info_p->sn); next_cursor_p = cursor_p;
} AssertFatal(previous_cursor_p->next == next_cursor_p,"AM Rx PDU Segment store at the end error, SN=%d \n",pdu_rx_info_p->sn);
else }
{ else
// the segment is duplicate {
return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; // the segment is duplicate
return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE;
}
} }
// Check that the Segment is not duplicate by scanning stored contiguous segments from previous_cursor_p // Check that the Segment is not duplicate by scanning stored contiguous segments from previous_cursor_p
pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info;
if ((previous_cursor_p != NULL) && (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn)) { if ((previous_cursor_p != NULL) && (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn)) {
so_start = pdu_info_previous_cursor_p->so; so_start = pdu_info_previous_cursor_p->so;
so_end = pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - 1; so_end = pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - 1;
cursor_p = previous_cursor_p; pdu_info_cursor_p = pdu_info_previous_cursor_p;
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; cursor_p = previous_cursor_p->next;
cursor_p = cursor_p->next;
rlc_am_pdu_info_t* pdu_info_cursor_next_p = NULL; rlc_am_pdu_info_t* pdu_info_cursor_next_p = NULL;
if (cursor_p != NULL) { if (cursor_p != NULL) {
pdu_info_cursor_next_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; pdu_info_cursor_next_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
...@@ -403,7 +401,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -403,7 +401,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
/* Now discard the PDU segment if it is within so_start so_end */ /* Now discard the PDU segment if it is within so_start so_end */
if ((so_start <= so_start_segment) && (so_end_segment <= so_end)) { if ((so_start <= so_start_segment) && (so_end_segment <= so_end)) {
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] DISCARD : DUPLICATE SEGMENT SN=%d\n", LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] DISCARD : DUPLICATE SEGMENT SN=%d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn); PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn);
return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE;
} }
} }
...@@ -411,8 +409,37 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -411,8 +409,37 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
// Now found the segment which will be right after the pdu to insert // Now found the segment which will be right after the pdu to insert
if (!next_segment_found) { if (!next_segment_found) {
/* special case if SN=vrR and some segments have been previously reassembled and not yet discarded */
/* update previous_cursor_p up to the last reassembled Segment */
if ((previous_cursor_p != NULL) && (pdu_rx_info_p->sn == rlc_pP->vr_r)) {
if (((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLED) {
pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info;
so_end = pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size;
cursor_p = previous_cursor_p->next;
if (cursor_p != NULL) {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
}
while ((cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn) &&
(((rlc_am_rx_pdu_management_t*)(cursor_p->data))->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLED)) {
AssertFatal(pdu_info_cursor_p->so == so_end,"AM Rx PDU Segment store contiguous reassembled error, SN=%d \n",pdu_rx_info_p->sn);
so_end += pdu_info_cursor_p->payload_size;
previous_cursor_p = cursor_p;
cursor_p = cursor_p->next;
if (cursor_p != NULL) {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
}
}
}
}
if (previous_cursor_p != NULL) {
cursor_p = previous_cursor_p->next;
}
else {
cursor_p = rlc_pP->receiver_buffer.head;
}
cursor_p = previous_cursor_p->next;
next_cursor_p = cursor_p; next_cursor_p = cursor_p;
if (next_cursor_p != NULL) { if (next_cursor_p != NULL) {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info;
...@@ -435,10 +462,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -435,10 +462,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
/* Now remove duplicate bytes */ /* Now remove duplicate bytes */
// remove duplicate at the begining, only valid if the segment is to be inserted after a PDU segment of the same SN // remove duplicate at the begining, only valid if the segment is to be inserted after a PDU segment of the same SN
pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; if (previous_cursor_p != NULL) {
if (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn) { pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info;
so_start_segment += (pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - pdu_rx_info_p->so); if (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn) {
so_start_segment += (pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - pdu_rx_info_p->so);
}
} }
// remove duplicate at the end // remove duplicate at the end
if (next_cursor_p != NULL) { if (next_cursor_p != NULL) {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info;
...@@ -448,6 +478,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -448,6 +478,7 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
} }
} }
AssertFatal((so_start_segment <= so_end_segment) && (pdu_rx_info_p->so <= so_start_segment) && AssertFatal((so_start_segment <= so_end_segment) && (pdu_rx_info_p->so <= so_start_segment) &&
(so_end_segment <= pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1), (so_end_segment <= pdu_rx_info_p->so + pdu_rx_info_p->payload_size - 1),
" AM RX PDU Segment Duplicate elimination error OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n", " AM RX PDU Segment Duplicate elimination error OldSOStart=%d OldSOEnd=%d newSOStart=%d newSOEnd =%d SN=%d\n",
...@@ -462,7 +493,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -462,7 +493,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] CREATE SEGMENT FROM SEGMENT OFFSET=%d DATA LENGTH=%d SN=%d\n", LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT] CREATE SEGMENT FROM SEGMENT OFFSET=%d DATA LENGTH=%d SN=%d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1,pdu_rx_info_p->sn); PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),so_start_segment - pdu_rx_info_p->so,so_end_segment - so_start_segment + 1,pdu_rx_info_p->sn);
list2_insert_after_element(trunc_segment, previous_cursor_p, &rlc_pP->receiver_buffer); if (previous_cursor_p != NULL) {
list2_insert_after_element(trunc_segment, previous_cursor_p, &rlc_pP->receiver_buffer);
}
else {
list2_insert_before_element(trunc_segment, rlc_pP->receiver_buffer.head, &rlc_pP->receiver_buffer);
}
/* Free original PDU Segment */ /* Free original PDU Segment */
free_mem_block(tb_pP, __func__); free_mem_block(tb_pP, __func__);
...@@ -474,7 +511,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -474,7 +511,13 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
} }
else else
{ {
list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer); if (previous_cursor_p != NULL) {
list2_insert_after_element(tb_pP, previous_cursor_p, &rlc_pP->receiver_buffer);
}
else {
list2_insert_before_element(tb_pP, rlc_pP->receiver_buffer.head, &rlc_pP->receiver_buffer);
}
return RLC_AM_DATA_PDU_STATUS_OK; return RLC_AM_DATA_PDU_STATUS_OK;
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment