Commit 49006696 authored by hbilel's avatar hbilel

RLC AM add various fixes

parent bb4131b3
......@@ -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;
......
......@@ -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
......
......@@ -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;
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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
......
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