rlc_am.c 58.7 KB
Newer Older
1 2 3 4 5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
Cedric Roux's avatar
Cedric Roux committed
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
gauthier's avatar
gauthier committed
21

22 23
#define RLC_AM_MODULE 1
#define RLC_AM_C 1
24 25 26 27
//-----------------------------------------------------------------------------
#include "platform_types.h"
#include "platform_constants.h"
//-----------------------------------------------------------------------------
28

29
#include "assertions.h"
knopp's avatar
knopp committed
30
#include "msc.h"
31
#include "hashtable.h"
32 33 34 35 36 37
#include "rlc_am.h"
#include "rlc_am_segment.h"
#include "rlc_am_timer_poll_retransmit.h"
#include "mac_primitives.h"
#include "rlc_primitives.h"
#include "list.h"
38
#include "LAYER2/MAC/mac_extern.h"
39
#include "common/utils/LOG/log.h"
40 41
#include "LTE_UL-AM-RLC.h"
#include "LTE_DL-AM-RLC.h"
42

gauthier's avatar
gauthier committed
43

fnabet's avatar
fnabet committed
44 45 46
//-----------------------------------------------------------------------------
uint32_t
rlc_am_get_status_pdu_buffer_occupancy(
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
  rlc_am_entity_t *const      rlc_pP) {
  //Compute Max Status PDU size according to what has been received and not received in the window [vrR vrMS[
  // minimum header size in bits to be transmitted: D/C + CPT + ACK_SN + E1
  uint32_t                    nb_bits_to_transmit   = RLC_AM_PDU_D_C_BITS + RLC_AM_STATUS_PDU_CPT_LENGTH + RLC_AM_SN_BITS + RLC_AM_PDU_E_BITS;
  mem_block_t                  *cursor_p              = rlc_pP->receiver_buffer.head;
  rlc_am_pdu_info_t            *pdu_info_cursor_p     = NULL;
  int                           waited_so             = 0;
  rlc_sn_t sn_cursor = rlc_pP->vr_r;
  rlc_sn_t sn_prev = rlc_pP->vr_r;
  rlc_sn_t sn_end = rlc_pP->vr_ms;
  boolean_t segment_loop_end    = false;

  if (sn_prev != sn_end) {
    while ((RLC_AM_DIFF_SN(sn_prev,rlc_pP->vr_r) < RLC_AM_DIFF_SN(sn_end,rlc_pP->vr_r)) && (cursor_p != NULL)) {
      pdu_info_cursor_p     = &((rlc_am_rx_pdu_management_t *)(cursor_p->data))->pdu_info;
      sn_cursor             = pdu_info_cursor_p->sn;

      // Add holes between sn_prev and sn_cursor
      while ((sn_prev != sn_cursor) && (sn_prev != sn_end)) {
        /* Add 1 NACK_SN + E1 + E2 */
        nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1));
        sn_prev = RLC_AM_NEXT_SN(sn_prev);
      } //end while (sn_prev != sn_cursor)

      /* Handle case sn_cursor is partially received */
      /* Each gap will add NACK_SN + E1 + E2 + SOStart + SOEnd */
      if ((((rlc_am_rx_pdu_management_t *)(cursor_p->data))->all_segments_received == 0) && (RLC_AM_DIFF_SN(sn_cursor,rlc_pP->vr_r) < RLC_AM_DIFF_SN(sn_end,rlc_pP->vr_r))) {
        /* Check lsf */
        segment_loop_end = (pdu_info_cursor_p->lsf == 1);

        /* Fill for [0 SO[ if SO not null */
        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;
        } 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) {
          if ((cursor_p != NULL) && (pdu_info_cursor_p->sn == sn_cursor)) {
            /* Check lsf */
            segment_loop_end = (pdu_info_cursor_p->lsf == 1);

            if (waited_so < 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));
            } else {
              /* contiguous segment: only update waited_so */
              /* Assuming so and payload_size updated according to duplication removal done at reception ... */
              waited_so += pdu_info_cursor_p->payload_size;
            }

            /* Go to next received PDU or PDU 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 {
            /* Fill last gap assuming LSF is not received */
            nb_bits_to_transmit += (RLC_AM_SN_BITS + (RLC_AM_PDU_E_BITS << 1) + (RLC_AM_STATUS_PDU_SO_LENGTH << 1));
            segment_loop_end = true;
          }
        } // end while (!segment_loop_end)
      } // end if segments
      else {
        /* Go to next received PDU or PDU segment with different SN */
        do {
          cursor_p = cursor_p->next;
        } while ((cursor_p != NULL) && (((rlc_am_rx_pdu_management_t *)(cursor_p->data))->pdu_info.sn == sn_cursor));
      }
125

126 127 128
      sn_prev = RLC_AM_NEXT_SN(sn_cursor);
    }
  } // end if (sn_prev != sn_end)
fnabet's avatar
fnabet committed
129

130 131
  // round up to the greatest byte
  return ((nb_bits_to_transmit + 7) >> 3);
fnabet's avatar
fnabet committed
132 133
}

134
//-----------------------------------------------------------------------------
135
uint32_t
136
rlc_am_get_buffer_occupancy_in_bytes (
137 138
  const protocol_ctxt_t *const ctxt_pP,
  rlc_am_entity_t *const      rlc_pP) {
139
  // priority of control trafic
Bilel's avatar
Bilel committed
140
  rlc_pP->status_buffer_occupancy = 0;
141

142 143 144 145 146
  if ((rlc_pP->status_requested) && !(rlc_pP->status_requested & RLC_AM_STATUS_NO_TX_MASK)) {
    rlc_pP->status_buffer_occupancy = rlc_am_get_status_pdu_buffer_occupancy(rlc_pP);
    LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" BO : CONTROL PDU %d bytes \n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
          rlc_pP->status_buffer_occupancy);
147 148
  }

149 150 151 152 153 154 155 156 157 158 159
  if ( LOG_DEBUGFLAG(DEBUG_RLC)) {
    if ((rlc_pP->status_buffer_occupancy + rlc_pP->retrans_num_bytes_to_retransmit + rlc_pP->sdu_buffer_occupancy ) > 0) {
      LOG_UI(RLC, PROTOCOL_RLC_AM_CTXT_FMT" BO : STATUS  BUFFER %d bytes \n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->status_buffer_occupancy);
      LOG_UI(RLC, PROTOCOL_RLC_AM_CTXT_FMT" BO : RETRANS BUFFER %d bytes \n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP), rlc_pP->retrans_num_bytes_to_retransmit);
      LOG_UI(RLC, PROTOCOL_RLC_AM_CTXT_FMT" BO : SDU	BUFFER %d bytes + li_overhead %d bytes header_overhead %d bytes (nb sdu not segmented %d)\n",
             PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
             rlc_pP->sdu_buffer_occupancy,
             0,
             0,
             rlc_pP->nb_sdu_no_segmented);
    }
160
  }
161

162
  return rlc_pP->status_buffer_occupancy + rlc_pP->retrans_num_bytes_to_retransmit + rlc_pP->sdu_buffer_occupancy;
163 164
}
//-----------------------------------------------------------------------------
165 166
void
rlc_am_release (
167 168 169
  const protocol_ctxt_t *const ctxt_pP,
  rlc_am_entity_t *const      rlc_pP
) {
170
  // empty
171 172
}
//-----------------------------------------------------------------------------
173 174
void
config_req_rlc_am (
175
  const protocol_ctxt_t *const ctxt_pP,
176
  const srb_flag_t             srb_flagP,
177
  const rlc_am_info_t         *config_am_pP,
178
  const rb_id_t                rb_idP,
179 180
  const logical_chan_id_t      chan_idP
) {
181 182
  rlc_union_t       *rlc_union_p = NULL;
  rlc_am_entity_t *l_rlc_p         = NULL;
183
  hash_key_t       key           = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
184
  hashtable_rc_t   h_rc;
185
  h_rc = hashtable_get(rlc_coll_p, key, (void **)&rlc_union_p);
186 187 188 189

  if (h_rc == HASH_TABLE_OK) {
    l_rlc_p = &rlc_union_p->rlc.am;
    LOG_D(RLC,
190 191
          PROTOCOL_RLC_AM_CTXT_FMT" CONFIG_REQ (max_retx_threshold=%d poll_pdu=%d poll_byte=%d t_poll_retransmit=%d t_reord=%d t_status_prohibit=%d)\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p),
192 193 194 195 196 197 198
          config_am_pP->max_retx_threshold,
          config_am_pP->poll_pdu,
          config_am_pP->poll_byte,
          config_am_pP->t_poll_retransmit,
          config_am_pP->t_reordering,
          config_am_pP->t_status_prohibit);
    rlc_am_init(ctxt_pP, l_rlc_p);
199
    rlc_am_set_debug_infos(ctxt_pP, l_rlc_p, srb_flagP, rb_idP, chan_idP);
200 201 202 203 204 205 206 207
    rlc_am_configure(ctxt_pP, l_rlc_p,
                     config_am_pP->max_retx_threshold,
                     config_am_pP->poll_pdu,
                     config_am_pP->poll_byte,
                     config_am_pP->t_poll_retransmit,
                     config_am_pP->t_reordering,
                     config_am_pP->t_status_prohibit);
  } else {
208 209
    LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" CONFIG_REQ RLC NOT FOUND\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p));
210
  }
211
}
212 213 214 215 216
uint16_t pollPDU_tab[LTE_PollPDU_pInfinity+1]= {4,8,16,32,64,128,256,RLC_AM_POLL_PDU_INFINITE}; //PollPDU_pInfinity is chosen to 0xFFFF for now
uint32_t maxRetxThreshold_tab[LTE_UL_AM_RLC__maxRetxThreshold_t32+1]= {1,2,3,4,6,8,16,32};
uint32_t pollByte_tab[LTE_PollByte_spare1]= {25000,50000,75000,100000,125000,250000,375000,500000,750000,1000000,1250000,1500000,2000000,3000000,RLC_AM_POLL_BYTE_INFINITE}; // PollByte_kBinfinity is chosen to 0xFFFFFFFF for now
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
uint32_t PollRetransmit_tab[LTE_T_PollRetransmit_spare5]= {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500,800,1000,2000,4000};
Cedric Roux's avatar
Cedric Roux committed
217
uint32_t am_t_Reordering_tab[32]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200,1600};
218
uint32_t t_StatusProhibit_tab[LTE_T_StatusProhibit_spare2]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500,800,1000,1200,1600,2000,2400};
Cedric Roux's avatar
Cedric Roux committed
219
#else
220 221 222
uint32_t PollRetransmit_tab[LTE_T_PollRetransmit_spare9]= {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500};
uint32_t am_t_Reordering_tab[LTE_T_Reordering_spare1]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200};
uint32_t t_StatusProhibit_tab[LTE_T_StatusProhibit_spare8]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500};
Cedric Roux's avatar
Cedric Roux committed
223
#endif
224 225

//-----------------------------------------------------------------------------
226
void config_req_rlc_am_asn1 (
227
  const protocol_ctxt_t *const         ctxt_pP,
228
  const srb_flag_t                     srb_flagP,
229
  const struct LTE_RLC_Config__am   *const config_am_pP,
230
  const rb_id_t                        rb_idP,
231
  const logical_chan_id_t              chan_idP) {
232
  rlc_union_t     *rlc_union_p   = NULL;
gauthier's avatar
gauthier committed
233
  rlc_am_entity_t *l_rlc_p         = NULL;
234
  hash_key_t       key           = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
235
  hashtable_rc_t   h_rc;
236
  h_rc = hashtable_get(rlc_coll_p, key, (void **)&rlc_union_p);
237

238
  if (h_rc == HASH_TABLE_OK) {
239 240
    l_rlc_p = &rlc_union_p->rlc.am;

241 242 243 244 245
    if ((config_am_pP->ul_AM_RLC.maxRetxThreshold <= LTE_UL_AM_RLC__maxRetxThreshold_t32) &&
        (config_am_pP->ul_AM_RLC.pollPDU<=LTE_PollPDU_pInfinity) &&
        (config_am_pP->ul_AM_RLC.pollByte<LTE_PollByte_spare1) &&
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
        (config_am_pP->ul_AM_RLC.t_PollRetransmit<LTE_T_PollRetransmit_spare5) &&
Cedric Roux's avatar
Cedric Roux committed
246
        (config_am_pP->dl_AM_RLC.t_Reordering<32) &&
247
        (config_am_pP->dl_AM_RLC.t_StatusProhibit<LTE_T_StatusProhibit_spare2) ) {
Cedric Roux's avatar
Cedric Roux committed
248
#else
249 250 251
        (config_am_pP->ul_AM_RLC.t_PollRetransmitLTE_T_PollRetransmit_spare9) &&
        (config_am_pP->dl_AM_RLC.t_Reordering<LTE_T_Reordering_spare1) &&
        (config_am_pP->dl_AM_RLC.t_StatusProhibit<LTE_T_StatusProhibit_spare8) ) {
Cedric Roux's avatar
Cedric Roux committed
252
#endif
253
      MSC_LOG_RX_MESSAGE(
254 255 256 257 258 259 260 261 262 263 264 265
        (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
        (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RRC_ENB:MSC_RRC_UE,
        NULL,
        0,
        MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" CONFIG-REQ t_PollRetx %u t_Reord %u t_StatusPro %u",
        MSC_AS_TIME_ARGS(ctxt_pP),
        PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, l_rlc_p),
        PollRetransmit_tab[config_am_pP->ul_AM_RLC.t_PollRetransmit],
        am_t_Reordering_tab[config_am_pP->dl_AM_RLC.t_Reordering],
        t_StatusProhibit_tab[config_am_pP->dl_AM_RLC.t_StatusProhibit]);
      LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" CONFIG_REQ (max_retx_threshold=%d poll_pdu=%d poll_byte=%d t_poll_retransmit=%d t_reord=%d t_status_prohibit=%d)\n",
            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p),
266 267 268 269 270 271 272
            maxRetxThreshold_tab[config_am_pP->ul_AM_RLC.maxRetxThreshold],
            pollPDU_tab[config_am_pP->ul_AM_RLC.pollPDU],
            pollByte_tab[config_am_pP->ul_AM_RLC.pollByte],
            PollRetransmit_tab[config_am_pP->ul_AM_RLC.t_PollRetransmit],
            am_t_Reordering_tab[config_am_pP->dl_AM_RLC.t_Reordering],
            t_StatusProhibit_tab[config_am_pP->dl_AM_RLC.t_StatusProhibit]);
      rlc_am_init(ctxt_pP, l_rlc_p);
273
      rlc_am_set_debug_infos(ctxt_pP, l_rlc_p, srb_flagP, rb_idP, chan_idP);
274 275 276 277 278 279 280
      rlc_am_configure(ctxt_pP, l_rlc_p,
                       maxRetxThreshold_tab[config_am_pP->ul_AM_RLC.maxRetxThreshold],
                       pollPDU_tab[config_am_pP->ul_AM_RLC.pollPDU],
                       pollByte_tab[config_am_pP->ul_AM_RLC.pollByte],
                       PollRetransmit_tab[config_am_pP->ul_AM_RLC.t_PollRetransmit],
                       am_t_Reordering_tab[config_am_pP->dl_AM_RLC.t_Reordering],
                       t_StatusProhibit_tab[config_am_pP->dl_AM_RLC.t_StatusProhibit]);
281 282
    }
    else {
283
      MSC_LOG_RX_DISCARDED_MESSAGE(
284 285 286 287 288 289 290
        (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
        (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RRC_ENB:MSC_RRC_UE,
        NULL,
        0,
        MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" CONFIG-REQ",
        MSC_AS_TIME_ARGS(ctxt_pP),
        PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, l_rlc_p));
291
      LOG_D(RLC,
Cedric Roux's avatar
Cedric Roux committed
292
            PROTOCOL_RLC_AM_CTXT_FMT"ILLEGAL CONFIG_REQ (max_retx_threshold=%ld poll_pdu=%ld poll_byte=%ld t_poll_retransmit=%ld t_reord=%ld t_status_prohibit=%ld), RLC-AM NOT CONFIGURED\n",
293
            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p),
294 295 296 297 298 299 300
            config_am_pP->ul_AM_RLC.maxRetxThreshold,
            config_am_pP->ul_AM_RLC.pollPDU,
            config_am_pP->ul_AM_RLC.pollByte,
            config_am_pP->ul_AM_RLC.t_PollRetransmit,
            config_am_pP->dl_AM_RLC.t_Reordering,
            config_am_pP->dl_AM_RLC.t_StatusProhibit);
    }
301
  } else {
302 303
    LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT"CONFIG_REQ RLC NOT FOUND\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p));
304
  }
305 306
}

307
//-----------------------------------------------------------------------------
308
void rlc_am_stat_req (
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
  const protocol_ctxt_t *const         ctxt_pP,
  rlc_am_entity_t *const              rlc_pP,
  unsigned int *stat_tx_pdcp_sdu,
  unsigned int *stat_tx_pdcp_bytes,
  unsigned int *stat_tx_pdcp_sdu_discarded,
  unsigned int *stat_tx_pdcp_bytes_discarded,
  unsigned int *stat_tx_data_pdu,
  unsigned int *stat_tx_data_bytes,
  unsigned int *stat_tx_retransmit_pdu_by_status,
  unsigned int *stat_tx_retransmit_bytes_by_status,
  unsigned int *stat_tx_retransmit_pdu,
  unsigned int *stat_tx_retransmit_bytes,
  unsigned int *stat_tx_control_pdu,
  unsigned int *stat_tx_control_bytes,
  unsigned int *stat_rx_pdcp_sdu,
  unsigned int *stat_rx_pdcp_bytes,
  unsigned int *stat_rx_data_pdus_duplicate,
  unsigned int *stat_rx_data_bytes_duplicate,
  unsigned int *stat_rx_data_pdu,
  unsigned int *stat_rx_data_bytes,
  unsigned int *stat_rx_data_pdu_dropped,
  unsigned int *stat_rx_data_bytes_dropped,
  unsigned int *stat_rx_data_pdu_out_of_window,
  unsigned int *stat_rx_data_bytes_out_of_window,
  unsigned int *stat_rx_control_pdu,
  unsigned int *stat_rx_control_bytes,
  unsigned int *stat_timer_reordering_timed_out,
  unsigned int *stat_timer_poll_retransmit_timed_out,
  unsigned int *stat_timer_status_prohibit_timed_out) {
338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
  *stat_tx_pdcp_sdu                     = rlc_pP->stat_tx_pdcp_sdu;
  *stat_tx_pdcp_bytes                   = rlc_pP->stat_tx_pdcp_bytes;
  *stat_tx_pdcp_sdu_discarded           = rlc_pP->stat_tx_pdcp_sdu_discarded;
  *stat_tx_pdcp_bytes_discarded         = rlc_pP->stat_tx_pdcp_bytes_discarded;
  *stat_tx_data_pdu                     = rlc_pP->stat_tx_data_pdu;
  *stat_tx_data_bytes                   = rlc_pP->stat_tx_data_bytes;
  *stat_tx_retransmit_pdu_by_status     = rlc_pP->stat_tx_retransmit_pdu_by_status;
  *stat_tx_retransmit_bytes_by_status   = rlc_pP->stat_tx_retransmit_bytes_by_status;
  *stat_tx_retransmit_pdu               = rlc_pP->stat_tx_retransmit_pdu;
  *stat_tx_retransmit_bytes             = rlc_pP->stat_tx_retransmit_bytes;
  *stat_tx_control_pdu                  = rlc_pP->stat_tx_control_pdu;
  *stat_tx_control_bytes                = rlc_pP->stat_tx_control_bytes;
  *stat_rx_pdcp_sdu                     = rlc_pP->stat_rx_pdcp_sdu;
  *stat_rx_pdcp_bytes                   = rlc_pP->stat_rx_pdcp_bytes;
  *stat_rx_data_pdus_duplicate          = rlc_pP->stat_rx_data_pdus_duplicate;
  *stat_rx_data_bytes_duplicate         = rlc_pP->stat_rx_data_bytes_duplicate;
  *stat_rx_data_pdu                     = rlc_pP->stat_rx_data_pdu;
  *stat_rx_data_bytes                   = rlc_pP->stat_rx_data_bytes;
  *stat_rx_data_pdu_dropped             = rlc_pP->stat_rx_data_pdu_dropped;
  *stat_rx_data_bytes_dropped           = rlc_pP->stat_rx_data_bytes_dropped;
  *stat_rx_data_pdu_out_of_window       = rlc_pP->stat_rx_data_pdu_out_of_window;
  *stat_rx_data_bytes_out_of_window     = rlc_pP->stat_rx_data_bytes_out_of_window;
  *stat_rx_control_pdu                  = rlc_pP->stat_rx_control_pdu;
  *stat_rx_control_bytes                = rlc_pP->stat_rx_control_bytes;
  *stat_timer_reordering_timed_out      = rlc_pP->stat_timer_reordering_timed_out;
  *stat_timer_poll_retransmit_timed_out = rlc_pP->stat_timer_poll_retransmit_timed_out;
  *stat_timer_status_prohibit_timed_out = rlc_pP->stat_timer_status_prohibit_timed_out;
365 366 367
}
//-----------------------------------------------------------------------------
void
368
rlc_am_get_pdus (
369 370 371
  const protocol_ctxt_t *const ctxt_pP,
  rlc_am_entity_t *const      rlc_pP
) {
372
  //int display_flag = 0;
373 374 375 376 377 378
  // 5.1.3.1 Transmit operations
  // 5.1.3.1.1
  // General
  // The transmitting side of an AM RLC entity shall prioritize transmission of RLC control PDUs over RLC data PDUs.
  // The transmitting side of an AM RLC entity shall prioritize retransmission of RLC data PDUs over transmission of new
  // AMD PDUs.
379
  switch (rlc_pP->protocol_state) {
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
    case RLC_NULL_STATE:
      break;

    case RLC_DATA_TRANSFER_READY_STATE:

      // TRY TO SEND CONTROL PDU FIRST
      if ((rlc_pP->nb_bytes_requested_by_mac >= 2) &&
          ((rlc_pP->status_requested) && !(rlc_pP->status_requested & RLC_AM_STATUS_NO_TX_MASK))) {
        // When STATUS reporting has been triggered, the receiving side of an AM RLC entity shall:
        // - if t-StatusProhibit is not running:
        //     - at the first transmission opportunity indicated by lower layer, construct a STATUS PDU and deliver it to lower layer;
        // - else:
        //     - at the first transmission opportunity indicated by lower layer after t-StatusProhibit expires, construct a single
        //       STATUS PDU even if status reporting was triggered several times while t-StatusProhibit was running and
        //       deliver it to lower layer;
        //
        // When a STATUS PDU has been delivered to lower layer, the receiving side of an AM RLC entity shall:
        //     - start t-StatusProhibit.
398
        rlc_am_send_status_pdu(ctxt_pP, rlc_pP);
399
        mem_block_t *pdu = list_remove_head(&rlc_pP->control_pdu_list);
400

401 402
        if (pdu) {
          list_add_tail_eurecom (pdu, &rlc_pP->pdus_to_mac_layer);
403
          RLC_AM_CLEAR_ALL_STATUS(rlc_pP->status_requested);
Bilel's avatar
Bilel committed
404
          rlc_pP->status_buffer_occupancy = 0;
405 406 407
          rlc_am_start_timer_status_prohibit(ctxt_pP, rlc_pP);
          return;
        }
408 409
      } else {
        LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" DELAYED SENT STATUS PDU (Available MAC Data %u)(T-PROHIBIT %u) (DELAY FLAG %u)\n",
fnabet's avatar
fnabet committed
410
              PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
411 412
              rlc_pP->nb_bytes_requested_by_mac,rlc_pP->t_status_prohibit.ms_time_out,(rlc_pP->status_requested & RLC_AM_STATUS_TRIGGERED_DELAYED));
      }
413

414
      // THEN TRY TO SEND RETRANS PDU
415
      if ((rlc_pP->retrans_num_bytes_to_retransmit) && (rlc_pP->nb_bytes_requested_by_mac > 2)) {
416 417
        /* Get 1 AM data PDU or PDU segment to retransmit */
        mem_block_t *pdu_retx = rlc_am_get_pdu_to_retransmit(ctxt_pP, rlc_pP);
418

419 420
        if (pdu_retx != NULL) {
          list_add_tail_eurecom (pdu_retx, &rlc_pP->pdus_to_mac_layer);
421
          return;
fnabet's avatar
fnabet committed
422
        }
423
      }
424

425 426 427 428
      // THEN TRY TO SEND NEW DATA PDU
      if ((rlc_pP->nb_bytes_requested_by_mac > 2) && (rlc_pP->sdu_buffer_occupancy) && (rlc_pP->vt_s != rlc_pP->vt_ms)) {
        rlc_am_segment_10(ctxt_pP, rlc_pP);
        list_add_list (&rlc_pP->segmentation_pdu_list, &rlc_pP->pdus_to_mac_layer);
429

430 431 432 433 434
        if (rlc_pP->pdus_to_mac_layer.head != NULL) {
          rlc_pP->stat_tx_data_pdu                   += 1;
          rlc_pP->stat_tx_data_bytes                 += (((struct mac_tb_req *)(rlc_pP->pdus_to_mac_layer.head->data))->tb_size);
          return;
        }
435 436
      }

437
      break;
438

439 440 441 442
    default:
      LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" MAC_DATA_REQ UNKNOWN PROTOCOL STATE 0x%02X\n",
            PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc_pP),
            rlc_pP->protocol_state);
443
  }
444 445 446
}
//-----------------------------------------------------------------------------
void
447
rlc_am_rx (
448 449
  const protocol_ctxt_t *const ctxt_pP,
  void *const                 arg_pP,
450
  struct mac_data_ind          data_indP
451
) {
gauthier's avatar
gauthier committed
452
  rlc_am_entity_t *rlc = (rlc_am_entity_t *) arg_pP;
453 454

  switch (rlc->protocol_state) {
455 456 457 458 459 460 461 462 463 464 465 466
    case RLC_NULL_STATE:
      LOG_I(RLC, PROTOCOL_RLC_AM_CTXT_FMT" ERROR MAC_DATA_IND IN RLC_NULL_STATE\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP, rlc));
      list_free (&data_indP.data);
      break;

    case RLC_DATA_TRANSFER_READY_STATE:
      rlc_am_receive_routing (ctxt_pP, rlc, data_indP);
      break;

    default:
      LOG_E(RLC, PROTOCOL_RLC_AM_CTXT_FMT" TX UNKNOWN PROTOCOL STATE 0x%02X\n", PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP, rlc), rlc->protocol_state);
      list_free (&data_indP.data);
467 468 469 470 471
  }
}

//-----------------------------------------------------------------------------
struct mac_status_resp
472
rlc_am_mac_status_indication (
473 474
  const protocol_ctxt_t *const ctxt_pP,
  void *const                 rlc_pP,
475
  const uint16_t               tb_sizeP,
476
  struct mac_status_ind        tx_statusP,
477
  const eNB_flag_t enb_flagP) {
478
  struct mac_status_resp  status_resp;
479 480 481
  uint16_t  sdu_size = 0;
  uint16_t  sdu_remaining_size = 0;
  int32_t diff_time=0;
gauthier's avatar
gauthier committed
482
  rlc_am_entity_t *rlc = (rlc_am_entity_t *) rlc_pP;
483 484 485 486 487
  status_resp.buffer_occupancy_in_bytes        = 0;
  status_resp.buffer_occupancy_in_pdus         = 0;
  status_resp.head_sdu_remaining_size_to_send  = 0;
  status_resp.head_sdu_creation_time           = 0;
  status_resp.head_sdu_is_segmented            = 0;
488 489
  status_resp.rlc_info.rlc_protocol_state = rlc->protocol_state;

Cedric Roux's avatar
Cedric Roux committed
490 491 492 493 494 495 496 497 498
  /* TODO: remove this hack. Problem is: there is a race.
   * UE comes. SRB2 is configured via message to RRC.
   * At some point the RLC AM is created but not configured yet.
   * At this moment (I think) MAC calls mac_rlc_status_ind
   * which calls this function. But the init was not finished yet
   * and we have a crash below when testing mem_block != NULL.
   */
  if (rlc->input_sdus == NULL) return status_resp;

499
  if (rlc->last_absolute_subframe_status_indication != (PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP))) {
500 501 502
    rlc_am_check_timer_poll_retransmit(ctxt_pP, rlc);
    rlc_am_check_timer_reordering(ctxt_pP, rlc);
    rlc_am_check_timer_status_prohibit(ctxt_pP, rlc);
503
  }
504

505
  rlc->last_absolute_subframe_status_indication = PROTOCOL_CTXT_TIME_MILLI_SECONDS(ctxt_pP);
506

507 508 509
  if (tb_sizeP > 0) {
    rlc->nb_bytes_requested_by_mac = tb_sizeP;
  }
510

511
  status_resp.buffer_occupancy_in_bytes = rlc_am_get_buffer_occupancy_in_bytes(ctxt_pP, rlc);
512

513 514 515
  // For eNB scheduler : Add Max RLC header size for new PDU
  // For UE : do not add RLC header part to be compliant with BSR definition in 36.321
  if (enb_flagP == ENB_FLAG_YES) {
516 517
    uint32_t max_li_overhead = 0;
    uint32_t header_overhead = 0;
518

519 520 521 522 523
    if (rlc->nb_sdu_no_segmented > 1) {
      /* This computation assumes there is no SDU with size greater than 2047 bytes, otherwise a new PDU must be built except for LI15 configuration from Rel12*/
      uint32_t num_li = rlc->nb_sdu_no_segmented - 1;
      max_li_overhead = num_li + (num_li >> 1) + (num_li & 1);
    }
524

525 526 527
    if (rlc->sdu_buffer_occupancy > 0) {
      header_overhead = 2;
    }
528

529
    status_resp.buffer_occupancy_in_bytes += (header_overhead + max_li_overhead);
530 531
  }

532
  if ((rlc->input_sdus[rlc->current_sdu_index].mem_block != NULL) && (status_resp.buffer_occupancy_in_bytes)) {
533 534 535 536 537 538 539 540 541 542 543 544 545
    //status_resp.buffer_occupancy_in_bytes += ((rlc_am_entity_t *) rlc)->tx_header_min_length_in_bytes;
    status_resp.buffer_occupancy_in_pdus = rlc->nb_sdu;
    diff_time =   ctxt_pP->frame - ((rlc_am_tx_sdu_management_t *) (rlc->input_sdus[rlc->current_sdu_index].mem_block->data))->sdu_creation_time;
    status_resp.head_sdu_creation_time = (diff_time > 0 ) ? (uint32_t) diff_time :  (uint32_t)(0xffffffff - diff_time + ctxt_pP->frame) ;
    sdu_size            = ((rlc_am_tx_sdu_management_t *) (rlc->input_sdus[rlc->current_sdu_index].mem_block->data))->sdu_size;
    sdu_remaining_size  = ((rlc_am_tx_sdu_management_t *) (rlc->input_sdus[rlc->current_sdu_index].mem_block->data))->sdu_remaining_size;
    status_resp.head_sdu_remaining_size_to_send = sdu_remaining_size;

    if (sdu_size == sdu_remaining_size)  {
      status_resp.head_sdu_is_segmented = 0;
    } else {
      status_resp.head_sdu_is_segmented = 1;
    }
546
  } else {
547 548 549 550 551 552 553 554 555 556
    /* Not so many possibilities ... */
    /* either buffer_occupancy_in_bytes = 0 and that's it */
    /* or we have segmented all received SDUs and buffer occupancy is then made of retransmissions and/or status pdu pending */
    /* then consider only retransmission buffer for the specific BO values used by eNB scheduler (not used up to now...) */
    if (rlc->retrans_num_bytes_to_retransmit) {
      status_resp.buffer_occupancy_in_pdus = rlc->retrans_num_pdus;
      status_resp.head_sdu_remaining_size_to_send = rlc->retrans_num_bytes_to_retransmit;
      status_resp.head_sdu_is_segmented = 1;
    }
  }
557

558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
  if (MESSAGE_CHART_GENERATOR) {
    MSC_LOG_RX_MESSAGE(
      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_MAC_ENB:MSC_MAC_UE,
      NULL,0,
      MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" STATUS-IND %u",
      MSC_AS_TIME_ARGS(ctxt_pP),
      PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, rlc),
      tb_sizeP);
    MSC_LOG_TX_MESSAGE(
      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_MAC_ENB:MSC_MAC_UE,
      NULL,0,
      MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" STATUS-RESP BO:%u/n%u(%u)  %s sdu remain %u",
      MSC_AS_TIME_ARGS(ctxt_pP),
      PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, rlc),
      status_resp.buffer_occupancy_in_bytes,
      status_resp.buffer_occupancy_in_pdus,rlc->nb_sdu,
      (status_resp.head_sdu_is_segmented)?"sdu seg":"sdu not seg",
      status_resp.head_sdu_remaining_size_to_send);
  }
579

580 581 582 583 584 585
  if (LOG_DEBUGFLAG(DEBUG_RLC)) {
    if (tb_sizeP > 0) {
      LOG_UI(RLC, PROTOCOL_RLC_AM_CTXT_FMT" MAC_STATUS_INDICATION (DATA) %d bytes -> %d bytes\n",
             PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,rlc),
             tb_sizeP,
             status_resp.buffer_occupancy_in_bytes);
586
    }
587
  }
588

589 590
  return status_resp;
}
591 592 593 594

//-----------------------------------------------------------------------------
void
rlc_am_set_nb_bytes_requested_by_mac (
595
  void *const            rlc_pP,
596
  const tb_size_t         tb_sizeP
597 598
) {
  ((rlc_am_entity_t *) rlc_pP)->nb_bytes_requested_by_mac = tb_sizeP;
599 600
}

601 602
//-----------------------------------------------------------------------------
struct mac_data_req
603
rlc_am_mac_data_request (
604 605
  const protocol_ctxt_t *const ctxt_pP,
  void *const                 rlc_pP,
606
  const eNB_flag_t        enb_flagP
607
) {
608
  struct mac_data_req data_req;
gauthier's avatar
gauthier committed
609 610 611 612 613
  rlc_am_entity_t *l_rlc_p = (rlc_am_entity_t *) rlc_pP;
  unsigned int nb_bytes_requested_by_mac = ((rlc_am_entity_t *) rlc_pP)->nb_bytes_requested_by_mac;
  rlc_am_pdu_info_t   pdu_info;
  rlc_am_pdu_sn_10_t *rlc_am_pdu_sn_10_p;
  mem_block_t        *tb_p;
614
  tb_size_t           tb_size_in_bytes;
gauthier's avatar
gauthier committed
615 616 617 618
  int                 num_nack;
  char                message_string[9000];
  size_t              message_string_size = 0;
  int                 octet_index, index;
Cedric Roux's avatar
Cedric Roux committed
619 620 621 622 623 624
  /* for no gcc warnings */
  (void)num_nack;
  (void)message_string;
  (void)message_string_size;
  (void)octet_index;
  (void)index;
625
  list_init (&data_req.data, NULL);
626
  rlc_am_get_pdus (ctxt_pP, l_rlc_p);
gauthier's avatar
gauthier committed
627
  list_add_list (&l_rlc_p->pdus_to_mac_layer, &data_req.data);
628

gauthier's avatar
gauthier committed
629
  //((rlc_am_entity_t *) rlc_pP)->tx_pdus += data_req.data.nb_elements;
630
  if ((nb_bytes_requested_by_mac + data_req.data.nb_elements) > 0) {
631 632
    LOG_D(RLC, PROTOCOL_RLC_AM_CTXT_FMT" MAC_DATA_REQUEST %05d BYTES REQUESTED -> %d TBs\n",
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p),
633 634
          nb_bytes_requested_by_mac,
          data_req.data.nb_elements);
635
  }
636

637
  if (enb_flagP) {
638 639
    // redundant in UE MAC Tx processing and not used in eNB ...
    data_req.buffer_occupancy_in_bytes   = rlc_am_get_buffer_occupancy_in_bytes(ctxt_pP, l_rlc_p);
640
  }
641

642
  data_req.rlc_info.rlc_protocol_state = l_rlc_p->protocol_state;
gauthier's avatar
gauthier committed
643

644
  if ( (MESSAGE_CHART_GENERATOR || LOG_DEBUGFLAG(DEBUG_RLC))&& data_req.data.nb_elements > 0) {
645
    tb_p = data_req.data.head;
gauthier's avatar
gauthier committed
646

647
    while (tb_p != NULL) {
648
      rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t *)((struct mac_tb_req *) (tb_p->data))->data_ptr;
649
      tb_size_in_bytes   = ((struct mac_tb_req *) (tb_p->data))->tb_size;
gauthier's avatar
gauthier committed
650

651
      if ((((struct mac_tb_req *) (tb_p->data))->data_ptr[0] & RLC_DC_MASK) == RLC_DC_DATA_PDU ) {
652
        if (rlc_am_get_data_pdu_infos(ctxt_pP,l_rlc_p,rlc_am_pdu_sn_10_p, tb_size_in_bytes, &pdu_info) >= 0) {
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668
          if (MESSAGE_CHART_GENERATOR) {
            message_string_size = 0;
            message_string_size += sprintf(&message_string[message_string_size],
                                           MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" DATA SN %u size %u RF %u P %u FI %u",
                                           MSC_AS_TIME_ARGS(ctxt_pP),
                                           PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, l_rlc_p),
                                           pdu_info.sn,
                                           tb_size_in_bytes,
                                           pdu_info.rf,
                                           pdu_info.p,
                                           pdu_info.fi);

            if (pdu_info.rf) {
              message_string_size += sprintf(&message_string[message_string_size], " LSF %u\n", pdu_info.lsf);
              message_string_size += sprintf(&message_string[message_string_size], " SO %u\n", pdu_info.so);
            }
669

670 671
            if (pdu_info.e) {
              message_string_size += sprintf(&message_string[message_string_size], "| HE:");
672

673 674 675
              for (index=0; index < pdu_info.num_li; index++) {
                message_string_size += sprintf(&message_string[message_string_size], " LI %u", pdu_info.li_list[index]);
              }
676 677
            }

678 679 680 681 682 683
            MSC_LOG_TX_MESSAGE(
              (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
              (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_UE:MSC_RLC_ENB,
              (char *)rlc_am_pdu_sn_10_p,
              tb_size_in_bytes,
              message_string);
684 685
          }

686 687 688 689 690 691
          if ( LOG_DEBUGFLAG(DEBUG_RLC)) {
            message_string_size = 0;
            message_string_size += sprintf(&message_string[message_string_size], "Bearer      : %u\n", l_rlc_p->rb_id);
            message_string_size += sprintf(&message_string[message_string_size], "PDU size    : %u\n", tb_size_in_bytes);
            message_string_size += sprintf(&message_string[message_string_size], "Header size : %u\n", pdu_info.header_size);
            message_string_size += sprintf(&message_string[message_string_size], "Payload size: %u\n", pdu_info.payload_size);
692

693 694 695 696 697
            if (pdu_info.rf) {
              message_string_size += sprintf(&message_string[message_string_size], "PDU type    : RLC AM DATA REQ: AMD PDU segment\n\n");
            } else {
              message_string_size += sprintf(&message_string[message_string_size], "PDU type    : RLC AM DATA REQ: AMD PDU\n\n");
            }
698

699 700 701 702 703 704 705 706 707 708 709
            message_string_size += sprintf(&message_string[message_string_size], "Header      :\n");
            message_string_size += sprintf(&message_string[message_string_size], "  D/C       : %u\n", pdu_info.d_c);
            message_string_size += sprintf(&message_string[message_string_size], "  RF        : %u\n", pdu_info.rf);
            message_string_size += sprintf(&message_string[message_string_size], "  P         : %u\n", pdu_info.p);
            message_string_size += sprintf(&message_string[message_string_size], "  FI        : %u\n", pdu_info.fi);
            message_string_size += sprintf(&message_string[message_string_size], "  E         : %u\n", pdu_info.e);
            message_string_size += sprintf(&message_string[message_string_size], "  SN        : %u\n", pdu_info.sn);

            if (pdu_info.rf) {
              message_string_size += sprintf(&message_string[message_string_size], "  LSF       : %u\n", pdu_info.lsf);
              message_string_size += sprintf(&message_string[message_string_size], "  SO        : %u\n", pdu_info.so);
710 711
            }

712 713
            if (pdu_info.e) {
              message_string_size += sprintf(&message_string[message_string_size], "\nHeader extension  : \n");
714

715 716
              for (index=0; index < pdu_info.num_li; index++) {
                message_string_size += sprintf(&message_string[message_string_size], "  LI        : %u\n", pdu_info.li_list[index]);
gauthier's avatar
gauthier committed
717
              }
718 719
            }

720 721 722 723
            message_string_size += sprintf(&message_string[message_string_size], "\nPayload  : \n");
            message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n");
            message_string_size += sprintf(&message_string[message_string_size], "      |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |\n");
            message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n");
724

725 726 727 728 729
            for (octet_index = 0; octet_index < pdu_info.payload_size; octet_index++) {
              if ((octet_index % 16) == 0) {
                if (octet_index != 0) {
                  message_string_size += sprintf(&message_string[message_string_size], " |\n");
                }
730

731 732
                message_string_size += sprintf(&message_string[message_string_size], " %04d |", octet_index);
              }
733

734 735 736 737 738 739 740 741
              /*
               * Print every single octet in hexadecimal form
               */
              message_string_size += sprintf(&message_string[message_string_size], " %02x", pdu_info.payload[octet_index]);
              /*
               * Align newline and pipes according to the octets in groups of 2
               */
            }
742

743 744 745 746 747 748
            /*
             * Append enough spaces and put final pipe
             */
            for (index = octet_index; index < 16; ++index) {
              message_string_size += sprintf(&message_string[message_string_size], "   ");
            }
749

750 751
            LOG_UI(RLC,"%s\n",message_string);
          } /* LOG_DEBUGFLAG(DEBUG_RLC) */
752 753
        }
      } else {
754
        if (rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10_p, &tb_size_in_bytes, &l_rlc_p->control_pdu_info) >= 0) {
755
          tb_size_in_bytes   = ((struct mac_tb_req *) (tb_p->data))->tb_size; //tb_size_in_bytes modified by rlc_am_get_control_pdu_infos!
756

757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774
          if (MESSAGE_CHART_GENERATOR ) {
            message_string_size = 0;
            message_string_size += sprintf(&message_string[message_string_size],
                                           MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" STATUS ACK_SN %u",
                                           MSC_AS_TIME_ARGS(ctxt_pP),
                                           PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, l_rlc_p),
                                           l_rlc_p->control_pdu_info.ack_sn);

            for (num_nack = 0; num_nack < l_rlc_p->control_pdu_info.num_nack; num_nack++) {
              if (l_rlc_p->control_pdu_info.nack_list[num_nack].e2) {
                message_string_size += sprintf(&message_string[message_string_size], "  NACK SN %u SO START %u SO END %u",
                                               l_rlc_p->control_pdu_info.nack_list[num_nack].nack_sn,
                                               l_rlc_p->control_pdu_info.nack_list[num_nack].so_start,
                                               l_rlc_p->control_pdu_info.nack_list[num_nack].so_end);
              } else {
                message_string_size += sprintf(&message_string[message_string_size], "  NACK SN %u",
                                               l_rlc_p->control_pdu_info.nack_list[num_nack].nack_sn);
              }
775 776
            }

777 778 779 780 781 782
            MSC_LOG_TX_MESSAGE(
              (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
              (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_UE:MSC_RLC_ENB,
              (char *)rlc_am_pdu_sn_10_p,
              tb_size_in_bytes,
              message_string);
783
          }
784

785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805
          if ( LOG_DEBUGFLAG(DEBUG_RLC)) {
            message_string_size = 0;
            message_string_size += sprintf(&message_string[message_string_size], "Bearer      : %u\n", l_rlc_p->rb_id);
            message_string_size += sprintf(&message_string[message_string_size], "PDU size    : %u\n", tb_size_in_bytes);
            message_string_size += sprintf(&message_string[message_string_size], "PDU type    : RLC AM DATA REQ: STATUS PDU\n\n");
            message_string_size += sprintf(&message_string[message_string_size], "Header      :\n");
            message_string_size += sprintf(&message_string[message_string_size], "  D/C       : %u\n", l_rlc_p->control_pdu_info.d_c);
            message_string_size += sprintf(&message_string[message_string_size], "  CPT       : %u\n", l_rlc_p->control_pdu_info.cpt);
            message_string_size += sprintf(&message_string[message_string_size], "  ACK_SN    : %u\n", l_rlc_p->control_pdu_info.ack_sn);
            message_string_size += sprintf(&message_string[message_string_size], "  E1        : %u\n", l_rlc_p->control_pdu_info.e1);

            for (num_nack = 0; num_nack < l_rlc_p->control_pdu_info.num_nack; num_nack++) {
              if (l_rlc_p->control_pdu_info.nack_list[num_nack].e2) {
                message_string_size += sprintf(&message_string[message_string_size], "  NACK SN %04d SO START %05d SO END %05d",
                                               l_rlc_p->control_pdu_info.nack_list[num_nack].nack_sn,
                                               l_rlc_p->control_pdu_info.nack_list[num_nack].so_start,
                                               l_rlc_p->control_pdu_info.nack_list[num_nack].so_end);
              } else {
                message_string_size += sprintf(&message_string[message_string_size], "  NACK SN %04d",  l_rlc_p->control_pdu_info.nack_list[num_nack].nack_sn);
              }
            }
806

807 808
            LOG_UI(RLC,"%s\n",message_string);
          } /* LOG_DEBUGFLAG(DEBUG_RLC) */
809
        }
810
      }
811 812

      tb_p = tb_p->next;
813 814
    } /* while */
  } /* MESSAGE_CHART_GENERATOR && data_req.data.nb_elements > 0 */
815

816 817 818 819
  return data_req;
}
//-----------------------------------------------------------------------------
void
820
rlc_am_mac_data_indication (
821 822
  const protocol_ctxt_t *const ctxt_pP,
  void *const                 rlc_pP,
823
  struct mac_data_ind          data_indP
824 825
) {
  rlc_am_entity_t           *l_rlc_p = (rlc_am_entity_t *) rlc_pP;
826 827 828
  /*rlc_am_control_pdu_info_t control_pdu_info;
  int                       num_li;
  int16_t                     tb_size;*/
gauthier's avatar
gauthier committed
829 830 831
  rlc_am_pdu_info_t   pdu_info;
  rlc_am_pdu_sn_10_t *rlc_am_pdu_sn_10_p;
  mem_block_t        *tb_p;
832
  sdu_size_t          tb_size_in_bytes;
gauthier's avatar
gauthier committed
833 834 835 836
  int                 num_nack;
  char                message_string[7000];
  size_t              message_string_size = 0;
  int                 octet_index, index;
Cedric Roux's avatar
Cedric Roux committed
837 838 839 840 841 842
  /* for no gcc warnings */
  (void)num_nack;
  (void)message_string;
  (void)message_string_size;
  (void)octet_index;
  (void)index;
843 844
  (void)l_rlc_p; /* avoid gcc warning "unused variable" */

845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
  if ( LOG_DEBUGFLAG(DEBUG_RLC) || MESSAGE_CHART_GENERATOR ) {
    if (data_indP.data.nb_elements > 0) {
      tb_p = data_indP.data.head;

      while (tb_p != NULL) {
        rlc_am_pdu_sn_10_p = (rlc_am_pdu_sn_10_t *)((struct mac_tb_ind *) (tb_p->data))->data_ptr;
        tb_size_in_bytes   = ((struct mac_tb_ind *) (tb_p->data))->size;

        if ((((struct mac_tb_ind *) (tb_p->data))->data_ptr[0] & RLC_DC_MASK) == RLC_DC_DATA_PDU ) {
          if (rlc_am_get_data_pdu_infos(ctxt_pP,l_rlc_p,rlc_am_pdu_sn_10_p, tb_size_in_bytes, &pdu_info) >= 0) {
            if (MESSAGE_CHART_GENERATOR) {
              message_string_size = 0;
              message_string_size += sprintf(&message_string[message_string_size],
                                             MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" DATA SN %u size %u RF %u P %u FI %u",
                                             MSC_AS_TIME_ARGS(ctxt_pP),
                                             PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, l_rlc_p),
                                             pdu_info.sn,
                                             tb_size_in_bytes,
                                             pdu_info.rf,
                                             pdu_info.p,
                                             pdu_info.fi);

              if (pdu_info.rf) {
                message_string_size += sprintf(&message_string[message_string_size], " LSF %u\n", pdu_info.lsf);
                message_string_size += sprintf(&message_string[message_string_size], " SO %u\n", pdu_info.so);
              }
gauthier's avatar
gauthier committed
871

872 873
              if (pdu_info.e) {
                message_string_size += sprintf(&message_string[message_string_size], "| HE:");
874

875 876 877 878
                for (index=0; index < pdu_info.num_li; index++) {
                  message_string_size += sprintf(&message_string[message_string_size], " LI %u", pdu_info.li_list[index]);
                }
              }
879

880 881 882 883 884 885
              MSC_LOG_RX_MESSAGE(
                (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
                (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_UE:MSC_RLC_ENB,
                (char *)rlc_am_pdu_sn_10_p,
                tb_size_in_bytes,
                message_string);
886 887
            }

888 889 890 891 892
            if ( LOG_DEBUGFLAG(DEBUG_RLC)) {
              message_string_size += sprintf(&message_string[message_string_size], "Bearer	: %u\n", l_rlc_p->rb_id);
              message_string_size += sprintf(&message_string[message_string_size], "PDU size	: %u\n", tb_size_in_bytes);
              message_string_size += sprintf(&message_string[message_string_size], "Header size : %u\n", pdu_info.header_size);
              message_string_size += sprintf(&message_string[message_string_size], "Payload size: %u\n", pdu_info.payload_size);
893

894 895 896 897 898
              if (pdu_info.rf) {
                message_string_size += sprintf(&message_string[message_string_size], "PDU type    : RLC AM DATA IND: AMD PDU segment\n\n");
              } else {
                message_string_size += sprintf(&message_string[message_string_size], "PDU type    : RLC AM DATA IND: AMD PDU\n\n");
              }
899

900 901 902 903 904 905 906 907 908 909 910 911
              message_string_size += sprintf(&message_string[message_string_size], "Header      :\n");
              message_string_size += sprintf(&message_string[message_string_size], "  D/C       : %u\n", pdu_info.d_c);
              message_string_size += sprintf(&message_string[message_string_size], "  RF        : %u\n", pdu_info.rf);
              message_string_size += sprintf(&message_string[message_string_size], "  P         : %u\n", pdu_info.p);
              message_string_size += sprintf(&message_string[message_string_size], "  FI        : %u\n", pdu_info.fi);
              message_string_size += sprintf(&message_string[message_string_size], "  E         : %u\n", pdu_info.e);
              message_string_size += sprintf(&message_string[message_string_size], "  SN        : %u\n", pdu_info.sn);

              if (pdu_info.rf) {
                message_string_size += sprintf(&message_string[message_string_size], "  LSF       : %u\n", pdu_info.lsf);
                message_string_size += sprintf(&message_string[message_string_size], "  SO        : %u\n", pdu_info.so);
              }
912

913 914
              if (pdu_info.e) {
                message_string_size += sprintf(&message_string[message_string_size], "\nHeader extension  : \n");
915

916 917 918 919
                for (index=0; index < pdu_info.num_li; index++) {
                  message_string_size += sprintf(&message_string[message_string_size], "  LI        : %u\n", pdu_info.li_list[index]);
                }
              }
920

921 922 923 924
              message_string_size += sprintf(&message_string[message_string_size], "\nPayload  : \n");
              message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n");
              message_string_size += sprintf(&message_string[message_string_size], "      |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |\n");
              message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n");
925

926 927 928 929 930
              for (octet_index = 0; octet_index < pdu_info.payload_size; octet_index++) {
                if ((octet_index % 16) == 0) {
                  if (octet_index != 0) {
                    message_string_size += sprintf(&message_string[message_string_size], " |\n");
                  }
931

932 933
                  message_string_size += sprintf(&message_string[message_string_size], " %04d |", octet_index);
                }
934

935 936 937 938 939 940 941
                /*
                 * Print every single octet in hexadecimal form
                 */
                message_string_size += sprintf(&message_string[message_string_size], " %02x", pdu_info.payload[octet_index]);
                /*
                 * Align newline and pipes according to the octets in groups of 2
                 */
gauthier's avatar
gauthier committed
942
              }
943

944 945 946 947 948 949
              /*
               * Append enough spaces and put final pipe
               */
              for (index = octet_index; index < 16; ++index) {
                message_string_size += sprintf(&message_string[message_string_size], "   ");
              }
950

951 952
              LOG_UI(RLC,"%s\n",message_string);
            } /* LOG_DEBUGFLAG */
953
          }
954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974
        } else {
          if (rlc_am_get_control_pdu_infos(rlc_am_pdu_sn_10_p, &tb_size_in_bytes, &l_rlc_p->control_pdu_info) >= 0) {
            if (MESSAGE_CHART_GENERATOR) {
              message_string_size = 0;
              message_string_size += sprintf(&message_string[message_string_size],
                                             MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" STATUS size ACK_SN %u",
                                             MSC_AS_TIME_ARGS(ctxt_pP),
                                             PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, l_rlc_p),
                                             l_rlc_p->control_pdu_info.ack_sn);

              for (num_nack = 0; num_nack < l_rlc_p->control_pdu_info.num_nack; num_nack++) {
                if (l_rlc_p->control_pdu_info.nack_list[num_nack].e2) {
                  message_string_size += sprintf(&message_string[message_string_size], "  NACK SN %u SO START %u SO END %u",
                                                 l_rlc_p->control_pdu_info.nack_list[num_nack].nack_sn,
                                                 l_rlc_p->control_pdu_info.nack_list[num_nack].so_start,
                                                 l_rlc_p->control_pdu_info.nack_list[num_nack].so_end);
                } else {
                  message_string_size += sprintf(&message_string[message_string_size], "  NACK SN %u",
                                                 l_rlc_p->control_pdu_info.nack_list[num_nack].nack_sn);
                }
              }
975

976 977 978 979 980 981
              MSC_LOG_RX_MESSAGE(
                (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
                (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_UE:MSC_RLC_ENB,
                (char *)rlc_am_pdu_sn_10_p,
                tb_size_in_bytes,
                message_string);
982 983
            }

984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004
            if ( LOG_DEBUGFLAG(DEBUG_RLC)) {
              message_string_size = 0;
              message_string_size += sprintf(&message_string[message_string_size], "Bearer      : %u\n", l_rlc_p->rb_id);
              message_string_size += sprintf(&message_string[message_string_size], "PDU size    : %u\n", ((struct mac_tb_ind *) (tb_p->data))->size);
              message_string_size += sprintf(&message_string[message_string_size], "PDU type    : RLC AM DATA IND: STATUS PDU\n\n");
              message_string_size += sprintf(&message_string[message_string_size], "Header      :\n");
              message_string_size += sprintf(&message_string[message_string_size], "  D/C       : %u\n", l_rlc_p->control_pdu_info.d_c);
              message_string_size += sprintf(&message_string[message_string_size], "  CPT       : %u\n", l_rlc_p->control_pdu_info.cpt);
              message_string_size += sprintf(&message_string[message_string_size], "  ACK_SN    : %u\n", l_rlc_p->control_pdu_info.ack_sn);
              message_string_size += sprintf(&message_string[message_string_size], "  E1        : %u\n", l_rlc_p->control_pdu_info.e1);

              for (num_nack = 0; num_nack < l_rlc_p->control_pdu_info.num_nack; num_nack++) {
                if (l_rlc_p->control_pdu_info.nack_list[num_nack].e2) {
                  message_string_size += sprintf(&message_string[message_string_size], "  NACK SN %04d SO START %05d SO END %05d",
                                                 l_rlc_p->control_pdu_info.nack_list[num_nack].nack_sn,
                                                 l_rlc_p->control_pdu_info.nack_list[num_nack].so_start,
                                                 l_rlc_p->control_pdu_info.nack_list[num_nack].so_end);
                } else {
                  message_string_size += sprintf(&message_string[message_string_size], "  NACK SN %04d",  l_rlc_p->control_pdu_info.nack_list[num_nack].nack_sn);
                }
              }
1005

1006
              LOG_UI(RLC, "%s\n",message_string);
1007
            }
gauthier's avatar
gauthier committed
1008
          }
1009 1010
        }

1011 1012
        tb_p = tb_p->next;
      }
1013
    }
1014
  } /* LOG_DEBUGFLAG(RLC) || MESSAGE_TRACE_GENERATOR) */
1015 1016

  rlc_am_rx (ctxt_pP, rlc_pP, data_indP);
1017 1018 1019 1020
}

//-----------------------------------------------------------------------------
void
1021
rlc_am_data_req (
1022 1023 1024
  const protocol_ctxt_t *const ctxt_pP,
  void *const                rlc_pP,
  mem_block_t *const         sdu_pP) {
gauthier's avatar
gauthier committed
1025
  rlc_am_entity_t     *l_rlc_p = (rlc_am_entity_t *) rlc_pP;
1026 1027 1028
  uint32_t             mui;
  uint16_t             data_offset;
  uint16_t             data_size;
gauthier's avatar
gauthier committed
1029 1030 1031
  char                 message_string[7000];
  size_t               message_string_size = 0;
  int                  octet_index, index;
knopp's avatar
knopp committed
1032
  RLC_AM_MUTEX_LOCK(&l_rlc_p->lock_input_sdus, ctxt_pP, l_rlc_p);
1033

gauthier's avatar
gauthier committed
1034 1035 1036
  if ((l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].mem_block == NULL) &&
      (l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].flags.segmented == 0) &&
      (((l_rlc_p->next_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE) != l_rlc_p->current_sdu_index)) {
1037 1038 1039 1040 1041
    memset(&l_rlc_p->input_sdus[l_rlc_p->next_sdu_index], 0, sizeof(rlc_am_tx_sdu_management_t));
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].mem_block = sdu_pP;
    mui         = ((struct rlc_am_data_req *) (sdu_pP->data))->mui;
    data_offset = ((struct rlc_am_data_req *) (sdu_pP->data))->data_offset;
    data_size   = ((struct rlc_am_data_req *) (sdu_pP->data))->data_size;
1042
    MSC_LOG_RX_MESSAGE(
1043 1044
      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
      (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
1045
      (const char *)(&sdu_pP->data[data_offset]),
1046 1047 1048 1049 1050 1051
      data_size,
      MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" DATA-REQ size %u mui %u",
      MSC_AS_TIME_ARGS(ctxt_pP),
      PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, l_rlc_p),
      data_size,
      mui);
1052

1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
    if (LOG_DEBUGFLAG(DEBUG_RLC)) {
      message_string_size += sprintf(&message_string[message_string_size], "Bearer      : %u\n", l_rlc_p->rb_id);
      message_string_size += sprintf(&message_string[message_string_size], "SDU size    : %u\n", data_size);
      message_string_size += sprintf(&message_string[message_string_size], "MUI         : %u\n", mui);
      message_string_size += sprintf(&message_string[message_string_size], "CONF        : %u\n", ((struct rlc_am_data_req *) (sdu_pP->data))->conf);
      message_string_size += sprintf(&message_string[message_string_size], "\nPayload  : \n");
      message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n");
      message_string_size += sprintf(&message_string[message_string_size], "      |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |\n");
      message_string_size += sprintf(&message_string[message_string_size], "------+-------------------------------------------------|\n");

      for (octet_index = 0; octet_index < data_size; octet_index++) {
        if ((octet_index % 16) == 0) {
          if (octet_index != 0) {
            message_string_size += sprintf(&message_string[message_string_size], " |\n");
          }
1068

1069
          message_string_size += sprintf(&message_string[message_string_size], " %04d |", octet_index);
1070 1071
        }

1072 1073 1074 1075 1076 1077 1078
        /*
         * Print every single octet in hexadecimal form
         */
        message_string_size += sprintf(&message_string[message_string_size], " %02x", ((uint8_t *)(&sdu_pP->data[data_offset]))[octet_index]);
        /*
         * Align newline and pipes according to the octets in groups of 2
         */
gauthier's avatar
gauthier committed
1079
      }
1080

gauthier's avatar
gauthier committed
1081
      /*
1082
       * Append enough spaces and put final pipe
gauthier's avatar
gauthier committed
1083
       */
1084 1085 1086
      for (index = octet_index; index < 16; ++index) {
        message_string_size += sprintf(&message_string[message_string_size], "   ");
      }
1087

1088 1089 1090
      message_string_size += sprintf(&message_string[message_string_size], " |\n");
      LOG_UI(RLC, "%s\n", message_string);
    } /* LOG_DEBUGFLAG(RLC) */
gauthier's avatar
gauthier committed
1091

1092 1093 1094 1095 1096 1097 1098
    l_rlc_p->stat_tx_pdcp_sdu   += 1;
    l_rlc_p->stat_tx_pdcp_bytes += data_size;
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].mui      = mui;
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].sdu_size = data_size;
    l_rlc_p->sdu_buffer_occupancy += data_size;
    l_rlc_p->nb_sdu += 1;
    l_rlc_p->nb_sdu_no_segmented += 1;
1099
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].first_byte = (uint8_t *)(&sdu_pP->data[data_offset]);
1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].sdu_remaining_size = l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].sdu_size;
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].sdu_segmented_size = 0;
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].sdu_creation_time  = ctxt_pP->frame;
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].nb_pdus            = 0;
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].nb_pdus_ack        = 0;
    //l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].nb_pdus_time = 0;
    //l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].nb_pdus_internal_use = 0;
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].flags.discarded    = 0;
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].flags.segmented    = 0;
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].flags.segmentation_in_progress = 0;
    l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].flags.no_new_sdu_segmented_in_last_pdu = 0;
    //l_rlc_p->input_sdus[l_rlc_p->next_sdu_index].li_index_for_discard = -1;
    l_rlc_p->next_sdu_index = (l_rlc_p->next_sdu_index + 1) % RLC_AM_SDU_CONTROL_BUFFER_SIZE;
1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124

    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 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,
            ((struct rlc_am_data_req *) (sdu_pP->data))->conf,
            mui,
            l_rlc_p->vt_a,
            l_rlc_p->vt_s);
Gabriel's avatar
Gabriel committed
1125
    }
1126
  } else {
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142
    if( MESSAGE_CHART_GENERATOR) {
      mui   = ((struct rlc_am_data_req *) (sdu_pP->data))->mui;
      data_offset = ((struct rlc_am_data_req *) (sdu_pP->data))->data_offset;
      data_size   = ((struct rlc_am_data_req *) (sdu_pP->data))->data_size;
      MSC_LOG_RX_DISCARDED_MESSAGE(
        (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_RLC_ENB:MSC_RLC_UE,
        (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
        (const char *)(&sdu_pP->data[data_offset]),
        data_size,
        MSC_AS_TIME_FMT" "PROTOCOL_RLC_AM_MSC_FMT" DATA-REQ size %u mui %u",
        MSC_AS_TIME_ARGS(ctxt_pP),
        PROTOCOL_RLC_AM_MSC_ARGS(ctxt_pP, l_rlc_p),
        data_size,
        mui);
    }

Bilel's avatar
Bilel committed
1143
    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",
1144
          PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p),
1145 1146 1147
          l_rlc_p->nb_sdu,
          l_rlc_p->current_sdu_index,
          l_rlc_p->next_sdu_index,
Bilel's avatar
Bilel committed
1148
          RLC_AM_SDU_CONTROL_BUFFER_SIZE,
1149 1150
          l_rlc_p->vt_a,
          l_rlc_p->vt_s);
1151 1152
    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);
1153 1154
    l_rlc_p->stat_tx_pdcp_sdu_discarded   += 1;
    l_rlc_p->stat_tx_pdcp_bytes_discarded += ((struct rlc_am_data_req *) (sdu_pP->data))->data_size;
1155
    free_mem_block (sdu_pP, __func__);
1156
#if STOP_ON_IP_TRAFFIC_OVERLOAD
1157 1158
    AssertFatal(0, PROTOCOL_RLC_AM_CTXT_FMT" RLC_AM_DATA_REQ size %d Bytes, SDU DROPPED, INPUT BUFFER OVERFLOW NB SDU %d current_sdu_index=%d next_sdu_index=%d \n",
                PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p),
1159 1160 1161 1162
                data_size,
                l_rlc_p->nb_sdu,
                l_rlc_p->current_sdu_index,
                l_rlc_p->next_sdu_index);
gauthier's avatar
gauthier committed