From 897b24dc2c60fc296012f96ec9c599e1cb4dfe03 Mon Sep 17 00:00:00 2001
From: Nick Ho <nick133371@gmail.com>
Date: Mon, 29 May 2017 12:28:24 +0200
Subject: [PATCH] Add new file dci_tools_nb_iot

---
 openair1/PHY/LTE_TRANSPORT/dci_tools_nb_iot.c | 2082 +++++++++++++++++
 openair1/PHY/defs.h                           |    1 +
 openair2/LAYER2/MAC/defs_nb_iot.h             |    4 +-
 openair2/LAYER2/MAC/eNB_scheduler_RA_nb_iot.c |    2 +-
 openair2/PHY_INTERFACE/IF_Module_nb_iot.h     |    4 +-
 5 files changed, 2088 insertions(+), 5 deletions(-)
 create mode 100644 openair1/PHY/LTE_TRANSPORT/dci_tools_nb_iot.c

diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools_nb_iot.c b/openair1/PHY/LTE_TRANSPORT/dci_tools_nb_iot.c
new file mode 100644
index 0000000000..765905f212
--- /dev/null
+++ b/openair1/PHY/LTE_TRANSPORT/dci_tools_nb_iot.c
@@ -0,0 +1,2082 @@
+/*
+ * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The OpenAirInterface Software Alliance licenses this file to You under
+ * the OAI Public License, Version 1.0  (the "License"); you may not use this file
+ * except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.openairinterface.org/?page_id=698
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *-------------------------------------------------------------------------------
+ * For more information about the OpenAirInterface (OAI) Software Alliance:
+ *      contact@openairinterface.org
+ */
+
+/*! \file PHY/LTE_TRANSPORT/dci_tools.c
+ * \brief PHY Support routines (eNB/UE) for filling PDSCH/PUSCH/DLSCH/ULSCH data structures based on DCI PDUs generated by eNB MAC scheduler.
+ * \author R. Knopp
+ * \date 2011
+ * \version 0.1
+ * \company Eurecom
+ * \email: knopp@eurecom.fr
+ * \note
+ * \warning
+ */
+#include "PHY/defs.h"
+#include "PHY/extern.h"
+#include "SCHED/defs.h"
+#ifdef DEBUG_DCI_TOOLS
+#include "PHY/vars.h"
+#endif
+#include "assertions.h"
+
+
+//#define DEBUG_HARQ
+
+#include "LAYER2/MAC/extern.h"
+#include "LAYER2/MAC/defs.h"
+
+//#define DEBUG_DCI
+
+
+
+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;
+
+int NB_generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB,
+                                       eNB_rxtx_proc_t *proc,
+                                       DCI_CONTENT *DCI_Content,
+                                       uint16_t rnti,
+                                       DCI_format_NB_t dci_format,
+                                       uint8_t UE_id)
+{
+
+  uint8_t harq_pid;
+  uint32_t rb_alloc;
+  uint8_t transmission_mode=eNB->transmission_mode[UE_id];
+  ANFBmode_t AckNackFBMode = eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode;
+  LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id];
+  LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms;
+  int subframe = proc->subframe_tx;
+
+  /// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
+  uint8_t type;
+  /// Subcarrier indication, 6 bits
+  uint8_t scind;
+  /// Resourse Assignment (RU Assignment), 3 bits
+  uint8_t ResAssign;
+  /// Modulation and Coding Scheme, 4 bits
+  uint8_t mcs;
+  /// New Data Indicator, 1 bits
+  uint8_t ndi;
+  /// Scheduling Delay, 2 bits
+  uint8_t Scheddly;
+  /// Repetition Number, 3 bits
+  uint8_t RepNum;
+  /// Redundancy version for HARQ (only use 0 and 2), 1 bits
+  uint8_t rv;
+  /// DCI subframe repetition Number, 2 bits
+  uint8_t DCIRep;
+  
+  if (dci_format == DCIFormatN0) 
+    {
+      /*HARQ PID Set*/
+      
+      type        = &DCI_Content->DCIN0.type;
+      scind       = &DCI_Content->DCIN0.scind;
+      ResAssign   = &DCI_Content->DCIN0.ResAssign;
+      mcs         = &DCI_Content->DCIN0.mcs;
+      ndi         = &DCI_Content->DCIN0.ndi;
+      Scheddly    = &DCI_Content->DCIN0.Scheddly;
+      RepNum      = &DCI_Content->DCIN0.RepNum;
+      rv          = &DCI_Content->DCIN0.rv;
+      DCIRep      = &DCI_Content->DCIN0.DCIRep;
+
+      // use this value to configure PHY both harq_processes and resource mapping.
+      
+      return(0);
+    } 
+    else 
+      {
+        LOG_E(PHY,"generate_eNB_ulsch_params_from_dci, Illegal dci_format %d\n",dci_format);
+        return(-1);
+      }
+}
+
+int NB_generate_eNB_dlsch_params_from_dci(int frame,
+                                       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 beamforming_mode)
+{
+
+  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=NULL;
+  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;
+  uint8_t TB0_active=0,TB1_active=0;
+  LTE_DL_eNB_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL;
+
+  //   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];
+      dlsch0_harq->codeword=0;
+
+      if (vrb_type==LOCALIZED) {
+  dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT6[rballoc];
+      }
+      else {
+  LOG_E(PHY,"Distributed RB allocation not done yet\n");
+  mac_xface->macphy_exit("exiting");
+      }
+      dlsch0_harq->vrb_type       = vrb_type;
+      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==LOCALIZED) {
+  dlsch0_harq->rb_alloc[0]    = localRIV2alloc_LUT25[rballoc];
+      }
+      else {
+  LOG_E(PHY,"Distributed RB allocation not done yet\n");
+  mac_xface->macphy_exit("exiting");
+      }
+      dlsch0_harq->vrb_type       = vrb_type;
+      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, TPC %d\n",mcs,rballoc,rv,TPC);
+      }
+
+      dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+      if (vrb_type==LOCALIZED) {
+  dlsch0_harq->rb_alloc[0]     = localRIV2alloc_LUT50_0[rballoc];
+  dlsch0_harq->rb_alloc[1]     = localRIV2alloc_LUT50_1[rballoc];
+      }
+      else {
+  LOG_E(PHY,"Distributed RB allocation not done yet\n");
+  mac_xface->macphy_exit("exiting");
+      }
+
+
+      dlsch0_harq->vrb_type        = vrb_type;
+      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];
+
+      dlsch0_harq->vrb_type         = vrb_type;
+      if (vrb_type==LOCALIZED) {
+  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 {
+  LOG_E(PHY,"Distributed RB allocation not done yet\n");
+  mac_xface->macphy_exit("exiting");
+      }
+
+
+
+      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>=8) {
+        LOG_E(PHY,"ERROR: Format 1A: harq_pid=%d >= 8\n", harq_pid);
+        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=%d >= 8\n", harq_pid);
+      return(-1);
+    }
+
+    dlsch0_harq = dlsch[0]->harq_processes[harq_pid];
+    dlsch0_harq->codeword=0;
+
+    // printf("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;
+    if (beamforming_mode == 0)
+      dlsch0_harq->mimo_mode = (frame_parms->mode1_flag == 1) ? SISO : ALAMOUTI;
+    else if (beamforming_mode == 7)
+      dlsch0_harq->mimo_mode = TM7;
+    else
+      LOG_E(PHY,"Invalid beamforming mode %dL\n", beamforming_mode);
+
+    dlsch0_harq->dl_power_off = 1;
+    /*
+      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: // DL Scheduling assignment for MIMO including closed loop spatial multiplexing
+
+    switch (frame_parms->N_RB_DL) {
+
+    case 6:
+      if (frame_parms->nb_antenna_ports_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_antenna_ports_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,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 25:
+      if (frame_parms->nb_antenna_ports_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_antenna_ports_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,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 50:
+      if (frame_parms->nb_antenna_ports_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_antenna_ports_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,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 100:
+      if (frame_parms->nb_antenna_ports_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_antenna_ports_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,"eNB: subframe %d UE %x, Format2 DCI: unsupported number of TX antennas %d\n",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+    }
+
+
+    if (harq_pid>=8) {
+      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
+      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
+    TB0_active = 1;
+    TB1_active = 1;
+
+    if ((rv1 == 1) && (mcs1 == 0)) {
+      TB0_active=0;
+    }
+    if ((rv2 == 1) && (mcs2 == 0)) {
+      TB1_active=0;
+    }
+#ifdef DEBUG_HARQ
+    printf("RV0 = %d, RV1 = %d. MCS0 = %d, MCS1=%d\n", rv1, rv2, mcs1, mcs2);
+#endif
+    if (TB0_active && TB1_active && tbswap==0) {
+      dlsch0=dlsch[0];
+      dlsch1=dlsch[1];
+      dlsch0->active = 1;
+      dlsch1->active = 1;
+      dlsch0_harq = dlsch0->harq_processes[harq_pid];
+      dlsch1_harq = dlsch1->harq_processes[harq_pid];
+      dlsch0_harq->mcs = mcs1;
+      dlsch1_harq->mcs = mcs2;
+      dlsch0_harq->rvidx = rv1;
+      dlsch1_harq->rvidx = rv2;
+      dlsch0_harq->status = ACTIVE;
+      dlsch1_harq->status = ACTIVE;
+      dlsch0_harq->codeword=0;
+      dlsch1_harq->codeword=1;
+#ifdef DEBUG_HARQ
+      printf("\n ENB: BOTH ACTIVE\n");
+#endif
+    }
+    else if (TB0_active && TB1_active && tbswap==1) {
+      dlsch0=dlsch[0];
+      dlsch1=dlsch[1];
+      dlsch0->active = 1;
+      dlsch1->active = 1;
+      dlsch0_harq = dlsch0->harq_processes[harq_pid];
+      dlsch1_harq = dlsch1->harq_processes[harq_pid];
+      dlsch0_harq->mcs = mcs1;
+      dlsch1_harq->mcs = mcs2;
+      dlsch0_harq->rvidx = rv1;
+      dlsch1_harq->rvidx = rv2;
+      dlsch0_harq->status = ACTIVE;
+      dlsch1_harq->status = ACTIVE;
+      dlsch0_harq->codeword=1;
+      dlsch1_harq->codeword=0;
+    }
+    else if (TB0_active && (TB1_active==0)) {
+      dlsch0=dlsch[0];
+      dlsch0->active = 1;
+      dlsch0_harq = dlsch0->harq_processes[harq_pid];
+      dlsch0_harq->mcs = mcs1;
+      dlsch0_harq->rvidx = rv1;
+      dlsch0_harq->status = ACTIVE;
+      dlsch0_harq->codeword = 0;
+      dlsch1=NULL;
+      dlsch1_harq = NULL;
+#ifdef DEBUG_HARQ
+      printf("\n ENB: TB1 is deactivated, retransmit TB0 transmit in TM6\n");
+#endif
+    }
+    else if ((TB0_active==0) && TB1_active) {
+      dlsch1=dlsch[1];
+      dlsch1->active = 1;
+      dlsch1_harq = dlsch1->harq_processes[harq_pid];
+      dlsch1_harq->mcs = mcs2;
+      dlsch1_harq->rvidx = rv2;
+      dlsch1_harq->status = ACTIVE;
+      dlsch1_harq->codeword = 0;
+      dlsch0=NULL;
+      dlsch0_harq = NULL;
+#ifdef DEBUG_HARQ
+      printf("\n ENB: TB0 is deactivated, retransmit TB1 transmit in TM6\n");
+#endif
+    }
+
+    if (dlsch0 != NULL){
+      dlsch0->subframe_tx[subframe] = 1;
+
+      dlsch0->current_harq_pid = harq_pid;
+      dlsch0->harq_ids[subframe] = harq_pid;
+    }
+
+    if (dlsch1_harq != NULL){
+      dlsch1->current_harq_pid = harq_pid;
+      dlsch1->harq_ids[subframe] = harq_pid;
+    }
+
+
+    if (dlsch0 != NULL ){
+      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);
+
+      if (dlsch1 != NULL){
+        dlsch1_harq->rb_alloc[0] = dlsch0_harq->rb_alloc[0];
+        dlsch1_harq->nb_rb = dlsch0_harq->nb_rb;
+      }
+    } else if ((dlsch0 == NULL ) && (dlsch1 != NULL )){
+        conv_rballoc(rah,
+                     rballoc,
+                     frame_parms->N_RB_DL,
+                     dlsch1_harq->rb_alloc);
+
+        dlsch1_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL);
+    }
+
+
+    /*if (dlsch0_harq->nb_rb == 0)
+      return(-1);*/
+
+
+    // assume both TBs are active
+    if (dlsch0_harq != NULL)
+      dlsch0_harq->Nl        = 1;
+    if (dlsch1_harq != NULL)
+      dlsch1_harq->Nl        = 1;
+
+
+    // check if either TB is disabled (see 36-213 V11.3 Section )
+
+    if (frame_parms->nb_antenna_ports_eNB == 2) {
+      if ((dlsch0 != NULL) && (dlsch1 != NULL)) {  //two CW active
+
+        dlsch0_harq->dl_power_off = 1;
+        dlsch1_harq->dl_power_off = 1;
+        dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+        dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
+        switch (tpmi) {
+        case 0:
+          dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
+          dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODING1;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,0,1);
+          dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,0,1);
+          break;
+        case 1:
+          dlsch0_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
+          dlsch1_harq->mimo_mode   = DUALSTREAM_UNIFORM_PRECODINGj;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1,1);
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1,1);
+
+          break;
+        case 2: // PUSCH precoding
+          dlsch0_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
+          dlsch0_harq->pmi_alloc   = DL_pmi_single;
+          dlsch1_harq->mimo_mode   = DUALSTREAM_PUSCH_PRECODING;
+          dlsch1_harq->pmi_alloc   = DL_pmi_single;
+          break;
+        default:
+          break;
+        }
+      } else if ((dlsch0 != NULL) && (dlsch1 == NULL))  { // only CW 0 active
+        dlsch0_harq->dl_power_off = 1;
+        dlsch0_harq->TBS= TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+        switch (tpmi) {
+        case 0 :
+          dlsch0_harq->mimo_mode   = ALAMOUTI;
+          break;
+        case 1:
+          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING11;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,0,0);
+          break;
+        case 2:
+          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1,0);
+          break;
+        case 3:
+          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,2,0);
+          break;
+        case 4:
+          dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
+          dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,3,0);
+          break;
+        case 5:
+          dlsch0_harq->mimo_mode   = PUSCH_PRECODING0;
+          dlsch0_harq->pmi_alloc   = DL_pmi_single;
+          break;
+        case 6:
+          dlsch0_harq->mimo_mode   = PUSCH_PRECODING1;
+          dlsch0_harq->pmi_alloc   = DL_pmi_single;
+          break;
+        }
+      } else if ((dlsch0 == NULL) && (dlsch1 != NULL))  {
+          dlsch1_harq->dl_power_off = 1;
+          dlsch1_harq->TBS= TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1];
+          switch (tpmi) {
+          case 0 :
+            dlsch1_harq->mimo_mode   = ALAMOUTI;
+            break;
+          case 1:
+            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING11;
+            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,0,0);
+            break;
+          case 2:
+            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1m1;
+            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,1,0);
+            break;
+          case 3:
+            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1j;
+            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,2,0);
+            break;
+          case 4:
+            dlsch1_harq->mimo_mode   = UNIFORM_PRECODING1mj;
+            dlsch1_harq->pmi_alloc   = pmi_extend(frame_parms,3,0);
+            break;
+          case 5:
+            dlsch1_harq->mimo_mode   = PUSCH_PRECODING0;
+            dlsch1_harq->pmi_alloc   = DL_pmi_single;
+            break;
+          case 6:
+            dlsch1_harq->mimo_mode   = PUSCH_PRECODING1;
+            dlsch1_harq->pmi_alloc   = DL_pmi_single;
+            break;
+          }
+        }
+
+    } else if (frame_parms->nb_antenna_ports_eNB == 4) {
+      // fill in later
+    }
+
+    // reset HARQ process if this is the first transmission
+   /* if (dlsch0_harq->round == 0)
+      dlsch0_harq->status = ACTIVE;
+
+    if (dlsch1_harq->round == 0)
+      dlsch1_harq->status = ACTIVE;*/
+    if (dlsch0_harq != NULL)
+      dlsch0->rnti = rnti;
+    if (dlsch1 != NULL)
+      dlsch1->rnti = rnti;
+
+    break;
+
+  case format2A:
+
+    switch (frame_parms->N_RB_DL) {
+
+    case 6:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2;
+          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_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rv1       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv2;
+          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",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 25:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2;
+          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_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv2;
+          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",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 50:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2;
+          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_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv2;
+          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",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+
+    case 100:
+      if (frame_parms->nb_antenna_ports_eNB == 2) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2;
+          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_antenna_ports_eNB == 4) {
+        if (frame_type == TDD) {
+          mcs1      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs1;
+          mcs2      = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs2;
+          rballoc   = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rballoc;
+          rah       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rah;
+          rv1       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv1;
+          rv2       = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv2;
+          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",subframe,rnti,frame_parms->nb_antenna_ports_eNB);
+      }
+
+      break;
+    }
+
+
+    if (harq_pid>=8) {
+      LOG_E(PHY,"ERROR: Format 2_2A: harq_pid=%d >= 8\n", harq_pid);
+      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
+    // This must be set as in TM4, does not work properly now.
+    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_antenna_ports_eNB == 2) {
+      dlsch0_harq->TBS         = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1];
+      dlsch1_harq->TBS         = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch0_harq->nb_rb-1];
+
+      if ((dlsch0->active==1) && (dlsch1->active==1)) {
+
+        dlsch0_harq->mimo_mode = LARGE_CDD;
+        dlsch1_harq->mimo_mode = LARGE_CDD;
+        dlsch0_harq->dl_power_off = 1;
+        dlsch1_harq->dl_power_off = 1;
+      } else {
+        dlsch0_harq->mimo_mode   = ALAMOUTI;
+        dlsch1_harq->mimo_mode   = ALAMOUTI;
+      }
+    } else if (frame_parms->nb_antenna_ports_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->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_antenna_ports_eNB);
+    }
+
+    // reset HARQ process if this is the first transmission
+    if ((dlsch0->active==1) && (dlsch0_harq->round == 0))
+      dlsch0_harq->status = ACTIVE;
+
+    if ((dlsch1->active==1) && (dlsch1_harq->round == 0))
+      dlsch1_harq->status = ACTIVE;
+
+    dlsch0->rnti = 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=%d >= 8\n", harq_pid);
+      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];
+
+    // Needs to be checked
+    dlsch0_harq->codeword=0;
+    dlsch1_harq->codeword=1;
+
+    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=%d >= 8\n", harq_pid);
+      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];
+
+    // Needs to be checked
+    dlsch0_harq->codeword=0;
+    dlsch1_harq->codeword=1;
+
+    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_antenna_ports_eNB == 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_antenna_ports_eNB == 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=%d >= 8\n", harq_pid);
+      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];
+
+    // Needs to be checked
+    dlsch0_harq->codeword=0;
+    dlsch1_harq->codeword=1;
+
+    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=%d >= 8\n", harq_pid);
+      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];
+       // Needs to be checked
+    dlsch0_harq->codeword=0;
+
+    conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah,
+                 ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,frame_parms->N_RB_DL,
+                 dlsch0_harq->rb_alloc);
+
+    //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, 0);
+
+      break;
+
+    case 2:
+      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1m1;
+      dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,1, 0);
+
+      break;
+
+    case 3:
+      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1j;
+      dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,2, 0);
+
+      break;
+
+    case 4:
+      dlsch0_harq->mimo_mode   = UNIFORM_PRECODING1mj;
+      dlsch0_harq->pmi_alloc   = pmi_extend(frame_parms,3, 0);
+      break;
+
+    case 5:
+      dlsch0_harq->mimo_mode   = PUSCH_PRECODING0;
+      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;
+  }
+
+
+  if (dlsch0_harq) {
+    dlsch0_harq->frame   = frame;
+    dlsch0_harq->subframe = subframe;
+  }
+  if (dlsch1_harq) {
+    dlsch1_harq->frame   = frame;
+    dlsch1_harq->subframe = subframe;
+  }
+
+#ifdef DEBUG_DCI
+
+  if (dlsch0) {
+    printf("dlsch0 eNB: dlsch0   %p\n",dlsch0);
+    printf("dlsch0 eNB: rnti     %x\n",dlsch0->rnti);
+    printf("dlsch0 eNB: NBRB     %d\n",dlsch0_harq->nb_rb);
+    printf("dlsch0 eNB: rballoc  %x\n",dlsch0_harq->rb_alloc[0]);
+    printf("dlsch0 eNB: harq_pid %d\n",harq_pid);
+    printf("dlsch0 eNB: round    %d\n",dlsch0_harq->round);
+    printf("dlsch0 eNB: rvidx    %d\n",dlsch0_harq->rvidx);
+    printf("dlsch0 eNB: TBS      %d (NPRB %d)\n",dlsch0_harq->TBS,NPRB);
+    printf("dlsch0 eNB: mcs      %d\n",dlsch0_harq->mcs);
+    printf("dlsch0 eNB: tpmi %d\n",tpmi);
+    printf("dlsch0 eNB: mimo_mode %d\n",dlsch0_harq->mimo_mode);
+  }
+
+    if (dlsch1) {
+    printf("dlsch1 eNB: dlsch1   %p\n",dlsch1);
+    printf("dlsch1 eNB: rnti     %x\n",dlsch1->rnti);
+    printf("dlsch1 eNB: NBRB     %d\n",dlsch1_harq->nb_rb);
+    printf("dlsch1 eNB: rballoc  %x\n",dlsch1_harq->rb_alloc[0]);
+    printf("dlsch1 eNB: harq_pid %d\n",harq_pid);
+    printf("dlsch1 eNB: round    %d\n",dlsch1_harq->round);
+    printf("dlsch1 eNB: rvidx    %d\n",dlsch1_harq->rvidx);
+    printf("dlsch1 eNB: TBS      %d (NPRB %d)\n",dlsch1_harq->TBS,NPRB);
+    printf("dlsch1 eNB: mcs      %d\n",dlsch1_harq->mcs);
+    printf("dlsch1 eNB: tpmi %d\n",tpmi);
+    printf("dlsch1 eNB: mimo_mode %d\n",dlsch1_harq->mimo_mode);
+  }
+
+#endif
+
+  // compute DL power control parameters
+
+  if (dlsch0 != NULL){
+  computeRhoA_eNB(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB);
+  computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off);
+}
+  if (dlsch1 != NULL){
+      computeRhoA_eNB(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB);
+  computeRhoB_eNB(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[1],dlsch1_harq->dl_power_off);
+  }
+
+
+  return(0);
+}
\ No newline at end of file
diff --git a/openair1/PHY/defs.h b/openair1/PHY/defs.h
index cd77973e0b..fcee28ab0a 100644
--- a/openair1/PHY/defs.h
+++ b/openair1/PHY/defs.h
@@ -129,6 +129,7 @@ static inline void* malloc16_clear( size_t size )
 #ifdef OPENAIR_LTE
 
 #include "PHY/LTE_TRANSPORT/defs.h"
+#include "PHY/LTE_TRANSPORT/defs_nb_iot.h"
 #include <pthread.h>
 
 #include "targets/ARCH/COMMON/common_lib.h"
diff --git a/openair2/LAYER2/MAC/defs_nb_iot.h b/openair2/LAYER2/MAC/defs_nb_iot.h
index a45f636e3f..63caffb784 100644
--- a/openair2/LAYER2/MAC/defs_nb_iot.h
+++ b/openair2/LAYER2/MAC/defs_nb_iot.h
@@ -74,7 +74,7 @@ typedef struct {
   //Modify uint8_t mcs[8];
   /// TPC from last scheduling
   //Delete uint8_t oldTPC[8];
-  // PHY interface info
+  // PHY interface infoerror
   /// DCI format for DLSCH
   uint16_t DLSCH_dci_fmt;
   /// Current Aggregation Level for DCI
@@ -95,7 +95,7 @@ typedef struct {
   //Delete int8_t pre_allocated_rb_table_index_ul;
   /// total allocated RBs
   //Delete int8_t total_allocated_rbs;
-  /// pre-assigned MCS by the ulsch preprocessor
+  /// pre-assigned MCS by the ulsch preprocessorerror
   uint8_t pre_assigned_mcs_ul;
   /// assigned MCS by the ulsch scheduler
   uint8_t assigned_mcs_ul;
diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA_nb_iot.c b/openair2/LAYER2/MAC/eNB_scheduler_RA_nb_iot.c
index 570e1c3a16..3d0b1c77b1 100644
--- a/openair2/LAYER2/MAC/eNB_scheduler_RA_nb_iot.c
+++ b/openair2/LAYER2/MAC/eNB_scheduler_RA_nb_iot.c
@@ -55,7 +55,7 @@
 #include "proto_nb_iot.h"
 #include "defs_nb_iot.h"
 #include "math.h"
-#include "openair1/PHY/LTE_TRANSPORT/dci_nb_iot.h"
+//#include "openair1/PHY/LTE_TRANSPORT/dci_nb_iot.h"
 //#include "LAYER2/MAC/pre_processor.c"
 #include "pdcp.h"
 
diff --git a/openair2/PHY_INTERFACE/IF_Module_nb_iot.h b/openair2/PHY_INTERFACE/IF_Module_nb_iot.h
index 98a71d7ec2..3944b31458 100644
--- a/openair2/PHY_INTERFACE/IF_Module_nb_iot.h
+++ b/openair2/PHY_INTERFACE/IF_Module_nb_iot.h
@@ -81,9 +81,9 @@ typedef struct{
 
  /*DCI start*/
  // Format of DCI
- uint8_t DCI_Format;
+ DCI_format_NB_t DCI_Format;
  // Content of DCI
- void *DCI_Content;
+ DCI_CONTENT *DCI_Content;
 
 }Sched_Rsp_t;
 
-- 
2.26.2