eNB_scheduler_dlsch.c 107 KB
Newer Older
1
/*******************************************************************************
nikaeinn's avatar
nikaeinn committed
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

nikaeinn's avatar
nikaeinn committed
5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9 10


nikaeinn's avatar
nikaeinn committed
11 12 13 14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

nikaeinn's avatar
nikaeinn committed
16 17
    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is
18 19
    included in this distribution in the file called "COPYING". If not,
    see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
nikaeinn's avatar
nikaeinn committed
22 23 24 25
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
nikaeinn's avatar
nikaeinn committed
27 28 29 30 31

*******************************************************************************/

/*! \file eNB_scheduler_dlsch.c
 * \brief procedures related to eNB for the DLSCH transport channel
32
 * \author  Navid Nikaein and Raymond Knopp
nikaeinn's avatar
nikaeinn committed
33
 * \date 2010 - 2014
34
 * \email: navid.nikaein@eurecom.fr
nikaeinn's avatar
nikaeinn committed
35
 * \version 1.0
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
 * @ingroup _mac

 */

#include "assertions.h"
#include "PHY/defs.h"
#include "PHY/extern.h"

#include "SCHED/defs.h"
#include "SCHED/extern.h"

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/proto.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"

#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"

//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"

62 63
#include "SIMULATION/TOOLS/defs.h" // for taus

64 65 66 67 68
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

#define ENABLE_MAC_PAYLOAD_DEBUG
69
//#define DEBUG_eNB_SCHEDULER 1
70

gauthier's avatar
gauthier committed
71

72

73 74 75 76 77 78 79 80 81 82
//------------------------------------------------------------------------------
void
add_ue_dlsch_info(
  module_id_t module_idP,
  int CC_id,
  int UE_id,
  sub_frame_t subframeP,
  UE_DLSCH_STATUS status
)
//------------------------------------------------------------------------------
83
{
84

85 86 87 88
  eNB_dlsch_info[module_idP][CC_id][UE_id].rnti             = UE_RNTI(module_idP,UE_id);
  //  eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight           = weight;
  eNB_dlsch_info[module_idP][CC_id][UE_id].subframe         = subframeP;
  eNB_dlsch_info[module_idP][CC_id][UE_id].status           = status;
89

90
  eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++;
91 92 93

}

94 95 96 97 98 99 100 101
//------------------------------------------------------------------------------
int
schedule_next_dlue(
  module_id_t module_idP,
  int CC_id,
  sub_frame_t subframeP
)
//------------------------------------------------------------------------------
102
{
103

104 105
  int next_ue;
  UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list;
106

107
  for (next_ue=UE_list->head; next_ue>=0; next_ue=UE_list->next[next_ue] ) {
108
    if  (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_WAITING) {
109
      return next_ue;
110
    }
111
  }
112 113

  for (next_ue=UE_list->head; next_ue>=0; next_ue=UE_list->next[next_ue] ) {
114 115
    if  (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_BUFFERED) {
      eNB_dlsch_info[module_idP][CC_id][next_ue].status = S_DL_WAITING;
116
    }
117 118 119
  }

  return(-1);//next_ue;
120 121 122

}

123 124 125
//------------------------------------------------------------------------------
unsigned char
generate_dlsch_header(
126 127 128 129 130 131 132 133 134
  unsigned char* mac_header,
  unsigned char num_sdus,
  unsigned short *sdu_lengths,
  unsigned char *sdu_lcids,
  unsigned char drx_cmd,
  short timing_advance_cmd,
  unsigned char *ue_cont_res_id,
  unsigned char short_padding,
  unsigned short post_padding
135 136
)
//------------------------------------------------------------------------------
137
{
138 139 140 141 142 143 144 145 146 147

  SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *)mac_header;
  uint8_t first_element=0,last_size=0,i;
  uint8_t mac_header_control_elements[16],*ce_ptr;

  ce_ptr = &mac_header_control_elements[0];

  // compute header components

  if ((short_padding == 1) || (short_padding == 2)) {
148 149 150 151 152
    mac_header_ptr->R    = 0;
    mac_header_ptr->E    = 0;
    mac_header_ptr->LCID = SHORT_PADDING;
    first_element=1;
    last_size=1;
153
  }
154

155
  if (short_padding == 2) {
156 157 158 159 160 161
    mac_header_ptr->E = 1;
    mac_header_ptr++;
    mac_header_ptr->R = 0;
    mac_header_ptr->E    = 0;
    mac_header_ptr->LCID = SHORT_PADDING;
    last_size=1;
162 163 164
  }

  if (drx_cmd != 255) {
165 166 167
    if (first_element>0) {
      mac_header_ptr->E = 1;
      mac_header_ptr++;
168
    } else {
169 170
      first_element=1;
    }
171

172 173 174 175
    mac_header_ptr->R = 0;
    mac_header_ptr->E    = 0;
    mac_header_ptr->LCID = DRX_CMD;
    last_size=1;
176 177 178
  }

  if (timing_advance_cmd != 0) {
179 180 181
    if (first_element>0) {
      mac_header_ptr->E = 1;
      mac_header_ptr++;
182
    } else {
183 184
      first_element=1;
    }
185

186 187 188 189 190 191
    mac_header_ptr->R = 0;
    mac_header_ptr->E    = 0;
    mac_header_ptr->LCID = TIMING_ADV_CMD;
    last_size=1;
    //    msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
    ((TIMING_ADVANCE_CMD *)ce_ptr)->R=0;
192
    ((TIMING_ADVANCE_CMD *)ce_ptr)->TA=(timing_advance_cmd+31)&0x3f;
193
    LOG_D(MAC,"timing advance =%d (%d)\n",timing_advance_cmd,((TIMING_ADVANCE_CMD *)ce_ptr)->TA);
194 195
    ce_ptr+=sizeof(TIMING_ADVANCE_CMD);
    //msg("offset %d\n",ce_ptr-mac_header_control_elements);
196 197 198
  }

  if (ue_cont_res_id) {
199 200 201
    if (first_element>0) {
      mac_header_ptr->E = 1;
      /*
202 203 204 205
      printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
      ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
      ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
      ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
206 207
      */
      mac_header_ptr++;
208
    } else {
209 210
      first_element=1;
    }
211

212 213 214 215
    mac_header_ptr->R = 0;
    mac_header_ptr->E    = 0;
    mac_header_ptr->LCID = UE_CONT_RES;
    last_size=1;
216

217
    LOG_T(MAC,"[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
218 219 220 221 222 223 224
          ue_cont_res_id[0],
          ue_cont_res_id[1],
          ue_cont_res_id[2],
          ue_cont_res_id[3],
          ue_cont_res_id[4],
          ue_cont_res_id[5]);

225 226 227
    memcpy(ce_ptr,ue_cont_res_id,6);
    ce_ptr+=6;
    // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
228 229 230 231
  }

  //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);

232
  for (i=0; i<num_sdus; i++) {
233
    LOG_T(MAC,"[eNB] Generate DLSCH header num sdu %d len sdu %d\n",num_sdus, sdu_lengths[i]);
234

235 236 237
    if (first_element>0) {
      mac_header_ptr->E = 1;
      /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
238 239 240
      ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
      ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
      ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
241 242 243
      */
      mac_header_ptr+=last_size;
      //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
244
    } else {
245 246
      first_element=1;
    }
247

248 249 250 251 252 253 254
    if (sdu_lengths[i] < 128) {
      ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R    = 0;
      ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E    = 0;
      ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F    = 0;
      ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i];
      ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L    = (unsigned char)sdu_lengths[i];
      last_size=2;
255
    } else {
256 257 258 259 260 261 262 263
      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R    = 0;
      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E    = 0;
      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F    = 1;
      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i];
      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB    = ((unsigned short) sdu_lengths[i]>>8)&0x7f;
      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB    = (unsigned short) sdu_lengths[i]&0xff;
      ((SCH_SUBHEADER_LONG *)mac_header_ptr)->padding   = 0x00;
      last_size=3;
264
#ifdef DEBUG_HEADER_PARSING
265
      LOG_D(MAC,"[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n",
266 267 268
            sdu_lengths[i],
            ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB,
            ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB);
269
#endif
270
    }
271
  }
272

273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
  /*

    printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);

    printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
    ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
    ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
    ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);


    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->LCID < UE_CONT_RES) {
    if (((SCH_SUBHEADER_SHORT*)mac_header_ptr)->F == 0)
    printf("F = 0, sdu len (L field) %d\n",(((SCH_SUBHEADER_SHORT*)mac_header_ptr)->L));
    else
    printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L));
    }
289
  */
290
  if (post_padding>0) {// we have lots of padding at the end of the packet
291 292 293 294 295 296 297
    mac_header_ptr->E = 1;
    mac_header_ptr+=last_size;
    // add a padding element
    mac_header_ptr->R    = 0;
    mac_header_ptr->E    = 0;
    mac_header_ptr->LCID = SHORT_PADDING;
    mac_header_ptr++;
298
  } else { // no end of packet padding
299 300
    // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE)
    mac_header_ptr++;
301 302 303 304 305
  }

  //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header);

  if ((ce_ptr-mac_header_control_elements) > 0) {
306 307 308
    // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements);
    memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements);
    mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements);
309
  }
310

311 312 313 314 315 316
  //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header);

  return((unsigned char*)mac_header_ptr - mac_header);

}

317 318 319 320 321 322 323 324 325 326 327
//------------------------------------------------------------------------------
void
set_ul_DAI(
  int module_idP,
  int UE_idP,
  int CC_idP,
  int frameP,
  int subframeP,
  LTE_DL_FRAME_PARMS*  frame_parms[MAX_NUM_CCs]
)
//------------------------------------------------------------------------------
328 329
{

330 331 332
  eNB_MAC_INST         *eNB      = &eNB_mac_inst[module_idP];
  UE_list_t            *UE_list  = &eNB->UE_list;
  unsigned char         DAI;
333

334 335
  if (frame_parms[CC_idP]->frame_type == TDD) {
    DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI-1)&3;
336
    LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n",module_idP,CC_idP,frameP,subframeP,DAI,UE_idP);
337
    // Save DAI for Format 0 DCI
338

339 340 341 342
    switch (frame_parms[CC_idP]->tdd_config) {
    case 0:
      //      if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6))
      break;
343

344 345 346
    case 1:
      switch (subframeP) {
      case 1:
347 348 349
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI;
        break;

350
      case 4:
351 352 353
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI;
        break;

354
      case 6:
355 356 357
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
        break;

358
      case 9:
359 360
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
        break;
361
      }
362

363 364
    case 2:
      //      if ((subframeP==3)||(subframeP==8))
365
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
366
      break;
367

368
    case 3:
369

370 371 372 373
      //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) {
      //  LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1);
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI;
      //}
374
      switch (subframeP) {
375 376 377
      case 5:
      case 6:
      case 1:
378 379 380
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
        break;

381 382
      case 7:
      case 8:
383 384 385
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
        break;

386 387
      case 9:
      case 0:
388 389 390
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI;
        break;

391
      default:
392
        break;
393
      }
394

395
      break;
396

397 398
    case 4:
      //      if ((subframeP==8)||(subframeP==9))
399
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
400
      break;
401

402 403
    case 5:
      //      if (subframeP==8)
404
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
405
      break;
406

407 408
    case 6:
      //      if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9))
409
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
410
      break;
411

412 413 414 415 416 417
    default:
      break;
    }
  }
}

418

419 420 421
//------------------------------------------------------------------------------
void
schedule_ue_spec(
422 423 424 425 426 427
  module_id_t   module_idP,
  frame_t       frameP,
  sub_frame_t   subframeP,
  unsigned int  *nb_rb_used0,
  unsigned int  *nCCE_used,
  int*           mbsfn_flag
428 429
)
//------------------------------------------------------------------------------
430
{
431

432
  uint8_t               CC_id;
433 434
  int                   UE_id;
  uint16_t              nCCE[MAX_NUM_CCs];
435
  int                   N_RBG[MAX_NUM_CCs];
436 437 438 439
  unsigned char         aggregation;
  mac_rlc_status_resp_t rlc_status;
  unsigned char         header_len_dcch=0, header_len_dcch_tmp=0,header_len_dtch=0,header_len_dtch_tmp=0, ta_len=0;
  unsigned char         sdu_lcids[11],offset,num_sdus=0;
440
  uint16_t              nb_rb,nb_rb_temp,total_nb_available_rb[MAX_NUM_CCs],nb_available_rb;
441
  uint16_t              TBS,j,sdu_lengths[11],rnti,padding=0,post_padding=0;
442 443 444 445 446
  unsigned char         dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
  unsigned char         round            = 0;
  unsigned char         harq_pid         = 0;
  void                 *DLSCH_dci        = NULL;
  LTE_eNB_UE_stats     *eNB_UE_stats     = NULL;
447
  uint16_t              sdu_length_total = 0;
448
  unsigned char         DAI;
449 450 451 452
  int                   i                = 0;
  uint8_t               dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
  unsigned char         rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBG_MAX];
  uint16_t              pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
453
  int                   mcs;
454
  uint16_t              min_rb_unit[MAX_NUM_CCs];
455
  short                 ta_update        = 0;
456 457
  eNB_MAC_INST         *eNB      = &eNB_mac_inst[module_idP];
  UE_list_t            *UE_list  = &eNB->UE_list;
458
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs];
459 460
  int                   continue_flag=0;

461
  if (UE_list->head==-1) {
462
    return;
463
  }
464

465
  start_meas(&eNB->schedule_dlsch);
gauthier's avatar
gauthier committed
466
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_IN);
467 468 469 470

  //weight = get_ue_weight(module_idP,UE_id);
  aggregation = 1; // set to the maximum aggregation level

471
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
472
    min_rb_unit[CC_id]=get_min_rb_unit(module_idP,CC_id);
473
    frame_parms[CC_id] = mac_xface->get_lte_frame_parms(module_idP,CC_id);
474
    total_nb_available_rb[CC_id] = frame_parms[CC_id]->N_RB_DL - nb_rb_used0[CC_id];
475
    nCCE[CC_id] = mac_xface->get_nCCE_max(module_idP,CC_id) - nCCE_used[CC_id];
476 477
    N_RBG[CC_id] = frame_parms[CC_id]->N_RBG;

478
    // store the global enb stats:
479 480 481 482 483 484
    eNB->eNB_stats[CC_id].num_dlactive_UEs =  UE_list->num_UEs;
    eNB->eNB_stats[CC_id].available_prbs =  total_nb_available_rb[CC_id];
    eNB->eNB_stats[CC_id].total_available_prbs +=  total_nb_available_rb[CC_id];
    eNB->eNB_stats[CC_id].available_ncces = nCCE[CC_id];
    eNB->eNB_stats[CC_id].dlsch_bytes_tx=0;
    eNB->eNB_stats[CC_id].dlsch_pdus_tx=0;
485
  }
486

487
  /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band)
488

gauthier's avatar
gauthier committed
489
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_IN);
490
  start_meas(&eNB->schedule_dlsch_preprocessor);
491
  dlsch_scheduler_pre_processor(module_idP,
492 493 494 495 496 497 498
                                frameP,
                                subframeP,
                                dl_pow_off,
                                pre_nb_available_rbs,
                                N_RBG,
                                rballoc_sub_UE,
                                mbsfn_flag);
499
  stop_meas(&eNB->schedule_dlsch_preprocessor);
gauthier's avatar
gauthier committed
500
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_OUT);
501

502 503

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
504
    LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n",CC_id);
505

506 507
    if (mbsfn_flag[CC_id]>0)
      continue;
508 509

    for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
510
      continue_flag=0; // reset the flag to allow allocation for the remaining UEs
511
      rnti = UE_RNTI(module_idP,UE_id);
512
      eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
513

514
      if (rnti==NOT_A_RNTI) {
515 516 517
        LOG_D(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_list->num_UEs);
        // mac_xface->macphy_exit("Cannot find rnti for UE_id");
        continue_flag=1;
518
      }
519

520
      if (eNB_UE_stats==NULL) {
521 522 523
        LOG_D(MAC,"[eNB] Cannot find eNB_UE_stats\n");
        //  mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
        continue_flag=1;
524
      }
525

526
      if ((pre_nb_available_rbs[CC_id][UE_id] == 0) || (nCCE[CC_id] < (1<<aggregation))) {
527 528 529 530 531 532
        LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
              module_idP, frameP, UE_id, CC_id, nb_rb_used0[CC_id], pre_nb_available_rbs[CC_id][UE_id], nCCE[CC_id], aggregation);
        //if(mac_xface->get_transmission_mode(module_idP,rnti)==5)
        continue_flag=1; //to next user (there might be rbs availiable for other UEs in TM5
        // else
        //  break;
533
      }
534

535
      if (frame_parms[CC_id]->frame_type == TDD)  {
536 537 538 539 540 541 542
        set_ue_dai (subframeP,
                    frame_parms[CC_id]->tdd_config,
                    UE_id,
                    CC_id,
                    UE_list);
        // update UL DAI after DLSCH scheduling
        set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP,frame_parms);
543 544 545

      }

546 547 548 549 550 551 552
      if (continue_flag == 1 ) {
        add_ue_dlsch_info(module_idP,
                          CC_id,
                          UE_id,
                          subframeP,
                          S_DL_NONE);
        continue;
553
      }
554

555 556
      nb_available_rb = pre_nb_available_rbs[CC_id][UE_id];
      UE_list->eNB_UE_stats[CC_id][UE_id].crnti= rnti;
557
      UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status=mac_eNB_get_rrc_status(module_idP,rnti);
558
      mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,0);
559 560
      UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid;
      UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round;
561

562 563
      sdu_length_total=0;
      num_sdus=0;
564 565 566 567 568

      /*
      DevCheck(((eNB_UE_stats->DL_cqi[0] < MIN_CQI_VALUE) || (eNB_UE_stats->DL_cqi[0] > MAX_CQI_VALUE)),
      eNB_UE_stats->DL_cqi[0], MIN_CQI_VALUE, MAX_CQI_VALUE);
      */
569
      eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]];
570
      eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
571

572

573
#ifdef EXMIMO
574

575
      if (mac_xface->get_transmission_mode(module_idP,CC_id, rnti)==5) {
576
        eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,16);
577
      }
578

579
#endif
580

581
      // store stats
582
      UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->DL_cqi[0];
583

584
      // initializing the rb allocation indicator for each UE
585 586
      for(j=0; j<frame_parms[CC_id]->N_RBG; j++) {
        UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0;
587 588
      }

589
      LOG_D(MAC,"[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, ncc %d, rrc %d)\n",
590 591 592 593 594 595
            module_idP, frameP, UE_id,CC_id,rnti,harq_pid, round,nb_available_rb,
            eNB_UE_stats->DL_cqi[0], eNB_UE_stats->dlsch_mcs1,
            nCCE[CC_id],
            UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status);


596 597
      // Note this code is for a specific DCI format
      DLSCH_dci = (void *)UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid];
598 599


600 601
      /* process retransmission  */

602
      if (round > 0) {
603 604 605 606

        if (frame_parms[CC_id]->frame_type == TDD) {
          UE_list->UE_template[CC_id][UE_id].DAI++;
          update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI);
607 608
          LOG_D(MAC,"DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n",
                CC_id,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].DAI);
609 610 611 612 613 614 615 616
        }

        // get freq_allocation
        nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];

        if (nb_rb <= nb_available_rb) {

          if(nb_rb == pre_nb_available_rbs[CC_id][UE_id]) {
617
            for(j=0; j<frame_parms[CC_id]->N_RBG; j++) { // for indicating the rballoc for each sub-band
618
              UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = rballoc_sub_UE[CC_id][UE_id][j];
619
            }
620 621 622 623 624 625 626 627 628 629
          } else {
            nb_rb_temp = nb_rb;
            j = 0;

            while((nb_rb_temp > 0) && (j<frame_parms[CC_id]->N_RBG)) {
              if(rballoc_sub_UE[CC_id][UE_id][j] == 1) {
                UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = rballoc_sub_UE[CC_id][UE_id][j];

                if((j == frame_parms[CC_id]->N_RBG-1) &&
                    ((frame_parms[CC_id]->N_RB_DL == 25)||
630
                     (frame_parms[CC_id]->N_RB_DL == 50))) {
631
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1;
632
                } else {
633
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id];
634
                }
635 636 637 638 639 640 641 642 643 644 645 646 647 648 649
              }

              j = j+1;
            }
          }

          nb_available_rb -= nb_rb;
          aggregation = process_ue_cqi(module_idP,UE_id);
          nCCE[CC_id]-=(1<<aggregation); // adjust the remaining nCCE
          nCCE_used[CC_id] += (1<<aggregation);


          PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
          PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[CC_id][UE_id];

650
          for(j=0; j<frame_parms[CC_id]->N_RBG; j++) {
651
            PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];
652
          }
653 654 655 656 657 658 659 660 661 662 663 664

          switch (mac_xface->get_transmission_mode(module_idP,CC_id,rnti)) {
          case 1:
          case 2:
          default:
            switch (frame_parms[CC_id]->N_RB_DL) {
            case 6:
              if (frame_parms[CC_id]->frame_type == TDD) {
                //        ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rv       = round&3;
                ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->dai      = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
665 666
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,(UE_list->UE_template[CC_id][UE_id].DAI-1),
667
                      ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->mcs);
668 669 670 671
              } else {
                //        ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rv       = round&3;
672 673
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->mcs);
674 675 676 677 678 679 680 681 682 683 684

              }

              break;

            case 25:
              if (frame_parms[CC_id]->frame_type == TDD) {
                //        ((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rv       = round&3;
                ((DCI1_5MHz_TDD_t*)DLSCH_dci)->dai      = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
685 686
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,(UE_list->UE_template[CC_id][UE_id].DAI-1),
687
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs);
688 689 690 691
              } else {
                //        ((DCI1_5MHz_FDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rv       = round&3;
692 693
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs);
694 695 696 697 698 699 700 701 702 703 704

              }

              break;

            case 50:
              if (frame_parms[CC_id]->frame_type == TDD) {
                //        ((DCI1_10MHz_TDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_10MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rv       = round&3;
                ((DCI1_10MHz_TDD_t*)DLSCH_dci)->dai      = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
705 706
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,(UE_list->UE_template[CC_id][UE_id].DAI-1),
707
                      ((DCI1_10MHz_TDD_t*)DLSCH_dci)->mcs);
708 709 710 711
              } else {
                //        ((DCI1_10MHz_FDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_10MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rv       = round&3;
712 713
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,((DCI1_10MHz_FDD_t*)DLSCH_dci)->mcs);
714 715 716 717 718 719 720 721 722 723 724

              }

              break;

            case 100:
              if (frame_parms[CC_id]->frame_type == TDD) {
                //        ((DCI1_20MHz_TDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_20MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rv       = round&3;
                ((DCI1_20MHz_TDD_t*)DLSCH_dci)->dai      = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
725 726
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,(UE_list->UE_template[CC_id][UE_id].DAI-1),
727
                      ((DCI1_20MHz_TDD_t*)DLSCH_dci)->mcs);
728 729 730 731
              } else {
                //        ((DCI1_20MHz_FDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_20MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rv       = round&3;
732 733
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,((DCI1_20MHz_FDD_t*)DLSCH_dci)->mcs);
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763

              }

              break;
            }

            break;

          case 4:
            //    if (nb_rb>10) {
            ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 0;
            ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
            ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
            // }
            //else {
            //  ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->ndi1 = 0;
            // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
            // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rv1 = round&3;
            // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
            // }
            break;

          case 5:
            // if(nb_rb>10){
            //((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->mcs = eNB_UE_stats->DL_cqi[0]<<1;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 0;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;

764
            if(dl_pow_off[CC_id][UE_id] == 2) {
765
              dl_pow_off[CC_id][UE_id] = 1;
766
            }
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794

            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = dl_pow_off[CC_id][UE_id];
            // }
            break;

          case 6:
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 0;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = 1;//dl_pow_off[UE_id];
            break;
          }

          add_ue_dlsch_info(module_idP,
                            CC_id,
                            UE_id,
                            subframeP,
                            S_DL_SCHEDULED);

          //eNB_UE_stats->dlsch_trials[round]++;
          UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission+=1;
          UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx=nb_rb;
          UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx+=nb_rb;
          UE_list->eNB_UE_stats[CC_id][UE_id].ncce_used_retx=nCCE[CC_id];
          UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1;
          UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=eNB_UE_stats->dlsch_mcs1;
        } else {
795 796
          LOG_D(MAC,"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
                module_idP, frameP, CC_id, UE_id);
797 798 799 800 801 802 803 804 805 806 807 808
        }
      } else { /* This is a potentially new SDU opportunity */

        rlc_status.bytes_in_buffer = 0;
        // Now check RLC information to compute number of required RBs
        // get maximum TBS size for RLC request
        //TBS = mac_xface->get_TBS(eNB_UE_stats->DL_cqi[0]<<1,nb_available_rb);
        TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb);
        // check first for RLC data on DCCH
        // add the length for  all the control elements (timing adv, drx, etc) : header + payload

        //#ifndef EXMIMO_IOT
809
        // to be checked by RK, NN, FK
810
        uint8_t update_TA=4;
811 812

        switch (frame_parms[CC_id]->N_RB_DL) {
813 814 815
        case 6:
          update_TA = 1;
          break;
816

817 818 819
        case 25:
          update_TA = 4;
          break;
820

821 822 823
        case 50:
          update_TA = 8;
          break;
824

825 826 827
        case 100:
          update_TA = 16;
          break;
828 829 830 831 832 833 834 835 836 837 838 839
        }

        ta_len = ((eNB_UE_stats->timing_advance_update/update_TA)!=0) ? 2 : 0;
        /*#else
        ta_len = 0;
        #endif*/

        header_len_dcch = 2; // 2 bytes DCCH SDU subheader

        if ( TBS-ta_len-header_len_dcch > 0 ) {
          rlc_status = mac_rlc_status_ind(
                         module_idP,
840
                         rnti,
841
			 module_idP,
842 843 844 845 846 847 848 849 850
                         frameP,
                         ENB_FLAG_YES,
                         MBMS_FLAG_NO,
                         DCCH,
                         (TBS-ta_len-header_len_dcch)); // transport block set size

          sdu_lengths[0]=0;

          if (rlc_status.bytes_in_buffer > 0) {  // There is DCCH to transmit
851 852
            LOG_D(MAC,"[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
                  module_idP,frameP,CC_id,TBS-header_len_dcch);
853 854
            sdu_lengths[0] += mac_rlc_data_req(
                                module_idP,
855
                                rnti,
856
				module_idP,
857 858 859 860 861 862
                                frameP,
                                ENB_FLAG_YES,
                                MBMS_FLAG_NO,
                                DCCH,
                                (char *)&dlsch_buffer[sdu_lengths[0]]);

863
            LOG_D(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",module_idP,CC_id,sdu_lengths[0]);
864 865 866 867 868
            sdu_length_total = sdu_lengths[0];
            sdu_lcids[0] = DCCH;
            UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH]+=1;
            UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH]+=sdu_lengths[0];
            num_sdus = 1;
869
#ifdef DEBUG_eNB_SCHEDULER
870
            LOG_T(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes :",module_idP,CC_id,sdu_lengths[0]);
871

872
            for (j=0; j<sdu_lengths[0]; j++) {
873
              LOG_T(MAC,"%x ",dlsch_buffer[j]);
874
            }
875 876 877 878 879 880 881 882 883 884 885 886 887

            LOG_T(MAC,"\n");
#endif
          } else {
            header_len_dcch = 0;
            sdu_length_total = 0;
          }
        }

        // check for DCCH1 and update header information (assume 2 byte sub-header)
        if (TBS-ta_len-header_len_dcch-sdu_length_total > 0 ) {
          rlc_status = mac_rlc_status_ind(
                         module_idP,
888
                         rnti,
889
			 module_idP,
890 891 892 893 894 895 896 897
                         frameP,
                         ENB_FLAG_YES,
                         MBMS_FLAG_NO,
                         DCCH+1,
                         (TBS-ta_len-header_len_dcch-sdu_length_total)); // transport block set size less allocations for timing advance and
          // DCCH SDU

          if (rlc_status.bytes_in_buffer > 0) {
898 899
            LOG_D(MAC,"[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
                  module_idP,frameP,CC_id,TBS-header_len_dcch-sdu_length_total);
900 901
            sdu_lengths[num_sdus] += mac_rlc_data_req(
                                       module_idP,
902
                                       rnti,
903
				       module_idP,
904 905 906 907 908 909 910 911 912 913 914 915
                                       frameP,
                                       ENB_FLAG_YES,
                                       MBMS_FLAG_NO,
                                       DCCH+1,
                                       (char *)&dlsch_buffer[sdu_lengths[0]]);

            sdu_lcids[num_sdus] = DCCH1;
            sdu_length_total += sdu_lengths[num_sdus];
            header_len_dcch += 2;
            UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1]+=1;
            UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1]+=sdu_lengths[num_sdus];
            num_sdus++;
916
            LOG_D(MAC,"[eNB %d] CC_id %d Got %d bytes for DCCH from RLC\n",module_idP,CC_id,sdu_lengths[0]);
917 918 919 920 921 922 923 924
          }
        }

        // check for DTCH and update header information
        // here we should loop over all possible DTCH

        header_len_dtch = 3; // 3 bytes DTCH SDU subheader

925 926
        LOG_D(MAC,"[eNB %d], Frame %d, DTCH->DLSCH, CC_id %d, Checking RLC status (rab %d, tbs %d, len %d)\n",
              module_idP,frameP,CC_id,DTCH,TBS,
927 928 929 930 931
              TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch);

        if (TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch > 0 ) {
          rlc_status = mac_rlc_status_ind(
                         module_idP,
932
                         rnti,
933
			 module_idP,
934 935 936 937 938 939 940 941
                         frameP,
                         ENB_FLAG_YES,
                         MBMS_FLAG_NO,
                         DTCH,
                         TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch);

          if (rlc_status.bytes_in_buffer > 0) {

942 943
            LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB], Frame %d, DTCH->DLSCH, CC_id %d, Requesting %d bytes from RLC (hdr len dtch %d)\n",
                  module_idP,frameP,CC_id,TBS-header_len_dcch-sdu_length_total-header_len_dtch,header_len_dtch);
944 945
            sdu_lengths[num_sdus] = mac_rlc_data_req(
                                      module_idP,
946
                                      rnti,
947
				      module_idP,
948 949 950 951 952 953
                                      frameP,
                                      ENB_FLAG_YES,
                                      MBMS_FLAG_NO,
                                      DTCH,
                                      (char*)&dlsch_buffer[sdu_length_total]);

954 955
            LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] CC_id %d Got %d bytes for DTCH %d \n",
                  module_idP,CC_id,sdu_lengths[num_sdus],DTCH);
956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988
            sdu_lcids[num_sdus] = DTCH;
            sdu_length_total += sdu_lengths[num_sdus];
            UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DTCH]+=1;
            UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DTCH]+=sdu_lengths[num_sdus];

            if (sdu_lengths[num_sdus] < 128) {
              header_len_dtch=2;
            }

            num_sdus++;
          } else {
            header_len_dtch = 0;
          }
        }

        // there is a payload
        if (((sdu_length_total + header_len_dcch + header_len_dtch )> 0)) {

          // Now compute number of required RBs for total sdu length
          // Assume RAH format 2
          // adjust  header lengths
          header_len_dcch_tmp = header_len_dcch;
          header_len_dtch_tmp = header_len_dtch;

          if (header_len_dtch==0) {
            header_len_dcch = (header_len_dcch >0) ? 1 : header_len_dcch;  // remove length field
          } else {
            header_len_dtch = (header_len_dtch > 0) ? 1 :header_len_dtch;     // remove length field for the last SDU
          }


          mcs = eNB_UE_stats->dlsch_mcs1;

989 990 991 992 993
          if (mcs==0) {
            nb_rb = 4;  // don't let the TBS get too small
          } else {
            nb_rb=min_rb_unit[CC_id];
          }
994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023

          TBS = mac_xface->get_TBS_DL(mcs,nb_rb);

          while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len))  {
            nb_rb += min_rb_unit[CC_id];  //

            if (nb_rb>nb_available_rb) { // if we've gone beyond the maximum number of RBs
              // (can happen if N_RB_DL is odd)
              TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb);
              nb_rb = nb_available_rb;
              break;
            }

            TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_rb);
          }

          if(nb_rb == pre_nb_available_rbs[CC_id][UE_id]) {
            for(j=0; j<frame_parms[CC_id]->N_RBG; j++) { // for indicating the rballoc for each sub-band
              UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = rballoc_sub_UE[CC_id][UE_id][j];
            }
          } else {
            nb_rb_temp = nb_rb;
            j = 0;

            while((nb_rb_temp > 0) && (j<frame_parms[CC_id]->N_RBG)) {
              if(rballoc_sub_UE[CC_id][UE_id][j] == 1) {
                UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = rballoc_sub_UE[CC_id][UE_id][j];

                if ((j == frame_parms[CC_id]->N_RBG-1) &&
                    ((frame_parms[CC_id]->N_RB_DL == 25)||
1024
                     (frame_parms[CC_id]->N_RB_DL == 50))) {
1025
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1;
1026
                } else {
1027
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id];
1028
                }
1029 1030 1031 1032 1033 1034 1035 1036 1037
              }

              j = j+1;
            }
          }

          PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
          PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[CC_id][UE_id];

1038
          for(j=0; j<frame_parms[CC_id]->N_RBG; j++) {
1039 1040
            PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];

1041
          }
1042 1043 1044 1045 1046 1047 1048 1049

          // decrease mcs until TBS falls below required length
          while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) {
            mcs--;
            TBS = mac_xface->get_TBS_DL(mcs,nb_rb);
          }

          // if we have decreased too much or we don't have enough RBs, increase MCS
1050 1051
          while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && ((( dl_pow_off[CC_id][UE_id]>0) && (mcs<28))
                 || ( (dl_pow_off[CC_id][UE_id]==0) && (mcs<=15)))) {
1052 1053 1054 1055 1056 1057 1058
            mcs++;
            TBS = mac_xface->get_TBS_DL(mcs,nb_rb);
          }

          LOG_D(MAC,"dlsch_mcs before and after the rate matching = (%d, %d)\n",eNB_UE_stats->dlsch_mcs1, mcs);

#ifdef DEBUG_eNB_SCHEDULER
1059 1060
          LOG_D(MAC,"[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n",
                module_idP,CC_id,mcs,TBS,nb_rb);
1061 1062
          // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n",
          //  TBS, sdu_length_total, offset, TBS-sdu_length_total-offset);
1063
#endif
1064 1065 1066 1067 1068 1069 1070 1071

          if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) {
            padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len);
            post_padding = 0;
          } else {
            padding = 0;

            // adjust the header len
1072
            if (header_len_dtch==0) {
1073
              header_len_dcch = header_len_dcch_tmp;
1074
            } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2)))
1075
              header_len_dtch = header_len_dtch_tmp;
1076
            }
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096

            post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len ; // 1 is for the postpadding header
          }

          //#ifndef EXMIMO_IOT
          ta_update = eNB_UE_stats->timing_advance_update/update_TA;
          /*#else
          ta_update = 0;
          #endif*/

          offset = generate_dlsch_header((unsigned char*)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
                                         // offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0],
                                         num_sdus,              //num_sdus
                                         sdu_lengths,  //
                                         sdu_lcids,
                                         255,                                   // no drx
                                         ta_update, // timing advance
                                         NULL,                                  // contention res id
                                         padding,
                                         post_padding);
1097

1098
          //#ifdef DEBUG_eNB_SCHEDULER
1099 1100
          if (ta_update) {
            LOG_I(MAC,
1101 1102 1103
                  "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n",
                  module_idP,frameP, UE_id, CC_id, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset,
                  ta_update,padding,post_padding,mcs,TBS,nb_rb,header_len_dcch,header_len_dtch);
1104
          }
1105 1106

          //#endif
1107
#ifdef DEBUG_eNB_SCHEDULER
1108 1109
          LOG_T(MAC,"[eNB %d] First 16 bytes of DLSCH : \n");

1110
          for (i=0; i<16; i++) {
1111
            LOG_T(MAC,"%x.",dlsch_buffer[i]);
1112
          }
1113 1114

          LOG_T(MAC,"\n");
1115
#endif
1116 1117 1118 1119 1120
          // cycle through SDUs and place in dlsch_buffer
          memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total);
          // memcpy(&eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]);

          // fill remainder of DLSCH with random data
1121
          for (j=0; j<(TBS-sdu_length_total-offset); j++) {
1122
            UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff);
1123
          }
1124 1125

          //eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset+sdu_lengths[0]+j] = (char)(taus()&0xff);
1126 1127 1128 1129
          if (opt_enabled == 1) {
            trace_pdu(1, (uint8_t *)UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0],
                      TBS, module_idP, 3, UE_RNTI(module_idP,UE_id),
                      eNB->subframe,0,0);
1130 1131
            LOG_D(OPT,"[eNB %d][DLSCH] CC_id %d Frame %d  rnti %x  with size %d\n",
                  module_idP, CC_id, frameP, UE_RNTI(module_idP,UE_id), TBS);
1132 1133 1134
          }

          aggregation = process_ue_cqi(module_idP,UE_id);
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171