rlc.c 28.8 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
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
 */

Lionel Gauthier's avatar
Lionel 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
#define RLC_C
#include "rlc.h"
#include "mem_block.h"
32
#include "../MAC/mac_extern.h"
laurent's avatar
laurent committed
33
#include "LAYER2/RLC/UM_v9.3.0/rlc_um.h"
34
#include "common/utils/LOG/log.h"
35
#include "UTIL/OCG/OCG_vars.h"
36
#include "common/utils/LOG/vcd_signal_dumper.h"
Y_Tomita's avatar
Y_Tomita committed
37
#include "targets/COMMON/openairinterface5g_limits.h"
38
#include "assertions.h"
39
#include <rlc.h>
40

41 42
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;
43

44 45 46 47 48 49
extern bool pdcp_data_ind(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);
50

Lionel Gauthier's avatar
 
Lionel Gauthier committed
51
#define DEBUG_RLC_PDCP_INTERFACE 1
52
//#define TRACE_RLC_PAYLOAD 1
53
#define DEBUG_RLC_DATA_REQ 1
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
void (*rlc_rrc_data_conf)(
  const protocol_ctxt_t *const ctxtP,
  const rb_id_t         rb_idP,
  const mui_t           muiP,
  const rlc_tx_status_t statusP) __attribute__ ((aligned(32)));

void (*rlc_rrc_data_ind)(
  const protocol_ctxt_t *const ctxtP,
  const rb_id_t     rb_idP,
  const sdu_size_t  sdu_sizeP,
  const uint8_t    *const sduP)  __attribute__ ((aligned(32)));

logical_chan_id_t    rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
logical_chan_id_t    rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
rlc_mbms_id_t        rlc_mbms_lcid2service_session_id_ue[MAX_MOBILES_PER_ENB][RLC_MAX_MBMS_LC];    // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
rlc_mbms_id_t        rlc_mbms_lcid2service_session_id_eNB[MAX_eNB][RLC_MAX_MBMS_LC];  // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h
hash_table_t  *rlc_coll_p  __attribute__ ((aligned(32)));

72

Laurent Thomas's avatar
Laurent Thomas committed
73 74
logical_chan_id_t    rlc_mbms_rbid2lcid_ue [MAX_MOBILES_PER_ENB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
logical_chan_id_t    rlc_mbms_rbid2lcid_eNB[MAX_eNB][NB_RB_MBMS_MAX];              /*!< \brief Pairing logical channel identifier with radio bearer identifer. */
75
//-----------------------------------------------------------------------------
76
void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP)
77 78 79 80 81 82 83 84
//-----------------------------------------------------------------------------
{
  unsigned long octet_index = 0;

  if (dataP == NULL) {
    return;
  }

85 86 87
  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");
88

89
  for (octet_index = 0; octet_index < sizeP; octet_index++) {
90
    if ((octet_index % 16) == 0) {
91
      if (octet_index != 0) {
92
        LOG_T(componentP, " |\n");
93
      }
94

Cedric Roux's avatar
Cedric Roux committed
95
      LOG_T(componentP, " %04lu |", octet_index);
96
    }
97

98 99 100 101 102 103 104 105 106 107 108 109 110
    /*
     * 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;
111

112
  for (index = octet_index; index < 16; ++index) {
113
    LOG_T(componentP, "   ");
114
  }
115

116 117
  LOG_T(componentP, " |\n");
}
118

119
//-----------------------------------------------------------------------------
120
rlc_op_status_t rlc_stat_req     (
121
  const protocol_ctxt_t *const ctxt_pP,
122 123
  const srb_flag_t    srb_flagP,
  const rb_id_t       rb_idP,
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
  unsigned int *stat_rlc_mode,
  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) {
152 153 154
  //-----------------------------------------------------------------------------
  rlc_mode_t             rlc_mode        = RLC_MODE_NONE;
  rlc_union_t           *rlc_union_p     = NULL;
155
  hash_key_t             key             = HASHTABLE_NOT_A_KEY_VALUE;
156
  hashtable_rc_t         h_rc;
157

teramoto.genki's avatar
teramoto.genki committed
158
  //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
159
  if(rb_idP >= NB_RB_MAX) {
laurent's avatar
laurent committed
160
    LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX);
161 162 163
    return RLC_OP_STATUS_BAD_PARAMETER;
  }

164
  key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
165
  h_rc = hashtable_get(rlc_coll_p, key, (void **)&rlc_union_p);
166 167 168 169

  if (h_rc == HASH_TABLE_OK) {
    rlc_mode = rlc_union_p->mode;
  }
170

171
  *stat_rlc_mode                     = rlc_mode;
172

173
  switch (rlc_mode) {
174 175 176 177 178 179 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 224 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 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
    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:
      rlc_am_stat_req(ctxt_pP,
                      &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;
      rlc_um_stat_req (&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;
331
  }
332
}
333

334
//-----------------------------------------------------------------------------
335
rlc_op_status_t rlc_data_req     (const protocol_ctxt_t *const ctxt_pP,
336 337 338 339
                                  const srb_flag_t   srb_flagP,
                                  const MBMS_flag_t  MBMS_flagP,
                                  const rb_id_t      rb_idP,
                                  const mui_t        muiP,
340 341
                                  confirm_t    confirmP,
                                  sdu_size_t   sdu_sizeP,
342 343 344
                                  mem_block_t *sdu_pP,
                                  const uint32_t *const sourceL2Id,
                                  const uint32_t *const destinationL2Id
345
                                 ) {
346
  //-----------------------------------------------------------------------------
347
  mem_block_t           *new_sdu_p    = NULL;
Lionel Gauthier's avatar
Lionel Gauthier committed
348
  rlc_mode_t             rlc_mode     = RLC_MODE_NONE;
349
  rlc_union_t           *rlc_union_p = NULL;
350
  hash_key_t             key         = HASHTABLE_NOT_A_KEY_VALUE;
351
  hashtable_rc_t         h_rc;
352 353
  rlc_mbms_id_t         *mbms_id_p  = NULL;
  logical_chan_id_t      log_ch_id  = 0;
354
#ifdef DEBUG_RLC_DATA_REQ
laurent's avatar
laurent committed
355
  LOG_D(RLC,PROTOCOL_CTXT_FMT"rlc_data_req:  rb_id %ld (MAX %d), muip %d, confirmP %d, sdu_sizeP %d, sdu_pP %p\n",
356
        PROTOCOL_CTXT_ARGS(ctxt_pP),
357 358 359 360 361 362
        rb_idP,
        NB_RAB_MAX,
        muiP,
        confirmP,
        sdu_sizeP,
        sdu_pP);
363
#endif
Cedric Roux's avatar
Cedric Roux committed
364
#if T_TRACER
365

Cedric Roux's avatar
Cedric Roux committed
366 367
  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));
368

Cedric Roux's avatar
Cedric Roux committed
369 370
#endif

371
  if (MBMS_flagP) {
teramoto.genki's avatar
teramoto.genki committed
372
    //AssertFatal (rb_idP < NB_RB_MBMS_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MBMS_MAX);
373
    if(rb_idP >= NB_RB_MBMS_MAX) {
laurent's avatar
laurent committed
374
      LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MBMS_MAX);
375 376
      return RLC_OP_STATUS_BAD_PARAMETER;
    }
377
  } else {
teramoto.genki's avatar
teramoto.genki committed
378
    //AssertFatal (rb_idP < NB_RB_MAX, "RB id is too high (%u/%d)!\n", rb_idP, NB_RB_MAX);
379
    if(rb_idP >= NB_RB_MAX) {
laurent's avatar
laurent committed
380
      LOG_E(RLC, "RB id is too high (%ld/%d)!\n", rb_idP, NB_RB_MAX);
381 382
      return RLC_OP_STATUS_BAD_PARAMETER;
    }
383
  }
384

teramoto.genki's avatar
teramoto.genki committed
385
  //DevAssert(sdu_pP != NULL);
386 387 388 389 390
  if(sdu_pP == NULL) {
    LOG_E(RLC, "sdu_pP == NULL\n");
    return RLC_OP_STATUS_BAD_PARAMETER;
  }

Haruki NAOI's avatar
Haruki NAOI committed
391 392
  //DevCheck(sdu_sizeP > 0, sdu_sizeP, 0, 0);
  if(sdu_sizeP <= 0) {
393
    LOG_E(RLC, "sdu_sizeP %d, file %s, line %d\n", sdu_sizeP, __FILE__,__LINE__);
Haruki NAOI's avatar
Haruki NAOI committed
394 395
    return RLC_OP_STATUS_BAD_PARAMETER;
  }
396

397
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_IN);
398

399
  if (MBMS_flagP == true) {
400 401 402
    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];
403
    } else {
404 405
      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];
406 407
    }

408
    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);
409
  } else if (sourceL2Id && destinationL2Id) {
laurent's avatar
laurent committed
410
    LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%ld, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP,
411 412 413 414 415
           srb_flagP);
    key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
    //Thinh's line originally uncommented
    //key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, *sourceL2Id, *destinationL2Id, srb_flagP);
    //key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, *sourceL2Id, *destinationL2Id, srb_flagP);
416
  } else {
laurent's avatar
laurent committed
417
    LOG_D (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%ld, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP,
418
           srb_flagP);
419
    key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
420 421
  }

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

424
  if (h_rc == HASH_TABLE_OK) {
425
    rlc_mode = rlc_union_p->mode;
426
  } else {
427
    rlc_mode = RLC_MODE_NONE;
teramoto.genki's avatar
teramoto.genki committed
428
    //AssertFatal (0 , "RLC not configured key %ju\n", key);
429 430
    LOG_E(RLC, "not configured key %lu\n", key);
    return RLC_OP_STATUS_OUT_OF_RESSOURCES;
431 432
  }

433
  if (MBMS_flagP == 0) {
laurent's avatar
laurent committed
434
    LOG_D(RLC, PROTOCOL_CTXT_FMT"[RB %ld] Display of rlc_data_req:\n",
435
          PROTOCOL_CTXT_ARGS(ctxt_pP),
436
          rb_idP);
437
#if defined(TRACE_RLC_PAYLOAD)
438
    rlc_util_print_hex_octets(RLC, (unsigned char *)sdu_pP->data, sdu_sizeP);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
439
#endif
440
#ifdef DEBUG_RLC_DATA_REQ
Cedric Roux's avatar
typo  
Cedric Roux committed
441
    LOG_D(RLC,"RLC_TYPE : %d\n", rlc_mode);
442
#endif
443 444

    switch (rlc_mode) {
445 446
      case RLC_MODE_NONE:
        free_mem_block(sdu_pP, __func__);
laurent's avatar
laurent committed
447
        LOG_E(RLC, PROTOCOL_CTXT_FMT" Received RLC_MODE_NONE as rlc_type for rb_id %ld\n",
448 449 450 451
              PROTOCOL_CTXT_ARGS(ctxt_pP),
              rb_idP);
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
        return RLC_OP_STATUS_BAD_PARAMETER;
452

453
      case RLC_MODE_AM:
454
#ifdef DEBUG_RLC_DATA_REQ
455
        LOG_D(RLC,"RLC_MODE_AM\n");
456
#endif
457
        new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_am_data_req_alloc), __func__);
458

459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
        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);
          free_mem_block(sdu_pP, __func__);
          rlc_am_data_req(ctxt_pP, &rlc_union_p->rlc.am, new_sdu_p);
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
          return RLC_OP_STATUS_OK;
        } else {
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
          free_mem_block(sdu_pP, __func__);
          return RLC_OP_STATUS_INTERNAL_ERROR;
        }
476

477
        break;
478

479
      case RLC_MODE_UM:
480

481 482 483 484 485 486 487 488
        /* TODO: this is a hack, needs better solution. Let's not use too
         * much memory and store at maximum 5 millions bytes.
         */
        /* look for HACK_RLC_UM_LIMIT for others places related to the hack. Please do not remove this comment. */
        if (rlc_um_get_buffer_occupancy(&rlc_union_p->rlc.um) > 5000000) {
          free_mem_block(sdu_pP, __func__);
          return RLC_OP_STATUS_OUT_OF_RESSOURCES;
        }
489

490
        new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__);
491

492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
        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);
          free_mem_block(sdu_pP, __func__);
          rlc_um_data_req(ctxt_pP, &rlc_union_p->rlc.um, new_sdu_p);
          //free_mem_block(new_sdu, __func__);
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
          return RLC_OP_STATUS_OK;
        } else {
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
          free_mem_block(sdu_pP, __func__);
          return RLC_OP_STATUS_INTERNAL_ERROR;
        }
508

509
        break;
510

511 512
      case RLC_MODE_TM:
        new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_tm_data_req_alloc), __func__);
513

514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
        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);
          free_mem_block(sdu_pP, __func__);
          rlc_tm_data_req(ctxt_pP, &rlc_union_p->rlc.tm, new_sdu_p);
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
          return RLC_OP_STATUS_OK;
        } else {
          //handle_event(ERROR,"FILE %s FONCTION rlc_data_req() LINE %s : out of memory\n", __FILE__, __LINE__);
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
          free_mem_block(sdu_pP, __func__);
          return RLC_OP_STATUS_INTERNAL_ERROR;
        }
530

531
        break;
532

533
      default:
534
        free_mem_block(sdu_pP, __func__);
535
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
536 537
        return RLC_OP_STATUS_INTERNAL_ERROR;
    }
538
  } else { /* MBMS_flag != 0 */
539 540 541
    //  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) {
542
        LOG_D(RLC,"received a packet with size %d for MBMS \n", sdu_sizeP);
543
        new_sdu_p = get_free_mem_block (sdu_sizeP + sizeof (struct rlc_um_data_req_alloc), __func__);
544 545 546 547 548 549 550

        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);
551
          free_mem_block(sdu_pP, __func__);
552
          rlc_um_data_req(ctxt_pP, &rlc_union_p->rlc.um, new_sdu_p);
553
          //free_mem_block(new_sdu, __func__);
554
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
555 556
          return RLC_OP_STATUS_OK;
        } else {
557
          VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
558
          free_mem_block(sdu_pP, __func__);
559 560 561
          return RLC_OP_STATUS_BAD_PARAMETER;
        }
      } else {
562
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
563 564 565
        return RLC_OP_STATUS_BAD_PARAMETER;
      }
    } else {
566
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_OUT);
567 568
      return RLC_OP_STATUS_BAD_PARAMETER;
    }
569
  }
570 571 572
}

//-----------------------------------------------------------------------------
573
void rlc_data_ind     (
574
  const protocol_ctxt_t *const ctxt_pP,
575 576 577 578
  const srb_flag_t  srb_flagP,
  const MBMS_flag_t MBMS_flagP,
  const rb_id_t     rb_idP,
  const sdu_size_t  sdu_sizeP,
579
  mem_block_t      *sdu_pP) {
580
  //-----------------------------------------------------------------------------
laurent's avatar
laurent committed
581
  LOG_D(RLC, PROTOCOL_CTXT_FMT"[%s %ld] Display of rlc_data_ind: size %u\n",
582
        PROTOCOL_CTXT_ARGS(ctxt_pP),
583
        (srb_flagP) ? "SRB" : "DRB",
584 585
        rb_idP,
        sdu_sizeP);
586 587
  rlc_util_print_hex_octets(RLC, (unsigned char *)sdu_pP->data, sdu_sizeP);

frtabu's avatar
frtabu committed
588 589
  if (ctxt_pP->enb_flag) {
#if T_TRACER
Cedric Roux's avatar
Cedric Roux committed
590
    T(T_ENB_RLC_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_sizeP));
591
#endif
frtabu's avatar
frtabu committed
592
    const ngran_node_t type = RC.rrc[ctxt_pP->module_id]->node_type;
593
    AssertFatal(!NODE_IS_CU(type),
frtabu's avatar
frtabu committed
594 595 596 597 598 599 600 601 602 603 604 605
                "Can't be CU, bad node type %d\n", type);

    if (NODE_IS_DU(type) && srb_flagP == 1) {
      MessageDef *msg = itti_alloc_new_message(TASK_RLC_ENB, F1AP_UL_RRC_MESSAGE);
      F1AP_UL_RRC_MESSAGE(msg).rnti = ctxt_pP->rnti;
      F1AP_UL_RRC_MESSAGE(msg).srb_id = rb_idP;
      F1AP_UL_RRC_MESSAGE(msg).rrc_container = sdu_pP->data;
      F1AP_UL_RRC_MESSAGE(msg).rrc_container_length = sdu_sizeP;
      itti_send_msg_to_task(TASK_DU_F1, ENB_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), msg);
      return;
    }
  } // case monolithic eNodeB or UE
606

frtabu's avatar
frtabu committed
607
  get_pdcp_data_ind_func()(ctxt_pP, srb_flagP, MBMS_flagP, rb_idP, sdu_sizeP, sdu_pP,NULL,NULL);
608 609
}
//-----------------------------------------------------------------------------
610
void rlc_data_conf     (const protocol_ctxt_t *const ctxt_pP,
611 612 613
                        const srb_flag_t      srb_flagP,
                        const rb_id_t         rb_idP,
                        const mui_t           muiP,
614
                        const rlc_tx_status_t statusP) {
615 616 617
  //-----------------------------------------------------------------------------
  if (srb_flagP) {
    if (rlc_rrc_data_conf != NULL) {
618
      rlc_rrc_data_conf (ctxt_pP, rb_idP, muiP, statusP);
619
    }
620
  }
621 622 623
}
//-----------------------------------------------------------------------------
int
Cedric Roux's avatar
Cedric Roux committed
624 625
rlc_module_init (int enb_flag) { /* enb_flag is unused, but needed for binary
                                  * compatibility with rlc_v2 */
626 627 628
  //-----------------------------------------------------------------------------
  int          k;
  module_id_t  module_id1;
Cedric Roux's avatar
Cedric Roux committed
629 630
  /* for no gcc warnings */
  (void)k;
631 632 633
  LOG_D(RLC, "MODULE INIT\n");
  rlc_rrc_data_ind  = NULL;
  rlc_rrc_data_conf = NULL;
634
  rlc_coll_p = hashtable_create ((LTE_maxDRB + 2) * NUMBER_OF_UE_MAX, NULL, rb_free_rlc_union);
635

Haruki NAOI's avatar
Haruki NAOI committed
636 637 638 639 640
  //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;
  }
641

642
  for (module_id1=0; module_id1 < MAX_MOBILES_PER_ENB; module_id1++) {
643 644 645 646 647 648
    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++) {
649
      rlc_mbms_rbid2lcid_ue[module_id1][k] = RLC_LC_UNALLOCATED;
650 651
    }
  }
652

frtabu's avatar
frtabu committed
653
  for (k=0; k < RLC_MAX_MBMS_LC; k++) {
654 655
    rlc_mbms_lcid2service_session_id_eNB[0][k].service_id = 0;
    rlc_mbms_lcid2service_session_id_eNB[0][k].session_id = 0;
frtabu's avatar
frtabu committed
656
  }
657

frtabu's avatar
frtabu committed
658
  for (k=0; k < NB_RB_MBMS_MAX; k++) {
659
    rlc_mbms_rbid2lcid_eNB[0][k] = RLC_LC_UNALLOCATED;
660
  }
661

662 663
  pool_buffer_init();
  return(0);
664 665 666
}
//-----------------------------------------------------------------------------
void
667
rlc_module_cleanup (void)
668 669
//-----------------------------------------------------------------------------
{
frtabu's avatar
frtabu committed
670
  hashtable_destroy(&rlc_coll_p);
671 672 673
}
//-----------------------------------------------------------------------------
void
674
rlc_layer_init (void) {
675
  //-----------------------------------------------------------------------------
676 677 678
}
//-----------------------------------------------------------------------------
void
679
rlc_layer_cleanup (void)
680 681 682 683
//-----------------------------------------------------------------------------
{
}