Commit b77694e8 authored by fnabet's avatar fnabet

main AM RX process PDU changes

parent dec41a2a
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
# define RLC_AM_SDU_CONTROL_BUFFER_SIZE 128 # define RLC_AM_SDU_CONTROL_BUFFER_SIZE 128
/** Size of the retransmission buffer (number of PDUs). */ /** Size of the retransmission buffer (number of PDUs). */
# define RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE RLC_AM_SN_MODULO # define RLC_AM_PDU_RETRANSMISSION_BUFFER_SIZE RLC_AM_WINDOW_SIZE
/** PDU minimal header size in bytes. */ /** PDU minimal header size in bytes. */
# define RLC_AM_HEADER_MIN_SIZE 2 # define RLC_AM_HEADER_MIN_SIZE 2
...@@ -69,6 +69,36 @@ ...@@ -69,6 +69,36 @@
# define RLC_AM_MAX_NACK_IN_STATUS_PDU 1023 # define RLC_AM_MAX_NACK_IN_STATUS_PDU 1023
/** Max holes created by NACK_SN with segment offsets for a PDU in the retransmission buffer. */ /** Max holes created by NACK_SN with segment offsets for a PDU in the retransmission buffer. */
# define RLC_AM_MAX_HOLES_REPORT_PER_PDU 32 # define RLC_AM_MAX_HOLES_REPORT_PER_PDU 16
/** @} */ /** @} */
# endif
/* MACRO DEFINITIONS */
#define RLC_AM_NEXT_SN(sn) (((sn)+1) & ((RLC_AM_SN_MODULO)-1))
#define RLC_AM_PREV_SN(sn) (((sn)+(RLC_AM_SN_MODULO)-1) & ((RLC_AM_SN_MODULO)-1))
#define RLC_DIFF_SN(sn,snref,modulus) ((sn+(modulus)-snref) & ((modulus)-1))
#define RLC_SN_IN_WINDOW(sn,snref,modulus) ((RLC_DIFF_SN(sn,snref,modulus)) < ((modulus) >> 1))
#define RLC_AM_DIFF_SN(sn,snref) (RLC_DIFF_SN(sn,snref,RLC_AM_SN_MODULO))
#define RLC_AM_SN_IN_WINDOW(sn,snref) (RLC_SN_IN_WINDOW(sn,snref,RLC_AM_SN_MODULO))
#define RLC_SET_EVENT(x,event) ((x) |= (event))
#define RLC_GET_EVENT(x,event) ((x) & (event))
#define RLC_CLEAR_EVENT(x,event) ((x) &= (~(event)))
/* Uplink STATUS PDU trigger events */
#define RLC_AM_STATUS_NOT_TRIGGERED 0
#define RLC_AM_STATUS_TRIGGERED_POLL 0x01 /* Status Report is triggered by a received poll */
#define RLC_AM_STATUS_TRIGGERED_T_REORDERING 0x02 /* Status Report is triggered by Timer Reordering Expiry */
#define RLC_AM_STATUS_TRIGGERED_DELAYED 0x10 /* Status is delayed until SN(receivedPoll) < VR(MS) */
#define RLC_AM_STATUS_PROHIBIT 0x20 /* TimerStatusProhibit still running */
/* Status triggered (bit 5-7) will be concatenated with Poll triggered (bit 0-4) for RLCdec. RLC_AM_STATUS_TRIGGERED_DELAYED is not recorded. */
#define RLC_AM_SET_STATUS(x,event) (RLC_SET_EVENT(x,event))
#define RLC_AM_GET_STATUS(x,event) (RLC_GET_EVENT(x,event))
#define RLC_AM_CLEAR_STATUS(x,event) (RLC_CLEAR_EVENT(x,event))
#define RLC_AM_CLEAR_ALL_STATUS(x) ((x) = (RLC_AM_STATUS_NOT_TRIGGERED))
#endif
...@@ -182,7 +182,8 @@ typedef struct rlc_am_entity_s { ...@@ -182,7 +182,8 @@ typedef struct rlc_am_entity_s {
rlc_sn_t first_retrans_pdu_sn; /*!< \brief Lowest sequence number of PDU to be retransmitted. */ rlc_sn_t first_retrans_pdu_sn; /*!< \brief Lowest sequence number of PDU to be retransmitted. */
list_t segmentation_pdu_list; /*!< \brief List of "freshly" segmented PDUs. */ list_t segmentation_pdu_list; /*!< \brief List of "freshly" segmented PDUs. */
boolean_t status_requested; /*!< \brief Status requested by peer. */ uint8_t status_requested; /*!< \brief Status bitmap requested by peer. */
rlc_sn_t sn_status_triggered_delayed; /*!< \brief SN of the last received poll for which Status is delayed until SN is out of Rx Window. */
frame_t last_frame_status_indication; /*!< \brief The last frame number a MAC status indication has been received by RLC. */ frame_t last_frame_status_indication; /*!< \brief The last frame number a MAC status indication has been received by RLC. */
//----------------------------- //-----------------------------
// buffer occupancy measurements sent to MAC // buffer occupancy measurements sent to MAC
......
...@@ -74,9 +74,10 @@ rlc_am_init( ...@@ -74,9 +74,10 @@ rlc_am_init(
// RX state variables // RX state variables
//rlc_pP->vr_r = 0; //rlc_pP->vr_r = 0;
rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE; rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE;
//rlc_pP->vr_x = 0; rlc_pP->vr_x = RLC_SN_UNDEFINED;
//rlc_pP->vr_ms = 0; //rlc_pP->vr_ms = 0;
//rlc_pP->vr_h = 0; //rlc_pP->vr_h = 0;
rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED;
rlc_pP->last_frame_status_indication = 123456; // any value > 1 rlc_pP->last_frame_status_indication = 123456; // any value > 1
rlc_pP->first_retrans_pdu_sn = -1; rlc_pP->first_retrans_pdu_sn = -1;
...@@ -128,9 +129,11 @@ rlc_am_reestablish( ...@@ -128,9 +129,11 @@ rlc_am_reestablish(
// RX state variables // RX state variables
rlc_pP->vr_r = 0; rlc_pP->vr_r = 0;
rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE; rlc_pP->vr_mr = rlc_pP->vr_r + RLC_AM_WINDOW_SIZE;
rlc_pP->vr_x = 0; rlc_pP->vr_x = RLC_SN_UNDEFINED;
rlc_pP->vr_ms = 0; rlc_pP->vr_ms = 0;
rlc_pP->vr_h = 0; rlc_pP->vr_h = 0;
rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED;
rlc_pP->status_requested = RLC_AM_STATUS_NOT_TRIGGERED;
rlc_pP->last_frame_status_indication = 123456; // any value > 1 rlc_pP->last_frame_status_indication = 123456; // any value > 1
rlc_pP->first_retrans_pdu_sn = -1; rlc_pP->first_retrans_pdu_sn = -1;
......
...@@ -47,7 +47,8 @@ rlc_am_get_data_pdu_infos( ...@@ -47,7 +47,8 @@ rlc_am_get_data_pdu_infos(
pdu_info_pP->num_li = 0; pdu_info_pP->num_li = 0;
if (pdu_info_pP->d_c) { AssertFatal (pdu_info_pP->d_c != 0, "RLC AM Rx PDU Data D/C Header Error LcId=%d\n", rlc_pP->channel_id);
pdu_info_pP->rf = (header_pP->b1 >> 6) & 0x01; pdu_info_pP->rf = (header_pP->b1 >> 6) & 0x01;
pdu_info_pP->p = (header_pP->b1 >> 5) & 0x01; pdu_info_pP->p = (header_pP->b1 >> 5) & 0x01;
pdu_info_pP->fi = (header_pP->b1 >> 3) & 0x03; pdu_info_pP->fi = (header_pP->b1 >> 3) & 0x03;
...@@ -117,12 +118,6 @@ rlc_am_get_data_pdu_infos( ...@@ -117,12 +118,6 @@ rlc_am_get_data_pdu_infos(
} }
return 0; return 0;
} else {
LOG_W(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[GET DATA PDU INFO] SN %04d ERROR CONTROL PDU ",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
pdu_info_pP->sn);
return -1;
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
...@@ -181,26 +176,22 @@ rlc_am_rx_update_vr_ms( ...@@ -181,26 +176,22 @@ rlc_am_rx_update_vr_ms(
do { do {
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
if (((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received == 0) { if ((((rlc_am_rx_pdu_management_t*)(cursor_p->data))->all_segments_received == 0) ||
(rlc_pP->vr_ms != pdu_info_cursor_p->sn)) {
#if TRACE_RLC_AM_RX #if TRACE_RLC_AM_RX
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[UPDATE VR(MS)] UPDATED VR(MS) %04d -> %04d\n", LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[UPDATE VR(MS)] UPDATED VR(MS) %04d -> %04d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
rlc_pP->vr_ms, pdu_info_cursor_p->sn); rlc_pP->vr_ms, pdu_info_cursor_p->sn);
#endif #endif
rlc_pP->vr_ms = pdu_info_cursor_p->sn;
return; return;
} }
rlc_pP->vr_ms = RLC_AM_NEXT_SN(pdu_info_cursor_p->sn);
cursor_p = cursor_p->next; cursor_p = cursor_p->next;
} while (cursor_p != NULL); } while ((cursor_p != NULL) && (rlc_pP->vr_ms != rlc_pP->vr_h));
#if TRACE_RLC_AM_RX
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[UPDATE VR(MS)] UPDATED VR(MS) %04d -> %04d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
rlc_pP->vr_ms,
(pdu_info_cursor_p->sn + 1) & RLC_AM_SN_MASK);
#endif
rlc_pP->vr_ms = (pdu_info_cursor_p->sn + 1) & RLC_AM_SN_MASK;
} }
} }
// assumed the sn of the tb_p is equal to VR(R) // assumed the sn of the tb_p is equal to VR(R)
...@@ -322,18 +313,14 @@ rlc_am_receive_process_data_pdu ( ...@@ -322,18 +313,14 @@ rlc_am_receive_process_data_pdu (
// - discard the duplicate byte segments. // - discard the duplicate byte segments.
rlc_am_pdu_info_t* pdu_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info; rlc_am_pdu_info_t* pdu_info_p = &((rlc_am_rx_pdu_management_t*)(tb_pP->data))->pdu_info;
rlc_am_pdu_sn_10_t* rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t*)first_byte_pP; rlc_am_pdu_sn_10_t* rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t*)first_byte_pP;
rlc_am_rx_pdu_status_t pdu_status = RLC_AM_DATA_PDU_STATUS_OK;
boolean_t reassemble = false;
if (rlc_am_get_data_pdu_infos(ctxt_pP,rlc_pP, rlc_am_pdu_sn_10_p, tb_size_in_bytesP, pdu_info_p) >= 0) { if (rlc_am_get_data_pdu_infos(ctxt_pP,rlc_pP, rlc_am_pdu_sn_10_p, tb_size_in_bytesP, pdu_info_p) >= 0) {
((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received = 0; ((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received = 0;
if (rlc_am_in_rx_window(ctxt_pP, rlc_pP, pdu_info_p->sn)) { if (RLC_AM_SN_IN_WINDOW(pdu_info_p->sn, rlc_pP->vr_r)) {
if (pdu_info_p->p) {
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] POLL BIT SET, STATUS REQUESTED:\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
rlc_pP->status_requested = 1;
}
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] VR(R) %04d VR(H) %04d VR(MR) %04d VR(MS) %04d VR(X) %04d\n", LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] VR(R) %04d VR(H) %04d VR(MR) %04d VR(MS) %04d VR(X) %04d\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
...@@ -346,10 +333,8 @@ rlc_am_receive_process_data_pdu ( ...@@ -346,10 +333,8 @@ rlc_am_receive_process_data_pdu (
if (rlc_am_rx_list_insert_pdu(ctxt_pP, rlc_pP,tb_pP) < 0) { if (rlc_am_rx_list_insert_pdu(ctxt_pP, rlc_pP,tb_pP) < 0) {
rlc_pP->stat_rx_data_pdu_dropped += 1; rlc_pP->stat_rx_data_pdu_dropped += 1;
rlc_pP->stat_rx_data_bytes_dropped += tb_size_in_bytesP; rlc_pP->stat_rx_data_bytes_dropped += tb_size_in_bytesP;
free_mem_block (tb_pP, __func__);
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU DISCARDED, STATUS REQUESTED:\n", LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU DISCARDED, STATUS REQUESTED:\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
rlc_pP->status_requested = 1;
#if RLC_STOP_ON_LOST_PDU #if RLC_STOP_ON_LOST_PDU
AssertFatal( 0 == 1, AssertFatal( 0 == 1,
PROTOCOL_RLC_AM_CTXT_FMT" LOST PDU DETECTED\n", PROTOCOL_RLC_AM_CTXT_FMT" LOST PDU DETECTED\n",
...@@ -394,12 +379,15 @@ rlc_am_receive_process_data_pdu ( ...@@ -394,12 +379,15 @@ rlc_am_receive_process_data_pdu (
rlc_am_rx_list_display(rlc_pP, "rlc_am_receive_process_data_pdu AFTER INSERTION "); rlc_am_rx_list_display(rlc_pP, "rlc_am_receive_process_data_pdu AFTER INSERTION ");
#endif #endif
if (rlc_am_sn_gte_vr_h(ctxt_pP, rlc_pP, pdu_info_p->sn) > 0) { /* 1) Update vrH if sn >= vrH */
rlc_pP->vr_h = (pdu_info_p->sn + 1) & RLC_AM_SN_MASK; if (RLC_AM_DIFF_SN(pdu_info_p->sn,rlc_pP->vr_r) >= RLC_AM_DIFF_SN(rlc_pP->vr_h,rlc_pP->vr_r))
{
rlc_pP->vr_h = RLC_AM_NEXT_SN(pdu_info_p->sn);
} }
rlc_am_rx_check_all_byte_segments(ctxt_pP, rlc_pP, tb_pP); rlc_am_rx_check_all_byte_segments(ctxt_pP, rlc_pP, tb_pP);
/* 2) Reordering Window Processing: Update vr_ms if sn = vr_ms and all bytes received for sn */
if ((pdu_info_p->sn == rlc_pP->vr_ms) && (((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received)) { if ((pdu_info_p->sn == rlc_pP->vr_ms) && (((rlc_am_rx_pdu_management_t*)(tb_pP->data))->all_segments_received)) {
rlc_am_rx_update_vr_ms(ctxt_pP, rlc_pP, tb_pP); rlc_am_rx_update_vr_ms(ctxt_pP, rlc_pP, tb_pP);
} }
...@@ -410,20 +398,35 @@ rlc_am_receive_process_data_pdu ( ...@@ -410,20 +398,35 @@ rlc_am_receive_process_data_pdu (
rlc_pP->vr_mr = (rlc_pP->vr_r + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK; rlc_pP->vr_mr = (rlc_pP->vr_r + RLC_AM_WINDOW_SIZE) & RLC_AM_SN_MASK;
} }
rlc_am_rx_list_reassemble_rlc_sdus(ctxt_pP, rlc_pP); reassemble = true;
//TODO : optimization : check whether a reassembly is needed by looking at LI, FI, SO, etc...
} }
//FNA: fix check VrX out of receiving window //FNA: fix check VrX out of receiving window
if (rlc_pP->t_reordering.running) { if ((rlc_pP->t_reordering.running) || ((rlc_pP->t_reordering.ms_duration == 0) && (rlc_pP->vr_x != RLC_SN_UNDEFINED))) {
if ((rlc_pP->vr_x == rlc_pP->vr_r) || ((rlc_am_in_rx_window(ctxt_pP, rlc_pP, rlc_pP->vr_x) == 0) && (rlc_pP->vr_x != rlc_pP->vr_mr))) { if ((rlc_pP->vr_x == rlc_pP->vr_r) || (!(RLC_AM_SN_IN_WINDOW(rlc_pP->vr_x, rlc_pP->vr_r)) && (rlc_pP->vr_x != rlc_pP->vr_mr))) {
rlc_am_stop_and_reset_timer_reordering(ctxt_pP, rlc_pP); rlc_am_stop_and_reset_timer_reordering(ctxt_pP, rlc_pP);
rlc_pP->vr_x = RLC_SN_UNDEFINED;
} }
} }
if (!(rlc_pP->t_reordering.running)) { if (!(rlc_pP->t_reordering.running)) {
if (rlc_pP->vr_h != rlc_pP->vr_r) { // - if VR (H) > VR(R) translated to - if VR (H) != VR(R) if (rlc_pP->vr_h != rlc_pP->vr_r) { // - if VR (H) > VR(R) translated to - if VR (H) != VR(R)
rlc_am_start_timer_reordering(ctxt_pP, rlc_pP);
rlc_pP->vr_x = rlc_pP->vr_h; rlc_pP->vr_x = rlc_pP->vr_h;
if (rlc_pP->t_reordering.ms_duration != 0) {
rlc_am_start_timer_reordering(ctxt_pP, rlc_pP);
}
else {
/* specific case for no timer reordering configured */
/* reordering window directly advances with vrH */
rlc_pP->vr_ms = rlc_pP->vr_h;
/* Trigger a Status and clear any existing Delay Flag */
RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_T_REORDERING);
RLC_AM_CLEAR_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED);
rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED;
}
} }
} }
} }
...@@ -437,12 +440,67 @@ rlc_am_receive_process_data_pdu ( ...@@ -437,12 +440,67 @@ rlc_am_receive_process_data_pdu (
} else { } else {
rlc_pP->stat_rx_data_pdu_out_of_window += 1; rlc_pP->stat_rx_data_pdu_out_of_window += 1;
rlc_pP->stat_rx_data_bytes_out_of_window += tb_size_in_bytesP; rlc_pP->stat_rx_data_bytes_out_of_window += tb_size_in_bytesP;
free_mem_block (tb_pP, __func__); pdu_status = RLC_AM_DATA_PDU_STATUS_SN_OUTSIDE_WINDOW;
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU OUT OF RX WINDOW, DISCARDED, STATUS REQUESTED:\n", LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] PDU OUT OF RX WINDOW, DISCARDED, STATUS REQUESTED:\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP)); PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
rlc_pP->status_requested = 1;
} }
/* 3) Check for triggering a Tx Status PDU if a poll is received or if a pending status was delayed */
if (pdu_info_p->p) {
LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT"[PROCESS RX PDU] POLL BIT SET, STATUS REQUESTED:\n",
PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP));
/* Polling Info Saving for In and Out of Window PDU */
/* avoid multi status trigger */
if ((RLC_AM_GET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED)) ||
!(RLC_AM_GET_STATUS(rlc_pP->status_requested,(RLC_AM_STATUS_TRIGGERED_POLL | RLC_AM_STATUS_TRIGGERED_T_REORDERING))))
{
RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_POLL);
if ((pdu_status != RLC_AM_DATA_PDU_STATUS_OK) || ((pdu_status == RLC_AM_DATA_PDU_STATUS_OK) &&
(!(RLC_AM_SN_IN_WINDOW(pdu_info_p->sn,rlc_pP->vr_r)) ||
(RLC_AM_DIFF_SN(pdu_info_p->sn,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r)))
)
)
{
/* Conditions are met for sending a Status Report */
/* Then clear Delay Flag and reset its corresponding sn */
RLC_AM_CLEAR_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED);
rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED;
}
else if (rlc_pP->sn_status_triggered_delayed == RLC_SN_UNDEFINED)
{
/* Delay status trigger if pdustatus OK and sn>= vr_ms */
/* Note: vr_r and vr_ms have been updated */
RLC_AM_SET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED);
rlc_pP->sn_status_triggered_delayed = pdu_info_p->sn;
}
}
}
/* ReEnable a previously delayed Status Trigger if PDU discarded or */
/* sn no more in RxWindow due to RxWindow advance or sn < vr_ms */
if ((RLC_AM_GET_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED)) &&
(pdu_status == RLC_AM_DATA_PDU_STATUS_OK) &&
(!(RLC_AM_SN_IN_WINDOW(rlc_pP->sn_status_triggered_delayed,rlc_pP->vr_r)) ||
(RLC_AM_DIFF_SN(rlc_pP->sn_status_triggered_delayed,rlc_pP->vr_r) < RLC_AM_DIFF_SN(rlc_pP->vr_ms,rlc_pP->vr_r)))
)
{
RLC_AM_CLEAR_STATUS(rlc_pP->status_requested,RLC_AM_STATUS_TRIGGERED_DELAYED);
rlc_pP->sn_status_triggered_delayed = RLC_SN_UNDEFINED;
}
} else { } else {
pdu_status = RLC_AM_DATA_PDU_STATUS_HEADER_ERROR;
}
if (pdu_status != RLC_AM_DATA_PDU_STATUS_OK) {
/* Discard received block if out of window, duplicate or header error */
free_mem_block (tb_pP, __func__); free_mem_block (tb_pP, __func__);
} }
else if (reassemble) {
/* Reassemble SDUs */
rlc_am_rx_list_reassemble_rlc_sdus(ctxt_pP, rlc_pP);
}
} }
...@@ -49,6 +49,10 @@ rlc_am_rx_list_insert_pdu( ...@@ -49,6 +49,10 @@ rlc_am_rx_list_insert_pdu(
cursor_p = rlc_pP->receiver_buffer.head; cursor_p = rlc_pP->receiver_buffer.head;
// it is assumed this pdu is in rx window // it is assumed this pdu is in rx window
//TODO : check for duplicate
// should be rewrite
/* look for previous SN */
if (cursor_p) { if (cursor_p) {
if (rlc_pP->vr_mr < rlc_pP->vr_r) { if (rlc_pP->vr_mr < rlc_pP->vr_r) {
if (pdu_info_p->sn >= rlc_pP->vr_r) { if (pdu_info_p->sn >= rlc_pP->vr_r) {
......
...@@ -474,7 +474,7 @@ rlc_am_send_status_pdu( ...@@ -474,7 +474,7 @@ rlc_am_send_status_pdu(
pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info; pdu_info_cursor_p = &((rlc_am_rx_pdu_management_t*)(cursor_p->data))->pdu_info;
sn_cursor = pdu_info_cursor_p->sn; sn_cursor = pdu_info_cursor_p->sn;
while (rlc_am_in_rx_window(ctxt_pP, rlc_pP, sn_cursor) == 0) { while (!(RLC_AM_SN_IN_WINDOW(sn_cursor, rlc_pP->vr_r))) {
cursor_p = cursor_p->next; cursor_p = cursor_p->next;
previous_sn_cursor = sn_cursor; previous_sn_cursor = sn_cursor;
......
...@@ -236,6 +236,28 @@ typedef struct rlc_am_rx_pdu_management { ...@@ -236,6 +236,28 @@ typedef struct rlc_am_rx_pdu_management {
uint8_t all_segments_received; /*!< \brief Is all segments of PDU SN have been received. */ uint8_t all_segments_received; /*!< \brief Is all segments of PDU SN have been received. */
} rlc_am_rx_pdu_management_t; } rlc_am_rx_pdu_management_t;
/** @} */ /** @} */
typedef enum rlc_am_rx_pdu_status
{
/** PDU okay. */
RLC_AM_DATA_PDU_STATUS_OK = 0,
/** SN outside RX window */
RLC_AM_DATA_PDU_STATUS_SN_OUTSIDE_WINDOW = 1,
/** SN already available */
RLC_AM_DATA_PDU_STATUS_SN_DUPLICATE = 2,
/** SN already available */
RLC_AM_DATA_PDU_STATUS_AM_SEGMENT_DUPLICATE = 3,
/** Buffer full */
RLC_AM_DATA_PDU_STATUS_BUFFER_FULL = 4,
/** Header Error (LI,SO...) */
RLC_AM_DATA_PDU_STATUS_HEADER_ERROR = 5,
/** Unknown bearer */
RLC_AM_DATA_PDU_STATUS_INVALID_BEARER = 6,
/** RLC in wrong state */
RLC_AM_DATA_PDU_STATUS_WRONG_STATE = 7
} rlc_am_rx_pdu_status_t;
/*! \cond PRIVATE */ /*! \cond PRIVATE */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// interlayers optimizations // interlayers optimizations
......
...@@ -64,6 +64,7 @@ enum RLC_OPERATION_MODE { TRANSMITTER_ONLY = 0x00, ...@@ -64,6 +64,7 @@ enum RLC_OPERATION_MODE { TRANSMITTER_ONLY = 0x00,
// dimensions // dimensions
# define SN_12BITS_MASK 0x0FFF # define SN_12BITS_MASK 0x0FFF
# define RLC_SN_OVERFLOW 0xFFFF # define RLC_SN_OVERFLOW 0xFFFF
# define RLC_SN_UNDEFINED RLC_SN_OVERFLOW
//---------------------------------------------------------- //----------------------------------------------------------
// DISCARD // DISCARD
//---------------------------------------------------------- //----------------------------------------------------------
......
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