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 eda90edf9ad1c7078fde2cc90e598a220febe9d3..03fabf47b31facd3d84479c1a7cc874713cfc88c 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -1253,14 +1253,16 @@ rlc_am_data_req ( l_rlc_p->next_sdu_index = (l_rlc_p->next_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; if (l_rlc_p->channel_id <3) { - LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_REQ size %d Bytes, NB SDU %d current_sdu_index=%d next_sdu_index=%d conf %d mui %d\n", + LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_REQ size %d Bytes, NB SDU %d current_sdu_index=%d next_sdu_index=%d conf %d mui %d vtA %d vtS %d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p), data_size, l_rlc_p->nb_sdu, l_rlc_p->current_sdu_index, l_rlc_p->next_sdu_index, conf, - mui); + mui, + l_rlc_p->vt_a, + l_rlc_p->vt_s); } } else { #if MESSAGE_CHART_GENERATOR @@ -1278,12 +1280,14 @@ rlc_am_data_req ( data_size, mui); #endif - LOG_W(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_REQ BUFFER FULL, NB SDU %d current_sdu_index=%d next_sdu_index=%d size_input_sdus_buffer=%d\n", + LOG_W(RLC, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_REQ BUFFER FULL, NB SDU %d current_sdu_index=%d next_sdu_index=%d size_input_sdus_buffer=%d vtA=%d vtS=%d\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p), l_rlc_p->nb_sdu, l_rlc_p->current_sdu_index, l_rlc_p->next_sdu_index, - RLC_AM_SDU_CONTROL_BUFFER_SIZE); + RLC_AM_SDU_CONTROL_BUFFER_SIZE, + l_rlc_p->vt_a, + l_rlc_p->vt_s); LOG_W(RLC, " input_sdus[].mem_block=%p next input_sdus[].flags.segmented=%d\n", l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].mem_block, l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].flags.segmented); l_rlc_p->stat_tx_pdcp_sdu_discarded += 1; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h index 10f310d5decf131751c73abb51133cc377c6fa5c..69429b84b889780baec29657ef27dabf1e765328 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_constants.h @@ -48,7 +48,7 @@ # define RLC_AM_SDU_DATA_BUFFER_SIZE 64*1024 /** Max number of incoming SDUs from upper layer that can be buffered in a RLC AM protocol instance. */ -# define RLC_AM_SDU_CONTROL_BUFFER_SIZE 128 +# define RLC_AM_SDU_CONTROL_BUFFER_SIZE 1024 /** Size of the retransmission buffer (number of PDUs). */ # define RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE RLC_AM_WINDOW_SIZE diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c index b41dea42f268db9f96b4a8bd3fd45a0b201fe59c..4b5c173d4b6e891c5d98b7eb7c1d95ade8e60719 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_in_sdu.c @@ -57,13 +57,12 @@ void rlc_am_free_in_sdu( memset(&rlcP->input_sdus[index_in_bufferP], 0, sizeof(rlc_am_tx_sdu_management_t)); rlcP->input_sdus[index_in_bufferP].flags.transmitted_successfully = 1; - // TODO : understand why. This should not happen + // case when either one SDU needs to be removed from segmentation or SDU buffer is full if (rlcP->current_sdu_index == index_in_bufferP) { rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; } - // TODO : this loop is useless as UL SDUs are transmitted and acknowledged in sequence - // even with PDCP UL SDU discard functionality + // wrapping and reset current_sdu_index to next_sdu_index when all transmitted SDUs have been acknowledged while ((rlcP->current_sdu_index != rlcP->next_sdu_index) && (rlcP->input_sdus[rlcP->current_sdu_index].flags.transmitted_successfully == 1)) { rlcP->current_sdu_index = (rlcP->current_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c index fc31d6e8b6cb54c679161e3b49d99dfbfcf91020..f80a46695d21baef203f4eaa59ec03b8267358ae 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_retransmit.c @@ -95,7 +95,7 @@ boolean_t rlc_am_nack_pdu ( } // Check consistency - if ((so_startP < so_endP) && (so_endP < tx_data_pdu_buffer_p->payload_size)) { + if ((so_startP <= so_endP) && (so_endP < tx_data_pdu_buffer_p->payload_size)) { if (prev_nack_snP != snP) { /* New NACK_SN with SO */ /* check whether a new segment is to be placed in Retransmission Buffer, then increment vrReTx */ 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 33b86f7948e6e90d9a296118410040aad1f190fc..cad1a776a8244503a7257fca0d3799c9d43d05d3 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 @@ -222,6 +222,7 @@ mem_block_t * create_new_segment_from_pdu( pdu_new_segment_info_p->p = pdu_rx_info_p->p; pdu_new_segment_info_p->rf = 1; pdu_new_segment_info_p->fi = (((fi_start ? 0: 1) << 1) | (fi_end ? 0: 1)); + pdu_new_segment_info_p->num_li = num_li; pdu_new_segment_info_p->e = (num_li ? 1: 0); pdu_new_segment_info_p->lsf = (lsf ? 1: 0); pdu_new_segment_info_p->so = pdu_rx_info_p->so + so_offset; @@ -380,6 +381,23 @@ rlc_am_rx_pdu_status_t rlc_am_rx_list_handle_pdu_segment( return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; } + // Try to catch a segment duplicate + next_cursor_p = cursor_p; + while ((next_cursor_p != NULL) && (pdu_info_cursor_p->sn == pdu_rx_info_p->sn)) { + if ((so_start_segment >= pdu_info_cursor_p->so) && (so_end_segment <= pdu_info_cursor_p->so + pdu_info_cursor_p->payload_size - 1)) { + 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); + return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; + } + next_cursor_p = next_cursor_p->next; + if (next_cursor_p != NULL) { + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(next_cursor_p->data))->pdu_info; + } + } + + // Reset pdu_info_cursor_p because of the loop before + pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; + // Try to Handle the most likely cases first if (pdu_info_cursor_p->so == 0) { @@ -425,7 +443,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_min and so_end */ - if ((so_start_min <= so_start_segment) && (so_end_segment < so_end)) { + if ((so_start_min <= so_start_segment) && (so_end_segment <= so_end - 1)) { 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); return RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE; 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 b1f53586cb26c7fca0a25cd36fd57d6c73312bb2..d33dc78e91ad73d19fbf70c81331feb34f0728fe 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 @@ -562,7 +562,7 @@ rlc_am_send_status_pdu( all_segments_received = ((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received; /* First fill NACK_SN with each missing PDU between current sn_nack and sn_cursor */ - while ((sn_nack != sn_cursor) && (sn_nack != rlc_pP->vr_ms)) { + while ((sn_nack != sn_cursor) && (RLC_AM_DIFF_SN(sn_nack,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r))) { if (nb_bits_transmitted + RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) <= nb_bits_to_transmit) { /* Fill NACK_SN infos */ control_pdu_info.nack_list[control_pdu_info.num_nack].nack_sn = sn_nack; @@ -596,6 +596,10 @@ rlc_am_send_status_pdu( } } + if (sn_nack == rlc_pP->vr_ms) { + break; + } + /* Now process all Segments of sn_cursor if PDU not fully received */ if ((!status_report_completed) && (all_segments_received == 0) && (sn_cursor != rlc_pP->vr_ms)) { AssertFatal (sn_nack == sn_cursor, "RLC AM Tx Status PDU Data sn_nack=%d and sn_cursor=%d should be equal LcId=%d\n",sn_nack,sn_cursor, rlc_pP->channel_id); @@ -732,10 +736,13 @@ rlc_am_send_status_pdu( } while ((cursor_p != NULL) && (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info.sn == sn_cursor)); } - /* Increment sn_nack except if sn_nack = vrMS and if current SN was not fully received */ - if (sn_nack != rlc_pP->vr_ms) { + /* Increment sn_nack except if sn_cursor = vrMS and if current SN was not fully received */ + if (RLC_AM_DIFF_SN(sn_cursor,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r)) { sn_nack = RLC_AM_NEXT_SN(sn_cursor); } + else { + sn_nack = rlc_pP->vr_ms; + } } // End main while NACK_SN