rlc_mac.c 18.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * 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
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * 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 24 25 26 27 28 29 30 31 32 33 34
/*
                                rlc_mac.c
                             -------------------
  AUTHOR  : Lionel GAUTHIER
  COMPANY : EURECOM
  EMAIL   : Lionel.Gauthier@eurecom.fr
*/

//-----------------------------------------------------------------------------
#define RLC_MAC_C
#include "rlc.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
gauthier's avatar
gauthier committed
35
#include "UTIL/OCG/OCG_vars.h"
36
#include "hashtable.h"
gauthier's avatar
gauthier committed
37
#include "assertions.h"
38
#include "UTIL/LOG/vcd_signal_dumper.h"
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
39
#include "LAYER2/MAC/defs_NB_IoT.h"
40

41
//#define DEBUG_MAC_INTERFACE 1
42 43

//-----------------------------------------------------------------------------
44
struct mac_data_ind mac_rlc_deserialize_tb (
45 46 47 48 49 50
  char     *buffer_pP,
  const tb_size_t tb_sizeP,
  num_tb_t  num_tbP,
  crc_t    *crcs_pP)
{
  //-----------------------------------------------------------------------------
51
  struct mac_data_ind  data_ind;
gauthier's avatar
gauthier committed
52
  mem_block_t*         tb_p;
53
  num_tb_t             nb_tb_read;
54
  tbs_size_t           tbs_size;
55 56 57 58 59 60

  nb_tb_read = 0;
  tbs_size   = 0;
  list_init(&data_ind.data, NULL);

  while (num_tbP > 0) {
61
    tb_p = get_free_mem_block(sizeof (mac_rlc_max_rx_header_size_t) + tb_sizeP, __func__);
62 63 64 65 66 67

    if (tb_p != NULL) {
      ((struct mac_tb_ind *) (tb_p->data))->first_bit = 0;
      ((struct mac_tb_ind *) (tb_p->data))->data_ptr = (uint8_t*)&tb_p->data[sizeof (mac_rlc_max_rx_header_size_t)];
      ((struct mac_tb_ind *) (tb_p->data))->size = tb_sizeP;

68
      if (crcs_pP) {
69
        ((struct mac_tb_ind *) (tb_p->data))->error_indication = crcs_pP[nb_tb_read];
70
      } else {
71
        ((struct mac_tb_ind *) (tb_p->data))->error_indication = 0;
72
      }
73 74

      memcpy(((struct mac_tb_ind *) (tb_p->data))->data_ptr, &buffer_pP[tbs_size], tb_sizeP);
75 76

#ifdef DEBUG_MAC_INTERFACE
77 78
      LOG_T(RLC, "[MAC-RLC] DUMP RX PDU(%d bytes):\n", tb_sizeP);
      rlc_util_print_hex_octets(RLC, ((struct mac_tb_ind *) (tb_p->data))->data_ptr, tb_sizeP);
79
#endif
80 81 82 83 84 85
      nb_tb_read = nb_tb_read + 1;
      tbs_size   = tbs_size   + tb_sizeP;
      list_add_tail_eurecom(tb_p, &data_ind.data);
    }

    num_tbP = num_tbP - 1;
86
  }
87

88 89 90 91 92 93
  data_ind.no_tb            = nb_tb_read;
  data_ind.tb_size          = tb_sizeP << 3;

  return data_ind;
}
//-----------------------------------------------------------------------------
94 95 96
tbs_size_t mac_rlc_serialize_tb (char* buffer_pP, list_t transport_blocksP)
{
  //-----------------------------------------------------------------------------
97
  mem_block_t *tb_p;
98 99 100 101
  tbs_size_t   tbs_size;
  tbs_size_t   tb_size;

  tbs_size = 0;
102

103
  while (transport_blocksP.nb_elements > 0) {
gauthier's avatar
gauthier committed
104
    tb_p = list_remove_head (&transport_blocksP);
105

gauthier's avatar
gauthier committed
106
    if (tb_p != NULL) {
107
      tb_size = ((struct mac_tb_req *) (tb_p->data))->tb_size;
108
#ifdef DEBUG_MAC_INTERFACE
109 110
      LOG_T(RLC, "[MAC-RLC] DUMP TX PDU(%d bytes):\n", tb_size);
      rlc_util_print_hex_octets(RLC, ((struct mac_tb_req *) (tb_p->data))->data_ptr, tb_size);
111
#endif
112 113
      memcpy(&buffer_pP[tbs_size], &((struct mac_tb_req *) (tb_p->data))->data_ptr[0], tb_size);
      tbs_size = tbs_size + tb_size;
114
      free_mem_block(tb_p, __func__);
115 116
    }
  }
117
  
118 119 120
  return tbs_size;
}
//-----------------------------------------------------------------------------
121
tbs_size_t mac_rlc_data_req(
122 123
  const module_id_t       module_idP,
  const rnti_t            rntiP,
124
  const eNB_index_t       eNB_index,
125 126 127 128
  const frame_t           frameP,
  const eNB_flag_t        enb_flagP,
  const MBMS_flag_t       MBMS_flagP,
  const logical_chan_id_t channel_idP,
129
  const tb_size_t         tb_sizeP,
130 131 132 133 134 135 136
  char             *buffer_pP)
{
  //-----------------------------------------------------------------------------
  struct mac_data_req    data_request;
  rlc_mode_t             rlc_mode        = RLC_MODE_NONE;
  rlc_mbms_id_t         *mbms_id_p       = NULL;
  rlc_union_t           *rlc_union_p     = NULL;
137
  hash_key_t             key             = HASHTABLE_NOT_A_KEY_VALUE;
138
  hashtable_rc_t         h_rc;
Nick Ho's avatar
Nick Ho committed
139
  srb_flag_t             srb_flag        = (channel_idP <= 3) ? SRB_FLAG_YES : SRB_FLAG_NO;
140 141
  tbs_size_t             ret_tb_size         = 0;
  protocol_ctxt_t     ctxt;
142
  //printf("***********data_request=%d (in rlc_mac.c)***********\n",data_request);
143
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, enb_flagP, rntiP, frameP, 0,eNB_index);
144

gauthier's avatar
gauthier committed
145
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_REQ,VCD_FUNCTION_IN);
146
#ifdef DEBUG_MAC_INTERFACE
147 148 149 150 151
  LOG_D(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_REQ channel %d (%d) MAX RB %d, Num_tb %d\n",
        PROTOCOL_CTXT_ARGS((&ctxt)),
        channel_idP,
        RLC_MAX_LC,
        NB_RB_MAX);
gauthier's avatar
gauthier committed
152

153
#endif // DEBUG_MAC_INTERFACE
154

155
  if (MBMS_flagP) {
156
    AssertFatal (channel_idP < RLC_MAX_MBMS_LC,        "channel id is too high (%u/%d)!\n",     channel_idP, RLC_MAX_MBMS_LC);
157
  } else {
158
    AssertFatal (channel_idP < NB_RB_MAX,        "channel id is too high (%u/%d)!\n",     channel_idP, NB_RB_MAX);
159
  }
160

161 162
#ifdef OAI_EMU
  CHECK_CTXT_ARGS(&ctxt);
nikaeinn's avatar
nikaeinn committed
163 164
  //printf("MBMS_flagP %d, MBMS_FLAG_NO %d \n",MBMS_flagP, MBMS_FLAG_NO);
  //  AssertFatal (MBMS_flagP == MBMS_FLAG_NO ," MBMS FLAG SHOULD NOT BE SET IN mac_rlc_data_req in UE\n");
165 166 167 168

#endif

  if (MBMS_flagP) {
169
    if (enb_flagP) {
170 171
      mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[module_idP][channel_idP];
      key = RLC_COLL_KEY_MBMS_VALUE(module_idP, rntiP, enb_flagP, mbms_id_p->service_id, mbms_id_p->session_id);
172
    } else {
173
      return (tbs_size_t)0;
174
    }
175
  } else {
176
    key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag);
Nick Ho's avatar
Nick Ho committed
177
  //key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, 1);
178 179 180
  }

  h_rc = hashtable_get(rlc_coll_p, key, (void**)&rlc_union_p);
181
 
CHIN-WEI, KANG's avatar
CHIN-WEI, KANG committed
182
 
183 184 185 186
  if (h_rc == HASH_TABLE_OK) {
    rlc_mode = rlc_union_p->mode;
  } else {
    rlc_mode = RLC_MODE_NONE;
187
    AssertFatal (0 , "RLC not configured lcid %u RNTI %x!\n", channel_idP, rntiP);
188
  }
gauthier's avatar
gauthier committed
189

190 191 192 193 194 195
  switch (rlc_mode) {
  case RLC_MODE_NONE:
    ret_tb_size =0;
    break;

  case RLC_MODE_AM:
196
    //if (!enb_flagP) rlc_am_set_nb_bytes_requested_by_mac(&rlc_union_p->rlc.am,tb_sizeP);
197
	data_request = rlc_am_mac_data_request(&ctxt, &rlc_union_p->rlc.am,enb_flagP);
198
    ret_tb_size =mac_rlc_serialize_tb(buffer_pP, data_request.data);
Nick Ho's avatar
Nick Ho committed
199
    //printf("****************data_request=%d (in rlc_mac.c)****************\n",data_request);
200 201 202
    break;

  case RLC_MODE_UM:
203
	if (!enb_flagP) rlc_um_set_nb_bytes_requested_by_mac(&rlc_union_p->rlc.um,tb_sizeP);
204
	data_request = rlc_um_mac_data_request(&ctxt, &rlc_union_p->rlc.um,enb_flagP);
205 206 207 208 209 210 211 212 213 214 215 216
    ret_tb_size = mac_rlc_serialize_tb(buffer_pP, data_request.data);
    break;

  case RLC_MODE_TM:
    data_request = rlc_tm_mac_data_request(&ctxt, &rlc_union_p->rlc.tm);
    ret_tb_size = mac_rlc_serialize_tb(buffer_pP, data_request.data);
    break;

  default:
    ;
  }

Cedric Roux's avatar
Cedric Roux committed
217 218 219 220 221
#if T_TRACER
  if (enb_flagP)
    T(T_ENB_RLC_MAC_DL, T_INT(module_idP), T_INT(rntiP), T_INT(channel_idP), T_INT(ret_tb_size));
#endif

gauthier's avatar
gauthier committed
222
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_REQ,VCD_FUNCTION_OUT);
223
  return ret_tb_size;
224 225
}
//-----------------------------------------------------------------------------
226
void mac_rlc_data_ind     (
227 228
  const module_id_t         module_idP,
  const rnti_t              rntiP,
229
  const module_id_t         eNB_index,
230 231 232 233 234 235 236 237 238 239 240 241 242
  const frame_t             frameP,
  const eNB_flag_t          enb_flagP,
  const MBMS_flag_t         MBMS_flagP,
  const logical_chan_id_t   channel_idP,
  char                     *buffer_pP,
  const tb_size_t           tb_sizeP,
  num_tb_t                  num_tbP,
  crc_t                    *crcs_pP)
{
  //-----------------------------------------------------------------------------
  rlc_mode_t             rlc_mode   = RLC_MODE_NONE;
  rlc_mbms_id_t         *mbms_id_p  = NULL;
  rlc_union_t           *rlc_union_p     = NULL;
243
  hash_key_t             key             = HASHTABLE_NOT_A_KEY_VALUE;
244
  hashtable_rc_t         h_rc;
CHIN-WEI, KANG's avatar
CHIN-WEI, KANG committed
245
  srb_flag_t             srb_flag        = (channel_idP <= 3) ? SRB_FLAG_YES : SRB_FLAG_NO;
246
  protocol_ctxt_t     ctxt;
Nick Ho's avatar
Nick Ho committed
247
  LOG_I(RLC,"NB-IoT: RLC PDU receive\n");
248

249
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, enb_flagP, rntiP, frameP, 0, eNB_index);
250

gauthier's avatar
gauthier committed
251
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_IND,VCD_FUNCTION_IN);
252
#ifdef DEBUG_MAC_INTERFACE
253 254

  if (num_tbP) {
255 256
    LOG_D(RLC, PROTOCOL_CTXT_FMT" MAC_RLC_DATA_IND on channel %d (%d), rb max %d, Num_tb %d\n",
          PROTOCOL_CTXT_ARGS(&ctxt),
257 258 259 260 261 262
          channel_idP,
          RLC_MAX_LC,
          NB_RB_MAX,
          num_tbP);
  }

263
#endif // DEBUG_MAC_INTERFACE
264
#ifdef OAI_EMU
265

266 267 268 269 270 271 272
  if (MBMS_flagP)
    AssertFatal (channel_idP < RLC_MAX_MBMS_LC,  "channel id is too high (%u/%d)!\n",
                 channel_idP, RLC_MAX_MBMS_LC);
  else
    AssertFatal (channel_idP < NB_RB_MAX,        "channel id is too high (%u/%d)!\n",
                 channel_idP, NB_RB_MAX);

273
  CHECK_CTXT_ARGS(&ctxt);
274

275
#endif
276

Cedric Roux's avatar
Cedric Roux committed
277 278 279 280
#if T_TRACER
  if (enb_flagP)
    T(T_ENB_RLC_MAC_UL, T_INT(module_idP), T_INT(rntiP), T_INT(channel_idP), T_INT(tb_sizeP));
#endif
281 282 283

  if (MBMS_flagP) {
    if (BOOL_NOT(enb_flagP)) {
284 285
      mbms_id_p = &rlc_mbms_lcid2service_session_id_ue[module_idP][channel_idP];
      key = RLC_COLL_KEY_MBMS_VALUE(module_idP, rntiP, enb_flagP, mbms_id_p->service_id, mbms_id_p->session_id);
gauthier's avatar
gauthier committed
286
    } else {
287
      return;
288
    }
289
  } else {
290
    key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag);
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305
  }

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

  if (h_rc == HASH_TABLE_OK) {
    rlc_mode = rlc_union_p->mode;
  } else {
    rlc_mode = RLC_MODE_NONE;
    //AssertFatal (0 , "%s RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP);
  }

  struct mac_data_ind data_ind = mac_rlc_deserialize_tb(buffer_pP, tb_sizeP, num_tbP, crcs_pP);

  switch (rlc_mode) {
  case RLC_MODE_NONE:
CHIN-WEI, KANG's avatar
CHIN-WEI, KANG committed
306 307
      LOG_I(RLC,"NB-IoT: No Radio bearer configure for\n");

308 309 310 311
    //handle_event(WARNING,"FILE %s FONCTION mac_rlc_data_ind() LINE %s : no radio bearer configured :%d\n", __FILE__, __LINE__, channel_idP);
    break;

  case RLC_MODE_AM:
CHIN-WEI, KANG's avatar
CHIN-WEI, KANG committed
312
    LOG_I(RLC,"NB-IoT: AM\n");
313 314
    rlc_am_mac_data_indication(&ctxt, &rlc_union_p->rlc.am, data_ind);
    break;
315

316
  case RLC_MODE_UM:
CHIN-WEI, KANG's avatar
CHIN-WEI, KANG committed
317
      LOG_I(RLC,"NB-IoT: UM\n");
318 319
    rlc_um_mac_data_indication(&ctxt, &rlc_union_p->rlc.um, data_ind);
    break;
320

321
  case RLC_MODE_TM:
CHIN-WEI, KANG's avatar
CHIN-WEI, KANG committed
322 323
      LOG_I(RLC,"NB-IoT: TM\n");

324 325 326 327
    rlc_tm_mac_data_indication(&ctxt, &rlc_union_p->rlc.tm, data_ind);
    break;
  }

gauthier's avatar
gauthier committed
328
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_IND,VCD_FUNCTION_OUT);
329

330
}
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
331 332

//-------------------------------------------------------------------------------
333
mac_rlc_status_resp_t mac_rlc_status_ind(
334 335
  const module_id_t       module_idP,
  const rnti_t            rntiP,
336
  const eNB_index_t       eNB_index,
337
  const frame_t           frameP,
338
  const sub_frame_t 	  subframeP,
339 340 341 342 343 344
  const eNB_flag_t        enb_flagP,
  const MBMS_flag_t       MBMS_flagP,
  const logical_chan_id_t channel_idP,
  const tb_size_t         tb_sizeP)
{
  //-----------------------------------------------------------------------------
345
  mac_rlc_status_resp_t  mac_rlc_status_resp;
gauthier's avatar
gauthier committed
346 347
  struct mac_status_ind  tx_status;
  struct mac_status_resp status_resp;
348 349 350
  rlc_mode_t             rlc_mode    = RLC_MODE_NONE;
  rlc_mbms_id_t         *mbms_id_p   = NULL;
  rlc_union_t           *rlc_union_p = NULL;
351
  hash_key_t             key         = HASHTABLE_NOT_A_KEY_VALUE;
352
  hashtable_rc_t         h_rc;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
353
  srb_flag_t             srb_flag    = (channel_idP <= 3) ? SRB_FLAG_YES : SRB_FLAG_NO;
354
  protocol_ctxt_t     ctxt;
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
355

356
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, enb_flagP, rntiP, frameP, subframeP, eNB_index);
gauthier's avatar
gauthier committed
357

gauthier's avatar
gauthier committed
358
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_STATUS_IND,VCD_FUNCTION_IN);
gauthier's avatar
gauthier committed
359 360 361
  memset (&mac_rlc_status_resp, 0, sizeof(mac_rlc_status_resp_t));
  memset (&tx_status          , 0, sizeof(struct mac_status_ind));

362
#ifdef OAI_EMU
363

gauthier's avatar
gauthier committed
364
  if (MBMS_flagP)
365
    AssertFatal (channel_idP < RLC_MAX_MBMS_LC,
366
                 "%s channel id is too high (%u/%d) enb module id %u ue %u!\n",
367 368 369
                 (enb_flagP) ? "eNB" : "UE",
                 channel_idP,
                 RLC_MAX_MBMS_LC,
370 371
                 module_idP,
                 rntiP);
gauthier's avatar
gauthier committed
372
  else
373
    AssertFatal (channel_idP < NB_RB_MAX,
374
                 "%s channel id is too high (%u/%d) enb module id %u ue %u!\n",
375 376 377
                 (enb_flagP) ? "eNB" : "UE",
                 channel_idP,
                 NB_RB_MAX,
378 379 380 381
                 module_idP,
                 rntiP);

  CHECK_CTXT_ARGS(&ctxt);
382 383

#endif
384 385 386

  if (MBMS_flagP) {
    if (enb_flagP) {
387
      mbms_id_p = &rlc_mbms_lcid2service_session_id_eNB[module_idP][channel_idP];
388
    } else {
389
      mbms_id_p = &rlc_mbms_lcid2service_session_id_ue[module_idP][channel_idP];
390
    }
391

392
    key = RLC_COLL_KEY_MBMS_VALUE(module_idP, rntiP, enb_flagP, mbms_id_p->service_id, mbms_id_p->session_id);
393
  } else {
394
    key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag);
395 396 397 398
  }

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

CHIN-WEI, KANG's avatar
CHIN-WEI, KANG committed
399

400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
  if (h_rc == HASH_TABLE_OK) {
    rlc_mode = rlc_union_p->mode;
  } else {
    rlc_mode = RLC_MODE_NONE;
    //LOG_W(RLC , "[%s] RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP);
    //LOG_D(RLC , "[%s] RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP);
  }

  switch (rlc_mode) {
  case RLC_MODE_NONE:
    //handle_event(WARNING,"FILE %s FONCTION mac_rlc_data_ind() LINE %s : no radio bearer configured :%d\n", __FILE__, __LINE__, channel_idP);
    mac_rlc_status_resp.bytes_in_buffer                 = 0;
    break;

  case RLC_MODE_AM:
415
    status_resp = rlc_am_mac_status_indication(&ctxt, &rlc_union_p->rlc.am, tb_sizeP, tx_status,enb_flagP);
416 417 418 419 420 421 422 423
    mac_rlc_status_resp.bytes_in_buffer                 = status_resp.buffer_occupancy_in_bytes;
    mac_rlc_status_resp.head_sdu_creation_time          = status_resp.head_sdu_creation_time;
    mac_rlc_status_resp.head_sdu_remaining_size_to_send = status_resp.head_sdu_remaining_size_to_send;
    mac_rlc_status_resp.head_sdu_is_segmented           = status_resp.head_sdu_is_segmented;
    //return mac_rlc_status_resp;
    break;

  case RLC_MODE_UM:
424
    status_resp = rlc_um_mac_status_indication(&ctxt, &rlc_union_p->rlc.um, tb_sizeP, tx_status, enb_flagP);
425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
    mac_rlc_status_resp.bytes_in_buffer                 = status_resp.buffer_occupancy_in_bytes;
    mac_rlc_status_resp.pdus_in_buffer                  = status_resp.buffer_occupancy_in_pdus;
    mac_rlc_status_resp.head_sdu_creation_time          = status_resp.head_sdu_creation_time;
    mac_rlc_status_resp.head_sdu_remaining_size_to_send = status_resp.head_sdu_remaining_size_to_send;
    mac_rlc_status_resp.head_sdu_is_segmented           = status_resp.head_sdu_is_segmented;
    //   return mac_rlc_status_resp;
    break;

  case RLC_MODE_TM:
    status_resp = rlc_tm_mac_status_indication(&ctxt, &rlc_union_p->rlc.tm, tb_sizeP, tx_status);
    mac_rlc_status_resp.bytes_in_buffer = status_resp.buffer_occupancy_in_bytes;
    mac_rlc_status_resp.pdus_in_buffer  = status_resp.buffer_occupancy_in_pdus;
    // return mac_rlc_status_resp;
    break;

  default:
    mac_rlc_status_resp.bytes_in_buffer                 = 0 ;
  }

gauthier's avatar
gauthier committed
444
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_STATUS_IND,VCD_FUNCTION_OUT);
Wolfgang A. Mozart's avatar
Wolfgang A. Mozart committed
445

446
  return mac_rlc_status_resp;
447 448
}

449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
//-----------------------------------------------------------------------------
rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind(
  const module_id_t       module_idP,
  const rnti_t            rntiP,
  const eNB_index_t       eNB_index,
  const frame_t           frameP,
  const sub_frame_t 	  subframeP,
  const eNB_flag_t        enb_flagP,
  const logical_chan_id_t channel_idP)
{
  //-----------------------------------------------------------------------------
  rlc_buffer_occupancy_t  mac_rlc_buffer_occupancy_resp = 0;
  rlc_mode_t             rlc_mode    = RLC_MODE_NONE;
  rlc_union_t           *rlc_union_p = NULL;
  hash_key_t             key         = HASHTABLE_NOT_A_KEY_VALUE;
  hashtable_rc_t         h_rc;
  srb_flag_t             srb_flag    = (channel_idP <= 2) ? SRB_FLAG_YES : SRB_FLAG_NO;
  protocol_ctxt_t     ctxt;

  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, enb_flagP, rntiP, frameP, 0, eNB_index);

  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_GET_BUFFER_OCCUPANCY_IND,VCD_FUNCTION_IN);


  /* Assumptions : for UE only */
  /* At each TTI, Buffer Occupancy is first computed in mac_rlc_status_ind called by MAC ue_scheduler() function */
  /* Then this function is called during MAC multiplexing ue_get_sdu(), and it may be call several times for the same bearer if it is in AM mode and there are several PDU types to transmit */
  AssertFatal(enb_flagP == FALSE,"RLC Tx mac_rlc_get_buffer_occupancy_ind function is not implemented for eNB LcId=%d\n", channel_idP);


  key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag);


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

CHIN-WEI, KANG's avatar
CHIN-WEI, KANG committed
484

485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
  if (h_rc == HASH_TABLE_OK) {
    rlc_mode = rlc_union_p->mode;
  } else {
    rlc_mode = RLC_MODE_NONE;
    //LOG_W(RLC , "[%s] RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP);
    //LOG_D(RLC , "[%s] RLC not configured rb id %u lcid %u module %u!\n", __FUNCTION__, rb_id, channel_idP, ue_module_idP);
  }

  switch (rlc_mode) {
   case RLC_MODE_AM:
    mac_rlc_buffer_occupancy_resp = rlc_am_get_buffer_occupancy_in_bytes(&ctxt, &rlc_union_p->rlc.am);
    break;

  case RLC_MODE_UM:
	mac_rlc_buffer_occupancy_resp = rlc_um_get_buffer_occupancy(&rlc_union_p->rlc.um);
    break;

  default:
	  mac_rlc_buffer_occupancy_resp                 = 0 ;
  }

  //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_GET_BUFFER_OCCUPANCY_IND,VCD_FUNCTION_OUT);

  return mac_rlc_buffer_occupancy_resp;
}