Commit dabf833c authored by gabrielC's avatar gabrielC

RLC AM Rx Segment and Tx Status Report fixes

parent 4a331c6f
...@@ -88,17 +88,18 @@ rlc_am_get_status_pdu_buffer_occupancy( ...@@ -88,17 +88,18 @@ rlc_am_get_status_pdu_buffer_occupancy(
if (pdu_info_cursor_p->so) { if (pdu_info_cursor_p->so) {
nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)); nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1));
waited_so = pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size; waited_so = pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size;
/* Go to next segment */
cursor_p = cursor_p->next;
if (cursor_p != NULL)
{
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
}
} }
else { else {
waited_so = pdu_info_cursor_p->payload_size; waited_so = pdu_info_cursor_p->payload_size;
} }
/* Go to next segment */
cursor_p = cursor_p->next;
if (cursor_p != NULL)
{
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
}
/* Fill following gaps if any */ /* Fill following gaps if any */
while (!segment_loop_end) while (!segment_loop_end)
{ {
......
...@@ -464,8 +464,8 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -464,8 +464,8 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
// 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
if (previous_cursor_p != NULL) { if (previous_cursor_p != NULL) {
pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info; pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info;
if (pdu_info_previous_cursor_p->sn == pdu_rx_info_p->sn) { 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)) {
so_start_segment += (pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - pdu_rx_info_p->so); so_start_segment += (pdu_info_previous_cursor_p->so + pdu_info_previous_cursor_p->payload_size - so_start_segment);
} }
} }
...@@ -512,9 +512,16 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( ...@@ -512,9 +512,16 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment(
else else
{ {
if (previous_cursor_p != NULL) { if (previous_cursor_p != NULL) {
pdu_info_previous_cursor_p = &((rlc_am_rx_pdu_management_t*)(previous_cursor_p->data))->pdu_info;
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d NOT EMPTY] PDU SEGMENT INSERTED AFTER PDU SN=%d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn,
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 { else {
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU SEGMENT SN=%d NOT EMPTY] PDU SEGMENT INSERTED BEFORE PDU SN=%d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),pdu_rx_info_p->sn,
pdu_rx_info_p->sn);
list2_insert_before_element(tb_pP, rlc_pP->receiver_buffer.head, &rlc_pP->receiver_buffer); list2_insert_before_element(tb_pP, rlc_pP->receiver_buffer.head, &rlc_pP->receiver_buffer);
} }
...@@ -1330,10 +1337,19 @@ rlc_am_rx_list_reassemble_rlc_sdus( ...@@ -1330,10 +1337,19 @@ rlc_am_rx_list_reassemble_rlc_sdus(
else if (rlc_am_rx_pdu_management_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING) { else if (rlc_am_rx_pdu_management_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING) {
rlc_am_rx_pdu_management_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLED; rlc_am_rx_pdu_management_p->segment_reassembled = RLC_AM_RX_PDU_SEGMENT_REASSEMBLED;
cursor_p = list2_remove_head(&rlc_pP->receiver_buffer);
rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p,FALSE); rlc_am_reassemble_pdu(ctxt_pP, rlc_pP, cursor_p,FALSE);
rlc_am_rx_old_pdu_management = rlc_am_rx_pdu_management_p; rlc_am_rx_old_pdu_management = rlc_am_rx_pdu_management_p;
cursor_p = list2_get_head(&rlc_pP->receiver_buffer); cursor_p = cursor_p->next;
if (cursor_p == NULL) {
return;
}
rlc_am_rx_pdu_management_p = ((rlc_am_rx_pdu_management_t*)(cursor_p->data));
}
else if (rlc_am_rx_pdu_management_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLED) {
rlc_am_rx_old_pdu_management = rlc_am_rx_pdu_management_p;
cursor_p = cursor_p->next;
if (cursor_p == NULL) { if (cursor_p == NULL) {
return; return;
...@@ -1354,9 +1370,8 @@ rlc_am_rx_list_reassemble_rlc_sdus( ...@@ -1354,9 +1370,8 @@ rlc_am_rx_list_reassemble_rlc_sdus(
return; return;
} }
} while ((rlc_am_rx_pdu_management_p->pdu_info.sn == ((rlc_am_rx_old_pdu_management->pdu_info.sn + 1) & RLC_AM_SN_MASK)) } while (((rlc_am_rx_pdu_management_p->pdu_info.sn == ((rlc_am_rx_old_pdu_management->pdu_info.sn + 1) & RLC_AM_SN_MASK)) && (rlc_am_rx_old_pdu_management->all_segments_received > 0))
|| ((rlc_am_rx_pdu_management_p->pdu_info.sn == rlc_am_rx_old_pdu_management->pdu_info.sn) && ( || ((rlc_am_rx_pdu_management_p->pdu_info.sn == rlc_am_rx_old_pdu_management->pdu_info.sn) && (rlc_am_rx_pdu_management_p->segment_reassembled != RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO)));
(rlc_am_rx_pdu_management_p->all_segments_received > 0) || (rlc_am_rx_pdu_management_p->segment_reassembled == RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_PENDING))));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
mem_block_t * mem_block_t *
......
...@@ -620,17 +620,18 @@ rlc_am_send_status_pdu( ...@@ -620,17 +620,18 @@ rlc_am_send_status_pdu(
pdu_info_cursor_p->so - 1); pdu_info_cursor_p->so - 1);
#endif #endif
waited_so = pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size; waited_so = pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size;
/* Go to next segment */
cursor_p = cursor_p->next;
if (cursor_p != NULL)
{
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
}
} }
else { else {
waited_so = pdu_info_cursor_p->payload_size; waited_so = pdu_info_cursor_p->payload_size;
} }
/* Go to next segment */
cursor_p = cursor_p->next;
if (cursor_p != NULL)
{
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
}
/* Find the first discontinuity and then fill SOStart/SOEnd */ /* Find the first discontinuity and then fill SOStart/SOEnd */
while (!segment_loop_end) { while (!segment_loop_end) {
if ((cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor)) { if ((cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor)) {
...@@ -644,7 +645,7 @@ rlc_am_send_status_pdu( ...@@ -644,7 +645,7 @@ rlc_am_send_status_pdu(
if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) { if ((nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1)) <= nb_bits_to_transmit) {
control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor; control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_cursor;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so; control_pdu_info.nack_list[control_pdu_info.num_nack].so_start = waited_so;
control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so; control_pdu_info.nack_list[control_pdu_info.num_nack].so_end = pdu_info_cursor_p->so - 1;
control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1; control_pdu_info.nack_list[control_pdu_info.num_nack].e2 = 1;
/* Set E1 for next NACK_SN. The last one will be cleared */ /* Set E1 for next NACK_SN. The last one will be cleared */
control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1; control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1;
...@@ -732,7 +733,7 @@ rlc_am_send_status_pdu( ...@@ -732,7 +733,7 @@ rlc_am_send_status_pdu(
} // End main while NACK_SN } // End main while NACK_SN
/* Clear E1 of last nack_sn entry */ /* Clear E1 of last nack_sn entry */
AssertFatal (control_pdu_info.num_nack, "RLC AM Tx Status PDU Data Error no NACK_SN LcId=%d\n",rlc_pP->channel_id); AssertFatal ((control_pdu_info.num_nack) || (all_segments_received == 0), "RLC AM Tx Status PDU Data Error no NACK_SN LcId=%d\n",rlc_pP->channel_id);
control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 0; control_pdu_info.nack_list[control_pdu_info.num_nack - 1].e1 = 0;
/* Set ACK_SN unless it was set before */ /* Set ACK_SN unless it was set before */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment