/*******************************************************************************
    OpenAirInterface 
    Copyright(c) 1999 - 2014 Eurecom

    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.


    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is 
   included in this distribution in the file called "COPYING". If not, 
   see <http://www.gnu.org/licenses/>.

  Contact Information
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr
  
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE

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

/*! \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"
#include "MAC_INTERFACE/defs.h"
#include "MAC_INTERFACE/extern.h"
#ifdef DEBUG_DCI_TOOLS
#include "PHY/vars.h"
#endif
#include "assertions.h"

//#define DEBUG_DCI

uint32_t  localRIV2alloc_LUT6[32];
uint32_t  distRIV2alloc_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_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  distRIV2alloc_LUT50_0[1600];
uint32_t  localRIV2alloc_LUT50_1[1600];
uint32_t  distRIV2alloc_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  distRIV2alloc_LUT100_0[6000];
uint32_t  localRIV2alloc_LUT100_1[6000];
uint32_t  distRIV2alloc_LUT100_1[6000];
uint32_t  localRIV2alloc_LUT100_2[6000];
uint32_t  distRIV2alloc_LUT100_2[6000];
uint32_t  localRIV2alloc_LUT100_3[6000];
uint32_t  distRIV2alloc_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_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:
    if (ra_header == 0) {// Type 0 Allocation

      for (i=16; i>0; i--) {
        if ((rb_alloc&(1<<i)) != 0)
          rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32));
      }
      /*
	for (i=1;i<=16;i++) {
        if ((rb_alloc&(1<<(16-i))) != 0) 
	rb_alloc2[(3*i)>>5] |= (7<<((3*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);
      /*      
	      for (i=0;i<16;i++) {
	      if (((rb_alloc>>(16-i))&1) != 0)
	      rb_alloc2[(3*i)>>5] |= (7<<((3*i)%32));
	      if ((i==10)&&((rb_alloc&(1<<6))!=0))
	      rb_alloc2[1] = 1;
	      //	printf("rb_alloc2[%d] (type 0) %x ((%x>>%d)&1=%d)\n",(3*i)>>5,rb_alloc2[(3*i)>>5],rb_alloc,i,(rb_alloc>>i)&1);

	      }
	      // fill in 2 from last bit instead of 3
	      if ((rb_alloc&1) != 0)
	      rb_alloc2[1] |= (3<<i);
	      //    printf("rb_alloc2[%d] (type 0) %x ((%x>>%d)&1=%d)\n",(3*i)>>5,rb_alloc2[(3*i)>>5],rb_alloc,i,(rb_alloc>>i)&1);
	      */
      //      printf("rb_alloc[1]=%x,rb_alloc[0]=%x\n",rb_alloc2[1],rb_alloc2[0]);
    }
    else {
      LOG_E(PHY,"resource type 1 not supported for  N_RB_DL=100\n");
      mac_xface->macphy_exit("resource type 1 not supported for  N_RB_DL=100\n");
      /*
	subset = rb_alloc&1;
	shift  = (rb_alloc>>1)&1;
	for (i=0;i<11;i++) {
	if ((rb_alloc&(1<<(i+2))) != 0)
	rb_alloc2 |= (1<<(2*i));
	//      printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
	}
	if ((shift == 0) && (subset == 1))
	rb_alloc2<<=1;
	else if ((shift == 1) && (subset == 0))
	rb_alloc2<<=4;
	else if ((shift == 1) && (subset == 1))
	rb_alloc2<<=3;
      */
    }
    break;

  case 100:
    if (ra_header == 0) {// Type 0 Allocation
      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));
      }
    }
    else {
      LOG_E(PHY,"resource type 1 not supported for  N_RB_DL=100\n");
      mac_xface->macphy_exit("resource type 1 not supported for  N_RB_DL=100\n");
      /*
	subset = rb_alloc&1;
	shift  = (rb_alloc>>1)&1;
	for (i=0;i<11;i++) {
	if ((rb_alloc&(1<<(i+2))) != 0)
	rb_alloc2 |= (1<<(2*i));
	//      printf("rb_alloc2 (type 1) %x\n",rb_alloc2);
	}
	if ((shift == 0) && (subset == 1))
	rb_alloc2<<=1;
	else if ((shift == 1) && (subset == 0))
	rb_alloc2<<=4;
	else if ((shift == 1) && (subset == 1))
	rb_alloc2<<=3;
      */
    }
    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);
}

int dist6[6]={0,2,3,5,1,4};
int dist50[50]={};
int dist100[100]={};

void generate_RIV_tables() {

  // 6RBs localized RIV
  uint8_t Lcrbs,RBstart;
  uint8_t distpos;
  uint16_t RIV;
  uint32_t alloc0,alloc_dist0;
  uint32_t alloc1,alloc_dist1;
  uint32_t alloc2,alloc_dist2;
  uint32_t alloc3,alloc_dist3;

  for (RBstart=0;RBstart<6;RBstart++) {
    alloc0 = 0;
    alloc_dist0 = 0;
    for (Lcrbs=1;Lcrbs<=(6-RBstart);Lcrbs++) {
      //printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
      alloc0 |= (1<<(RBstart+Lcrbs-1));
      // This is the RB<->VRB relationship for N_RB_DL=25
      alloc_dist0 |= (1<<dist6[RBstart+Lcrbs-1]);

      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_LUT6[RIV]  = alloc_dist0;
      RIV2nb_rb_LUT6[RIV]      = Lcrbs;
      RIV2first_rb_LUT6[RIV]   = RBstart;
    }
  }


  for (RBstart=0;RBstart<25;RBstart++) {
    alloc0 = 0;
    alloc_dist0 = 0;
    for (Lcrbs=1;Lcrbs<=(25-RBstart);Lcrbs++) {
      //      printf("RBstart %d, len %d --> ",RBstart,Lcrbs);
      alloc0 |= (1<<(RBstart+Lcrbs-1));
      // This is the RB<->VRB relationship for N_RB_DL=25
      distpos = ((RBstart+Lcrbs-1)*6)%23;
      if (distpos == 0)
	distpos = 23;
      alloc_dist0 |= (1<<distpos);
          
      RIV=computeRIV(25,RBstart,Lcrbs);
      if (RIV>RIV_max25)
	RIV_max25 = RIV;
          
      //      printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs);
      localRIV2alloc_LUT25[RIV] = alloc0;
      distRIV2alloc_LUT25[RIV]  = alloc_dist0;
      RIV2nb_rb_LUT25[RIV]      = Lcrbs;
      RIV2first_rb_LUT25[RIV]   = RBstart;
    }
  }


  for (RBstart=0;RBstart<50;RBstart++) {
    alloc0 = 0;
    alloc_dist0 = 0;
    alloc1 = 0;
    alloc_dist1 = 0;
    for (Lcrbs=1;Lcrbs<=(50-RBstart);Lcrbs++) {
      //      printf("RBstart %d, len %d --> ",RBstart,Lcrbs);

      if ((RBstart+Lcrbs-1)<32)
	alloc0 |= (1<<(RBstart+Lcrbs-1));
      else
	alloc1 |= (1<<(RBstart+Lcrbs-33));

      if (dist50[RBstart+Lcrbs-1]<32)
	alloc_dist0 |= (1<<dist50[RBstart+Lcrbs-1]);
      else
	alloc_dist1 |= (1<<dist50[RBstart+Lcrbs-33]);

      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_LUT50_0[RIV]  = alloc_dist0;
      distRIV2alloc_LUT50_1[RIV]  = alloc_dist1;
      RIV2nb_rb_LUT50[RIV]        = Lcrbs;
      RIV2first_rb_LUT50[RIV]     = RBstart;
    }
  }


  for (RBstart=0;RBstart<100;RBstart++) {
    alloc0 = 0;
    alloc_dist0 = 0;
    alloc1 = 0;
    alloc_dist1 = 0;
    alloc2 = 0;
    alloc_dist2 = 0;
    alloc3 = 0;
    alloc_dist3 = 0;

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

      if ((RBstart+Lcrbs-1)<32)
	alloc0 |= (1<<(RBstart+Lcrbs-1));
      else if ((RBstart+Lcrbs-1)<64)
	alloc1 |= (1<<(RBstart+Lcrbs-33));
      else if ((RBstart+Lcrbs-1)<96)
	alloc2 |= (1<<(RBstart+Lcrbs-65));
      else
	alloc3 |= (1<<(RBstart+Lcrbs-97));

      if (dist100[RBstart+Lcrbs-1]<32)
	alloc_dist0 |= (1<<dist100[RBstart+Lcrbs-1]);
      else if (dist100[RBstart+Lcrbs-1]<64)
	alloc_dist1 |= (1<<dist100[RBstart+Lcrbs-33]);
      else if (dist100[RBstart+Lcrbs-1]<64)
	alloc_dist2 |= (1<<dist100[RBstart+Lcrbs-65]);
      else
	alloc_dist3 |= (1<<dist100[RBstart+Lcrbs-97]);

      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;
      distRIV2alloc_LUT100_0[RIV]  = alloc_dist0;
      localRIV2alloc_LUT100_1[RIV] = alloc1;
      distRIV2alloc_LUT100_1[RIV]  = alloc_dist1;
      localRIV2alloc_LUT100_2[RIV] = alloc2;
      distRIV2alloc_LUT100_2[RIV]  = alloc_dist2;
      localRIV2alloc_LUT100_3[RIV] = alloc3;
      distRIV2alloc_LUT100_3[RIV]  = alloc_dist3;
      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)


 
uint32_t get_rballoc(uint8_t vrb_type,uint16_t rb_alloc_dci) {

  if (vrb_type == 0)
    return(localRIV2alloc_LUT25[rb_alloc_dci]);
  else
    return(distRIV2alloc_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,PHY_vars_eNB_g[Mod_id][CC_id]);
  DevAssert( UE_id != (unsigned char)-1 );

  return(PHY_vars_eNB_g[Mod_id][CC_id]->transmission_mode[UE_id]);
}

int generate_eNB_dlsch_params_from_dci(uint8_t subframe,
				       void *dci_pdu,
				       uint16_t rnti,
				       DCI_format_t dci_format,
				       LTE_eNB_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,
				       uint16_t DL_pmi_single) {

  uint8_t harq_pid = UINT8_MAX;
  uint32_t rballoc = UINT32_MAX;
  uint32_t RIV_max = 0;
  uint8_t NPRB,tbswap,tpmi=0;
  LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1;
  uint8_t frame_type=frame_parms->frame_type;
  uint8_t vrb_type=0;
  uint8_t mcs=0,mcs1=0,mcs2=0;
  uint8_t I_mcs = 0;
  uint8_t rv=0,rv1=0,rv2=0;
  uint8_t rah=0;
  uint8_t TPC=0;
  LTE_DL_eNB_HARQ_t *dlsch0_harq,*dlsch1_harq;

  //   printf("Generate eNB DCI, format %d, rnti %x (pdu %p)\n",dci_format,rnti,dci_pdu);

  switch (dci_format) {

  case format0:
    return(-1);
    break;
  case format1A:  // This is DLSCH allocation for control traffic

 

    dlsch[0]->subframe_tx[subframe] = 1;


    switch (frame_parms->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;
	TPC      = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; 
	harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;

	//	      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      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;
	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, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }


      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
      if (vrb_type == 0)
	dlsch0_harq->rb_alloc[0]                       = localRIV2alloc_LUT6[rballoc];
      else
	dlsch0_harq->rb_alloc[0]                       = distRIV2alloc_LUT6[rballoc];
      
      dlsch0_harq->nb_rb                               = RIV2nb_rb_LUT6[rballoc];//NPRB;
      RIV_max = RIV_max6;

      
      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;
	TPC      = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC; 
	harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid;

	//      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      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;
	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, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }

      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
      if (vrb_type == 0)
	dlsch0_harq->rb_alloc[0]                       = localRIV2alloc_LUT25[rballoc];
      else
	dlsch0_harq->rb_alloc[0]                       = distRIV2alloc_LUT25[rballoc];
      
      dlsch0_harq->nb_rb                               = RIV2nb_rb_LUT25[rballoc];//NPRB;
      RIV_max = RIV_max25;      
      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;
	TPC      = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC; 
	harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid;

	//      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      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;
	TPC      = ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC; 
	harq_pid = ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid;
	//      printf("FDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }

      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
      if (vrb_type == 0) {
	dlsch0_harq->rb_alloc[0]                       = localRIV2alloc_LUT50_0[rballoc];
	dlsch0_harq->rb_alloc[1]                       = localRIV2alloc_LUT50_1[rballoc];
      }
      else {
	dlsch0_harq->rb_alloc[0]                       = distRIV2alloc_LUT50_0[rballoc];
	dlsch0_harq->rb_alloc[1]                       = distRIV2alloc_LUT50_1[rballoc];
      }
      dlsch0_harq->nb_rb                               = RIV2nb_rb_LUT50[rballoc];//NPRB;
      RIV_max = RIV_max50;
      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;
	TPC      = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC; 
	harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid;
	//      printf("TDD 1A: mcs %d, rballoc %x,rv %d, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }
      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;
	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, NPRB %d\n",mcs,rballoc,rv,NPRB);
      }

      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
      if (vrb_type == 0) {
	dlsch0_harq->rb_alloc[0]                       = localRIV2alloc_LUT100_0[rballoc];
	dlsch0_harq->rb_alloc[1]                       = localRIV2alloc_LUT100_1[rballoc];
	dlsch0_harq->rb_alloc[2]                       = localRIV2alloc_LUT100_2[rballoc];
	dlsch0_harq->rb_alloc[3]                       = localRIV2alloc_LUT100_3[rballoc];
      }
      else {
	dlsch0_harq->rb_alloc[0]                       = distRIV2alloc_LUT100_0[rballoc];
	dlsch0_harq->rb_alloc[1]                       = distRIV2alloc_LUT100_1[rballoc];
	dlsch0_harq->rb_alloc[2]                       = distRIV2alloc_LUT100_2[rballoc];
	dlsch0_harq->rb_alloc[3]                       = distRIV2alloc_LUT100_3[rballoc];
      }
      dlsch0_harq->nb_rb                               = RIV2nb_rb_LUT100[rballoc];//NPRB;
      RIV_max = RIV_max100;
      break;

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

    // harq_pid field is reserved
    if ((rnti==si_rnti) || (rnti==ra_rnti) || (rnti==p_rnti)){  //
      harq_pid=0;
      // see 36-212 V8.6.0 p. 45
      NPRB      = (TPC&1)+2;
      // 36-213 sec.7.1.7.2 p.26
      I_mcs     = mcs;
    }
    else {
      if (harq_pid>1) {
	LOG_E(PHY,"ERROR: Format 1A: harq_pid > 1\n");
	return(-1);
      }
      if (rballoc>RIV_max) {
	LOG_E(PHY,"ERROR: Format 1A: rb_alloc (%x) > RIV_max (%x)\n",rballoc,RIV_max);
	return(-1);
      }
      NPRB      = dlsch0_harq->nb_rb;
      I_mcs     = get_I_TBS(mcs);
    }

    if (NPRB==0)
      return(-1);

    //  printf("NPRB %d, nb_rb %d, ndi %d\n",NPRB,dlsch0_harq->nb_rb,ndi);
    dlsch0_harq->rvidx     = rv; 

    dlsch0_harq->Nl          = 1;
    //dlsch0_harq->layer_index = 0;

    dlsch0_harq->mimo_mode   = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
    /*   
	 if ((rnti!=si_rnti)&&(rnti!=ra_rnti)&&(rnti!=p_rnti)) {  //handle toggling for C-RNTI
	 if (dlsch0_harq->first_tx == 1) {
	 LOG_D(PHY,"First TX for TC-RNTI %x, clearing first_tx flag\n",rnti);
	 dlsch0_harq->first_tx=0;
	 dlsch0_harq->Ndi = 1;
	 } 
	 else {
	 if (ndi == dlsch0_harq->DCINdi)
	 dlsch0_harq->Ndi         = 0;
	 else
	 dlsch0_harq->Ndi         = 1;
	 }
    
	 dlsch0_harq->DCINdi=ndi;
	 }
	 else {
	 dlsch0_harq->Ndi         = 1;
	 }
    */
    dlsch0_harq->dl_power_off = 1;



    dlsch0_harq->mcs           = mcs;
    dlsch0_harq->TBS           = TBStable[I_mcs][NPRB-1];

    dlsch[0]->current_harq_pid   = harq_pid;
    dlsch[0]->harq_ids[subframe] = harq_pid;

    dlsch[0]->active = 1;
    dlsch0 = dlsch[0];

    dlsch[0]->rnti = rnti;

    dlsch[0]->harq_ids[subframe] = harq_pid;
    if (dlsch0_harq->round == 0)
      dlsch0_harq->status = ACTIVE;

    break;
  case format1:

    switch (frame_parms->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;
	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;
	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;
	harq_pid  = ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid;
	LOG_D(PHY,"eNB: subframe %d UE %x, Format1 DCI: ndi %d, harq_pid %d\n",subframe,rnti,((DCI1_5MHz_TDD_t *)dci_pdu)->ndi,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;
	harq_pid = ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid;
	LOG_D(PHY,"eNB: subframe %d UE %x, Format1 DCI: ndi %d, harq_pid %d\n",subframe,rnti,((DCI1_5MHz_FDD_t *)dci_pdu)->ndi,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;
	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;
	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;
	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;
	harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;

    }

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

    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];

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

    conv_rballoc(rah,
		 rballoc,frame_parms->N_RB_DL,
		 dlsch0_harq->rb_alloc);

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

    NPRB      = dlsch0_harq->nb_rb;


    if (NPRB==0)
      return(-1);


    dlsch0_harq->rvidx       = rv;

    dlsch0_harq->Nl          = 1;
    //    dlsch[0]->layer_index = 0;
    dlsch0_harq->mimo_mode   = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
    dlsch0_harq->dl_power_off = 1;
    /*
      if (dlsch[0]->harq_processes[harq_pid]->first_tx == 1) {
      LOG_D(PHY,"First TX for C-RNTI %x, clearing first_tx flag, shouldn't happen!\n",rnti);
      dlsch[0]->harq_processes[harq_pid]->first_tx=0;
      dlsch[0]->harq_processes[harq_pid]->Ndi = 1;
      } 
      else {
      LOG_D(PHY,"Checking for Toggled Ndi for C-RNTI %x, old value %d, DCINdi %d\n",rnti,dlsch[0]->harq_processes[harq_pid]->DCINdi,ndi);
      if (ndi == dlsch[0]->harq_processes[harq_pid]->DCINdi)
      dlsch[0]->harq_processes[harq_pid]->Ndi         = 0;
      else
      dlsch[0]->harq_processes[harq_pid]->Ndi         = 1;
      }
      dlsch[0]->harq_processes[harq_pid]->DCINdi=ndi;
    */

    dlsch[0]->active = 1;



    if (dlsch0_harq->round == 0) {
      dlsch0_harq->status = ACTIVE;
      //            printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
      // MCS and TBS don't change across HARQ rounds
      dlsch0_harq->mcs         = mcs;
      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][NPRB-1];

    }


    dlsch[0]->current_harq_pid = harq_pid;
    dlsch[0]->harq_ids[subframe] = harq_pid;



    dlsch0 = dlsch[0];

    dlsch[0]->rnti = rnti;


    break;

  case format2:

    switch (frame_parms->N_RB_DL) {

    case 6:
      if (frame_parms->nb_antennas_tx == 2) {
	if (frame_type == TDD) {
	  mcs1      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
	  mcs2      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
	  rballoc   = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
	  rv1       = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1;
	  rv2       = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2;
	  harq_pid  = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
	  tpmi      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
	}
	else {
	  mcs1      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
	  mcs2      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
	  rballoc   = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
	  rv1       = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1;
	  rv2       = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2;
	  harq_pid  = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
	  tpmi      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
	}
      }
      else if (frame_parms->nb_antennas_tx == 4) {
	if (frame_type == TDD) {
	  mcs1      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
	  mcs2      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
	  rballoc   = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
	  rv1       = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv1;
	  rv2       = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv2;
	  harq_pid  = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
	  tpmi      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
	}
	else {
	  mcs1      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
	  mcs2      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
	  rballoc   = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
	  rv1       = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv1;
	  rv2       = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv2;
	  harq_pid  = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
	  tpmi      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx);
      }
      break;
    case 25:
      if (frame_parms->nb_antennas_tx == 2) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else if (frame_parms->nb_antennas_tx == 4) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx);
      }      
      break;
    case 50:
      if (frame_parms->nb_antennas_tx == 2) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else if (frame_parms->nb_antennas_tx == 4) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx);
      }
      break;

    case 100:
      if (frame_parms->nb_antennas_tx == 2) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else if (frame_parms->nb_antennas_tx == 4) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx);
      }
      break;
    }


    if (harq_pid>=8) {
      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n");
      return(-1);
    }


    // 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
    if (tbswap == 0) {
      dlsch0 = dlsch[0];
      dlsch1 = dlsch[1];
    }
    else{
      dlsch0 = dlsch[1];
      dlsch1 = dlsch[0];
    }

    dlsch0_harq = dlsch0->harq_processes[harq_pid];
    dlsch1_harq = dlsch1->harq_processes[harq_pid];

    dlsch0->subframe_tx[subframe] = 1;

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


    conv_rballoc(rah,
		 rballoc,
		 frame_parms->N_RB_DL,
		 dlsch0_harq->rb_alloc);

    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];
    dlsch0_harq->nb_rb                               = conv_nprb(rah,
								 rballoc,
								 frame_parms->N_RB_DL);
    dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;

    if (dlsch0_harq->nb_rb == 0)
      return(-1);

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

    // assume both TBs are active
    dlsch0_harq->Nl        = 1;
    dlsch1_harq->Nl        = 1;
    dlsch0->active = 1;
    dlsch1->active = 1;


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

    if (frame_parms->nb_antennas_tx == 2) {
      if (dlsch1->active == 1) { // both TBs are active
	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];
	switch (tpmi) {
	case 0:
	  dlsch0_harq->mimo_mode   = UNIFORM_PRECODING11;
	  dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1m1;
	  dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,0);
	  dlsch1_harq->pmi_alloc                             = pmi_extend(frame_parms,1);
	  break;
	case 1:
	  dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
	  dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1mj;
	  dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,2);
	  dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,3);
	  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;
	}
	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];
      }
      else { // only one is active
	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);
	  break;
	case 2:
	  dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
	  dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,1);
	  break;
	case 3:
	  dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
	  dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,2);
	  break;
	case 4:
	  dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
	  dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,3);
	  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;
	}
	dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
      }
    }
    else if (frame_parms->nb_antennas_tx == 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;
    }

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

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

    break;

  case format2A:

    switch (frame_parms->N_RB_DL) {

    case 6:
      if (frame_parms->nb_antennas_tx == 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;
	  harq_pid  = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
	}
	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;
	  harq_pid  = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
	}
      }
      else if (frame_parms->nb_antennas_tx == 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;
	  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;
	}
	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;
	  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;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx);
      }
      break;
    case 25:
      if (frame_parms->nb_antennas_tx == 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;
	  harq_pid  = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
	}
	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;
	  harq_pid  = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
	}
      }
      else if (frame_parms->nb_antennas_tx == 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;
	  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;
	}
	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;
	  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;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx);
      }      
      break;
    case 50:
      if (frame_parms->nb_antennas_tx == 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;
	  harq_pid  = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap;
	}
	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;
	  harq_pid  = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap;
	}
      }
      else if (frame_parms->nb_antennas_tx == 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;
	  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;
	}
	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;
	  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;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx);
      }
      break;

    case 100:
      if (frame_parms->nb_antennas_tx == 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;
	  harq_pid  = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap;
	}
	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;
	  harq_pid  = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap;
	}
      }
      else if (frame_parms->nb_antennas_tx == 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;
	  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;
	}
	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;
	  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;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx);
      }
      break;
    }


    if (harq_pid>=8) {
      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n");
      return(-1);
    }


    // 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
    if (tbswap == 0) {
      dlsch0 = dlsch[0];
      dlsch1 = dlsch[1];
    }
    else{
      dlsch0 = dlsch[1];
      dlsch1 = dlsch[0];
    }

    dlsch0_harq = dlsch0->harq_processes[harq_pid];
    dlsch1_harq = dlsch1->harq_processes[harq_pid];

    dlsch0->subframe_tx[subframe] = 1;

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


    conv_rballoc(rah,
		 rballoc,
		 frame_parms->N_RB_DL,
		 dlsch0_harq->rb_alloc);

    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];
    dlsch0_harq->nb_rb                               = conv_nprb(rah,
								 rballoc,
								 frame_parms->N_RB_DL);
    dlsch1_harq->nb_rb                               = dlsch0_harq->nb_rb;

    if (dlsch0_harq->nb_rb == 0)
      return(-1);

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

    // assume both TBs are active
    dlsch0_harq->Nl        = 1;
    dlsch1_harq->Nl        = 1;
    dlsch0->active = 1;
    dlsch1->active = 1;


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

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


    if (frame_parms->nb_antennas_tx == 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 (frame_parms->nb_antennas_tx == 4) { // 4 antenna case
      if ((dlsch0->active==1) && (dlsch1->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->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 (frame_parms->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 (tpmi) {
	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",tpmi); 
	  break;
	}
      }
      else if (dlsch1->active == 1) {
	switch (tpmi) {
	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",tpmi); 
	  break;
	}
      }
    }
    else {
      LOG_E(PHY,"Illegal number of antennas for eNB %d\n",frame_parms->nb_antennas_tx);
    }
  
    // 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 = rnti;
    dlsch1->rnti = rnti;


    //    printf("eNB: Format 2A TBS0 %d, TBS1 %d\n",dlsch0_harq->TBS,dlsch1_harq->TBS);

    break;

  case format2B:

    switch (frame_parms->N_RB_DL) {

    case 6:
      if (frame_type == TDD) {
	mcs1      = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->rballoc;
	rv1       = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2B_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->rballoc;
	rv1       = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2B_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;
    case 25:
      if (frame_type == TDD) {
	mcs1      = ((DCI2B_5MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2B_5MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2B_5MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2B_5MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2B_5MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2B_5MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2B_5MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2B_5MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;
    case 50:
      if (frame_type == TDD) {
	mcs1      = ((DCI2B_10MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2B_10MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2B_10MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2B_10MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2B_10MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2B_10MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2B_10MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2B_10MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;

    case 100:
      if (frame_type == TDD) {
	mcs1      = ((DCI2B_20MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2B_20MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2B_20MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2B_20MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2B_20MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2B_20MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2B_20MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2B_20MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;
    }


    if (harq_pid>=8) {
      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n");
      return(-1);
    }



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


    dlsch0->subframe_tx[subframe] = 1;

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


    dlsch0_harq = dlsch0->harq_processes[harq_pid];
    dlsch1_harq = dlsch1->harq_processes[harq_pid];

    conv_rballoc(rah,
		 rballoc,
		 frame_parms->N_RB_DL,
		 dlsch0_harq->rb_alloc);
    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];

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

    dlsch0_harq->mcs       = mcs1;
    dlsch1_harq->mcs       = mcs2;
    dlsch0_harq->rvidx     = rv1;
    dlsch1_harq->rvidx     = 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;


    if (dlsch0_harq->round == 0) {
      dlsch0_harq->status = ACTIVE;
      //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
    }

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

    dlsch0->active = 1;

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

    dlsch0_harq->dl_power_off = 1;
    dlsch1_harq->dl_power_off = 1;

    break;

  case format2C:

    switch (frame_parms->N_RB_DL) {

    case 6:
      if (frame_type == TDD) {
	mcs1      = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->rballoc;
	rv1       = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2C_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->rballoc;
	rv1       = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2C_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;
    case 25:
      if (frame_type == TDD) {
	mcs1      = ((DCI2C_5MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2C_5MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2C_5MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2C_5MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2C_5MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2C_5MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2C_5MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2C_5MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;
    case 50:
      if (frame_type == TDD) {
	mcs1      = ((DCI2C_10MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2C_10MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2C_10MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2C_10MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2C_10MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2C_10MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2C_10MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2C_10MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;

    case 100:
      if (frame_type == TDD) {
	mcs1      = ((DCI2C_20MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2C_20MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2C_20MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2C_20MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2C_20MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2C_20MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2C_20MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2C_20MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;
    }


    if (harq_pid>=8) {
      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n");
      return(-1);
    }



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

    dlsch0->subframe_tx[subframe] = 1;

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

    dlsch0_harq = dlsch0->harq_processes[harq_pid];
    dlsch1_harq = dlsch1->harq_processes[harq_pid];

    conv_rballoc(rah,
		 rballoc,
		 frame_parms->N_RB_DL,
		 dlsch0_harq->rb_alloc);
    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];

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

    if (dlsch0_harq->nb_rb == 0)
      return(-1);

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

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


    if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) {
      dlsch0->active = 0;
    }
    if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) {
      dlsch1->active = 0;
    }



    if ((dlsch0_harq->round == 0) && (dlsch0->active == 1) ) {
      dlsch0_harq->status      = ACTIVE;
      dlsch0_harq->mcs         = mcs1;
    }

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

    // check TPMI information to compute TBS
    if (frame_parms->nb_antennas_tx == 2) {
      if (dlsch1->active == 1) { // both TBs are active
	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];
      }
      else {
	dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
      }
    }
    else if (frame_parms->nb_antennas_tx == 4) {

    }

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

    dlsch0_harq->dl_power_off = 1;
    dlsch1_harq->dl_power_off = 1;

    break;

  case format2D:

    switch (frame_parms->N_RB_DL) {

    case 6:
      if (frame_type == TDD) {
	mcs1      = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->rballoc;
	rv1       = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2D_1_5MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->rballoc;
	rv1       = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2D_1_5MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;
    case 25:
      if (frame_type == TDD) {
	mcs1      = ((DCI2D_5MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2D_5MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2D_5MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2D_5MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2D_5MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2D_5MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2D_5MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2D_5MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;
    case 50:
      if (frame_type == TDD) {
	mcs1      = ((DCI2D_10MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2D_10MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2D_10MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2D_10MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2D_10MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2D_10MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2D_10MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2D_10MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;

    case 100:
      if (frame_type == TDD) {
	mcs1      = ((DCI2D_20MHz_TDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2D_20MHz_TDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2D_20MHz_TDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2D_20MHz_TDD_t *)dci_pdu)->harq_pid;
      }
      else {
	mcs1      = ((DCI2D_20MHz_FDD_t *)dci_pdu)->mcs1;
	mcs2      = ((DCI2D_20MHz_FDD_t *)dci_pdu)->mcs2;
	rballoc   = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rballoc;
	rah       = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rah;
	rv1       = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rv1;
	rv2       = ((DCI2D_20MHz_FDD_t *)dci_pdu)->rv2;
	harq_pid  = ((DCI2D_20MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;
    }


    if (harq_pid>=8) {
      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n");
      return(-1);
    }



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

    dlsch0->subframe_tx[subframe] = 1;

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


    dlsch0_harq = dlsch0->harq_processes[harq_pid];
    dlsch1_harq = dlsch1->harq_processes[harq_pid];

    conv_rballoc(rah,
		 rballoc,
		 frame_parms->N_RB_DL,
		 dlsch0_harq->rb_alloc);
    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];

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

    dlsch0_harq->mcs       = mcs1;
    dlsch1_harq->mcs       = mcs2;
    dlsch0_harq->rvidx     = rv1;
    dlsch1_harq->rvidx     = 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;


    if (dlsch0_harq->round == 0) {
      dlsch0_harq->status = ACTIVE;
      //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
    }

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

    dlsch0->active = 1;

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

    dlsch0_harq->dl_power_off = 1;
    dlsch1_harq->dl_power_off = 1;

    break;


  case format1E_2A_M10PRB:

    harq_pid  = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid;
    if (harq_pid>=8) {
      LOG_E(PHY,"ERROR: Format 1E_2A_M10PRB: harq_pid >= 8\n");
      return(-1);
    }

    /*
      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->subframe_tx[subframe] = 1;

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

    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);
		 
    //dlsch1->rb_alloc[0]                         = dlsch0->rb_alloc[0];

    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->nb_rb                               = dlsch0->nb_rb;

    dlsch0_harq->mcs       = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs;
    //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) --> only for format 2 and 2A

    //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;

    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);
      break;
    case 2:
      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
      dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,1);
      break;
    case 3:
      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
      dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,2);
      break;
    case 4:
      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
      dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,3);
      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;
      return(-1);
      break;
    }

    //    printf("Set pmi %x (tpmi %d)\n",dlsch0->pmi_alloc,tpmi);


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

    //    dlsch0_harq->Ndi         = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi;
    if (dlsch0_harq->round == 0) {
      dlsch0_harq->status = ACTIVE;
      //      printf("Setting DLSCH process %d to ACTIVE\n",harq_pid);
    }

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

    dlsch0->active = 1;

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

    //    dlsch0->dl_power_off = 1;
    dlsch0_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off;
    //dlsch1->dl_power_off = 1;

    break;
  default:
    LOG_E(PHY,"Unknown DCI format\n");
    return(-1);
    break;
  }
#ifdef DEBUG_DCI
  if (dlsch0) {
    msg("dlsch0 eNB: dlsch0   %p\n",dlsch0);
    msg("dlsch0 eNB: rnti     %x\n",dlsch0->rnti);
    msg("dlsch0 eNB: NBRB     %d\n",dlsch0_harq->nb_rb);
    msg("dlsch0 eNB: rballoc  %x\n",dlsch0_harq->rb_alloc[0]);
    msg("dlsch0 eNB: harq_pid %d\n",harq_pid);
    msg("dlsch0 eNB: round    %d\n",dlsch0_harq->round);
    msg("dlsch0 eNB: rvidx    %d\n",dlsch0_harq->rvidx);
    msg("dlsch0 eNB: TBS      %d (NPRB %d)\n",dlsch0_harq->TBS,NPRB);
    msg("dlsch0 eNB: mcs      %d\n",dlsch0_harq->mcs);
    msg("dlsch0 eNB: tpmi %d\n",tpmi);
    msg("dlsch0 eNB: mimo_mode %d\n",dlsch0_harq->mimo_mode);
  }
#endif

  // compute DL power control parameters   
  computeRhoA_eNB(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off);
  
  computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[0],dlsch0_harq->dl_power_off);

  return(0);
}


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:
	msg("DCI format1A (TDD1-6, 1_5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
	msg("VRB_TYPE %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
	msg("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]);
	msg("MCS %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
	msg("HARQ_PID %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
	msg("NDI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
	msg("RV %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
	msg("TPC %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
	msg("DAI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai);
	break;
      case 25:
	msg("DCI format1A (TDD1-6, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
	msg("VRB_TYPE %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
	msg("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]);
	msg("MCS %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
	msg("HARQ_PID %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
	msg("NDI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
	msg("RV %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
	msg("TPC %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
	msg("DAI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai);
	break;
      case 50:
	msg("DCI format1A (TDD1-6, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
	msg("VRB_TYPE %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
	msg("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]);
	msg("MCS %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
	msg("HARQ_PID %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
	msg("NDI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
	msg("RV %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
	msg("TPC %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
	msg("DAI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai);
	break;
      case 100:
	msg("DCI format1A (TDD1-6, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
	msg("VRB_TYPE %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type);
	msg("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]);
	msg("MCS %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs);
	msg("HARQ_PID %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid);
	msg("NDI %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi);
	msg("RV %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv);
	msg("TPC %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC);
	msg("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:
	msg("DCI format1A(FDD, 1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
	msg("VRB_TYPE %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
	msg("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]);
	msg("MCS %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
	msg("HARQ_PID %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
	msg("NDI %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
	msg("RV %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv);
	msg("TPC %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
	break;
      case 25:
	msg("DCI format1A(FDD, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
	msg("VRB_TYPE %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
	msg("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]);
	msg("MCS %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
	msg("HARQ_PID %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
	msg("NDI %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
	msg("RV %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rv);
	msg("TPC %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
	break;
      case 50:
	msg("DCI format1A(FDD, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
	msg("VRB_TYPE %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
	msg("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]);
	msg("MCS %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
	msg("HARQ_PID %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
	msg("NDI %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
	msg("RV %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rv);
	msg("TPC %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC);
	break;
      case 100:
	msg("DCI format1A(FDD, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]);
	msg("VRB_TYPE %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type);
	msg("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]);
	msg("MCS %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs);
	msg("HARQ_PID %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid);
	msg("NDI %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi);
	msg("RV %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rv);
	msg("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 format2:

    if ((frame_parms->frame_type == TDD) &&
	(frame_parms->tdd_config>0)) {
      if (frame_parms->nb_antennas_tx == 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, harq_pid %d, ndi %d, RV %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, harq_pid %d, ndi %d, RV %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, harq_pid %d, ndi %d, RV %d, TPC %d, dai %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, harq_pid %d, ndi %d, RV %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_antennas_tx == 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, harq_pid %d, ndi %d, RV %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, harq_pid %d, ndi %d, RV %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, harq_pid %d, ndi %d, RV %d, TPC %d, dai %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, harq_pid %d, ndi %d, RV %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_antennas_tx == 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, mcs %d, harq_pid %d, ndi %d, RV %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, harq_pid %d, ndi %d, RV %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, harq_pid %d, ndi %d, RV %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_antennas_tx == 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, harq_pid %d, ndi %d, RV %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, harq_pid %d, ndi %d, RV %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, harq_pid %d, ndi %d, RV %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_antennas_tx_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 (%llx): 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 (%llx): 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 (%llx): 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_antennas_tx_eNB == 4) {
	switch(frame_parms->N_RB_DL) {
	case 6:
	  LOG_D(PHY,"DCI format2A 4 antennas (TDD 1.5 MHz), rnti %x (%llx): 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 (%llx): 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 (%llx): 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 (%llx): 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_antennas_tx_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 (%llx): 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 (%llx): 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 (%llx): 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_antennas_tx_eNB == 4) {
	switch(frame_parms->N_RB_DL) {
	  
	case 6:
	  LOG_D(PHY,"DCI format2A 4 antennas (FDD, 1.5 MHz), rnti %x (%llx): 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 (%llx): 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 (%llx): 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 (%llx): 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);
}


int generate_ue_dlsch_params_from_dci(uint8_t subframe,
                                      void *dci_pdu,
                                      uint16_t rnti,
                                      DCI_format_t dci_format,
                                      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 harq_pid=0;
  uint32_t rballoc=0,RIV_max;
  uint8_t frame_type=frame_parms->frame_type;
  uint8_t vrb_type=0;
  uint8_t mcs=0,mcs1=0,mcs2=0;
  uint8_t rv=0,rv1=0,rv2=0;
  uint8_t ndi=0,ndi1=0,ndi2=0;
  uint8_t rah=0;
  uint8_t TPC=0;
  uint8_t NPRB=0,tbswap=0,tpmi=0;
  LTE_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL;
  LTE_DL_UE_HARQ_t *dlsch0_harq,*dlsch1_harq;

#ifdef DEBUG_DCI
  msg("dci_tools.c: Filling ue dlsch params -> rnti %x, dci_format %d\n",rnti,dci_format);
#endif

  switch (dci_format) {

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

    switch (frame_parms->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;
	//	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);
      }

      if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)){  //
	harq_pid = 0;
	dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
	// see 36-212 V8.6.0 p. 45
	NPRB = (TPC&1) + 2;
      }
      else {
                
	if (harq_pid>1) {
	  LOG_E(PHY,"Format 1A: harq_pid > 1\n");
	  return(-1);
	}
	dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
	NPRB = RIV2nb_rb_LUT6[rballoc];            
	dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];      
      }
            
      if (vrb_type == 0)
	dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT6[rballoc];
      else
	dlsch0_harq->rb_alloc[0] = distRIV2alloc_LUT6[rballoc];
            
      dlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rballoc];//NPRB;
      RIV_max = RIV_max6;
            
      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;
	//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);
      }

      if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)){  //
	harq_pid = 0;
	// see 36-212 V8.6.0 p. 45
	NPRB = (TPC&1) + 2;
	dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
      }
      else {
                
	if (harq_pid>1) {
	  LOG_E(PHY,"Format 1A: harq_pid > 1\n");
	  return(-1);
	}
	dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
	NPRB = RIV2nb_rb_LUT25[rballoc];            
	dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];      
      }

      if (vrb_type == 0)
	dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT25[rballoc];
      else
	dlsch0_harq->rb_alloc[0] = distRIV2alloc_LUT25[rballoc];
            
      dlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc];//NPRB;
      RIV_max = RIV_max25;    
            
      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;
	//	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, rballoc %x,ndi %d, rv %d, TPC %d\n",mcs,rballoc,ndi,rv,TPC);
      }
            
      if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)){  //
	harq_pid = 0;
	dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
	// see 36-212 V8.6.0 p. 45
	NPRB = (TPC&1) + 2;
      }
      else {
                
	if (harq_pid>1) {
	  LOG_E(PHY,"Format 1A: harq_pid > 1\n");
	  return(-1);
	}
	dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
	NPRB = RIV2nb_rb_LUT50[rballoc];            
	dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];      
      }

      if (vrb_type == 0) {
	dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT50_0[rballoc];
	dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT50_1[rballoc];
      }
      else {
	dlsch0_harq->rb_alloc[0] = distRIV2alloc_LUT50_0[rballoc];
	dlsch0_harq->rb_alloc[1] = distRIV2alloc_LUT50_1[rballoc];
      }
      dlsch0_harq->nb_rb  = RIV2nb_rb_LUT50[rballoc];//NPRB;
      RIV_max = RIV_max50;
      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;
	//	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);
      }

      if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)){  //
	harq_pid = 0;
	dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
	// see 36-212 V8.6.0 p. 45
	NPRB = (TPC&1) + 2;
	// toggle the ndi 
      }
      else {
                
	if (harq_pid>1) {
	  LOG_E(PHY,"Format 1A: harq_pid > 1\n");
	  return(-1);
	}
	dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
	NPRB = RIV2nb_rb_LUT100[rballoc];            
	dlsch0_harq->delta_PUCCH = delta_PUCCH_lut[TPC&3];      
      }

      if (vrb_type == 0) {
	dlsch0_harq->rb_alloc[0] = localRIV2alloc_LUT100_0[rballoc];
	dlsch0_harq->rb_alloc[1] = localRIV2alloc_LUT100_1[rballoc];
	dlsch0_harq->rb_alloc[2] = localRIV2alloc_LUT100_2[rballoc];
	dlsch0_harq->rb_alloc[3] = localRIV2alloc_LUT100_3[rballoc];
      }
      else {
	dlsch0_harq->rb_alloc[0] = distRIV2alloc_LUT100_0[rballoc];
	dlsch0_harq->rb_alloc[1] = distRIV2alloc_LUT100_1[rballoc];
	dlsch0_harq->rb_alloc[2] = distRIV2alloc_LUT100_2[rballoc];
	dlsch0_harq->rb_alloc[3] = distRIV2alloc_LUT100_3[rballoc];
      }
      dlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rballoc];//NPRB;
      RIV_max = RIV_max100;
      break;
    }
        
    if (rballoc>RIV_max) {
      LOG_E(PHY,"Format 1A: rb_alloc > RIV_max\n");
      return(-1);
    }
            
    if (NPRB==0) {
      LOG_E(PHY,"Format 1A: NPRB=0\n");
      return(-1);
    }
    // change the mcs limit from 7 to 8, supported by MAC
    if (mcs > 10) {
      LOG_E(PHY,"Format 1A: unlikely mcs for format 1A (%d)\n",mcs);
      return(-1);
    } 

    if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)){  //
      // toggle the ndi, always toggled for si,p and ra 
      ndi  = 1-dlsch0_harq->DCINdi;
    }

    dlsch[0]->current_harq_pid = harq_pid;
    //    msg("Format 1A: harq_pid %d\n",harq_pid);        
    dlsch0_harq->rvidx = rv;        
    dlsch0_harq->Nl = 1;
    //    dlsch[0]->layer_index = 0;
    dlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI;
    dlsch0_harq->dl_power_off = 1; //no power offset

    LOG_D(PHY,"UE (%x/%d): Subframe %d Format1A DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d\n",dlsch[0]->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi,
	  dlsch0_harq->first_tx,dlsch0_harq->status);
    if ((rnti != si_rnti) && (rnti!=ra_rnti)) { 
    if ((ndi!=dlsch0_harq->DCINdi)||  // DCI has been toggled or this is the first transmission
	(dlsch0_harq->first_tx==1)) {
      dlsch0_harq->round = 0;
      if (dlsch0_harq->first_tx==1) {
	LOG_I(PHY,"[PDSCH %x/%d] Format 1A DCI First TX: Clearing flag\n");
	dlsch0_harq->first_tx = 0;
      }
    }
    }
    dlsch0_harq->DCINdi = ndi;

    dlsch0_harq->mcs = mcs;        
    dlsch0_harq->TBS = TBStable[get_I_TBS(mcs)][NPRB-1];        
    dlsch[0]->rnti = rnti;        
    dlsch0 = dlsch[0];
    break;

  case format1:

    switch (frame_parms->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;
	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;
	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;
	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;
	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;
	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;
	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;
	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;
	ndi      = ((DCI1_20MHz_FDD_t *)dci_pdu)->ndi;
	harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid;
      }
      break;
    }
    if (harq_pid>=8) {
      LOG_E(PHY,"Format 1: harq_pid >= 8\n");
      return(-1);
    }
    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
    dlsch[0]->current_harq_pid = harq_pid;
    dlsch[0]->harq_ack[subframe].harq_id = harq_pid;

    conv_rballoc(rah,rballoc,frame_parms->N_RB_DL,dlsch0_harq->rb_alloc);

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

    NPRB = dlsch0_harq->nb_rb;

    //    printf("test PDSCH NPRB %d, rah %d, rballoc %x, rballoc2 %x\n",NPRB,rah,rballoc,dlsch0_harq->rb_alloc[0]);

    if (NPRB==0) {
      LOG_E(PHY,"Format 1: NPRB=0 (rballoc %x,mcs %d, frame_type %d N_RB_DL %d)\n",rballoc,mcs,frame_parms->frame_type,frame_parms->N_RB_DL);
      return(-1);
    }

    //    printf("NPRB %d\n",NPRB);
    dlsch0_harq->delta_PUCCH     = delta_PUCCH_lut[TPC&3];      

    dlsch0_harq->rvidx     = rv;

    dlsch0_harq->Nl          = 1;
    //    dlsch[0]->layer_index = 0;

    dlsch0_harq->dl_power_off = 1; //no power offset

    LOG_D(PHY,"UE (%x/%d): Subframe %d Format2 DCI: ndi %d, old_ndi %d (first tx %d) harq_status %d\n",dlsch[0]->rnti,harq_pid,subframe,ndi,dlsch0_harq->DCINdi,
	  dlsch0_harq->first_tx,dlsch0_harq->status);

    //    printf("Format2 DCI (UE, hard pid %d): ndi %d, old_ndi %d (first tx %d)\n",harq_pid,ndi,dlsch0_harq->DCINdi,
    //	  dlsch0_harq->first_tx);
    
    if ((ndi!=dlsch0_harq->DCINdi)||
	(dlsch0_harq->first_tx==1)) {
      //    printf("Rate: setting round to zero (ndi %d, DCINdi %d,first_tx %d)\n",ndi,dlsch0_harq->DCINdi,dlsch0_harq->first_tx);
      dlsch0_harq->round=0;
      dlsch0_harq->status = ACTIVE;
      dlsch0_harq->DCINdi = ndi;
      if (dlsch0_harq->first_tx==1) {
	LOG_D(PHY,"[PDSCH %x/%d] Format 1 DCI First TX: Clearing flag\n");
	dlsch0_harq->first_tx = 0;
      }
    }
    else if (dlsch0_harq->status == SCH_IDLE) {  // we got an Ndi = 0 for a previously decoded process,
      // this happens if either another harq process in the same
      // is NAK or an ACK was not received

      dlsch[0]->harq_ack[subframe].ack              = 1;
      dlsch[0]->harq_ack[subframe].harq_id          = harq_pid;
      dlsch[0]->harq_ack[subframe].send_harq_status = 1;
      dlsch[0]->active = 0;
      //     printf("Got NDI=0 for correctly decoded SDU (harq_pid %d) subframe %d\n",harq_pid,subframe);
      return(0);
    }
    dlsch0_harq->mcs         = mcs;

    dlsch0_harq->TBS         = TBStable[get_I_TBS(mcs)][NPRB-1];
    //    msg("test: MCS %d, NPRB %d, TBS %d\n",mcs,NPRB,dlsch0_harq->TBS);
    dlsch[0]->current_harq_pid = harq_pid;

    dlsch[0]->active = 1;

    dlsch[0]->rnti = rnti;

    dlsch0_harq->mimo_mode   = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;

    dlsch0 = dlsch[0];

    break;

  case format2:
    switch (frame_parms->N_RB_DL) {

    case 6:
      if (frame_parms->nb_antennas_tx_eNB == 2) {
	if (frame_type == TDD) {
	  mcs1      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
	  mcs2      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
	  rballoc   = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
	  rv1       = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv1;
	  rv2       = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->rv2;
	  harq_pid  = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap;
	  tpmi      = ((DCI2_1_5MHz_2A_TDD_t *)dci_pdu)->tpmi;
	}
	else {
	  mcs1      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1;
	  mcs2      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2;
	  rballoc   = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc;
	  rv1       = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv1;
	  rv2       = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->rv2;
	  harq_pid  = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap;
	  tpmi      = ((DCI2_1_5MHz_2A_FDD_t *)dci_pdu)->tpmi;
	}
      }
      else if (frame_parms->nb_antennas_tx_eNB == 4) {
	if (frame_type == TDD) {
	  mcs1      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
	  mcs2      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
	  rballoc   = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
	  rv1       = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv1;
	  rv2       = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->rv2;
	  harq_pid  = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap;
	  tpmi      = ((DCI2_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi;
	}
	else {
	  mcs1      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1;
	  mcs2      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2;
	  rballoc   = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc;
	  rv1       = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv1;
	  rv2       = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->rv2;
	  harq_pid  = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid;
	  tbswap    = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap;
	  tpmi      = ((DCI2_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi;
	}
      }
      else {
	LOG_E(PHY,"UE: subframe %d Format2 DCI: unsupported number of TX antennas %d\n",subframe,frame_parms->nb_antennas_tx_eNB);
      }
      break;
    case 25:
      if (frame_parms->nb_antennas_tx_eNB == 2) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else if (frame_parms->nb_antennas_tx_eNB == 4) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else {
	LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB);
      }      
      break;
    case 50:
      if (frame_parms->nb_antennas_tx_eNB == 2) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else if (frame_parms->nb_antennas_tx_eNB == 4) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else {
	LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB);
      }
      break;

    case 100:
      if (frame_parms->nb_antennas_tx_eNB == 2) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else if (frame_parms->nb_antennas_tx_eNB == 4) {
	if (frame_type == TDD) {
	  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;
	  rah       = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah;
	  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;
	}
	else {
	  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;
	  rah       = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah;
	  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;
	}
      }
      else {
	LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",frame_parms->nb_antennas_tx_eNB);
      }
      break;
    }

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


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

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

    dlsch0_harq = dlsch0->harq_processes[harq_pid];
    dlsch1_harq = dlsch1->harq_processes[harq_pid];
    conv_rballoc(rah,
		 rballoc,
		 frame_parms->N_RB_DL,
		 dlsch0_harq->rb_alloc);
    dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];

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

    dlsch0_harq->mcs       = mcs1;

    dlsch0_harq->delta_PUCCH     = delta_PUCCH_lut[TPC&3];      
    /*
      if (dlsch0_harq->mcs>20) {
      msg("dci_tools.c: mcs > 20 disabled for now (asked %d)\n",dlsch0_harq->mcs);
      return(-1);
      }
    */

    dlsch1_harq->mcs       = mcs2;
    dlsch0_harq->rvidx     = rv1;
    dlsch1_harq->rvidx     = 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;

    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);
      break;
    case 2:
      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
      dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,1);
      break;
    case 3:
      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
      dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,2);
      break;
    case 4:
      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
      dlsch0_harq->pmi_alloc                             = pmi_extend(frame_parms,3);
      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->mode1_flag == 1)
      dlsch0_harq->mimo_mode   = SISO;
    if (ndi1!=dlsch0_harq->DCINdi) {
      dlsch0_harq->round = 0;
      dlsch0_harq->status = ACTIVE;
      dlsch0_harq->DCINdi         = ndi1;
    }      
    else if (dlsch0_harq->status == SCH_IDLE) {  // we got an Ndi = 0 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->mcs         = mcs1;
    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;
    /*
      if (dlsch0_harq->mcs > 18)
      printf("mcs %d, TBS %d\n",dlsch0_harq->mcs,dlsch0_harq->TBS);
    */

    if (dlsch1_harq->DCINdi != ndi2) {
      dlsch1_harq->round=0;
      dlsch1_harq->status = ACTIVE;
    }
    dlsch1_harq->DCINdi      = ndi2;
    dlsch1_harq->mcs         = mcs2;
    if (dlsch1_harq->nb_rb>1) {
      dlsch1_harq->TBS       = TBStable[dlsch1_harq->mcs][dlsch1_harq->nb_rb-1];
    }
    else
      dlsch1_harq->TBS         = 0;

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

    dlsch0_harq->dl_power_off = 1; //no power offset
    dlsch1_harq->dl_power_off = 1; //no power offset

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

    break;

  case format2A:

    switch (frame_parms->N_RB_DL) {

    case 6:
      if (frame_parms->nb_antennas_tx_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;
	}
	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;
	}
      }
      else if (frame_parms->nb_antennas_tx_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;
	}
	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;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx_eNB);
      }
      break;
    case 25:
      if (frame_parms->nb_antennas_tx_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;
	}
	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;
	}
      }
      else if (frame_parms->nb_antennas_tx_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;
	}
	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;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx_eNB);
      }      
      break;
    case 50:
      if (frame_parms->nb_antennas_tx_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;
	}
	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;
	}
      }
      else if (frame_parms->nb_antennas_tx_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;
	}
	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;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx_eNB);
      }
      break;

    case 100:
      if (frame_parms->nb_antennas_tx_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;
	}
	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;
	}
      }
      else if (frame_parms->nb_antennas_tx_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;
	}
	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;
	}
      }
      else {
	LOG_E(PHY,"eNB: subframe %d UE %x, Format2A DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antennas_tx_eNB);
      }
      break;
    }


    if (harq_pid>=8) {
      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid >= 8\n");
      return(-1);
    }

    //    printf("UE: format 2A, rballoc=%x, harq_pid= %d, mcs1=%d,mcs2=%d, rv1=%d, rv2=%d, ndi1=%d, ndi2=%d\n",rballoc, harq_pid, mcs1,mcs2,rv1,rv2,ndi1,ndi2);

    // 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
    if (tbswap == 0) {
      dlsch0 = dlsch[0];
      dlsch1 = dlsch[1];
    }
    else{
      dlsch0 = dlsch[1];
      dlsch1 = dlsch[0];
    }
    
    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
    dlsch1_harq = dlsch[1]->harq_processes[harq_pid];
    dlsch0->current_harq_pid = harq_pid;
    dlsch1->current_harq_pid = harq_pid;
    dlsch0->harq_ack[subframe].harq_id = harq_pid;
    dlsch1->harq_ack[subframe].harq_id = harq_pid;

    conv_rballoc(rah,rballoc,frame_parms->N_RB_DL,dlsch0_harq->rb_alloc);

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

    dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;

    NPRB = dlsch0_harq->nb_rb;


    if (NPRB==0) {
      LOG_E(PHY,"Format 2A: NPRB=0 (rballoc %x,mcs %d, frame_type %d N_RB_DL %d)\n",rballoc,mcs,frame_parms->frame_type,frame_parms->N_RB_DL);
      return(-1);
    }

    //    printf("NPRB %d\n",NPRB);
    dlsch0_harq->delta_PUCCH     = delta_PUCCH_lut[TPC&3];      
    dlsch1_harq->delta_PUCCH     = delta_PUCCH_lut[TPC&3];      

    dlsch0_harq->mcs     = mcs1;
    dlsch1_harq->mcs     = mcs2;

    dlsch0_harq->rvidx     = rv1;
    dlsch1_harq->rvidx     = rv2;



    dlsch0_harq->Nl          = 1;
    dlsch1_harq->Nl          = 1;
    //    dlsch[0]->layer_index = 0;

    dlsch0_harq->dl_power_off = 1; //no power offset
    dlsch1_harq->dl_power_off = 1; //no power offset

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

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


    //    printf("Format2A DCI (UE, hard pid %d): ndi %d, old_ndi %d (first tx %d)\n",harq_pid,ndi,dlsch0_harq->DCINdi,
    //	  dlsch0_harq->first_tx);
    
    if (dlsch0->active == 1) {
      if ((ndi1!=dlsch0_harq->DCINdi)||
	  (dlsch0_harq->first_tx==1)) {
	//      printf("Rate: setting round to zero (ndi %d, DCINdi %d,first_tx %d)\n",ndi,dlsch0_harq->DCINdi,dlsch0_harq->first_tx);
	dlsch0_harq->round=0;
	dlsch0_harq->status = ACTIVE;
	dlsch0_harq->DCINdi = ndi1;
	if (dlsch0_harq->first_tx==1) {
	  LOG_D(PHY,"[PDSCH %x/%d] Format 2A DCI First TX0: Clearing flag\n");
	  dlsch0_harq->first_tx = 0;
	}
      }
      else if (dlsch0_harq->status == SCH_IDLE) {  // we got an Ndi = 0 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;
	//     printf("Got NDI=0 for correctly decoded SDU (harq_pid %d) subframe %d\n",harq_pid,subframe);
      }
    }

    if (dlsch1->active == 1) {
      if ((ndi2!=dlsch1_harq->DCINdi)||
	  (dlsch1_harq->first_tx==1)) {
	dlsch1_harq->round=0;
	dlsch1_harq->status = ACTIVE;
	dlsch1_harq->DCINdi = ndi2;
	
	if (dlsch1_harq->first_tx==1) {
	  LOG_D(PHY,"[PDSCH %x/%d] Format 2A DCI First TX1: Clearing flag\n",rnti,harq_pid);
	  dlsch1_harq->first_tx = 0;
	}

      }
      else if (dlsch1_harq->status == SCH_IDLE) {  // we got an Ndi = 0 for a previously decoded process,
	// this happens if either another harq process in the same
	// is NAK or an ACK was not received
	
	dlsch1->harq_ack[subframe].ack              = 1;
	dlsch1->harq_ack[subframe].harq_id          = harq_pid;
	dlsch1->harq_ack[subframe].send_harq_status = 1;
	dlsch1->active = 0;
	//     printf("Got NDI=0 for correctly decoded SDU (harq_pid %d) subframe %d\n",harq_pid,subframe);
      }
    }

    if (frame_parms->nb_antennas_tx_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 = 0; //apply power offset
	dlsch1_harq->dl_power_off = 0; //apply power offset
      }
      else {
	dlsch0_harq->mimo_mode   = ALAMOUTI;
	dlsch1_harq->mimo_mode   = ALAMOUTI;
      }
    }
    else if (frame_parms->nb_antennas_tx_eNB == 4) { // 4 antenna case
      if ((dlsch0->active==1) && (dlsch1->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 = 0; //apply power offset
	  dlsch1_harq->dl_power_off = 0; //apply power offset
	  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];
	  break;
	case 1: // one-layers on TB 0, two on TB 1
	  dlsch0_harq->mimo_mode   = LARGE_CDD;
	  dlsch1_harq->mimo_mode   = LARGE_CDD;
	  dlsch0_harq->dl_power_off = 0; //apply power offset
	  dlsch1_harq->dl_power_off = 0; //apply power offset
	  dlsch1_harq->Nl          = 2;
	  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
	  dlsch0_harq->mimo_mode   = LARGE_CDD;
	  dlsch1_harq->mimo_mode   = LARGE_CDD;
	  dlsch0_harq->Nl          = 2;
	  dlsch0_harq->dl_power_off = 0; //apply power offset
	  dlsch1_harq->dl_power_off = 0; //apply power offset
	  if (frame_parms->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 (tpmi) {
	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->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",tpmi); 
	  break;
	}
      }
      else if (dlsch1->active == 1) {
	switch (tpmi) {
	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;
	  dlsch0_harq->dl_power_off = 1; //apply power offset
	  dlsch1_harq->dl_power_off = 0; //apply power offset
	  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",tpmi); 
	  break;
	}
      }
    }
    else {
      LOG_E(PHY,"Illegal number of antennas for eNB %d\n",frame_parms->nb_antennas_tx_eNB);
    }
     
    //    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);
    

    break;

  case format1E_2A_M10PRB:

    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 >= 8\n");
      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];
    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);
    //dlsch1_harq->rb_alloc[0]                         = dlsch0_harq->rb_alloc[0];

    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) {
      msg("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;
    //    msg("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);
      break;
    case 2:
      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
      dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1);
      break;
    case 3:
      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
      dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,2);
      break;
    case 4:
      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
      dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,3);
      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->mode1_flag == 1)
      dlsch0_harq->mimo_mode   = SISO;


    if (dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) {
      
      dlsch0_harq->round = 0;
      dlsch0_harq->status = ACTIVE;
    }
    else if (dlsch0_harq->status == SCH_IDLE) {  // we got an Ndi = 0 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 DEBUG_DCI
  if (dlsch[0]) {
    msg("PDSCH dlsch0 UE: rnti     %x\n",dlsch[0]->rnti);
    msg("PDSCH dlsch0 UE: NBRB     %d\n",dlsch0_harq->nb_rb);
    msg("PDSCH dlsch0 UE: rballoc  %x\n",dlsch0_harq->rb_alloc[0]);
    msg("PDSCH dlsch0 UE: harq_pid %d\n",harq_pid);
    msg("PDSCH dlsch0 UE: DCINdi   %d\n",dlsch0_harq->DCINdi);
    msg("PDSCH dlsch0 UE: rvidx    %d\n",dlsch0_harq->rvidx);
    msg("PDSCH dlsch0 UE: TBS      %d\n",dlsch0_harq->TBS);
    msg("PDSCH dlsch0 UE: mcs      %d\n",dlsch0_harq->mcs);
    msg("PDSCH dlsch0 UE: pwr_off  %d\n",dlsch0_harq->dl_power_off);
  }
#endif
  dlsch[0]->active=1;

  // compute DL power control parameters   
  computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off);

  computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antennas_tx_eNB,dlsch[0],dlsch0_harq->dl_power_off);

  return(0);
}


uint8_t subframe2harq_pid(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe) {
  /*
    #ifdef DEBUG_DCI
    if (frame_parms->frame_type == TDD)
    msg("dci_tools.c: subframe2_harq_pid, subframe %d for TDD configuration %d\n",subframe,frame_parms->tdd_config);
    else
    msg("dci_tools.c: subframe2_harq_pid, subframe %d for FDD \n",subframe);
    #endif
  */
  if (frame_parms->frame_type == FDD) {
    return(((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:
	  return(subframe-2);
	  break;
	case 7:
	case 8:
	  return(subframe-5);
	  break;
	default:
	  LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
	  return(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);
	mac_xface->macphy_exit("subframe2_harq_pid, Illegal subframe");
	return(255);
      }
      return(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);
	return(255);
      }
      return(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);
	return(255);
      }
      return(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);
	return(255);
      }
      return(subframe-2);
      break;
    default:
      LOG_E(PHY,"subframe2_harq_pid, Unsupported TDD mode %d\n",frame_parms->tdd_config);
      return(255);

    }
  }
  return(255);
}

uint8_t pdcch_alloc2ul_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint8_t n){

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

}

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){

  if ((frame_parms->frame_type == TDD) && 
      (frame_parms->tdd_config == 1) &&
      ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5
    return(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)))  
    return(frame + (n>=5 ? 1 : 0));
  else if ((frame_parms->frame_type == TDD) && 
	   (frame_parms->tdd_config == 6) &&
	   (n==9)) // tdd_config 6 SF 9
    return(frame+1);
  else
    return(frame+(n>=6 ? 1 : 0));

}

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

  int i, aarx;
  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++) {
    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 {
      // This needs to be done properly!!!
      msg("PMI feedback for rank>1 not supported!\n");
      pmivect = 0;
    }
  }

  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;

  if(flag_LA==0){
    // Ideal Channel Estimation
    if (sinr<=-4.89)
      return(0);
    else if (sinr < -3.53)
      return(3);
    else if (sinr <= -1.93)
      return(4);
    else if (sinr <= -0.43)
      return(5);
    else if (sinr <= 1.11)
      return(6);
    else if (sinr <= 3.26)
      return(7);
    else if (sinr <= 5)
      return(8);
    else if (sinr <= 7)
      return(9);
    else if (sinr <= 9)
      return(10);
    else if (sinr <= 11)
      return(11);
    else if (sinr <= 13)
      return(12);
    else if (sinr <= 15.5)
      return(13);
    else if (sinr <= 17.5)
      return(14);
    else if (sinr > 19.5)
      return(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])
	return(h);
    }
  }
  return(0);
}
//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) {
  
  //  msg("[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");
      mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!");
      break;
    default:
      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
      mac_xface->macphy_exit("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");
      mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!");
      break;
    default:
      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
      mac_xface->macphy_exit("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");
      mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!");
      break;
    default:
      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
      mac_xface->macphy_exit("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");
      mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!");
      break;
    default:
      LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format);
      mac_xface->macphy_exit("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 i,wideband_pmi2=wideband_pmi&3;
  uint32_t pmi_ex = 0;

  for (i=0;i<14;i+=2)
    pmi_ex|=(wideband_pmi2<<i);

  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 *phy_vars_ue,
				      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 = phy_vars_ue->transmission_mode[eNB_id];
  ANFBmode_t AckNackFBMode = phy_vars_ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode;
  LTE_UE_ULSCH_t *ulsch = phy_vars_ue->ulsch_ue[eNB_id];
  //  LTE_UE_DLSCH_t **dlsch = phy_vars_ue->dlsch_ue[0];
  PHY_MEASUREMENTS *meas = &phy_vars_ue->PHY_measurements;
  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_ue->lte_frame_parms;
  //  uint32_t current_dlsch_cqi = phy_vars_ue->current_dlsch_cqi[eNB_id];

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

  if (dci_format == format0) {

    if (rnti == ra_rnti)
      harq_pid = 0;
    else
      harq_pid = subframe2harq_pid(frame_parms,
				   pdcch_alloc2ul_frame(frame_parms,phy_vars_ue->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",
	    phy_vars_ue->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;
	//	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;
	//	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;
	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;
	//	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;
	//	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];
      //      printf("***********rballoc %d, first_rb %d, nb_rb %d\n",rballoc,ulsch->harq_processes[harq_pid]->first_rb,ulsch->harq_processes[harq_pid]->nb_rb);
      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;
	//	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;
	//	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;
	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;
	//	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;
	//	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("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 > RIV_max\n", 	  
	    phy_vars_ue->frame_rx, subframe, rnti, dci_format);
      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;
    
    ulsch->harq_processes[harq_pid]->TPC                                   = TPC;

    if (phy_vars_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",
	phy_vars_ue->Mod_id,harq_pid,phy_vars_ue->frame_rx,subframe,ulsch->f_pusch,
	delta_PUSCH_acc[phy_vars_ue->ulsch_ue[eNB_id]->harq_processes[harq_pid]->TPC],
	phy_vars_ue->ulsch_ue[eNB_id]->harq_processes[harq_pid]->TPC);
      ulsch->f_pusch += delta_PUSCH_acc[phy_vars_ue->ulsch_ue[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",
	phy_vars_ue->Mod_id,harq_pid,phy_vars_ue->frame_rx,subframe,ulsch->f_pusch,
	delta_PUSCH_abs[phy_vars_ue->ulsch_ue[eNB_id]->harq_processes[harq_pid]->TPC],
	phy_vars_ue->ulsch_ue[eNB_id]->harq_processes[harq_pid]->TPC);
      ulsch->f_pusch = delta_PUSCH_abs[phy_vars_ue->ulsch_ue[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]->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
      }
    }
    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;
    }
    //    msg("[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) {
      ulsch->O_RI = 1; //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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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 (phy_vars_ue->lte_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,phy_vars_ue->lte_frame_parms.N_RB_DL);

    //FK: moved this part to ulsch_coding to be more recent
    /*
      fill_CQI(ulsch->o,ulsch->uci_format,meas,eNB_id,transmission_mode);
      print_CQI(ulsch->o,ulsch->uci_format,eNB_id);
   
      // save PUSCH pmi for later (transmission modes 4,5,6)
      // msg("ulsch: saving pmi for DL %x\n",pmi2hex_2Ar1(((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi));
      dlsch[0]->pmi_alloc = ((wideband_cqi_rank1_2A_5MHz *)ulsch->o)->pmi;
    */

        // check this (see comment in generate_ue_ulsch_params_from_dci)
    if (frame_parms->frame_type == FDD) {
      int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4);
      if (phy_vars_ue->dlsch_ue[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;
      }
    } 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[phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index];//18;
    ulsch->beta_offset_ri_times8                 = beta_ri[phy_vars_ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index];//10;
    ulsch->beta_offset_harqack_times8            = beta_ack[phy_vars_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;
    ulsch->bundling = 1-AckNackFBMode;

    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 < 29)
	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
	LOG_E(PHY,"Fatal: mcs > 28!!! and round == 0\n");
      /*
	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;
      ulsch->harq_processes[harq_pid]->round = 0;

      // a Ndi=1 automatically acknowledges previous PUSCH transmission
      if (phy_vars_ue->ulsch_ue_Msg3_active[eNB_id] == 1) 
	phy_vars_ue->ulsch_ue_Msg3_active[eNB_id] = 0;  
    } 
    else {
      //      printf("Ndi = 0 : Setting RVidx from mcs %d\n",((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs);
      if (mcs>28) ulsch->harq_processes[harq_pid]->rvidx = mcs - 28;
      //      ulsch->harq_processes[harq_pid]->round++;
    }

    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\n",
	  phy_vars_ue->Mod_id,harq_pid,phy_vars_ue->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);

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

#ifdef DEBUG_DCI
    msg("Format 0 DCI : ulsch (ue): NBRB        %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
    msg("Format 0 DCI :ulsch (ue): first_rb    %d\n",ulsch->harq_processes[harq_pid]->first_rb);
    msg("Format 0 DCI :ulsch (ue): harq_pid    %d\n",harq_pid);
    msg("Format 0 DCI :ulsch (ue): round       %d\n",ulsch->harq_processes[harq_pid]->round);
    msg("Format 0 DCI :ulsch (ue): TBS         %d\n",ulsch->harq_processes[harq_pid]->TBS);
    msg("Format 0 DCI :ulsch (ue): mcs         %d\n",ulsch->harq_processes[harq_pid]->mcs);
    msg("Format 0 DCI :ulsch (ue): O           %d\n",ulsch->O);
    if (frame_parms->frame_type == TDD)
      msg("Format 0 DCI :ulsch (ue): O_ACK/DAI   %d/%d\n",ulsch->harq_processes[harq_pid]->O_ACK,dai);
    else      
      msg("Format 0 DCI :ulsch (ue): O_ACK       %d\n",ulsch->harq_processes[harq_pid]->O_ACK);

    msg("Format 0 DCI :ulsch (ue): Nsymb_pusch   %d\n",ulsch->Nsymb_pusch);
    msg("Format 0 DCI :ulsch (ue): cshift        %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2);
#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",
	  phy_vars_ue->frame_rx, subframe,dci_format);
    return(-1);
  }

}

int generate_eNB_ulsch_params_from_dci(void *dci_pdu,
				       uint16_t rnti,
				       uint8_t sched_subframe,
				       DCI_format_t dci_format,
				       uint8_t UE_id,
				       PHY_VARS_eNB *phy_vars_eNB,
				       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=phy_vars_eNB->transmission_mode[UE_id];
  ANFBmode_t AckNackFBMode = phy_vars_eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode;
  LTE_eNB_ULSCH_t *ulsch=phy_vars_eNB->ulsch_eNB[UE_id];
  LTE_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->lte_frame_parms;
  int subframe = phy_vars_eNB->proc[sched_subframe].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
  LOG_D(PHY,"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,
						      phy_vars_eNB->proc[sched_subframe].frame_tx,
						      subframe),
				 pdcch_alloc2ul_subframe(frame_parms,subframe));

    //    printf("eNB: sched_subframe %d, subframe %d, frame_tx %d\n",sched_subframe,subframe,phy_vars_eNB->proc[sched_subframe].frame_tx);

    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;
	//	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;
	//	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;
    if (rb_alloc>RIV_max) {
      LOG_E(PHY,"Format 0: rb_alloc > RIV_max\n");
      mac_xface->macphy_exit("Format 0: rb_alloc > RIV_max\n");
      return(-1);
    }

#ifdef DEBUG_DCI
    LOG_D(PHY,"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) {
      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 
      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;//1;
      ulsch->harq_processes[harq_pid]->Or2                                   = 0;
      ulsch->harq_processes[harq_pid]->Or1                                   = 0;//sizeof_HLC_subband_cqi_nopmi_5MHz;
      ulsch->harq_processes[harq_pid]->uci_format                            = HLC_subband_cqi_nopmi;
    }

    if (frame_parms->frame_type == FDD) {
      int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4);
      if (phy_vars_eNB->dlsch_eNB[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[phy_vars_eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index];//18;
    ulsch->beta_offset_ri_times8                 = beta_ri[phy_vars_eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index];//10;
    ulsch->beta_offset_harqack_times8            = beta_ack[phy_vars_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;
    ulsch->bundling = 1-AckNackFBMode;
    //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",
	  phy_vars_eNB->Mod_id,harq_pid,phy_vars_eNB->proc[sched_subframe].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
    msg("ulsch (eNB): NBRB          %d\n",ulsch->harq_processes[harq_pid]->nb_rb);
    msg("ulsch (eNB): first_rb      %d\n",ulsch->harq_processes[harq_pid]->first_rb);
    msg("ulsch (eNB): harq_pid      %d\n",harq_pid);
    msg("ulsch (eNB): round         %d\n",ulsch->harq_processes[harq_pid]->round);
    msg("ulsch (eNB): TBS           %d\n",ulsch->harq_processes[harq_pid]->TBS);
    msg("ulsch (eNB): mcs           %d\n",ulsch->harq_processes[harq_pid]->mcs);
    msg("ulsch (eNB): Or1           %d\n",ulsch->harq_processes[harq_pid]->Or1);
    msg("ulsch (eNB): Nsymb_pusch   %d\n",ulsch->harq_processes[harq_pid]->Nsymb_pusch);
    msg("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 *phy_vars_ue, uint8_t eNB_id){
  uint8_t transmission_mode = phy_vars_ue->transmission_mode[eNB_id];
  PHY_MEASUREMENTS *meas = &phy_vars_ue->PHY_measurements;
  LTE_DL_FRAME_PARMS *frame_parms =  &phy_vars_ue->lte_frame_parms;
  int32_t **dl_channel_est = phy_vars_ue->lte_ue_common_vars.dl_ch_estimates[eNB_id];
  double *s_dB;
  s_dB = phy_vars_ue->sinr_CQI_dB;   
  //  LTE_UE_ULSCH_t *ulsch  = phy_vars_ue->ulsch_ue[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_antennas_tx_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_antennas_tx_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_antennas_tx_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:
		msg("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_antennas_tx_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:
		msg("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:
    msg("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);
  
  //msg("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();

  for (i=0;i<512;i++) {
    msg("RIV %d: nb_rb %d, alloc %x, alloc_dist %x\n",
	i,
	RIV2nb_rb_LUT25[i],
	localRIV2alloc_LUT25[i],
	distRIV2alloc_LUT25[i]);

  }

  rah = 0;
  rballoc = 0x1fff;
  msg("rballoc 0 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
  rah = 1;

  rballoc = 0x1678;
  msg("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));

  rballoc = 0xfffc;
  msg("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
  rballoc = 0xfffd;
  msg("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
  rballoc = 0xffff;
  msg("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
  rballoc = 0xfffe;
  msg("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc));
}

#endif