diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index df8682f726dc6e06dc9e346afd8f8c1cfddb348c..f7f4de1718ec94d818fcaa8de38296e22284a8d5 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -88,17 +88,18 @@ rlc_am_get_status_pdu_buffer_occupancy( 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)); 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 { 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 */ while (!segment_loop_end) { diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c index 310c66a44c0f749c3fca52ae3fa18670c6ca3c3e..bb1d1724512e1a631054eebab418ab64ecf73229 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_rx_list.c @@ -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 if (previous_cursor_p != NULL) { 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) { - 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)) { + 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( else { 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); } 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); } @@ -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) { 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_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) { return; @@ -1354,9 +1370,8 @@ rlc_am_rx_list_reassemble_rlc_sdus( 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)) - || ((rlc_am_rx_pdu_management_p->pdu_info.sn == rlc_am_rx_old_pdu_management->pdu_info.sn) && ( - (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)))); + } 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->segment_reassembled != RLC_AM_RX_PDU_SEGMENT_REASSEMBLE_NO))); } //----------------------------------------------------------------------------- mem_block_t * diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c index 6d4fd0a2b76159a8c3a2b359b2ebf0d95c21bdb9..dfa62f03516e795859af63d72a99f2ffb610674f 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_status_report.c @@ -620,17 +620,18 @@ rlc_am_send_status_pdu( pdu_info_cursor_p->so - 1); #endif 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 { 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 */ while (!segment_loop_end) { if ((cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor)) { @@ -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) { 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_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; /* Set E1 for next NACK_SN. The last one will be cleared */ control_pdu_info.nack_list[control_pdu_info.num_nack].e1 = 1; @@ -732,7 +733,7 @@ rlc_am_send_status_pdu( } // End main while NACK_SN /* 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; /* Set ACK_SN unless it was set before */