RLC AM add various fixes
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user