/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

/*! \file PHY/LTE_TRANSPORT/dci_tools.c
 * \brief PHY Support routines (eNB/UE) for filling PDSCH/PUSCH/DLSCH/ULSCH data structures based on DCI PDUs generated by eNB MAC scheduler.
 * \author R. Knopp
 * \date 2011
 * \version 0.1
 * \company Eurecom
 * \email: knopp@eurecom.fr
 * \note
 * \warning
 */

#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#ifdef DEBUG_DCI_TOOLS
#include "PHY/vars.h"
#endif
#include "assertions.h"
#include "nfapi_interface.h"

//#define DEBUG_HARQ

#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/defs.h"

//#define DEBUG_DCI

uint32_t localRIV2alloc_LUT6[32];
uint32_t distRIV2alloc_even_LUT6[32];
uint32_t distRIV2alloc_odd_LUT6[32];
uint16_t RIV2nb_rb_LUT6[32];
uint16_t RIV2first_rb_LUT6[32];
uint16_t RIV_max6=0;

uint32_t localRIV2alloc_LUT25[512];
uint32_t distRIV2alloc_even_LUT25[512];
uint32_t distRIV2alloc_odd_LUT25[512];
uint16_t RIV2nb_rb_LUT25[512];
uint16_t RIV2first_rb_LUT25[512];
uint16_t RIV_max25=0;


uint32_t localRIV2alloc_LUT50_0[1600];
uint32_t localRIV2alloc_LUT50_1[1600];
uint32_t distRIV2alloc_gap0_even_LUT50_0[1600];
uint32_t distRIV2alloc_gap0_odd_LUT50_0[1600];
uint32_t distRIV2alloc_gap0_even_LUT50_1[1600];
uint32_t distRIV2alloc_gap0_odd_LUT50_1[1600];
uint32_t distRIV2alloc_gap1_even_LUT50_0[1600];
uint32_t distRIV2alloc_gap1_odd_LUT50_0[1600];
uint32_t distRIV2alloc_gap1_even_LUT50_1[1600];
uint32_t distRIV2alloc_gap1_odd_LUT50_1[1600];
uint16_t RIV2nb_rb_LUT50[1600];
uint16_t RIV2first_rb_LUT50[1600];
uint16_t RIV_max50=0;

uint32_t localRIV2alloc_LUT100_0[6000];
uint32_t localRIV2alloc_LUT100_1[6000];
uint32_t localRIV2alloc_LUT100_2[6000];
uint32_t localRIV2alloc_LUT100_3[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_0[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_0[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_1[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_1[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_2[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_2[6000];
uint32_t distRIV2alloc_gap0_even_LUT100_3[6000];
uint32_t distRIV2alloc_gap0_odd_LUT100_3[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_0[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_0[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_1[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_1[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_2[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_2[6000];
uint32_t distRIV2alloc_gap1_even_LUT100_3[6000];
uint32_t distRIV2alloc_gap1_odd_LUT100_3[6000];
uint16_t RIV2nb_rb_LUT100[6000];
uint16_t RIV2first_rb_LUT100[6000];
uint16_t RIV_max100=0;


extern uint32_t current_dlsch_cqi;

// Table 8.6.3-3 36.213
uint16_t beta_cqi[16] = {0,   //reserved
                         0,   //reserved
                         9,   //1.125
                         10,  //1.250
                         11,  //1.375
                         13,  //1.625
                         14,  //1.750
                         16,  //2.000
                         18,  //2.250
                         20,  //2.500
                         23,  //2.875
                         25,  //3.125
                         28,  //3.500
                         32,  //4.000
                         40,  //5.000
                         50
                        }; //6.250

// Table 8.6.3-2 36.213
uint16_t beta_ri[16] = {10,   //1.250
                        13,   //1.625
                        16,   //2.000
                        20,   //2.500
                        25,   //3.125
                        32,   //4.000
                        40,   //5.000
                        50,   //6.250
                        64,   //8.000
                        80,   //10.000
                        101,  //12.625
                        127,  //15.875
                        160,  //20.000
                        0,    //reserved
                        0,    //reserved
                        0
                       };   //reserved

// Table 8.6.3-2 36.213
uint16_t beta_ack[16] = {16,  //2.000
                         20,  //2.500
                         25,  //3.125
                         32,  //4.000
                         40,  //5.000
                         50,  //6.250
                         64,  //8.000
                         80,  //10.000
                         101, //12.625
                         127, //15.875
                         160, //20.000
                         248, //31.000
                         400, //50.000
                         640, //80.000
                         808
                        };//126.00

int8_t delta_PUSCH_abs[4] = {-4,-1,1,4};
int8_t delta_PUSCH_acc[4] = {-1,0,1,3};

int8_t *delta_PUCCH_lut = delta_PUSCH_acc;

void conv_eMTC_rballoc(uint16_t resource_block_coding,
		       uint32_t N_RB_DL,
		       uint32_t *rb_alloc) {

   
  int narrowband = resource_block_coding>>5;
  int RIV        = resource_block_coding&31;
  int N_NB_DL    = N_RB_DL/6;
  int i0         = (N_RB_DL>>1) - (3*N_NB_DL);
  int first_rb   = (6*narrowband)+i0;
  int alloc      = localRIV2alloc_LUT6[RIV];
  int ind        = first_rb>>5;
  int ind_mod    = first_rb&31;

  if (((N_RB_DL&1) > 0) && (narrowband>=(N_NB_DL>>1))) first_rb++;
  rb_alloc[0]                        = 0;
  rb_alloc[1]                        = 0;
  rb_alloc[2]                        = 0;
  rb_alloc[3]                        = 0;
  rb_alloc[ind]                      = alloc<<ind_mod;
  if (ind_mod > 26)  rb_alloc[ind+1] = alloc>>(6-(ind_mod-26)); 
}

void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t *rb_alloc2)
{

  uint32_t i,shift,subset;
  rb_alloc2[0] = 0;
  rb_alloc2[1] = 0;
  rb_alloc2[2] = 0;
  rb_alloc2[3] = 0;

  //  printf("N_RB_DL %d, ra_header %d, rb_alloc %x\n",N_RB_DL,ra_header,rb_alloc);

  switch (N_RB_DL) {

  case 6:
    rb_alloc2[0] = rb_alloc&0x3f;
    break;

  case 25:
    if (ra_header == 0) {// Type 0 Allocation

      for (i=12; i>0; i--) {
        if ((rb_alloc&(1<<i)) != 0)
          rb_alloc2[0] |= (3<<((2*(12-i))));

        //      printf("rb_alloc2 (type 0) %x\n",rb_alloc2);
      }

      if ((rb_alloc&1) != 0)
        rb_alloc2[0] |= (1<<24);
    } else {
      subset = rb_alloc&1;
      shift  = (rb_alloc>>1)&1;

      for (i=0; i<11; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          rb_alloc2[0] |= (1<<(2*i));

        //printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
      }

      if ((shift == 0) && (subset == 1))
        rb_alloc2[0]<<=1;
      else if ((shift == 1) && (subset == 0))
        rb_alloc2[0]<<=4;
      else if ((shift == 1) && (subset == 1))
        rb_alloc2[0]<<=3;
    }

    break;

  case 50:
    AssertFatal(ra_header==0,"resource type 1 not supported for  N_RB_DL=50\n");

    for (i=16; i>0; i--) {
      if ((rb_alloc&(1<<i)) != 0)
	rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32));
    }

    // bit mask across
    if ((rb_alloc2[0]>>31)==1)
      rb_alloc2[1] |= 1;
    
    if ((rb_alloc&1) != 0)
      rb_alloc2[1] |= (3<<16);
    break;

  case 100:
    AssertFatal(ra_header==0,"resource type 1 not supported for  N_RB_DL=100\n");
    for (i=0; i<25; i++) {
      if ((rb_alloc&(1<<(24-i))) != 0)
	rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32));
      
      //  printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i));
    }

    break;

  default:
    LOG_E(PHY,"Invalid N_RB_DL %d\n", N_RB_DL);
    DevParam (N_RB_DL, 0, 0);
    break;
  }

}



uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL)
{

  uint32_t nprb=0,i;

  switch (N_RB_DL) {
  case 6:
    for (i=0; i<6; i++) {
      if ((rb_alloc&(1<<i)) != 0)
        nprb += 1;
    }

    break;

  case 25:
    if (ra_header == 0) {// Type 0 Allocation

      for (i=12; i>0; i--) {
        if ((rb_alloc&(1<<i)) != 0)
          nprb += 2;
      }

      if ((rb_alloc&1) != 0)
        nprb += 1;
    } else {
      for (i=0; i<11; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          nprb += 1;
      }
    }

    break;

  case 50:
    if (ra_header == 0) {// Type 0 Allocation

      for (i=0; i<16; i++) {
        if ((rb_alloc&(1<<(16-i))) != 0)
          nprb += 3;
      }

      if ((rb_alloc&1) != 0)
        nprb += 2;

    } else {
      for (i=0; i<17; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          nprb += 1;
      }
    }

    break;

  case 100:
    if (ra_header == 0) {// Type 0 Allocation

      for (i=0; i<25; i++) {
        if ((rb_alloc&(1<<(24-i))) != 0)
          nprb += 4;
      }
    } else {
      for (i=0; i<25; i++) {
        if ((rb_alloc&(1<<(i+2))) != 0)
          nprb += 1;
      }
    }

    break;

  default:
    LOG_E(PHY,"Invalide N_RB_DL %d\n", N_RB_DL);
    DevParam (N_RB_DL, 0, 0);
    break;
  }

  return(nprb);
}

uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs)
{

  uint16_t RIV;

  if (Lcrbs<=(1+(N_RB_DL>>1)))
    RIV = (N_RB_DL*(Lcrbs-1)) + RBstart;
  else
    RIV = (N_RB_DL*(N_RB_DL+1-Lcrbs)) + (N_RB_DL-1-RBstart);

  return(RIV);
}

// Convert a DCI Format 1C RIV to a Format 1A RIV
// This extracts the start and length in PRBs from the 1C rballoc and
// recomputes the RIV as if it were the 1A rballoc

uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) {

  int NpDLVRB,N_RB_step,LpCRBsm1,RBpstart;

  switch (N_RB_DL) {

  case 6: // N_RB_step = 2, NDLVRB = 6, NpDLVRB = 3
    NpDLVRB   = 3;
    N_RB_step = 2;
    break;
  case 25: // N_RB_step = 2, NDLVRB = 24, NpDLVRB = 12
    NpDLVRB   = 12;
    N_RB_step = 2;
    break;
  case 50: // N_RB_step = 4, NDLVRB = 46, NpDLVRB = 11
    NpDLVRB   = 11;
    N_RB_step = 4;
    break;
  case 100: // N_RB_step = 4, NDLVRB = 96, NpDLVRB = 24
    NpDLVRB   = 24;
    N_RB_step = 4;
    break;
  default:
    NpDLVRB   = 24;
    N_RB_step = 4;
    break;
  }

  // This is the 1C part from 7.1.6.3 in 36.213
  LpCRBsm1 = rballoc/NpDLVRB;
  //  printf("LpCRBs = %d\n",LpCRBsm1+1);

  if (LpCRBsm1 <= (NpDLVRB/2)) {
    RBpstart = rballoc % NpDLVRB;
  }
  else {
    LpCRBsm1 = NpDLVRB-LpCRBsm1;
    RBpstart = NpDLVRB-(rballoc%NpDLVRB);
  }
  //  printf("RBpstart %d\n",RBpstart);
  return(computeRIV(N_RB_DL,N_RB_step*RBpstart,N_RB_step*(LpCRBsm1+1)));

}

uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) {

  int offset;

  switch (N_RB_DL) {

  case 6:
  // N_RB_DL = tildeN_RB_DL = 6
  // Ngap = 4 , P=1, Nrow = 2, Nnull = 2

    switch (vrb) {
    case 0:  // even: 0->0, 1->2, odd: 0->3, 1->5
    case 1:
      return ((3*odd_slot) + 2*(vrb&3))%6;
      break;
    case 2:  // even: 2->3, 3->5, odd: 2->0, 3->2
    case 3:
      return ((3*odd_slot) + 2*(vrb&3) + 5)%6;
      break;
    case 4:  // even: 4->1, odd: 4->4
      return ((3*odd_slot) + 1)%6;
    case 5:  // even: 5->4, odd: 5->1
      return ((3*odd_slot) + 4)%6;
      break;
    }
    break;

  case 15:
    if (vrb<12) {
      if ((vrb&3) < 2)     // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11
  return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14);
      else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13
  return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14);
    }
    if (vrb==12)
      return (3+(7*odd_slot)) % 14;
    if (vrb==13)
      return (10+(7*odd_slot)) % 14;
    return 14;
    break;

  case 25:
    return (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24);
    break;

  case 50: // P=3
    if (Ngap==0) {
      // Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27
      if (vrb>=23)
  offset=4;
      else
  offset=0;
      if (vrb<44) {
  if ((vrb&3)>=2)
    return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46;
  else
    return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46;
      }
      if (vrb==44)  // even: 44->11, odd: 45->34
  return offset+((23*odd_slot) + 22-12+1);
      if (vrb==45)  // even: 45->10, odd: 45->33
  return offset+((23*odd_slot) + 22+12);
      if (vrb==46)
  return offset+46+((23*odd_slot) + 23-12+1) % 46;
      if (vrb==47)
  return offset+46+((23*odd_slot) + 23+12) % 46;
      if (vrb==48)
  return offset+46+((23*odd_slot) + 23-12+1) % 46;
      if (vrb==49)
  return offset+46+((23*odd_slot) + 23+12) % 46;
    }
    else {
      // Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27
      if (vrb>=9)
  offset=18;
      else
  offset=0;

      if (vrb<12) {
  if ((vrb&3)>=2)
    return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18;
  else
    return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18;
      }
      else {
  return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18);
      }
    }
    break;
  case 75:
    // Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0
    if (Ngap ==0) {
      return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64);
    } else {
      // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
      return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
    }
    break;
  case 100:
    // Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0
    if (Ngap ==0) {
      return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96);
    } else {
      // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0
      return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32);
    }
    break;
  default:
    LOG_E(PHY,"Unknown N_RB_DL %d\n",N_RB_DL);
    return 0;
  }
  return 0;

}


void generate_RIV_tables()
{

  // 6RBs localized RIV
  uint8_t Lcrbs,RBstart;
  uint16_t RIV;
  uint32_t alloc0,allocdist0_0_even,allocdist0_0_odd,allocdist0_1_even,allocdist0_1_odd;
  uint32_t alloc1,allocdist1_0_even,allocdist1_0_odd,allocdist1_1_even,allocdist1_1_odd;
  uint32_t alloc2,allocdist2_0_even,allocdist2_0_odd,allocdist2_1_even,allocdist2_1_odd;
  uint32_t alloc3,allocdist3_0_even,allocdist3_0_odd,allocdist3_1_even,allocdist3_1_odd;
  uint32_t nVRB,nVRB_even_dist,nVRB_odd_dist;

  for (RBstart=0; RBstart<6; RBstart++) {
    alloc0 = 0;
    allocdist0_0_even = 0;
    allocdist0_0_odd  = 0;
    for (Lcrbs=1; Lcrbs<=(6-RBstart); Lcrbs++) {
      //printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
      nVRB             = Lcrbs-1+RBstart;
      alloc0          |= (1<<nVRB);
      allocdist0_0_even |= (1<<get_prb(6,0,nVRB,0));
      allocdist0_0_odd  |= (1<<get_prb(6,1,nVRB,0));
      RIV=computeRIV(6,RBstart,Lcrbs);

      if (RIV>RIV_max6)
        RIV_max6 = RIV;

      //      printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs);
      localRIV2alloc_LUT6[RIV] = alloc0;
      distRIV2alloc_even_LUT6[RIV]  = allocdist0_0_even;
      distRIV2alloc_odd_LUT6[RIV]  = allocdist0_0_odd;
      RIV2nb_rb_LUT6[RIV]      = Lcrbs;
      RIV2first_rb_LUT6[RIV]   = RBstart;
    }
  }


  for (RBstart=0; RBstart<25; RBstart++) {
    alloc0 = 0;
    allocdist0_0_even = 0;
    allocdist0_0_odd  = 0;
    for (Lcrbs=1; Lcrbs<=(25-RBstart); Lcrbs++) {
      nVRB = Lcrbs-1+RBstart;
      //printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
      alloc0     |= (1<<nVRB);
      allocdist0_0_even |= (1<<get_prb(25,0,nVRB,0));
      allocdist0_0_odd  |= (1<<get_prb(25,1,nVRB,0));

      //printf("alloc 0 %x, allocdist0_even %x, allocdist0_odd %x\n",alloc0,allocdist0_0_even,allocdist0_0_odd);
      RIV=computeRIV(25,RBstart,Lcrbs);

      if (RIV>RIV_max25)
        RIV_max25 = RIV;;


      localRIV2alloc_LUT25[RIV]      = alloc0;
      distRIV2alloc_even_LUT25[RIV]  = allocdist0_0_even;
      distRIV2alloc_odd_LUT25[RIV]   = allocdist0_0_odd;
      RIV2nb_rb_LUT25[RIV]           = Lcrbs;
      RIV2first_rb_LUT25[RIV]        = RBstart;
    }
  }


  for (RBstart=0; RBstart<50; RBstart++) {
    alloc0 = 0;
    alloc1 = 0;
    allocdist0_0_even=0;
    allocdist1_0_even=0;
    allocdist0_0_odd=0;
    allocdist1_0_odd=0;
    allocdist0_1_even=0;
    allocdist1_1_even=0;
    allocdist0_1_odd=0;
    allocdist1_1_odd=0;

    for (Lcrbs=1; Lcrbs<=(50-RBstart); Lcrbs++) {

      nVRB = Lcrbs-1+RBstart;


      if (nVRB<32)
        alloc0 |= (1<<nVRB);
      else
        alloc1 |= (1<<(nVRB-32));

      // Distributed Gap1, even slot
      nVRB_even_dist = get_prb(50,0,nVRB,0);
      if (nVRB_even_dist<32)
        allocdist0_0_even |= (1<<nVRB_even_dist);
      else
        allocdist1_0_even |= (1<<(nVRB_even_dist-32));

      // Distributed Gap1, odd slot
      nVRB_odd_dist = get_prb(50,1,nVRB,0);
      if (nVRB_odd_dist<32)
        allocdist0_0_odd |= (1<<nVRB_odd_dist);
      else
        allocdist1_0_odd |= (1<<(nVRB_odd_dist-32));

      // Distributed Gap2, even slot
      nVRB_even_dist = get_prb(50,0,nVRB,1);
      if (nVRB_even_dist<32)
        allocdist0_1_even |= (1<<nVRB_even_dist);
      else
        allocdist1_1_even |= (1<<(nVRB_even_dist-32));

      // Distributed Gap2, odd slot
      nVRB_odd_dist = get_prb(50,1,nVRB,1);
      if (nVRB_odd_dist<32)
        allocdist0_1_odd |= (1<<nVRB_odd_dist);
      else
        allocdist1_1_odd |= (1<<(nVRB_odd_dist-32));

      RIV=computeRIV(50,RBstart,Lcrbs);

      if (RIV>RIV_max50)
        RIV_max50 = RIV;

      //      printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs);
      localRIV2alloc_LUT50_0[RIV]      = alloc0;
      localRIV2alloc_LUT50_1[RIV]      = alloc1;
      distRIV2alloc_gap0_even_LUT50_0[RIV]  = allocdist0_0_even;
      distRIV2alloc_gap0_even_LUT50_1[RIV]  = allocdist1_0_even;
      distRIV2alloc_gap0_odd_LUT50_0[RIV]   = allocdist0_0_odd;
      distRIV2alloc_gap0_odd_LUT50_1[RIV]   = allocdist1_0_odd;
      distRIV2alloc_gap1_even_LUT50_0[RIV]  = allocdist0_1_even;
      distRIV2alloc_gap1_even_LUT50_1[RIV]  = allocdist1_1_even;
      distRIV2alloc_gap1_odd_LUT50_0[RIV]   = allocdist0_1_odd;
      distRIV2alloc_gap1_odd_LUT50_1[RIV]   = allocdist1_1_odd;
      RIV2nb_rb_LUT50[RIV]        = Lcrbs;
      RIV2first_rb_LUT50[RIV]     = RBstart;
    }
  }


  for (RBstart=0; RBstart<100; RBstart++) {
    alloc0 = 0;
    alloc1 = 0;
    alloc2 = 0;
    alloc3 = 0;
    allocdist0_0_even=0;
    allocdist1_0_even=0;
    allocdist2_0_even=0;
    allocdist3_0_even=0;
    allocdist0_0_odd=0;
    allocdist1_0_odd=0;
    allocdist2_0_odd=0;
    allocdist3_0_odd=0;
    allocdist0_1_even=0;
    allocdist1_1_even=0;
    allocdist2_1_even=0;
    allocdist3_1_even=0;
    allocdist0_1_odd=0;
    allocdist1_1_odd=0;
    allocdist2_1_odd=0;
    allocdist3_1_odd=0;

    for (Lcrbs=1; Lcrbs<=(100-RBstart); Lcrbs++) {

      nVRB = Lcrbs-1+RBstart;

      if (nVRB<32)
        alloc0 |= (1<<nVRB);
      else if (nVRB<64)
        alloc1 |= (1<<(nVRB-32));
      else if (nVRB<96)
        alloc2 |= (1<<(nVRB-64));
      else
        alloc3 |= (1<<(nVRB-96));

      // Distributed Gap1, even slot
      nVRB_even_dist = get_prb(100,0,nVRB,0);

//      if ((RBstart==0) && (Lcrbs<=8))
//  printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist);


      if (nVRB_even_dist<32)
        allocdist0_0_even |= (1<<nVRB_even_dist);
      else if (nVRB_even_dist<64)
        allocdist1_0_even |= (1<<(nVRB_even_dist-32));
      else if (nVRB_even_dist<96)
  allocdist2_0_even |= (1<<(nVRB_even_dist-64));
      else
  allocdist3_0_even |= (1<<(nVRB_even_dist-96));
/*      if ((RBstart==0) && (Lcrbs<=8))
  printf("rballoc =>(%08x.%08x.%08x.%08x)\n",
         allocdist0_0_even,
         allocdist1_0_even,
         allocdist2_0_even,
         allocdist3_0_even
         );
*/
      // Distributed Gap1, odd slot
      nVRB_odd_dist = get_prb(100,1,nVRB,0);
      if (nVRB_odd_dist<32)
        allocdist0_0_odd |= (1<<nVRB_odd_dist);
      else if (nVRB_odd_dist<64)
        allocdist1_0_odd |= (1<<(nVRB_odd_dist-32));
      else if (nVRB_odd_dist<96)
  allocdist2_0_odd |= (1<<(nVRB_odd_dist-64));
      else
  allocdist3_0_odd |= (1<<(nVRB_odd_dist-96));


      // Distributed Gap2, even slot
      nVRB_even_dist = get_prb(100,0,nVRB,1);
      if (nVRB_even_dist<32)
        allocdist0_1_even |= (1<<nVRB_even_dist);
      else if (nVRB_even_dist<64)
        allocdist1_1_even |= (1<<(nVRB_even_dist-32));
      else if (nVRB_even_dist<96)
  allocdist2_1_even |= (1<<(nVRB_even_dist-64));
      else
  allocdist3_1_even |= (1<<(nVRB_even_dist-96));


      // Distributed Gap2, odd slot
      nVRB_odd_dist = get_prb(100,1,nVRB,1);
      if (nVRB_odd_dist<32)
        allocdist0_1_odd |= (1<<nVRB_odd_dist);
      else if (nVRB_odd_dist<64)
        allocdist1_1_odd |= (1<<(nVRB_odd_dist-32));
      else if (nVRB_odd_dist<96)
  allocdist2_1_odd |= (1<<(nVRB_odd_dist-64));
      else
  allocdist3_1_odd |= (1<<(nVRB_odd_dist-96));


      RIV=computeRIV(100,RBstart,Lcrbs);

      if (RIV>RIV_max100)
        RIV_max100 = RIV;

      //      printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs);
      localRIV2alloc_LUT100_0[RIV] = alloc0;
      localRIV2alloc_LUT100_1[RIV] = alloc1;
      localRIV2alloc_LUT100_2[RIV] = alloc2;
      localRIV2alloc_LUT100_3[RIV] = alloc3;
      distRIV2alloc_gap0_even_LUT100_0[RIV]  = allocdist0_0_even;
      distRIV2alloc_gap0_even_LUT100_1[RIV]  = allocdist1_0_even;
      distRIV2alloc_gap0_even_LUT100_2[RIV]  = allocdist2_0_even;
      distRIV2alloc_gap0_even_LUT100_3[RIV]  = allocdist3_0_even;
      distRIV2alloc_gap0_odd_LUT100_0[RIV]   = allocdist0_0_odd;
      distRIV2alloc_gap0_odd_LUT100_1[RIV]   = allocdist1_0_odd;
      distRIV2alloc_gap0_odd_LUT100_2[RIV]   = allocdist2_0_odd;
      distRIV2alloc_gap0_odd_LUT100_3[RIV]   = allocdist3_0_odd;
      distRIV2alloc_gap1_even_LUT100_0[RIV]  = allocdist0_1_even;
      distRIV2alloc_gap1_even_LUT100_1[RIV]  = allocdist1_1_even;
      distRIV2alloc_gap1_even_LUT100_2[RIV]  = allocdist2_1_even;
      distRIV2alloc_gap1_even_LUT100_3[RIV]  = allocdist3_1_even;
      distRIV2alloc_gap1_odd_LUT100_0[RIV]   = allocdist0_1_odd;
      distRIV2alloc_gap1_odd_LUT100_1[RIV]   = allocdist1_1_odd;
      distRIV2alloc_gap1_odd_LUT100_2[RIV]   = allocdist2_1_odd;
      distRIV2alloc_gap1_odd_LUT100_3[RIV]   = allocdist3_1_odd;

      RIV2nb_rb_LUT100[RIV]      = Lcrbs;
      RIV2first_rb_LUT100[RIV]   = RBstart;
    }
  }
}

// Ngap = 3, N_VRB_DL=6, P=1, N_row=2, N_null=4*2-6=2
// permutation for even slots :
//    n_PRB'(0,2,4) = (0,1,2), n_PRB'(1,3,5) = (4,5,6)
//    n_PRB''(0,1,2,3) = (0,2,4,6)
//    => n_tilde_PRB(5) = (4)
//       n_tilde_PRB(4) = (1)
//       n_tilde_PRB(2,3) = (3,5)
//       n_tilde_PRB(0,1) = (0,2)


int8_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
{
  uint8_t i;
  int8_t first_free_index=-1;

  AssertFatal(eNB!=NULL,"eNB is null\n");
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    AssertFatal(eNB->dlsch[i]!=NULL,"eNB->dlsch[%d] is null\n",i);
    AssertFatal(eNB->dlsch[i]!=NULL,"eNB->dlsch[%d][0] is null\n",i);
    LOG_D(PHY,"searching for rnti %x : UE index %d=> harq_mask %x, rnti %x, first_free_index %d\n",
          rnti,i,eNB->dlsch[i][0]->harq_mask,eNB->dlsch[i][0]->rnti,first_free_index);
    if ((eNB->dlsch[i][0]->harq_mask >0) &&
        (eNB->dlsch[i][0]->rnti==rnti))       return i;
    else if ((eNB->dlsch[i][0]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
  }
  if (type == SEARCH_EXIST) return -1;
  if (first_free_index != -1)
    eNB->dlsch[first_free_index][0]->rnti = 0;
  return first_free_index;
}

int8_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type)
{
  uint8_t i;
  int8_t first_free_index=-1;

  AssertFatal(eNB!=NULL,"eNB is null\n");
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    AssertFatal(eNB->ulsch[i]!=NULL,"eNB->ulsch[%d] is null\n",i);
    if ((eNB->ulsch[i]->harq_mask >0) &&
        (eNB->ulsch[i]->rnti==rnti))       return i;
    else if ((eNB->ulsch[i]->harq_mask == 0) && (first_free_index==-1)) first_free_index=i;
  }
  if (type == SEARCH_EXIST) return -1;
  if (first_free_index != -1)
    eNB->ulsch[first_free_index]->rnti = 0;
  return first_free_index;
}


uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci)
{

  return(localRIV2alloc_LUT25[rb_alloc_dci]);

}

/*
uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti)
{
  unsigned char UE_id;

  // find the UE_index corresponding to rnti
  UE_id = find_ue(rnti,RC.eNB[Mod_id][CC_id]);
  DevAssert( UE_id != (unsigned char)-1 );

  return(RC.eNB[Mod_id][CC_id]->transmission_mode[UE_id]);
}
*/

void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) {

  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;

  uint8_t *dci_pdu = &dci_alloc->dci_pdu[0];
  nfapi_dl_config_dci_dl_pdu_rel8_t *rel8 = &pdu->dci_dl_pdu_rel8;

  LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
  LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
  int beamforming_mode = 0;
  int UE_id=-1;
  int subframe = proc->subframe_tx;
  int NPRB;
  int TB0_active;
  int TB1_active;
  uint16_t DL_pmi_single=0; // This should be taken from DLSCH parameters for PUSCH precoding
  uint8_t I_mcs = 0;
 
  dci_alloc->firstCCE = rel8->cce_idx;
  dci_alloc->L        = rel8->aggregation_level;
  dci_alloc->rnti     = rel8->rnti;
  dci_alloc->harq_pid = rel8->harq_process;
  dci_alloc->ra_flag  = 0;

  LOG_D(PHY,"NFAPI: DCI format %d, nCCE %d, L %d, rnti %x,harq_pid %d\n",
	rel8->dci_format,rel8->cce_idx,rel8->aggregation_level,rel8->rnti,rel8->harq_process);
  if ((rel8->rnti_type == 2 ) && (rel8->rnti != SI_RNTI) && (rel8->rnti != P_RNTI)) dci_alloc->ra_flag = 1;

  UE_id = find_dlsch(rel8->rnti,eNB,SEARCH_EXIST_OR_FREE);
  AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
  AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
  dlsch0 = eNB->dlsch[UE_id][0];
  dlsch1 = eNB->dlsch[UE_id][1];

    
  beamforming_mode                          = eNB->transmission_mode[(uint8_t)UE_id]<7?0:eNB->transmission_mode[(uint8_t)UE_id];
  dlsch0_harq                               = dlsch0->harq_processes[rel8->harq_process];
  dlsch0_harq->codeword                     = 0;
  dlsch1_harq                               = dlsch1->harq_processes[rel8->harq_process];
  dlsch1_harq->codeword                     = 1;
  dlsch0->subframe_tx[subframe]             = 1;
  if (dlsch0->rnti != rel8->rnti) { // if rnti of dlsch is not the same as in the config, this is a new entry
    dlsch0_harq->round=0;
    dlsch0->harq_mask=0;
  }
  if ((dlsch0->harq_mask & (1<<rel8->harq_process)) > 0 ) {
    if (rel8->new_data_indicator_1 != dlsch0_harq->ndi)
      dlsch0_harq->round=0;
  }
  else  { // process is inactive, so activate and set round to 0
    dlsch0_harq->round=0;
  }
  dlsch0_harq->ndi = rel8->new_data_indicator_1;

  dlsch0->active        = 1;
  if (rel8->rnti_type == 2)
      dlsch0_harq->round    = 0;
LOG_D(PHY,"NFAPI: harq_pid %d harq_mask %x, round %d ndi (%d,%d) rnti type %d\n",rel8->harq_process,dlsch0->harq_mask,dlsch0_harq->round,
	dlsch0_harq->ndi,rel8->new_data_indicator_1, rel8->rnti_type);

  switch (rel8->dci_format) {

  case NFAPI_DL_DCI_FORMAT_1A:

      AssertFatal(rel8->resource_block_coding < 8192, "Frame %d, Subframe %d: rel8->resource_block_coding (%p) %u >= 8192 (rnti %x, rnti_type %d, format %d, harq_id %d\n",
                proc->frame_tx,subframe,
                &rel8->resource_block_coding,rel8->resource_block_coding,rel8->rnti,rel8->rnti_type,rel8->dci_format,rel8->harq_process);
  

    dci_alloc->format     = format1A;

    switch (fp->N_RB_DL) {
    case 6:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                         = sizeof_DCI1A_1_5MHz_TDD_1_6_t; 
        ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->type     = 1;
        ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type = rel8->virtual_resource_block_assignment_flag;
        ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs      = rel8->mcs_1;
        ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi      = rel8->new_data_indicator_1;
        ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc  = rel8->resource_block_coding;
        ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv       = rel8->redundancy_version_1;
        ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC      = rel8->tpc;
        ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid = rel8->harq_process;
        ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai      = rel8->downlink_assignment_index;
	
      } else {
	dci_alloc->dci_length                         = sizeof_DCI1A_1_5MHz_FDD_t; 
	((DCI1A_1_5MHz_FDD_t *)dci_pdu)->type         = 1;
        ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type     = rel8->virtual_resource_block_assignment_flag;
        ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs          = rel8->mcs_1;
        ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->ndi          = rel8->new_data_indicator_1;
        ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc      = rel8->resource_block_coding;
        ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv           = rel8->redundancy_version_1;
        ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC          = rel8->tpc;
        ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid     = rel8->harq_process;
        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      // check if PDCCH order
      if (rel8->resource_block_coding == 63) { 
          dlsch0->active        = 0;
          return;
      }
      AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n");
      dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT6[rel8->resource_block_coding];
      dlsch0_harq->vrb_type           =  rel8->virtual_resource_block_assignment_flag;
      dlsch0_harq->nb_rb          = RIV2nb_rb_LUT6[rel8->resource_block_coding];//NPRB;
      break;
    case 25:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                         = sizeof_DCI1A_5MHz_TDD_1_6_t; 
        ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->type       = 1;
        ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type   = rel8->virtual_resource_block_assignment_flag;
        ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs        = rel8->mcs_1;
        ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi        = rel8->new_data_indicator_1;
        ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc    = rel8->resource_block_coding;
        ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv         = rel8->redundancy_version_1;
        ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC        = rel8->tpc;
        ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid   = rel8->harq_process;
        ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai      = rel8->downlink_assignment_index; 	
         //        printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                         = sizeof_DCI1A_5MHz_FDD_t; 
	((DCI1A_5MHz_FDD_t *)dci_pdu)->type           = 1;
        ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type       = rel8->virtual_resource_block_assignment_flag;
        ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs            = rel8->mcs_1;
        ((DCI1A_5MHz_FDD_t *)dci_pdu)->ndi            = rel8->new_data_indicator_1;
        ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc        = rel8->resource_block_coding;
        ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv             = rel8->redundancy_version_1;
        ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC            = rel8->tpc;
        ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid       = rel8->harq_process;
        //      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }

      // check if PDCCH order
	  if (rel8->resource_block_coding == 511)  {
          dlsch0->active        = 0;
          return;
      }
      AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n");
      dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT25[rel8->resource_block_coding];
      dlsch0_harq->vrb_type           =  rel8->virtual_resource_block_assignment_flag;
      dlsch0_harq->nb_rb          = RIV2nb_rb_LUT25[rel8->resource_block_coding];//NPRB;
      break;
    case 50:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                         = sizeof_DCI1A_10MHz_TDD_1_6_t; 
        ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->type      = 1;
        ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type  = rel8->virtual_resource_block_assignment_flag;
        ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs       = rel8->mcs_1;
        ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->ndi       = rel8->new_data_indicator_1;
        ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc   = rel8->resource_block_coding;
        ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv        = rel8->redundancy_version_1;
        ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC       = rel8->tpc;
        ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid  = rel8->harq_process;
        ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai       = rel8->downlink_assignment_index;	
        //        printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                         = sizeof_DCI1A_10MHz_FDD_t; 
	((DCI1A_10MHz_FDD_t *)dci_pdu)->type          = 1;
        ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type      = rel8->virtual_resource_block_assignment_flag;
        ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs           = rel8->mcs_1;
        ((DCI1A_10MHz_FDD_t *)dci_pdu)->ndi           = rel8->new_data_indicator_1;
        ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc       = rel8->resource_block_coding;
        ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv            = rel8->redundancy_version_1;
        ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC           = rel8->tpc;
        ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid      = rel8->harq_process;
	//      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      // check if PDCCH order
      if (rel8->resource_block_coding == 2047) {
          dlsch0->active        = 0;
          return;
      }
      AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n");
      dlsch0_harq->rb_alloc[0]     = localRIV2alloc_LUT50_0[rel8->resource_block_coding];
      dlsch0_harq->rb_alloc[1]     = localRIV2alloc_LUT50_1[rel8->resource_block_coding];
      dlsch0_harq->vrb_type           =  rel8->virtual_resource_block_assignment_flag;
      dlsch0_harq->nb_rb              = RIV2nb_rb_LUT50[rel8->resource_block_coding];//NPRB;
      break;
    case 100:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                         = sizeof_DCI1A_20MHz_TDD_1_6_t; 
        ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->type      = 1;
        ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type  = rel8->virtual_resource_block_assignment_flag;
        ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs       = rel8->mcs_1;
        ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->ndi       = rel8->new_data_indicator_1;
        ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc   = rel8->resource_block_coding;
        ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv        = rel8->redundancy_version_1;
        ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC       = rel8->tpc;
        ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid  = rel8->harq_process;
        ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai       = rel8->downlink_assignment_index;	
        //        printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                         = sizeof_DCI1A_20MHz_FDD_t; 
	((DCI1A_20MHz_FDD_t *)dci_pdu)->type          = 1;
        ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type      = rel8->virtual_resource_block_assignment_flag;
        ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs           = rel8->mcs_1;
        ((DCI1A_20MHz_FDD_t *)dci_pdu)->ndi           = rel8->new_data_indicator_1;
        ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc       = rel8->resource_block_coding;
        ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv            = rel8->redundancy_version_1;
        ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC           = rel8->tpc;
        ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid      = rel8->harq_process;
	//      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      // check if PDCCH order
      if (rel8->resource_block_coding == 8191) {
          dlsch0->active        = 0;
          return;
      }
      AssertFatal(rel8->virtual_resource_block_assignment_flag==LOCALIZED,"Distributed RB allocation not done yet\n");
      dlsch0_harq->rb_alloc[0]      = localRIV2alloc_LUT100_0[rel8->resource_block_coding];
      dlsch0_harq->rb_alloc[1]      = localRIV2alloc_LUT100_1[rel8->resource_block_coding];
      dlsch0_harq->rb_alloc[2]      = localRIV2alloc_LUT100_2[rel8->resource_block_coding];
      dlsch0_harq->rb_alloc[3]      = localRIV2alloc_LUT100_3[rel8->resource_block_coding];
      dlsch0_harq->vrb_type         =  rel8->virtual_resource_block_assignment_flag;
      dlsch0_harq->nb_rb            = RIV2nb_rb_LUT100[rel8->resource_block_coding];//NPRB;
      break;
    }

    if (rel8->rnti_type == 2 ) {
      // see 36-212 V8.6.0 p. 45
      NPRB      = (rel8->tpc&1)+2;
      // 36-213 sec.7.1.7.2 p.26
      I_mcs     = rel8->mcs_1;
    }
    else {
      NPRB      = dlsch0_harq->nb_rb;
      I_mcs     = get_I_TBS(rel8->mcs_1);
    }
    AssertFatal(NPRB>0,"DCI 1A: NPRB = 0 (rnti %x, rnti type %d, tpc %d, round %d, resource_block_coding %d)\n",rel8->rnti,rel8->rnti_type,rel8->tpc,dlsch0_harq->round,rel8->resource_block_coding);
    dlsch0_harq->rvidx         = rel8->redundancy_version_1;
    dlsch0_harq->Nl            = 1;
    dlsch0_harq->mimo_mode     = (fp->nb_antenna_ports_eNB == 1) ? SISO : ALAMOUTI;
    dlsch0_harq->dl_power_off  = 1;
    
    

    dlsch0_harq->mcs             = rel8->mcs_1;
    dlsch0_harq->Qm              = 2;
    dlsch0_harq->TBS             = TBStable[I_mcs][NPRB-1];
    dlsch0->harq_ids[subframe]   = rel8->harq_process;
    dlsch0->active               = 1;
    dlsch0->rnti                 = rel8->rnti;
    dlsch0->harq_ids[subframe]   = rel8->harq_process;
    if (dlsch0_harq->round == 0)
      dlsch0_harq->status = ACTIVE;

    dlsch0->harq_mask            |= (1<<rel8->harq_process);

    if (rel8->rnti_type == 1) LOG_I(PHY,"DCI 1A: round %d, mcs %d, rballoc %x,rv %d, rnti %x\n",dlsch0_harq->round,rel8->mcs_1,rel8->resource_block_coding,rel8->redundancy_version_1,rel8->rnti);

    break;
  case NFAPI_DL_DCI_FORMAT_1:

    dci_alloc->format           = format1;
    dlsch0->active              = 1;

    LOG_D(PHY,"Frame %d, Subframe %d: Programming DLSCH for Format 1 DCI, harq_pid %d\n",proc->frame_tx,subframe,rel8->harq_process);

    switch (fp->N_RB_DL) {
    case 6:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                     = sizeof_DCI1_1_5MHz_TDD_t; 
        ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah       = rel8->resource_allocation_type;
        ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs       = rel8->mcs_1;
        ((DCI1_1_5MHz_TDD_t *)dci_pdu)->ndi       = rel8->new_data_indicator_1;
        ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc   = rel8->resource_block_coding;
        ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv        = rel8->redundancy_version_1;
        ((DCI1_1_5MHz_TDD_t *)dci_pdu)->TPC       = rel8->tpc;
        ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid  = rel8->harq_process;
        ((DCI1_1_5MHz_TDD_t *)dci_pdu)->dai       = rel8->downlink_assignment_index; 	
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                         = sizeof_DCI1_1_5MHz_FDD_t; 
        ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah           = rel8->resource_allocation_type;
        ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs           = rel8->mcs_1;
        ((DCI1_1_5MHz_FDD_t *)dci_pdu)->ndi       = rel8->new_data_indicator_1;
        ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc       = rel8->resource_block_coding;
        ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv            = rel8->redundancy_version_1;
        ((DCI1_1_5MHz_FDD_t *)dci_pdu)->TPC           = rel8->tpc;
        ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid      = rel8->harq_process;
        //      printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      break;
    case 25:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                      = sizeof_DCI1_5MHz_TDD_t; 
        ((DCI1_5MHz_TDD_t *)dci_pdu)->rah      = rel8->resource_allocation_type;
        ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs      = rel8->mcs_1;
        ((DCI1_5MHz_TDD_t *)dci_pdu)->ndi      = rel8->new_data_indicator_1;
        ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc  = rel8->resource_block_coding;
        ((DCI1_5MHz_TDD_t *)dci_pdu)->rv       = rel8->redundancy_version_1;
        ((DCI1_5MHz_TDD_t *)dci_pdu)->TPC      = rel8->tpc;
        ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process;
        ((DCI1_5MHz_TDD_t *)dci_pdu)->dai      = rel8->downlink_assignment_index;	
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                  = sizeof_DCI1_5MHz_FDD_t; 
        ((DCI1_5MHz_FDD_t *)dci_pdu)->rah      = rel8->resource_allocation_type;
        ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs      = rel8->mcs_1;
        ((DCI1_5MHz_FDD_t *)dci_pdu)->ndi      = rel8->new_data_indicator_1;
        ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc  = rel8->resource_block_coding;
        ((DCI1_5MHz_FDD_t *)dci_pdu)->rv       = rel8->redundancy_version_1;
        ((DCI1_5MHz_FDD_t *)dci_pdu)->TPC      = rel8->tpc;
        ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process;
        //      printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      break;
    case 50:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                       = sizeof_DCI1_10MHz_TDD_t; 
        ((DCI1_10MHz_TDD_t *)dci_pdu)->rah      = rel8->resource_allocation_type;
        ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs      = rel8->mcs_1;
        ((DCI1_10MHz_TDD_t *)dci_pdu)->ndi      = rel8->new_data_indicator_1;
        ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc  = rel8->resource_block_coding;
        ((DCI1_10MHz_TDD_t *)dci_pdu)->rv       = rel8->redundancy_version_1;
        ((DCI1_10MHz_TDD_t *)dci_pdu)->TPC      = rel8->tpc;
        ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process;
        ((DCI1_10MHz_TDD_t *)dci_pdu)->dai      = rel8->downlink_assignment_index;	
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                   = sizeof_DCI1_10MHz_FDD_t; 
        ((DCI1_10MHz_FDD_t *)dci_pdu)->rah      = rel8->resource_allocation_type;
        ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs      = rel8->mcs_1;
        ((DCI1_10MHz_FDD_t *)dci_pdu)->ndi      = rel8->new_data_indicator_1;
        ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc  = rel8->resource_block_coding;
        ((DCI1_10MHz_FDD_t *)dci_pdu)->rv       = rel8->redundancy_version_1;
        ((DCI1_10MHz_FDD_t *)dci_pdu)->TPC      = rel8->tpc;
        ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process;
      }
      break;
    case 100:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                       = sizeof_DCI1_20MHz_TDD_t; 
        ((DCI1_20MHz_TDD_t *)dci_pdu)->rah      = rel8->resource_allocation_type;
        ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs      = rel8->mcs_1;
        ((DCI1_20MHz_TDD_t *)dci_pdu)->ndi      = rel8->new_data_indicator_1;
        ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc  = rel8->resource_block_coding;
        ((DCI1_20MHz_TDD_t *)dci_pdu)->rv       = rel8->redundancy_version_1;
        ((DCI1_20MHz_TDD_t *)dci_pdu)->TPC      = rel8->tpc;
        ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process;
        ((DCI1_20MHz_TDD_t *)dci_pdu)->dai      = rel8->downlink_assignment_index;	
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                   = sizeof_DCI1_20MHz_FDD_t; 
        ((DCI1_20MHz_FDD_t *)dci_pdu)->rah      = rel8->resource_allocation_type;
        ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs      = rel8->mcs_1;
        ((DCI1_20MHz_FDD_t *)dci_pdu)->ndi      = rel8->new_data_indicator_1;
        ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc  = rel8->resource_block_coding;
        ((DCI1_20MHz_FDD_t *)dci_pdu)->rv       = rel8->redundancy_version_1;
        ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC      = rel8->tpc;
        ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid = rel8->harq_process;
      }
      break;
    }

    AssertFatal(rel8->harq_process<8,"Format 1: harq_pid=%d >= 8\n", rel8->harq_process);


    dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
    dlsch0_harq->codeword=0;

    // printf("DCI: Setting subframe_tx for subframe %d\n",subframe);
    dlsch0->subframe_tx[subframe] = 1;

    conv_rballoc(rel8->resource_allocation_type,
                 rel8->resource_block_coding,
		 fp->N_RB_DL,
                 dlsch0_harq->rb_alloc);

    dlsch0_harq->nb_rb = conv_nprb(rel8->resource_allocation_type,
                                   rel8->resource_block_coding,
                                   fp->N_RB_DL);

    NPRB      = dlsch0_harq->nb_rb;


    AssertFatal(NPRB>0,"NPRB == 0\n");

    dlsch0_harq->rvidx       = rel8->redundancy_version_1;

    dlsch0_harq->Nl          = 1;
    //    dlsch[0]->layer_index = 0;
    if (beamforming_mode == 0)
      dlsch0_harq->mimo_mode = (fp->nb_antenna_ports_eNB == 1) ? SISO : ALAMOUTI;
    else if (beamforming_mode == 7)
      dlsch0_harq->mimo_mode = TM7;
    else
      LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode);

    dlsch0_harq->dl_power_off = 1;

    dlsch0->active = 1;



    if (dlsch0_harq->round == 0) {
      dlsch0_harq->status = ACTIVE;

      //            printf("Setting DLSCH process %d to ACTIVE\n",rel8->harq_process);
      // MCS and TBS don't change across HARQ rounds
      dlsch0_harq->mcs         = rel8->mcs_1;
      dlsch0_harq->Qm          = get_Qm(rel8->mcs_1);
      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][NPRB-1];

    }

    LOG_D(PHY,"DCI: Set harq_ids[%d] to %d (%p)\n",subframe,rel8->harq_process,dlsch0);
    dlsch0->harq_ids[subframe] = rel8->harq_process;

    dlsch0->harq_mask          |= (1<<rel8->harq_process);


    dlsch0->rnti = rel8->rnti;


    break;
  case NFAPI_DL_DCI_FORMAT_2A:

    dci_alloc->format     = format2A;
    switch (fp->N_RB_DL) {
    case 6:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                         = sizeof_DCI2A_1_5MHz_2A_TDD_t; 
        ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rah      = rel8->resource_allocation_type;
        ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1     = rel8->mcs_1;
        ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2     = rel8->mcs_2;
        ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1     = rel8->new_data_indicator_1;
        ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2     = rel8->new_data_indicator_2;
        ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc  = rel8->resource_block_coding;
        ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1      = rel8->redundancy_version_1;
        ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2      = rel8->redundancy_version_2;
        ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->TPC      = rel8->tpc;
        ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process;
	((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap  = rel8->transport_block_to_codeword_swap_flag;
        ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->dai      = rel8->downlink_assignment_index;
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                         = sizeof_DCI2A_1_5MHz_2A_FDD_t; 
        ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rah          = rel8->resource_allocation_type;
        ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1         = rel8->mcs_1;
        ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2         = rel8->mcs_2;
        ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1         = rel8->new_data_indicator_1;
        ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2         = rel8->new_data_indicator_2;
        ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc      = rel8->resource_block_coding;
        ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv1          = rel8->redundancy_version_1;
        ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv2          = rel8->redundancy_version_2;
        ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->TPC          = rel8->tpc;
        ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid     = rel8->harq_process;
	((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap      = rel8->transport_block_to_codeword_swap_flag;
        //      printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      break;
    case 25:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                        = sizeof_DCI2A_5MHz_2A_TDD_t; 
        ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah       = rel8->resource_allocation_type;
        ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1      = rel8->mcs_1;
        ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2      = rel8->mcs_2;
        ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi1      = rel8->new_data_indicator_1;
        ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi2      = rel8->new_data_indicator_2;
        ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc   = rel8->resource_block_coding;
        ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1       = rel8->redundancy_version_1;
        ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2       = rel8->redundancy_version_2;
        ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->TPC       = rel8->tpc;
        ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid  = rel8->harq_process;
	((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap   = rel8->transport_block_to_codeword_swap_flag;	
        ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->dai       = rel8->downlink_assignment_index;	
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                           = sizeof_DCI2A_5MHz_2A_FDD_t; 
        ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rah           = rel8->resource_allocation_type;
        ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs1          = rel8->mcs_1;
        ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs2          = rel8->mcs_2;
        ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi1          = rel8->new_data_indicator_1;
        ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi2          = rel8->new_data_indicator_2;
        ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rballoc       = rel8->resource_block_coding;
        ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv1           = rel8->redundancy_version_1;
        ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv2           = rel8->redundancy_version_2;
        ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->TPC           = rel8->tpc;
        ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid      = rel8->harq_process;
	((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap       = rel8->transport_block_to_codeword_swap_flag;	
        //      printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      break;
    case 50:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                        = sizeof_DCI2A_10MHz_2A_TDD_t; 
        ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah      = rel8->resource_allocation_type;
        ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1     = rel8->mcs_1;
        ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2     = rel8->mcs_2;
        ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi1     = rel8->new_data_indicator_1;
        ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi2     = rel8->new_data_indicator_2;
        ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc  = rel8->resource_block_coding;
        ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1      = rel8->redundancy_version_1;
        ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2      = rel8->redundancy_version_2;
        ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->TPC      = rel8->tpc;
        ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process;
	((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap  = rel8->transport_block_to_codeword_swap_flag;	
        ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->dai      = rel8->downlink_assignment_index;	
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                        = sizeof_DCI2A_10MHz_2A_FDD_t; 
        ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rah       = rel8->resource_allocation_type;
        ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs1      = rel8->mcs_1;
        ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs2      = rel8->mcs_2;
        ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi1      = rel8->new_data_indicator_1;
        ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi2      = rel8->new_data_indicator_2;
        ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rballoc   = rel8->resource_block_coding;
        ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv1       = rel8->redundancy_version_1;
        ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2       = rel8->redundancy_version_2;
        ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->TPC       = rel8->tpc;
        ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid  = rel8->harq_process;
	((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap   = rel8->transport_block_to_codeword_swap_flag;	
      }
      break;
    case 100:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                        = sizeof_DCI2A_20MHz_2A_TDD_t; 
        ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah       = rel8->resource_allocation_type;
        ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1      = rel8->mcs_1;
        ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2      = rel8->mcs_2;
        ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi1      = rel8->new_data_indicator_1;
        ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi2      = rel8->new_data_indicator_2;
        ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc   = rel8->resource_block_coding;
        ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1       = rel8->redundancy_version_1;
        ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2       = rel8->redundancy_version_2;
        ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->TPC       = rel8->tpc;
        ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid  = rel8->harq_process;
	((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap   = rel8->transport_block_to_codeword_swap_flag;		
        ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->dai       = rel8->downlink_assignment_index;	
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                           = sizeof_DCI2A_20MHz_2A_FDD_t; 
        ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rah          = rel8->resource_allocation_type;
        ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs1         = rel8->mcs_1;
        ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs2         = rel8->mcs_2;
        ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi1         = rel8->new_data_indicator_1;
        ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi2         = rel8->new_data_indicator_2;
        ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rballoc      = rel8->resource_block_coding;
        ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv1          = rel8->redundancy_version_1;
        ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2          = rel8->redundancy_version_2;
        ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->TPC          = rel8->tpc;
        ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid     = rel8->harq_process;
	((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap      = rel8->transport_block_to_codeword_swap_flag;	
      }
      break;

    }

    AssertFatal(rel8->harq_process<8,"Format 2_2A: harq_pid=%d >= 8\n", rel8->harq_process);


    // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0
    // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated

    // This must be set as in TM4, does not work properly now.
    if (rel8->transport_block_to_codeword_swap_flag == 1) {
      dlsch0 = eNB->dlsch[UE_id][1];
      dlsch1 = eNB->dlsch[UE_id][0];
    }

    dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
    dlsch1_harq = dlsch1->harq_processes[rel8->harq_process];

    dlsch0->subframe_tx[subframe] = 1;

    dlsch0->harq_ids[subframe] = rel8->harq_process;
    dlsch1->harq_ids[subframe] = rel8->harq_process;
    //    printf("Setting DLSCH harq id %d to subframe %d\n",harq_pid,subframe);


    conv_rballoc(rel8->resource_allocation_type,
                 rel8->resource_block_coding,
                 fp->N_RB_DL,
                 dlsch0_harq->rb_alloc);

    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];
    dlsch0_harq->nb_rb                               = conv_nprb(rel8->resource_allocation_type,
								 rel8->resource_block_coding,
								 fp->N_RB_DL);
    dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;

    AssertFatal(dlsch0_harq->nb_rb > 0,"nb_rb=0\n");

    dlsch0_harq->mcs       = rel8->mcs_1;
    dlsch1_harq->mcs       = rel8->mcs_2;
    dlsch0_harq->Qm        = get_Qm(rel8->mcs_1);
    dlsch1_harq->Qm        = get_Qm(rel8->mcs_2);
    dlsch0_harq->rvidx     = rel8->redundancy_version_1;
    dlsch1_harq->rvidx     = rel8->redundancy_version_2;

    // assume both TBs are active
    dlsch0_harq->Nl        = 1;
    dlsch1_harq->Nl        = 1;
    dlsch0->active = 1;
    dlsch1->active = 1;
    dlsch0->harq_mask                         |= (1<<rel8->harq_process);
    dlsch1->harq_mask                         |= (1<<rel8->harq_process);

    // check if either TB is disabled (see 36-213 V11.3 Section )
    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
      dlsch0->active = 0;
      dlsch0->harq_mask                         &= ~(1<<rel8->harq_process);
    }

    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
      dlsch1->active = 0;
      dlsch1->harq_mask                         &= ~(1<<rel8->harq_process);
    }

   // dlsch0_harq->dl_power_off = 0;
   // dlsch1_harq->dl_power_off = 0;


    if (fp->nb_antenna_ports_eNB == 2) {
      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
      dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];

      if ((dlsch0->active==1) && (dlsch1->active==1)) {

        dlsch0_harq->mimo_mode = LARGE_CDD;
        dlsch1_harq->mimo_mode = LARGE_CDD;
        dlsch0_harq->dl_power_off = 1;
        dlsch1_harq->dl_power_off = 1;
      } else {
        dlsch0_harq->mimo_mode   = ALAMOUTI;
        dlsch1_harq->mimo_mode   = ALAMOUTI;
      }
    } else if (fp->nb_antenna_ports_eNB == 4) { // 4 antenna case
      if ((dlsch0->active==1) && (dlsch1->active==1)) {
        switch (rel8->precoding_information) {
        case 0: // one layer per transport block
          dlsch0_harq->mimo_mode   = LARGE_CDD;
          dlsch1_harq->mimo_mode   = LARGE_CDD;
          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
          dlsch0_harq->dl_power_off = 1;
          dlsch1_harq->dl_power_off = 1;
          break;

        case 1: // one-layers on TB 0, two on TB 1
          dlsch0_harq->mimo_mode   = LARGE_CDD;
          dlsch1_harq->mimo_mode   = LARGE_CDD;
          dlsch1_harq->Nl          = 2;
          dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1];
          dlsch0_harq->dl_power_off = 1;
          dlsch1_harq->dl_power_off = 1;
          break;

        case 2: // two-layers on TB 0, two on TB 1
          dlsch0_harq->mimo_mode   = LARGE_CDD;
          dlsch1_harq->mimo_mode   = LARGE_CDD;
          dlsch0_harq->Nl          = 2;
          dlsch0_harq->dl_power_off = 1;
          dlsch1_harq->dl_power_off = 1;

          if (fp->N_RB_DL <= 56) {
            dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1];
            dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1];
          } else {
            LOG_E(PHY,"Add implementation of Table 7.1.7.2.2-1 for two-layer TBS conversion with N_RB_DL > 56\n");
          }

          break;

        case 3: //
          LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n");
          break;
        }
      } else if (dlsch0->active == 1) {
        switch (rel8->precoding_information) {
        case 0: // one layer per transport block
          dlsch0_harq->mimo_mode   = ALAMOUTI;
          dlsch1_harq->mimo_mode   = ALAMOUTI;
          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
          break;

        case 1: // two-layers on TB 0
          dlsch0_harq->mimo_mode   = LARGE_CDD;
          dlsch0_harq->Nl          = 2;
          dlsch0_harq->dl_power_off = 1;
          dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1];
          break;

        case 2: // two-layers on TB 0, two on TB 1
        case 3: //
          LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",rel8->precoding_information);
          break;
        }
      } else if (dlsch1->active == 1) {
        switch (rel8->precoding_information) {
        case 0: // one layer per transport block
          dlsch0_harq->mimo_mode   = ALAMOUTI;
          dlsch1_harq->mimo_mode   = ALAMOUTI;
          dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
          break;

        case 1: // two-layers on TB 0
          dlsch1_harq->mimo_mode   = LARGE_CDD;
          dlsch1_harq->Nl          = 2;
          dlsch1_harq->dl_power_off = 1;
          dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][(dlsch1_harq->nb_rb<<1)-1];
          break;

        case 2: // two-layers on TB 0, two on TB 1
        case 3: //
          LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",rel8->precoding_information);
          break;
        }
      }
    } else {
      LOG_E(PHY,"Illegal number of antennas for eNB %d\n",fp->nb_antenna_ports_eNB);
    }

    // reset HARQ process if this is the first transmission
    if ((dlsch0->active==1) && (dlsch0_harq->round == 0))
      dlsch0_harq->status = ACTIVE;

    if ((dlsch1->active==1) && (dlsch1_harq->round == 0))
      dlsch1_harq->status = ACTIVE;

    dlsch0->rnti = rel8->rnti;
    dlsch1->rnti = rel8->rnti;


    break;
      
  case NFAPI_DL_DCI_FORMAT_2:

    dci_alloc->format     = format2;
    switch (fp->N_RB_DL) {
    case 6:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                       = sizeof_DCI2_1_5MHz_2A_TDD_t; 
        ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1     = rel8->mcs_1;
        ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2     = rel8->mcs_2;
        ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1     = rel8->new_data_indicator_1;
        ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2     = rel8->new_data_indicator_2;
        ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc  = rel8->resource_block_coding;
        ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1      = rel8->redundancy_version_1;
        ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2      = rel8->redundancy_version_2;
        ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->TPC      = rel8->tpc;
        ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process;
	((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap  = rel8->transport_block_to_codeword_swap_flag;
        ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->dai      = rel8->downlink_assignment_index;
        ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi     = rel8->precoding_information;
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                         = sizeof_DCI2_1_5MHz_2A_FDD_t; 
        ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1         = rel8->mcs_1;
        ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2         = rel8->mcs_2;
        ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1         = rel8->new_data_indicator_1;
        ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2         = rel8->new_data_indicator_2;
        ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc      = rel8->resource_block_coding;
        ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1          = rel8->redundancy_version_1;
        ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2          = rel8->redundancy_version_2;
        ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->TPC          = rel8->tpc;
        ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid     = rel8->harq_process;
	((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap      = rel8->transport_block_to_codeword_swap_flag;
        ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi         = rel8->precoding_information;
        //      printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      break;
    case 25:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                        = sizeof_DCI2_5MHz_2A_TDD_t; 
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah       = rel8->resource_allocation_type;
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1      = rel8->mcs_1;
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2      = rel8->mcs_2;
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1      = rel8->new_data_indicator_1;
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2      = rel8->new_data_indicator_2;
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc   = rel8->resource_block_coding;
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1       = rel8->redundancy_version_1;
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2       = rel8->redundancy_version_2;
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC       = rel8->tpc;
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid  = rel8->harq_process;
	((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap   = rel8->transport_block_to_codeword_swap_flag;	
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->dai       = rel8->downlink_assignment_index;	
        ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi      = rel8->precoding_information;
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                           = sizeof_DCI2_5MHz_2A_FDD_t; 
        ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah           = rel8->resource_allocation_type;
        ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1          = rel8->mcs_1;
        ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2          = rel8->mcs_2;
        ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1          = rel8->new_data_indicator_1;
        ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2          = rel8->new_data_indicator_2;
        ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc       = rel8->resource_block_coding;
        ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1           = rel8->redundancy_version_1;
        ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2           = rel8->redundancy_version_2;
        ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC           = rel8->tpc;
        ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid      = rel8->harq_process;
	((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap       = rel8->transport_block_to_codeword_swap_flag;
        ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi     = rel8->precoding_information;	
        //      printf("FDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      break;
    case 50:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                        = sizeof_DCI2_10MHz_2A_TDD_t; 
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah      = rel8->resource_allocation_type;
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1     = rel8->mcs_1;
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2     = rel8->mcs_2;
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1     = rel8->new_data_indicator_1;
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2     = rel8->new_data_indicator_2;
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc  = rel8->resource_block_coding;
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1      = rel8->redundancy_version_1;
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2      = rel8->redundancy_version_2;
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->TPC      = rel8->tpc;
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid = rel8->harq_process;
	((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap  = rel8->transport_block_to_codeword_swap_flag;	
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->dai      = rel8->downlink_assignment_index;	
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi     = rel8->precoding_information;
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                        = sizeof_DCI2_10MHz_2A_FDD_t; 
        ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah       = rel8->resource_allocation_type;
        ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1      = rel8->mcs_1;
        ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2      = rel8->mcs_2;
        ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1      = rel8->new_data_indicator_1;
        ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2      = rel8->new_data_indicator_2;
        ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc   = rel8->resource_block_coding;
        ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1       = rel8->redundancy_version_1;
        ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2       = rel8->redundancy_version_2;
        ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->TPC       = rel8->tpc;
        ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid  = rel8->harq_process;
	((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap   = rel8->transport_block_to_codeword_swap_flag;	
        ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi      = rel8->precoding_information;
      }
      break;
    case 100:
      if (fp->frame_type == TDD) {
	dci_alloc->dci_length                        = sizeof_DCI2_20MHz_2A_TDD_t; 
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah       = rel8->resource_allocation_type;
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1      = rel8->mcs_1;
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2      = rel8->mcs_2;
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1      = rel8->new_data_indicator_1;
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2      = rel8->new_data_indicator_2;
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc   = rel8->resource_block_coding;
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1       = rel8->redundancy_version_1;
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2       = rel8->redundancy_version_2;
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->TPC       = rel8->tpc;
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid  = rel8->harq_process;
	((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap   = rel8->transport_block_to_codeword_swap_flag;		
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->dai       = rel8->downlink_assignment_index;	
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi      = rel8->precoding_information;
        //        printf("TDD 1: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      } else {
	dci_alloc->dci_length                           = sizeof_DCI2_20MHz_2A_FDD_t; 
        ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah          = rel8->resource_allocation_type;
        ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1         = rel8->mcs_1;
        ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2         = rel8->mcs_2;
        ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1         = rel8->new_data_indicator_1;
        ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2         = rel8->new_data_indicator_2;
        ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc      = rel8->resource_block_coding;
        ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1          = rel8->redundancy_version_1;
        ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2          = rel8->redundancy_version_2;
        ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->TPC          = rel8->tpc;
        ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid     = rel8->harq_process;
	((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap      = rel8->transport_block_to_codeword_swap_flag;	
        ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi         = rel8->precoding_information;
      }
      break;

    }

    AssertFatal(rel8->harq_process>=8, "Format 2_2A: harq_pid=%d >= 8\n", rel8->harq_process);


    // Flip the TB to codeword mapping as described in 5.3.3.1.5 of 36-212 V11.3.0
    // note that we must set tbswap=0 in eNB scheduler if one TB is deactivated
    TB0_active = 1;
    TB1_active = 1;

    if ((rel8->redundancy_version_1 == 1) && (rel8->mcs_1 == 0)) {
      TB0_active=0;
    }
    if ((rel8->redundancy_version_2 == 1) && (rel8->mcs_2 == 0)) {
      TB1_active=0;
    }
#ifdef DEBUG_HARQ
    printf("RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rel8->redundancy_version_1, rel8->redundancy_version_2, rel8->mcs_1, rel8->mcs_2);
#endif
    if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag==0) {
      dlsch0->active = 1;
      dlsch1->active = 1;
      dlsch0->harq_mask                         |= (1<<rel8->harq_process);
      dlsch1->harq_mask                         |= (1<<rel8->harq_process);
      dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
      dlsch1_harq = dlsch1->harq_processes[rel8->harq_process];
      dlsch0_harq->mcs = rel8->mcs_1;
      dlsch1_harq->mcs = rel8->mcs_2;
      dlsch0_harq->Qm  = get_Qm(rel8->mcs_1);
      dlsch1_harq->Qm  = get_Qm(rel8->mcs_2);
      dlsch0_harq->rvidx = rel8->redundancy_version_1;
      dlsch1_harq->rvidx = rel8->redundancy_version_2;
      dlsch0_harq->status = ACTIVE;
      dlsch1_harq->status = ACTIVE;
      dlsch0_harq->codeword=0;
      dlsch1_harq->codeword=1;
#ifdef DEBUG_HARQ
      printf("\n ENB: BOTH ACTIVE\n");
#endif
    }
    else if (TB0_active && TB1_active && rel8->transport_block_to_codeword_swap_flag==1) {
      dlsch0 = eNB->dlsch[UE_id][1];
      dlsch1 = eNB->dlsch[UE_id][0];
      dlsch0->active = 1;
      dlsch1->active = 1;

      dlsch0->harq_mask                         |= (1<<rel8->harq_process);
      dlsch1->harq_mask                         |= (1<<rel8->harq_process);

      dlsch1_harq = dlsch1->harq_processes[rel8->harq_process];
      dlsch0_harq->mcs = rel8->mcs_1;
      dlsch1_harq->mcs = rel8->mcs_2;
      dlsch0_harq->Qm  = get_Qm(rel8->mcs_1);
      dlsch1_harq->Qm  = get_Qm(rel8->mcs_2);
      dlsch0_harq->rvidx = rel8->redundancy_version_1;
      dlsch1_harq->rvidx = rel8->redundancy_version_2;
      dlsch0_harq->status = ACTIVE;
      dlsch1_harq->status = ACTIVE;
      dlsch0_harq->codeword=1;
      dlsch1_harq->codeword=0;
    }
    else if (TB0_active && (TB1_active==0)) {
      dlsch0->active = 1;
      dlsch0->harq_mask                         |= (1<<rel8->harq_process);
      dlsch0_harq = dlsch0->harq_processes[rel8->harq_process];
      dlsch0_harq->mcs = rel8->mcs_1;
      dlsch0_harq->Qm  = get_Qm(rel8->mcs_1);
      dlsch0_harq->rvidx = rel8->redundancy_version_1;
      dlsch0_harq->status = ACTIVE;
      dlsch0_harq->codeword = 0;
      dlsch1=NULL;
      dlsch1_harq = NULL;
#ifdef DEBUG_HARQ
      printf("\n ENB: TB1 is deactivated, retransmit TB0 transmit in TM6\n");
#endif
    }
    else if ((TB0_active==0) && TB1_active) {
      dlsch1->active = 1;
      dlsch1->harq_mask                         |= (1<<rel8->harq_process);
      dlsch1_harq = dlsch1->harq_processes[rel8->harq_process];
      dlsch1_harq->mcs = rel8->mcs_2;
      dlsch1_harq->Qm  = get_Qm(rel8->mcs_2);
      dlsch1_harq->rvidx = rel8->redundancy_version_2;
      dlsch1_harq->status = ACTIVE;
      dlsch1_harq->codeword = 0;
      dlsch0=NULL;
      dlsch0_harq = NULL;
#ifdef DEBUG_HARQ
      printf("\n ENB: TB0 is deactivated, retransmit TB1 transmit in TM6\n");
#endif
    }

    if (dlsch0 != NULL){
      dlsch0->subframe_tx[subframe] = 1;

      dlsch0->harq_ids[subframe] = rel8->harq_process;
    }

    if (dlsch1_harq != NULL){
      dlsch1->harq_ids[subframe] = rel8->harq_process;
    }


    if (dlsch0 != NULL ){
      conv_rballoc(rel8->resource_allocation_type,
                   rel8->resource_block_coding,
                   fp->N_RB_DL,
                   dlsch0_harq->rb_alloc);

      dlsch0_harq->nb_rb = conv_nprb(rel8->resource_allocation_type, rel8->resource_block_coding, fp->N_RB_DL);

      if (dlsch1 != NULL){
        dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0];
        dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
      }
    } else if ((dlsch0 == NULL ) && (dlsch1 != NULL )){
        conv_rballoc(rel8->resource_allocation_type,
                     rel8->resource_block_coding,
                     fp->N_RB_DL,
                     dlsch1_harq->rb_alloc);

        dlsch1_harq->nb_rb = conv_nprb(rel8->resource_allocation_type, rel8->resource_block_coding, fp->N_RB_DL);
    }


    // assume both TBs are active
    if (dlsch0_harq != NULL)
      dlsch0_harq->Nl        = 1;
    if (dlsch1_harq != NULL)
      dlsch1_harq->Nl        = 1;


    // check if either TB is disabled (see 36-213 V11.3 Section )

    if (fp->nb_antenna_ports_eNB == 2) {
      if ((dlsch0 != NULL) && (dlsch1 != NULL)) {  //two CW active

        dlsch0_harq->dl_power_off = 1;
        dlsch1_harq->dl_power_off = 1;
        dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
        dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
        switch (rel8->precoding_information) {
        case 0:
          dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
          dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
          dlsch0_harq->pmi_alloc   = pmi_extend(fp,0,1);
          dlsch1_harq->pmi_alloc   = pmi_extend(fp,0,1);
          break;
        case 1:
          dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
          dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
          dlsch0_harq->pmi_alloc   = pmi_extend(fp,1,1);
          dlsch0_harq->pmi_alloc   = pmi_extend(fp,1,1);

          break;
        case 2: // PUSCH precoding
          dlsch0_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
          dlsch0_harq->pmi_alloc   = DL_pmi_single;
          dlsch1_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
          dlsch1_harq->pmi_alloc   = DL_pmi_single;
          break;
        default:
          break;
        }
      } else if ((dlsch0 != NULL) && (dlsch1 == NULL))  { // only CW 0 active
        dlsch0_harq->dl_power_off = 1;
        dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
        switch (rel8->precoding_information) {
        case 0 :
          dlsch0_harq->mimo_mode   = ALAMOUTI;
          break;
        case 1:
          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING11;
          dlsch0_harq->pmi_alloc   = pmi_extend(fp,0,0);
          break;
        case 2:
          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
          dlsch0_harq->pmi_alloc   = pmi_extend(fp,1,0);
          break;
        case 3:
          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
          dlsch0_harq->pmi_alloc   = pmi_extend(fp,2,0);
          break;
        case 4:
          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
          dlsch0_harq->pmi_alloc   = pmi_extend(fp,3,0);
          break;
        case 5:
          dlsch0_harq->mimo_mode   = PUSCH_PRECODING0;
          dlsch0_harq->pmi_alloc   = DL_pmi_single;
          break;
        case 6:
          dlsch0_harq->mimo_mode   = PUSCH_PRECODING1;
          dlsch0_harq->pmi_alloc   = DL_pmi_single;
          break;
        }
      } else if ((dlsch0 == NULL) && (dlsch1 != NULL))  {
          dlsch1_harq->dl_power_off = 1;
          dlsch1_harq->TBS= TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
          switch (rel8->precoding_information) {
          case 0 :
            dlsch1_harq->mimo_mode   = ALAMOUTI;
            break;
          case 1:
            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING11;
            dlsch1_harq->pmi_alloc   = pmi_extend(fp,0,0);
            break;
          case 2:
            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1m1;
            dlsch1_harq->pmi_alloc   = pmi_extend(fp,1,0);
            break;
          case 3:
            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1j;
            dlsch1_harq->pmi_alloc   = pmi_extend(fp,2,0);
            break;
          case 4:
            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1mj;
            dlsch1_harq->pmi_alloc   = pmi_extend(fp,3,0);
            break;
          case 5:
            dlsch1_harq->mimo_mode   = PUSCH_PRECODING0;
            dlsch1_harq->pmi_alloc   = DL_pmi_single;
            break;
          case 6:
            dlsch1_harq->mimo_mode   = PUSCH_PRECODING1;
            dlsch1_harq->pmi_alloc   = DL_pmi_single;
            break;
          }
        }

    } else if (fp->nb_antenna_ports_eNB == 4) {
      // fill in later
    }

    // reset HARQ process if this is the first transmission
   /* if (dlsch0_harq->round == 0)
      dlsch0_harq->status = ACTIVE;

    if (dlsch1_harq->round == 0)
      dlsch1_harq->status = ACTIVE;*/
    if (dlsch0_harq != NULL)
      dlsch0->rnti = rel8->rnti;
    if (dlsch1 != NULL)
      dlsch1->rnti = rel8->rnti;

    break;
  }

  if (dlsch0_harq) {
    dlsch0_harq->frame    = proc->frame_tx;
    dlsch0_harq->subframe = subframe;
  }
  if (dlsch1_harq) {
    dlsch1_harq->frame    = proc->frame_tx;
    dlsch1_harq->subframe = subframe;
  }

#ifdef DEBUG_DCI

  if (dlsch0) {
    printf("dlsch0 eNB: dlsch0   %p\n",dlsch0);
    printf("dlsch0 eNB: rnti     %x\n",dlsch0->rnti);
    printf("dlsch0 eNB: NBRB     %d\n",dlsch0_harq->nb_rb);
    printf("dlsch0 eNB: rballoc  %x\n",dlsch0_harq->rb_alloc[0]);
    printf("dlsch0 eNB: harq_pid %d\n",harq_pid);
    printf("dlsch0 eNB: round    %d\n",dlsch0_harq->round);
    printf("dlsch0 eNB: rvidx    %d\n",dlsch0_harq->rvidx);
    printf("dlsch0 eNB: TBS      %d (NPRB %d)\n",dlsch0_harq->TBS,NPRB);
    printf("dlsch0 eNB: mcs      %d\n",dlsch0_harq->mcs);
    printf("dlsch0 eNB: tpmi %d\n",rel8->precoding_information);
    printf("dlsch0 eNB: mimo_mode %d\n",dlsch0_harq->mimo_mode);
  }

    if (dlsch1) {
    printf("dlsch1 eNB: dlsch1   %p\n",dlsch1);
    printf("dlsch1 eNB: rnti     %x\n",dlsch1->rnti);
    printf("dlsch1 eNB: NBRB     %d\n",dlsch1_harq->nb_rb);
    printf("dlsch1 eNB: rballoc  %x\n",dlsch1_harq->rb_alloc[0]);
    printf("dlsch1 eNB: harq_pid %d\n",harq_pid);
    printf("dlsch1 eNB: round    %d\n",dlsch1_harq->round);
    printf("dlsch1 eNB: rvidx    %d\n",dlsch1_harq->rvidx);
    printf("dlsch1 eNB: TBS      %d (NPRB %d)\n",dlsch1_harq->TBS,NPRB);
    printf("dlsch1 eNB: mcs      %d\n",dlsch1_harq->mcs);
    printf("dlsch1 eNB: tpmi %d\n",rel8->precoding_information);
    printf("dlsch1 eNB: mimo_mode %d\n",dlsch1_harq->mimo_mode);
  }

#endif
    
#if T_TRACER
  if (dlsch0->active)
    T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(proc->frame_tx), T_INT(proc->subframe_tx),
      T_INT(rel8->rnti), T_INT(rel8->dci_format), T_INT(rel8->harq_process),
      T_INT(rel8->mcs_1), T_INT(dlsch0_harq->TBS));
#endif

}

void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu) {

  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;

  uint8_t *dci_pdu = &dci_alloc->dci_pdu[0];
  nfapi_dl_config_mpdcch_pdu_rel13_t *rel13 = &pdu->mpdcch_pdu_rel13;

  LTE_eNB_DLSCH_t *dlsch0=NULL;
  LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL;
  int UE_id;
  int subframe = proc->subframe_tx;

  dci_alloc->firstCCE                   = rel13->ecce_index;
  dci_alloc->L                          = rel13->aggregation_level;
  dci_alloc->rnti                       = rel13->rnti;
  dci_alloc->harq_pid                   = rel13->harq_process;
  dci_alloc->narrowband                  = rel13->mpdcch_narrow_band;
  dci_alloc->number_of_prb_pairs        = rel13->number_of_prb_pairs;
  dci_alloc->resource_block_assignment  = rel13->resource_block_assignment;
  dci_alloc->transmission_type          = rel13->mpdcch_tansmission_type;
  dci_alloc->start_symbol               = rel13->start_symbol;
  dci_alloc->ce_mode                    = rel13->ce_mode;
  dci_alloc->dmrs_scrambling_init       = rel13->drms_scrambling_init;
  dci_alloc->i0                         = rel13->initial_transmission_sf_io;

  dci_alloc->ra_flag  = 0;
  if (rel13->rnti_type == 2 ) dci_alloc->ra_flag = 1;

  UE_id = find_dlsch(rel13->rnti,eNB,SEARCH_EXIST_OR_FREE);
  AssertFatal(UE_id!=-1,"no free or exiting dlsch_context\n");
  AssertFatal(UE_id<NUMBER_OF_UE_MAX,"returned UE_id %d >= %d(NUMBER_OF_UE_MAX)\n",UE_id,NUMBER_OF_UE_MAX);
  dlsch0 = eNB->dlsch[UE_id][0];
  dlsch0_harq                               = dlsch0->harq_processes[rel13->harq_process];

  AssertFatal(fp->frame_type==FDD,"TDD is not supported yet for eMTC\n");
  AssertFatal(fp->N_RB_DL==25 || fp->N_RB_DL==50 ||fp->N_RB_DL==100,
	      "eMTC only with N_RB_DL = 25,50,100\n");

  switch (rel13->dci_format) {

  case 10:  // Format 6-1A
    dci_alloc->format     = format6_1A;
    dlsch0->active       = 1;
    switch (fp->N_RB_DL) {

    case 25:
      dci_alloc->dci_length                     = sizeof_DCI6_1A_5MHz_t; 
      ((DCI6_1A_5MHz_t *)dci_pdu)->type         = 1;
      ((DCI6_1A_5MHz_t *)dci_pdu)->hopping      = rel13->frequency_hopping_enabled_flag;
      ((DCI6_1A_5MHz_t *)dci_pdu)->rballoc      = rel13->resource_block_coding;
      ((DCI6_1A_5MHz_t *)dci_pdu)->mcs          = rel13->mcs;
      ((DCI6_1A_5MHz_t *)dci_pdu)->rep          = (rel13->pdsch_reptition_levels-1);
      ((DCI6_1A_5MHz_t *)dci_pdu)->harq_pid     = rel13->harq_process;
      ((DCI6_1A_5MHz_t *)dci_pdu)->ndi          = rel13->new_data_indicator;
      ((DCI6_1A_5MHz_t *)dci_pdu)->rv           = rel13->redundancy_version;
      ((DCI6_1A_5MHz_t *)dci_pdu)->TPC          = rel13->tpc;
      ((DCI6_1A_5MHz_t *)dci_pdu)->srs_req      = rel13->srs_request;
      ((DCI6_1A_5MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset;
      ((DCI6_1A_5MHz_t *)dci_pdu)->dci_rep      = rel13->dci_subframe_repetition_number-1;
    
      break;
    case 50:
      dci_alloc->dci_length                     = sizeof_DCI6_1A_10MHz_t; 
      ((DCI6_1A_10MHz_t *)dci_pdu)->type         = 1;
      ((DCI6_1A_10MHz_t *)dci_pdu)->hopping      = rel13->frequency_hopping_enabled_flag;
      ((DCI6_1A_10MHz_t *)dci_pdu)->rballoc      = rel13->resource_block_coding;
      ((DCI6_1A_10MHz_t *)dci_pdu)->mcs          = rel13->mcs;
      ((DCI6_1A_10MHz_t *)dci_pdu)->rep          = (rel13->pdsch_reptition_levels-1);
      ((DCI6_1A_10MHz_t *)dci_pdu)->harq_pid     = rel13->harq_process;
      ((DCI6_1A_10MHz_t *)dci_pdu)->ndi          = rel13->new_data_indicator;
      ((DCI6_1A_10MHz_t *)dci_pdu)->rv           = rel13->redundancy_version;
      ((DCI6_1A_10MHz_t *)dci_pdu)->TPC          = rel13->tpc;
      ((DCI6_1A_10MHz_t *)dci_pdu)->srs_req      = rel13->srs_request;
      ((DCI6_1A_10MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset;
      ((DCI6_1A_10MHz_t *)dci_pdu)->dci_rep      = rel13->dci_subframe_repetition_number-1;
      break;
    case 100:
      dci_alloc->dci_length                     = sizeof_DCI6_1A_20MHz_t; 
      ((DCI6_1A_20MHz_t *)dci_pdu)->type         = 1;
      ((DCI6_1A_20MHz_t *)dci_pdu)->hopping      = rel13->frequency_hopping_enabled_flag;
      ((DCI6_1A_20MHz_t *)dci_pdu)->rballoc      = rel13->resource_block_coding;
      ((DCI6_1A_20MHz_t *)dci_pdu)->mcs          = rel13->mcs;
      ((DCI6_1A_20MHz_t *)dci_pdu)->rep          = (rel13->pdsch_reptition_levels-1);
      ((DCI6_1A_20MHz_t *)dci_pdu)->harq_pid     = rel13->harq_process;
      ((DCI6_1A_20MHz_t *)dci_pdu)->ndi          = rel13->new_data_indicator;
      ((DCI6_1A_20MHz_t *)dci_pdu)->rv           = rel13->redundancy_version;
      ((DCI6_1A_20MHz_t *)dci_pdu)->TPC          = rel13->tpc;
      ((DCI6_1A_20MHz_t *)dci_pdu)->srs_req      = rel13->srs_request;
      ((DCI6_1A_20MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset;
      ((DCI6_1A_20MHz_t *)dci_pdu)->dci_rep      = rel13->dci_subframe_repetition_number-1;
      break;
    }
    break;
  case 11:  // Format 6-1B
    dci_alloc->format     = format6_1B;
    dlsch0->active       = 1;
    switch (fp->N_RB_DL) {

    case 25:
      dci_alloc->dci_length                     = sizeof_DCI6_1B_5MHz_t; 
      ((DCI6_1B_5MHz_t *)dci_pdu)->type         = 1;
      ((DCI6_1B_5MHz_t *)dci_pdu)->rballoc      = rel13->resource_block_coding;
      ((DCI6_1B_5MHz_t *)dci_pdu)->mcs          = rel13->mcs;
      ((DCI6_1B_5MHz_t *)dci_pdu)->rep          = (rel13->pdsch_reptition_levels-1);
      ((DCI6_1B_5MHz_t *)dci_pdu)->harq_pid     = rel13->harq_process;
      ((DCI6_1B_5MHz_t *)dci_pdu)->ndi          = rel13->new_data_indicator;
      ((DCI6_1B_5MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset;
      ((DCI6_1B_5MHz_t *)dci_pdu)->dci_rep      = rel13->dci_subframe_repetition_number-1;
  
      break;
    case 50:
      dci_alloc->dci_length                      = sizeof_DCI6_1B_10MHz_t; 
      ((DCI6_1B_10MHz_t *)dci_pdu)->type         = 1;
      ((DCI6_1B_10MHz_t *)dci_pdu)->rballoc      = rel13->resource_block_coding;
      ((DCI6_1B_10MHz_t *)dci_pdu)->mcs          = rel13->mcs;
      ((DCI6_1B_10MHz_t *)dci_pdu)->rep          = (rel13->pdsch_reptition_levels-1);
      ((DCI6_1B_10MHz_t *)dci_pdu)->harq_pid     = rel13->harq_process;
      ((DCI6_1B_10MHz_t *)dci_pdu)->ndi          = rel13->new_data_indicator;
      ((DCI6_1B_10MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset;
      ((DCI6_1B_10MHz_t *)dci_pdu)->dci_rep      = rel13->dci_subframe_repetition_number-1;
      break;
    case 100:
      dci_alloc->dci_length                      = sizeof_DCI6_1B_20MHz_t; 
      ((DCI6_1B_20MHz_t *)dci_pdu)->type         = 1;
      ((DCI6_1B_20MHz_t *)dci_pdu)->rballoc      = rel13->resource_block_coding;
      ((DCI6_1B_20MHz_t *)dci_pdu)->mcs          = rel13->mcs;
      ((DCI6_1B_20MHz_t *)dci_pdu)->rep          = (rel13->pdsch_reptition_levels-1);
      ((DCI6_1B_20MHz_t *)dci_pdu)->harq_pid     = rel13->harq_process;
      ((DCI6_1B_20MHz_t *)dci_pdu)->ndi          = rel13->new_data_indicator;
      ((DCI6_1B_20MHz_t *)dci_pdu)->harq_ack_off = rel13->harq_resource_offset;
      ((DCI6_1B_20MHz_t *)dci_pdu)->dci_rep      = rel13->dci_subframe_repetition_number-1;
      break;
    }
  case 12: // Format 6-2
    dci_alloc->format     = format6_2;
    dlsch0->active       = 1;
    switch (fp->N_RB_DL) {
    case 25:
      dci_alloc->dci_length                 = sizeof_DCI6_2_5MHz_t; 
      if (rel13->paging_direct_indication_differentiation_flag==0) {
	((DCI6_2_di_5MHz_t *)dci_pdu)->type    = 0;
	((DCI6_2_di_5MHz_t *)dci_pdu)->di_info = rel13->direct_indication;
      }
      else {
	((DCI6_2_paging_5MHz_t *)dci_pdu)->type    = 1;
	((DCI6_2_paging_5MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding;
	((DCI6_2_paging_5MHz_t *)dci_pdu)->mcs     = rel13->mcs;
	((DCI6_2_paging_5MHz_t *)dci_pdu)->rep     = (rel13->pdsch_reptition_levels-1);
	((DCI6_2_paging_5MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1;
      }

    break;
    case 50:
      dci_alloc->dci_length                 = sizeof_DCI6_2_10MHz_t; 
      if (rel13->paging_direct_indication_differentiation_flag==0) {
	((DCI6_2_di_10MHz_t *)dci_pdu)->type    = 0;
	((DCI6_2_di_10MHz_t *)dci_pdu)->di_info = rel13->direct_indication;
      }
      else {
	((DCI6_2_paging_10MHz_t *)dci_pdu)->type    = 1;
	((DCI6_2_paging_10MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding;
	((DCI6_2_paging_10MHz_t *)dci_pdu)->mcs     = rel13->mcs;
	((DCI6_2_paging_10MHz_t *)dci_pdu)->rep     = (rel13->pdsch_reptition_levels-1);
	((DCI6_2_paging_10MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1;
      }

    break;
    case 100:
      dci_alloc->dci_length                 = sizeof_DCI6_2_20MHz_t; 
      if (rel13->paging_direct_indication_differentiation_flag==0) {
	((DCI6_2_di_20MHz_t *)dci_pdu)->type    = 0;
	((DCI6_2_di_20MHz_t *)dci_pdu)->di_info = rel13->direct_indication;
      }
      else {
	((DCI6_2_paging_20MHz_t *)dci_pdu)->type    = 1;
	((DCI6_2_paging_20MHz_t *)dci_pdu)->rballoc = rel13->resource_block_coding;
	((DCI6_2_paging_20MHz_t *)dci_pdu)->mcs     = rel13->mcs;
	((DCI6_2_paging_20MHz_t *)dci_pdu)->rep     = (rel13->pdsch_reptition_levels-1);
	((DCI6_2_paging_20MHz_t *)dci_pdu)->dci_rep = rel13->dci_subframe_repetition_number-1;
      }

      break;
    }
  }
  AssertFatal(rel13->harq_process<8,
	      "ERROR: Format 6_1A: harq_pid=%d >= 8\n", rel13->harq_process);
  
  dlsch0_harq = dlsch0->harq_processes[rel13->harq_process];
  dlsch0_harq->codeword=0;
  
  // printf("DCI: Setting subframe_tx for subframe %d\n",subframe);
  dlsch0->subframe_tx[subframe] = 1;
  
  conv_eMTC_rballoc(rel13->resource_block_coding,
		    fp->N_RB_DL,
		    dlsch0_harq->rb_alloc);
  
  dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rel13->resource_block_coding&31]; // this is the 6PRB RIV
  
  
  dlsch0_harq->rvidx       = rel13->redundancy_version;
  
  dlsch0_harq->Nl          = 1;
  //    dlsch[0]->layer_index = 0;
  //  if (beamforming_mode == 0)
  dlsch0_harq->mimo_mode = (fp->nb_antenna_ports_eNB == 1) ? SISO : ALAMOUTI;
    //else if (beamforming_mode == 7)
    //  dlsch0_harq->mimo_mode = TM7;
    //else
    //LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode);
  
  dlsch0_harq->dl_power_off = 1;
  
  dlsch0->active = 1;
  dlsch0->harq_mask                         |= (1<<rel13->harq_process);  
  
  
  if (dlsch0_harq->round == 0) {
    dlsch0_harq->status = ACTIVE;
    //            printf("Setting DLSCH process %d to ACTIVE\n",rel8->harq_process);
    // MCS and TBS don't change across HARQ rounds
    dlsch0_harq->mcs         = rel13->mcs;
    dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
    
  }
  
  dlsch0->harq_ids[subframe] = rel13->harq_process;
  
  
  
  dlsch0->rnti = rel13->rnti;







}

void fill_dci0(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,
               nfapi_hi_dci0_dci_pdu *pdu)
{
  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;

  uint32_t cqi_req = pdu->dci_pdu_rel8.cqi_csi_request;
  uint32_t dai     = pdu->dci_pdu_rel8.dl_assignment_index;
  uint32_t cshift  = pdu->dci_pdu_rel8.cyclic_shift_2_for_drms;
  uint32_t TPC     = pdu->dci_pdu_rel8.tpc;
  uint32_t mcs     = pdu->dci_pdu_rel8.mcs_1;
  uint32_t hopping = pdu->dci_pdu_rel8.frequency_hopping_enabled_flag;
  uint32_t rballoc = computeRIV(frame_parms->N_RB_DL,
				pdu->dci_pdu_rel8.resource_block_start,
				pdu->dci_pdu_rel8.number_of_resource_block);

  uint32_t ndi     = pdu->dci_pdu_rel8.new_data_indication_1;

#ifdef T_TRACER
  T(T_ENB_PHY_ULSCH_UE_DCI, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx),
    T_INT(pdu->dci_pdu_rel8.rnti), T_INT(((proc->frame_tx*10+proc->subframe_tx+4) % 8) /* TODO: correct harq pid */),
    T_INT(mcs), T_INT(-1 /* TODO: remove round? */),
    T_INT(pdu->dci_pdu_rel8.resource_block_start),
    T_INT(pdu->dci_pdu_rel8.number_of_resource_block),
    T_INT(-1 /* TODO: get TBS */),
    T_INT(pdu->dci_pdu_rel8.aggregation_level),
    T_INT(pdu->dci_pdu_rel8.cce_index));
#endif

  void *dci_pdu = (void*)dci_alloc->dci_pdu;

  LOG_D(PHY,"Filling DCI0 with cqi %d, mcs %d, hopping %d, rballoc %x (%d,%d) ndi %d TPC %d cshift %d\n",cqi_req,
	mcs,hopping,rballoc,pdu->dci_pdu_rel8.resource_block_start,pdu->dci_pdu_rel8.number_of_resource_block,
	ndi,TPC,cshift);

  dci_alloc->format   = format0;
  dci_alloc->firstCCE = pdu->dci_pdu_rel8.cce_index;
  dci_alloc->L        = pdu->dci_pdu_rel8.aggregation_level;
  dci_alloc->rnti     = pdu->dci_pdu_rel8.rnti;
  dci_alloc->ra_flag  = 0;

  switch (frame_parms->N_RB_DL) {
  case 6:
    if (frame_parms->frame_type == TDD) {
      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req;
      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai     = dai;
      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift  = cshift;
      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC     = TPC;
      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping;
      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
      ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0;
      dci_alloc->dci_length                       = sizeof_DCI0_1_5MHz_TDD_1_6_t; 
    } else {
      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req     = cqi_req;
      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift      = cshift;
      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC         = TPC;
      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs         = mcs;
      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->ndi         = ndi;
      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping     = hopping;
      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type        = 0;
      ((DCI0_1_5MHz_FDD_t *)dci_pdu)->padding     = 0;
      dci_alloc->dci_length                       = sizeof_DCI0_1_5MHz_FDD_t; 
    }
    
    break;
    
  case 25:
    if (frame_parms->frame_type == TDD) {
      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req;
      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai     = dai;
      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift  = cshift;
      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC     = TPC;
      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping;
      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
      ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->padding = 0;
      dci_alloc->dci_length                     = sizeof_DCI0_5MHz_TDD_1_6_t; 
    } else {
      ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req     = cqi_req;
      ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift      = cshift;
      ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC         = TPC;
      ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs         = mcs;
      ((DCI0_5MHz_FDD_t *)dci_pdu)->ndi         = ndi;
      ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
      ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping     = hopping;
      ((DCI0_5MHz_FDD_t *)dci_pdu)->type        = 0;
      ((DCI0_5MHz_FDD_t *)dci_pdu)->padding     = 0;
      dci_alloc->dci_length                     = sizeof_DCI0_5MHz_FDD_t; 
    }
    
    break;
    
  case 50:
    if (frame_parms->frame_type == TDD) {
      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req;
      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai     = dai;
      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift  = cshift;
      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC     = TPC;
      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping;
      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
      ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->padding = 0;
      dci_alloc->dci_length                      = sizeof_DCI0_10MHz_TDD_1_6_t; 
    } else {
      ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req     = cqi_req;
      ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift      = cshift;
      ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC         = TPC;
      ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs         = mcs;
      ((DCI0_10MHz_FDD_t *)dci_pdu)->ndi         = ndi;
      ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
      ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping     = hopping;
      ((DCI0_10MHz_FDD_t *)dci_pdu)->type        = 0;
      ((DCI0_10MHz_FDD_t *)dci_pdu)->padding     = 0;
      dci_alloc->dci_length                      = sizeof_DCI0_10MHz_FDD_t; 
    }
    
    break;
    
  case 100:
    if (frame_parms->frame_type == TDD) {
      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req = cqi_req;
      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai     = dai;
      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift  = cshift;
      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC     = TPC;
      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs     = mcs;
      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->ndi     = ndi;
      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc = rballoc;
      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping = hopping;
      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type    = 0;
      ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->padding = 0;

      dci_alloc->dci_length                      = sizeof_DCI0_20MHz_TDD_1_6_t; 
    } else {
      ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req     = cqi_req;
      ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift      = cshift;
      ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC         = TPC;
      ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs         = mcs;
      ((DCI0_20MHz_FDD_t *)dci_pdu)->ndi         = ndi;
      ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc     = rballoc;
      ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping     = hopping;
      ((DCI0_20MHz_FDD_t *)dci_pdu)->type        = 0;
      ((DCI0_20MHz_FDD_t *)dci_pdu)->padding     = 0;
      dci_alloc->dci_length                      = sizeof_DCI0_20MHz_FDD_t; 
    }
    
      //printf("eNB: rb_alloc (20 MHz dci) %d\n",rballoc);
      break;
      
  default:
    LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
    DevParam (frame_parms->N_RB_DL, 0, 0);
    break;
  }
}

void fill_ulsch(PHY_VARS_eNB *eNB,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe)
{
  uint8_t harq_pid;
  uint8_t UE_id;
  boolean_t new_ulsch = (find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST)==-1) ? TRUE : FALSE;

  AssertFatal((UE_id=find_ulsch(ulsch_pdu->ulsch_pdu_rel8.rnti,eNB,SEARCH_EXIST_OR_FREE))>=0,
	      "No existing/free UE ULSCH for rnti %x\n",ulsch_pdu->ulsch_pdu_rel8.rnti);

  LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id];
  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;

  int use_srs = 0;

  harq_pid = ulsch_pdu->ulsch_pdu_rel8.harq_process_number;

  ulsch->harq_mask |= 1 << harq_pid;

  ulsch->harq_processes[harq_pid]->frame                                 = frame;
  ulsch->harq_processes[harq_pid]->subframe                              = subframe;
  ulsch->harq_processes[harq_pid]->handled                               = 0;

  ulsch->harq_processes[harq_pid]->first_rb                              = ulsch_pdu->ulsch_pdu_rel8.resource_block_start;
  ulsch->harq_processes[harq_pid]->nb_rb                                 = ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;

  AssertFatal(ulsch->harq_processes[harq_pid]->nb_rb>0,"nb_rb = 0\n");

  ulsch->harq_processes[harq_pid]->dci_alloc                             = 1;
  ulsch->harq_processes[harq_pid]->rar_alloc                             = 0;
  ulsch->harq_processes[harq_pid]->n_DMRS                                = ulsch_pdu->ulsch_pdu_rel8.cyclic_shift_2_for_drms;

  ulsch->harq_processes[harq_pid]->Nsymb_pusch                           = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1);
  ulsch->harq_processes[harq_pid]->srs_active                            = use_srs;

  //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1)
  if(ulsch->harq_processes[harq_pid]->n_DMRS == 0)
    ulsch->harq_processes[harq_pid]->n_DMRS2 = 0;
  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 1)
    ulsch->harq_processes[harq_pid]->n_DMRS2 = 6;
  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 2)
    ulsch->harq_processes[harq_pid]->n_DMRS2 = 3;
  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 3)
    ulsch->harq_processes[harq_pid]->n_DMRS2 = 4;
  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 4)
    ulsch->harq_processes[harq_pid]->n_DMRS2 = 2;
  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 5)
    ulsch->harq_processes[harq_pid]->n_DMRS2 = 8;
  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 6)
    ulsch->harq_processes[harq_pid]->n_DMRS2 = 10;
  else if(ulsch->harq_processes[harq_pid]->n_DMRS == 7)
    ulsch->harq_processes[harq_pid]->n_DMRS2 = 9;

  LOG_D(PHY,"[eNB %d][PUSCH %d] Programming PUSCH with n_DMRS2 %d (cshift %d) for Frame %d, Subframe %d\n",
	eNB->Mod_id,harq_pid,ulsch->harq_processes[harq_pid]->n_DMRS2,ulsch->harq_processes[harq_pid]->n_DMRS,
	frame,subframe);

  ulsch->harq_processes[harq_pid]->rvidx = ulsch_pdu->ulsch_pdu_rel8.redundancy_version;
  ulsch->harq_processes[harq_pid]->Qm    = ulsch_pdu->ulsch_pdu_rel8.modulation_type;
  // Set O_ACK to 0 by default, will be set of DLSCH is scheduled and needs to be
  ulsch->harq_processes[harq_pid]->O_ACK         = 0;

  if ((ulsch->harq_processes[harq_pid]->status == SCH_IDLE) ||
      (ulsch->harq_processes[harq_pid]->ndi    != ulsch_pdu->ulsch_pdu_rel8.new_data_indication) ||
	  (new_ulsch == TRUE)){
    ulsch->harq_processes[harq_pid]->status        = ACTIVE;

    ulsch->harq_processes[harq_pid]->TBS           = ulsch_pdu->ulsch_pdu_rel8.size<<3;

    ulsch->harq_processes[harq_pid]->Msc_initial   = 12*ulsch_pdu->ulsch_pdu_rel8.number_of_resource_blocks;
    ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->harq_processes[harq_pid]->Nsymb_pusch;
    ulsch->harq_processes[harq_pid]->round         = 0;
    ulsch->harq_processes[harq_pid]->ndi           = ulsch_pdu->ulsch_pdu_rel8.new_data_indication;
    // note here, the CQI bits need to be kept constant as in initial transmission
    // set to 0 in initial transmission, and don't touch them during retransmissions
    // will be set if MAC has activated ULSCH_CQI_RI_PDU or ULSCH_CQI_HARQ_RI_PDU
    ulsch->harq_processes[harq_pid]->Or1           = 0;
    ulsch->harq_processes[harq_pid]->Or2           = 0;
  }
  else  ulsch->harq_processes[harq_pid]->round++;

  ulsch->rnti = ulsch_pdu->ulsch_pdu_rel8.rnti;
  LOG_D(PHY,"Filling ULSCH %x (UE_id %d) (new_ulsch %d) for Frame %d, Subframe %d : harq_pid %d, first_rb %d, nb_rb %d, rvidx %d, Qm %d, TBS %d, round %d \n",
	ulsch->rnti,
        UE_id,
        new_ulsch,
	frame,
	subframe,
	harq_pid,
	ulsch->harq_processes[harq_pid]->first_rb,
	ulsch->harq_processes[harq_pid]->nb_rb,
	ulsch->harq_processes[harq_pid]->rvidx,
	ulsch->harq_processes[harq_pid]->Qm,
	ulsch->harq_processes[harq_pid]->TBS,
	ulsch->harq_processes[harq_pid]->round);
}

int dump_dci(LTE_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci)
{
  switch (dci->format) {

  case format0:   // This is an UL SCH allocation so nothing here, inform MAC
    if ((frame_parms->frame_type == TDD) &&
        (frame_parms->tdd_config>0))
      switch(frame_parms->N_RB_DL) {
      case 6:
        LOG_D(PHY,"DCI format0 (TDD, 1.5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu[0])[0],
              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping,
              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs,
              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi,
              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC,
              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift,
              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai,
              ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req);
        break;

      case 25:
        LOG_D(PHY,"DCI format0 (TDD1-6, 5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu[0])[0],
              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping,
              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs,
              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi,
              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC,
              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift,
              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai,
              ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req);
        break;

      case 50:
        LOG_D(PHY,"DCI format0 (TDD1-6, 10MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu[0])[0],
              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping,
              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs,
              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi,
              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC,
              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift,
              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai,
              ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req);
        break;

      case 100:
        LOG_D(PHY,"DCI format0 (TDD1-6, 20MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu[0])[0],
              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping,
              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs,
              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi,
              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC,
              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift,
              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai,
              ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req);
        break;

      default:
        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
        DevParam (frame_parms->N_RB_DL, 0, 0);
        break;
      }
    else if (frame_parms->frame_type == FDD)
      switch(frame_parms->N_RB_DL) {
      case 6:
        LOG_D(PHY,"DCI format0 (FDD, 1.5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu[0])[0],
              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->hopping,
              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC,
              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->cshift,
              ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req);
        break;

      case 25:
        LOG_D(PHY,"DCI format0 (FDD, 5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu[0])[0],
              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->hopping,
              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC,
              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->cshift,
              ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req);
        break;

      case 50:
        LOG_D(PHY,"DCI format0 (FDD, 10MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu[0])[0],
              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->hopping,
              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC,
              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->cshift,
              ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req);
        break;

      case 100:
        LOG_D(PHY,"DCI format0 (FDD, 20MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu[0])[0],
              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->hopping,
              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC,
              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->cshift,
              ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req);
        break;

      default:
        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
        DevParam (frame_parms->N_RB_DL, 0, 0);
        break;
      }
    else
      LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n");

    break;

  case format1:
    if ((frame_parms->frame_type == TDD) &&
        (frame_parms->tdd_config>0))

      switch(frame_parms->N_RB_DL) {
      case 6:
        LOG_D(PHY,"DCI format1 (TDD 1.5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu)[0],
              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah,
              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid,
              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rv,
              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->TPC,
              ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->dai);
        break;

      case 25:
        LOG_D(PHY,"DCI format1 (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu)[0],
              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah,
              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid,
              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rv,
              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->TPC,
              ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->dai);
        break;

      case 50:
        LOG_D(PHY,"DCI format1 (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu)[0],
              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rah,
              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid,
              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rv,
              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->TPC,
              ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->dai);
        break;

      case 100:
        LOG_D(PHY,"DCI format1 (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu)[0],
              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rah,
              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid,
              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rv,
              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->TPC,
              ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->dai);
        break;

      default:
        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
        DevParam (frame_parms->N_RB_DL, 0, 0);
        break;
      }
    else if (frame_parms->frame_type == FDD) {
      switch(frame_parms->N_RB_DL) {
      case 6:
        LOG_D(PHY,"DCI format1 (FDD, 1.5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu)[0],
              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rah,
              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid,
              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv,
              ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
        break;

      case 25:
        LOG_D(PHY,"DCI format1 (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu)[0],
              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rah,
              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid,
              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv,
              ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
        break;

      case 50:
        LOG_D(PHY,"DCI format1 (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu)[0],
              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rah,
              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid,
              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rv,
              ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
        break;

      case 100:
        LOG_D(PHY,"DCI format1 (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n",
              dci->rnti,
              ((uint32_t*)&dci->dci_pdu)[0],
              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rah,
              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,
              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs,
              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid,
              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi,
              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rv,
              ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
        break;

      default:
        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
        DevParam (frame_parms->N_RB_DL, 0, 0);
        break;
      }
    }

    else
      LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n");

    break;

  case format1A:  // This is DLSCH allocation for control traffic
    if ((frame_parms->frame_type == TDD) &&
        (frame_parms->tdd_config>0)) {
      switch (frame_parms->N_RB_DL) {
      case 6:
        LOG_D(PHY,"DCI format1A (TDD1-6, 1_5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]);
        LOG_D(PHY,"MCS %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
        LOG_D(PHY,"NDI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
        LOG_D(PHY,"RV %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
        LOG_D(PHY,"TPC %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
        LOG_D(PHY,"DAI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai);
        break;

      case 25:
        LOG_D(PHY,"DCI format1A (TDD1-6, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
        LOG_D(PHY,"RB_ALLOC %d (NB_RB %d)\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]);
        LOG_D(PHY,"MCS %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
        LOG_D(PHY,"NDI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
        LOG_D(PHY,"RV %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
        LOG_D(PHY,"TPC %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
        LOG_D(PHY,"DAI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai);
        break;

      case 50:
        LOG_D(PHY,"DCI format1A (TDD1-6, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]);
        LOG_D(PHY,"MCS %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
        LOG_D(PHY,"NDI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
        LOG_D(PHY,"RV %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
        LOG_D(PHY,"TPC %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
        LOG_D(PHY,"DAI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai);
        break;

      case 100:
        LOG_D(PHY,"DCI format1A (TDD1-6, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT100[((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]);
        LOG_D(PHY,"MCS %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
        LOG_D(PHY,"NDI %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
        LOG_D(PHY,"RV %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
        LOG_D(PHY,"TPC %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
        LOG_D(PHY,"DAI %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai);
        break;

      default:
        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
        DevParam (frame_parms->N_RB_DL, 0, 0);
        break;
      }

    } else if (frame_parms->frame_type == FDD) {
      switch (frame_parms->N_RB_DL) {
      case 6:
        LOG_D(PHY,"DCI format1A(FDD, 1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]);
        LOG_D(PHY,"MCS %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
        LOG_D(PHY,"NDI %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
        LOG_D(PHY,"RV %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv);
        LOG_D(PHY,"TPC %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
        break;

      case 25:
        LOG_D(PHY,"DCI format1A(FDD, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]);
        LOG_D(PHY,"MCS %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
        LOG_D(PHY,"NDI %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
        LOG_D(PHY,"RV %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rv);
        LOG_D(PHY,"TPC %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
        break;

      case 50:
        LOG_D(PHY,"DCI format1A(FDD, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]);
        LOG_D(PHY,"MCS %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
        LOG_D(PHY,"NDI %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
        LOG_D(PHY,"RV %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rv);
        LOG_D(PHY,"TPC %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
        break;

      case 100:
        LOG_D(PHY,"DCI format1A(FDD, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
        LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
        LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT100[((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]);
        LOG_D(PHY,"MCS %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
        LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
        LOG_D(PHY,"NDI %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
        LOG_D(PHY,"RV %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rv);
        LOG_D(PHY,"TPC %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
        break;

      default:
        LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
        DevParam (frame_parms->N_RB_DL, 0, 0);
        break;
      }
    }

    break;

  case format1C:  // This is DLSCH allocation for control traffic
    switch (frame_parms->N_RB_DL) {
    case 6:
      LOG_D(PHY,"DCI format1C (1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
      LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",
      ((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT6[conv_1C_RIV(((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,6)]);
      LOG_D(PHY,"MCS %d\n",((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->mcs);
      break;

    case 25:
      LOG_D(PHY,"DCI format1C (5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
      LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[conv_1C_RIV(((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,25)]);
      LOG_D(PHY,"MCS %d\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->mcs);
      break;

    case 50:
      LOG_D(PHY,"DCI format1C (10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
      LOG_D(PHY,"Ngap %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->Ngap);
      LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,50)]);
      LOG_D(PHY,"MCS %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->mcs);
      break;

    case 100:
      LOG_D(PHY,"DCI format1C (20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
      LOG_D(PHY,"Ngap %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->Ngap);
      LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,100)]);
      LOG_D(PHY,"MCS %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->mcs);
      break;


    default:
      LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
        DevParam (frame_parms->N_RB_DL, 0, 0);
        break;
    }


    break;

  case format2:

    if ((frame_parms->frame_type == TDD) &&
        (frame_parms->tdd_config>0)) {
      if (frame_parms->nb_antenna_ports_eNB == 2) {
        switch(frame_parms->N_RB_DL) {
        case 6:
          LOG_D(PHY,"DCI format2 2 antennas (TDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi
               );
          break;

        case 25:
          LOG_D(PHY,"DCI format2 2 antennas (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi);
          break;

        case 50:
          LOG_D(PHY,"DCI format2 2 antennas (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi);
          break;

        case 100:
          LOG_D(PHY,"DCI format2 2 antennas (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi);
          break;

        default:
          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
          DevParam (frame_parms->N_RB_DL, 0, 0);
          break;
        }
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
        switch(frame_parms->N_RB_DL) {
        case 6:
          LOG_D(PHY,"DCI format2 2 antennas (TDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi
               );
          break;

        case 25:
          LOG_D(PHY,"DCI format2 2 antennas (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
          break;

        case 50:
          LOG_D(PHY,"DCI format2 2 antennas (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
          break;

        case 100:
          LOG_D(PHY,"DCI format2 2 antennas (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
          break;

        default:
          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
          DevParam (frame_parms->N_RB_DL, 0, 0);
          break;
        }
      }
    } else if (frame_parms->frame_type == FDD) {
      if (frame_parms->nb_antenna_ports_eNB == 2) {
        switch(frame_parms->N_RB_DL) {
        case 6:
          LOG_D(PHY,"DCI format2 2 antennas (FDD, 1.5 MHz), rnti %x (%x):  rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 25:

          LOG_D(PHY,"DCI format2 2 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, swap %d, TPMI %d, TPC %d\n",

                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 50:
          LOG_D(PHY,"DCI format2 2 antennas (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 100:
          LOG_D(PHY,"DCI format2 2 antennas (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        default:
          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
          DevParam (frame_parms->N_RB_DL, 0, 0);
          break;
        }
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
        switch(frame_parms->N_RB_DL) {

        case 6:
          LOG_D(PHY,"DCI format2 4 antennas (FDD, 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 25:
          LOG_D(PHY,"DCI format2 4 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 50:
          LOG_D(PHY,"DCI format2 4 antennas (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 100:
          LOG_D(PHY,"DCI format2 4 antennas (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        default:
          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
          DevParam (frame_parms->N_RB_DL, 0, 0);
          break;
        }
      }
    }

    else
      LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n");

    break;

  case format2A:

    if ((frame_parms->frame_type == TDD) &&
        (frame_parms->tdd_config>0)) {
      if (frame_parms->nb_antenna_ports_eNB == 2) {
        switch(frame_parms->N_RB_DL) {
        case 6:
          LOG_D(PHY,"DCI format2A 2 antennas (FDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap
               );
          break;

        case 25:
          LOG_D(PHY,"DCI format2A 2 antennas (FDD 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap);
          break;

        case 50:
          LOG_D(PHY,"DCI format2A 2 antennas (FDD 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap);
          break;

        case 100:
          LOG_D(PHY,"DCI format2A 2 antennas (FDD 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap);
          break;

        default:
          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
          DevParam (frame_parms->N_RB_DL, 0, 0);
          break;
        }
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
        switch(frame_parms->N_RB_DL) {
        case 6:
          LOG_D(PHY,"DCI format2A 4 antennas (TDD 1.5 MHz), rnti %x (%"PRIu64"): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi
               );
          break;

        case 25:
          LOG_D(PHY,"DCI format2A 4 antennas (TDD 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
          break;

        case 50:
          LOG_D(PHY,"DCI format2A 4 antennas (TDD 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
          break;

        case 100:
          LOG_D(PHY,"DCI format2A 4 antennas (TDD 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi);
          break;

        default:
          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
          DevParam (frame_parms->N_RB_DL, 0, 0);
          break;
        }
      }
    } else if (frame_parms->frame_type == FDD) {
      if (frame_parms->nb_antenna_ports_eNB == 2) {
        switch(frame_parms->N_RB_DL) {
        case 6:
          LOG_D(PHY,"DCI format2A 2 antennas (FDD, 1.5 MHz), rnti %x (%x):  rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n",
                dci->rnti,
                ((uint32_t*)&dci->dci_pdu)[0],
                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 25:
          LOG_D(PHY,"DCI format2A 2 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 50:
          LOG_D(PHY,"DCI format2A 2 antennas (FDD, 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 100:
          LOG_D(PHY,"DCI format2A 2 antennas (FDD, 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        default:
          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
          DevParam (frame_parms->N_RB_DL, 0, 0);
          break;
        }
      } else if (frame_parms->nb_antenna_ports_eNB == 4) {
        switch(frame_parms->N_RB_DL) {

        case 6:
          LOG_D(PHY,"DCI format2A 4 antennas (FDD, 1.5 MHz), rnti %x (%"PRIu64"): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 25:
          LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 50:
          LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        case 100:
          LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n",
                dci->rnti,
                ((uint64_t*)&dci->dci_pdu)[0],
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah,
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc,
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1,
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2,
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid,
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1,
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2,
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1,
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2,
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap,
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi,
                ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC);
          break;

        default:
          LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
          DevParam (frame_parms->N_RB_DL, 0, 0);
          break;
        }
      }
    }

    else
      LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n");

    break;

  case format1E_2A_M10PRB:

    LOG_D(PHY,"DCI format1E_2A_M10PRB, rnti %x (%8x): harq_pid %d, rah %d, rb_alloc %x, mcs %d, rv %d, tpmi %d, ndi %d, dl_power_offset %d\n",
          dci->rnti,
          ((uint32_t *)&dci->dci_pdu)[0],
          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->harq_pid,
          //((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->tb_swap,
          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rah,
          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rballoc,
          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->mcs,
          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rv,
          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->tpmi,
          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->ndi,
          ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->dl_power_off
         );

    break;

  default:
    LOG_E(PHY,"dci_tools.c: dump_dci, unknown format %d\n",dci->format);
    return(-1);
  }

  return(0);
}

void extract_dci1A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
{
    uint8_t harq_pid=0;
    uint32_t rballoc=0;
    uint8_t vrb_type=0;
    uint8_t mcs=0;
    uint8_t rv=0;
    uint8_t ndi=0;
    uint8_t TPC=0;

    uint8_t dai=0;

    switch (N_RB_DL) {
    case 6:
        if (frame_type == TDD) {
            vrb_type = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
            mcs      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
            rballoc  = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
            rv       = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv;
            ndi      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi;
            TPC      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
            harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
            dai      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai;
            //  printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
        } else {
            vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type;
            mcs      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs;
            rballoc  = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc;
            rv       = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv;
            ndi      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->ndi;
            TPC      = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC;
            harq_pid  = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
            //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
        }
        break;

    case 25:

        if (frame_type == TDD) {
            vrb_type = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
            mcs      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
            rballoc  = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
            rv       = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv;
            ndi      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi;
            TPC      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
            harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
            dai      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai;
            //printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
        } else {
            vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type;
            mcs      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs;
            rballoc  = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc;
            rv       = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv;
            ndi      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->ndi;
            TPC      = ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC;
            harq_pid  = ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid;
            //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
        }

        break;

    case 50:
        if (frame_type == TDD) {
            vrb_type = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
            mcs      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs;
            rballoc  = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc;
            rv       = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv;
            ndi      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->ndi;
            TPC      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC;
            harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
            dai      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai;
            //  printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
        } else {
            vrb_type = ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type;
            mcs      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs;
            rballoc  = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc;
            rv       = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv;
            ndi      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->ndi;
            TPC      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC;
            harq_pid  = ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid;
            //printf("FDD 1A: mcs %d, vrb_type %d, rballoc %x,ndi %d, rv %d, TPC %d\n",mcs,vrb_type,rballoc,ndi,rv,TPC);
        }
        break;

    case 100:
        if (frame_type == TDD) {
            vrb_type = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type;
            mcs      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs;
            rballoc  = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc;
            rv       = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv;
            ndi      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->ndi;
            TPC      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC;
            harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
            dai      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai;
            //  printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
        } else {
            vrb_type = ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type;
            mcs      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs;
            rballoc  = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc;
            rv       = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv;
            ndi      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->ndi;
            TPC      = ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC;
            harq_pid = ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid;
            //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC);
        }
        break;
    }

    pdci_info_extarcted->vrb_type = vrb_type;
    pdci_info_extarcted->mcs1     = mcs;
    pdci_info_extarcted->rballoc  = rballoc;
    pdci_info_extarcted->rv1      = rv;
    pdci_info_extarcted->ndi1     = ndi;
    pdci_info_extarcted->TPC      = TPC;
    pdci_info_extarcted->harq_pid = harq_pid;
    pdci_info_extarcted->dai      = dai;
}

void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
{

    uint32_t rballoc=0;
    uint8_t mcs=0;

    switch (N_RB_DL) {
        case 6:
          mcs             = ((DCI1C_5MHz_t *)dci_pdu)->mcs;
          rballoc         = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6);

          break;

        case 25:
            mcs             = ((DCI1C_5MHz_t *)dci_pdu)->mcs;
            rballoc         = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6);

          break;

        case 50:
            mcs             = ((DCI1C_10MHz_t *)dci_pdu)->mcs;
            rballoc         = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc,6);

          break;

        case 100:
            mcs             = ((DCI1C_20MHz_t *)dci_pdu)->mcs;
            rballoc         = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc,6);
          break;

        default:
          AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",N_RB_DL);
          break;
        }

    pdci_info_extarcted->mcs1     = mcs;
    pdci_info_extarcted->rballoc  = rballoc;
}

void extract_dci1_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
{

    uint32_t rballoc=0;
    uint8_t mcs=0;
    uint8_t rah=0;
    uint8_t rv=0;
    uint8_t TPC=0;
    uint8_t ndi=0;
    uint8_t harq_pid=0;

    switch (N_RB_DL) {
    case 6:
        if (frame_type == TDD) {
            mcs       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs;
            rballoc   = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc;
            rah       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah;
            rv        = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv;
            TPC       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->TPC;
            ndi       = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->ndi;
            harq_pid  = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
        } else {
            mcs      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs;
            rah      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah;
            rballoc  = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc;
            rv       = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv;
            TPC       = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->TPC;
            ndi      = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->ndi;
            harq_pid = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
        }

        break;

    case 25:
        if (frame_type == TDD) {
            mcs       = ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs;
            rballoc   = ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc;
            rah       = ((DCI1_5MHz_TDD_t *)dci_pdu)->rah;
            rv        = ((DCI1_5MHz_TDD_t *)dci_pdu)->rv;
            TPC       = ((DCI1_5MHz_TDD_t *)dci_pdu)->TPC;
            ndi       = ((DCI1_5MHz_TDD_t *)dci_pdu)->ndi;
            harq_pid  = ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid;
        } else {
            mcs      = ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs;
            rah      = ((DCI1_5MHz_FDD_t *)dci_pdu)->rah;
            rballoc  = ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc;
            rv       = ((DCI1_5MHz_FDD_t *)dci_pdu)->rv;
            TPC      = ((DCI1_5MHz_FDD_t *)dci_pdu)->TPC;
            ndi      = ((DCI1_5MHz_FDD_t *)dci_pdu)->ndi;
            harq_pid = ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid;
        }

        break;

    case 50:
        if (frame_type == TDD) {
            mcs       = ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs;
            rballoc   = ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc;
            rah       = ((DCI1_10MHz_TDD_t *)dci_pdu)->rah;
            rv        = ((DCI1_10MHz_TDD_t *)dci_pdu)->rv;
            TPC       = ((DCI1_10MHz_TDD_t *)dci_pdu)->TPC;
            ndi       = ((DCI1_10MHz_TDD_t *)dci_pdu)->ndi;
            harq_pid  = ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid;
        } else {
            mcs      = ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs;
            rah      = ((DCI1_10MHz_FDD_t *)dci_pdu)->rah;
            rballoc  = ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc;
            rv       = ((DCI1_10MHz_FDD_t *)dci_pdu)->rv;
            TPC      = ((DCI1_10MHz_FDD_t *)dci_pdu)->TPC;
            ndi      = ((DCI1_10MHz_FDD_t *)dci_pdu)->ndi;
            harq_pid = ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid;
        }

        break;

    case 100:
        if (frame_type == TDD) {
            mcs       = ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs;
            rballoc   = ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc;
            rah       = ((DCI1_20MHz_TDD_t *)dci_pdu)->rah;
            rv        = ((DCI1_20MHz_TDD_t *)dci_pdu)->rv;
            TPC        = ((DCI1_20MHz_TDD_t *)dci_pdu)->TPC;
            ndi       = ((DCI1_20MHz_TDD_t *)dci_pdu)->ndi;
            harq_pid  = ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid;
        } else {
            mcs      = ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs;
            rah      = ((DCI1_20MHz_FDD_t *)dci_pdu)->rah;
            rballoc  = ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc;
            rv       = ((DCI1_20MHz_FDD_t *)dci_pdu)->rv;
            TPC      = ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC;
            ndi      = ((DCI1_20MHz_FDD_t *)dci_pdu)->ndi;
            harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid;
        }

        break;
    }

    pdci_info_extarcted->mcs1     = mcs;
    pdci_info_extarcted->rah      = rah;
    pdci_info_extarcted->rballoc  = rballoc;
    pdci_info_extarcted->rv1      = rv;
    pdci_info_extarcted->TPC      = TPC;
    pdci_info_extarcted->ndi1     = ndi;
    pdci_info_extarcted->harq_pid = harq_pid;

}

void extract_dci2_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
{

    uint32_t rballoc=0;
    uint8_t rah=0;
    uint8_t mcs1=0;
    uint8_t mcs2=0;
    uint8_t rv1=0;
    uint8_t rv2=0;
    uint8_t ndi1=0;
    uint8_t ndi2=0;
    uint8_t tbswap=0;
    uint8_t tpmi=0;
    uint8_t harq_pid=0;
    uint8_t TPC=0;

    switch (N_RB_DL) {

    case 6:
        if (nb_antenna_ports_eNB == 2) {
            if (frame_type == TDD) {
                rah       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2;
            } else {
                rah       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2;
            }
        } else if (nb_antenna_ports_eNB == 4) {
            if (frame_type == TDD) {
                rah       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi2;
            } else {
                rah       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2;
            }
        } else {
            LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB);
        }

        break;

    case 25:
        if (nb_antenna_ports_eNB == 2) {
            if (frame_type == TDD) {
                rah       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2;
            } else {
                rah       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2;
            }
        } else if (nb_antenna_ports_eNB == 4) {
            if (frame_type == TDD) {
                rah       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2;
            } else {
                rah       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2;
            }
        } else {
            LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB);
        }

        break;

    case 50:
        if (nb_antenna_ports_eNB == 2) {
            if (frame_type == TDD) {
                rah       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2;
            } else {
                rah       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2;
            }
        } else if (nb_antenna_ports_eNB == 4) {
            if (frame_type == TDD) {
                rah       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi2;
            } else {
                rah       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi2;
            }
        } else {
            LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB);
        }

        break;

    case 100:
        if (nb_antenna_ports_eNB == 2) {
            if (frame_type == TDD) {
                rah       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2;
            } else {
                rah       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2;
            }
        } else if (nb_antenna_ports_eNB == 4) {
            if (frame_type == TDD) {
                rah       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi2;
            } else {
                rah       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah;
                mcs1      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs1;
                mcs2      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs2;
                rballoc   = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rballoc;
                rv1       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1;
                rv2       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2;
                harq_pid  = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid;
                tbswap    = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap;
                tpmi      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
                TPC       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->TPC;
                ndi1      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi1;
                ndi2      = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi2;
            }
        } else {
            LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB);
        }

        break;
    }

    pdci_info_extarcted->rah      = rah;
    pdci_info_extarcted->mcs1     = mcs1;
    pdci_info_extarcted->mcs2     = mcs2;
    pdci_info_extarcted->rv1      = rv1;
    pdci_info_extarcted->rv2      = rv2;
    pdci_info_extarcted->harq_pid = harq_pid;
    pdci_info_extarcted->rballoc  = rballoc;
    pdci_info_extarcted->tb_swap  = tbswap;
    pdci_info_extarcted->tpmi     = tpmi;
    pdci_info_extarcted->TPC      = TPC;
    pdci_info_extarcted->ndi1     = ndi1;
    pdci_info_extarcted->ndi2     = ndi2;

}

void extract_dci2A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted)
{

    uint32_t rballoc=0;
    uint8_t rah=0;
    uint8_t mcs1=0;
    uint8_t mcs2=0;
    uint8_t rv1=0;
    uint8_t rv2=0;
    uint8_t ndi1=0;
    uint8_t ndi2=0;
    uint8_t tbswap=0;
    uint8_t tpmi=0;
    uint8_t harq_pid=0;
    uint8_t TPC=0;

    AssertFatal( (nb_antenna_ports_eNB == 2) || (nb_antenna_ports_eNB == 4), "unsupported nb_antenna_ports_eNB %d\n", nb_antenna_ports_eNB);
    switch (N_RB_DL) {

    case 6:
      if (nb_antenna_ports_eNB == 2) {
        if (frame_type == TDD) {
          mcs1      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
          rv1       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
          TPC       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->TPC;
        } else {
          mcs1      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
          rv1       = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
          TPC       = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->TPC;
        }
      } else if (nb_antenna_ports_eNB == 4) {
        if (frame_type == TDD) {
          mcs1      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
          rv1       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
          tpmi      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
          TPC       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->TPC;
        } else {
          mcs1      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
          rv1       = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
          tpmi      = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
          TPC       = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->TPC;
        }
      }

      break;

    case 25:
      if (nb_antenna_ports_eNB == 2) {
        if (frame_type == TDD) {
          mcs1      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
          TPC       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->TPC;
        } else {
          mcs1      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
          TPC       = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->TPC;
        }
      } else if (nb_antenna_ports_eNB == 4) {
        if (frame_type == TDD) {
          mcs1      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
          tpmi      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
          TPC       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->TPC;
        } else {
          mcs1      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
          tpmi      = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
          TPC       = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->TPC;
        }
      }
      break;

    case 50:
      if (nb_antenna_ports_eNB == 2) {
        if (frame_type == TDD) {
          mcs1      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap;
          TPC       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->TPC;
        } else {
          mcs1      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
          TPC       = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->TPC;
        }
      } else if (nb_antenna_ports_eNB == 4) {
        if (frame_type == TDD) {
          mcs1      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tb_swap;
          tpmi      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tpmi;
          TPC       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->TPC;
        } else {
          mcs1      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tb_swap;
          tpmi      = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tpmi;
          TPC       = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->TPC;
        }
      }

      break;

    case 100:
      if (nb_antenna_ports_eNB == 2) {
        if (frame_type == TDD) {
          mcs1      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap;
          TPC       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->TPC;
        } else {
          mcs1      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
          TPC       = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->TPC;
        }
      } else if (nb_antenna_ports_eNB == 4) {
        if (frame_type == TDD) {
          mcs1      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tb_swap;
          tpmi      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tpmi;
          TPC       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->TPC;
        } else {
          mcs1      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs1;
          mcs2      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs2;
          rballoc   = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rballoc;
          rah       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rah;
          rv1       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv1;
          rv2       = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv2;
          ndi1      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi1;
          ndi2      = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi2;
          harq_pid  = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->harq_pid;
          tbswap    = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tb_swap;
          tpmi    = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tpmi;
          TPC     = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->TPC;
        }
      }

      break;
    }

    pdci_info_extarcted->mcs1     = mcs1;
    pdci_info_extarcted->mcs2     = mcs2;
    pdci_info_extarcted->rballoc  = rballoc;
    pdci_info_extarcted->rah      = rah;
    pdci_info_extarcted->rv1      = rv1;
    pdci_info_extarcted->rv2      = rv2;
    pdci_info_extarcted->ndi1     = ndi1;
    pdci_info_extarcted->ndi2     = ndi2;
    pdci_info_extarcted->harq_pid = harq_pid;
    pdci_info_extarcted->tb_swap  = tbswap;
    pdci_info_extarcted->TPC      = TPC;
    pdci_info_extarcted->tpmi     = tpmi;
}

int check_dci_format1_1a_coherency(DCI_format_t dci_format,
        uint8_t N_RB_DL,
        uint16_t rnti,
        uint16_t tc_rnti,
        uint16_t si_rnti,
        uint16_t ra_rnti,
        uint16_t p_rnti,
        uint32_t frame,
        uint8_t  subframe,
        DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
        LTE_DL_UE_HARQ_t *pdlsch0_harq)
{
    uint8_t  harq_pid  = pdci_info_extarcted->harq_pid;
    uint32_t rballoc   = pdci_info_extarcted->rballoc;
    uint8_t  mcs1      = pdci_info_extarcted->mcs1;
    uint8_t  TPC       = pdci_info_extarcted->TPC;
    uint8_t  rah       = pdci_info_extarcted->rah;
#ifdef DEBUG_DCI
    uint8_t  rv1       = pdci_info_extarcted->rv1;
    uint8_t  ndi1      = pdci_info_extarcted->ndi1;
#endif

    uint8_t  NPRB    = 0;
    long long int RIV_max = 0;

#ifdef DEBUG_DCI
    LOG_I(PHY,"[DCI-FORMAT-1-1A] AbsSubframe %d.%d dci_format %d\n", frame, subframe, dci_format);
    LOG_I(PHY,"[DCI-FORMAT-1-1A] rnti       %x\n",  rnti);
    LOG_I(PHY,"[DCI-FORMAT-1-1A] harq_pid   %d\n", harq_pid);
    LOG_I(PHY,"[DCI-FORMAT-1-1A] rah        %d\n", rah);
    LOG_I(PHY,"[DCI-FORMAT-1-1A] rballoc    %x\n", rballoc);
    LOG_I(PHY,"[DCI-FORMAT-1-1A] mcs1       %d\n", mcs1);
    LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1        %d\n", rv1);
    LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1       %d\n", ndi1);
    LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC        %d\n", TPC);
#endif


    // I- check dci content minimum coherency
    if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0)
    {
        return(0);
    }

    if(harq_pid>=8)
    {
        LOG_I(PHY,"bad harq id \n");
        return(0);
    }

    if(dci_format == format1 && ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) )
    {
        LOG_I(PHY,"bad dci format \n");
        return(0);
    }


    if( mcs1 > 28)
    {
        if(pdlsch0_harq->round == 0)
        {
            LOG_I(PHY,"bad dci mcs + round \n");
            return(0);
        }

        if((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
        {
            LOG_I(PHY,"bad dci mcs + rnti  \n");
            return(0);
        }
    }

    if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
    {
        NPRB = (TPC&1) + 2;
        switch (N_RB_DL) {
        case 6:
            RIV_max  = RIV_max6;
            break;
        case 25:
            RIV_max  = RIV_max25;
            break;
        case 50:
            RIV_max  = RIV_max50;
            break;
        case 100:
            RIV_max  = RIV_max100;
            break;
        }
    }
    else
    {
        switch (N_RB_DL) {
        case 6:
            NPRB     = RIV2nb_rb_LUT6[rballoc];//NPRB;
            if(rah)
              RIV_max  = RIV_max6;
            else
              RIV_max  = 0x3F;
            break;
        case 25:
            NPRB     = RIV2nb_rb_LUT25[rballoc];//NPRB;
            if(rah)
              RIV_max  = RIV_max25;
            else
              RIV_max  = 0x1FFF;
            break;
        case 50:
            NPRB     = RIV2nb_rb_LUT50[rballoc];//NPRB;
            if(rah)
              RIV_max  = RIV_max50;
            else
              RIV_max  = 0x1FFFF;
            break;
        case 100:
            NPRB     = RIV2nb_rb_LUT100[rballoc];//NPRB;
            if(rah)
              RIV_max  = RIV_max100;
            else
              RIV_max  =  0x1FFFFFF;
            break;
        }
    }


    if(dci_format == format1)
    {
        NPRB = conv_nprb(rah, rballoc, N_RB_DL);
    }


    if(rballoc > RIV_max)
    {
        LOG_I(PHY,"bad dci rballoc rballoc %d  RIV_max %lld \n",rballoc, RIV_max);
        // DCI false detection
        return(0);
    }

    if(NPRB == 0)
    {
        // DCI false detection
        LOG_I(PHY,"bad NPRB = 0 \n");
        return(0);
    }

    // this a retransmission
    if(pdlsch0_harq->round>0)
    {
        // compare old TBS to new TBS
        if((mcs1<29) && (pdlsch0_harq->TBS != TBStable[get_I_TBS(mcs1)][NPRB-1]))
        {
            // this is an eNB issue
            // retransmisison but old and new TBS are different !!!
            // work around, consider it as a new transmission
            LOG_E(PHY,"Format1A Retransmission but TBS are different: consider it as new transmission !!! \n");
            pdlsch0_harq->round = 0;
            //return(0); // ?? to cross check
        }
    }

    return(1);
}

int check_dci_format1c_coherency(uint8_t N_RB_DL,
                                 DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                 uint16_t rnti,
                                 uint16_t si_rnti,
                                 uint16_t ra_rnti,
                                 uint16_t p_rnti,
                                 LTE_DL_UE_HARQ_t *pdlsch0_harq)
{
    uint32_t rballoc = pdci_info_extarcted->rballoc;

    uint8_t  NPRB    = 0;
    uint32_t RIV_max = 0;

    // I- check dci content minimum coherency

    if((rnti!=si_rnti) && (rnti!=p_rnti) && (rnti!=ra_rnti))
      return(0);

    switch (N_RB_DL) {
    case 6:
      NPRB     = RIV2nb_rb_LUT6[rballoc];//NPRB;
      RIV_max  = RIV_max6;
    break;
    case 25:
      NPRB     = RIV2nb_rb_LUT25[rballoc];//NPRB;
      RIV_max  = RIV_max25;
    break;
    case 50:
      NPRB     = RIV2nb_rb_LUT50[rballoc];//NPRB;
      RIV_max  = RIV_max50;
    break;
    case 100:
      NPRB     = RIV2nb_rb_LUT100[rballoc];//NPRB;
      RIV_max  = RIV_max100;
    break;
    }

   if(rballoc > RIV_max)
   {
      // DCI false detection
      return(0);
   }

   if(NPRB == 0)
   {
      // DCI false detection
      return(0);
   }

   return(1);
}

int check_dci_format2_2a_coherency(DCI_format_t dci_format,
                                   uint8_t N_RB_DL,
                                   DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                   uint16_t rnti,
                                   uint16_t si_rnti,
                                   uint16_t ra_rnti,
                                   uint16_t p_rnti,
                                   LTE_DL_UE_HARQ_t *pdlsch0_harq,
                                   LTE_DL_UE_HARQ_t *pdlsch1_harq)
{
    uint8_t  rah  = pdci_info_extarcted->rah;
    uint8_t  mcs1 = pdci_info_extarcted->mcs1;
    uint8_t  mcs2 = pdci_info_extarcted->mcs2;
    uint8_t  rv1  = pdci_info_extarcted->rv1;
    uint8_t  rv2  = pdci_info_extarcted->rv2;
    uint8_t  harq_pid = pdci_info_extarcted->harq_pid;
    uint32_t rballoc  = pdci_info_extarcted->rballoc;

#ifdef DEBUG_DCI
    uint8_t  ndi1     = pdci_info_extarcted->ndi1;
    uint8_t  ndi2     = pdci_info_extarcted->ndi2;
#endif

    uint8_t  NPRB    = 0;
    long long RIV_max = 0;

#ifdef DEBUG_DCI
    LOG_I(PHY, "extarcted dci - dci_format %d \n", dci_format);
    LOG_I(PHY, "extarcted dci - rnti       %d \n", rnti);
    LOG_I(PHY, "extarcted dci - rah        %d \n", rah);
    LOG_I(PHY, "extarcted dci - mcs1       %d \n", mcs1);
    LOG_I(PHY, "extarcted dci - mcs2       %d \n", mcs2);
    LOG_I(PHY, "extarcted dci - rv1        %d \n", rv1);
    LOG_I(PHY, "extarcted dci - rv2        %d \n", rv2);
    //LOG_I(PHY, "extarcted dci - ndi1       %d \n", ndi1);
    //LOG_I(PHY, "extarcted dci - ndi2       %d \n", ndi2);
    LOG_I(PHY, "extarcted dci - rballoc    %x \n", rballoc);
    LOG_I(PHY, "extarcted dci - harq pid   %d \n", harq_pid);
    LOG_I(PHY, "extarcted dci - round0     %d \n", pdlsch0_harq->round);
    LOG_I(PHY, "extarcted dci - round1     %d \n", pdlsch1_harq->round);
#endif

    // I- check dci content minimum coherency
    if(harq_pid>=8)
    {
        LOG_I(PHY,"bad harq pid\n");
      return(0);
    }

    if( (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) )
    {
        LOG_I(PHY,"bad rnti\n");
        return(0);
    }


    if( mcs1 > 28)
    {
      if(pdlsch0_harq->round == 0)
      {
          LOG_I(PHY,"bad mcs1\n");
        return(0);
      }
    }

    if( mcs2 > 28)
    {
      if(pdlsch1_harq->round == 0)
      {
          LOG_I(PHY,"bad mcs2\n");
          return(0);
      }
    }


    if((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0))
    {
      // DCI false detection
        LOG_I(PHY,"bad rv1\n");
      return(0);
    }

    if((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0))
    {
      // DCI false detection
        LOG_I(PHY,"bad rv2\n");
      return(0);
    }


    switch (N_RB_DL) {
    case 6:
        if (rah == 0)
        {
            //RBG = 1;
            RIV_max = 0x3F;
        }
        else
        {
            RIV_max  = RIV_max6;
        }
        break;
    case 25:
        if (rah == 0)
        {
            //RBG = 2;
            RIV_max = 0x1FFF;
        }
        else
        {
            RIV_max  = RIV_max25;
        }
        break;
    case 50:
        if (rah == 0)
        {
            //RBG = 3;
            RIV_max = 0x1FFFF;
        }
        else
        {
            RIV_max  = RIV_max50;
        }
        break;
    case 100:
        if (rah == 0)
        {
            //RBG = 4;
            RIV_max  = 0x1FFFFFF;
        }
        else
        {
            RIV_max  = RIV_max100;
        }
        break;
    }

    NPRB = conv_nprb(rah,
                     rballoc,
                     N_RB_DL);



   if( (rballoc > RIV_max) && (rah == 1) )
   {
      // DCI false detection
       LOG_I(PHY,"bad rballoc %d RIV_max %lld\n", rballoc, RIV_max);
      return(0);
   }

   if(NPRB == 0)
   {
      // DCI false detection
       LOG_I(PHY,"bad NPRB\n");
      return(0);
   }

   return(1);
}

void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms,
                        LTE_UE_PDCCH *pdcch_vars,
                        LTE_UE_PDSCH *pdsch_vars,
                        LTE_DL_UE_HARQ_t *dlsch0_harq,
                        uint8_t nb_rb_alloc,
                        uint8_t subframe)
{
    uint32_t pbch_pss_sss_re;
    uint32_t crs_re;
    uint32_t granted_re;
    uint32_t data_re;
    uint32_t llr_offset;
    uint8_t symbol;
    uint8_t symbol_mod;

    pdsch_vars->llr_offset[pdcch_vars->num_pdcch_symbols] = 0;

    //LOG_I(PHY,"compute_llr_offset:  nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm);

    //dlsch0_harq->rb_alloc_even;
    //dlsch0_harq->rb_alloc_odd;

    for(symbol=pdcch_vars->num_pdcch_symbols; symbol<frame_parms->symbols_per_tti; symbol++)
    {
        symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol;
        if((symbol_mod == 0) || symbol_mod == (4-frame_parms->Ncp))
        {
	  if (frame_parms->nb_antennas_tx == 2) 
	    crs_re = 4;
	  else
	    crs_re = 2;
        }
        else
        {
            crs_re = 0;
        }

        granted_re = nb_rb_alloc * (12-crs_re);
        pbch_pss_sss_re = adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,dlsch0_harq->Qm,subframe,symbol);
        pbch_pss_sss_re = (double)pbch_pss_sss_re * ((double)(12-crs_re)/12);
        data_re = granted_re - pbch_pss_sss_re;
        llr_offset = data_re * dlsch0_harq->Qm * 2;

        pdsch_vars->llr_length[symbol]   = data_re;
        if(symbol < (frame_parms->symbols_per_tti-1))
          pdsch_vars->llr_offset[symbol+1] = pdsch_vars->llr_offset[symbol] + llr_offset;

        //LOG_I(PHY,"Granted Re subframe %d / symbol %d => %d (%d RBs)\n", subframe, symbol_mod, granted_re,dlsch0_harq->nb_rb);
        //LOG_I(PHY,"Pbch/PSS/SSS Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, pbch_pss_sss_re);
        //LOG_I(PHY,"CRS Re Per PRB subframe %d / symbol %d => %d \n", subframe, symbol_mod, crs_re);
        //LOG_I(PHY,"Data Re subframe %d / symbol %d => %d \n", subframe, symbol_mod, data_re);



        //LOG_I(PHY,"Data Re subframe %d-symbol %d => llr length %d, llr offset %d \n", subframe, symbol,
        //      pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]);
    }
}
void prepare_dl_decoding_format1_1A(DCI_format_t dci_format,
                                    uint8_t N_RB_DL,
                                    DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                    LTE_DL_FRAME_PARMS *frame_parms,
                                    LTE_UE_PDCCH *pdcch_vars,
                                    LTE_UE_PDSCH *pdsch_vars,
                                    uint8_t  subframe,
                                    uint16_t rnti,
									uint16_t tc_rnti,
                                    uint16_t si_rnti,
                                    uint16_t ra_rnti,
                                    uint16_t p_rnti,
                                    LTE_DL_UE_HARQ_t *pdlsch0_harq,
                                    LTE_UE_DLSCH_t *pdlsch0)
{

    uint8_t  harq_pid  = pdci_info_extarcted->harq_pid;
    uint8_t  vrb_type  = pdci_info_extarcted->vrb_type;
    uint32_t rballoc   = pdci_info_extarcted->rballoc;
    uint8_t  mcs1      = pdci_info_extarcted->mcs1;
    uint8_t  rv1       = pdci_info_extarcted->rv1;
    uint8_t  ndi1      = pdci_info_extarcted->ndi1;
    uint8_t  TPC       = pdci_info_extarcted->TPC;
    uint8_t  rah       = pdci_info_extarcted->rah;
    uint8_t  dai       = pdci_info_extarcted->dai;


    uint8_t  NPRB      = 0;
    uint8_t  NPRB4TBS  = 0;
    uint8_t  nb_rb_alloc = 0;

    if(dci_format == format1A)
    {
      switch (N_RB_DL) {
      case 6:
	NPRB     = RIV2nb_rb_LUT6[rballoc];
	break;
      case 25:
	NPRB     = RIV2nb_rb_LUT25[rballoc];
	break;
      case 50:
	NPRB     = RIV2nb_rb_LUT50[rballoc];
	break;
      case 100:
	NPRB     = RIV2nb_rb_LUT100[rballoc];
	break;
      }
      if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
        {
	  NPRB4TBS = (TPC&1) + 2;
        }
      else
        {
	  NPRB4TBS = NPRB;
	  /*
            switch (N_RB_DL) {
            case 6:
                NPRB     = RIV2nb_rb_LUT6[rballoc];//NPRB;
                break;
            case 25:
                NPRB     = RIV2nb_rb_LUT25[rballoc];//NPRB;
                break;
            case 50:
                NPRB     = RIV2nb_rb_LUT50[rballoc];//NPRB;
                break;
            case 100:
                NPRB     = RIV2nb_rb_LUT100[rballoc];//NPRB;
                break;
            }

	  */
	  nb_rb_alloc = NPRB;
        }
    }
    else // format1
    {
        NPRB = conv_nprb(rah, rballoc, N_RB_DL);
	NPRB4TBS=NPRB;
	nb_rb_alloc = NPRB;
    }

    pdlsch0->current_harq_pid = harq_pid;
    pdlsch0->active           = 1;
    pdlsch0->rnti             = rnti;
    if(dci_format == format1A)
        pdlsch0->harq_ack[subframe].vDAI_DL = dai+1;

    if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
    {
        pdlsch0_harq->round    = 0;
        pdlsch0_harq->status   = ACTIVE;
    }
    else //CRNTI
    {
    	if (rnti == tc_rnti) {
			//fix for standalone Contention Resolution Id
	  pdlsch0_harq->DCINdi = (uint8_t)-1;
	  LOG_D(PHY,"UE (%x/%d): Format1A DCI: C-RNTI is temporary. Set NDI = %d and to be ignored\n",
		rnti,harq_pid,pdlsch0_harq->DCINdi);
    	}

        // NDI has been toggled or this is the first transmission
        if ((ndi1!=pdlsch0_harq->DCINdi) || (pdlsch0_harq->first_tx==1))
        {
            pdlsch0_harq->round    = 0;
            pdlsch0_harq->first_tx = 0;
            pdlsch0_harq->status   = ACTIVE;

        }else if (rv1  != 0 )
            //NDI has not been toggled but rv was increased by eNB: retransmission
        {
            if (pdlsch0_harq->status == SCH_IDLE)
                //packet was actually decoded in previous transmission (ACK was missed by eNB)
                //However, the round is not a good check as it might have been decoded in a retransmission prior to this one.
            {
                LOG_D(PHY,"skip pdsch decoding and report ack\n");
                // skip pdsch decoding and report ack
                //pdlsch0_harq->status   = SCH_IDLE;
                pdlsch0->active       = 0;
                pdlsch0->harq_ack[subframe].ack = 1;
                pdlsch0->harq_ack[subframe].harq_id = harq_pid;
                pdlsch0->harq_ack[subframe].send_harq_status = 1;

                //pdlsch0_harq->first_tx = 0;
            }
            else  //normal retransmission
            {
                // nothing special to do
            }
        }
        else
        {
            pdlsch0_harq->status   = ACTIVE;
        }
    }

    pdlsch0_harq->DCINdi = ndi1;
    pdlsch0_harq->mcs    = mcs1;
    pdlsch0_harq->rvidx  = rv1;
    pdlsch0_harq->nb_rb  = NPRB;

    pdlsch0_harq->codeword     = 0;
    pdlsch0_harq->Nl           = 1;
    pdlsch0_harq->mimo_mode    = frame_parms->nb_antenna_ports_eNB == 1 ?SISO : ALAMOUTI;
    pdlsch0_harq->dl_power_off = 1; //no power offset
    pdlsch0_harq->delta_PUCCH  = delta_PUCCH_lut[TPC &3];

    // compute resource allocation
    if(dci_format == format1A)
    {
        switch (N_RB_DL) {
        case 6:
            if (vrb_type == LOCALIZED) {
                pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT6[rballoc];
                pdlsch0_harq->rb_alloc_odd[0]  = localRIV2alloc_LUT6[rballoc];
            }
            else {
                pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc];
                pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_odd_LUT6[rballoc];
            }
            break;

        case 25:
            if (vrb_type == LOCALIZED) {
                pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT25[rballoc];
                pdlsch0_harq->rb_alloc_odd[0]  = localRIV2alloc_LUT25[rballoc];
            }
            else {
                pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc];
                pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_odd_LUT25[rballoc];
            }
            break;

        case 50:
            if (vrb_type == LOCALIZED) {
                pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc];
                pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc];
                pdlsch0_harq->rb_alloc_odd[0]  = localRIV2alloc_LUT50_0[rballoc];
                pdlsch0_harq->rb_alloc_odd[1]  = localRIV2alloc_LUT50_1[rballoc];
                      printf("rballoc: %08x.%08x\n",pdlsch0_harq->rb_alloc_even[0],pdlsch0_harq->rb_alloc_even[1]);
            } else { // DISTRIBUTED
                if ((rballoc&(1<<10)) == 0) {
                    rballoc = rballoc&(~(1<<10));
                    pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc];
                    pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc];
                    pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap0_odd_LUT50_0[rballoc];
                    pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap0_odd_LUT50_1[rballoc];
                }
                else {
                    rballoc = rballoc&(~(1<<10));
                    pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc];
                    pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc];
                    pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap0_odd_LUT50_0[rballoc];
                    pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap0_odd_LUT50_1[rballoc];
                }
            }
            break;

        case 100:
            if (vrb_type == LOCALIZED) {
                pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT100_0[rballoc];
                pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT100_1[rballoc];
                pdlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc];
                pdlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc];
                pdlsch0_harq->rb_alloc_odd[0]  = localRIV2alloc_LUT100_0[rballoc];
                pdlsch0_harq->rb_alloc_odd[1]  = localRIV2alloc_LUT100_1[rballoc];
                pdlsch0_harq->rb_alloc_odd[2]  = localRIV2alloc_LUT100_2[rballoc];
                pdlsch0_harq->rb_alloc_odd[3]  = localRIV2alloc_LUT100_3[rballoc];
            } else {
                if ((rballoc&(1<<10)) == 0) { //Gap 1
                    rballoc = rballoc&(~(1<<12));
                    pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc];
                    pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc];
                    pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc];
                    pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc];
                    pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap0_odd_LUT100_0[rballoc];
                    pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap0_odd_LUT100_1[rballoc];
                    pdlsch0_harq->rb_alloc_odd[2]  = distRIV2alloc_gap0_odd_LUT100_2[rballoc];
                    pdlsch0_harq->rb_alloc_odd[3]  = distRIV2alloc_gap0_odd_LUT100_3[rballoc];
                }
                else { //Gap 2
                    rballoc = rballoc&(~(1<<12));
                    pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc];
                    pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc];
                    pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc];
                    pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc];
                    pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap1_odd_LUT100_0[rballoc];
                    pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap1_odd_LUT100_1[rballoc];
                    pdlsch0_harq->rb_alloc_odd[2]  = distRIV2alloc_gap1_odd_LUT100_2[rballoc];
                    pdlsch0_harq->rb_alloc_odd[3]  = distRIV2alloc_gap1_odd_LUT100_3[rballoc];
                }
            }
            break;
        }
    }
    else // format1
    {
        conv_rballoc(rah,rballoc,frame_parms->N_RB_DL,pdlsch0_harq->rb_alloc_even);
        pdlsch0_harq->rb_alloc_odd[0]= pdlsch0_harq->rb_alloc_even[0];
        pdlsch0_harq->rb_alloc_odd[1]= pdlsch0_harq->rb_alloc_even[1];
        pdlsch0_harq->rb_alloc_odd[2]= pdlsch0_harq->rb_alloc_even[2];
        pdlsch0_harq->rb_alloc_odd[3]= pdlsch0_harq->rb_alloc_even[3];
    }
    if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti))
    {
        pdlsch0_harq->TBS = TBStable[mcs1][NPRB4TBS-1];
        pdlsch0_harq->Qm  = 2;
    }
    else
    {
        if(mcs1 < 29)
        {
            pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB4TBS-1];
            pdlsch0_harq->Qm  = get_Qm(mcs1);
        }
    }

    compute_llr_offset(frame_parms,
                       pdcch_vars,
                       pdsch_vars,
                       pdlsch0_harq,
                       nb_rb_alloc,
                       subframe);
}

void prepare_dl_decoding_format1C(uint8_t N_RB_DL,
                                  DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                  LTE_DL_FRAME_PARMS *frame_parms,
                                  LTE_UE_PDCCH *pdcch_vars,
                                  LTE_UE_PDSCH *pdsch_vars,
                                  uint32_t rnti,
                                  uint32_t si_rnti,
                                  uint32_t ra_rnti,
                                  uint32_t p_rnti,
                                  uint32_t frame,
                                  uint8_t  subframe,
                                  LTE_DL_UE_HARQ_t *pdlsch0_harq,
                                  LTE_UE_DLSCH_t *pdlsch0)
{

    uint8_t  harq_pid  = pdci_info_extarcted->harq_pid;
    uint32_t rballoc   = pdci_info_extarcted->rballoc;
    uint8_t  mcs1      = pdci_info_extarcted->mcs1;
    uint8_t  Ngap      = pdci_info_extarcted->Ngap;

      pdlsch0_harq->round     = 0;
      pdlsch0_harq->first_tx  = 1;
      pdlsch0_harq->vrb_type  = DISTRIBUTED;

      if (rnti==si_rnti) { // rule from Section 5.3.1 of 36.321
        if (((frame&1) == 0) && (subframe == 5))
           pdlsch0_harq->rvidx = (((3*((frame>>1)&3))+1)>>1)&3;  // SIB1
        else
           pdlsch0_harq->rvidx = (((3*(subframe&3))+1)>>1)&3;  // other SIBs
      }
      else if ((rnti==p_rnti) || (rnti==ra_rnti)) { // Section 7.1.7.3
        pdlsch0_harq->rvidx = 0;
      }


      pdlsch0_harq->Nl           = 1;
      pdlsch0_harq->mimo_mode    = frame_parms->nb_antenna_ports_eNB == 1 ?SISO : ALAMOUTI;
      pdlsch0_harq->dl_power_off = 1; //no power offset

      pdlsch0_harq->codeword = 0;
      pdlsch0_harq->mcs      = mcs1;
      pdlsch0_harq->TBS      = TBStable1C[mcs1];
      pdlsch0_harq->Qm       = 2;


      pdlsch0->current_harq_pid = harq_pid;
      pdlsch0->active = 1;
      pdlsch0->rnti   = rnti;

    switch (N_RB_DL) {
    case 6:
        pdlsch0_harq->nb_rb            = RIV2nb_rb_LUT6[rballoc];
        pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc];
        pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_odd_LUT6[rballoc];

        break;

    case 25:
        pdlsch0_harq->nb_rb            = RIV2nb_rb_LUT25[rballoc];
        pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc];
        pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_odd_LUT25[rballoc];
        break;

    case 50:
        pdlsch0_harq->nb_rb            = RIV2nb_rb_LUT50[rballoc];
        if (Ngap == 0) {
            pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc];
            pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap0_odd_LUT50_0[rballoc];
            pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc];
            pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap0_odd_LUT50_1[rballoc];
        }
        else {
            pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc];
            pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap1_odd_LUT50_0[rballoc];
            pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc];
            pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap1_odd_LUT50_1[rballoc];
        }
        break;

    case 100:
        pdlsch0_harq->nb_rb       = RIV2nb_rb_LUT100[rballoc];
        if (Ngap==0) {
            pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc];
            pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap0_odd_LUT100_0[rballoc];
            pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc];
            pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap0_odd_LUT100_1[rballoc];
            pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc];
            pdlsch0_harq->rb_alloc_odd[2]  = distRIV2alloc_gap0_odd_LUT100_2[rballoc];
            pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc];
            pdlsch0_harq->rb_alloc_odd[3]  = distRIV2alloc_gap0_odd_LUT100_3[rballoc];
        }
        else {
            pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc];
            pdlsch0_harq->rb_alloc_odd[0]  = distRIV2alloc_gap1_odd_LUT100_0[rballoc];
            pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc];
            pdlsch0_harq->rb_alloc_odd[1]  = distRIV2alloc_gap1_odd_LUT100_1[rballoc];
            pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc];
            pdlsch0_harq->rb_alloc_odd[2]  = distRIV2alloc_gap1_odd_LUT100_2[rballoc];
            pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc];
            pdlsch0_harq->rb_alloc_odd[3]  = distRIV2alloc_gap1_odd_LUT100_3[rballoc];
        }
        break;

    default:
        AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL);
        break;
    }

    compute_llr_offset(frame_parms,
                       pdcch_vars,
                       pdsch_vars,
                       pdlsch0_harq,
                       pdlsch0_harq->nb_rb,
                       subframe);

}

void compute_precoding_info_2cw(uint8_t tpmi, uint8_t tbswap, uint16_t pmi_alloc, LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_UE_HARQ_t *dlsch0_harq, LTE_DL_UE_HARQ_t *dlsch1_harq)
{

switch (tpmi) {
          case 0:
            dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
            dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
            dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,0, 1);
            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,0, 1);
          break;
          case 1:
            dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
            dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
            dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1, 1);
            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,1, 1);
          break;
          case 2: // PUSCH precoding
            dlsch0_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
            dlsch1_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
            if (tbswap==0){
              dlsch0_harq->pmi_alloc   = pmi_alloc;
              dlsch1_harq->pmi_alloc   = pmi_alloc^0x1555;
            } else {
                dlsch1_harq->pmi_alloc   = pmi_alloc;
                dlsch0_harq->pmi_alloc   = pmi_alloc^0x1555;
            }
#ifdef DEBUG_HARQ
              printf ("\n \n compute_precoding_info_2cw pmi_alloc_new = %d\n", dlsch0_harq->pmi_alloc);
  #endif
          break;
          default:
          break;
        }
}

void compute_precoding_info_1cw(uint8_t tpmi, uint16_t pmi_alloc, LTE_DL_FRAME_PARMS *frame_parms, LTE_DL_UE_HARQ_t *dlsch_harq)
{

switch (tpmi) {
            case 0 :
              dlsch_harq->mimo_mode   = ALAMOUTI;
            break;
            case 1:
              dlsch_harq->mimo_mode   = UNIFORM_PRECODING11;
              dlsch_harq->pmi_alloc   = pmi_extend(frame_parms,0, 0);
            break;
            case 2:
              dlsch_harq->mimo_mode   = UNIFORM_PRECODING1m1;
              dlsch_harq->pmi_alloc   = pmi_extend(frame_parms,1, 0);
            break;
            case 3:
              dlsch_harq->mimo_mode   = UNIFORM_PRECODING1j;
              dlsch_harq->pmi_alloc   = pmi_extend(frame_parms,2, 0);
            break;
            case 4:
              dlsch_harq->mimo_mode   = UNIFORM_PRECODING1mj;
              dlsch_harq->pmi_alloc   = pmi_extend(frame_parms,3, 0);
            break;
            case 5:
              dlsch_harq->mimo_mode   = PUSCH_PRECODING0;
              dlsch_harq->pmi_alloc   = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0);
            break;
            case 6:
              dlsch_harq->mimo_mode   = PUSCH_PRECODING1;
              dlsch_harq->pmi_alloc   = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1);
            break;
            }
  #ifdef DEBUG_HARQ
              printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d with tpmi %d\n", dlsch_harq->pmi_alloc, tpmi);
  #endif
            }

void compute_precoding_info_format2A(uint8_t tpmi,
                                     uint8_t nb_antenna_ports_eNB,
                                     uint8_t tb0_active,
                                     uint8_t tb1_active,
                                     LTE_DL_UE_HARQ_t *dlsch0_harq,
                                     LTE_DL_UE_HARQ_t *dlsch1_harq)
{

    dlsch0_harq->dl_power_off = 0;
    dlsch1_harq->dl_power_off = 0;

    if (nb_antenna_ports_eNB == 2) {
        if ((tb0_active==1) && (tb1_active==1)) {
          dlsch0_harq->mimo_mode = LARGE_CDD;
          dlsch1_harq->mimo_mode = LARGE_CDD;
          dlsch0_harq->dl_power_off = 1;
          dlsch1_harq->dl_power_off = 1;
        } else {
          dlsch0_harq->mimo_mode   = ALAMOUTI;
          dlsch1_harq->mimo_mode   = ALAMOUTI;
        }
      } else if (nb_antenna_ports_eNB == 4) { // 4 antenna case
        if ((tb0_active==1) && (tb1_active==1)) {
          switch (tpmi) {
          case 0: // one layer per transport block
            dlsch0_harq->mimo_mode   = LARGE_CDD;
            dlsch1_harq->mimo_mode   = LARGE_CDD;
            dlsch0_harq->dl_power_off = 1;
            dlsch1_harq->dl_power_off = 1;
            break;

          case 1: // one-layers on TB 0, two on TB 1
            dlsch0_harq->mimo_mode   = LARGE_CDD;
            dlsch1_harq->mimo_mode   = LARGE_CDD;
            dlsch1_harq->Nl          = 2;
            dlsch0_harq->dl_power_off = 1;
            dlsch1_harq->dl_power_off = 1;
            break;

          case 2: // two-layers on TB 0, two on TB 1
            dlsch0_harq->mimo_mode   = LARGE_CDD;
            dlsch1_harq->mimo_mode   = LARGE_CDD;
            dlsch0_harq->Nl          = 2;
            dlsch0_harq->dl_power_off = 1;
            dlsch1_harq->dl_power_off = 1;
            break;

          case 3: //
            LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n");
            break;
          }
        } else if (tb0_active == 1) {
          switch (tpmi) {
          case 0: // one layer per transport block
            dlsch0_harq->mimo_mode   = ALAMOUTI;
            dlsch1_harq->mimo_mode   = ALAMOUTI;
            break;

          case 1: // two-layers on TB 0
            dlsch0_harq->mimo_mode   = LARGE_CDD;
            dlsch0_harq->Nl          = 2;
            dlsch0_harq->dl_power_off = 1;
            break;

          case 2: // two-layers on TB 0, two on TB 1
          case 3: //
            LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi);
            break;
          }
        } else if (tb1_active == 1) {
          switch (tpmi) {
          case 0: // one layer per transport block
            dlsch0_harq->mimo_mode   = ALAMOUTI;
            dlsch1_harq->mimo_mode   = ALAMOUTI;
            break;

          case 1: // two-layers on TB 0
            dlsch1_harq->mimo_mode   = LARGE_CDD;
            dlsch1_harq->Nl          = 2;
            dlsch0_harq->dl_power_off = 1;
            break;

          case 2: // two-layers on TB 0, two on TB 1
          case 3: //
            LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi);
            break;
          }
        }
      }
      //    printf("Format 2A: NPRB=%d (rballoc %x,mcs1 %d, mcs2 %d, frame_type %d N_RB_DL %d,active %d/%d)\n",NPRB,rballoc,mcs1,mcs2,frame_parms->frame_type,frame_parms->N_RB_DL,dlsch0->active,dlsch1->active);
      //printf("UE (%x/%d): Subframe %d Format2A DCI: ndi1 %d, old_ndi1 %d, ndi2 %d, old_ndi2 %d (first tx1 %d, first tx2 %d) harq_status1 %d, harq_status2 %d\n",dlsch0->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi,
      //    dlsch0_harq->first_tx,dlsch1_harq->first_tx,dlsch0_harq->status,dlsch1_harq->status);
      //printf("TBS0 %d, TBS1 %d\n",dlsch0_harq->TBS,dlsch1_harq->TBS);

}

void prepare_dl_decoding_format2_2A(DCI_format_t dci_format,
                                    DCI_INFO_EXTRACTED_t *pdci_info_extarcted,
                                    LTE_DL_FRAME_PARMS *frame_parms,
                                    LTE_UE_PDCCH *pdcch_vars,
                                    LTE_UE_PDSCH *pdsch_vars,
                                    uint16_t rnti,
                                    uint8_t subframe,
                                    LTE_DL_UE_HARQ_t *dlsch0_harq,
                                    LTE_DL_UE_HARQ_t *dlsch1_harq,
                                    LTE_UE_DLSCH_t *pdlsch0,
                                    LTE_UE_DLSCH_t *pdlsch1)
{

    uint8_t  rah  = pdci_info_extarcted->rah;
    uint8_t  mcs1 = pdci_info_extarcted->mcs1;
    uint8_t  mcs2 = pdci_info_extarcted->mcs2;
    uint8_t  rv1  = pdci_info_extarcted->rv1;
    uint8_t  rv2  = pdci_info_extarcted->rv2;
    uint8_t  harq_pid = pdci_info_extarcted->harq_pid;
    uint32_t rballoc  = pdci_info_extarcted->rballoc;
    uint8_t  tbswap   = pdci_info_extarcted->tb_swap;
    uint8_t  tpmi     = pdci_info_extarcted->tpmi;
    uint8_t  TPC      = pdci_info_extarcted->TPC;
    uint8_t  ndi1     = pdci_info_extarcted->ndi1;
    uint8_t  ndi2     = pdci_info_extarcted->ndi2;

    uint8_t TB0_active = 1;
    uint8_t TB1_active = 1;

   // printf("inside prepare pdlsch1->pmi_alloc %d \n",pdlsch1->pmi_alloc);


      if ((rv1 == 1) && (mcs1 == 0)) {
        TB0_active=0;
      }
      if ((rv2 == 1) && (mcs2 == 0)) {
        TB1_active=0;
      }

#ifdef DEBUG_HARQ
      printf("[DCI UE]: TB0 status %d , TB1 status %d\n", TB0_active, TB1_active);
#endif

        dlsch0_harq->mcs      = mcs1;
        dlsch1_harq->mcs      = mcs2;
        dlsch0_harq->rvidx    = rv1;
        dlsch1_harq->rvidx    = rv2;
        dlsch0_harq->DCINdi   = ndi1;
        dlsch1_harq->DCINdi   = ndi2;

        dlsch0_harq->codeword = 0;
        dlsch1_harq->codeword = 1;
        dlsch0_harq->Nl       = 1;
        dlsch1_harq->Nl       = 1;
        dlsch0_harq->delta_PUCCH  = delta_PUCCH_lut[TPC&3];
        dlsch1_harq->delta_PUCCH  = delta_PUCCH_lut[TPC&3];
        dlsch0_harq->dl_power_off = 1;
        dlsch1_harq->dl_power_off = 1;

        pdlsch0->current_harq_pid = harq_pid;
        pdlsch0->harq_ack[subframe].harq_id     = harq_pid;
        pdlsch1->current_harq_pid = harq_pid;
        pdlsch1->harq_ack[subframe].harq_id     = harq_pid;

        // assume two CW are active
        dlsch0_harq->status   = ACTIVE;
        dlsch1_harq->status   = ACTIVE;
        pdlsch0->active = 1;
        pdlsch1->active = 1;
        pdlsch0->rnti = rnti;
        pdlsch1->rnti = rnti;


      if (TB0_active && TB1_active && tbswap==1) {
        dlsch0_harq->codeword = 1;
        dlsch1_harq->codeword = 0;
      }


      if (!TB0_active && TB1_active){
        dlsch1_harq->codeword = 0;
      }

      if (TB0_active && !TB1_active){
        dlsch0_harq->codeword = 0;
      }


      if (TB0_active==0) {
        dlsch0_harq->status = SCH_IDLE;
        pdlsch0->active     = 0;
  #ifdef DEBUG_HARQ
        printf("[DCI UE]: TB0 is deactivated, retransmit TB1 transmit in TM6\n");
  #endif
      }

      if (TB1_active==0) {
        dlsch1_harq->status = SCH_IDLE;
        pdlsch1->active     = 0;
      }

#ifdef DEBUG_HARQ
      printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
#endif

      // compute resource allocation
      if (TB0_active == 1){

        dlsch0_harq->nb_rb = conv_nprb(rah,
                                       rballoc,
                                       frame_parms->N_RB_DL);
        conv_rballoc(rah,
                     rballoc,
                     frame_parms->N_RB_DL,
                     dlsch0_harq->rb_alloc_even);

        dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0];
        dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1];
        dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2];
        dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3];

        if (TB1_active == 1){
          dlsch1_harq->rb_alloc_even[0]= dlsch0_harq->rb_alloc_even[0];
          dlsch1_harq->rb_alloc_even[1]= dlsch0_harq->rb_alloc_even[1];
          dlsch1_harq->rb_alloc_even[2]= dlsch0_harq->rb_alloc_even[2];
          dlsch1_harq->rb_alloc_even[3]= dlsch0_harq->rb_alloc_even[3];
          dlsch1_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_odd[0];
          dlsch1_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_odd[1];
          dlsch1_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_odd[2];
          dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3];

          dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;

          //dlsch0_harq->Nl       = 1;
          //dlsch1_harq->Nl       = 1;
        }
      } else if ((TB0_active == 0) && (TB1_active == 1)){

          conv_rballoc(rah,
                       rballoc,
                       frame_parms->N_RB_DL,
                       dlsch1_harq->rb_alloc_even);

          dlsch1_harq->rb_alloc_odd[0]= dlsch1_harq->rb_alloc_even[0];
          dlsch1_harq->rb_alloc_odd[1]= dlsch1_harq->rb_alloc_even[1];
          dlsch1_harq->rb_alloc_odd[2]= dlsch1_harq->rb_alloc_even[2];
          dlsch1_harq->rb_alloc_odd[3]= dlsch1_harq->rb_alloc_even[3];
          dlsch1_harq->nb_rb = conv_nprb(rah,
                                         rballoc,
                                         frame_parms->N_RB_DL);
        }


      // compute precoding matrix + mimo mode
      if(dci_format == format2)
      {
      if ((TB0_active) && (TB1_active)){  //two CW active
        compute_precoding_info_2cw(tpmi, tbswap, pdlsch0->pmi_alloc,frame_parms, dlsch0_harq, dlsch1_harq);

   //   printf("[DCI UE 1]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
      } else if ((TB0_active) && (!TB1_active))  { // only CW 0 active
        compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch0_harq);
      } else {
        compute_precoding_info_1cw(tpmi, pdlsch1->pmi_alloc, frame_parms, dlsch1_harq);
       // printf("I am doing compute_precoding_info_1cw with tpmi %d \n", tpmi);
      }
      //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode);
      if ((frame_parms->nb_antenna_ports_eNB == 1) && (TB0_active))
        dlsch0_harq->mimo_mode   = SISO;
      }
      else
      {
        compute_precoding_info_format2A( tpmi,
                                      frame_parms->nb_antenna_ports_eNB,
                                      TB0_active,
                                      TB1_active,
                                      dlsch0_harq,
                                      dlsch1_harq);
      }
  //    printf("[DCI UE 2]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
      // reset round + compute Qm
      if (TB0_active) {
       // printf("TB0 ndi1 =%d, dlsch0_harq->DCINdi =%d, dlsch0_harq->first_tx = %d\n", ndi1, dlsch0_harq->DCINdi, dlsch0_harq->first_tx);
        if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1))  {
          dlsch0_harq->round = 0;
           dlsch0_harq->status = ACTIVE;
           dlsch0_harq->DCINdi = ndi1;

          //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW0 subframe %d (pid %d, round %d)\n",
          //           subframe,harq_pid,dlsch0_harq->round);
          if ( dlsch0_harq->first_tx==1) {
            LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n");
            dlsch0_harq->first_tx = 0;
          }
        }
	/*else if (rv1  != 0 )
	  //NDI has not been toggled but rv was increased by eNB: retransmission
	  {
	    if(dlsch0_harq->status == SCH_IDLE) {
            // skip pdsch decoding and report ack
	      //dlsch0_harq->status   = SCH_IDLE;
            pdlsch0->active       = 0;
            pdlsch0->harq_ack[subframe].ack = 1;
            pdlsch0->harq_ack[subframe].harq_id = harq_pid;
            pdlsch0->harq_ack[subframe].send_harq_status = 1;
	    }*/

        // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
        // PDCCH for the same trasport block using Imcs in [0 .. 28]
        if(dlsch0_harq->mcs <= 28)
        {
            dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
            LOG_D(PHY,"[UE] DLSCH: New TBS CW0 subframe %d (pid %d, round %d) TBS %d \n",
                       subframe,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS);
        }
        else
        {
            LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW0 subframe %d (pid %d, round %d) TBS %d \n",
                       subframe,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS);
        }
        //if(dlsch0_harq->Nl == 2)
        //dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1];
        if (mcs1 <= 28)
            dlsch0_harq->Qm = get_Qm(mcs1);
        else if (mcs1<=31)
            dlsch0_harq->Qm = (mcs1-28)<<1;
      }

   //   printf("[DCI UE 3]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);

      if (TB1_active) {
       // printf("TB1 ndi2 =%d, dlsch1_harq->DCINdi =%d, dlsch1_harq->first_tx = %d\n", ndi2, dlsch1_harq->DCINdi, dlsch1_harq->first_tx);
        if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) {
          dlsch1_harq->round = 0;
          dlsch1_harq->status = ACTIVE;
          dlsch1_harq->DCINdi = ndi2;
          //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW1 subframe %d (pid %d, round %d)\n",
          //           subframe,harq_pid,dlsch0_harq->round);
          if (dlsch1_harq->first_tx==1) {
            LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n");
            dlsch1_harq->first_tx = 0;
          }
        }
	/*else if (rv1  != 0 )
	//NDI has not been toggled but rv was increased by eNB: retransmission
	  {
	    if(dlsch1_harq->status == SCH_IDLE) {
            // skip pdsch decoding and report ack
	      //dlsch1_harq->status   = SCH_IDLE;
            pdlsch1->active       = 0;
            pdlsch1->harq_ack[subframe].ack = 1;
            pdlsch1->harq_ack[subframe].harq_id = harq_pid;
            pdlsch1->harq_ack[subframe].send_harq_status = 1;
         }
	  }*/

        // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest
        // PDCCH for the same trasport block using Imcs in [0 .. 28]
        if(dlsch1_harq->mcs <= 28)
        {
            dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
            LOG_D(PHY,"[UE] DLSCH: New TBS CW1 subframe %d (pid %d, round %d) TBS %d \n",
                       subframe,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS);
        }
        else
        {
            LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW1 subframe %d (pid %d, round %d) TBS %d \n",
                       subframe,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS);
        }
        if (mcs2 <= 28)
            dlsch1_harq->Qm = get_Qm(mcs2);
        else if (mcs1<=31)
            dlsch1_harq->Qm = (mcs2-28)<<1;
      }


      compute_llr_offset(frame_parms,
                         pdcch_vars,
                         pdsch_vars,
                         dlsch0_harq,
                         dlsch0_harq->nb_rb,
                         subframe);


 /* #ifdef DEBUG_HARQ
      printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status);
      printf("[DCI UE]: TB0_active %d , TB1_active %d\n", TB0_active, TB1_active);
      if (dlsch0 != NULL && dlsch1 != NULL)
        printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status);
      else if (dlsch0 == NULL && dlsch1 != NULL)
        printf("[DCI UE] dlsch0_harq NULL dlsch1_harq status = %d\n", dlsch1_harq->status);
      else if (dlsch0 != NULL && dlsch1 == NULL)
        printf("[DCI UE] dlsch1_harq NULL dlsch0_harq status = %d\n", dlsch0_harq->status);
  #endif*/
}

int generate_ue_dlsch_params_from_dci(int frame,
                                      uint8_t subframe,
                                      void *dci_pdu,
                                      uint16_t rnti,
                                      DCI_format_t dci_format,
                                      LTE_UE_PDCCH *pdcch_vars,
                                      LTE_UE_PDSCH *pdsch_vars,
                                      LTE_UE_DLSCH_t **dlsch,
                                      LTE_DL_FRAME_PARMS *frame_parms,
                                      PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated,
                                      uint16_t si_rnti,
                                      uint16_t ra_rnti,
                                      uint16_t p_rnti,
                                      uint8_t beamforming_mode,
                                      uint16_t tc_rnti)
{

    uint8_t harq_pid=0;
    uint8_t frame_type=frame_parms->frame_type;
    uint8_t tpmi=0;
    LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
    LTE_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;

    DCI_INFO_EXTRACTED_t dci_info_extarcted;
    uint8_t status=0;

    if (!dlsch[0]) return -1;

  #ifdef DEBUG_DCI
    LOG_D(PHY,"dci_tools.c: Filling ue dlsch params -> rnti %x, SFN/SF %d/%d, dci_format %s\n",
        rnti,
        frame%1024,
        subframe,
        (dci_format==format0?  "Format 0":(
         dci_format==format1?  "format 1":(
         dci_format==format1A? "format 1A":(
         dci_format==format1B? "format 1B":(
         dci_format==format1C? "format 1C":(
         dci_format==format1D? "format 1D":(
         dci_format==format1E_2A_M10PRB? "format 1E_2A_M10PRB":(
         dci_format==format2?  "format 2":(
         dci_format==format2A? "format 2A":(
         dci_format==format2B? "format 2B":(
         dci_format==format2C? "format 2C":(
         dci_format==format2D? "format 2D":(
         dci_format==format3?  "format 3": "UNKNOWN"
         ))))))))))))));
  #endif

    memset(&dci_info_extarcted,0,sizeof(dci_info_extarcted));
    switch (dci_format) {

    case format0:   // This is an ULSCH allocation so nothing here, inform MAC
      LOG_E(PHY,"format0 not possible\n");
      return(-1);
      break;

    case format1A:
    {
      // extract dci infomation
#ifdef DEBUG_DCI
      LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d extarct dci info \n", frame, subframe);
#endif
      extract_dci1A_info(frame_parms->N_RB_DL,
                         frame_type,
                         dci_pdu,
                         &dci_info_extarcted);


      // check dci content
      dlsch0 = dlsch[0];
      dlsch0->active = 0;
      dlsch0_harq   = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid];
#ifdef DEBUG_DCI
      LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d check dci coherency \n", frame, subframe);
#endif
      status = check_dci_format1_1a_coherency(format1A,
                                              frame_parms->N_RB_DL,
                                              rnti,
                                              tc_rnti,
                                              si_rnti,
                                              ra_rnti,
                                              p_rnti,frame,subframe,
                                              &dci_info_extarcted,
                                              dlsch0_harq);
      if(status == 0)
      {
        printf("bad DCI 1A !!! \n");
        return(-1);
      }

      // dci is correct ==> update internal structure and prepare dl decoding
#ifdef DEBUG_DCI
      LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d prepare dl decoding \n", frame, subframe);
#endif
      prepare_dl_decoding_format1_1A(format1A,
                                     frame_parms->N_RB_DL,
                                     &dci_info_extarcted,
                                     frame_parms,
                                     pdcch_vars,
                                     pdsch_vars,
                                     subframe,
                                     rnti,
									 tc_rnti,
                                     si_rnti,
                                     ra_rnti,
                                     p_rnti,
                                     dlsch0_harq,
                                     dlsch0);



      break;
    }
    case format1C:
    {
      // extract dci infomation
#ifdef DEBUG_DL_DECODING
      LOG_I(PHY,"[DCI Format-1C] extact dci information \n");
#endif
      extract_dci1C_info(frame_parms->N_RB_DL,
                         frame_type,
                         dci_pdu,
                         &dci_info_extarcted);


      // check dci content
#ifdef DEBUG_DL_DECODING
      LOG_I(PHY,"[DCI Format-1C] check dci content \n");
#endif
      dlsch0 = dlsch[0];
      dlsch0->active = 0;
      dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid];

      status = check_dci_format1c_coherency(frame_parms->N_RB_DL,
                                            &dci_info_extarcted,
                                            rnti,
                                            si_rnti,
                                            ra_rnti,
                                            p_rnti,
                                            dlsch0_harq);
      if(status == 0)
        return(-1);

      // dci is correct ==> update internal structure and prepare dl decoding
#ifdef DEBUG_DL_DECODING
      LOG_I(PHY,"[DCI Format-1C] prepare downlink decoding \n");
#endif
      prepare_dl_decoding_format1C(frame_parms->N_RB_DL,
                                   &dci_info_extarcted,
                                   frame_parms,
                                   pdcch_vars,
                                   pdsch_vars,
                                   rnti,
                                   si_rnti,
                                   ra_rnti,
                                   p_rnti,
                                   frame,
                                   subframe,
                                   dlsch0_harq,
                                   dlsch0);

      break;
    }

    case format1:
    {
      // extract dci infomation
#ifdef DEBUG_DCI
      LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d extarct dci info \n", frame, subframe);
#endif
      extract_dci1_info(frame_parms->N_RB_DL,
                         frame_type,
                         dci_pdu,
                         &dci_info_extarcted);

      // check dci content
      dlsch0 = dlsch[0];
      dlsch0->active = 0;
      dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid];

#ifdef DEBUG_DCI
      LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d check dci coherency \n", frame, subframe);
#endif
      status = check_dci_format1_1a_coherency(format1,
                                              frame_parms->N_RB_DL,
                                              rnti,
                                              tc_rnti,
                                              si_rnti,
                                              ra_rnti,
                                              p_rnti,frame,subframe,
                                              &dci_info_extarcted,
                                              dlsch0_harq);
      if(status == 0)
      {
          printf("bad DCI 1 !!! \n");
          return(-1);
      }


      // dci is correct ==> update internal structure and prepare dl decoding
#ifdef DEBUG_DCI
      LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d prepare dl decoding \n", frame, subframe);
#endif
      prepare_dl_decoding_format1_1A(format1,
                                     frame_parms->N_RB_DL,
                                     &dci_info_extarcted,
                                     frame_parms,
                                     pdcch_vars,
                                     pdsch_vars,
                                     subframe,
                                     rnti,
									 tc_rnti,
                                     si_rnti,
                                     ra_rnti,
                                     p_rnti,
                                     dlsch0_harq,
                                     dlsch0);
      break;
    }

    case format2:
    {
        // extract dci infomation
        //LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame, subframe);
        extract_dci2_info(frame_parms->N_RB_DL,
                frame_type,
                frame_parms->nb_antenna_ports_eNB,
                dci_pdu,
                &dci_info_extarcted);


        // check dci content
        dlsch[0]->active = 1;
        dlsch[1]->active = 1;

            dlsch0 = dlsch[0];
            dlsch1 = dlsch[1];

    dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid];
    dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid];
   // printf("before coherency dlsch[1]->pmi_alloc %d\n",dlsch[1]->pmi_alloc);
   // printf("before coherency dlsch1->pmi_alloc %d\n",dlsch1->pmi_alloc);
   // printf("before coherency dlsch1_harq->pmi_alloc %d\n",dlsch1_harq->pmi_alloc);

        //LOG_I(PHY,"[DCI-format2] check dci content \n");
        status = check_dci_format2_2a_coherency(format2,
                frame_parms->N_RB_DL,
                &dci_info_extarcted,
                rnti,
                si_rnti,
                ra_rnti,
                p_rnti,
                dlsch0_harq,
                dlsch1_harq);
        if(status == 0)
            return(-1);


        // dci is correct ==> update internal structure and prepare dl decoding
        //LOG_I(PHY,"[DCI-format2] update internal structure and prepare dl decoding \n");
        prepare_dl_decoding_format2_2A(format2,
                &dci_info_extarcted,
                frame_parms,
                pdcch_vars,
                pdsch_vars,
                rnti,
                subframe,
                dlsch0_harq,
                dlsch1_harq,
                dlsch0,
                dlsch1);
    }
    break;

    case format2A:
    {
    // extract dci infomation
    LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame%1024, subframe);
    extract_dci2A_info(frame_parms->N_RB_DL,
                       frame_type,
                       frame_parms->nb_antenna_ports_eNB,
                       dci_pdu,
                       &dci_info_extarcted);

    // check dci content
    //LOG_I(PHY,"[DCI-format2A] check dci content \n");
    //LOG_I(PHY,"[DCI-format2A] tb_swap %d harq_pid %d\n", dci_info_extarcted.tb_swap, dci_info_extarcted.harq_pid);
      //dlsch[0]->active = 0;
      //dlsch[1]->active = 0;

    if (dci_info_extarcted.tb_swap == 0) {
      dlsch0 = dlsch[0];
      dlsch1 = dlsch[1];
    } else {
      dlsch0 = dlsch[1];
      dlsch1 = dlsch[0];
    }
    dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid];
    dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid];

    //LOG_I(PHY,"[DCI-format2A] check dci content \n");
    status = check_dci_format2_2a_coherency(format2A,
                                              frame_parms->N_RB_DL,
                                              &dci_info_extarcted,
                                              rnti,
                                              si_rnti,
                                              ra_rnti,
                                              p_rnti,
                                              dlsch0_harq,
                                              dlsch1_harq);
    if(status == 0)
      return(-1);

    // dci is correct ==> update internal structure and prepare dl decoding
    //LOG_I(PHY,"[DCI-format2A] update internal structure and prepare dl decoding \n");
    prepare_dl_decoding_format2_2A(format2A,
                                   &dci_info_extarcted,
                                   frame_parms,
                                   pdcch_vars,
                                   pdsch_vars,
                                   rnti,
                                   subframe,
                                   dlsch0_harq,
                                   dlsch1_harq,
                                   dlsch0,
                                   dlsch1);
    }
      break;

    case format1E_2A_M10PRB:
      if (!dlsch[0]) return -1;

      harq_pid  = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid;

      if (harq_pid>=8) {
        LOG_E(PHY,"Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid);
        return(-1);
      }

      dlsch[0]->current_harq_pid = harq_pid;
      dlsch[0]->harq_ack[subframe].harq_id = harq_pid;

      /*
        tbswap = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tb_swap;
        if (tbswap == 0) {
        dlsch0 = dlsch[0];
        dlsch1 = dlsch[1];
        }
        else{
        dlsch0 = dlsch[1];
        dlsch1 = dlsch[0];
        }
      */
      dlsch0 = dlsch[0];

      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
      // Needs to be checked
      dlsch0_harq->codeword=0;
      conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah,
                   ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,frame_parms->N_RB_DL,
                   dlsch0_harq->rb_alloc_even);

      dlsch0_harq->rb_alloc_odd[0]                         = dlsch0_harq->rb_alloc_even[0];
      dlsch0_harq->rb_alloc_odd[1]                         = dlsch0_harq->rb_alloc_even[1];
      dlsch0_harq->rb_alloc_odd[2]                         = dlsch0_harq->rb_alloc_even[2];
      dlsch0_harq->rb_alloc_odd[3]                         = dlsch0_harq->rb_alloc_even[3];
      /*
      dlsch1_harq->rb_alloc_even[0]                         = dlsch0_harq->rb_alloc_even[0];
      dlsch1_harq->rb_alloc_even[1]                         = dlsch0_harq->rb_alloc_even[1];
      dlsch1_harq->rb_alloc_even[2]                         = dlsch0_harq->rb_alloc_even[2];
      dlsch1_harq->rb_alloc_even[3]                         = dlsch0_harq->rb_alloc_even[3];
      */
      dlsch0_harq->nb_rb                               = conv_nprb(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah,
								   ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,
								   frame_parms->N_RB_DL);
      //dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;

      dlsch0_harq->mcs             = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;
      dlsch0_harq->delta_PUCCH     = delta_PUCCH_lut[((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->TPC&3];



      /*
        if (dlsch0_harq->mcs>20) {
        printf("dci_tools.c: mcs > 20 disabled for now (asked %d)\n",dlsch0_harq->mcs);
        return(-1);
        }
      */

      //dlsch1_harq->mcs       = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs2;
      dlsch0_harq->rvidx     = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv;
      //dlsch1_harq->rvidx     = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv2;

      // check if either TB is disabled (see 36-213 V8.6 p. 26)

      if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
        dlsch0_harq->status = DISABLED;
      }

      //if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
      //dlsch1_harq->status = DISABLED;
      //}
      dlsch0_harq->Nl        = 1;

      //dlsch0->layer_index                         = tbswap;
      //dlsch1->layer_index                         = 1-tbswap;


      // Fix this
      tpmi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tpmi;
      //    printf("ue: tpmi %d\n",tpmi);

      switch (tpmi) {
      case 0 :
        dlsch0_harq->mimo_mode   = ALAMOUTI;
        break;

      case 1:
        dlsch0_harq->mimo_mode   = UNIFORM_PRECODING11;
        dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,0,0);
        break;

      case 2:
        dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
        dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1, 0);
        break;

      case 3:
        dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
        dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,2, 0);

        break;

      case 4:
        dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
        dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,3, 0);
        break;

      case 5:
        dlsch0_harq->mimo_mode   = PUSCH_PRECODING0;
        // pmi stored from ulsch allocation routine
        dlsch0_harq->pmi_alloc   = dlsch0->pmi_alloc;
        //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc));
        break;


      case 6:
        dlsch0_harq->mimo_mode   = PUSCH_PRECODING1;
        LOG_E(PHY,"Unsupported TPMI\n");
        return(-1);
        break;
      }


      if (frame_parms->nb_antenna_ports_eNB == 1)
        dlsch0_harq->mimo_mode   = SISO;


      if ((dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) ||
	(dlsch0_harq->first_tx==1)) {

        dlsch0_harq->round = 0;
	dlsch0_harq->first_tx = 0;
        dlsch0_harq->status = ACTIVE;
      }
      /*
	else if (dlsch0_harq->status == SCH_IDLE) { // we got same ndi for a previously decoded process,
        // this happens if either another harq process in the same
        // is NAK or an ACK was not received

        dlsch0->harq_ack[subframe].ack              = 1;
        dlsch0->harq_ack[subframe].harq_id          = harq_pid;
        dlsch0->harq_ack[subframe].send_harq_status = 1;
        dlsch0->active = 0;
        return(0);
      }
      */

      dlsch0_harq->DCINdi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi;
      dlsch0_harq->mcs    = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;

      if (dlsch0_harq->nb_rb>1) {
        dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
      } else
        dlsch0_harq->TBS         =0;

      dlsch0->rnti = rnti;
      //dlsch1->rnti = rnti;

      dlsch0->active = 1;
      //dlsch1->active = 1;

      dlsch0_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off;
      //dlsch1_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off;


      break;

    default:
      LOG_E(PHY,"format %d not yet implemented\n",dci_format);
      return(-1);
      break;
    }

#ifdef UE_DEBUG_TRACE

    if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) {
        LOG_I(PHY,"dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,subframe);
        LOG_I(PHY,"PDSCH dlsch0 UE: rnti     %x\n",dlsch[0]->rnti);
        LOG_D(PHY,"PDSCH dlsch0 UE: NBRB     %d\n",dlsch0_harq->nb_rb);
        LOG_D(PHY,"PDSCH dlsch0 UE: rballoc  %x\n",dlsch0_harq->rb_alloc_even[0]);
        LOG_I(PHY,"PDSCH dlsch0 UE: harq_pid %d\n",dci_info_extarcted.harq_pid);
        LOG_I(PHY,"PDSCH dlsch0 UE: g        %d\n",dlsch[0]->g_pucch);
        LOG_D(PHY,"PDSCH dlsch0 UE: round    %d\n",dlsch0_harq->round);
        LOG_D(PHY,"PDSCH dlsch0 UE: DCINdi   %d\n",dlsch0_harq->DCINdi);
        LOG_D(PHY,"PDSCH dlsch0 UE: rvidx    %d\n",dlsch0_harq->rvidx);
        LOG_D(PHY,"PDSCH dlsch0 UE: TBS      %d\n",dlsch0_harq->TBS);
        LOG_D(PHY,"PDSCH dlsch0 UE: mcs      %d\n",dlsch0_harq->mcs);
        LOG_D(PHY,"PDSCH dlsch0 UE: pwr_off  %d\n",dlsch0_harq->dl_power_off);
    }
#endif

#if T_TRACER
    if( (dlsch[0]->rnti != si_rnti) && (dlsch[0]->rnti != ra_rnti) && (dlsch[0]->rnti != p_rnti))
    {
      T(T_UE_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame%1024), T_INT(subframe),
        T_INT(dlsch[0]->rnti), T_INT(dci_format),
        T_INT(harq_pid),
        T_INT(dlsch0_harq->mcs),
        T_INT(dlsch0_harq->TBS));
    }
#endif


    // compute DL power control parameters
    if (dlsch0_harq != NULL){
      computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB);
      computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off);
    }

    if (dlsch1_harq != NULL) {
      computeRhoA_UE(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB);
      computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[1],dlsch1_harq->dl_power_off);
    }


    return(0);
}


uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe)
{
  uint8_t ret = 255;

  if (frame_parms->frame_type == FDD) {
    ret = (((frame<<1)+subframe)&7);
  } else {

    switch (frame_parms->tdd_config) {

    case 1:
      if ((subframe==2) ||
          (subframe==3) ||
          (subframe==7) ||
          (subframe==8))
        switch (subframe) {
        case 2:
        case 3:
          ret = (subframe-2);
          break;

        case 7:
        case 8:
          ret = (subframe-5);
          break;

        default:
          LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
          ret = (255);
          break;
        }

      break;

    case 2:
      if ((subframe!=2) && (subframe!=7)) {
	LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
	ret=255;
      }
      else ret = (subframe/7);
      break;

    case 3:
      if ((subframe<2) || (subframe>4)) {
        LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
        ret = (255);
      }
      else ret = (subframe-2);
      break;

    case 4:
      if ((subframe<2) || (subframe>3)) {
        LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
        ret = (255);
      }
      else ret = (subframe-2);
      break;

    case 5:
      if (subframe!=2) {
        LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
        ret = (255);
      }
      else ret = (subframe-2);
      break;

    default:
      LOG_E(PHY,"subframe2_harq_pid, Unsupported TDD mode %d\n",frame_parms->tdd_config);
      ret = (255);
    }
  }

  AssertFatal(ret!=255,
	      "invalid harq_pid(%d) at SFN/SF = %d/%d\n", (int8_t)ret, frame, subframe);
  return ret;
}

uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n)
{
  uint8_t ul_subframe = 255;

  if ((frame_parms->frame_type == TDD) &&
      (frame_parms->tdd_config == 1) &&
      ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5
    ul_subframe = ((n+6)%10);
  else if ((frame_parms->frame_type == TDD) &&
           (frame_parms->tdd_config == 6) &&
           ((n==0)||(n==1)||(n==5)||(n==6)))
    ul_subframe = ((n+7)%10);
  else if ((frame_parms->frame_type == TDD) &&
           (frame_parms->tdd_config == 6) &&
           (n==9)) // tdd_config 6 SF 9
    ul_subframe = ((n+5)%10);
  else
    ul_subframe = ((n+4)%10);

  LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe);
  return ul_subframe;
}

uint8_t ul_subframe2pdcch_alloc_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n)
{
  if ((frame_parms->frame_type == TDD) &&
      (frame_parms->tdd_config == 1) &&
      ((n==7)||(n==2))) // tdd_config 0,1 SF 1,5
    return((n==7)? 1 : 6);
  else if ((frame_parms->frame_type == TDD) &&
           (frame_parms->tdd_config == 6) &&
           ((n==7)||(n==8)||(n==2)||(n==3)))
    return((n+3)%10);
  else if ((frame_parms->frame_type == TDD) &&
           (frame_parms->tdd_config == 6) &&
           (n==4)) // tdd_config 6 SF 9
    return(9);
  else
    return((n+6)%10);
}

uint32_t pdcch_alloc2ul_frame(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n)
{
  uint32_t ul_frame;

  if ((frame_parms->frame_type == TDD) &&
      (frame_parms->tdd_config == 1) &&
      ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5
    ul_frame = (frame + (n==1 ? 0 : 1));
  else if ((frame_parms->frame_type == TDD) &&
           (frame_parms->tdd_config == 6) &&
           ((n==0)||(n==1)||(n==5)||(n==6)))
    ul_frame = (frame + (n>=5 ? 1 : 0));
  else if ((frame_parms->frame_type == TDD) &&
           (frame_parms->tdd_config == 6) &&
           (n==9)) // tdd_config 6 SF 9
    ul_frame = (frame+1);
  else
    ul_frame = (frame+(n>=6 ? 1 : 0));

  LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, ul_frame);
  return ul_frame % 1024;
}

int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb)
{
  int nb_subbands = 0;
  int32_t pmi_alloc_new = 0, pmi_new = 0, pmi_old = 0;
  int i;

  switch (nb_rb) {
    case 6:
      nb_subbands = 6;
      break;
    default:
    case 25:
      nb_subbands = 7;
      break;
    case 50:
      nb_subbands = 9;
      break;
    case 100:
      nb_subbands = 13;
      break;
    }

  for (i = 0; i < nb_subbands; i++) {
    pmi_old = (pmi_alloc >> i)&1;

    if (pmi_old == 0)
      if (tpmi == 5)
        pmi_new = 0;
      else
        pmi_new = 1;
    else
      if (tpmi == 5)
        pmi_new = 2;
      else
        pmi_new = 3;

    pmi_alloc_new|=pmi_new<<(2*i);

  }
#ifdef DEBUG_HARQ
printf("  [DCI UE] pmi_alloc_old %d, pmi_alloc_new %d pmi_old %d , pmi_new %d\n", pmi_alloc, pmi_alloc_new,pmi_old, pmi_new );
#endif
return(pmi_alloc_new);

}

uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb)
{

  int i, aarx;
  uint16_t pmiq=0;
  uint32_t pmivect = 0;
  uint8_t rank = meas->rank[eNB_id];
  int pmi_re,pmi_im;
  int  nb_subbands=0;


  switch (nb_rb) {
    case 6:
      nb_subbands = 6;
      break;
    default:
    case 25:
      nb_subbands = 7;
      break;
    case 50:
      nb_subbands = 9;
      break;
    case 100:
      nb_subbands = 13;
      break;
    }


  for (i=0; i<nb_subbands; i++) {
    pmi_re = 0;
    pmi_im = 0;

    if (rank == 0) {
      for (aarx=0; aarx<meas->nb_antennas_rx; aarx++) {
        pmi_re += meas->subband_pmi_re[eNB_id][i][aarx];
        pmi_im += meas->subband_pmi_im[eNB_id][i][aarx];
      }

      //  pmi_re = meas->subband_pmi_re[eNB_id][i][meas->selected_rx_antennas[eNB_id][i]];
      //  pmi_im = meas->subband_pmi_im[eNB_id][i][meas->selected_rx_antennas[eNB_id][i]];

      //      printf("pmi => (%d,%d)\n",pmi_re,pmi_im);
      if ((pmi_re > pmi_im) && (pmi_re > -pmi_im))
        pmiq = PMI_2A_11;
      else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im))
        pmiq = PMI_2A_1j;
      else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im))
        pmiq = PMI_2A_1m1;
      else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im))
        pmiq = PMI_2A_1mj;

      //      printf("subband %d, pmi%d \n",i,pmiq);
      pmivect |= (pmiq<<(2*i));
    }

    else if (rank==1) {
      for (aarx=0; aarx<meas->nb_antennas_rx; aarx++) {
        pmi_re += meas->subband_pmi_re[eNB_id][i][aarx];
  //printf("meas->subband_pmi_re[eNB_id][i][%d]=%d\n", aarx, meas->subband_pmi_re[eNB_id][i][aarx]);
        pmi_im += meas->subband_pmi_im[eNB_id][i][aarx];
  //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]);
      }
     if (pmi_re >= pmi_im) // this is not orthogonal
     // this is orthogonal
     //if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re <= pmi_im) && (pmi_re >= -pmi_im)))
       pmiq = PMI_2A_R1_11;
     else
       pmiq = PMI_2A_R1_1j;

     // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq);
     // printf("subband %d, pmi%d \n",i,pmiq);
      //According to Section 7.2.4 of 36.213

      pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit
    }
    else {
      LOG_E(PHY,"PMI feedback for rank>1 not supported!\n");
      pmivect = 0;
    }

  }
#ifdef DEBUG_HARQ
    printf( "quantize_subband_pmi pmivect %d \n", pmivect);
#endif
  return(pmivect);
}

uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands)
{

  uint8_t i;
  uint16_t pmiq=0;
  uint16_t pmivect = 0;
  uint8_t rank = meas->rank[eNB_id];
  int pmi_re,pmi_im;

  for (i=0; i<nb_subbands; i++) {

    if (rank == 0) {
      pmi_re = meas->subband_pmi_re[eNB_id][i][a_id];
      pmi_im = meas->subband_pmi_im[eNB_id][i][a_id];

      if ((pmi_re > pmi_im) && (pmi_re > -pmi_im))
        pmiq = PMI_2A_11;
      else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im))
        pmiq = PMI_2A_1j;
      else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im))
        pmiq = PMI_2A_1m1;
      else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im))
        pmiq = PMI_2A_1mj;

      pmivect |= (pmiq<<(2*i));
    } else {
      // This needs to be done properly!!!
      pmivect = 0;
    }
  }

  return(pmivect);
}

uint16_t quantize_wideband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id)
{

  uint16_t pmiq=0;
  uint8_t rank = meas->rank[eNB_id];
  //int pmi;
  int pmi_re,pmi_im;

  if (rank == 1) {
    //pmi =
    pmi_re = meas->wideband_pmi_re[eNB_id][meas->selected_rx_antennas[eNB_id][0]];
    pmi_im = meas->wideband_pmi_im[eNB_id][meas->selected_rx_antennas[eNB_id][0]];

    if ((pmi_re > pmi_im) && (pmi_re > -pmi_im))
      pmiq = PMI_2A_11;
    else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im))
      pmiq = PMI_2A_1j;
    else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im))
      pmiq = PMI_2A_1m1;
    else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im))
      pmiq = PMI_2A_1mj;

  } else {
    // This needs to be done properly!
    pmiq = PMI_2A_11;
  }


  return(pmiq);
}
/*
  uint8_t sinr2cqi(int sinr) {
  if (sinr<-3)
  return(0);
  if (sinr>14)
  return(10);
  else
  return(3+(sinr>>1));
  }
*/

uint8_t sinr2cqi(double sinr,uint8_t trans_mode)
{
  // int flag_LA=0;

  uint8_t retValue = 0;

  if(flag_LA==0) {
    // Ideal Channel Estimation
    if (sinr<=-4.89)
      retValue = (0);
    else if (sinr < -3.53)
      retValue = (3);
    else if (sinr <= -1.93)
      retValue = (4);
    else if (sinr <= -0.43)
      retValue = (5);
    else if (sinr <= 1.11)
      retValue = (6);
    else if (sinr <= 3.26)
      retValue = (7);
    else if (sinr <= 5.0)
      retValue = (8);
    else if (sinr <= 7.0)
      retValue = (9);
    else if (sinr <= 9.0)
      retValue = (10);
    else if (sinr <= 11.0)
      retValue = (11);
    else if (sinr <= 13.0)
      retValue = (12);
    else if (sinr <= 15.5)
      retValue = (13);
    else if (sinr <= 17.5)
      retValue = (14);
    else
      retValue = (15);
  } else {
    int h=0;
    int trans_mode_tmp;

    if (trans_mode ==5)
      trans_mode_tmp=2;
    else if(trans_mode ==6)
      trans_mode_tmp=3;
    else
      trans_mode_tmp = trans_mode-1;

    for(h=0; h<16; h++) {
      if(sinr<=sinr_to_cqi[trans_mode_tmp][h])
        retValue = (h);
    }
  }

  LOG_D(PHY, "sinr=%f trans_mode=%d cqi=%d\n", sinr, trans_mode, retValue);
  return retValue;
}
//uint32_t fill_subband_cqi(PHY_MEASUREMENTS *meas,uint8_t eNB_id) {
//
//  uint8_t i;
////  uint16_t cqivect = 0;
//  uint32_t cqivect = 0;
//
////  char diff_cqi;
//  int diff_cqi=0;
//
//  for (i=0;i<NUMBER_OF_SUBBANDS;i++) {
//
//    diff_cqi = -sinr2cqi(meas->wideband_cqi_dB[eNB_id][0]) + sinr2cqi(meas->subband_cqi_dB[eNB_id][0][i]);
//
//    // Note, this is Table 7.2.1-2 from 36.213
//    if (diff_cqi<=-1)
//      diff_cqi = 3;
//    else if (diff_cqi>2)
//      diff_cqi = 2;
//    cqivect |= (diff_cqi<<(2*i));
//
//  }
//
//  return(cqivect);
//}


uint32_t fill_subband_cqi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t trans_mode,int nb_subbands)
{

  uint8_t i;

  uint32_t cqivect = 0,offset=0;


  int diff_cqi=0;

  for (i=0; i<nb_subbands; i++) {

    diff_cqi = -sinr2cqi(meas->wideband_cqi_avg[eNB_id],trans_mode) + sinr2cqi(meas->subband_cqi_tot_dB[eNB_id][i],trans_mode);

    // Note, this is Table 7.2.1-2 from 36.213
    if (diff_cqi<=-1)
      offset = 3;
    else if (diff_cqi>=2)
      offset = 2;
    else
      offset=(uint32_t)diff_cqi;

    cqivect |= (offset<<(2*i));

  }

  return(cqivect);
}

void fill_CQI(LTE_UE_ULSCH_t *ulsch,PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t harq_pid,int N_RB_DL,uint16_t rnti, uint8_t trans_mode, double sinr_eff)
{

  //  printf("[PHY][UE] Filling CQI for eNB %d, meas->wideband_cqi_tot[%d] %d\n",
  //      eNB_id,eNB_id,meas->wideband_cqi_tot[eNB_id]);
  double sinr_tmp;
  uint8_t *o = ulsch->o;
  UCI_format_t uci_format = ulsch->uci_format;

  if(flag_LA==1)
    sinr_tmp = sinr_eff;
  else
    sinr_tmp = (double) meas->wideband_cqi_avg[eNB_id];



  //LOG_I(PHY,"[UE][UCI] Filling CQI format %d for eNB %d N_RB_DL %d\n",uci_format,eNB_id,N_RB_DL);

  switch (N_RB_DL) {

  case 6:
    switch (uci_format) {
    case wideband_cqi_rank1_2A:
      ((wideband_cqi_rank1_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode);
      ((wideband_cqi_rank1_2A_1_5MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,6);
      break;

    case wideband_cqi_rank2_2A:
      ((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
      ((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
      ((wideband_cqi_rank2_2A_1_5MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,6);
      break;

    case HLC_subband_cqi_nopmi:
      ((HLC_subband_cqi_nopmi_1_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_nopmi_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6);
      break;

    case HLC_subband_cqi_rank1_2A:
      ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6);
      ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->pmi      = quantize_wideband_pmi(meas,eNB_id);
      break;

    case HLC_subband_cqi_rank2_2A:
      // This has to be improved!!!
      ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6);
      ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi2     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,6);
      ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->pmi      = quantize_subband_pmi(meas,eNB_id,6);
      break;

    case HLC_subband_cqi_mcs_CBA:
      // this is the cba mcs uci for cba transmission
      ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->mcs     = ulsch->harq_processes[harq_pid]->mcs;
      ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->crnti  = rnti;
      LOG_D(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs);
      break;

    case ue_selected:
      LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n");
      AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!");
      break;

    default:
      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
      AssertFatal(1==0,"unsupported CQI mode !!!");
      break;

    }

    break;

  case 25:
    switch (uci_format) {
    case wideband_cqi_rank1_2A:
      ((wideband_cqi_rank1_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode);
      ((wideband_cqi_rank1_2A_5MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,7);
      break;

    case wideband_cqi_rank2_2A:
      ((wideband_cqi_rank2_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
      ((wideband_cqi_rank2_2A_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
      ((wideband_cqi_rank2_2A_5MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,7);
      break;

    case HLC_subband_cqi_nopmi:
      ((HLC_subband_cqi_nopmi_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_nopmi_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7);
      break;

    case HLC_subband_cqi_rank1_2A:
      ((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7);
      ((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi      = quantize_wideband_pmi(meas,eNB_id);
      break;

    case HLC_subband_cqi_rank2_2A:
      // This has to be improved!!!
      ((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7);
      ((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi2     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,7);
      ((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi      = quantize_subband_pmi(meas,eNB_id,7);
      break;

    case HLC_subband_cqi_mcs_CBA:
      // this is the cba mcs uci for cba transmission
      ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs     = ulsch->harq_processes[harq_pid]->mcs;
      ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti  = rnti;
      LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs);
      break;

    case ue_selected:
      LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n");
      AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!");
      break;

    default:
      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
      AssertFatal(1==0,"unsupported CQI mode !!!");
      break;

    }

    break;

  case 50:
    switch (uci_format) {
    case wideband_cqi_rank1_2A:
      ((wideband_cqi_rank1_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode);
      ((wideband_cqi_rank1_2A_10MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,9);
      break;

    case wideband_cqi_rank2_2A:
      ((wideband_cqi_rank2_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
      ((wideband_cqi_rank2_2A_10MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
      ((wideband_cqi_rank2_2A_10MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,9);
      break;

    case HLC_subband_cqi_nopmi:
      ((HLC_subband_cqi_nopmi_10MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_nopmi_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9);
      break;

    case HLC_subband_cqi_rank1_2A:
      ((HLC_subband_cqi_rank1_2A_10MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank1_2A_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9);
      ((HLC_subband_cqi_rank1_2A_10MHz *)o)->pmi      = quantize_wideband_pmi(meas,eNB_id);
      break;

    case HLC_subband_cqi_rank2_2A:
      // This has to be improved!!!
      ((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9);
      ((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi2     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,9);
      ((HLC_subband_cqi_rank2_2A_10MHz *)o)->pmi      = quantize_subband_pmi(meas,eNB_id,9);
      break;

    case HLC_subband_cqi_mcs_CBA:
      // this is the cba mcs uci for cba transmission
      ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->mcs     = ulsch->harq_processes[harq_pid]->mcs;
      ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->crnti  = rnti;
      LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs);
      break;

    case ue_selected:
      LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n");
      AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!");
      break;

    default:
      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
      AssertFatal(1==0,"unsupported CQI mode !!!");
      break;

    }

    break;

  case 100:
    switch (uci_format) {
    case wideband_cqi_rank1_2A:
      ((wideband_cqi_rank1_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode);
      ((wideband_cqi_rank1_2A_20MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,13);
      break;

    case wideband_cqi_rank2_2A:
      ((wideband_cqi_rank2_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
      ((wideband_cqi_rank2_2A_20MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi
      ((wideband_cqi_rank2_2A_20MHz *)o)->pmi  = quantize_subband_pmi(meas,eNB_id,13);
      break;

    case HLC_subband_cqi_nopmi:
      ((HLC_subband_cqi_nopmi_20MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_nopmi_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13);
      break;

    case HLC_subband_cqi_rank1_2A:
      ((HLC_subband_cqi_rank1_2A_20MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank1_2A_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13);
      ((HLC_subband_cqi_rank1_2A_20MHz *)o)->pmi      = quantize_wideband_pmi(meas,eNB_id);
      break;

    case HLC_subband_cqi_rank2_2A:
      // This has to be improved!!!
      ((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi1     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13);
      ((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi2     = sinr2cqi(sinr_tmp,trans_mode);
      ((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,13);
      ((HLC_subband_cqi_rank2_2A_20MHz *)o)->pmi      = quantize_subband_pmi(meas,eNB_id,13);
      break;

    case HLC_subband_cqi_mcs_CBA:
      // this is the cba mcs uci for cba transmission
      ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->mcs     = ulsch->harq_processes[harq_pid]->mcs;
      ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->crnti  = rnti;
      LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs);
      break;

    case ue_selected:
      LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n");
      AssertFatal(1==0,"fill_CQI ue_selected CQI not supported yet!!!");
      break;

    default:
      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
      AssertFatal(1==0,"unsupported CQI mode !!!");
      break;

    }

    break;

  }


}

void reset_cba_uci(void *o)
{
  // this is the cba mcs uci for cba transmission
  ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs     = 0; //fixme
  ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti  = 0x0;
}


uint32_t pmi_extend(LTE_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank)
{

  uint8_t i,wideband_pmi2;
  uint32_t pmi_ex = 0;

  if (frame_parms->N_RB_DL!=25) {
    LOG_E(PHY,"pmi_extend not yet implemented for anything else than 25PRB\n");
    return(-1);
  }

  if (rank==0) {
    wideband_pmi2=wideband_pmi&3;
    for (i=0; i<14; i+=2)
      pmi_ex|=(wideband_pmi2<<i);
  }
  else if (rank==1) {
    wideband_pmi2=wideband_pmi&1;
    for (i=0; i<7; i++)
      pmi_ex|=(wideband_pmi2<<i);
  }
  else {
    LOG_E(PHY,"unsupported rank\n");
    return(-1);
  }

  return(pmi_ex);
}


int generate_ue_ulsch_params_from_dci(void *dci_pdu,
                                      uint16_t rnti,
                                      uint8_t subframe,
                                      DCI_format_t dci_format,
                                      PHY_VARS_UE *ue,
                                      UE_rxtx_proc_t *proc,
                                      uint16_t si_rnti,
                                      uint16_t ra_rnti,
                                      uint16_t p_rnti,
                                      uint16_t cba_rnti,
                                      uint8_t eNB_id,
                                      uint8_t use_srs)
{

  uint8_t harq_pid;
  uint8_t transmission_mode = ue->transmission_mode[eNB_id];
  ANFBmode_t AckNackFBMode;
  LTE_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id];
  LTE_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[subframe]][0];
  PHY_MEASUREMENTS *meas = &ue->measurements;
  LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
  //  uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id];

  if(frame_parms->frame_type == TDD)
  {
      AckNackFBMode = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
  }
  else
  {
      AckNackFBMode = 1; // 1: multiplexing for FDD
  }

  uint32_t cqi_req;
  uint32_t dai=3;
  uint32_t cshift;
  uint32_t TPC;
  uint32_t ndi;
  uint32_t mcs;
  uint32_t rballoc,RIV_max;
  uint16_t* RIV2first_rb_LUT;
  uint16_t* RIV2nb_rb_LUT;

  //  uint32_t hopping;
  //  uint32_t type;

  if (dci_format == format0) {

    if (!ulsch)
      return -1;

    if (rnti == ra_rnti)
      harq_pid = 0;
    else
      harq_pid = subframe2harq_pid(frame_parms,
                                   pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,subframe),
                                   pdcch_alloc2ul_subframe(frame_parms,subframe));

    if (harq_pid == 255) {
      LOG_E(PHY, "frame %d, subframe %d, rnti %x, format %d: illegal harq_pid!\n",
            proc->frame_rx, subframe, rnti, dci_format);
      return(-1);
    }

    switch (frame_parms->N_RB_DL) {
    case 6:
      if (frame_parms->frame_type == TDD) {
        cqi_req = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
        dai     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai;
        cshift  = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
        ndi     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi;
        mcs     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping;
        //  type    = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type;
      } else {
        cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req;
        cshift  = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC;
        ndi     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->ndi;
        mcs     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping=hopping;
        //  type    = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type;
      }

      RIV_max = RIV_max6;
      RIV2first_rb_LUT = RIV2first_rb_LUT6;
      RIV2nb_rb_LUT = RIV2nb_rb_LUT6;

      break;

    case 25:
      if (frame_parms->frame_type == TDD) {
        cqi_req = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
        dai     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai;
        cshift  = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
        ndi     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->ndi;
        mcs     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping;
        //  type    = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type;
      } else {
        cqi_req = ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req;
        cshift  = ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC;
        ndi     = ((DCI0_5MHz_FDD_t *)dci_pdu)->ndi;
        mcs     = ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping=hopping;
        //  type    = ((DCI0_5MHz_FDD_t *)dci_pdu)->type;
      }

      RIV_max = RIV_max25;
      RIV2first_rb_LUT = RIV2first_rb_LUT25;
      RIV2nb_rb_LUT = RIV2nb_rb_LUT25;
      //      printf("***********rballoc %d, first_rb %d, nb_rb %d (dci %p)\n",rballoc,ulsch->harq_processes[harq_pid]->first_rb,ulsch->harq_processes[harq_pid]->nb_rb,dci_pdu);
      break;

    case 50:
      if (frame_parms->frame_type == TDD) {
        cqi_req = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
        dai     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai;
        cshift  = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC;
        ndi     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->ndi;
        mcs     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping;
        //  type    = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type;
      } else {
        cqi_req = ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req;
        cshift  = ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC;
        ndi     = ((DCI0_10MHz_FDD_t *)dci_pdu)->ndi;
        mcs     = ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping=hopping;
        //  type    = ((DCI0_10MHz_FDD_t *)dci_pdu)->type;
      }

      RIV_max = RIV_max50;
      RIV2first_rb_LUT = RIV2first_rb_LUT50;
      RIV2nb_rb_LUT = RIV2nb_rb_LUT50;

      break;

    case 100:
      if (frame_parms->frame_type == TDD) {
        cqi_req = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
        dai     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai;
        cshift  = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC;
        ndi     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->ndi;
        mcs     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping;
        //  type    = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type;
      } else {
        cqi_req = ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req;
        cshift  = ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC;
        ndi     = ((DCI0_20MHz_FDD_t *)dci_pdu)->ndi;
        mcs     = ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping=hopping;
        //  type    = ((DCI0_20MHz_FDD_t *)dci_pdu)->type;
      }

      RIV_max = RIV_max100;
      RIV2first_rb_LUT = RIV2first_rb_LUT100;
      RIV2nb_rb_LUT = RIV2nb_rb_LUT100;

      //      printf("rb_alloc (20 MHz dci) %d\n",rballoc);
      break;

    default:
      LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
      DevParam (frame_parms->N_RB_DL, 0, 0);
      break;
    }


    if (rballoc > RIV_max) {
      LOG_E(PHY,"frame %d, subframe %d, rnti %x, format %d: FATAL ERROR: generate_ue_ulsch_params_from_dci, rb_alloc[%d] > RIV_max[%d]\n",
            proc->frame_rx, subframe, rnti, dci_format,rballoc,RIV_max);
      LOG_E(PHY,"Wrong DCI0 detection, do not transmit PUSCH for HARQID: %d\n",harq_pid);
      ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
      return(-1);
    }


    // indicate that this process is to be serviced in subframe n+4
    if ((rnti >= cba_rnti) && (rnti < p_rnti))
      ulsch->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1; //+=1 this indicates the number of dci / cba group: not supported in the data struct
    else
    {
        ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
        //LOG_I(PHY,"[HARQ-UL harqId: %d] DCI0 ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);

    }

    ulsch->harq_processes[harq_pid]->TPC                                   = TPC;
    ulsch->harq_processes[harq_pid]->first_rb                              = RIV2first_rb_LUT[rballoc];
    ulsch->harq_processes[harq_pid]->nb_rb                                 = RIV2nb_rb_LUT[rballoc];

    if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) {
      LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d: f_pusch (ACC) %d, adjusting by %d (TPC %d)\n",
            ue->Mod_id,harq_pid,proc->frame_rx,subframe,ulsch->f_pusch,
            delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC],
            ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC);
      ulsch->f_pusch += delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC];
    } else {
      LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d: f_pusch (ABS) %d, adjusting to %d (TPC %d)\n",
            ue->Mod_id,harq_pid,proc->frame_rx,subframe,ulsch->f_pusch,
            delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC],
            ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC);
      ulsch->f_pusch = delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC];
    }

    if (ulsch->harq_processes[harq_pid]->first_tx==1) {
      //      ulsch->harq_processes[harq_pid]->Ndi                                   = 1;
      ulsch->harq_processes[harq_pid]->first_tx=0;
      ulsch->harq_processes[harq_pid]->DCINdi= ndi;
      ulsch->harq_processes[harq_pid]->round = 0;
    } else {
      if (ulsch->harq_processes[harq_pid]->DCINdi!=ndi) { // new SDU opportunity
        //  ulsch->harq_processes[harq_pid]->Ndi = 1;
        ulsch->harq_processes[harq_pid]->DCINdi= ndi;
        ulsch->harq_processes[harq_pid]->round = 0;
      } else {
        //  ulsch->harq_processes[harq_pid]->Ndi = 0;
        //ulsch->harq_processes[harq_pid]->round++;  // This is done in phich RX

        //#ifdef DEBUG_PHICH
        //LOG_I(PHY,"[UE  %d][PUSCH %d] Frame %d subframe %d Adaptative Retrans, NDI not toggled => Nack. maxHARQ_Tx %d \n",
        //      ue->Mod_id,harq_pid,
        //      proc->frame_rx,
        //      subframe,
        //      ulsch->Mlimit);
        //#endif
/*
        if (ulsch->harq_processes[harq_pid]->round > 0) // NACK detected on phich
        {
            // ulsch->harq_processes[harq_pid]->round++; already done on phich_rx
            // ulsch->harq_processes[harq_pid] = ulsch->harq_processes[8];
            // LOG_I(PHY,"          Adaptative retransmission - copy temporary harq Process to current harq process. [harqId %d round %d] \n",harq_pid, ulsch->harq_processes[8]->round);

            if (ulsch->harq_processes[harq_pid]->round >= ulsch->Mlimit) //UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx)
            {
                ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0;
                ulsch->harq_processes[harq_pid]->round  = 0;
                ulsch->harq_processes[harq_pid]->status = IDLE;
                //LOG_I(PHY,"          PUSCH MAX Retransmission acheived ==> flush harq buff (%d) \n",harq_pid);
                //LOG_I(PHY,"          [HARQ-UL harqId: %d] Adaptative retransmission NACK MAX RETRANS(%d) ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round);
            }
            else
            {
                // ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
                uint8_t rv_table[4] = {0, 2, 3, 1};
                ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3];
                ulsch->O_RI = 0;
                ulsch->O    = 0;
                ulsch->uci_format = HLC_subband_cqi_nopmi;
                //LOG_I(PHY,"          [HARQ-UL harqId: %d] Adaptative retransmission NACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,ulsch->harq_processes[harq_pid]->round);
            }
        }
*/
      }
    }

    ulsch->harq_processes[harq_pid]->n_DMRS                                = cshift;

    //printf("nb_rb %d, first_rb %d (RIV %d)\n",ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb,rballoc);
    if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
      // ulsch->cba_rnti[0]=rnti;
    } else {
      ulsch->rnti = rnti;
    }

    //    printf("[PHY][UE] DCI format 0: harq_pid %d nb_rb %d, rballoc %d\n",harq_pid,ulsch->harq_processes[harq_pid]->nb_rb,
    //     ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc);
    //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1)
    if(cshift == 0)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 0;
    else if(cshift == 1)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 6;
    else if(cshift == 2)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 3;
    else if(cshift == 3)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 4;
    else if(cshift == 4)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 2;
    else if(cshift == 5)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 8;
    else if(cshift == 6)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 10;
    else if(cshift == 7)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 9;


    //reserved for cooperative communication
    /*
      if(ulsch->n_DMRS2 == 6)
      ulsch->cooperation_flag = 2;
      else
      ulsch->cooperation_flag = 0;
    */

    if ((ulsch->harq_processes[harq_pid]->nb_rb>0) && (ulsch->harq_processes[harq_pid]->nb_rb < 25))
      ulsch->power_offset = ue_power_offsets[ulsch->harq_processes[harq_pid]->nb_rb-1];

    //    if (ulsch->harq_processes[harq_pid]->Ndi == 1)
    //    ulsch->harq_processes[harq_pid]->status = ACTIVE;


    if (cqi_req == 1) {

      if( (AntennaInfoDedicated__transmissionMode_tm3 == transmission_mode) || (AntennaInfoDedicated__transmissionMode_tm4 == transmission_mode) )
      {
          ulsch->O_RI = 1;
      }
      else
      {
          ulsch->O_RI = 0;
      }
      //ulsch->O_RI = 0; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table

      switch(transmission_mode) {
        // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling
      case 1:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
          ulsch->o_RI[0]                             = 0;
        } else  if(meas->rank[eNB_id] == 0) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
          ulsch->o_RI[0]                             = 0;
        } else {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
          ulsch->o_RI[0]                             = 1;
        }

        break;

      case 2:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
          ulsch->o_RI[0]                             = 0;
        } else if(meas->rank[eNB_id] == 0) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
          ulsch->o_RI[0]                             = 0;
        } else {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
          ulsch->o_RI[0]                             = 1;
        }

        break;

      case 3:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
          ulsch->o_RI[0]                             = 0;
        } else if(meas->rank[eNB_id] == 0) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
          ulsch->o_RI[0]                             = 0;
        } else {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
          ulsch->o_RI[0]                             = 1;
        }

        break;

      case 4:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
          ulsch->o_RI[0]                             = 0;
        } else if(meas->rank[eNB_id] == 0) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_20MHz;
            break;
          }

          ulsch->uci_format                          = wideband_cqi_rank1_2A;
          ulsch->o_RI[0]                             = 0;
        } else {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_20MHz;
            break;
          }

          ulsch->uci_format                          = wideband_cqi_rank2_2A;
          ulsch->o_RI[0]                             = 1;
        }

        break;

      case 5:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
          ulsch->o_RI[0]                             = 0;
        } else if(meas->rank[eNB_id] == 0) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_20MHz;
            break;
          }

          ulsch->uci_format                          = wideband_cqi_rank1_2A;
          ulsch->o_RI[0]                             = 0;
        } else {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_20MHz;
            break;
          }

          ulsch->uci_format                          = wideband_cqi_rank2_2A;
          ulsch->o_RI[0]                             = 1;
        }

        break;

      case 6:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
          ulsch->o_RI[0]                             = 0;
        } else if(meas->rank[eNB_id] == 0) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_wideband_cqi_rank1_2A_20MHz;
            break;
          }

          ulsch->uci_format                          = wideband_cqi_rank1_2A;
          ulsch->o_RI[0]                             = 0;
        } else {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_wideband_cqi_rank2_2A_20MHz;
            break;
          }

          ulsch->uci_format                          = wideband_cqi_rank2_2A;
          ulsch->o_RI[0]                             = 1;
        }

        break;

      case 7:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_mcs_CBA;
          ulsch->o_RI[0]                             = 0;
        } else if(meas->rank[eNB_id] == 0) {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
          ulsch->o_RI[0]                             = 0;
        } else {
          switch (ue->frame_parms.N_RB_DL) {
          case 6:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
            break;

          case 25:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
            break;

          case 50:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
            break;

          case 100:
            ulsch->O                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
            break;
          }

          ulsch->uci_format                          = HLC_subband_cqi_nopmi;
          ulsch->o_RI[0]                             = 1;
        }

        break;

      default:
        LOG_E(PHY,"Incorrect Transmission Mode \n");
        break;
      }
    } else {
      ulsch->O_RI = 0;
      ulsch->O                                   = 0;
      ulsch->uci_format                          = HLC_subband_cqi_nopmi;
    }

    print_CQI(ulsch->o,ulsch->uci_format,eNB_id,ue->frame_parms.N_RB_DL);

    ulsch->bundling = 1-AckNackFBMode;

    if (frame_parms->frame_type == FDD) {
      //int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4);
      int dl_subframe = subframe;

      if (ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_ack[dl_subframe].send_harq_status>0) { // we have downlink transmission
        ulsch->harq_processes[harq_pid]->O_ACK = 1;
      } else {
        ulsch->harq_processes[harq_pid]->O_ACK = 0;
      }
      /*LOG_I(PHY,"DCI 0 Processing: dl_subframe %d send_harq_status Odd %d send_harq_status Even %d harq_pid %d O_ACK %d\n", dl_subframe,
              ue->dlsch[0][eNB_id][0]->harq_ack[dl_subframe].send_harq_status,
              ue->dlsch[1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status,
              harq_pid,
              ulsch->harq_processes[harq_pid]->O_ACK);*/

    } else {
      if (ulsch->bundling)
        ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1;
      else
        ulsch->harq_processes[harq_pid]->O_ACK = (dai >= 2)? 2 : (dai+1)&3; //(dai+1)&3;

      //      ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1;
    }

    dlsch[0]->harq_ack[subframe].vDAI_UL = dai+1;


    /*LOG_I(PHY, "[PUSCH %d] Format0 DCI %s, CQI_req=%d, cshift=%d, TPC=%d, DAI=%d, vDAI_UL[sf#%d]=%d, NDI=%d, MCS=%d, RBalloc=%d, first_rb=%d, harq_pid=%d, nb_rb=%d, subframe_scheduling_flag=%d"
            "   ulsch->bundling %d, O_ACK %d \n",
        harq_pid,
        (frame_parms->frame_type == TDD? "TDD" : "FDD"),
        cqi_req, cshift, TPC, dai, subframe, dlsch[0]->harq_ack[subframe].vDAI_UL, ndi, mcs, rballoc,
        ulsch->harq_processes[harq_pid]->first_rb, harq_pid, ulsch->harq_processes[harq_pid]->nb_rb,
        ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,
        ulsch->bundling,
        ulsch->harq_processes[harq_pid]->O_ACK);*/
    LOG_D(PHY,"Setting beta_offset_cqi_times8 to %d, index %d\n",
	  beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index],
	  ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index);

    ulsch->beta_offset_cqi_times8                = beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index];//18;
    ulsch->beta_offset_ri_times8                 = beta_ri[ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index];//10;
    ulsch->beta_offset_harqack_times8            = beta_ack[ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index];//16;

    ulsch->Nsymb_pusch                             = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1);
    ulsch->srs_active                              = use_srs;

    if ((rnti >= cba_rnti) && (rnti < p_rnti))
      ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE;
    else
      ulsch->harq_processes[harq_pid]->status = ACTIVE;

    ulsch->harq_processes[harq_pid]->rvidx = 0;

    //      ulsch->harq_processes[harq_pid]->calibration_flag =0;
    if (mcs < 29) {
      ulsch->harq_processes[harq_pid]->mcs = mcs;
      // ulsch->harq_processes[harq_pid]->round = 0;
    } else {
      ulsch->harq_processes[harq_pid]->rvidx = mcs - 28;
      if (ulsch->harq_processes[harq_pid]->round == 0) {
        LOG_W(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round);
      } else {
        LOG_D(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round);
      }
      //LOG_E(PHY,"Fatal: mcs(%d) > 28!!! and round == 0\n", mcs);
    }
    ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1];

    /*
       else if (ulsch->harq_processes[harq_pid]->mcs == 29) {
       ulsch->harq_processes[harq_pid]->mcs = 4;
       ulsch->harq_processes[harq_pid]->TBS         = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1];
    // ulsch->harq_processes[harq_pid]->calibration_flag =1;
    // printf("Auto-Calibration (UE): mcs %d, TBS %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->TBS,ulsch->harq_processes[harq_pid]->nb_rb);
    }*/
    ulsch->harq_processes[harq_pid]->Msc_initial   = 12*ulsch->harq_processes[harq_pid]->nb_rb;
    ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->Nsymb_pusch;

    // a Ndi=1 automatically acknowledges previous PUSCH transmission
    if (ue->ulsch_Msg3_active[eNB_id] == 1)
      ue->ulsch_Msg3_active[eNB_id] = 0;

    LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d), nb_rb %d, first_rb %d, mcs %d, round %d, rv %d, ulsch_ue_Msg3_active %d, cqi_req %d => O %d\n",
        ue->Mod_id,harq_pid,
        proc->frame_rx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift,ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb,
	  ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->rvidx, ue->ulsch_Msg3_active[eNB_id],cqi_req,ulsch->O);

  // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift;

#ifdef UE_DEBUG_TRACE

    LOG_I(PHY,"Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,subframe);
    LOG_D(PHY,"Format 0 DCI : ulsch (ue): NBRB        %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
    LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_rb    %d\n",ulsch->harq_processes[harq_pid]->first_rb);
    LOG_D(PHY,"Format 0 DCI :ulsch (ue): rballoc     %d\n",rballoc);
    LOG_D(PHY,"Format 0 DCI :ulsch (ue): harq_pid    %d\n",harq_pid);
    LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_tx       %d\n",ulsch->harq_processes[harq_pid]->first_tx);
    LOG_D(PHY,"Format 0 DCI :ulsch (ue): DCINdi       %d\n",ulsch->harq_processes[harq_pid]->DCINdi);
    LOG_D(PHY,"Format 0 DCI :ulsch (ue): round       %d\n",ulsch->harq_processes[harq_pid]->round);
    //LOG_I(PHY,"Format 0 DCI :ulsch (ue): TBS         %d\n",ulsch->harq_processes[harq_pid]->TBS);
    LOG_D(PHY,"Format 0 DCI :ulsch (ue): mcs         %d\n",ulsch->harq_processes[harq_pid]->mcs);
    //LOG_I(PHY,"Format 0 DCI :ulsch (ue): O           %d\n",ulsch->O);
    //LOG_I(PHY,"Format 0 DCI :ulsch (ue): cqiReq      %d\n",cqi_req);
    //if (frame_parms->frame_type == TDD)
    //  LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK/DAI   %d/%d\n",ulsch->harq_processes[harq_pid]->O_ACK,dai);
    //else
    //  LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK       %d\n",ulsch->harq_processes[harq_pid]->O_ACK);

    LOG_D(PHY,"Format 0 DCI :ulsch (ue): Nsymb_pusch   %d\n",ulsch->Nsymb_pusch);
    LOG_D(PHY,"Format 0 DCI :ulsch (ue): cshift        %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2);
    LOG_D(PHY,"Format 0 DCI :ulsch (ue): phich status  %d\n",ulsch->harq_processes[harq_pid]->status);
#else
    UNUSED_VARIABLE(dai);
#endif
    return(0);
  } else {
    LOG_E(PHY,"frame %d, subframe %d: FATAL ERROR, generate_ue_ulsch_params_from_dci, Illegal dci_format %d\n",
          proc->frame_rx, subframe,dci_format);
    return(-1);
  }

}

/*
int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
                                       eNB_rxtx_proc_t *proc,
                                       void *dci_pdu,
                                       uint16_t rnti,
                                       DCI_format_t dci_format,
                                       uint8_t UE_id,
                                       uint16_t si_rnti,
                                       uint16_t ra_rnti,
                                       uint16_t p_rnti,
                                       uint16_t cba_rnti,
                                       uint8_t use_srs)
{

  uint8_t harq_pid;
  uint32_t rb_alloc;
  uint8_t transmission_mode=eNB->transmission_mode[UE_id];
  ANFBmode_t AckNackFBMode = eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode;
  LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id];
  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
  int subframe = proc->subframe_tx;

  uint32_t cqi_req = 0;
  uint32_t dai = 0;
  uint32_t cshift = 0;
  uint32_t TPC = 0;
  uint32_t mcs = 0;
  uint32_t rballoc = UINT32_MAX;
  uint32_t RIV_max = 0;
  //  uint32_t hopping;
  //  uint32_t type;

#ifdef DEBUG_DCI
  printf("filling eNB ulsch params for rnti %x, dci format %d, dci %x, subframe %d\n",
        rnti,dci_format,*(uint32_t*)dci_pdu,subframe);
#endif

  if (dci_format == format0) {

    harq_pid = subframe2harq_pid(frame_parms,
                                 pdcch_alloc2ul_frame(frame_parms,
                                                      proc->frame_tx,
                                                      subframe),
                                 pdcch_alloc2ul_subframe(frame_parms,subframe));
    switch (frame_parms->N_RB_DL) {
    case 6:
      if (frame_parms->frame_type == TDD) {
        cqi_req = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
        dai     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai;
        cshift  = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
        mcs     = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping=hopping;
        //  type    = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type;
      } else {
        cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req;
        cshift  = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC;
        mcs     = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping=hopping;
        //  type    = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type;
      }
      
      RIV_max = RIV_max6;
      ulsch->harq_processes[harq_pid]->first_rb                              = RIV2first_rb_LUT6[rballoc];
      ulsch->harq_processes[harq_pid]->nb_rb                                 = RIV2nb_rb_LUT6[rballoc];

      break;

    case 25:
      if (frame_parms->frame_type == TDD) {
        cqi_req = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
        dai     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai;
        cshift  = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC;
        mcs     = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping;
        //  type    = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type;
      } else {
        cqi_req = ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req;
        cshift  = ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC;
        mcs     = ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping;
        //  type    = ((DCI0_5MHz_FDD_t *)dci_pdu)->type;
      }

      RIV_max = RIV_max25;
      ulsch->harq_processes[harq_pid]->first_rb                              = RIV2first_rb_LUT25[rballoc];
      ulsch->harq_processes[harq_pid]->nb_rb                                 = RIV2nb_rb_LUT25[rballoc];

      break;

    case 50:
      if (frame_parms->frame_type == TDD) {
        cqi_req = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
        dai     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai;
        cshift  = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC;
        mcs     = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping;
        //  type    = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type;
      } else {
        cqi_req = ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req;
        cshift  = ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC;
        mcs     = ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping;
        //  type    = ((DCI0_10MHz_FDD_t *)dci_pdu)->type;
      }

      RIV_max = RIV_max50;
      ulsch->harq_processes[harq_pid]->first_rb                              = RIV2first_rb_LUT50[rballoc];
      ulsch->harq_processes[harq_pid]->nb_rb                                 = RIV2nb_rb_LUT50[rballoc];

      break;

    case 100:
      if (frame_parms->frame_type == TDD) {
        cqi_req = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req;
        dai     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai;
        cshift  = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC;
        mcs     = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping;
        //  type    = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type;
      } else {
        cqi_req = ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req;
        cshift  = ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift;
        TPC     = ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC;
        mcs     = ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs;
        rballoc = ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc;
        //  hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping;
        //  type    = ((DCI0_20MHz_FDD_t *)dci_pdu)->type;
      }

      RIV_max = RIV_max100;
      ulsch->harq_processes[harq_pid]->first_rb                              = RIV2first_rb_LUT100[rballoc];
      ulsch->harq_processes[harq_pid]->nb_rb                                 = RIV2nb_rb_LUT100[rballoc];

      //printf("eNB: rb_alloc (20 MHz dci) %d\n",rballoc);
      break;

    default:
      LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL);
      DevParam (frame_parms->N_RB_DL, 0, 0);
      break;
    }


    rb_alloc = rballoc;
    AssertFatal(rb_alloc>RIV_max,
		"Format 0: rb_alloc (%d) > RIV_max (%d)\n",rb_alloc,RIV_max);
#ifdef DEBUG_DCI
    printf("generate_eNB_ulsch_params_from_dci: subframe %d, rnti %x,harq_pid %d,cqi_req %d\n",subframe,rnti,harq_pid,cqi_req);
#endif

    ulsch->harq_processes[harq_pid]->dci_alloc                             = 1;
    ulsch->harq_processes[harq_pid]->rar_alloc                             = 0;
    ulsch->harq_processes[harq_pid]->TPC                                   = TPC;
    ulsch->harq_processes[harq_pid]->n_DMRS                                = cshift;


    if (cqi_req == 1) {
      // 36.213 7.2.1 (release 10) says:
      // "RI is only reported for transmission modes 3 and 4,
      // as well as transmission modes 8 and 9 with PMI/RI reporting"
      // This is for aperiodic reporting.
      // TODO: deal with TM 8&9 correctly when they are implemented.
      // TODO: deal with periodic reporting if we implement it.
      //
      if (transmission_mode == 3 || transmission_mode == 4)
        ulsch->harq_processes[harq_pid]->O_RI = 1; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table
      else
        ulsch->harq_processes[harq_pid]->O_RI = 0;

      switch(transmission_mode) {
        // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling
      case 1:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          ulsch->harq_processes[harq_pid]->Or2                                   = 0;

          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
        } else {
          ulsch->harq_processes[harq_pid]->Or2                                   = 0;

          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
            break;
          }

          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
        }

        break;

      case 2:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          ulsch->harq_processes[harq_pid]->Or2                                   = 0;

          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
        } else {
          ulsch->harq_processes[harq_pid]->Or2                                   = 0;

          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
            break;
          }

          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
        }

        break;

      case 3:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          ulsch->harq_processes[harq_pid]->Or2                                   = 0;

          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
        } else {
          ulsch->harq_processes[harq_pid]->Or2                                   = 0;

          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
            break;
          }

          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
        }

        break;

      case 4:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          ulsch->harq_processes[harq_pid]->Or2                                   = 0;

          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
        } else {
          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_1_5MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_5MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_10MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_20MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_20MHz;
            break;

          }

          ulsch->harq_processes[harq_pid]->uci_format                          = wideband_cqi_rank1_2A;
        }

        break;

      case 5:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          ulsch->harq_processes[harq_pid]->Or2                                   = 0;

          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
        } else {
          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_1_5MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_5MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_10MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_20MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_20MHz;
            break;
          }

          ulsch->harq_processes[harq_pid]->uci_format                          = wideband_cqi_rank1_2A;
        }

        break;

      case 6:
        if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
          ulsch->harq_processes[harq_pid]->Or2                                   = 0;

          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_mcs_CBA_20MHz;
            break;
          }

          ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_mcs_CBA;
        } else {
          switch (frame_parms->N_RB_DL) {
          case 6:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_1_5MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_1_5MHz;
            break;

          case 25:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_5MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_5MHz;
            break;

          case 50:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_10MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_10MHz;
            break;

          case 100:
            ulsch->harq_processes[harq_pid]->Or2                                 = sizeof_wideband_cqi_rank2_2A_20MHz;
            ulsch->harq_processes[harq_pid]->Or1                                 = sizeof_wideband_cqi_rank1_2A_20MHz;
            break;
          }

          ulsch->harq_processes[harq_pid]->uci_format                          = wideband_cqi_rank1_2A;
        }

        break;

      case 7:
        ulsch->harq_processes[harq_pid]->Or2                                   = 0;

        switch (frame_parms->N_RB_DL) {
        case 6:
          ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_1_5MHz;
          break;

        case 25:
          ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_5MHz;
          break;

        case 50:
          ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_10MHz;
          break;

        case 100:
          ulsch->harq_processes[harq_pid]->Or1                                   = sizeof_HLC_subband_cqi_nopmi_20MHz;
          break;
        }

        ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
        break;

      default:
        LOG_E(PHY,"Incorrect Transmission Mode \n");
        break;
      }
    } else {
      ulsch->harq_processes[harq_pid]->O_RI = 0;
      ulsch->harq_processes[harq_pid]->Or2                                   = 0;
      ulsch->harq_processes[harq_pid]->Or1                                   = 0;
      ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
    }

    ulsch->bundling = 1-AckNackFBMode;

    if (frame_parms->frame_type == FDD) {
      int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4);

      if (eNB->dlsch[UE_id][0]->subframe_tx[dl_subframe]>0) { // we have downlink transmission
        ulsch->harq_processes[harq_pid]->O_ACK = 1;
      } else {
        ulsch->harq_processes[harq_pid]->O_ACK = 0;
      }
    } else {
      if (ulsch->bundling)
        ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1;
      else
        ulsch->harq_processes[harq_pid]->O_ACK = (dai+1)&3;

      ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1;
    }

    ulsch->beta_offset_cqi_times8                = beta_cqi[eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index];//18;
    ulsch->beta_offset_ri_times8                 = beta_ri[eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index];//10;
    ulsch->beta_offset_harqack_times8            = beta_ack[eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index];//16;

    ulsch->harq_processes[harq_pid]->Nsymb_pusch                             = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1);
    ulsch->harq_processes[harq_pid]->srs_active                            = use_srs;

    //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1)
    if(cshift == 0)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 0;
    else if(cshift == 1)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 6;
    else if(cshift == 2)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 3;
    else if(cshift == 3)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 4;
    else if(cshift == 4)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 2;
    else if(cshift == 5)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 8;
    else if(cshift == 6)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 10;
    else if(cshift == 7)
      ulsch->harq_processes[harq_pid]->n_DMRS2 = 9;


    LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d)\n",
          eNB->Mod_id,harq_pid,proc->frame_tx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift);



    if (ulsch->harq_processes[harq_pid]->round == 0) {
      if ((rnti >= cba_rnti) && (rnti < p_rnti))
        ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE;
      else
        ulsch->harq_processes[harq_pid]->status = ACTIVE;

      ulsch->harq_processes[harq_pid]->rvidx = 0;
      ulsch->harq_processes[harq_pid]->mcs         = mcs;
      //      ulsch->harq_processes[harq_pid]->calibration_flag = 0;
      //if (ulsch->harq_processes[harq_pid]->mcs)
      //
      //if (ulsch->harq_processes[harq_pid]->mcs == 29) {
      //ulsch->harq_processes[harq_pid]->mcs = 4;
      // ulsch->harq_processes[harq_pid]->calibration_flag = 1;
      // printf("Auto-Calibration (eNB): mcs %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->nb_rb);
      //}
      
      ulsch->harq_processes[harq_pid]->TBS         = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1];

      ulsch->harq_processes[harq_pid]->Msc_initial   = 12*ulsch->harq_processes[harq_pid]->nb_rb;
      ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->harq_processes[harq_pid]->Nsymb_pusch;
      ulsch->harq_processes[harq_pid]->round = 0;
    } else {
      if (mcs>28)
        ulsch->harq_processes[harq_pid]->rvidx = mcs - 28;
      else {
        ulsch->harq_processes[harq_pid]->rvidx = 0;
        ulsch->harq_processes[harq_pid]->mcs = mcs;
      }

      //      ulsch->harq_processes[harq_pid]->round++;
    }

    if ((rnti >= cba_rnti) && (rnti < p_rnti)) {
      ulsch->cba_rnti[0] = rnti;
    } else {
      ulsch->rnti = rnti;
    }

    //ulsch->n_DMRS2 = cshift;

#ifdef DEBUG_DCI
    printf("ulsch (eNB): NBRB          %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
    printf("ulsch (eNB): first_rb      %d\n",ulsch->harq_processes[harq_pid]->first_rb);
    printf("ulsch (eNB): harq_pid      %d\n",harq_pid);
    printf("ulsch (eNB): round         %d\n",ulsch->harq_processes[harq_pid]->round);
    printf("ulsch (eNB): TBS           %d\n",ulsch->harq_processes[harq_pid]->TBS);
    printf("ulsch (eNB): mcs           %d\n",ulsch->harq_processes[harq_pid]->mcs);
    printf("ulsch (eNB): Or1           %d\n",ulsch->harq_processes[harq_pid]->Or1);
    printf("ulsch (eNB): Nsymb_pusch   %d\n",ulsch->harq_processes[harq_pid]->Nsymb_pusch);
    printf("ulsch (eNB): cshift        %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2);
#else
    UNUSED_VARIABLE(dai);
#endif
    return(0);
  } else {
    LOG_E(PHY,"generate_eNB_ulsch_params_from_dci, Illegal dci_format %d\n",dci_format);
    return(-1);
  }

}
*/

double sinr_eff_cqi_calc(PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe)
{
  uint8_t transmission_mode = ue->transmission_mode[eNB_id];
  PHY_MEASUREMENTS *meas = &ue->measurements;
  LTE_DL_FRAME_PARMS *frame_parms =  &ue->frame_parms;
  int32_t **dl_channel_est = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id];
  double *s_dB;
  s_dB = ue->sinr_CQI_dB;
  //  LTE_UE_ULSCH_t *ulsch  = ue->ulsch[eNB_id];
  //for the calculation of SINR_eff for CQI calculation
  int count,a_rx,a_tx;
  double abs_channel=0;
  double channelx=0;
  double channely=0;
  double channelx_i=0;
  double channely_i=0;
  uint16_t q = quantize_subband_pmi(meas,eNB_id,7);
  uint8_t qq;

  switch(transmission_mode) {
  case 1:
    for (count=0; count<frame_parms->N_RB_DL*12; count++) {
      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
        for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
          s_dB[count] = 10*log10(pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2],
                                 2)) - meas->n0_power_avg_dB;
        }
      }
    }

    break;

  case 2:
    for (count=0; count<frame_parms->N_RB_DL*12; count++) {
      abs_channel=0;

      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
        for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
          abs_channel += (pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2],2));
        }
      }

      s_dB[count] = 10*log10(abs_channel/2) - meas->n0_power_avg_dB;
    }

    break;

  case 5:
    for (count=0; count<frame_parms->N_RB_DL*12; count++) {
      channelx=0;
      channely=0;
      channelx_i=0;
      channely_i=0;
      qq = (q>>(((count/12)>>2)<<1))&3;

      //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq);
      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
        for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
          switch(qq) {
          case 0:
            if (channelx==0 || channely==0) {
              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            } else {
              channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channelx_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            }

            break;

          case 1:
            if (channelx==0 || channely==0) {
              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            } else {
              channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channelx_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            }

            break;

          case 2:
            if (channelx==0 || channely==0) {
              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            } else {
              channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channelx_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channely_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
            }

            break;

          case 3:
            if (channelx==0 || channely==0) {
              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            } else {
              channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channelx_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channely_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
            }

            break;

          default:
            printf("Problem in SINR Calculation for TM5 \n");
            break;
          }//switch(qq)
        }//a_rx
      }//a_tx

      s_dB[count] =  10 * log10 ((pow(channelx,2) + pow(channely,2))/2) - 10 * log10 ((pow(channelx_i,2) + pow(channely_i,2))/2) - meas->n0_power_avg_dB;
    }//count

    break;

  case 6:
    for (count=0; count<frame_parms->N_RB_DL*12; count++) {
      channelx=0;
      channely=0;
      qq = (q>>(((count/12)>>2)<<1))&3;

      //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq);
      for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) {
        for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) {
          switch(qq) {
          case 0:
            if (channelx==0 || channely==0) {
              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            } else {
              channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            }

            break;

          case 1:
            if (channelx==0 || channely==0) {
              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            } else {
              channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            }

            break;

          case 2:
            if (channelx==0 || channely==0) {
              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            } else {
              channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
            }

            break;

          case 3:
            if (channelx==0 || channely==0) {
              channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
              channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
            } else {
              channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2];
              channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2];
            }

            break;

          default:
            printf("Problem in SINR Calculation for TM6 \n");
            break;
          }//switch(qq)
        }//a_rx
      }//a_tx

      s_dB[count] =  10 * log10 ((pow(channelx,2) + pow(channely,2))/2) - meas->n0_power_avg_dB;
    }//count

    break;

  default:
    printf("Problem in SINR Calculation for CQI \n");
    break;
  }

  int ii;
  double sinr_eff = 0;
  double sinr_eff_qpsk=0;
  double sinr_eff_qam16=0;
  double sinr_eff_qam64=0;
  double x = 0;
  double I_qpsk=0;
  double I_qam16=0;
  double I_qam64=0;
  double I_qpsk_avg=0;
  double I_qam16_avg=0;
  double I_qam64_avg=0;
  double qpsk_max=12.2;
  double qam16_max=19.2;
  double qam64_max=25.2;
  double sinr_min = -20;
  int offset=0;


  for (offset = 0; offset <= 24; offset++) {
    for(ii=0; ii<12; ii++) {
      //x is the sinr_dB in dB
      x = s_dB[(offset*12)+ii];

      if(x<sinr_min) {
        I_qpsk +=0;
        I_qam16 +=0;
        I_qam64 +=0;
      } else {
        if(x>qpsk_max)
          I_qpsk += 1;
        else
          I_qpsk += (q_qpsk[0]*pow(x,7) + q_qpsk[1]*pow(x,6) + q_qpsk[2]*pow(x,5) + q_qpsk[3]*pow(x,4) + q_qpsk[4]*pow(x,3) + q_qpsk[5]*pow(x,2) + q_qpsk[6]*x + q_qpsk[7]);

        if(x>qam16_max)
          I_qam16 += 1;
        else
          I_qam16 += (q_qam16[0]*pow(x,7) + q_qam16[1]*pow(x,6) + q_qam16[2]*pow(x,5) + q_qam16[3]*pow(x,4) + q_qam16[4]*pow(x,3) + q_qam16[5]*pow(x,2) + q_qam16[6]*x + q_qam16[7]);

        if(x>qam64_max)
          I_qam64 += 1;
        else
          I_qam64 += (q_qam64[0]*pow(x,7) + q_qam64[1]*pow(x,6) + q_qam64[2]*pow(x,5) + q_qam64[3]*pow(x,4) + q_qam64[4]*pow(x,3) + q_qam64[5]*pow(x,2) + q_qam64[6]*x + q_qam64[7]);

      }
    }
  }

  // averaging of accumulated MI
  I_qpsk_avg = I_qpsk/(12*frame_parms->N_RB_DL);
  I_qam16_avg = I_qam16/(12*frame_parms->N_RB_DL);
  I_qam64_avg = I_qam64/(12*frame_parms->N_RB_DL);

  // I->SINR_effective Mapping

  sinr_eff_qpsk = (p_qpsk[0]*pow(I_qpsk_avg,7) + p_qpsk[1]*pow(I_qpsk_avg,6) + p_qpsk[2]*pow(I_qpsk_avg,5) + p_qpsk[3]*pow(I_qpsk_avg,4) + p_qpsk[4]*pow(I_qpsk_avg,3) + p_qpsk[5]*pow(I_qpsk_avg,
                   2) + p_qpsk[6]*I_qpsk_avg + p_qpsk[7]);

  sinr_eff_qam16 = (p_qam16[0]*pow(I_qam16_avg,7) + p_qam16[1]*pow(I_qam16_avg,6) + p_qam16[2]*pow(I_qam16_avg,5) + p_qam16[3]*pow(I_qam16_avg,4) + p_qam16[4]*pow(I_qam16_avg,
                    3) + p_qam16[5]*pow(I_qam16_avg,2) + p_qam16[6]*I_qam16_avg + p_qam16[7]);

  sinr_eff_qam64 = (p_qam64[0]*pow(I_qam64_avg,7) + p_qam64[1]*pow(I_qam64_avg,6) + p_qam64[2]*pow(I_qam64_avg,5) + p_qam64[3]*pow(I_qam64_avg,4) + p_qam64[4]*pow(I_qam64_avg,
                    3) + p_qam64[5]*pow(I_qam64_avg,2) + p_qam64[6]*I_qam64_avg + p_qam64[7]);
  sinr_eff = cmax3(sinr_eff_qpsk,sinr_eff_qam16,sinr_eff_qam64);

  //printf("SINR_Eff = %e\n",sinr_eff);

  return(sinr_eff);
}
//



#ifdef DEBUG_DLSCH_TOOLS
main()
{

  int i;
  uint8_t rah;
  uint32_t rballoc;

  generate_RIV_tables();

  rah = 0;
  rballoc = 0x1fff;
  printf("rballoc 0 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
  rah = 1;

  rballoc = 0x1678;
  printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));

  rballoc = 0xfffc;
  printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
  rballoc = 0xfffd;
  printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
  rballoc = 0xffff;
  printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
  rballoc = 0xfffe;
  printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
}

#endif

