rlc.c 24.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 21
 * 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
22 23 24 25 26 27 28
/*
                                rlc.c
                             -------------------
  AUTHOR  : Lionel GAUTHIER
  COMPANY : EURECOM
  EMAIL   : Lionel.Gauthier at eurecom dot fr
*/
29 30 31 32 33
#define RLC_C
#include "rlc.h"
#include "mem_block.h"
#include "../MAC/extern.h"
#include "UTIL/LOG/log.h"
gauthier's avatar
gauthier committed
34
#include "UTIL/OCG/OCG_vars.h"
35
#include "UTIL/LOG/vcd_signal_dumper.h"
36 37 38

#include "assertions.h"

39
extern boolean_t pdcp_data_ind(
40 41 42 43 44 45
  const protocol_ctxt_t* const ctxt_pP,
  const srb_flag_t srb_flagP,
  const MBMS_flag_t MBMS_flagP,
  const rb_id_t rb_idP,
  const sdu_size_t sdu_buffer_sizeP,
  mem_block_t* const sdu_buffer_pP);
46

47
#define DEBUG_RLC_PDCP_INTERFACE 1
48
//#define TRACE_RLC_PAYLOAD 1
gauthier's avatar
gauthier committed
49
#define DEBUG_RLC_DATA_REQ 1
50 51

//-----------------------------------------------------------------------------
52
void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char* dataP, const signed long sizeP)
53 54 55 56 57 58 59 60 61
//-----------------------------------------------------------------------------
{
  unsigned long octet_index = 0;

  if (dataP == NULL) {
    return;
  }


62 63 64 65 66


  LOG_T(componentP, "+-----+-------------------------------------------------+\n");
  LOG_T(componentP, "|     |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |\n");
  LOG_T(componentP, "+-----+-------------------------------------------------+\n");
67

68
  for (octet_index = 0; octet_index < sizeP; octet_index++) {
69
    if ((octet_index % 16) == 0) {
70
      if (octet_index != 0) {
71
        LOG_T(componentP, " |\n");
72
      }
73

Cedric Roux's avatar
Cedric Roux committed
74
      LOG_T(componentP, " %04lu |", octet_index);
75
    }
76

77 78 79 80 81 82 83 84 85 86 87 88 89
    /*
     * Print every single octet in hexadecimal form
     */
    LOG_T(componentP, " %02x", dataP[octet_index]);
    /*
     * Align newline and pipes according to the octets in groups of 2
     */
  }

  /*
   * Append enough spaces and put final pipe
   */
  unsigned char index;
90

91
  for (index = octet_index; index < 16; ++index) {
92
    LOG_T(componentP, "   ");
93
  }
94

95 96
  LOG_T(componentP, " |\n");
}
97

98
//-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
99
rlc_op_status_t rlc_stat_req     (
100
  const protocol_ctxt_t* const ctxt_pP,
101 102
  const srb_flag_t    srb_flagP,
  const rb_id_t       rb_idP,
103
  unsigned int* stat_rlc_mode,
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
  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)
{
  //-----------------------------------------------------------------------------
  rlc_mode_t             rlc_mode        = RLC_MODE_NONE;
  rlc_union_t           *rlc_union_p     = NULL;
135
  hash_key_t             key             = HASHTABLE_NOT_A_KEY_VALUE;
136
  hashtable_rc_t         h_rc;
gauthier's avatar
gauthier committed
137

138
  AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
139
  key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
140 141 142 143 144
  h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);

  if (h_rc == HASH_TABLE_OK) {
    rlc_mode = rlc_union_p->mode;
  }
145
  *stat_rlc_mode                     = rlc_mode;
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
  switch (rlc_mode) {
  case RLC_MODE_NONE:
    *stat_tx_pdcp_sdu                     = 0;
    *stat_tx_pdcp_bytes                   = 0;
    *stat_tx_pdcp_sdu_discarded           = 0;
    *stat_tx_pdcp_bytes_discarded         = 0;
    *stat_tx_data_pdu                     = 0;
    *stat_tx_data_bytes                   = 0;
    *stat_tx_retransmit_pdu_by_status     = 0;
    *stat_tx_retransmit_bytes_by_status   = 0;
    *stat_tx_retransmit_pdu               = 0;
    *stat_tx_retransmit_bytes             = 0;
    *stat_tx_control_pdu                  = 0;
    *stat_tx_control_bytes                = 0;
    *stat_rx_pdcp_sdu                     = 0;
    *stat_rx_pdcp_bytes                   = 0;
    *stat_rx_data_pdus_duplicate          = 0;
    *stat_rx_data_bytes_duplicate         = 0;
    *stat_rx_data_pdu                     = 0;
    *stat_rx_data_bytes                   = 0;
    *stat_rx_data_pdu_dropped             = 0;
    *stat_rx_data_bytes_dropped           = 0;
    *stat_rx_data_pdu_out_of_window       = 0;
    *stat_rx_data_bytes_out_of_window     = 0;
    *stat_rx_control_pdu                  = 0;
    *stat_rx_control_bytes                = 0;
    *stat_timer_reordering_timed_out      = 0;
    *stat_timer_poll_retransmit_timed_out = 0;
    *stat_timer_status_prohibit_timed_out = 0;
    return RLC_OP_STATUS_BAD_PARAMETER;
    break;

  case RLC_MODE_AM:
179
    rlc_am_stat_req(ctxt_pP,
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
                    &rlc_union_p->rlc.am,
                    stat_tx_pdcp_sdu,
                    stat_tx_pdcp_bytes,
                    stat_tx_pdcp_sdu_discarded,
                    stat_tx_pdcp_bytes_discarded,
                    stat_tx_data_pdu,
                    stat_tx_data_bytes,
                    stat_tx_retransmit_pdu_by_status,
                    stat_tx_retransmit_bytes_by_status,
                    stat_tx_retransmit_pdu,
                    stat_tx_retransmit_bytes,
                    stat_tx_control_pdu,
                    stat_tx_control_bytes,
                    stat_rx_pdcp_sdu,
                    stat_rx_pdcp_bytes,
                    stat_rx_data_pdus_duplicate,
                    stat_rx_data_bytes_duplicate,
                    stat_rx_data_pdu,
                    stat_rx_data_bytes,
                    stat_rx_data_pdu_dropped,
                    stat_rx_data_bytes_dropped,
                    stat_rx_data_pdu_out_of_window,
                    stat_rx_data_bytes_out_of_window,
                    stat_rx_control_pdu,
                    stat_rx_control_bytes,
                    stat_timer_reordering_timed_out,
                    stat_timer_poll_retransmit_timed_out,
                    stat_timer_status_prohibit_timed_out);
    return RLC_OP_STATUS_OK;
    break;

  case RLC_MODE_UM:
    *stat_tx_retransmit_pdu_by_status     = 0;
    *stat_tx_retransmit_bytes_by_status   = 0;
    *stat_tx_retransmit_pdu               = 0;
    *stat_tx_retransmit_bytes             = 0;
    *stat_tx_control_pdu                  = 0;
    *stat_tx_control_bytes                = 0;
    *stat_rx_data_pdu_dropped             = 0;
    *stat_rx_data_bytes_dropped           = 0;
    *stat_rx_data_pdu_out_of_window       = 0;
    *stat_rx_data_bytes_out_of_window     = 0;
    *stat_timer_poll_retransmit_timed_out = 0;
    *stat_timer_status_prohibit_timed_out = 0;
224
    rlc_um_stat_req (ctxt_pP,
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
                     &rlc_union_p->rlc.um,
                     stat_tx_pdcp_sdu,
                     stat_tx_pdcp_bytes,
                     stat_tx_pdcp_sdu_discarded,
                     stat_tx_pdcp_bytes_discarded,
                     stat_tx_data_pdu,
                     stat_tx_data_bytes,
                     stat_rx_pdcp_sdu,
                     stat_rx_pdcp_bytes,
                     stat_rx_data_pdus_duplicate,
                     stat_rx_data_bytes_duplicate,
                     stat_rx_data_pdu,
                     stat_rx_data_bytes,
                     stat_rx_data_pdu_dropped,
                     stat_rx_data_bytes_dropped,
                     stat_rx_data_pdu_out_of_window,
                     stat_rx_data_bytes_out_of_window,
                     stat_timer_reordering_timed_out);
    return RLC_OP_STATUS_OK;
    break;

  case RLC_MODE_TM:
    *stat_tx_pdcp_sdu                     = 0;
    *stat_tx_pdcp_bytes                   = 0;
    *stat_tx_pdcp_sdu_discarded           = 0;
    *stat_tx_pdcp_bytes_discarded         = 0;
    *stat_tx_data_pdu                     = 0;
    *stat_tx_data_bytes                   = 0;
    *stat_tx_retransmit_pdu_by_status     = 0;
    *stat_tx_retransmit_bytes_by_status   = 0;
    *stat_tx_retransmit_pdu               = 0;
    *stat_tx_retransmit_bytes             = 0;
    *stat_tx_control_pdu                  = 0;
    *stat_tx_control_bytes                = 0;
    *stat_rx_pdcp_sdu                     = 0;
    *stat_rx_pdcp_bytes                   = 0;
    *stat_rx_data_pdus_duplicate          = 0;
    *stat_rx_data_bytes_duplicate         = 0;
    *stat_rx_data_pdu                     = 0;
    *stat_rx_data_bytes                   = 0;
    *stat_rx_data_pdu_dropped             = 0;
    *stat_rx_data_bytes_dropped           = 0;
    *stat_rx_data_pdu_out_of_window       = 0;
    *stat_rx_data_bytes_out_of_window     = 0;
    *stat_rx_control_pdu                  = 0;
    *stat_rx_control_bytes                = 0;
    *stat_timer_reordering_timed_out      = 0;
    *stat_timer_poll_retransmit_timed_out = 0;
    *stat_timer_status_prohibit_timed_out = 0;
    return RLC_OP_STATUS_BAD_PARAMETER;
    break;

  default:
    *stat_tx_pdcp_sdu                     = 0;
    *stat_tx_pdcp_bytes                   = 0;
    *stat_tx_pdcp_sdu_discarded           = 0;
    *stat_tx_pdcp_bytes_discarded         = 0;
    *stat_tx_data_pdu                     = 0;
    *stat_tx_data_bytes                   = 0;
    *stat_tx_retransmit_pdu_by_status     = 0;
    *stat_tx_retransmit_bytes_by_status   = 0;
    *stat_tx_retransmit_pdu               = 0;
    *stat_tx_retransmit_bytes             = 0;
    *stat_tx_control_pdu                  = 0;
    *stat_tx_control_bytes                = 0;
    *stat_rx_pdcp_sdu                     = 0;
    *stat_rx_pdcp_bytes                   = 0;
    *stat_rx_data_pdus_duplicate          = 0;
    *stat_rx_data_bytes_duplicate         = 0;
    *stat_rx_data_pdu                     = 0;
    *stat_rx_data_bytes                   = 0;
    *stat_rx_data_pdu_dropped             = 0;
    *stat_rx_data_bytes_dropped           = 0;
    *stat_rx_data_pdu_out_of_window       = 0;
    *stat_rx_data_bytes_out_of_window     = 0;
    *stat_rx_control_pdu                  = 0;
    *stat_rx_control_bytes                = 0;

    *stat_timer_poll_retransmit_timed_out = 0;
    *stat_timer_status_prohibit_timed_out = 0;
    return RLC_OP_STATUS_BAD_PARAMETER;
  }
307
}
308

309
//-----------------------------------------------------------------------------
310
rlc_op_status_t rlc_data_req     (const protocol_ctxt_t* const ctxt_pP,
311 312 313 314
                                  const srb_flag_t   srb_flagP,
                                  const MBMS_flag_t  MBMS_flagP,
                                  const rb_id_t      rb_idP,
                                  const mui_t        muiP,
315 316
                                  confirm_t    confirmP,
                                  sdu_size_t   sdu_sizeP,
317 318 319
                                  mem_block_t *sdu_pP)
{
  //-----------------------------------------------------------------------------
320
  mem_block_t           *new_sdu_p    = NULL;
gauthier's avatar
gauthier committed
321
  rlc_mode_t             rlc_mode     = RLC_MODE_NONE;
322
  rlc_union_t           *rlc_union_p = NULL;
323
  hash_key_t             key         = HASHTABLE_NOT_A_KEY_VALUE;
324 325
  hashtable_rc_t         h_rc;

Cedric Roux's avatar
Cedric Roux committed
326
#if defined(Rel10) || defined(Rel14)
327 328
  rlc_mbms_id_t         *mbms_id_p  = NULL;
  logical_chan_id_t      log_ch_id  = 0;
329 330
#endif
#ifdef DEBUG_RLC_DATA_REQ
Cedric Roux's avatar
typo  
Cedric Roux committed
331
  LOG_D(RLC,PROTOCOL_CTXT_FMT"rlc_data_req:  rb_id %u (MAX %d), muip %d, confirmP %d, sdu_sizeP %d, sdu_pP %p\n",
332
        PROTOCOL_CTXT_ARGS(ctxt_pP),
gauthier's avatar
gauthier committed
333 334 335 336 337 338
        rb_idP,
        NB_RAB_MAX,
        muiP,
        confirmP,
        sdu_sizeP,
        sdu_pP);
339
#endif
Cedric Roux's avatar
Cedric Roux committed
340
#if defined(Rel10) || defined(Rel14)
341
#else
gauthier's avatar
gauthier committed
342
  AssertFatal(MBMS_flagP == 0, "MBMS_flagP %u", MBMS_flagP);
343
#endif
344

Cedric Roux's avatar
Cedric Roux committed
345 346 347 348 349
#if T_TRACER
  if (ctxt_pP->enb_flag)
    T(T_ENB_RLC_DL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP));
#endif

350
  if (MBMS_flagP) {
351
    AssertFatal (rb_idP < NB_RB_MBMS_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX);
352
  } else {
353
    AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
354
  }
355

gauthier's avatar
gauthier committed
356
  DevAssert(sdu_pP != NULL);
Haruki Naoi's avatar
Haruki Naoi committed
357 358 359 360 361
  //DevCheck(sdu_sizeP > 0, sdu_sizeP, 0, 0);
  if(sdu_sizeP <= 0) {
    LOG_E(RLC, "sdu_sizeP %d, file %s, line %s\n", sdu_sizeP, __FILE__ ,__LINE__);
    return RLC_OP_STATUS_BAD_PARAMETER;
  }
362

Cedric Roux's avatar
Cedric Roux committed
363
#if !defined(Rel10) && !defined(Rel14)
364 365 366
  DevCheck(MBMS_flagP == 0, MBMS_flagP, 0, 0);
#endif

gauthier's avatar
gauthier committed
367
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_IN);
368

Cedric Roux's avatar
Cedric Roux committed
369
#if defined(Rel10) || defined(Rel14)
370

371
  if (MBMS_flagP == TRUE) {
372 373 374
    if (ctxt_pP->enb_flag) {
      log_ch_id = rlc_mbms_enb_get_lcid_by_rb_id(ctxt_pP->module_id,rb_idP);
      mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][log_ch_id];
375
    } else {
376 377
      log_ch_id = rlc_mbms_ue_get_lcid_by_rb_id(ctxt_pP->rnti,rb_idP);
      mbms_id_p = &rlc_mbms_lcid2service_session_id_ue[ctxt_pP->rnti][log_ch_id];
378 379
    }

380
    key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id);
381 382 383
  } else
#endif
  {
384
    key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
385 386 387
  }

  h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
388

389
  if (h_rc == HASH_TABLE_OK) {
390
    rlc_mode = rlc_union_p->mode;
391
  } else {
392 393
    rlc_mode = RLC_MODE_NONE;
    AssertFatal (0 , "RLC not configured key %ju\n", key);
gauthier's avatar
gauthier committed
394 395
  }

396
  if (MBMS_flagP == 0) {
397 398
    LOG_D(RLC, PROTOCOL_CTXT_FMT"[RB %u] Display of rlc_data_req:\n",
          PROTOCOL_CTXT_ARGS(ctxt_pP),
gauthier's avatar
gauthier committed
399
          rb_idP);
400
#if defined(TRACE_RLC_PAYLOAD)
401
    rlc_util_print_hex_octets(RLC, (unsigned char*)sdu_pP->data, sdu_sizeP);
402
#endif
403 404

#ifdef DEBUG_RLC_DATA_REQ
Cedric Roux's avatar
typo  
Cedric Roux committed
405
    LOG_D(RLC,"RLC_TYPE : %d\n", rlc_mode);
406
#endif
407 408 409

    switch (rlc_mode) {
    case RLC_MODE_NONE:
410
      free_mem_block(sdu_pP, __func__);
411 412
      LOG_E(RLC, PROTOCOL_CTXT_FMT" Received RLC_MODE_NONE as rlc_type for rb_id %u\n",
            PROTOCOL_CTXT_ARGS(ctxt_pP),
413
            rb_idP);
gauthier's avatar
gauthier committed
414
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
415 416 417
      return RLC_OP_STATUS_BAD_PARAMETER;

    case RLC_MODE_AM:
418
#ifdef DEBUG_RLC_DATA_REQ
419
      LOG_D(RLC,"RLC_MODE_AM\n");
420
#endif
421
      new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_am_data_req_alloc), __func__);
422 423 424 425 426 427 428 429 430 431

      if (new_sdu_p != NULL) {
        // PROCESS OF COMPRESSION HERE:
        memset (new_sdu_p->data, 0, sizeof (struct rlc_am_data_req_alloc));
        memcpy (&new_sdu_p->data[sizeof (struct rlc_am_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);

        ((struct rlc_am_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
        ((struct rlc_am_data_req *) (new_sdu_p->data))->conf = confirmP;
        ((struct rlc_am_data_req *) (new_sdu_p->data))->mui  = muiP;
        ((struct rlc_am_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_am_data_req_alloc);
432
        free_mem_block(sdu_pP, __func__);
433
        rlc_am_data_req(ctxt_pP, &rlc_union_p->rlc.am, new_sdu_p);
gauthier's avatar
gauthier committed
434
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
435 436
        return RLC_OP_STATUS_OK;
      } else {
gauthier's avatar
gauthier committed
437
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
438
        free_mem_block(sdu_pP, __func__);
439 440 441 442 443 444
        return RLC_OP_STATUS_INTERNAL_ERROR;
      }

      break;

    case RLC_MODE_UM:
445
      new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__);
446 447 448 449 450 451 452 453

      if (new_sdu_p != NULL) {
        // PROCESS OF COMPRESSION HERE:
        memset (new_sdu_p->data, 0, sizeof (struct rlc_um_data_req_alloc));
        memcpy (&new_sdu_p->data[sizeof (struct rlc_um_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);

        ((struct rlc_um_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
        ((struct rlc_um_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_um_data_req_alloc);
454
        free_mem_block(sdu_pP, __func__);
455

456
        rlc_um_data_req(ctxt_pP, &rlc_union_p->rlc.um, new_sdu_p);
457

458
        //free_mem_block(new_sdu, __func__);
gauthier's avatar
gauthier committed
459
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
460 461
        return RLC_OP_STATUS_OK;
      } else {
gauthier's avatar
gauthier committed
462
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
463
        free_mem_block(sdu_pP, __func__);
464 465
        return RLC_OP_STATUS_INTERNAL_ERROR;
      }
gauthier's avatar
gauthier committed
466

467 468 469
      break;

    case RLC_MODE_TM:
470
      new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_tm_data_req_alloc), __func__);
471 472 473 474 475 476 477 478

      if (new_sdu_p != NULL) {
        // PROCESS OF COMPRESSION HERE:
        memset (new_sdu_p->data, 0, sizeof (struct rlc_tm_data_req_alloc));
        memcpy (&new_sdu_p->data[sizeof (struct rlc_tm_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);

        ((struct rlc_tm_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
        ((struct rlc_tm_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_tm_data_req_alloc);
479
        free_mem_block(sdu_pP, __func__);
480
        rlc_tm_data_req(ctxt_pP, &rlc_union_p->rlc.tm, new_sdu_p);
gauthier's avatar
gauthier committed
481
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
482 483 484
        return RLC_OP_STATUS_OK;
      } else {
        //handle_event(ERROR,"FILE %s FONCTION rlc_data_req() LINE %s : out of memory\n", __FILE__, __LINE__);
gauthier's avatar
gauthier committed
485
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
486
        free_mem_block(sdu_pP, __func__);
487
        return RLC_OP_STATUS_INTERNAL_ERROR;
gauthier's avatar
gauthier committed
488
      }
489

490 491 492
      break;

    default:
493
      free_mem_block(sdu_pP, __func__);
gauthier's avatar
gauthier committed
494
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
495 496 497 498
      return RLC_OP_STATUS_INTERNAL_ERROR;

    }

Cedric Roux's avatar
Cedric Roux committed
499
#if defined(Rel10) || defined(Rel14)
500
  } else { /* MBMS_flag != 0 */
501 502 503 504
    //  LOG_I(RLC,"DUY rlc_data_req: mbms_rb_id in RLC instant is: %d\n", mbms_rb_id);
    if (sdu_pP != NULL) {
      if (sdu_sizeP > 0) {
        LOG_I(RLC,"received a packet with size %d for MBMS \n", sdu_sizeP);
505
        new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__);
506 507 508 509 510 511 512

        if (new_sdu_p != NULL) {
          // PROCESS OF COMPRESSION HERE:
          memset (new_sdu_p->data, 0, sizeof (struct rlc_um_data_req_alloc));
          memcpy (&new_sdu_p->data[sizeof (struct rlc_um_data_req_alloc)], &sdu_pP->data[0], sdu_sizeP);
          ((struct rlc_um_data_req *) (new_sdu_p->data))->data_size = sdu_sizeP;
          ((struct rlc_um_data_req *) (new_sdu_p->data))->data_offset = sizeof (struct rlc_um_data_req_alloc);
513
          free_mem_block(sdu_pP, __func__);
514
          rlc_um_data_req(ctxt_pP, &rlc_union_p->rlc.um, new_sdu_p);
515

516
          //free_mem_block(new_sdu, __func__);
gauthier's avatar
gauthier committed
517
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
518 519
          return RLC_OP_STATUS_OK;
        } else {
gauthier's avatar
gauthier committed
520
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
521
          free_mem_block(sdu_pP, __func__);
522 523 524
          return RLC_OP_STATUS_BAD_PARAMETER;
        }
      } else {
gauthier's avatar
gauthier committed
525
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
526 527 528
        return RLC_OP_STATUS_BAD_PARAMETER;
      }
    } else {
gauthier's avatar
gauthier committed
529
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
530 531
      return RLC_OP_STATUS_BAD_PARAMETER;
    }
532
  }
533

534
#else
535 536 537
  }
  else  /* MBMS_flag != 0 */
  {
538
    free_mem_block(sdu_pP, __func__);
Cedric Roux's avatar
Cedric Roux committed
539
    LOG_E(RLC, "MBMS_flag != 0 while Rel10/Rel14 is not defined...\n");
540
    //handle_event(ERROR,"FILE %s FONCTION rlc_data_req() LINE %s : parameter module_id out of bounds :%d\n", __FILE__, __LINE__, module_idP);
gauthier's avatar
gauthier committed
541
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
542
    return RLC_OP_STATUS_BAD_PARAMETER;
543
  }
544

545
#endif
546 547 548
}

//-----------------------------------------------------------------------------
549
void rlc_data_ind     (
550
  const protocol_ctxt_t* const ctxt_pP,
551 552 553 554 555 556 557
  const srb_flag_t  srb_flagP,
  const MBMS_flag_t MBMS_flagP,
  const rb_id_t     rb_idP,
  const sdu_size_t  sdu_sizeP,
  mem_block_t      *sdu_pP)
{
  //-----------------------------------------------------------------------------
gauthier's avatar
gauthier committed
558 559


560 561 562
#if defined(TRACE_RLC_PAYLOAD)
  LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %u] Display of rlc_data_ind: size %u\n",
        PROTOCOL_CTXT_ARGS(ctxt_pP),
563
        (srb_flagP) ? "SRB" : "DRB",
gauthier's avatar
gauthier committed
564 565 566 567
        rb_idP,
        sdu_sizeP);

  rlc_util_print_hex_octets(RLC, (unsigned char*)sdu_pP->data, sdu_sizeP);
568
#endif
569

Cedric Roux's avatar
Cedric Roux committed
570 571 572 573 574 575
#if T_TRACER
  if (ctxt_pP->enb_flag)
    T(T_ENB_RLC_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP));
#endif


576
  pdcp_data_ind (
577
    ctxt_pP,
578 579 580 581 582
    srb_flagP,
    MBMS_flagP,
    rb_idP,
    sdu_sizeP,
    sdu_pP);
583 584
}
//-----------------------------------------------------------------------------
585
void rlc_data_conf     (const protocol_ctxt_t* const ctxt_pP,
586 587 588
                        const srb_flag_t      srb_flagP,
                        const rb_id_t         rb_idP,
                        const mui_t           muiP,
589 590 591 592 593 594
                        const rlc_tx_status_t statusP)
{
  //-----------------------------------------------------------------------------

  if (srb_flagP) {
    if (rlc_rrc_data_conf != NULL) {
595
      rlc_rrc_data_conf (ctxt_pP, rb_idP , muiP, statusP);
596
    }
597
  }
598 599 600
}
//-----------------------------------------------------------------------------
int
601
rlc_module_init (void)
602
{
603 604 605
  //-----------------------------------------------------------------------------
  int          k;
  module_id_t  module_id1;
gauthier's avatar
gauthier committed
606

Cedric Roux's avatar
Cedric Roux committed
607 608 609
  /* for no gcc warnings */
  (void)k;

610 611 612
  LOG_D(RLC, "MODULE INIT\n");
  rlc_rrc_data_ind  = NULL;
  rlc_rrc_data_conf = NULL;
gauthier's avatar
gauthier committed
613

614
  rlc_coll_p = hashtable_create ((maxDRB + 2) * 16, NULL, rb_free_rlc_union);
Haruki Naoi's avatar
Haruki Naoi committed
615 616 617 618 619
  //AssertFatal(rlc_coll_p != NULL, "UNRECOVERABLE error, RLC hashtable_create failed");
  if(rlc_coll_p == NULL) {
    LOG_E(RLC, "UNRECOVERABLE error, RLC hashtable_create failed\n");
    return -1;
  }
gauthier's avatar
gauthier committed
620

621
  for (module_id1=0; module_id1 < NUMBER_OF_UE_MAX; module_id1++) {
Cedric Roux's avatar
Cedric Roux committed
622
#if defined(Rel10) || defined(Rel14)
623 624 625 626 627 628 629

    for (k=0; k < RLC_MAX_MBMS_LC; k++) {
      rlc_mbms_lcid2service_session_id_ue[module_id1][k].service_id = 0;
      rlc_mbms_lcid2service_session_id_ue[module_id1][k].session_id = 0;
    }

    for (k=0; k < NB_RB_MBMS_MAX; k++) {
630
      rlc_mbms_rbid2lcid_ue[module_id1][k] = RLC_LC_UNALLOCATED;
631 632
    }

gauthier's avatar
gauthier committed
633
#endif
634
  }
gauthier's avatar
gauthier committed
635

636
  for (module_id1=0; module_id1 < NUMBER_OF_eNB_MAX; module_id1++) {
Cedric Roux's avatar
Cedric Roux committed
637
#if defined(Rel10) || defined(Rel14)
638 639 640 641 642 643 644

    for (k=0; k < RLC_MAX_MBMS_LC; k++) {
      rlc_mbms_lcid2service_session_id_eNB[module_id1][k].service_id = 0;
      rlc_mbms_lcid2service_session_id_eNB[module_id1][k].session_id = 0;
    }

    for (k=0; k < NB_RB_MBMS_MAX; k++) {
645
      rlc_mbms_rbid2lcid_eNB[module_id1][k] = RLC_LC_UNALLOCATED;
646 647
    }

gauthier's avatar
gauthier committed
648
#endif
649
  }
gauthier's avatar
gauthier committed
650

651
  pool_buffer_init();
652

653
  return(0);
654 655 656
}
//-----------------------------------------------------------------------------
void
657
rlc_module_cleanup (void)
658 659
//-----------------------------------------------------------------------------
{
660
  hashtable_destroy(rlc_coll_p);
661 662 663
}
//-----------------------------------------------------------------------------
void
664
rlc_layer_init (void)
665
{
666
  //-----------------------------------------------------------------------------
667 668 669
}
//-----------------------------------------------------------------------------
void
670
rlc_layer_cleanup (void)
671 672 673 674
//-----------------------------------------------------------------------------
{
}