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