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

  Eurecom OpenAirInterface
  Copyright(c) 1999 - 2010 Eurecom

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope 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.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Contact Information
  Openair Admin: openair_admin@eurecom.fr
  Openair Tech : openair_tech@eurecom.fr
  Forums       : http://forums.eurecom.fsr/openairinterface
  Address      : Eurecom, 2229, route des crĂȘtes, 06560 Valbonne Sophia Antipolis, France

 *******************************************************************************/
/*! \file eNB_scheduler.c
 * \brief procedures related to UE on the DLSCH transport channel
 * \author  Navid Nikaein and Raymond Knopp
 * \date 2011
 * \email: navid.nikaein@eurecom.fr
 * \version 0.5
 * @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 "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/defs.h"
#include "ARCH/CBMIMO1/DEVICE_DRIVER/from_grlib_softregs.h"

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

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

#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

#define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1


// function for determining which active ue should be granted resources in downlink based on CQI, SI, and BSR
uint8_t find_dlgranted_UEs(module_id_t module_idP){

  // all active users should be granted
  return(find_active_UEs(module_idP));
}

void add_ue_dlsch_info(module_id_t module_idP, module_id_t ue_mod_idP, sub_frame_t subframeP, UE_DLSCH_STATUS status){

  eNB_dlsch_info[module_idP][ue_mod_idP].rnti             = find_UE_RNTI(module_idP,ue_mod_idP);
  //  eNB_dlsch_info[module_idP][ue_mod_idP].weight           = weight;
  eNB_dlsch_info[module_idP][ue_mod_idP].subframe         = subframeP;
  eNB_dlsch_info[module_idP][ue_mod_idP].status           = status;

  eNB_dlsch_info[module_idP][ue_mod_idP].serving_num++;

}

module_id_t schedule_next_dlue(module_id_t module_idP, sub_frame_t subframeP){

  module_id_t next_ue;

  for (next_ue=0; next_ue < NUMBER_OF_UE_MAX; next_ue++ ){
      if  (eNB_dlsch_info[module_idP][next_ue].status == S_DL_WAITING)
        return next_ue;
  }
  for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ )
    if  (eNB_dlsch_info[module_idP][next_ue].status == S_DL_BUFFERED) {
        eNB_dlsch_info[module_idP][next_ue].status = S_DL_WAITING;
    }
  // next_ue = -1;
  return (module_id_t)(-1);//next_ue;

}

unsigned char generate_dlsch_header(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) {

  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)) {
      mac_header_ptr->R    = 0;
      mac_header_ptr->E    = 0;
      mac_header_ptr->LCID = SHORT_PADDING;
      first_element=1;
      last_size=1;
  }
  if (short_padding == 2) {
      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;
  }

  if (drx_cmd != 255) {
      if (first_element>0) {
          mac_header_ptr->E = 1;
          mac_header_ptr++;
      }
      else {
          first_element=1;
      }
      mac_header_ptr->R = 0;
      mac_header_ptr->E    = 0;
      mac_header_ptr->LCID = DRX_CMD;
      last_size=1;
  }

  if (timing_advance_cmd != 0) {
      if (first_element>0) {
          mac_header_ptr->E = 1;
          mac_header_ptr++;
      }
      else {
          first_element=1;
      }
      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;
      ((TIMING_ADVANCE_CMD *)ce_ptr)->TA=timing_advance_cmd&0x3f;
      LOG_I(MAC,"timing advance =%d (%d)\n",timing_advance_cmd,((TIMING_ADVANCE_CMD *)ce_ptr)->TA);
      ce_ptr+=sizeof(TIMING_ADVANCE_CMD);
      //msg("offset %d\n",ce_ptr-mac_header_control_elements);
  }

  if (ue_cont_res_id) {
      if (first_element>0) {
          mac_header_ptr->E = 1;
          /*
	   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);
           */
          mac_header_ptr++;
      }
      else {
          first_element=1;
      }

      mac_header_ptr->R = 0;
      mac_header_ptr->E    = 0;
      mac_header_ptr->LCID = UE_CONT_RES;
      last_size=1;

      LOG_T(MAC,"[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
          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]);

      memcpy(ce_ptr,ue_cont_res_id,6);
      ce_ptr+=6;
      // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
  }

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

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

      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,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
           */
          mac_header_ptr+=last_size;
          //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
      }
      else {
          first_element=1;
      }
      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;
      }
      else {
          ((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;
#ifdef DEBUG_HEADER_PARSING
          LOG_D(MAC,"[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n",
              sdu_lengths[i],
              ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB,
              ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB);
#endif
      }
  }
  /*

    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));
    }
   */
  if (post_padding>0) {// we have lots of padding at the end of the packet
      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++;
  }
  else { // no end of packet padding
      // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE)
      mac_header_ptr++;
  }

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

  if ((ce_ptr-mac_header_control_elements) > 0) {
      // 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);
  }
  //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header);

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

}


void schedule_ue_spec(module_id_t   module_idP,
                      frame_t       frameP,
                      sub_frame_t   subframeP,
                      uint16_t           nb_rb_used0,
                      unsigned int *nCCE_used,
                      int           mbsfn_flag) {

  module_id_t           ue_mod_id          = -1;
  module_id_t           next_ue          = -1;
  unsigned char         granted_UEs      = 0;
  uint16_t                   nCCE;
  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;
  uint16_t                   nb_rb,nb_rb_temp,nb_available_rb,TBS,j,sdu_lengths[11],rnti,padding=0,post_padding=0;
  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;
  uint16_t                   sdu_length_total = 0;
  unsigned char         DAI;
  uint16_t                   i                = 0;
  uint8_t                    dl_pow_off[NUMBER_OF_UE_MAX];
  unsigned char         rballoc_sub_UE[NUMBER_OF_UE_MAX][N_RBGS_MAX];
  uint16_t                   pre_nb_available_rbs[NUMBER_OF_UE_MAX];
  int                   mcs;
  uint16_t                   min_rb_unit;
  short                 ta_update        = 0;

  if (mbsfn_flag>0)
    return;

  reset_meas(&eNB_mac_inst[module_idP].schedule_dlsch);

  switch (mac_xface->lte_frame_parms->N_RB_DL) {
  case 6:
    min_rb_unit=1;
    break;
  case 25:
    min_rb_unit=2;
    break;
  case 50:
    min_rb_unit=3;
    break;
  case 100:
    min_rb_unit=4;
    break;
  default:
    min_rb_unit=2;
    break;
  }

  //int **rballoc_sub = (int **)malloc(1792*sizeof(int *));
  granted_UEs = find_dlgranted_UEs(module_idP);


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


  /// Initialization for pre-processor
  for(i=0;i<NUMBER_OF_UE_MAX;i++){
      pre_nb_available_rbs[i] = 0;
      dl_pow_off[i] = 2;
      for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++){
          //       rballoc_sub[j] = 0;
          rballoc_sub_UE[i][j] = 0;
      }
  }


  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
      PHY_vars_eNB_g[module_idP]->mu_mimo_mode[i].pre_nb_available_rbs = 0;
      for (j = 0; j < mac_xface->lte_frame_parms->N_RBGS; j++) {
          PHY_vars_eNB_g[module_idP]->mu_mimo_mode[i].rballoc_sub[j] = 0;
      }
  }


  // set current available nb_rb and nCCE to maximum
  nb_available_rb = mac_xface->lte_frame_parms->N_RB_DL - nb_rb_used0;
  nCCE = mac_xface->get_nCCE_max(module_idP) - *nCCE_used;

  // store the goloabl enb stats
  eNB_mac_inst[module_idP].eNB_stats.num_dlactive_UEs =  granted_UEs;
  eNB_mac_inst[module_idP].eNB_stats.available_prbs =  nb_available_rb;
  eNB_mac_inst[module_idP].eNB_stats.total_available_prbs +=  nb_available_rb;
  eNB_mac_inst[module_idP].eNB_stats.available_ncces = nCCE;
  eNB_mac_inst[module_idP].eNB_stats.dlsch_bytes_tx=0;
  eNB_mac_inst[module_idP].eNB_stats.dlsch_pdus_tx=0;


  /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band)
  start_meas(&eNB_mac_inst[module_idP].schedule_dlsch_preprocessor);
  dlsch_scheduler_pre_processor(module_idP,
				frameP,
				subframeP,
				dl_pow_off,
				pre_nb_available_rbs,
				mac_xface->lte_frame_parms->N_RBGS,
				rballoc_sub_UE);
  stop_meas(&eNB_mac_inst[module_idP].schedule_dlsch_preprocessor);

  for (ue_mod_id=0;ue_mod_id<granted_UEs;ue_mod_id++) {

      rnti = find_UE_RNTI(module_idP,ue_mod_id);

      eNB_mac_inst[module_idP].eNB_UE_stats[ue_mod_id].crnti= rnti;
      eNB_mac_inst[module_idP].eNB_UE_stats[ue_mod_id].rrc_status=mac_get_rrc_status(module_idP,1,ue_mod_id);
      if (rnti==0) {
          LOG_E(MAC,"Cannot find rnti for UE_id %d (granted UEs %d)\n",ue_mod_id,granted_UEs);
          mac_xface->macphy_exit("Cannot find rnti for UE_id");//continue;
      }

      eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,rnti);
      if (eNB_UE_stats==NULL)
        mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");

      // Get candidate harq_pid from PHY
      mac_xface->get_ue_active_harq_pid(module_idP,rnti,subframeP,&harq_pid,&round,0);
      //    printf("Got harq_pid %d, round %d\n",harq_pid,round);


      nb_available_rb = pre_nb_available_rbs[ue_mod_id];

      if ((nb_available_rb == 0) || (nCCE < (1<<aggregation))) {
          LOG_D(MAC,"UE %d: nb_availiable_rb exhausted (nb_rb_used %d, nb_available_rb %d, nCCE %d, aggregation %d)\n",
              ue_mod_id, nb_rb_used0, nb_available_rb, nCCE, aggregation);
          //if(mac_xface->get_transmission_mode(module_idP,rnti)==5)
          continue; //to next user (there might be rbs availiable for other UEs in TM5
          // else
          //	break;
      }
      sdu_length_total=0;
      num_sdus=0;

      // get Round-Robin allocation
      next_ue = ue_mod_id;//schedule_next_dlue(module_idP,subframeP); // next scheduled user
      // If nobody is left, exit while loop and go to next step
      if (next_ue == 255)
        break;

      if (mac_xface->lte_frame_parms->frame_type == TDD) {
          switch (mac_xface->lte_frame_parms->tdd_config) {
          case 0:
            if ((subframeP==0)||(subframeP==1)||(subframeP==3)||(subframeP==5)||(subframeP==6)||(subframeP==8))
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0;
          case 1:
            if ((subframeP==0)||(subframeP==4)||(subframeP==5)||(subframeP==9))
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0;
            break;
          case 2:
            if ((subframeP==4)||(subframeP==5))
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0;
            break;
          case 3:
            if ((subframeP==5)||(subframeP==7)||(subframeP==9))
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0;
            break;
          case 4:
            if ((subframeP==0)||(subframeP==6))
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0;
            break;
          case 5:
            if (subframeP==9)
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0;
            break;
          case 6:
            if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6)||(subframeP==9))
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI = 0;
          default:
            break;
          }
      }

      // This is an allocated UE_id
      rnti = find_UE_RNTI(module_idP,next_ue);
      if (rnti==0)
        continue;

      eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,rnti);

      if (eNB_UE_stats==NULL)
        mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");

      if (openair_daq_vars.target_ue_dl_mcs <= 0) {
	eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]];
	LOG_T(MAC,"CQI %d\n",eNB_UE_stats->DL_cqi[0]);
      }
      else
	eNB_UE_stats->dlsch_mcs1 = openair_daq_vars.target_ue_dl_mcs;


      if(eNB_UE_stats->dlsch_mcs1>22)
        eNB_UE_stats->dlsch_mcs1=22;


      // for TM5, limit the MCS to 16QAM


      // for EXMIMO, limit the MCS to 16QAM as well
#ifdef EXMIMO
      eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,16);
#endif

      // Get candidate harq_pid from PHY
      mac_xface->get_ue_active_harq_pid(module_idP,rnti,subframeP,&harq_pid,&round,0);

      eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].harq_pid = harq_pid;
      eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].harq_round = round;
      // Note this code is for a specific DCI format
      DLSCH_dci = (void *)eNB_mac_inst[module_idP].UE_template[next_ue].DLSCH_DCI[harq_pid];

      for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++){ // initializing the rb allocation indicator for each UE
          eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j] = 0;
      }
      // store stats
      eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].dl_cqi= eNB_UE_stats->DL_cqi[0];

      if (round > 0) {
          if (mac_xface->lte_frame_parms->frame_type == TDD) {
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI++;
              LOG_D(MAC,"DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,next_ue,eNB_mac_inst[module_idP].UE_template[next_ue].DAI);

              update_ul_dci(module_idP,rnti,eNB_mac_inst[module_idP].UE_template[next_ue].DAI);
          }

          // get freq_allocation
          nb_rb = eNB_mac_inst[module_idP].UE_template[next_ue].nb_rb[harq_pid];
          if (nb_rb <= nb_available_rb) {

              if(nb_rb == pre_nb_available_rbs[next_ue]){
                  for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++) // for indicating the rballoc for each sub-band
                    eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j] = rballoc_sub_UE[next_ue][j];}
              else
                {
                  nb_rb_temp = nb_rb;
                  j = 0;
                  while((nb_rb_temp > 0) && (j<mac_xface->lte_frame_parms->N_RBGS)){
                      if(rballoc_sub_UE[next_ue][j] == 1){
                          eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j] = rballoc_sub_UE[next_ue][j];
                          if((j == mac_xface->lte_frame_parms->N_RBGS-1) &&
                              ((mac_xface->lte_frame_parms->N_RB_DL == 25)||
                                  (mac_xface->lte_frame_parms->N_RB_DL == 50)))
                            nb_rb_temp = nb_rb_temp - min_rb_unit+1;
                          else
                            nb_rb_temp = nb_rb_temp - min_rb_unit;
                      }
                      j = j+1;
                  }
                }

              nb_available_rb -= nb_rb;
              aggregation = process_ue_cqi(module_idP,next_ue);
              nCCE-=(1<<aggregation); // adjust the remaining nCCE
              *nCCE_used += (1<<aggregation);


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

              for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++)
                PHY_vars_eNB_g[module_idP]->mu_mimo_mode[next_ue].rballoc_sub[j] = eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j];

              switch (mac_xface->get_transmission_mode(module_idP,rnti)) {
              case 1:
              case 2:
              default:
                switch (mac_xface->lte_frame_parms->N_RB_DL) {
                case 6:
                  if (mac_xface->lte_frame_parms->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      = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                      LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1),((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->mcs);
                  }
                  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;
                      LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->mcs);

                  }
                  break;
                case 25:
                  if (mac_xface->lte_frame_parms->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      = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                      LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1),((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs);
                  }
                  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;
                      LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs);

                  }
                  break;
                case 50:
                  if (mac_xface->lte_frame_parms->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      = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                      LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1),((DCI1_10MHz_TDD_t*)DLSCH_dci)->mcs);
                  }
                  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;
                      LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_10MHz_FDD_t*)DLSCH_dci)->mcs);

                  }
                  break;
                case 100:
                  if (mac_xface->lte_frame_parms->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      = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                      LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, dai %d, mcs %d\n",module_idP,harq_pid,round,(eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1),((DCI1_20MHz_TDD_t*)DLSCH_dci)->mcs);
                  }
                  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;
                      LOG_D(MAC,"[eNB %d] Retransmission : harq_pid %d, round %d, mcs %d\n",module_idP,harq_pid,round,((DCI1_20MHz_FDD_t*)DLSCH_dci)->mcs);

                  }
                  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 = (eNB_mac_inst[module_idP].UE_template[next_ue].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 = (eNB_mac_inst[module_idP].UE_template[next_ue].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 = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                  if(dl_pow_off[next_ue] == 2)
                    dl_pow_off[next_ue] = 1;
                  ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = dl_pow_off[next_ue];
                  // }
                  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 = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                  ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = 1;//dl_pow_off[next_ue];
                  break;
              }

              add_ue_dlsch_info(module_idP,
                  next_ue,
                  subframeP,
                  S_DL_SCHEDULED);

              //eNB_UE_stats->dlsch_trials[round]++;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_retransmission+=1;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].rbs_used_retx=nb_rb;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].total_rbs_used_retx+=nb_rb;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].ncce_used_retx=nCCE;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].dlsch_mcs2=eNB_UE_stats->dlsch_mcs1;
          }
          else { // don't schedule this UE, its retransmission takes more resources than we have

          }
      }
      else {  // This is a potentially new SDU opportunity

          // calculate mcs

          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
          ta_len = ((eNB_UE_stats->timing_advance_update/4)!=0) ? 2 : 0;
#else
          ta_len = 0;
#endif

          header_len_dcch = 2; // 2 bytes DCCH SDU subheader


          rlc_status = mac_rlc_status_ind(
              module_idP,
              ue_mod_id,
              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
              LOG_D(MAC,"[eNB %d] Frame %d, DL-DCCH->DLSCH, Requesting %d bytes from RLC (RRC message)\n",module_idP,frameP,TBS-header_len_dcch);
              sdu_lengths[0] += mac_rlc_data_req(
                  module_idP,
                  ue_mod_id,
                  frameP,
                  ENB_FLAG_YES,
                  MBMS_FLAG_NO,
                  DCCH,
                  (char *)&dlsch_buffer[sdu_lengths[0]]);

              LOG_D(MAC,"[eNB %d][DCCH] Got %d bytes from RLC\n",module_idP,sdu_lengths[0]);
              sdu_length_total = sdu_lengths[0];
              sdu_lcids[0] = DCCH;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_pdu_tx[DCCH]+=1;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_bytes_tx[DCCH]+=sdu_lengths[0];
              num_sdus = 1;
#ifdef DEBUG_eNB_SCHEDULER
              LOG_T(MAC,"[eNB %d][DCCH] Got %d bytes :",module_idP,sdu_lengths[0]);
              for (j=0;j<sdu_lengths[0];j++)
                LOG_T(MAC,"%x ",dlsch_buffer[j]);
              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)
          rlc_status = mac_rlc_status_ind(
              module_idP,
              ue_mod_id,
              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) {
              LOG_D(MAC,"[eNB %d], Frame %d, DCCH1->DLSCH, Requesting %d bytes from RLC (RRC message)\n",
                            module_idP,frameP,TBS-header_len_dcch-sdu_length_total);
              sdu_lengths[num_sdus] += mac_rlc_data_req(
                  module_idP,
                  ue_mod_id,
                  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;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_pdu_tx[DCCH1]+=1;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_bytes_tx[DCCH1]+=sdu_lengths[num_sdus];
              num_sdus++;
              LOG_D(MAC,"[eNB %d] Got %d bytes for DCCH from RLC\n",module_idP,sdu_lengths[0]);
          }
          // check for DTCH and update header information
          // here we should loop over all possible DTCH

          header_len_dtch = 3; // 3 bytes DTCH SDU subheader

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

          rlc_status = mac_rlc_status_ind(
              module_idP,
              ue_mod_id,
              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) {

              LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB], Frame %d, DTCH->DLSCH, Requesting %d bytes from RLC (hdr len dtch %d)\n",
                  module_idP,frameP,TBS-header_len_dcch-sdu_length_total-header_len_dtch,header_len_dtch);
              sdu_lengths[num_sdus] = mac_rlc_data_req(
                  module_idP,
                  ue_mod_id,
                  frameP,
                  ENB_FLAG_YES,
                  MBMS_FLAG_NO,
                  DTCH,
                  (char*)&dlsch_buffer[sdu_length_total]);

              LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",module_idP,sdu_lengths[num_sdus],DTCH);
              sdu_lcids[num_sdus] = DTCH;
              sdu_length_total += sdu_lengths[num_sdus];
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].num_pdu_tx[DTCH]+=1;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].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;
              if (mcs==0) nb_rb = 4;   // don't let the TBS get too small
              else nb_rb=min_rb_unit;

              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;  //
                  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[next_ue]) {
                for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++) {// for indicating the rballoc for each sub-band
                  eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j] = rballoc_sub_UE[next_ue][j];
                }
              } else
                {
                  nb_rb_temp = nb_rb;
                  j = 0;
                  while((nb_rb_temp > 0) && (j<mac_xface->lte_frame_parms->N_RBGS)){
                      if(rballoc_sub_UE[next_ue][j] == 1){
                          eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j] = rballoc_sub_UE[next_ue][j];
                          if ((j == mac_xface->lte_frame_parms->N_RBGS-1) &&
                              ((mac_xface->lte_frame_parms->N_RB_DL == 25)||
                                  (mac_xface->lte_frame_parms->N_RB_DL == 50)))
                            nb_rb_temp = nb_rb_temp - min_rb_unit+1;
                          else
                            nb_rb_temp = nb_rb_temp - min_rb_unit;
                      }
                      j = j+1;
                  }
                }

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

              for(j=0;j<mac_xface->lte_frame_parms->N_RBGS;j++)
                PHY_vars_eNB_g[module_idP]->mu_mimo_mode[next_ue].rballoc_sub[j] = eNB_mac_inst[module_idP].UE_template[next_ue].rballoc_subband[harq_pid][j];


              // 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
              while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && ((( dl_pow_off[next_ue]>0) && (mcs<28)) || ( (dl_pow_off[next_ue]==0) && (mcs<=15)))) {
                  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
              LOG_D(MAC,"[eNB %d] Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n",
                  module_idP,mcs,TBS,nb_rb);
              // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n",
              //	TBS, sdu_length_total, offset, TBS-sdu_length_total-offset);
#endif

              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
                  if (header_len_dtch==0)
                    header_len_dcch = header_len_dcch_tmp;
                  else //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2)))
                    header_len_dtch = header_len_dtch_tmp;

                  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/4;
#else
              ta_update = 0;
#endif

              offset = generate_dlsch_header((unsigned char*)eNB_mac_inst[module_idP].DLSCH_pdu[(module_id_t)next_ue][0].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);
              //#ifdef DEBUG_eNB_SCHEDULER
              LOG_I(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Generate header : sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, next_ue %d,padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n",
                  module_idP,sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],offset,
                  ta_len,next_ue,padding,post_padding,mcs,TBS,nb_rb,header_len_dcch,header_len_dtch);
              //#endif

              LOG_T(MAC,"[eNB %d] First 16 bytes of DLSCH : \n");
              for (i=0;i<16;i++)
                LOG_T(MAC,"%x.",dlsch_buffer[i]);
              LOG_T(MAC,"\n");

              // cycle through SDUs and place in dlsch_buffer
              memcpy(&eNB_mac_inst[module_idP].DLSCH_pdu[(module_id_t)next_ue][0].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
              for (j=0;j<(TBS-sdu_length_total-offset);j++)
                eNB_mac_inst[module_idP].DLSCH_pdu[(module_id_t)next_ue][0].payload[0][offset+sdu_length_total+j] = (char)(taus()&0xff);
              //eNB_mac_inst[0].DLSCH_pdu[0][0].payload[0][offset+sdu_lengths[0]+j] = (char)(taus()&0xff);

#if defined(USER_MODE) && defined(OAI_EMU)
              /* Tracing of PDU is done on UE side */
              if (oai_emulation.info.opt_enabled)
                trace_pdu(1, (uint8_t *)eNB_mac_inst[module_idP].DLSCH_pdu[(module_id_t)next_ue][0].payload[0],
                    TBS, module_idP, 3, find_UE_RNTI(module_idP,next_ue),
                    eNB_mac_inst[module_idP].subframe,0,0);
              LOG_D(OPT,"[eNB %d][DLSCH] Frame %d  rnti %x  with size %d\n",
                  module_idP, frameP, find_UE_RNTI(module_idP,next_ue), TBS);
#endif

              aggregation = process_ue_cqi(module_idP,next_ue);
              nCCE-=(1<<aggregation); // adjust the remaining nCCE
              *nCCE_used+=(1<<aggregation); // adjust the remaining nCCE
              eNB_mac_inst[module_idP].UE_template[next_ue].nb_rb[harq_pid] = nb_rb;

              add_ue_dlsch_info(module_idP,
                  next_ue,
                  subframeP,
                  S_DL_SCHEDULED);
              // store stats
              eNB_mac_inst[module_idP].eNB_stats.dlsch_bytes_tx+=sdu_length_total;
              eNB_mac_inst[module_idP].eNB_stats.dlsch_pdus_tx+=1;

              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].rbs_used = nb_rb;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].total_rbs_used += nb_rb;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].ncce_used = nCCE;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].dlsch_mcs2=mcs;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].TBS = TBS;

              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].overhead_bytes= TBS- sdu_length_total;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].total_sdu_bytes+= sdu_length_total;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].total_pdu_bytes+= TBS;
              eNB_mac_inst[module_idP].eNB_UE_stats[next_ue].total_num_pdus+=1;

              if (mac_xface->lte_frame_parms->frame_type == TDD) {
                  eNB_mac_inst[module_idP].UE_template[next_ue].DAI++;
                  //	printf("DAI update: subframeP %d: UE %d, DAI %d\n",subframeP,next_ue,eNB_mac_inst[module_idP].UE_template[next_ue].DAI);
#warning only for 5MHz channel 
                  update_ul_dci(module_idP,rnti,eNB_mac_inst[module_idP].UE_template[next_ue].DAI);
              }

              switch (mac_xface->get_transmission_mode(module_idP,rnti)) {
              case 1:
              case 2:
              default:
                if (mac_xface->lte_frame_parms->frame_type == TDD) {
                    switch (mac_xface->lte_frame_parms->N_RB_DL) {
                    case 6:
                      ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->mcs = mcs;
                      ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                      ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid];
                      ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rv = 0;
                      ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->dai      = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                      break;
                    case 25:
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs = mcs;
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid];
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rv = 0;
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->dai      = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                      LOG_D(MAC,"Format1 DCI: harq_pid %d, ndi %d\n",harq_pid,((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi);
                      break;
                    case 50:
                      ((DCI1_10MHz_TDD_t*)DLSCH_dci)->mcs = mcs;
                      ((DCI1_10MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                      ((DCI1_10MHz_TDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid];
                      ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rv = 0;
                      ((DCI1_10MHz_TDD_t*)DLSCH_dci)->dai      = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                      break;
                    case 100:
                      ((DCI1_20MHz_TDD_t*)DLSCH_dci)->mcs = mcs;
                      ((DCI1_20MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                      ((DCI1_20MHz_TDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid];
                      ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rv = 0;
                      ((DCI1_20MHz_TDD_t*)DLSCH_dci)->dai      = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                      break;
                    default:
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs = mcs;
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid];
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rv = 0;
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->dai      = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                      break;
                    }
                }
                else {
                    switch (mac_xface->lte_frame_parms->N_RB_DL) {
                    case 6:
                      ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->mcs = mcs;
                      ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                      ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid];
                      ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rv = 0;
                      break;
                    case 25:
                      ((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs = mcs;
                      ((DCI1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                      ((DCI1_5MHz_FDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid];
                      ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rv = 0;
                      break;
                    case 50:
                      ((DCI1_10MHz_FDD_t*)DLSCH_dci)->mcs = mcs;
                      ((DCI1_10MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                      ((DCI1_10MHz_FDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid];
                      ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rv = 0;
                      break;
                    case 100:
                      ((DCI1_20MHz_FDD_t*)DLSCH_dci)->mcs = mcs;
                      ((DCI1_20MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                      ((DCI1_20MHz_FDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid];
                      ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rv = 0;
                      break;
                    default:
                      ((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs = mcs;
                      ((DCI1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                      ((DCI1_5MHz_FDD_t*)DLSCH_dci)->ndi = 1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid];
                      ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rv = 0;
                      break;
                    }
                }
                break;
              case 4:
                //  if (nb_rb>10) {
                ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->mcs1 = mcs;
                ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 1;
                ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rv1 = round&3;
                ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;

                //}
                /* else {
	     ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->mcs1 = eNB_UE_stats->DL_cqi[0];
	     ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
	     ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->ndi1 = 1;
	     ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rv1 = round&3;
	     ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->tpmi = 5;
	     ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
	     }*/
                break;
              case 5:

                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->mcs = mcs;
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 1;
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3;
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                if(dl_pow_off[next_ue] == 2)
                  dl_pow_off[next_ue] = 1;
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = dl_pow_off[next_ue];
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->tpmi = 5;
                break;
              case 6:
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->mcs = mcs;
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 1;
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3;
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = 1;
                ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->tpmi = 5;
                break;
              }
              // Toggle NDI for next time
              LOG_D(MAC,"Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n",frameP,subframeP,next_ue,
                  eNB_mac_inst[module_idP].UE_template[next_ue].rnti,harq_pid,eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]);
              eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid]=1-eNB_mac_inst[module_idP].UE_template[next_ue].oldNDI[harq_pid];
          }

          else {  // There is no data from RLC or MAC header, so don't schedule

          }
      }
      if (mac_xface->lte_frame_parms->frame_type == TDD) {
          DAI = (eNB_mac_inst[module_idP].UE_template[next_ue].DAI-1)&3;
          LOG_D(MAC,"[eNB %d] Frame %d: DAI %d for UE %d\n",module_idP,frameP,DAI,next_ue);
          // Save DAI for Format 0 DCI

          switch (mac_xface->lte_frame_parms->tdd_config) {
          case 0:
            //      if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6))
            break;
          case 1:
            switch (subframeP) {
            case 1:
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[7] = DAI;
              break;
            case 4:
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[8] = DAI;
              break;
            case 6:
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[2] = DAI;
              break;
            case 9:
              eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[3] = DAI;
              break;
            }
            case 2:
              //      if ((subframeP==3)||(subframeP==8))
              //	eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul = DAI;
              break;
            case 3:
              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);
                  eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul[((subframeP+8)%10)>>1] = DAI;
              }
              break;
            case 4:
              //      if ((subframeP==8)||(subframeP==9))
              //	eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul = DAI;
              break;
            case 5:
              //      if (subframeP==8)
              //	eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul = DAI;
              break;
            case 6:
              //      if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9))
              //	eNB_mac_inst[module_idP].UE_template[next_ue].DAI_ul = DAI;
              break;
            default:
              break;
          }
      }
      //printf("MAC nCCE : %d\n",*nCCE_used);
  }
  stop_meas(&eNB_mac_inst[module_idP].schedule_dlsch);
}

void fill_DLSCH_dci(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,uint32_t RBalloc,uint8_t RA_scheduled,int mbsfn_flag) {

  // loop over all allocated UEs and compute frequency allocations for PDSCH
  module_id_t   ue_mod_id = -1;
  uint8_t            first_rb,nb_rb=3;
  rnti_t        rnti;
  unsigned char vrb_map[100];
  uint8_t            rballoc_sub[mac_xface->lte_frame_parms->N_RBGS];
  //uint8_t number_of_subbands=13;
  uint32_t           rballoc = RBalloc;

  unsigned char round;
  unsigned char harq_pid;
  void         *DLSCH_dci=NULL;
  DCI_PDU      *DCI_pdu= &eNB_mac_inst[module_idP].DCI_pdu;
  int           i;
  void         *BCCH_alloc_pdu=(void*)&eNB_mac_inst[module_idP].BCCH_alloc_pdu;
  int           size_bits,size_bytes;

  if (mbsfn_flag>0)
    return;

  start_meas(&eNB_mac_inst[module_idP].fill_DLSCH_dci);

  // clear vrb_map
  memset(vrb_map,0,100);

  // SI DLSCH
  //  printf("BCCH check\n");
  if (eNB_mac_inst[module_idP].bcch_active == 1) {
      eNB_mac_inst[module_idP].bcch_active = 0;
      LOG_D(MAC,"[eNB %d] Frame %d subframeP %d: BCCH active\n", module_idP, frameP, subframeP);
      // randomize frequency allocation for SI
      first_rb = (unsigned char)(taus()%(mac_xface->lte_frame_parms->N_RB_DL-4));
      if (mac_xface->lte_frame_parms->frame_type == TDD) {

      }
      else {
          BCCH_alloc_pdu_fdd.rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
          rballoc |= mac_xface->get_rballoc(BCCH_alloc_pdu_fdd.vrb_type,BCCH_alloc_pdu_fdd.rballoc);
      }

      vrb_map[first_rb] = 1;
      vrb_map[first_rb+1] = 1;
      vrb_map[first_rb+2] = 1;
      vrb_map[first_rb+3] = 1;

      if (mac_xface->lte_frame_parms->frame_type == TDD) {
          switch (mac_xface->lte_frame_parms->N_RB_DL) {
          case 6:
            ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
            ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1;
            ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0;
            ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1;
            ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1;
            ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0;
            ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1;
            ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0;
            rballoc |= mac_xface->get_rballoc(0,((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc);
            add_common_dci(DCI_pdu,
                BCCH_alloc_pdu,
                SI_RNTI,
                sizeof(DCI1A_1_5MHz_TDD_1_6_t),
                2,
                sizeof_DCI1A_1_5MHz_TDD_1_6_t,
                format1A,0);
            break;
          case 25:
            ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
            ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1;
            ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0;
            ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1;
            ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1;
            ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0;
            ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1;
            ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0;
            rballoc |= mac_xface->get_rballoc(0,((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc);
            add_common_dci(DCI_pdu,
                BCCH_alloc_pdu,
                SI_RNTI,
                sizeof(DCI1A_5MHz_TDD_1_6_t),
                2,
                sizeof_DCI1A_5MHz_TDD_1_6_t,
                format1A,0);
            break;
          case 50:
            ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
            ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1;
            ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0;
            ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1;
            ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1;
            ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0;
            ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1;
            ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0;
            rballoc |= mac_xface->get_rballoc(0,((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc);
            add_common_dci(DCI_pdu,
                BCCH_alloc_pdu,
                SI_RNTI,
                sizeof(DCI1A_10MHz_TDD_1_6_t),
                2,
                sizeof_DCI1A_10MHz_TDD_1_6_t,
                format1A,0);
            break;
          case 100:
            ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
            ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->type = 1;
            ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->vrb_type = 0;
            ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->ndi = 1;
            ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rv = 1;
            ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->harq_pid = 0;
            ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->TPC = 1;
            ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->padding = 0;
            rballoc |= mac_xface->get_rballoc(0,((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->rballoc);
            add_common_dci(DCI_pdu,
                BCCH_alloc_pdu,
                SI_RNTI,
                sizeof(DCI1A_20MHz_TDD_1_6_t),
                2,
                sizeof_DCI1A_20MHz_TDD_1_6_t,
                format1A,0);
            break;
          }
      }
      else {
          switch (mac_xface->lte_frame_parms->N_RB_DL) {
          case 6:
            ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
            ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->type = 1;
            ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0;
            ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1;
            ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1;
            ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0;
            ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1;
            ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0;

            rballoc |= mac_xface->get_rballoc(0,((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc);
            add_common_dci(DCI_pdu,
                BCCH_alloc_pdu,
                SI_RNTI,
                sizeof(DCI1A_1_5MHz_FDD_t),
                2,
                sizeof_DCI1A_1_5MHz_FDD_t,
                format1A,0);
            break;
          case 25:
            ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
            ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->type = 1;
            ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0;
            ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1;
            ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1;
            ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0;
            ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1;
            ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0;

            rballoc |= mac_xface->get_rballoc(0,((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->rballoc);
            add_common_dci(DCI_pdu,
                BCCH_alloc_pdu,
                SI_RNTI,
                sizeof(DCI1A_5MHz_FDD_t),
                2,
                sizeof_DCI1A_5MHz_FDD_t,
                format1A,0);
            break;
          case 50:
            ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
            ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->type = 1;
            ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0;
            ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1;
            ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1;
            ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0;
            ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1;
            ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0;

            rballoc |= mac_xface->get_rballoc(0,((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->rballoc);
            add_common_dci(DCI_pdu,
                BCCH_alloc_pdu,
                SI_RNTI,
                sizeof(DCI1A_10MHz_FDD_t),
                2,
                sizeof_DCI1A_10MHz_FDD_t,
                format1A,0);
            break;
          case 100:
            ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
            ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->type = 1;
            ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->vrb_type = 0;
            ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->ndi = 1;
            ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rv = 1;
            ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->harq_pid = 0;
            ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->TPC = 1;
            ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->padding = 0;

            rballoc |= mac_xface->get_rballoc(0,((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->rballoc);
            add_common_dci(DCI_pdu,
                BCCH_alloc_pdu,
                SI_RNTI,
                sizeof(DCI1A_20MHz_FDD_t),
                2,
                sizeof_DCI1A_20MHz_FDD_t,
                format1A,0);
            break;
          }
      }
  }
  if (RA_scheduled == 1) {
      for (i=0;i<NB_RA_PROC_MAX;i++) {

          if (eNB_mac_inst[module_idP].RA_template[i].generate_rar == 1) {

              //FK: postponed to fill_rar
              //eNB_mac_inst[module_idP].RA_template[i].generate_rar = 0;

              LOG_D(MAC,"[eNB %d] Frame %d, subframeP %d: Generating RAR DCI (proc %d), RA_active %d format 1A (%d,%d))\n",
                  module_idP,frameP, subframeP,i,
                  eNB_mac_inst[module_idP].RA_template[i].RA_active,
                  eNB_mac_inst[module_idP].RA_template[i].RA_dci_fmt1,
                  eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bits1);
              // randomize frequency allocation for RA
              while (1) {
                  first_rb = (unsigned char)(taus()%(mac_xface->lte_frame_parms->N_RB_DL-4));
                  if ((vrb_map[first_rb] != 1) && (vrb_map[first_rb+3] != 1))
                    break;
              }
              vrb_map[first_rb] = 1;
              vrb_map[first_rb+1] = 1;
              vrb_map[first_rb+2] = 1;
              vrb_map[first_rb+3] = 1;

              if (mac_xface->lte_frame_parms->frame_type == TDD) {
                  switch(mac_xface->lte_frame_parms->N_RB_DL) {
                  case 6:
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type,
                        ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc);
                    break;
                  case 25:
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type,
                        ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc);
                    break;
                  case 50:
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type,
                        ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc);
                    break;
                  case 100:
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type,
                        ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc);
                    break;
                  default:
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type,
                        ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc);
                    break;
                  }
              }
              else {
                  switch(mac_xface->lte_frame_parms->N_RB_DL) {
                  case 6:
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type,
                        ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc);
                    break;
                  case 25:
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type,
                        ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc);
                    break;
                  case 50:
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type,
                        ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc);
                    break;
                  case 100:
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->type=1;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type=0;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->ndi=1;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rv=0;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->mcs=0;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->harq_pid=0;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->TPC=1;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->padding=0;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->vrb_type,
                        ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0])->rballoc);
                    break;
                  default:
                    break;
                  }
              }
              add_common_dci(DCI_pdu,
                  (void*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu1[0],
                  eNB_mac_inst[module_idP].RA_template[i].RA_rnti,
                  eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bytes1,
                  2,
                  eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bits1,
                  eNB_mac_inst[module_idP].RA_template[i].RA_dci_fmt1,
                  1);



              LOG_D(MAC,"[eNB %d] Frame %d: Adding common dci for RA%d (RAR) RA_active %d\n",module_idP,frameP,i,
                  eNB_mac_inst[module_idP].RA_template[i].RA_active);
          }
          if (eNB_mac_inst[module_idP].RA_template[i].generate_Msg4_dci == 1) {

              // randomize frequency allocation for RA
              while (1) {
                  first_rb = (unsigned char)(taus()%(mac_xface->lte_frame_parms->N_RB_DL-4));
                  if ((vrb_map[first_rb] != 1) && (vrb_map[first_rb+3] != 1))
                    break;
              }
              vrb_map[first_rb] = 1;
              vrb_map[first_rb+1] = 1;
              vrb_map[first_rb+2] = 1;
              vrb_map[first_rb+3] = 1;

              if (mac_xface->lte_frame_parms->frame_type == TDD) {
                  switch (mac_xface->lte_frame_parms->N_RB_DL) {
                  case 6:
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0;
                    ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                        ((DCI1A_1_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                    break;
                  case 25:
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                        ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                    break;
                  case 50:
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0;
                    ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                        ((DCI1A_10MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                    break;
                  case 100:
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1;
                    ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                        ((DCI1A_20MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                    break;
                  default:
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0;
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                        ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                    break;
                  }
              }
              else {
                  switch (mac_xface->lte_frame_parms->N_RB_DL) {

                  case 6:
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0;
                    ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                        ((DCI1A_1_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                    break;
                  case 25:
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                        ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                    break;
                  case 50:
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0;
                    ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                        ((DCI1A_10MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                    break;
                  case 100:
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->padding=0;
                    ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                        ((DCI1A_20MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                    break;
                  default:
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->type=1;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rv=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->harq_pid=0;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->TPC=1;
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc= mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_DL,first_rb,4);
                    rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                        ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                    break;
                  }
              }

              add_ue_spec_dci(DCI_pdu,
                  (void*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0],
                  eNB_mac_inst[module_idP].RA_template[i].rnti,
                  eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bytes2,
                  1,
                  eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bits2,
                  eNB_mac_inst[module_idP].RA_template[i].RA_dci_fmt2,
                  0);
              LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Adding ue specific dci (rnti %x) for Msg4\n",
                  module_idP,frameP,subframeP,eNB_mac_inst[module_idP].RA_template[i].rnti);
              eNB_mac_inst[module_idP].RA_template[i].generate_Msg4_dci=0;

          }
          else if (eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4==1) {
              // check HARQ status and retransmit if necessary
              LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Checking if Msg4 was acknowledged: \n",
                  module_idP,frameP,subframeP);
              // Get candidate harq_pid from PHY
              mac_xface->get_ue_active_harq_pid(module_idP,eNB_mac_inst[module_idP].RA_template[i].rnti,subframeP,&harq_pid,&round,0);
              if (round>0) {
                  // we have to schedule a retransmission
                  if (mac_xface->lte_frame_parms->frame_type == TDD)
                    ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->ndi=1;
                  else
                    ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->ndi=1;
                  // randomize frequency allocation for RA
                  while (1) {
                      first_rb = (unsigned char)(taus()%(mac_xface->lte_frame_parms->N_RB_DL-4));
                      if ((vrb_map[first_rb] != 1) && (vrb_map[first_rb+3] != 1))
                        break;
                  }
                  vrb_map[first_rb] = 1;
                  vrb_map[first_rb+1] = 1;
                  vrb_map[first_rb+2] = 1;
                  vrb_map[first_rb+3] = 1;
                  if (mac_xface->lte_frame_parms->frame_type == TDD) {
                      ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL,first_rb,4);
                      rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                          ((DCI1A_5MHz_TDD_1_6_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                  }
                  else {
                      ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc = mac_xface->computeRIV(mac_xface->lte_frame_parms->N_RB_UL,first_rb,4);
                      rballoc |= mac_xface->get_rballoc(((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->vrb_type,
                          ((DCI1A_5MHz_FDD_t*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0])->rballoc);
                  }

                  add_ue_spec_dci(DCI_pdu,
                      (void*)&eNB_mac_inst[module_idP].RA_template[i].RA_alloc_pdu2[0],
                      eNB_mac_inst[module_idP].RA_template[i].rnti,
                      eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bytes2,
                      2,
                      eNB_mac_inst[module_idP].RA_template[i].RA_dci_size_bits2,
                      eNB_mac_inst[module_idP].RA_template[i].RA_dci_fmt2,
                      0);
                  LOG_W(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Msg4 not acknowledged, adding ue specific dci (rnti %x) for RA (Msg4 Retransmission)\n",
                      module_idP,frameP,subframeP,eNB_mac_inst[module_idP].RA_template[i].rnti);
              }
              else {
                  LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d : Msg4 acknowledged\n",module_idP,frameP,subframeP);
                  eNB_mac_inst[module_idP].RA_template[i].wait_ack_Msg4=0;
                  eNB_mac_inst[module_idP].RA_template[i].RA_active=FALSE;
              }
          }
      }
  } // RA is scheduled in this subframeP

  // UE specific DCIs
  for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) {
      //printf("UE_id: %d => status %d\n",UE_id,eNB_dlsch_info[module_idP][UE_id].status);
      if (eNB_dlsch_info[module_idP][ue_mod_id].status == S_DL_SCHEDULED) {

          // clear scheduling flag
          eNB_dlsch_info[module_idP][ue_mod_id].status = S_DL_WAITING;
          rnti = find_UE_RNTI(module_idP,ue_mod_id);
          mac_xface->get_ue_active_harq_pid(module_idP,rnti,subframeP,&harq_pid,&round,0);
          nb_rb = eNB_mac_inst[module_idP].UE_template[ue_mod_id].nb_rb[harq_pid];

          DLSCH_dci = (void *)eNB_mac_inst[module_idP].UE_template[ue_mod_id].DLSCH_DCI[harq_pid];


          /// Synchronizing rballoc with rballoc_sub
          for(i=0;i<mac_xface->lte_frame_parms->N_RBGS;i++){
              rballoc_sub[i] = eNB_mac_inst[module_idP].UE_template[ue_mod_id].rballoc_subband[harq_pid][i];
              if(rballoc_sub[i] == 1)
                rballoc |= (0x0001<<i);  // TO be FIXED!!!!!!
          }


          switch(mac_xface->get_transmission_mode(module_idP,rnti)) {
          default:

          case 1:

          case 2:
            LOG_D(MAC,"[USER-PLANE DEFAULT DRB] Adding UE spec DCI for %d PRBS (%x) => ",nb_rb,rballoc);
            if (mac_xface->lte_frame_parms->frame_type == TDD) {
                switch (mac_xface->lte_frame_parms->N_RB_DL) {
                case 6:
                  ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
                  ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rah = 0;
                  size_bytes = sizeof(DCI1_1_5MHz_TDD_t);
                  size_bits  = sizeof_DCI1_1_5MHz_TDD_t;
                  break;
                case 25:
                  ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
                  ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rah = 0;
                  size_bytes = sizeof(DCI1_5MHz_TDD_t);
                  size_bits  = sizeof_DCI1_5MHz_TDD_t;
                  break;
                case 50:
                  ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
                  ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rah = 0;
                  size_bytes = sizeof(DCI1_10MHz_TDD_t);
                  size_bits  = sizeof_DCI1_10MHz_TDD_t;
                  break;
                case 100:
                  ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
                  ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rah = 0;
                  size_bytes = sizeof(DCI1_20MHz_TDD_t);
                  size_bits  = sizeof_DCI1_20MHz_TDD_t;
                  break;
                default:
                  ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
                  ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rah = 0;
                  size_bytes = sizeof(DCI1_5MHz_TDD_t);
                  size_bits  = sizeof_DCI1_5MHz_TDD_t;
                  break;
                }


            }
            else {
                switch(mac_xface->lte_frame_parms->N_RB_DL) {
                case 6:
                  ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
                  ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rah = 0;
                  size_bytes=sizeof(DCI1_1_5MHz_FDD_t);
                  size_bits=sizeof_DCI1_1_5MHz_FDD_t;
                  break;
                case 25:
                  ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
                  ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rah = 0;
                  size_bytes=sizeof(DCI1_5MHz_FDD_t);
                  size_bits=sizeof_DCI1_5MHz_FDD_t;
                  break;
                case 50:
                  ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
                  ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rah = 0;
                  size_bytes=sizeof(DCI1_10MHz_FDD_t);
                  size_bits=sizeof_DCI1_10MHz_FDD_t;
                  break;
                case 100:
                  ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
                  ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rah = 0;
                  size_bytes=sizeof(DCI1_20MHz_FDD_t);
                  size_bits=sizeof_DCI1_20MHz_FDD_t;
                  break;
                default:
                  ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
                  ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rah = 0;
                  size_bytes=sizeof(DCI1_5MHz_FDD_t);
                  size_bits=sizeof_DCI1_5MHz_FDD_t;
                  break;
                }
            }

            add_ue_spec_dci(DCI_pdu,
                DLSCH_dci,
                rnti,
                size_bytes,
                process_ue_cqi (module_idP,ue_mod_id),//aggregation,
                size_bits,
                format1,
                0);

            break;
          case 4:

            //if (nb_rb>10) {
            // DCI format 2_2A
            ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
            ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->rah = 0;
            add_ue_spec_dci(DCI_pdu,
                DLSCH_dci,
                rnti,
                sizeof(DCI2_5MHz_2A_TDD_t),
                process_ue_cqi (module_idP,ue_mod_id),//aggregation,
                sizeof_DCI2_5MHz_2A_TDD_t,
                format2,
                0);
            /*}
	  else {
	  ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
	  add_ue_spec_dci(DCI_pdu,
	  DLSCH_dci,
	  rnti,
	  sizeof(DCI2_5MHz_2A_L10PRB_TDD_t),
	  2,//aggregation,
	  sizeof_DCI2_5MHz_2A_L10PRB_TDD_t,
	  format2_2A_L10PRB);
	  }*/
            break;
          case 5:
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rah = 0;

            add_ue_spec_dci(DCI_pdu,
                DLSCH_dci,
                rnti,
                sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t),
                process_ue_cqi (module_idP,ue_mod_id),//aggregation,
                sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t,
                format1E_2A_M10PRB,
                0);
            break;

          case 6:
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rballoc = allocate_prbs_sub(nb_rb,rballoc_sub);
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rah = 0;

            add_ue_spec_dci(DCI_pdu,
                DLSCH_dci,
                rnti,
                sizeof(DCI1E_5MHz_2A_M10PRB_TDD_t),
                process_ue_cqi (module_idP,ue_mod_id),//aggregation
                sizeof_DCI1E_5MHz_2A_M10PRB_TDD_t,
                format1E_2A_M10PRB,
                0);
            break;

          }
      }


  }
  stop_meas(&eNB_mac_inst[module_idP].fill_DLSCH_dci);
}