/* * 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.1 (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_nr.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, A. Mico Pereperez * \date 2018 * \version 0.1 * \company Eurecom * \email: knopp@eurecom.fr * \note * \warning */ //#include "PHY/defs.h" #include "PHY/defs_nr_UE.h" //#include "PHY/NR_UE_TRANSPORT/nr_transport_ue.h" //#include "PHY/extern.h" //#include "SCHED/defs.h" #ifdef DEBUG_DCI_TOOLS #include "PHY/vars.h" #endif #include "assertions.h" #include "SCHED_NR_UE/harq_nr.h" //#define DEBUG_HARQ //#include "LAYER2/MAC/extern.h" //#include "LAYER2/MAC/defs.h" //#include "../openair2/LAYER2/MAC/extern.h" //#include "../openair2/LAYER2/MAC/defs.h" //#define DEBUG_DCI #define NR_PDCCH_DCI_TOOLS #define NR_PDCCH_DCI_TOOLS_DEBUG #if 0 uint32_t localRIV2alloc_LUT6[32]; uint32_t distRIV2alloc_even_LUT6[32]; uint32_t distRIV2alloc_odd_LUT6[32]; uint16_t RIV2nb_rb_LUT6[32]; uint16_t RIV2first_rb_LUT6[32]; uint16_t RIV_max6=0; uint32_t localRIV2alloc_LUT25[512]; uint32_t distRIV2alloc_even_LUT25[512]; uint32_t distRIV2alloc_odd_LUT25[512]; uint16_t RIV2nb_rb_LUT25[512]; uint16_t RIV2first_rb_LUT25[512]; uint16_t RIV_max25=0; uint32_t localRIV2alloc_LUT50_0[1600]; uint32_t localRIV2alloc_LUT50_1[1600]; uint32_t distRIV2alloc_gap0_even_LUT50_0[1600]; uint32_t distRIV2alloc_gap0_odd_LUT50_0[1600]; uint32_t distRIV2alloc_gap0_even_LUT50_1[1600]; uint32_t distRIV2alloc_gap0_odd_LUT50_1[1600]; uint32_t distRIV2alloc_gap1_even_LUT50_0[1600]; uint32_t distRIV2alloc_gap1_odd_LUT50_0[1600]; uint32_t distRIV2alloc_gap1_even_LUT50_1[1600]; uint32_t distRIV2alloc_gap1_odd_LUT50_1[1600]; uint16_t RIV2nb_rb_LUT50[1600]; uint16_t RIV2first_rb_LUT50[1600]; uint16_t RIV_max50=0; uint32_t localRIV2alloc_LUT100_0[6000]; uint32_t localRIV2alloc_LUT100_1[6000]; uint32_t localRIV2alloc_LUT100_2[6000]; uint32_t localRIV2alloc_LUT100_3[6000]; uint32_t distRIV2alloc_gap0_even_LUT100_0[6000]; uint32_t distRIV2alloc_gap0_odd_LUT100_0[6000]; uint32_t distRIV2alloc_gap0_even_LUT100_1[6000]; uint32_t distRIV2alloc_gap0_odd_LUT100_1[6000]; uint32_t distRIV2alloc_gap0_even_LUT100_2[6000]; uint32_t distRIV2alloc_gap0_odd_LUT100_2[6000]; uint32_t distRIV2alloc_gap0_even_LUT100_3[6000]; uint32_t distRIV2alloc_gap0_odd_LUT100_3[6000]; uint32_t distRIV2alloc_gap1_even_LUT100_0[6000]; uint32_t distRIV2alloc_gap1_odd_LUT100_0[6000]; uint32_t distRIV2alloc_gap1_even_LUT100_1[6000]; uint32_t distRIV2alloc_gap1_odd_LUT100_1[6000]; uint32_t distRIV2alloc_gap1_even_LUT100_2[6000]; uint32_t distRIV2alloc_gap1_odd_LUT100_2[6000]; uint32_t distRIV2alloc_gap1_even_LUT100_3[6000]; uint32_t distRIV2alloc_gap1_odd_LUT100_3[6000]; uint16_t RIV2nb_rb_LUT100[6000]; uint16_t RIV2first_rb_LUT100[6000]; uint16_t RIV_max100=0; extern uint32_t current_dlsch_cqi; // Table 8.6.3-3 36.213 uint16_t beta_cqi[16] = {0, //reserved 0, //reserved 9, //1.125 10, //1.250 11, //1.375 13, //1.625 14, //1.750 16, //2.000 18, //2.250 20, //2.500 23, //2.875 25, //3.125 28, //3.500 32, //4.000 40, //5.000 50 }; //6.250 // Table 8.6.3-2 36.213 uint16_t beta_ri[16] = {10, //1.250 13, //1.625 16, //2.000 20, //2.500 25, //3.125 32, //4.000 40, //5.000 50, //6.250 64, //8.000 80, //10.000 101, //12.625 127, //15.875 160, //20.000 0, //reserved 0, //reserved 0 }; //reserved // Table 8.6.3-2 36.213 uint16_t beta_ack[16] = {16, //2.000 20, //2.500 25, //3.125 32, //4.000 40, //5.000 50, //6.250 64, //8.000 80, //10.000 101, //12.625 127, //15.875 160, //20.000 248, //31.000 400, //50.000 640, //80.000 808 };//126.00 #endif int8_t nr_delta_PUSCH_abs[4] = {-4,-1,1,4}; int8_t nr_delta_PUSCH_acc[4] = {-1,0,1,3}; int8_t *nr_delta_PUCCH_lut = nr_delta_PUSCH_acc; #if 0 void conv_rballoc(uint8_t ra_header,uint32_t rb_alloc,uint32_t N_RB_DL,uint32_t *rb_alloc2) { uint32_t i,shift,subset; rb_alloc2[0] = 0; rb_alloc2[1] = 0; rb_alloc2[2] = 0; rb_alloc2[3] = 0; // printf("N_RB_DL %d, ra_header %d, rb_alloc %x\n",N_RB_DL,ra_header,rb_alloc); switch (N_RB_DL) { case 6: rb_alloc2[0] = rb_alloc&0x3f; break; case 25: if (ra_header == 0) {// Type 0 Allocation for (i=12; i>0; i--) { if ((rb_alloc&(1<<i)) != 0) rb_alloc2[0] |= (3<<((2*(12-i)))); // printf("rb_alloc2 (type 0) %x\n",rb_alloc2); } if ((rb_alloc&1) != 0) rb_alloc2[0] |= (1<<24); } else { subset = rb_alloc&1; shift = (rb_alloc>>1)&1; for (i=0; i<11; i++) { if ((rb_alloc&(1<<(i+2))) != 0) rb_alloc2[0] |= (1<<(2*i)); //printf("rb_alloc2 (type 1) %x\n",rb_alloc2); } if ((shift == 0) && (subset == 1)) rb_alloc2[0]<<=1; else if ((shift == 1) && (subset == 0)) rb_alloc2[0]<<=4; else if ((shift == 1) && (subset == 1)) rb_alloc2[0]<<=3; } break; case 50: if (ra_header == 0) {// Type 0 Allocation for (i=16; i>0; i--) { if ((rb_alloc&(1<<i)) != 0) rb_alloc2[(3*(16-i))>>5] |= (7<<((3*(16-i))%32)); } /* for (i=1;i<=16;i++) { if ((rb_alloc&(1<<(16-i))) != 0) rb_alloc2[(3*i)>>5] |= (7<<((3*i)%32)); } */ // bit mask across if ((rb_alloc2[0]>>31)==1) rb_alloc2[1] |= 1; if ((rb_alloc&1) != 0) rb_alloc2[1] |= (3<<16); /* for (i=0;i<16;i++) { if (((rb_alloc>>(16-i))&1) != 0) rb_alloc2[(3*i)>>5] |= (7<<((3*i)%32)); if ((i==10)&&((rb_alloc&(1<<6))!=0)) rb_alloc2[1] = 1; // printf("rb_alloc2[%d] (type 0) %x ((%x>>%d)&1=%d)\n",(3*i)>>5,rb_alloc2[(3*i)>>5],rb_alloc,i,(rb_alloc>>i)&1); } // fill in 2 from last bit instead of 3 if ((rb_alloc&1) != 0) rb_alloc2[1] |= (3<<i); // printf("rb_alloc2[%d] (type 0) %x ((%x>>%d)&1=%d)\n",(3*i)>>5,rb_alloc2[(3*i)>>5],rb_alloc,i,(rb_alloc>>i)&1); */ // printf("rb_alloc[1]=%x,rb_alloc[0]=%x\n",rb_alloc2[1],rb_alloc2[0]); } else { LOG_E(PHY,"resource type 1 not supported for N_RB_DL=50\n"); // mac_xface->macphy_exit("resource type 1 not supported for N_RB_DL=100\n"); /* subset = rb_alloc&1; shift = (rb_alloc>>1)&1; for (i=0;i<11;i++) { if ((rb_alloc&(1<<(i+2))) != 0) rb_alloc2 |= (1<<(2*i)); // printf("rb_alloc2 (type 1) %x\n",rb_alloc2); } if ((shift == 0) && (subset == 1)) rb_alloc2<<=1; else if ((shift == 1) && (subset == 0)) rb_alloc2<<=4; else if ((shift == 1) && (subset == 1)) rb_alloc2<<=3; */ } break; case 100: if (ra_header == 0) {// Type 0 Allocation for (i=0; i<25; i++) { if ((rb_alloc&(1<<(24-i))) != 0) rb_alloc2[(4*i)>>5] |= (0xf<<((4*i)%32)); // printf("rb_alloc2[%d] (type 0) %x (%d)\n",(4*i)>>5,rb_alloc2[(4*i)>>5],rb_alloc&(1<<i)); } } else { LOG_E(PHY,"resource type 1 not supported for N_RB_DL=100\n"); // mac_xface->macphy_exit("resource type 1 not supported for N_RB_DL=100\n"); /* subset = rb_alloc&1; shift = (rb_alloc>>1)&1; for (i=0;i<11;i++) { if ((rb_alloc&(1<<(i+2))) != 0) rb_alloc2 |= (1<<(2*i)); // printf("rb_alloc2 (type 1) %x\n",rb_alloc2); } if ((shift == 0) && (subset == 1)) rb_alloc2<<=1; else if ((shift == 1) && (subset == 0)) rb_alloc2<<=4; else if ((shift == 1) && (subset == 1)) rb_alloc2<<=3; */ } break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", N_RB_DL); DevParam (N_RB_DL, 0, 0); break; } } uint32_t conv_nprb(uint8_t ra_header,uint32_t rb_alloc,int N_RB_DL) { uint32_t nprb=0,i; switch (N_RB_DL) { case 6: for (i=0; i<6; i++) { if ((rb_alloc&(1<<i)) != 0) nprb += 1; } break; case 25: if (ra_header == 0) {// Type 0 Allocation for (i=12; i>0; i--) { if ((rb_alloc&(1<<i)) != 0) nprb += 2; } if ((rb_alloc&1) != 0) nprb += 1; } else { for (i=0; i<11; i++) { if ((rb_alloc&(1<<(i+2))) != 0) nprb += 1; } } break; case 50: if (ra_header == 0) {// Type 0 Allocation for (i=0; i<16; i++) { if ((rb_alloc&(1<<(16-i))) != 0) nprb += 3; } if ((rb_alloc&1) != 0) nprb += 2; } else { for (i=0; i<17; i++) { if ((rb_alloc&(1<<(i+2))) != 0) nprb += 1; } } break; case 100: if (ra_header == 0) {// Type 0 Allocation for (i=0; i<25; i++) { if ((rb_alloc&(1<<(24-i))) != 0) nprb += 4; } } else { for (i=0; i<25; i++) { if ((rb_alloc&(1<<(i+2))) != 0) nprb += 1; } } break; default: LOG_E(PHY,"Invalide N_RB_DL %d\n", N_RB_DL); DevParam (N_RB_DL, 0, 0); break; } return(nprb); } uint16_t computeRIV(uint16_t N_RB_DL,uint16_t RBstart,uint16_t Lcrbs) { uint16_t RIV; if (Lcrbs<=(1+(N_RB_DL>>1))) RIV = (N_RB_DL*(Lcrbs-1)) + RBstart; else RIV = (N_RB_DL*(N_RB_DL+1-Lcrbs)) + (N_RB_DL-1-RBstart); return(RIV); } // Convert a DCI Format 1C RIV to a Format 1A RIV // This extracts the start and length in PRBs from the 1C rballoc and // recomputes the RIV as if it were the 1A rballoc uint32_t conv_1C_RIV(int32_t rballoc,uint32_t N_RB_DL) { int NpDLVRB,N_RB_step,LpCRBsm1,RBpstart; switch (N_RB_DL) { case 6: // N_RB_step = 2, NDLVRB = 6, NpDLVRB = 3 NpDLVRB = 3; N_RB_step = 2; break; case 25: // N_RB_step = 2, NDLVRB = 24, NpDLVRB = 12 NpDLVRB = 12; N_RB_step = 2; break; case 50: // N_RB_step = 4, NDLVRB = 46, NpDLVRB = 11 NpDLVRB = 11; N_RB_step = 4; break; case 100: // N_RB_step = 4, NDLVRB = 96, NpDLVRB = 24 NpDLVRB = 24; N_RB_step = 4; break; default: NpDLVRB = 24; N_RB_step = 4; break; } // This is the 1C part from 7.1.6.3 in 36.213 LpCRBsm1 = rballoc/NpDLVRB; // printf("LpCRBs = %d\n",LpCRBsm1+1); if (LpCRBsm1 <= (NpDLVRB/2)) { RBpstart = rballoc % NpDLVRB; } else { LpCRBsm1 = NpDLVRB-LpCRBsm1; RBpstart = NpDLVRB-(rballoc%NpDLVRB); } // printf("RBpstart %d\n",RBpstart); return(computeRIV(N_RB_DL,N_RB_step*RBpstart,N_RB_step*(LpCRBsm1+1))); } uint32_t get_prb(int N_RB_DL,int odd_slot,int vrb,int Ngap) { int offset; switch (N_RB_DL) { case 6: // N_RB_DL = tildeN_RB_DL = 6 // Ngap = 4 , P=1, Nrow = 2, Nnull = 2 switch (vrb) { case 0: // even: 0->0, 1->2, odd: 0->3, 1->5 case 1: return ((3*odd_slot) + 2*(vrb&3))%6; break; case 2: // even: 2->3, 3->5, odd: 2->0, 3->2 case 3: return ((3*odd_slot) + 2*(vrb&3) + 5)%6; break; case 4: // even: 4->1, odd: 4->4 return ((3*odd_slot) + 1)%6; case 5: // even: 5->4, odd: 5->1 return ((3*odd_slot) + 4)%6; break; } break; case 15: if (vrb<12) { if ((vrb&3) < 2) // even: 0->0, 1->4, 4->1, 5->5, 8->2, 9->6 odd: 0->7, 1->11 return(((7*odd_slot) + 4*(vrb&3) + (vrb>>2))%14) + 14*(vrb/14); else if (vrb < 12) // even: 2->7, 3->11, 6->8, 7->12, 10->9, 11->13 return (((7*odd_slot) + 4*(vrb&3) + (vrb>>2) +13 )%14) + 14*(vrb/14); } if (vrb==12) return (3+(7*odd_slot)) % 14; if (vrb==13) return (10+(7*odd_slot)) % 14; return 14; break; case 25: return (((12*odd_slot) + 6*(vrb&3) + (vrb>>2))%24) + 24*(vrb/24); break; case 50: // P=3 if (Ngap==0) { // Nrow=12,Nnull=2,NVRBDL=46,Ngap1= 27 if (vrb>=23) offset=4; else offset=0; if (vrb<44) { if ((vrb&3)>=2) return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2) + 45)%46; else return offset+((23*odd_slot) + 12*(vrb&3) + (vrb>>2))%46; } if (vrb==44) // even: 44->11, odd: 45->34 return offset+((23*odd_slot) + 22-12+1); if (vrb==45) // even: 45->10, odd: 45->33 return offset+((23*odd_slot) + 22+12); if (vrb==46) return offset+46+((23*odd_slot) + 23-12+1) % 46; if (vrb==47) return offset+46+((23*odd_slot) + 23+12) % 46; if (vrb==48) return offset+46+((23*odd_slot) + 23-12+1) % 46; if (vrb==49) return offset+46+((23*odd_slot) + 23+12) % 46; } else { // Nrow=6,Nnull=6,NVRBDL=18,Ngap1= 27 if (vrb>=9) offset=18; else offset=0; if (vrb<12) { if ((vrb&3)>=2) return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2) + 17)%18; else return offset+((9*odd_slot) + 6*(vrb&3) + (vrb>>2))%18; } else { return offset+((9*odd_slot) + 12*(vrb&1)+(vrb>>1) )%18 + 18*(vrb/18); } } break; case 75: // Ngap1 = 32, NVRBRL=64, P=4, Nrow= 16, Nnull=0 if (Ngap ==0) { return ((32*odd_slot) + 16*(vrb&3) + (vrb>>2))%64 + (vrb/64); } else { // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); } break; case 100: // Ngap1 = 48, NVRBDL=96, Nrow=24, Nnull=0 if (Ngap ==0) { return ((48*odd_slot) + 24*(vrb&3) + (vrb>>2))%96 + (vrb/96); } else { // Ngap2 = 16, NVRBDL=32, Nrow=8, Nnull=0 return ((16*odd_slot) + 8*(vrb&3) + (vrb>>2))%32 + (vrb/32); } break; default: LOG_E(PHY,"Unknown N_RB_DL %d\n",N_RB_DL); return 0; } return 0; } void generate_RIV_tables() { // 6RBs localized RIV uint8_t Lcrbs,RBstart; uint16_t RIV; uint32_t alloc0,allocdist0_0_even,allocdist0_0_odd,allocdist0_1_even,allocdist0_1_odd; uint32_t alloc1,allocdist1_0_even,allocdist1_0_odd,allocdist1_1_even,allocdist1_1_odd; uint32_t alloc2,allocdist2_0_even,allocdist2_0_odd,allocdist2_1_even,allocdist2_1_odd; uint32_t alloc3,allocdist3_0_even,allocdist3_0_odd,allocdist3_1_even,allocdist3_1_odd; uint32_t nVRB,nVRB_even_dist,nVRB_odd_dist; for (RBstart=0; RBstart<6; RBstart++) { alloc0 = 0; allocdist0_0_even = 0; allocdist0_0_odd = 0; for (Lcrbs=1; Lcrbs<=(6-RBstart); Lcrbs++) { //printf("RBstart %d, len %d --> ",RBstart,Lcrbs); nVRB = Lcrbs-1+RBstart; alloc0 |= (1<<nVRB); allocdist0_0_even |= (1<<get_prb(6,0,nVRB,0)); allocdist0_0_odd |= (1<<get_prb(6,1,nVRB,0)); RIV=computeRIV(6,RBstart,Lcrbs); if (RIV>RIV_max6) RIV_max6 = RIV; // printf("RIV %d (%d) : first_rb %d NBRB %d\n",RIV,localRIV2alloc_LUT25[RIV],RBstart,Lcrbs); localRIV2alloc_LUT6[RIV] = alloc0; distRIV2alloc_even_LUT6[RIV] = allocdist0_0_even; distRIV2alloc_odd_LUT6[RIV] = allocdist0_0_odd; RIV2nb_rb_LUT6[RIV] = Lcrbs; RIV2first_rb_LUT6[RIV] = RBstart; } } for (RBstart=0; RBstart<25; RBstart++) { alloc0 = 0; allocdist0_0_even = 0; allocdist0_0_odd = 0; for (Lcrbs=1; Lcrbs<=(25-RBstart); Lcrbs++) { nVRB = Lcrbs-1+RBstart; //printf("RBstart %d, len %d --> ",RBstart,Lcrbs); alloc0 |= (1<<nVRB); allocdist0_0_even |= (1<<get_prb(25,0,nVRB,0)); allocdist0_0_odd |= (1<<get_prb(25,1,nVRB,0)); //printf("alloc 0 %x, allocdist0_even %x, allocdist0_odd %x\n",alloc0,allocdist0_0_even,allocdist0_0_odd); RIV=computeRIV(25,RBstart,Lcrbs); if (RIV>RIV_max25) RIV_max25 = RIV;; localRIV2alloc_LUT25[RIV] = alloc0; distRIV2alloc_even_LUT25[RIV] = allocdist0_0_even; distRIV2alloc_odd_LUT25[RIV] = allocdist0_0_odd; RIV2nb_rb_LUT25[RIV] = Lcrbs; RIV2first_rb_LUT25[RIV] = RBstart; } } for (RBstart=0; RBstart<50; RBstart++) { alloc0 = 0; alloc1 = 0; allocdist0_0_even=0; allocdist1_0_even=0; allocdist0_0_odd=0; allocdist1_0_odd=0; allocdist0_1_even=0; allocdist1_1_even=0; allocdist0_1_odd=0; allocdist1_1_odd=0; for (Lcrbs=1; Lcrbs<=(50-RBstart); Lcrbs++) { nVRB = Lcrbs-1+RBstart; if (nVRB<32) alloc0 |= (1<<nVRB); else alloc1 |= (1<<(nVRB-32)); // Distributed Gap1, even slot nVRB_even_dist = get_prb(50,0,nVRB,0); if (nVRB_even_dist<32) allocdist0_0_even |= (1<<nVRB_even_dist); else allocdist1_0_even |= (1<<(nVRB_even_dist-32)); // Distributed Gap1, odd slot nVRB_odd_dist = get_prb(50,1,nVRB,0); if (nVRB_odd_dist<32) allocdist0_0_odd |= (1<<nVRB_odd_dist); else allocdist1_0_odd |= (1<<(nVRB_odd_dist-32)); // Distributed Gap2, even slot nVRB_even_dist = get_prb(50,0,nVRB,1); if (nVRB_even_dist<32) allocdist0_1_even |= (1<<nVRB_even_dist); else allocdist1_1_even |= (1<<(nVRB_even_dist-32)); // Distributed Gap2, odd slot nVRB_odd_dist = get_prb(50,1,nVRB,1); if (nVRB_odd_dist<32) allocdist0_1_odd |= (1<<nVRB_odd_dist); else allocdist1_1_odd |= (1<<(nVRB_odd_dist-32)); RIV=computeRIV(50,RBstart,Lcrbs); if (RIV>RIV_max50) RIV_max50 = RIV; // printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs); localRIV2alloc_LUT50_0[RIV] = alloc0; localRIV2alloc_LUT50_1[RIV] = alloc1; distRIV2alloc_gap0_even_LUT50_0[RIV] = allocdist0_0_even; distRIV2alloc_gap0_even_LUT50_1[RIV] = allocdist1_0_even; distRIV2alloc_gap0_odd_LUT50_0[RIV] = allocdist0_0_odd; distRIV2alloc_gap0_odd_LUT50_1[RIV] = allocdist1_0_odd; distRIV2alloc_gap1_even_LUT50_0[RIV] = allocdist0_1_even; distRIV2alloc_gap1_even_LUT50_1[RIV] = allocdist1_1_even; distRIV2alloc_gap1_odd_LUT50_0[RIV] = allocdist0_1_odd; distRIV2alloc_gap1_odd_LUT50_1[RIV] = allocdist1_1_odd; RIV2nb_rb_LUT50[RIV] = Lcrbs; RIV2first_rb_LUT50[RIV] = RBstart; } } for (RBstart=0; RBstart<100; RBstart++) { alloc0 = 0; alloc1 = 0; alloc2 = 0; alloc3 = 0; allocdist0_0_even=0; allocdist1_0_even=0; allocdist2_0_even=0; allocdist3_0_even=0; allocdist0_0_odd=0; allocdist1_0_odd=0; allocdist2_0_odd=0; allocdist3_0_odd=0; allocdist0_1_even=0; allocdist1_1_even=0; allocdist2_1_even=0; allocdist3_1_even=0; allocdist0_1_odd=0; allocdist1_1_odd=0; allocdist2_1_odd=0; allocdist3_1_odd=0; for (Lcrbs=1; Lcrbs<=(100-RBstart); Lcrbs++) { nVRB = Lcrbs-1+RBstart; if (nVRB<32) alloc0 |= (1<<nVRB); else if (nVRB<64) alloc1 |= (1<<(nVRB-32)); else if (nVRB<96) alloc2 |= (1<<(nVRB-64)); else alloc3 |= (1<<(nVRB-96)); // Distributed Gap1, even slot nVRB_even_dist = get_prb(100,0,nVRB,0); // if ((RBstart==0) && (Lcrbs<=8)) // printf("nVRB %d => nVRB_even_dist %d\n",nVRB,nVRB_even_dist); if (nVRB_even_dist<32) allocdist0_0_even |= (1<<nVRB_even_dist); else if (nVRB_even_dist<64) allocdist1_0_even |= (1<<(nVRB_even_dist-32)); else if (nVRB_even_dist<96) allocdist2_0_even |= (1<<(nVRB_even_dist-64)); else allocdist3_0_even |= (1<<(nVRB_even_dist-96)); /* if ((RBstart==0) && (Lcrbs<=8)) printf("rballoc =>(%08x.%08x.%08x.%08x)\n", allocdist0_0_even, allocdist1_0_even, allocdist2_0_even, allocdist3_0_even ); */ // Distributed Gap1, odd slot nVRB_odd_dist = get_prb(100,1,nVRB,0); if (nVRB_odd_dist<32) allocdist0_0_odd |= (1<<nVRB_odd_dist); else if (nVRB_odd_dist<64) allocdist1_0_odd |= (1<<(nVRB_odd_dist-32)); else if (nVRB_odd_dist<96) allocdist2_0_odd |= (1<<(nVRB_odd_dist-64)); else allocdist3_0_odd |= (1<<(nVRB_odd_dist-96)); // Distributed Gap2, even slot nVRB_even_dist = get_prb(100,0,nVRB,1); if (nVRB_even_dist<32) allocdist0_1_even |= (1<<nVRB_even_dist); else if (nVRB_even_dist<64) allocdist1_1_even |= (1<<(nVRB_even_dist-32)); else if (nVRB_even_dist<96) allocdist2_1_even |= (1<<(nVRB_even_dist-64)); else allocdist3_1_even |= (1<<(nVRB_even_dist-96)); // Distributed Gap2, odd slot nVRB_odd_dist = get_prb(100,1,nVRB,1); if (nVRB_odd_dist<32) allocdist0_1_odd |= (1<<nVRB_odd_dist); else if (nVRB_odd_dist<64) allocdist1_1_odd |= (1<<(nVRB_odd_dist-32)); else if (nVRB_odd_dist<96) allocdist2_1_odd |= (1<<(nVRB_odd_dist-64)); else allocdist3_1_odd |= (1<<(nVRB_odd_dist-96)); RIV=computeRIV(100,RBstart,Lcrbs); if (RIV>RIV_max100) RIV_max100 = RIV; // printf("RIV %d : first_rb %d NBRB %d\n",RIV,RBstart,Lcrbs); localRIV2alloc_LUT100_0[RIV] = alloc0; localRIV2alloc_LUT100_1[RIV] = alloc1; localRIV2alloc_LUT100_2[RIV] = alloc2; localRIV2alloc_LUT100_3[RIV] = alloc3; distRIV2alloc_gap0_even_LUT100_0[RIV] = allocdist0_0_even; distRIV2alloc_gap0_even_LUT100_1[RIV] = allocdist1_0_even; distRIV2alloc_gap0_even_LUT100_2[RIV] = allocdist2_0_even; distRIV2alloc_gap0_even_LUT100_3[RIV] = allocdist3_0_even; distRIV2alloc_gap0_odd_LUT100_0[RIV] = allocdist0_0_odd; distRIV2alloc_gap0_odd_LUT100_1[RIV] = allocdist1_0_odd; distRIV2alloc_gap0_odd_LUT100_2[RIV] = allocdist2_0_odd; distRIV2alloc_gap0_odd_LUT100_3[RIV] = allocdist3_0_odd; distRIV2alloc_gap1_even_LUT100_0[RIV] = allocdist0_1_even; distRIV2alloc_gap1_even_LUT100_1[RIV] = allocdist1_1_even; distRIV2alloc_gap1_even_LUT100_2[RIV] = allocdist2_1_even; distRIV2alloc_gap1_even_LUT100_3[RIV] = allocdist3_1_even; distRIV2alloc_gap1_odd_LUT100_0[RIV] = allocdist0_1_odd; distRIV2alloc_gap1_odd_LUT100_1[RIV] = allocdist1_1_odd; distRIV2alloc_gap1_odd_LUT100_2[RIV] = allocdist2_1_odd; distRIV2alloc_gap1_odd_LUT100_3[RIV] = allocdist3_1_odd; RIV2nb_rb_LUT100[RIV] = Lcrbs; RIV2first_rb_LUT100[RIV] = RBstart; } } } // Ngap = 3, N_VRB_DL=6, P=1, N_row=2, N_null=4*2-6=2 // permutation for even slots : // n_PRB'(0,2,4) = (0,1,2), n_PRB'(1,3,5) = (4,5,6) // n_PRB''(0,1,2,3) = (0,2,4,6) // => n_tilde_PRB(5) = (4) // n_tilde_PRB(4) = (1) // n_tilde_PRB(2,3) = (3,5) // n_tilde_PRB(0,1) = (0,2) uint32_t get_rballoc(vrb_t vrb_type,uint16_t rb_alloc_dci) { return(localRIV2alloc_LUT25[rb_alloc_dci]); } uint8_t get_transmission_mode(module_id_t Mod_id, uint8_t CC_id, rnti_t rnti) { unsigned char UE_id; // find the UE_index corresponding to rnti UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]); DevAssert( UE_id != (unsigned char)-1 ); return(PHY_vars_eNB_g[Mod_id][CC_id]->transmission_mode[UE_id]); } int generate_eNB_dlsch_params_from_dci(int frame, uint8_t subframe, void *dci_pdu, uint16_t rnti, DCI_format_t dci_format, LTE_eNB_DLSCH_t **dlsch, NR_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; // 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(" eNOdeB 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 } // printf("[eNB] dlsch0_harq->round = %d, dlsch1_harq->round = %d \n", dlsch0_harq->round, dlsch1_harq->round); 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; } // printf ("[eNB] dlsch1_harq->pmi_alloc %d\n", dlsch1_harq->pmi_alloc); } } 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); } int dump_dci(NR_DL_FRAME_PARMS *frame_parms, DCI_ALLOC_t *dci) { switch (dci->format) { case format0: // This is an UL SCH allocation so nothing here, inform MAC if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config>0)) switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format0 (TDD, 1.5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu[0])[0], ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, ((DCI0_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); break; case 25: LOG_D(PHY,"DCI format0 (TDD1-6, 5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu[0])[0], ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, ((DCI0_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); break; case 50: LOG_D(PHY,"DCI format0 (TDD1-6, 10MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu[0])[0], ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, ((DCI0_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); break; case 100: LOG_D(PHY,"DCI format0 (TDD1-6, 20MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, dai %d, cqi_req %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu[0])[0], ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->hopping, ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc, ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs, ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi, ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC, ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cshift, ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai, ((DCI0_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->cqi_req); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } else if (frame_parms->frame_type == FDD) switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format0 (FDD, 1.5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu[0])[0], ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->hopping, ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC, ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->cshift, ((DCI0_1_5MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); break; case 25: LOG_D(PHY,"DCI format0 (FDD, 5MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu[0])[0], ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->hopping, ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC, ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->cshift, ((DCI0_5MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); break; case 50: LOG_D(PHY,"DCI format0 (FDD, 10MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu[0])[0], ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->hopping, ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs, ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi, ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC, ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->cshift, ((DCI0_10MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); break; case 100: LOG_D(PHY,"DCI format0 (FDD, 20MHz), rnti %x (%x): hopping %d, rb_alloc %x, mcs %d, ndi %d, TPC %d, cshift %d, cqi_req %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu[0])[0], ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->hopping, ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs, ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi, ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC, ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->cshift, ((DCI0_20MHz_FDD_t *)&dci->dci_pdu[0])->cqi_req); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } else LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); break; case format1: if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config>0)) switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format1 (TDD 1.5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->mcs, ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->ndi, ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->rv, ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI1_1_5MHz_TDD_t *)&dci->dci_pdu[0])->dai); break; case 25: LOG_D(PHY,"DCI format1 (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->mcs, ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->ndi, ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->rv, ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI1_5MHz_TDD_t *)&dci->dci_pdu[0])->dai); break; case 50: LOG_D(PHY,"DCI format1 (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->mcs, ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->ndi, ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->rv, ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI1_10MHz_TDD_t *)&dci->dci_pdu[0])->dai); break; case 100: LOG_D(PHY,"DCI format1 (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d, dai %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->mcs, ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->ndi, ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->rv, ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI1_20MHz_TDD_t *)&dci->dci_pdu[0])->dai); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } else if (frame_parms->frame_type == FDD) { switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format1 (FDD, 1.5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv, ((DCI1_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 25: LOG_D(PHY,"DCI format1 (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs, ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi, ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv, ((DCI1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 50: LOG_D(PHY,"DCI format1 (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs, ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi, ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->rv, ((DCI1_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 100: LOG_D(PHY,"DCI format1 (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d, harq_pid %d, ndi %d, RV %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs, ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi, ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->rv, ((DCI1_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } } else LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); break; case format1A: // This is DLSCH allocation for control traffic if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config>0)) { switch (frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format1A (TDD1-6, 1_5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); LOG_D(PHY,"MCS %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); LOG_D(PHY,"NDI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); LOG_D(PHY,"RV %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); LOG_D(PHY,"TPC %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); LOG_D(PHY,"DAI %d\n",((DCI1A_1_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); break; case 25: LOG_D(PHY,"DCI format1A (TDD1-6, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); LOG_D(PHY,"RB_ALLOC %d (NB_RB %d)\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); LOG_D(PHY,"MCS %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); LOG_D(PHY,"NDI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); LOG_D(PHY,"RV %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); LOG_D(PHY,"TPC %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); LOG_D(PHY,"DAI %d\n",((DCI1A_5MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); break; case 50: LOG_D(PHY,"DCI format1A (TDD1-6, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); LOG_D(PHY,"MCS %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); LOG_D(PHY,"NDI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); LOG_D(PHY,"RV %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); LOG_D(PHY,"TPC %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); LOG_D(PHY,"DAI %d\n",((DCI1A_10MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); break; case 100: LOG_D(PHY,"DCI format1A (TDD1-6, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->vrb_type); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT100[((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rballoc]); LOG_D(PHY,"MCS %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->mcs); LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->harq_pid); LOG_D(PHY,"NDI %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->ndi); LOG_D(PHY,"RV %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->rv); LOG_D(PHY,"TPC %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->TPC); LOG_D(PHY,"DAI %d\n",((DCI1A_20MHz_TDD_1_6_t *)&dci->dci_pdu[0])->dai); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } } else if (frame_parms->frame_type == FDD) { switch (frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format1A(FDD, 1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); LOG_D(PHY,"MCS %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs); LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); LOG_D(PHY,"NDI %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi); LOG_D(PHY,"RV %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->rv); LOG_D(PHY,"TPC %d\n",((DCI1A_1_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 25: LOG_D(PHY,"DCI format1A(FDD, 5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); LOG_D(PHY,"MCS %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->mcs); LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); LOG_D(PHY,"NDI %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->ndi); LOG_D(PHY,"RV %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->rv); LOG_D(PHY,"TPC %d\n",((DCI1A_5MHz_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 50: LOG_D(PHY,"DCI format1A(FDD, 10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); LOG_D(PHY,"MCS %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->mcs); LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); LOG_D(PHY,"NDI %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->ndi); LOG_D(PHY,"RV %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->rv); LOG_D(PHY,"TPC %d\n",((DCI1A_10MHz_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 100: LOG_D(PHY,"DCI format1A(FDD, 20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"VRB_TYPE %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->vrb_type); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT100[((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rballoc]); LOG_D(PHY,"MCS %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->mcs); LOG_D(PHY,"HARQ_PID %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->harq_pid); LOG_D(PHY,"NDI %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->ndi); LOG_D(PHY,"RV %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->rv); LOG_D(PHY,"TPC %d\n",((DCI1A_20MHz_FDD_t *)&dci->dci_pdu[0])->TPC); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } } break; case format1C: // This is DLSCH allocation for control traffic switch (frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format1C (1.5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n", ((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT6[conv_1C_RIV(((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->rballoc,6)]); LOG_D(PHY,"MCS %d\n",((DCI1C_1_5MHz_t *)&dci->dci_pdu[0])->mcs); break; case 25: LOG_D(PHY,"DCI format1C (5MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT25[conv_1C_RIV(((DCI1C_5MHz_t *)&dci->dci_pdu[0])->rballoc,25)]); LOG_D(PHY,"MCS %d\n",((DCI1C_5MHz_t *)&dci->dci_pdu[0])->mcs); break; case 50: LOG_D(PHY,"DCI format1C (10MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"Ngap %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->Ngap); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_10MHz_t *)&dci->dci_pdu[0])->rballoc,50)]); LOG_D(PHY,"MCS %d\n",((DCI1C_10MHz_t *)&dci->dci_pdu[0])->mcs); break; case 100: LOG_D(PHY,"DCI format1C (20MHz), rnti %x (%x)\n",dci->rnti,((uint32_t*)&dci->dci_pdu[0])[0]); LOG_D(PHY,"Ngap %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->Ngap); LOG_D(PHY,"RB_ALLOC %x (NB_RB %d)\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,RIV2nb_rb_LUT50[conv_1C_RIV(((DCI1C_20MHz_t *)&dci->dci_pdu[0])->rballoc,100)]); LOG_D(PHY,"MCS %d\n",((DCI1C_20MHz_t *)&dci->dci_pdu[0])->mcs); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } break; case format2: if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config>0)) { if (frame_parms->nb_antenna_ports_eNB == 2) { switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format2 2 antennas (TDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tbswap %d, tpmi %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi ); break; case 25: LOG_D(PHY,"DCI format2 2 antennas (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi); break; case 50: LOG_D(PHY,"DCI format2 2 antennas (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi); break; case 100: LOG_D(PHY,"DCI format2 2 antennas (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tpmi); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } } else if (frame_parms->nb_antenna_ports_eNB == 4) { switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format2 2 antennas (TDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tbswap %d, tpmi %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi ); break; case 25: LOG_D(PHY,"DCI format2 2 antennas (TDD 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); break; case 50: LOG_D(PHY,"DCI format2 2 antennas (TDD 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); break; case 100: LOG_D(PHY,"DCI format2 2 antennas (TDD 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, TPC %d, dai %d, tb_swap %d, tpmi %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } } } else if (frame_parms->frame_type == FDD) { if (frame_parms->nb_antenna_ports_eNB == 2) { switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format2 2 antennas (FDD, 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 25: LOG_D(PHY,"DCI format2 2 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, swap %d, TPMI %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 50: LOG_D(PHY,"DCI format2 2 antennas (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 100: LOG_D(PHY,"DCI format2 2 antennas (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } } else if (frame_parms->nb_antenna_ports_eNB == 4) { switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format2 4 antennas (FDD, 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 25: LOG_D(PHY,"DCI format2 4 antennas (FDD, 5 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 50: LOG_D(PHY,"DCI format2 4 antennas (FDD, 10 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 100: LOG_D(PHY,"DCI format2 4 antennas (FDD, 20 MHz), rnti %x (%x): rah %d, rb_alloc %x, mcs %d|%d, harq_pid %d, ndi %d|%d, RV %d|%d, tb_swap %d, tpmi %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } } } else LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); break; case format2A: if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config>0)) { if (frame_parms->nb_antenna_ports_eNB == 2) { switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format2A 2 antennas (FDD 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2A_1_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap ); break; case 25: LOG_D(PHY,"DCI format2A 2 antennas (FDD 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2A_5MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap); break; case 50: LOG_D(PHY,"DCI format2A 2 antennas (FDD 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2A_10MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap); break; case 100: LOG_D(PHY,"DCI format2A 2 antennas (FDD 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2A_20MHz_2A_TDD_t *)&dci->dci_pdu[0])->tb_swap); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } } else if (frame_parms->nb_antenna_ports_eNB == 4) { switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format2A 4 antennas (TDD 1.5 MHz), rnti %x (%"PRIu64"): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_1_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi ); break; case 25: LOG_D(PHY,"DCI format2A 4 antennas (TDD 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_5MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); break; case 50: LOG_D(PHY,"DCI format2A 4 antennas (TDD 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_10MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); break; case 100: LOG_D(PHY,"DCI format2A 4 antennas (TDD 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, TPC %d, dai %d, tbswap %d, tpmi %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->TPC, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->dai, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_20MHz_4A_TDD_t *)&dci->dci_pdu[0])->tpmi); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } } } else if (frame_parms->frame_type == FDD) { if (frame_parms->nb_antenna_ports_eNB == 2) { switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format2A 2 antennas (FDD, 1.5 MHz), rnti %x (%x): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", dci->rnti, ((uint32_t*)&dci->dci_pdu)[0], ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_1_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 25: LOG_D(PHY,"DCI format2A 2 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_5MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 50: LOG_D(PHY,"DCI format2A 2 antennas (FDD, 10 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_10MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 100: LOG_D(PHY,"DCI format2A 2 antennas (FDD, 20 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, TPC %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_20MHz_2A_FDD_t *)&dci->dci_pdu[0])->TPC); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } } else if (frame_parms->nb_antenna_ports_eNB == 4) { switch(frame_parms->N_RB_DL) { case 6: LOG_D(PHY,"DCI format2A 4 antennas (FDD, 1.5 MHz), rnti %x (%"PRIu64"): rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2A_1_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 25: LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2A_5MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 50: LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2A_10MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); break; case 100: LOG_D(PHY,"DCI format2A 4 antennas (FDD, 5 MHz), rnti %x (%"PRIu64"): rah %d, rb_alloc %x, mcs1 %d, mcs2 %d, harq_pid %d, ndi1 %d, ndi2 %d, RV1 %d, RV2 %d, tb_swap %d, tpmi %d, TPC %d\n", dci->rnti, ((uint64_t*)&dci->dci_pdu)[0], ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rah, ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs1, ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->mcs2, ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->harq_pid, ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi1, ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->ndi2, ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv1, ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->rv2, ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI2A_20MHz_4A_FDD_t *)&dci->dci_pdu[0])->TPC); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } } } else LOG_E(PHY,"Don't know how to handle TDD format 0 yet\n"); break; case format1E_2A_M10PRB: LOG_D(PHY,"DCI format1E_2A_M10PRB, rnti %x (%8x): harq_pid %d, rah %d, rb_alloc %x, mcs %d, rv %d, tpmi %d, ndi %d, dl_power_offset %d\n", dci->rnti, ((uint32_t *)&dci->dci_pdu)[0], ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->harq_pid, //((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->tb_swap, ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rah, ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rballoc, ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->mcs, ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->rv, ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->tpmi, ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->ndi, ((DCI1E_5MHz_2A_M10PRB_TDD_t *)&dci->dci_pdu[0])->dl_power_off ); break; default: LOG_E(PHY,"dci_tools.c: dump_dci, unknown format %d\n",dci->format); return(-1); } return(0); } #endif //(0) #ifdef NR_PDCCH_DCI_TOOLS int nr_extract_dci_info(PHY_VARS_NR_UE *ue, uint8_t eNB_id, lte_frame_type_t frame_type, uint8_t dci_length, uint16_t rnti, void *dci_pdu, NR_DCI_INFO_EXTRACTED_t *nr_pdci_info_extracted, uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], NR_DL_UE_HARQ_t *pdlsch0_harq, NR_UE_DLSCH_t *pdlsch0, NR_UE_ULSCH_t *ulsch0, NR_DCI_format_t dci_format, uint8_t nr_tti_rx, uint16_t n_RB_ULBWP, uint16_t n_RB_DLBWP, uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES]) { /* * This function will extract the different elements of the dci pdu and interpret the values extracted to update correctly the parameters in: * NR_DL_UE_HARQ_t *pdlsch0_harq, * NR_UE_DLSCH_t *pdlsch0, * * We need to know the dci length and the dci_fields_sizes (array containing each field size in number of bits) * In order to get the value of a specific field we will proceed as follows (let's have a look to an example: * If the length of the pdu is 38 bits and the content of the dci_pdu is 0x3A8900789A (pdu is 11 1010 1000 1001 0000 0000 0111 1000 1001 1010) * If the dci_fields_sizes is {0 0 1 0 0 0 0 0 0 13 0 1 0 0 0 0 0 0 0 0 0 0 5 1 2 4 2 0 0 0 2 3 3 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...} * This means: * number bits for carrier_ind field is 0 * number bits for sul_ind_0_1 field is 0 * number bits for identifier_dci_formats field is 0 * number bits for slot_format_ind field is 0 * number bits for pre_emption_ind field is 0 * ... * number bits for freq_dom_resource_assignment_DL field is 13 * ... * number bits for padding is 0 * In order to extract the information of (e.g.) freq_dom_resource_assignment_DL field, * we will do a left-shift of 1 position (because previous to this field, and according to the dci_fields_sizes array, there is only one non-empty field of size 1 bit) -> (1 1010 1000 1001 0000 0000 0111 1000 1001 1010 0) * then we will do a right-shit of dci_length-13 positions -> (1 1010 1000 1001). And this is the content of the freq_dom_resource_assignment_DL field * * * At the moment we have implemented: * Format 0_0, that contains the following fields according to Specification 38.212 V15.1.1 Section 7.3.1 * 0 IDENTIFIER_DCI_FORMATS: * 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: PUSCH hopping with resource allocation type 1 not considered * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 6.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, * 17 FREQ_HOPPING_FLAG: 0 bit if only resource allocation type 0 * 24 MCS: * 25 NDI: * 26 RV: * 27 HARQ_PROCESS_NUMBER: * 32 TPC_PUSCH: * 49 PADDING_NR_DCI: (Note 2) If DCI format 0_0 is monitored in common search space * 50 SUL_IND_0_0: * * Format 1_0, that contains the following fields * 0 IDENTIFIER_DCI_FORMATS: * 8 SHORT_MESSAGE_IND * 9 SHORT_MESSAGES * 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: * 12 TIME_DOM_RESOURCE_ASSIGNMENT: 0, 1, 2, 3, or 4 bits as defined in Subclause 5.1.2.1 of [6, TS 38.214]. The bitwidth for this field is determined as log2(I) bits, * 13 VRB_TO_PRB_MAPPING: 0 bit if only resource allocation type 0 * 24 MCS: * 25 NDI: * 26 RV: * 27 HARQ_PROCESS_NUMBER: * 28 DAI_: For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI * 31 TB_SCALING * 33 TPC_PUCCH: * 34 PUCCH_RESOURCE_IND: * 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: * 51 RA_PREAMBLE_INDEX: * 52 SUL_IND_1_0: * 53 SS_PBCH_INDEX: * 54 PRACH_MASK_INDEX: * 55 RESERVED_NR_DCI * */ uint64_t pdu_bitmap = 0xFFFFFFFFFFFFFFFF; pdu_bitmap = (pdu_bitmap << (64 - dci_length)) >> (64 - dci_length); // this variable will help to remove the bits of other fields when left-switching uint8_t dci_field=0; uint8_t sizes_count=0; uint8_t left_shift=0; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> Entering function nr_extract_dci_info() with dci_pdu=%llx with pdu_bitmap=%llx dci_length=%d\n",(*(uint64_t *)dci_pdu), pdu_bitmap, dci_length); printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> for format %d, dci_fields_sizes {",dci_format-15); for (int i=0; i<NBR_NR_DCI_FIELDS; i++) printf("%d ",dci_fields_sizes[i][dci_format-15]); printf("}\n"); #endif uint8_t prev_ndi = pdlsch0_harq->DCINdi; uint16_t l_RB; uint16_t start_RB; uint16_t tmp_RIV; uint16_t l_symbol; uint16_t start_symbol; uint16_t tmp_symbol; // dmrs_typeA_pos provided by higher layers. FIXME !!! uint8_t dmrs_typeA_pos = 2; uint8_t sliv_S; uint8_t sliv_L; uint8_t k_offset; uint8_t table_5_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1 {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?12:11}, // row index 1 {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?10:9}, // row index 2 {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?9:8}, // row index 3 {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?7:6}, // row index 4 {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?5:4}, // row index 5 {0,(dmrs_typeA_pos == 2)?9:10,(dmrs_typeA_pos == 2)?4:4}, // row index 6 {0,(dmrs_typeA_pos == 2)?4:6, (dmrs_typeA_pos == 2)?4:4}, // row index 7 {0,5,7}, // row index 8 {0,5,2}, // row index 9 {0,9,2}, // row index 10 {0,12,2}, // row index 11 {0,1,13}, // row index 12 {0,1,6}, // row index 13 {0,2,4}, // row index 14 {0,4,7}, // row index 15 {0,8,4} // row index 16 }; uint8_t table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1 {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?6:5}, // row index 1 {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?10:9}, // row index 2 {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?9:8}, // row index 3 {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?7:6}, // row index 4 {0,(dmrs_typeA_pos == 2)?2:3, (dmrs_typeA_pos == 2)?5:4}, // row index 5 {0,(dmrs_typeA_pos == 2)?6:8, (dmrs_typeA_pos == 2)?4:2}, // row index 6 {0,(dmrs_typeA_pos == 2)?4:6, (dmrs_typeA_pos == 2)?4:4}, // row index 7 {0,5,6}, // row index 8 {0,5,2}, // row index 9 {0,9,2}, // row index 10 {0,10,2}, // row index 11 {0,1,11}, // row index 12 {0,1,6}, // row index 13 {0,2,4}, // row index 14 {0,4,6}, // row index 15 {0,8,4} // row index 16 }; uint8_t table_5_1_2_1_1_4_time_dom_res_alloc_B[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1 {0,2,2}, // row index 1 {0,4,2}, // row index 2 {0,6,2}, // row index 3 {0,8,2}, // row index 4 {0,10,2}, // row index 5 {1,2,2}, // row index 6 {1,4,2}, // row index 7 {0,2,4}, // row index 8 {0,4,4}, // row index 9 {0,6,4}, // row index 10 {0,8,4}, // row index 11 {0,10,4}, // row index 12 {0,2,7}, // row index 13 {0,(dmrs_typeA_pos == 2)?2:3,(dmrs_typeA_pos == 2)?12:11}, // row index 14 {1,2,4}, // row index 15 {0,0,0} // row index 16 }; uint8_t table_5_1_2_1_1_5_time_dom_res_alloc_C[16][3]={ // for PDSCH from TS 38.214 subclause 5.1.2.1.1 {0,2,2}, // row index 1 {0,4,2}, // row index 2 {0,6,2}, // row index 3 {0,8,2}, // row index 4 {0,10,2}, // row index 5 {0,0,0}, // row index 6 {0,0,0}, // row index 7 {0,2,4}, // row index 8 {0,4,4}, // row index 9 {0,6,4}, // row index 10 {0,8,4}, // row index 11 {0,10,4}, // row index 12 {0,2,7}, // row index 13 {0,(dmrs_typeA_pos == 2)?2:3,(dmrs_typeA_pos == 2)?12:11}, // row index 14 {0,0,6}, // row index 15 {0,2,6} // row index 16 }; uint8_t mu_pusch = 1; // definition table j Table 6.1.2.1.1-4 uint8_t j = (mu_pusch==3)?3:(mu_pusch==2)?2:1; uint8_t table_6_1_2_1_1_2_time_dom_res_alloc_A[16][3]={ // for PUSCH from TS 38.214 subclause 6.1.2.1.1 {j, 0,14}, // row index 1 {j, 0,12}, // row index 2 {j, 0,10}, // row index 3 {j, 2,10}, // row index 4 {j, 4,10}, // row index 5 {j, 4,8}, // row index 6 {j, 4,6}, // row index 7 {j+1,0,14}, // row index 8 {j+1,0,12}, // row index 9 {j+1,0,10}, // row index 10 {j+2,0,14}, // row index 11 {j+2,0,12}, // row index 12 {j+2,0,10}, // row index 13 {j, 8,6}, // row index 14 {j+3,0,14}, // row index 15 {j+3,0,10} // row index 16 }; uint8_t table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[16][3]={ // for PUSCH from TS 38.214 subclause 6.1.2.1.1 {j, 0,8}, // row index 1 {j, 0,12}, // row index 2 {j, 0,10}, // row index 3 {j, 2,10}, // row index 4 {j, 4,4}, // row index 5 {j, 4,8}, // row index 6 {j, 4,6}, // row index 7 {j+1,0,8}, // row index 8 {j+1,0,12}, // row index 9 {j+1,0,10}, // row index 10 {j+2,0,6}, // row index 11 {j+2,0,12}, // row index 12 {j+2,0,10}, // row index 13 {j, 8,4}, // row index 14 {j+3,0,8}, // row index 15 {j+3,0,10} // row index 16 }; /* * Some dci fields need to be interpreted before the others. */ if (dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format-15] != 0) { // E.g: 27 HARQ_PROCESS_NUMBER (27 is the position in dci_fields_sizes array for field HARQ_PROCESS_NUMBER) for (int i=0; i<=HARQ_PROCESS_NUMBER; i++) left_shift = left_shift + dci_fields_sizes[i][dci_format-15]; nr_pdci_info_extracted->harq_process_number = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format-15])); left_shift = 0; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->harq_process_number=%x\n",nr_pdci_info_extracted->harq_process_number); #endif } /* store rnti type */ for (int k=0; k < TOTAL_NBR_SCRAMBLED_VALUES; k++) { if (rnti == crc_scrambled_values[k]) { if ((dci_format == format1_0) || (dci_format == format1_1)) { pdlsch0->rnti_type = k; } else { ulsch0->rnti_type = k; } } } if (j == TOTAL_NBR_SCRAMBLED_VALUES) { LOG_E(PHY, "Fatal error in DCI due to unknown RNTI type at line %d in function %s of file %s \n", __LINE__ , __func__, __FILE__); } if ((dci_format == format1_0) || (dci_format == format1_1)) { if (rnti==crc_scrambled_values[_SI_RNTI_]) { ue->dlsch_SI[eNB_id]->active = 1; } else if (rnti==crc_scrambled_values[_P_RNTI_]) { ue->dlsch_p[eNB_id]->active = 1; } else if (rnti==crc_scrambled_values[_RA_RNTI_]) { ue->dlsch_ra[eNB_id]->active = 1; } else { pdlsch0->active = 1; } pdlsch0->rnti = rnti; pdlsch0_harq->codeword = 0; pdlsch0_harq->Nl = 1; // pdlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; pdlsch0_harq->dl_power_off = 1; //no power offset if ((rnti==crc_scrambled_values[_SI_RNTI_]) || (rnti==crc_scrambled_values[_P_RNTI_]) || (rnti==crc_scrambled_values[_RA_RNTI_])) { pdlsch0_harq->round = 0; pdlsch0_harq->status = ACTIVE; } else { } } for (dci_field=0; dci_field<NBR_NR_DCI_FIELDS; dci_field++) { left_shift = left_shift + dci_fields_sizes[dci_field][dci_format-15]; if (dci_fields_sizes[dci_field][dci_format-15] != 0){ sizes_count = dci_fields_sizes[dci_field][dci_format-15]; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> sizes_count = dci_fields_sizes[%d][%d] = %d\n",dci_field,dci_format-15,sizes_count); #endif switch (dci_field){ case IDENTIFIER_DCI_FORMATS: // 0 IDENTIFIER_DCI_FORMATS: (field defined for format0_0,format0_1,format1_0,format1_1,format2_0,format2_1,format2_2,format2_3) // if format 0_0: The value of this bit field is always set to 0, indicating an UL DCI format (TS38.212 Section 7.3.1.1.1) // if format 1_0: The value of this bit field is always set to 1, indicating a DL DCI format (TS38.212 Section 7.3.1.2.1) nr_pdci_info_extracted->identifier_dci_formats = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->identifier_dci_formats=%x\n",nr_pdci_info_extracted->identifier_dci_formats); #endif break; case CARRIER_IND: // 1 CARRIER_IND: (field defined for -,format0_1,-,format1_1,-,-,-,-) // 0 or 3 bits, as defined in Subclause x.x of [5, TS38.213] nr_pdci_info_extracted->carrier_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->carrier_ind=%x\n",nr_pdci_info_extracted->carrier_ind); #endif break; case SUL_IND_0_1: // 2 SUL_IND_0_1: (field defined for -,format0_1,-,-,-,-,-,-) nr_pdci_info_extracted->sul_ind_0_1 = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->sul_ind_0_1=%x\n",nr_pdci_info_extracted->sul_ind_0_1); #endif break; case SLOT_FORMAT_IND: // 3 SLOT_FORMAT_IND: (field defined for -,-,-,-,format2_0,-,-,-) // size of DCI format 2_0 is configurable by higher layers up to 128 bits, according to Subclause 11.1.1 of [5, TS 38.213] nr_pdci_info_extracted->slot_format_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->slot_format_ind=%x\n",nr_pdci_info_extracted->slot_format_ind); #endif break; case PRE_EMPTION_IND: // 4 PRE_EMPTION_IND: (field defined for -,-,-,-,-,format2_1,-,-) // size of DCI format 2_1 is configurable by higher layers up to 126 bits, according to Subclause 11.2 of [5, TS 38.213]. Each pre-emption indication is 14 bits nr_pdci_info_extracted->pre_emption_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pre_emption_ind=%x\n",nr_pdci_info_extracted->pre_emption_ind); #endif break; case TPC_CMD_NUMBER: // 5 TPC_CMD_NUMBER: (field defined for -,-,-,-,-,-,format2_2,-) // The parameter xxx provided by higher layers determines the index to the TPC command number for an UL of a cell. Each TPC command number is 2 bits nr_pdci_info_extracted->tpc_cmd_number = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_cmd_number=%x\n",nr_pdci_info_extracted->tpc_cmd_number); #endif break; case BLOCK_NUMBER: // 6 BLOCK_NUMBER: (field defined for -,-,-,-,-,-,-,format2_3) // starting position of a block is determined by the parameter startingBitOfFormat2_3 nr_pdci_info_extracted->block_number = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->block_number=%x\n",nr_pdci_info_extracted->block_number); #endif break; case BANDWIDTH_PART_IND: // 7 BANDWIDTH_PART_IND: (field defined for -,format0_1,-,format1_1,-,-,-,-) nr_pdci_info_extracted->bandwidth_part_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->bandwidth_part_ind=%x\n",nr_pdci_info_extracted->bandwidth_part_ind); #endif break; case SHORT_MESSAGE_IND: // 8 SHORT_MESSAGE_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) nr_pdci_info_extracted->short_message_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->short_message_ind=%x\n",nr_pdci_info_extracted->short_message_ind); #endif break; case SHORT_MESSAGES: // 9 SHORT_MESSAGES: (field defined for -,-,format1_0,format1_1,-,-,-,-) nr_pdci_info_extracted->short_messages = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->short_messages=%x\n",nr_pdci_info_extracted->short_messages); #endif break; case FREQ_DOM_RESOURCE_ASSIGNMENT_UL: // 10 FREQ_DOM_RESOURCE_ASSIGNMENT_UL: (field defined for format0_0,format0_1,-,-,-,-,-,-) // PUSCH hopping with resource allocation type 1 not considered // According to 38.214 V15.1.0 Section 6.1.2.2 Two uplink resource allocation schemes, type 0 and type 1, are supported. // The UE shall assume that when the scheduling PDCCH is received with DCI format 0_0, then uplink resource allocation type 1 is used. nr_pdci_info_extracted->freq_dom_resource_assignment_UL = (uint16_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); if (dci_format == format0_1){ // uplink resource allocation type 0 or 1 can be used } if (dci_format == format0_0){ // only uplink resource allocation type 1 // At the moment we are supporting only format 1_0 (and not format 1_1), so we only support resource allocation type 1 (and not type 0). // For resource allocation type 1, the resource allocation field consists of a resource indication value (RIV): // RIV = n_RB_ULBWP * (l_RB - 1) + start_RB if (l_RB - 1) <= floor (n_RB_ULBWP/2) // RIV = n_RB_ULBWP * (n_RB_ULBWP - l_RB + 1) + (n_RB_ULBWP - 1 - start_RB) if (l_RB - 1) > floor (n_RB_ULBWP/2) // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_ULBWP/2) l_RB = floor(nr_pdci_info_extracted->freq_dom_resource_assignment_DL/n_RB_ULBWP) + 1; start_RB = nr_pdci_info_extracted->freq_dom_resource_assignment_DL%n_RB_ULBWP; // if (l_RB - 1) > floor (n_RB_ULBWP/2) we need to recalculate them using the following lines tmp_RIV = n_RB_ULBWP * (l_RB - 1) + start_RB; if (tmp_RIV != nr_pdci_info_extracted->freq_dom_resource_assignment_DL) { // then (l_RB - 1) > floor (n_RB_ULBWP/2) and we need to recalculate l_RB and start_RB l_RB = n_RB_ULBWP - l_RB + 2; start_RB = n_RB_ULBWP - start_RB - 1; } ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->first_rb = start_RB; ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->nb_rb = l_RB; } #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_dom_resource_assignment_UL=%x\n",nr_pdci_info_extracted->freq_dom_resource_assignment_UL); printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> l_RB=%d, start_RB=%d, n_RB_DLBWP=%d\n",l_RB,start_RB,n_RB_ULBWP); #endif break; case FREQ_DOM_RESOURCE_ASSIGNMENT_DL: // 11 FREQ_DOM_RESOURCE_ASSIGNMENT_DL: (field defined for -,-,format1_0,format1_1,-,-,-,-) // According to 38.214 V15.1.0 Section 5.1.2.2 Two downlink resource allocation schemes, type 0 and type 1, are supported. // The UE shall assume that when the scheduling grant is received with DCI format 1_0, then downlink resource allocation type 1 is used. nr_pdci_info_extracted->freq_dom_resource_assignment_DL = (uint16_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); if (dci_format == format1_1){ // uplink resource allocation type 0 or 1 can be used } if (dci_format == format1_0){ // only uplink resource allocation type 1 // At the moment we are supporting only format 0_0 (and not format 0_1), so we only support resource allocation type 1 (and not type 0). // For resource allocation type 1, the resource allocation field consists of a resource indication value (RIV): // RIV = n_RB_DLBWP * (l_RB - 1) + start_RB if (l_RB - 1) <= floor (n_RB_DLBWP/2) // RIV = n_RB_DLBWP * (n_RB_DLBWP - l_RB + 1) + (n_RB_DLBWP - 1 - start_RB) if (l_RB - 1) > floor (n_RB_DLBWP/2) // the following two expressions apply only if (l_RB - 1) <= floor (n_RB_DLBWP/2) l_RB = floor(nr_pdci_info_extracted->freq_dom_resource_assignment_DL/n_RB_DLBWP) + 1; start_RB = nr_pdci_info_extracted->freq_dom_resource_assignment_DL%n_RB_DLBWP; // if (l_RB - 1) > floor (n_RB_DLBWP/2) we need to recalculate them using the following lines tmp_RIV = n_RB_DLBWP * (l_RB - 1) + start_RB; if (tmp_RIV != nr_pdci_info_extracted->freq_dom_resource_assignment_DL) { // then (l_RB - 1) > floor (n_RB_DLBWP/2) and we need to recalculate l_RB and start_RB l_RB = n_RB_DLBWP - l_RB + 2; start_RB = n_RB_DLBWP - start_RB - 1; } pdlsch0_harq->nb_rb = l_RB; } #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_dom_resource_assignment_DL=%x, RIV = %d\n",nr_pdci_info_extracted->freq_dom_resource_assignment_DL,nr_pdci_info_extracted->freq_dom_resource_assignment_DL); printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> l_RB=%d, start_RB=%d, n_RB_DLBWP=%d\n",l_RB,start_RB,n_RB_DLBWP); /* * According to TC 38.212 Subclause 7.3.1.2.1 (V15.2.0) (not implemented FIXME!!!) * If the CRC of the DCI format 1_0 is scrambled by C-RNTI * and the "Frequency domain resource assignment" field are of all ones, * the DCI format 1_0 is for random access procedure initiated by a PDCCH order, * with all remaining fields set as follows: * - Random Access Preamble index (6 bits) * - UL/SUL indicator (1 bit) * - SS/PBCH index (6 bits) * - PRACH Mask index (4 bits) * - Reserved bits (10 bits) * */ /* * The following commented code is used to verify that l_RB and start_RB are correctly calculated * * printf("\ns_RB\t"); n_RB_DLBWP = 20; for (int k = 0 ; k < n_RB_DLBWP; k++) printf("%d\t",k); printf("\nl_RB"); for (int j = 1 ; j <= n_RB_DLBWP; j++){ // l_RB printf("\n%d\t",j); for (int i = 0 ; i < n_RB_DLBWP; i++) { // start_RB if ((j-1) <= (floor(n_RB_DLBWP/2)) && ((j+i) <= n_RB_DLBWP)) { tmp_RIV = n_RB_DLBWP * (j - 1) + i; l_RB = floor(tmp_RIV/n_RB_DLBWP) + 1; start_RB = tmp_RIV%n_RB_DLBWP; printf("%d(%d,%d) ",tmp_RIV,l_RB,start_RB); } if ((j-1) > (floor(n_RB_DLBWP/2)) && ((j+i) <= n_RB_DLBWP)) { tmp_RIV = n_RB_DLBWP * (n_RB_DLBWP - j + 1) + (n_RB_DLBWP - 1 - i); //l_RB = floor(tmp_RIV/n_RB_DLBWP) + 1; //start_RB = tmp_RIV%n_RB_DLBWP; l_RB = n_RB_DLBWP - (floor(tmp_RIV/n_RB_DLBWP) + 1) + 2; start_RB = n_RB_DLBWP - (tmp_RIV%n_RB_DLBWP) - 1; printf("%d*(%d,%d) ",tmp_RIV,l_RB,start_RB); } } }*/ #endif break; case TIME_DOM_RESOURCE_ASSIGNMENT: // 12 TIME_DOM_RESOURCE_ASSIGNMENT: (field defined for format0_0,format0_1,format1_0,format1_1,-,-,-,-) // 0, 1, 2, 3, or 4 bits as defined in: // Subclause 6.1.2.1 of [6, TS 38.214] for formats format0_0,format0_1 // Subclause 5.1.2.1 of [6, TS 38.214] for formats format1_0,format1_1 // The bitwidth for this field is determined as log2(I) bits, // where I the number of entries in the higher layer parameter pusch-AllocationList nr_pdci_info_extracted->time_dom_resource_assignment = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); if (dci_format == format0_0 || dci_format == format0_1){ // Subclause 6.1.2.1 of [6, TS 38.214] k_offset = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][0]; sliv_S = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][1]; sliv_L = table_6_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][2]; // k_offset = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; // sliv_S = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; // sliv_L = table_6_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; } if (dci_format == format1_0 || dci_format == format1_1){ // Subclause 5.1.2.1 of [6, TS 38.214] // the Time domain resource assignment field of the DCI provides a row index of a higher layer configured table pdsch-symbolAllocation // FIXME! To clarify which parameters to update after reception of row index k_offset = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][0]; sliv_S = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][1]; sliv_L = table_5_1_2_1_1_2_time_dom_res_alloc_A[nr_pdci_info_extracted->time_dom_resource_assignment][2]; // k_offset = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][0]; // sliv_S = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][1]; // sliv_L = table_5_1_2_1_1_3_time_dom_res_alloc_A_extCP[nr_pdci_info_extracted->time_dom_resource_assignment][2]; // k_offset = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][0]; // sliv_S = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][1]; // sliv_L = table_5_1_2_1_1_4_time_dom_res_alloc_B[nr_pdci_info_extracted->time_dom_resource_assignment][2]; // k_offset = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][0]; // sliv_S = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][1]; // sliv_L = table_5_1_2_1_1_5_time_dom_res_alloc_C[nr_pdci_info_extracted->time_dom_resource_assignment][2]; } #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->time_dom_resource_assignment=%x\n",nr_pdci_info_extracted->time_dom_resource_assignment); #endif break; case VRB_TO_PRB_MAPPING: // 13 VRB_TO_PRB_MAPPING: (field defined for -,format0_1,format1_0,format1_1,-,-,-,-) //0 bit if resource allocation type 0 //1 bit if resource allocation type 1 //Table 7.3.1.1.2-33: VRB-to-PRB mapping // 0 Non-interleaved // 1 Interleaved nr_pdci_info_extracted->vrb_to_prb_mapping = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); if (nr_pdci_info_extracted->vrb_to_prb_mapping == 0) { // Non-interleaved } else { // Interleaved // format 0_1 defined in TS 38.211 Section 6.3.1.7 // formats 1_0 and 1_1 not defined yet } #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->vrb_to_prb_mapping=%x\n",nr_pdci_info_extracted->vrb_to_prb_mapping); #endif break; case PRB_BUNDLING_SIZE_IND: // 14 PRB_BUNDLING_SIZE_IND: (field defined for -,-,-,format1_1,-,-,-,-) // 0 bit if the higher layer parameter PRB_bundling is not configured or is set to 'static', or 1 bit if the higher layer parameter PRB_bundling is set to 'dynamic' according to Subclause 5.1.2.3 of [6, TS 38.214] nr_pdci_info_extracted->prb_bundling_size_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->prb_bundling_size_ind=%x\n",nr_pdci_info_extracted->prb_bundling_size_ind); #endif break; case RATE_MATCHING_IND: // 15 RATE_MATCHING_IND: (field defined for -,-,-,format1_1,-,-,-,-) // 0, 1, or 2 bits according to higher layer parameter rate-match-PDSCH-resource-set nr_pdci_info_extracted->rate_matching_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->rate_matching_ind=%x\n",nr_pdci_info_extracted->rate_matching_ind); #endif break; case ZP_CSI_RS_TRIGGER: // 16 ZP_CSI_RS_TRIGGER: (field defined for -,-,-,format1_1,-,-,-,-) nr_pdci_info_extracted->zp_csi_rs_trigger = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->zp_csi_rs_trigger=%x\n",nr_pdci_info_extracted->zp_csi_rs_trigger); #endif break; case FREQ_HOPPING_FLAG: // 17 FREQ_HOPPING_FLAG: (field defined for format0_0,format0_1,-,-,-,-,-,-) // 0 bit if only resource allocation type 0 // 1 bit otherwise, only applicable to resource allocation type 1, as defined in Subclause 6.3 of [6, TS 38.214] nr_pdci_info_extracted->freq_hopping_flag = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); if (nr_pdci_info_extracted->freq_hopping_flag != 0) { // PUSCH frequency hopping is performed (only resource allocation type 1) } else { // PUSCH frequency hopping is not performed (only resource allocation type 1) // At the moment PUSCH hopping is not implemented. We are considering that the bit is present and the value is '0' } #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->freq_hopping_flag=%x\n",nr_pdci_info_extracted->freq_hopping_flag); #endif break; case TB1_MCS: // 18 TB1_MCS: (field defined for -,-,-,format1_1,-,-,-,-) nr_pdci_info_extracted->tb1_mcs = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs = nr_pdci_info_extracted->tb1_mcs; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_mcs=%x\n",nr_pdci_info_extracted->tb1_mcs); #endif break; case TB1_NDI: // 19 TB1_NDI: (field defined for -,-,-,format1_1,-,-,-,-) nr_pdci_info_extracted->tb1_ndi = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); pdlsch0_harq->DCINdi = nr_pdci_info_extracted->tb1_ndi; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_ndi=%x\n",nr_pdci_info_extracted->tb1_ndi); #endif break; case TB1_RV: // 20 TB1_RV: (field defined for -,-,-,format1_1,-,-,-,-) nr_pdci_info_extracted->tb1_rv = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); pdlsch0_harq->rvidx = nr_pdci_info_extracted->tb1_rv; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb1_rv=%x\n",nr_pdci_info_extracted->tb1_rv); #endif break; case TB2_MCS: // 21 TB2_MCS: (field defined for -,-,-,format1_1,-,-,-,-) nr_pdci_info_extracted->tb2_mcs = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); if (nr_pdci_info_extracted->mcs < 29) pdlsch0_harq->mcs = nr_pdci_info_extracted->tb2_mcs; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_mcs=%x\n",nr_pdci_info_extracted->tb2_mcs); #endif break; case TB2_NDI: // 22 TB2_NDI: (field defined for -,-,-,format1_1,-,-,-,-) nr_pdci_info_extracted->tb2_ndi = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); pdlsch0_harq->DCINdi = nr_pdci_info_extracted->tb2_ndi; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_ndi=%x\n",nr_pdci_info_extracted->tb2_ndi); #endif break; case TB2_RV: // 23 TB2_RV: (field defined for -,-,-,format1_1,-,-,-,-) nr_pdci_info_extracted->tb2_rv = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); pdlsch0_harq->rvidx = nr_pdci_info_extracted->tb2_rv; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb2_rv=%x\n",nr_pdci_info_extracted->tb2_rv); #endif break; case MCS: // 24 MCS: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) nr_pdci_info_extracted->mcs = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); if (nr_pdci_info_extracted->mcs < 29) { if (dci_format == format0_0 || dci_format == format0_1) ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->mcs = nr_pdci_info_extracted->mcs; else pdlsch0_harq->mcs = nr_pdci_info_extracted->mcs; } else { return(0); } #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->mcs=%x\n",nr_pdci_info_extracted->mcs); #endif break; case NDI: // 25 NDI: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) nr_pdci_info_extracted->ndi = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ndi=%x\n",nr_pdci_info_extracted->ndi); #endif break; case RV: // 26 RV: (field defined for format0_0,format0_1,format1_0,-,-,-,-,-) nr_pdci_info_extracted->rv = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); if (dci_format == format0_0 || dci_format == format0_1) ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->rvidx = nr_pdci_info_extracted->rv; else pdlsch0_harq->rvidx = nr_pdci_info_extracted->rv; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->rv=%x\n",nr_pdci_info_extracted->rv); #endif break; case HARQ_PROCESS_NUMBER: // 27 HARQ_PROCESS_NUMBER: (field defined for format0_0,format0_1,format1_0,format1_1,-,-,-,-) nr_pdci_info_extracted->harq_process_number = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->harq_process_number=%x\n",nr_pdci_info_extracted->harq_process_number); #endif break; case DAI_: // 28 DAI_: (field defined for -,-,format1_0,format1_1,-,-,-,-) // For format1_0: 2 bits as defined in Subclause 9.1.3 at TS 38.213 // For format1_1: 4 if more than one serving cell are configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 MSB bits are the counter DAI and the 2 LSB bits are the total DAI // 2 if one serving cell is configured in the DL and the higher layer parameter HARQ-ACK-codebook=dynamic, where the 2 bits are the counter DAI // 0 otherwise nr_pdci_info_extracted->dai = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->dai=%x\n",nr_pdci_info_extracted->dai); #endif break; case FIRST_DAI: // 29 FIRST_DAI: (field defined for -,format0_1,-,-,-,-,-,-) // (1 or 2 bits) 1 bit for semi-static HARQ-ACK nr_pdci_info_extracted->first_dai = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->first_dai=%x\n",nr_pdci_info_extracted->first_dai); #endif break; case SECOND_DAI: // 30 SECOND_DAI: (field defined for -,format0_1,-,-,-,-,-,-) // (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks nr_pdci_info_extracted->second_dai = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->second_dai=%x\n",nr_pdci_info_extracted->second_dai); #endif break; case TB_SCALING: // 31 TB_SCALING: (field defined for -,format0_1,-,-,-,-,-,-) // (0 or 2 bits) 2 bits for dynamic HARQ-ACK codebook with two HARQ-ACK sub-codebooks nr_pdci_info_extracted->tb_scaling = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tb_scaling=%x\n",nr_pdci_info_extracted->tb_scaling); #endif break; case TPC_PUSCH: // 32 TPC_PUSCH: (field defined for format0_0,format0_1,-,-,-,-,-,-) // defined in Subclause 7.1.1 TS 38.213 nr_pdci_info_extracted->tpc_pusch = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC = nr_pdci_info_extracted->tpc_pusch; if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) { ulsch0->f_pusch += nr_delta_PUSCH_acc[ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC]; } else { ulsch0->f_pusch = nr_delta_PUSCH_abs[ulsch0->harq_processes[nr_pdci_info_extracted->harq_process_number]->TPC]; } #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_pusch=%x\n",nr_pdci_info_extracted->tpc_pusch); #endif break; case TPC_PUCCH: // 33 TPC_PUCCH: (field defined for -,-,format1_0,format1_1,-,-,-,-) // defined in Subclause 7.2.1 TS 38.213 nr_pdci_info_extracted->tpc_pucch = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); pdlsch0_harq->delta_PUCCH = nr_delta_PUCCH_lut[nr_pdci_info_extracted->tpc_pucch &3]; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_pucch=%x\n",nr_pdci_info_extracted->tpc_pucch); #endif break; case PUCCH_RESOURCE_IND: // 34 PUCCH_RESOURCE_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) // defined in Subclause 9.2.3 TS 38.213 // PUCCH_RESOURCE_IND points to PUCCH-ResourceId, but PUCCH-ResourceId is not defined yet nr_pdci_info_extracted->pucch_resource_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pucch_resource_ind=%x\n",nr_pdci_info_extracted->pucch_resource_ind); #endif break; case PDSCH_TO_HARQ_FEEDBACK_TIME_IND: // 35 PDSCH_TO_HARQ_FEEDBACK_TIME_IND: (field defined for -,-,format1_0,format1_1,-,-,-,-) // defined in Subclause 9.2.3 TS 38.213 // PDSCH_TO_HARQ_FEEDBACK_TIME_IND points to DL-data-DL-acknowledgement, but DL-data-DL-acknowledgement is not defined yet nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind=%x\n",nr_pdci_info_extracted->pdsch_to_harq_feedback_time_ind); #endif break; case SRS_RESOURCE_IND: // 36 SRS_RESOURCE_IND: (field defined for -,format0_1,-,-,-,-,-,-) nr_pdci_info_extracted->srs_resource_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->srs_resource_ind=%x\n",nr_pdci_info_extracted->srs_resource_ind); #endif break; case PRECOD_NBR_LAYERS: // 37 PRECOD_NBR_LAYERS: (field defined for -,format0_1,-,-,-,-,-,-) nr_pdci_info_extracted->precod_nbr_layers = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->precod_nbr_layers=%x\n",nr_pdci_info_extracted->precod_nbr_layers); #endif break; case ANTENNA_PORTS: // 38 ANTENNA_PORTS: (field defined for -,format0_1,-,format1_1,-,-,-,-) nr_pdci_info_extracted->antenna_ports = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->antenna_ports=%x\n",nr_pdci_info_extracted->antenna_ports); #endif break; case TCI: // 39 TCI: (field defined for -,-,-,format1_1,-,-,-,-) // 0 bit if higher layer parameter tci-PresentInDCI is not enabled; otherwise 3 bits nr_pdci_info_extracted->tci = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tci=%x\n",nr_pdci_info_extracted->tci); #endif break; case SRS_REQUEST: // 40 SRS_REQUEST: (field defined for -,format0_1,-,format1_1,-,-,-,format2_3) nr_pdci_info_extracted->srs_request = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->srs_request=%x\n",nr_pdci_info_extracted->srs_request); #endif break; case TPC_CMD_NUMBER_FORMAT2_3: // 41 TPC_CMD_NUMBER_FORMAT2_3: (field defined for -,-,-,-,-,-,-,format2_3) nr_pdci_info_extracted->tpc_cmd_number_format2_3 = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->tpc_cmd_number_format2_3=%x\n",nr_pdci_info_extracted->tpc_cmd_number_format2_3); #endif break; case CSI_REQUEST: // 42 CSI_REQUEST: (field defined for -,format0_1,-,-,-,-,-,-) nr_pdci_info_extracted->csi_request = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->csi_request=%x\n",nr_pdci_info_extracted->csi_request); #endif break; case CBGTI: // 43 CBGTI: (field defined for -,format0_1,-,format1_1,-,-,-,-) // 0, 2, 4, 6, or 8 bits determined by higher layer parameter maxCodeBlockGroupsPerTransportBlock for the PDSCH nr_pdci_info_extracted->cbgti = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->cbgti=%x\n",nr_pdci_info_extracted->cbgti); #endif break; case CBGFI: // 44 CBGFI: (field defined for -,-,-,format1_1,-,-,-,-) // 0 or 1 bit determined by higher layer parameter codeBlockGroupFlushIndicator nr_pdci_info_extracted->cbgfi = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->cbgfi=%x\n",nr_pdci_info_extracted->cbgfi); #endif break; case PTRS_DMRS: // 45 PTRS_DMRS: (field defined for -,format0_1,-,-,-,-,-,-) nr_pdci_info_extracted->ptrs_dmrs = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ptrs_dmrs=%x\n",nr_pdci_info_extracted->ptrs_dmrs); #endif break; case BETA_OFFSET_IND: // 46 BETA_OFFSET_IND: (field defined for -,format0_1,-,-,-,-,-,-) nr_pdci_info_extracted->beta_offset_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->beta_offset_ind=%x\n",nr_pdci_info_extracted->beta_offset_ind); #endif break; case DMRS_SEQ_INI: // 47 DMRS_SEQ_INI: (field defined for -,format0_1,-,format1_1,-,-,-,-) // 1 bit if the cell has two ULs and the number of bits for DCI format 1_0 before padding is larger than the number of bits for DCI format 0_0 before padding; 0 bit otherwise nr_pdci_info_extracted->dmrs_seq_ini = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->dmrs_seq_ini=%x\n",nr_pdci_info_extracted->dmrs_seq_ini); #endif break; case UL_SCH_IND: // 48 UL_SCH_IND: (field defined for -,format0_1,-,-,-,-,-,-) // value of "1" indicates UL-SCH shall be transmitted on the PUSCH and a value of "0" indicates UL-SCH shall not be transmitted on the PUSCH nr_pdci_info_extracted->ul_sch_ind = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->dmrs_seq_ini=%x\n",nr_pdci_info_extracted->ul_sch_ind); #endif break; case PADDING_NR_DCI: // 49 PADDING_NR_DCI: (field defined for format0_0,-,format1_0,-,-,-,-,-) // (Note 2) If DCI format 0_0 is monitored in common search space nr_pdci_info_extracted->padding_nr_dci = (uint16_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->padding=%x\n",nr_pdci_info_extracted->padding_nr_dci); #endif break; case SUL_IND_0_0: // 50 SUL_IND_0_0: (field defined for format0_0,-,-,-,-,-,-,-) nr_pdci_info_extracted->sul_ind_0_0 = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->sul_ind_0_0=%x\n",nr_pdci_info_extracted->sul_ind_0_0); #endif break; case RA_PREAMBLE_INDEX: // 51 RA_PREAMBLE_INDEX: (field defined for format0_0,-,-,-,-,-,-,-) nr_pdci_info_extracted->ra_preamble_index = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ra_preamble_index=%x\n",nr_pdci_info_extracted->ra_preamble_index); #endif break; case SUL_IND_1_0: // 52 SUL_IND_1_0: (field defined for -,-,format1_0,-,-,-,-,-) nr_pdci_info_extracted->sul_ind_1_0 = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->sul_ind_1_0=%x\n",nr_pdci_info_extracted->sul_ind_1_0); #endif break; case SS_PBCH_INDEX: // 53 SS_PBCH_INDEX: (field defined for -,-,format1_0,-,-,-,-,-) nr_pdci_info_extracted->ss_pbch_index = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->ss_pbch_index=%x\n",nr_pdci_info_extracted->ss_pbch_index); #endif break; case PRACH_MASK_INDEX: // 54 PRACH_MASK_INDEX: (field defined for -,-,-,format1_0,-,-,-,-) nr_pdci_info_extracted->prach_mask_index = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->prach_mask_index=%x\n",nr_pdci_info_extracted->prach_mask_index); #endif break; case RESERVED_NR_DCI: // 55 RESERVED_NR_DCI: (field defined for -,-,-,format1_0,-,-,-,-) nr_pdci_info_extracted->reserved_nr_dci = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[dci_field][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[dci_field][dci_format-15])); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> nr_pdci_info_extracted->reserved_nr_dci=%x\n",nr_pdci_info_extracted->reserved_nr_dci); #endif break; } } } /* process harq -> set dlsch[0]->harq_processes[dlsch[0]->current_harq_pid].rx_status give NEW TRANSMISSION or RETRANSMISSION */ get_dci_info_for_harq(ue, nr_pdci_info_extracted, pdlsch0, ulsch0, nr_tti_rx, k_offset); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_extract_dci_info) -> Ending function nr_extract_dci_info()\n"); #endif return(1); } #endif #if 0 void extract_dci1A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) { uint8_t harq_pid=0; uint32_t rballoc=0; uint8_t vrb_type=0; uint8_t mcs=0; uint8_t rv=0; uint8_t ndi=0; uint8_t TPC=0; uint8_t dai=0; switch (N_RB_DL) { case 6: if (frame_type == TDD) { vrb_type = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type; mcs = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; rv = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->rv; ndi = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi; TPC = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; dai = ((DCI1A_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); } else { vrb_type = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->vrb_type; mcs = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rballoc; rv = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->rv; ndi = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->ndi; TPC = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_1_5MHz_FDD_t *)dci_pdu)->harq_pid; //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); } break; case 25: if (frame_type == TDD) { vrb_type = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->vrb_type; mcs = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; rv = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->rv; ndi = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->ndi; TPC = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->harq_pid; dai = ((DCI1A_5MHz_TDD_1_6_t *)dci_pdu)->dai; //printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); } else { vrb_type = ((DCI1A_5MHz_FDD_t *)dci_pdu)->vrb_type; mcs = ((DCI1A_5MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rballoc; rv = ((DCI1A_5MHz_FDD_t *)dci_pdu)->rv; ndi = ((DCI1A_5MHz_FDD_t *)dci_pdu)->ndi; TPC = ((DCI1A_5MHz_FDD_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_5MHz_FDD_t *)dci_pdu)->harq_pid; //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); } break; case 50: if (frame_type == TDD) { vrb_type = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->vrb_type; mcs = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rballoc; rv = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->rv; ndi = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->ndi; TPC = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->harq_pid; dai = ((DCI1A_10MHz_TDD_1_6_t *)dci_pdu)->dai; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); } else { vrb_type = ((DCI1A_10MHz_FDD_t *)dci_pdu)->vrb_type; mcs = ((DCI1A_10MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rballoc; rv = ((DCI1A_10MHz_FDD_t *)dci_pdu)->rv; ndi = ((DCI1A_10MHz_FDD_t *)dci_pdu)->ndi; TPC = ((DCI1A_10MHz_FDD_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_10MHz_FDD_t *)dci_pdu)->harq_pid; //printf("FDD 1A: mcs %d, vrb_type %d, rballoc %x,ndi %d, rv %d, TPC %d\n",mcs,vrb_type,rballoc,ndi,rv,TPC); } break; case 100: if (frame_type == TDD) { vrb_type = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->vrb_type; mcs = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rballoc; rv = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->rv; ndi = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->ndi; TPC = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->harq_pid; dai = ((DCI1A_20MHz_TDD_1_6_t *)dci_pdu)->dai; // printf("TDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); } else { vrb_type = ((DCI1A_20MHz_FDD_t *)dci_pdu)->vrb_type; mcs = ((DCI1A_20MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rballoc; rv = ((DCI1A_20MHz_FDD_t *)dci_pdu)->rv; ndi = ((DCI1A_20MHz_FDD_t *)dci_pdu)->ndi; TPC = ((DCI1A_20MHz_FDD_t *)dci_pdu)->TPC; harq_pid = ((DCI1A_20MHz_FDD_t *)dci_pdu)->harq_pid; //printf("FDD 1A: mcs %d, rballoc %x,rv %d, TPC %d\n",mcs,rballoc,rv,TPC); } break; } pdci_info_extarcted->vrb_type = vrb_type; pdci_info_extarcted->mcs1 = mcs; pdci_info_extarcted->rballoc = rballoc; pdci_info_extarcted->rv1 = rv; pdci_info_extarcted->ndi1 = ndi; pdci_info_extarcted->TPC = TPC; pdci_info_extarcted->harq_pid = harq_pid; pdci_info_extarcted->dai = dai; } void extract_dci1C_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) { uint32_t rballoc=0; uint8_t mcs=0; switch (N_RB_DL) { case 6: mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); break; case 25: mcs = ((DCI1C_5MHz_t *)dci_pdu)->mcs; rballoc = conv_1C_RIV(((DCI1C_5MHz_t *)dci_pdu)->rballoc,6); break; case 50: mcs = ((DCI1C_10MHz_t *)dci_pdu)->mcs; rballoc = conv_1C_RIV(((DCI1C_10MHz_t *)dci_pdu)->rballoc,6); break; case 100: mcs = ((DCI1C_20MHz_t *)dci_pdu)->mcs; rballoc = conv_1C_RIV(((DCI1C_20MHz_t *)dci_pdu)->rballoc,6); break; default: AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",N_RB_DL); break; } pdci_info_extarcted->mcs1 = mcs; pdci_info_extarcted->rballoc = rballoc; } void extract_dci1_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) { uint32_t rballoc=0; uint8_t mcs=0; uint8_t rah=0; uint8_t rv=0; uint8_t TPC=0; uint8_t ndi=0; uint8_t harq_pid=0; switch (N_RB_DL) { case 6: if (frame_type == TDD) { mcs = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->mcs; rballoc = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rballoc; rah = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rah; rv = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->rv; TPC = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->TPC; ndi = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->ndi; harq_pid = ((DCI1_1_5MHz_TDD_t *)dci_pdu)->harq_pid; } else { mcs = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->mcs; rah = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rah; rballoc = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rballoc; rv = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->rv; TPC = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->TPC; ndi = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->ndi; harq_pid = ((DCI1_1_5MHz_FDD_t *)dci_pdu)->harq_pid; } break; case 25: if (frame_type == TDD) { mcs = ((DCI1_5MHz_TDD_t *)dci_pdu)->mcs; rballoc = ((DCI1_5MHz_TDD_t *)dci_pdu)->rballoc; rah = ((DCI1_5MHz_TDD_t *)dci_pdu)->rah; rv = ((DCI1_5MHz_TDD_t *)dci_pdu)->rv; TPC = ((DCI1_5MHz_TDD_t *)dci_pdu)->TPC; ndi = ((DCI1_5MHz_TDD_t *)dci_pdu)->ndi; harq_pid = ((DCI1_5MHz_TDD_t *)dci_pdu)->harq_pid; } else { mcs = ((DCI1_5MHz_FDD_t *)dci_pdu)->mcs; rah = ((DCI1_5MHz_FDD_t *)dci_pdu)->rah; rballoc = ((DCI1_5MHz_FDD_t *)dci_pdu)->rballoc; rv = ((DCI1_5MHz_FDD_t *)dci_pdu)->rv; TPC = ((DCI1_5MHz_FDD_t *)dci_pdu)->TPC; ndi = ((DCI1_5MHz_FDD_t *)dci_pdu)->ndi; harq_pid = ((DCI1_5MHz_FDD_t *)dci_pdu)->harq_pid; } break; case 50: if (frame_type == TDD) { mcs = ((DCI1_10MHz_TDD_t *)dci_pdu)->mcs; rballoc = ((DCI1_10MHz_TDD_t *)dci_pdu)->rballoc; rah = ((DCI1_10MHz_TDD_t *)dci_pdu)->rah; rv = ((DCI1_10MHz_TDD_t *)dci_pdu)->rv; TPC = ((DCI1_10MHz_TDD_t *)dci_pdu)->TPC; ndi = ((DCI1_10MHz_TDD_t *)dci_pdu)->ndi; harq_pid = ((DCI1_10MHz_TDD_t *)dci_pdu)->harq_pid; } else { mcs = ((DCI1_10MHz_FDD_t *)dci_pdu)->mcs; rah = ((DCI1_10MHz_FDD_t *)dci_pdu)->rah; rballoc = ((DCI1_10MHz_FDD_t *)dci_pdu)->rballoc; rv = ((DCI1_10MHz_FDD_t *)dci_pdu)->rv; TPC = ((DCI1_10MHz_FDD_t *)dci_pdu)->TPC; ndi = ((DCI1_10MHz_FDD_t *)dci_pdu)->ndi; harq_pid = ((DCI1_10MHz_FDD_t *)dci_pdu)->harq_pid; } break; case 100: if (frame_type == TDD) { mcs = ((DCI1_20MHz_TDD_t *)dci_pdu)->mcs; rballoc = ((DCI1_20MHz_TDD_t *)dci_pdu)->rballoc; rah = ((DCI1_20MHz_TDD_t *)dci_pdu)->rah; rv = ((DCI1_20MHz_TDD_t *)dci_pdu)->rv; TPC = ((DCI1_20MHz_TDD_t *)dci_pdu)->TPC; ndi = ((DCI1_20MHz_TDD_t *)dci_pdu)->ndi; harq_pid = ((DCI1_20MHz_TDD_t *)dci_pdu)->harq_pid; } else { mcs = ((DCI1_20MHz_FDD_t *)dci_pdu)->mcs; rah = ((DCI1_20MHz_FDD_t *)dci_pdu)->rah; rballoc = ((DCI1_20MHz_FDD_t *)dci_pdu)->rballoc; rv = ((DCI1_20MHz_FDD_t *)dci_pdu)->rv; TPC = ((DCI1_20MHz_FDD_t *)dci_pdu)->TPC; ndi = ((DCI1_20MHz_FDD_t *)dci_pdu)->ndi; harq_pid = ((DCI1_20MHz_FDD_t *)dci_pdu)->harq_pid; } break; } pdci_info_extarcted->mcs1 = mcs; pdci_info_extarcted->rah = rah; pdci_info_extarcted->rballoc = rballoc; pdci_info_extarcted->rv1 = rv; pdci_info_extarcted->TPC = TPC; pdci_info_extarcted->ndi1 = ndi; pdci_info_extarcted->harq_pid = harq_pid; } void extract_dci2_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) { uint32_t rballoc=0; uint8_t rah=0; uint8_t mcs1=0; uint8_t mcs2=0; uint8_t rv1=0; uint8_t rv2=0; uint8_t ndi1=0; uint8_t ndi2=0; uint8_t tbswap=0; uint8_t tpmi=0; uint8_t harq_pid=0; uint8_t TPC=0; switch (N_RB_DL) { case 6: if (nb_antenna_ports_eNB == 2) { if (frame_type == TDD) { rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; } else { rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; } } else if (nb_antenna_ports_eNB == 4) { if (frame_type == TDD) { rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->ndi2; } else { rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; } } else { LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); } break; case 25: if (nb_antenna_ports_eNB == 2) { if (frame_type == TDD) { rah = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; } else { rah = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_5MHz_2A_FDD_t *)dci_pdu)->ndi2; } } else if (nb_antenna_ports_eNB == 4) { if (frame_type == TDD) { rah = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_5MHz_4A_TDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_5MHz_2A_TDD_t *)dci_pdu)->ndi2; } else { rah = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_5MHz_4A_FDD_t *)dci_pdu)->ndi2; } } else { LOG_E(PHY,"UE: Format2 DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); } break; case 50: if (nb_antenna_ports_eNB == 2) { if (frame_type == TDD) { rah = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_10MHz_2A_TDD_t *)dci_pdu)->ndi2; } else { rah = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_10MHz_2A_FDD_t *)dci_pdu)->ndi2; } } else if (nb_antenna_ports_eNB == 4) { if (frame_type == TDD) { rah = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_10MHz_4A_TDD_t *)dci_pdu)->ndi2; } else { rah = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_10MHz_4A_FDD_t *)dci_pdu)->ndi2; } } else { LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); } break; case 100: if (nb_antenna_ports_eNB == 2) { if (frame_type == TDD) { rah = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_20MHz_2A_TDD_t *)dci_pdu)->ndi2; } else { rah = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_20MHz_2A_FDD_t *)dci_pdu)->ndi2; } } else if (nb_antenna_ports_eNB == 4) { if (frame_type == TDD) { rah = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_20MHz_4A_TDD_t *)dci_pdu)->ndi2; } else { rah = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rah; mcs1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->rv2; harq_pid = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->TPC; ndi1 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2_20MHz_4A_FDD_t *)dci_pdu)->ndi2; } } else { LOG_E(PHY,"UE: Format2A DCI: unsupported number of TX antennas %d\n",nb_antenna_ports_eNB); } break; } pdci_info_extarcted->rah = rah; pdci_info_extarcted->mcs1 = mcs1; pdci_info_extarcted->mcs2 = mcs2; pdci_info_extarcted->rv1 = rv1; pdci_info_extarcted->rv2 = rv2; pdci_info_extarcted->harq_pid = harq_pid; pdci_info_extarcted->rballoc = rballoc; pdci_info_extarcted->tb_swap = tbswap; pdci_info_extarcted->tpmi = tpmi; pdci_info_extarcted->TPC = TPC; pdci_info_extarcted->ndi1 = ndi1; pdci_info_extarcted->ndi2 = ndi2; } void extract_dci2A_info(uint8_t N_RB_DL, lte_frame_type_t frame_type, uint8_t nb_antenna_ports_eNB, void *dci_pdu, DCI_INFO_EXTRACTED_t *pdci_info_extarcted) { uint32_t rballoc=0; uint8_t rah=0; uint8_t mcs1=0; uint8_t mcs2=0; uint8_t rv1=0; uint8_t rv2=0; uint8_t ndi1=0; uint8_t ndi2=0; uint8_t tbswap=0; uint8_t tpmi=0; uint8_t harq_pid=0; uint8_t TPC=0; AssertFatal( (nb_antenna_ports_eNB == 2) || (nb_antenna_ports_eNB == 4), "unsupported nb_antenna_ports_eNB %d\n", nb_antenna_ports_eNB); switch (N_RB_DL) { case 6: if (nb_antenna_ports_eNB == 2) { if (frame_type == TDD) { mcs1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; TPC = ((DCI2A_1_5MHz_2A_TDD_t *)dci_pdu)->TPC; } else { mcs1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; TPC = ((DCI2A_1_5MHz_2A_FDD_t *)dci_pdu)->TPC; } } else if (nb_antenna_ports_eNB == 4) { if (frame_type == TDD) { mcs1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2A_1_5MHz_4A_TDD_t *)dci_pdu)->TPC; } else { mcs1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rballoc; rv1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2A_1_5MHz_4A_FDD_t *)dci_pdu)->TPC; } } break; case 25: if (nb_antenna_ports_eNB == 2) { if (frame_type == TDD) { mcs1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->tb_swap; TPC = ((DCI2A_5MHz_2A_TDD_t *)dci_pdu)->TPC; } else { mcs1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->tb_swap; TPC = ((DCI2A_5MHz_2A_FDD_t *)dci_pdu)->TPC; } } else if (nb_antenna_ports_eNB == 4) { if (frame_type == TDD) { mcs1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->TPC; } else { mcs1 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_5MHz_4A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2A_5MHz_4A_FDD_t *)dci_pdu)->TPC; } } break; case 50: if (nb_antenna_ports_eNB == 2) { if (frame_type == TDD) { mcs1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->tb_swap; TPC = ((DCI2A_10MHz_2A_TDD_t *)dci_pdu)->TPC; } else { mcs1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->tb_swap; TPC = ((DCI2A_10MHz_2A_FDD_t *)dci_pdu)->TPC; } } else if (nb_antenna_ports_eNB == 4) { if (frame_type == TDD) { mcs1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2A_10MHz_4A_TDD_t *)dci_pdu)->TPC; } else { mcs1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2A_10MHz_4A_FDD_t *)dci_pdu)->TPC; } } break; case 100: if (nb_antenna_ports_eNB == 2) { if (frame_type == TDD) { mcs1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->tb_swap; TPC = ((DCI2A_20MHz_2A_TDD_t *)dci_pdu)->TPC; } else { mcs1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->tb_swap; TPC = ((DCI2A_20MHz_2A_FDD_t *)dci_pdu)->TPC; } } else if (nb_antenna_ports_eNB == 4) { if (frame_type == TDD) { mcs1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->tpmi; TPC = ((DCI2A_20MHz_4A_TDD_t *)dci_pdu)->TPC; } else { mcs1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs1; mcs2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->mcs2; rballoc = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rballoc; rah = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rah; rv1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv1; rv2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->rv2; ndi1 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi1; ndi2 = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->ndi2; harq_pid = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->harq_pid; tbswap = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tb_swap; tpmi = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->tpmi; TPC = ((DCI2A_20MHz_4A_FDD_t *)dci_pdu)->TPC; } } break; } pdci_info_extarcted->mcs1 = mcs1; pdci_info_extarcted->mcs2 = mcs2; pdci_info_extarcted->rballoc = rballoc; pdci_info_extarcted->rah = rah; pdci_info_extarcted->rv1 = rv1; pdci_info_extarcted->rv2 = rv2; pdci_info_extarcted->ndi1 = ndi1; pdci_info_extarcted->ndi2 = ndi2; pdci_info_extarcted->harq_pid = harq_pid; pdci_info_extarcted->tb_swap = tbswap; pdci_info_extarcted->TPC = TPC; pdci_info_extarcted->tpmi = tpmi; } int check_dci_format1_1a_coherency(DCI_format_t dci_format, uint8_t N_RB_DL, uint16_t rnti, uint16_t tc_rnti, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, uint32_t frame, uint8_t nr_tti_rx, DCI_INFO_EXTRACTED_t *pdci_info_extarcted, NR_DL_UE_HARQ_t *pdlsch0_harq) { uint8_t harq_pid = pdci_info_extarcted->harq_pid; uint32_t rballoc = pdci_info_extarcted->rballoc; uint8_t mcs1 = pdci_info_extarcted->mcs1; uint8_t TPC = pdci_info_extarcted->TPC; uint8_t rah = pdci_info_extarcted->rah; #ifdef DEBUG_DCI uint8_t rv1 = pdci_info_extarcted->rv1; uint8_t ndi1 = pdci_info_extarcted->ndi1; #endif uint8_t NPRB = 0; long long int RIV_max = 0; #ifdef DEBUG_DCI LOG_I(PHY,"[DCI-FORMAT-1-1A] AbsSubframe %d.%d dci_format %d\n", frame, nr_tti_rx, dci_format); LOG_I(PHY,"[DCI-FORMAT-1-1A] rnti %x\n", rnti); LOG_I(PHY,"[DCI-FORMAT-1-1A] harq_pid %d\n", harq_pid); LOG_I(PHY,"[DCI-FORMAT-1-1A] rah %d\n", rah); LOG_I(PHY,"[DCI-FORMAT-1-1A] rballoc %x\n", rballoc); LOG_I(PHY,"[DCI-FORMAT-1-1A] mcs1 %d\n", mcs1); LOG_I(PHY,"[DCI-FORMAT-1-1A] rv1 %d\n", rv1); LOG_I(PHY,"[DCI-FORMAT-1-1A] ndi1 %d\n", ndi1); LOG_I(PHY,"[DCI-FORMAT-1-1A] TPC %d\n", TPC); #endif // I- check dci content minimum coherency if( ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) && harq_pid > 0) { return(0); } if(harq_pid>=8) { LOG_I(PHY,"bad harq id \n"); return(0); } if(dci_format == format1 && ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) ) { LOG_I(PHY,"bad dci format \n"); return(0); } if( mcs1 > 28) { if(pdlsch0_harq->round == 0) { LOG_I(PHY,"bad dci mcs + round \n"); return(0); } if((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { LOG_I(PHY,"bad dci mcs + rnti \n"); return(0); } } if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { NPRB = (TPC&1) + 2; switch (N_RB_DL) { case 6: RIV_max = RIV_max6; break; case 25: RIV_max = RIV_max25; break; case 50: RIV_max = RIV_max50; break; case 100: RIV_max = RIV_max100; break; } } /*else { switch (N_RB_DL) { case 6: NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; if(rah) RIV_max = RIV_max6; else RIV_max = 0x3F; break; case 25: NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; if(rah) RIV_max = RIV_max25; else RIV_max = 0x1FFF; break; case 50: NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; if(rah) RIV_max = RIV_max50; else RIV_max = 0x1FFFF; break; case 100: NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; if(rah) RIV_max = RIV_max100; else RIV_max = 0x1FFFFFF; break; } }*/ if(dci_format == format1) { NPRB = conv_nprb(rah, rballoc, N_RB_DL); } /* if(rballoc > RIV_max) { LOG_I(PHY,"bad dci rballoc rballoc %d RIV_max %lld \n",rballoc, RIV_max); // DCI false detection return(0); } */ if(NPRB == 0) { // DCI false detection LOG_I(PHY,"bad NPRB = 0 \n"); return(0); } // this a retransmission if(pdlsch0_harq->round>0) { // compare old TBS to new TBS if((mcs1<29) && (pdlsch0_harq->TBS != TBStable[get_I_TBS(mcs1)][NPRB-1])) { // this is an eNB issue // retransmisison but old and new TBS are different !!! // work around, consider it as a new transmission LOG_E(PHY,"Format1A Retransmission but TBS are different: consider it as new transmission !!! \n"); pdlsch0_harq->round = 0; //return(0); // ?? to cross check } } return(1); } int check_dci_format1c_coherency(uint8_t N_RB_DL, DCI_INFO_EXTRACTED_t *pdci_info_extarcted, uint16_t rnti, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, NR_DL_UE_HARQ_t *pdlsch0_harq) { uint32_t rballoc = pdci_info_extarcted->rballoc; uint8_t NPRB = 0; uint32_t RIV_max = 0; // I- check dci content minimum coherency if((rnti!=si_rnti) && (rnti!=p_rnti) && (rnti!=ra_rnti)) return(0); switch (N_RB_DL) { case 6: NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; RIV_max = RIV_max6; break; case 25: NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; RIV_max = RIV_max25; break; case 50: NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; RIV_max = RIV_max50; break; case 100: NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; RIV_max = RIV_max100; break; } if(rballoc > RIV_max) { // DCI false detection return(0); } if(NPRB == 0) { // DCI false detection return(0); } return(1); } int check_dci_format2_2a_coherency(DCI_format_t dci_format, uint8_t N_RB_DL, DCI_INFO_EXTRACTED_t *pdci_info_extarcted, uint16_t rnti, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, NR_DL_UE_HARQ_t *pdlsch0_harq, NR_DL_UE_HARQ_t *pdlsch1_harq) { uint8_t rah = pdci_info_extarcted->rah; uint8_t mcs1 = pdci_info_extarcted->mcs1; uint8_t mcs2 = pdci_info_extarcted->mcs2; uint8_t rv1 = pdci_info_extarcted->rv1; uint8_t rv2 = pdci_info_extarcted->rv2; uint8_t harq_pid = pdci_info_extarcted->harq_pid; uint32_t rballoc = pdci_info_extarcted->rballoc; #ifdef DEBUG_DCI uint8_t ndi1 = pdci_info_extarcted->ndi1; uint8_t ndi2 = pdci_info_extarcted->ndi2; #endif uint8_t NPRB = 0; long long RIV_max = 0; #ifdef DEBUG_DCI LOG_I(PHY, "extarcted dci - dci_format %d \n", dci_format); LOG_I(PHY, "extarcted dci - rnti %d \n", rnti); LOG_I(PHY, "extarcted dci - rah %d \n", rah); LOG_I(PHY, "extarcted dci - mcs1 %d \n", mcs1); LOG_I(PHY, "extarcted dci - mcs2 %d \n", mcs2); LOG_I(PHY, "extarcted dci - rv1 %d \n", rv1); LOG_I(PHY, "extarcted dci - rv2 %d \n", rv2); //LOG_I(PHY, "extarcted dci - ndi1 %d \n", ndi1); //LOG_I(PHY, "extarcted dci - ndi2 %d \n", ndi2); LOG_I(PHY, "extarcted dci - rballoc %x \n", rballoc); LOG_I(PHY, "extarcted dci - harq pid %d \n", harq_pid); LOG_I(PHY, "extarcted dci - round0 %d \n", pdlsch0_harq->round); LOG_I(PHY, "extarcted dci - round1 %d \n", pdlsch1_harq->round); #endif // I- check dci content minimum coherency if(harq_pid>=8) { LOG_I(PHY,"bad harq pid\n"); return(0); } if( (rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti) ) { LOG_I(PHY,"bad rnti\n"); return(0); } if( mcs1 > 28) { if(pdlsch0_harq->round == 0) { LOG_I(PHY,"bad mcs1\n"); return(0); } } if( mcs2 > 28) { if(pdlsch1_harq->round == 0) { LOG_I(PHY,"bad mcs2\n"); return(0); } } if((pdlsch0_harq->round == 0) && (rv1 > 0) && (mcs1 != 0)) { // DCI false detection LOG_I(PHY,"bad rv1\n"); return(0); } if((pdlsch1_harq->round == 0) && (rv2 > 0) && (mcs2 != 0)) { // DCI false detection LOG_I(PHY,"bad rv2\n"); return(0); } switch (N_RB_DL) { case 6: if (rah == 0) { //RBG = 1; RIV_max = 0x3F; } else { RIV_max = RIV_max6; } break; case 25: if (rah == 0) { //RBG = 2; RIV_max = 0x1FFF; } else { RIV_max = RIV_max25; } break; case 50: if (rah == 0) { //RBG = 3; RIV_max = 0x1FFFF; } else { RIV_max = RIV_max50; } break; case 100: if (rah == 0) { //RBG = 4; RIV_max = 0x1FFFFFF; } else { RIV_max = RIV_max100; } break; } NPRB = conv_nprb(rah, rballoc, N_RB_DL); if( (rballoc > RIV_max) && (rah == 1) ) { // DCI false detection LOG_I(PHY,"bad rballoc %d RIV_max %lld\n", rballoc, RIV_max); return(0); } if(NPRB == 0) { // DCI false detection LOG_I(PHY,"bad NPRB\n"); return(0); } return(1); } void compute_llr_offset(NR_DL_FRAME_PARMS *frame_parms, NR_UE_PDCCH *pdcch_vars, NR_UE_PDSCH *pdsch_vars, NR_DL_UE_HARQ_t *dlsch0_harq, uint8_t nb_rb_alloc, uint8_t nr_tti_rx) { uint32_t pbch_pss_sss_re; uint32_t crs_re; uint32_t granted_re; uint32_t data_re; uint32_t llr_offset; uint8_t symbol; uint8_t symbol_mod; pdsch_vars->llr_offset[pdcch_vars->num_pdcch_symbols] = 0; //LOG_I(PHY,"compute_llr_offset: nb RB %d - Qm %d \n", nb_rb_alloc, dlsch0_harq->Qm); //dlsch0_harq->rb_alloc_even; //dlsch0_harq->rb_alloc_odd; for(symbol=pdcch_vars->num_pdcch_symbols; symbol<frame_parms->symbols_per_tti; symbol++) { symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; if((symbol_mod == 0) || symbol_mod == (4-frame_parms->Ncp)) { if (frame_parms->mode1_flag==0) crs_re = 4; else crs_re = 2; } else { crs_re = 0; } granted_re = nb_rb_alloc * (12-crs_re); pbch_pss_sss_re = adjust_G2(frame_parms,dlsch0_harq->rb_alloc_even,dlsch0_harq->Qm,nr_tti_rx,symbol); pbch_pss_sss_re = (double)pbch_pss_sss_re * ((double)(12-crs_re)/12); data_re = granted_re - pbch_pss_sss_re; llr_offset = data_re * dlsch0_harq->Qm * 2; pdsch_vars->llr_length[symbol] = data_re; if(symbol < (frame_parms->symbols_per_tti-1)) pdsch_vars->llr_offset[symbol+1] = pdsch_vars->llr_offset[symbol] + llr_offset; //LOG_I(PHY,"Granted Re nr_tti_rx %d / symbol %d => %d (%d RBs)\n", nr_tti_rx, symbol_mod, granted_re,dlsch0_harq->nb_rb); //LOG_I(PHY,"Pbch/PSS/SSS Re nr_tti_rx %d / symbol %d => %d \n", nr_tti_rx, symbol_mod, pbch_pss_sss_re); //LOG_I(PHY,"CRS Re Per PRB nr_tti_rx %d / symbol %d => %d \n", nr_tti_rx, symbol_mod, crs_re); //LOG_I(PHY,"Data Re nr_tti_rx %d / symbol %d => %d \n", nr_tti_rx, symbol_mod, data_re); //LOG_I(PHY,"Data Re nr_tti_rx %d-symbol %d => llr length %d, llr offset %d \n", nr_tti_rx, symbol, // pdsch_vars->llr_length[symbol], pdsch_vars->llr_offset[symbol]); } } void prepare_dl_decoding_format1_1A(DCI_format_t dci_format, uint8_t N_RB_DL, DCI_INFO_EXTRACTED_t *pdci_info_extarcted, NR_DL_FRAME_PARMS *frame_parms, NR_UE_PDCCH *pdcch_vars, NR_UE_PDSCH *pdsch_vars, uint8_t nr_tti_rx, uint16_t rnti, uint16_t tc_rnti, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, NR_DL_UE_HARQ_t *pdlsch0_harq, NR_UE_DLSCH_t *pdlsch0) { uint8_t harq_pid = pdci_info_extarcted->harq_pid; uint8_t vrb_type = pdci_info_extarcted->vrb_type; uint32_t rballoc = pdci_info_extarcted->rballoc; uint8_t mcs1 = pdci_info_extarcted->mcs1; uint8_t rv1 = pdci_info_extarcted->rv1; uint8_t ndi1 = pdci_info_extarcted->ndi1; uint8_t TPC = pdci_info_extarcted->TPC; uint8_t rah = pdci_info_extarcted->rah; uint8_t dai = pdci_info_extarcted->dai; uint8_t NPRB = 0; uint8_t nb_rb_alloc = 0; if(dci_format == format1A) { if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { NPRB = (TPC&1) + 2; switch (N_RB_DL) { case 6: nb_rb_alloc = RIV2nb_rb_LUT6[rballoc];//NPRB; break; case 25: nb_rb_alloc = RIV2nb_rb_LUT25[rballoc];//NPRB; break; case 50: nb_rb_alloc = RIV2nb_rb_LUT50[rballoc];//NPRB; break; case 100: nb_rb_alloc = RIV2nb_rb_LUT100[rballoc];//NPRB; break; } } else { switch (N_RB_DL) { case 6: NPRB = RIV2nb_rb_LUT6[rballoc];//NPRB; break; case 25: NPRB = RIV2nb_rb_LUT25[rballoc];//NPRB; break; case 50: NPRB = RIV2nb_rb_LUT50[rballoc];//NPRB; break; case 100: NPRB = RIV2nb_rb_LUT100[rballoc];//NPRB; break; } nb_rb_alloc = NPRB; } } else // format1 { NPRB = conv_nprb(rah, rballoc, N_RB_DL); nb_rb_alloc = NPRB; } pdlsch0->current_harq_pid = harq_pid; pdlsch0->active = 1; pdlsch0->rnti = rnti; if(dci_format == format1A) pdlsch0->harq_ack[nr_tti_rx].vDAI_DL = dai+1; if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { pdlsch0_harq->round = 0; pdlsch0_harq->status = ACTIVE; } else //CRNTI { if (rnti == tc_rnti) { //fix for standalone Contention Resolution Id pdlsch0_harq->DCINdi = (uint8_t)-1; LOG_D(PHY,"UE (%x/%d): Format1A DCI: C-RNTI is temporary. Set NDI = %d and to be ignored\n", rnti,harq_pid,pdlsch0_harq->DCINdi); } // NDI has been toggled or this is the first transmission if ((ndi1!=pdlsch0_harq->DCINdi) || (pdlsch0_harq->first_tx==1)) { pdlsch0_harq->round = 0; pdlsch0_harq->first_tx = 0; pdlsch0_harq->status = ACTIVE; }else if (rv1 != 0 ) //NDI has not been toggled but rv was increased by eNB: retransmission { if (pdlsch0_harq->status == SCH_IDLE) //packet was actually decoded in previous transmission (ACK was missed by eNB) //However, the round is not a good check as it might have been decoded in a retransmission prior to this one. { LOG_D(PHY,"skip pdsch decoding and report ack\n"); // skip pdsch decoding and report ack //pdlsch0_harq->status = SCH_IDLE; pdlsch0->active = 0; pdlsch0->harq_ack[nr_tti_rx].ack = 1; pdlsch0->harq_ack[nr_tti_rx].harq_id = harq_pid; pdlsch0->harq_ack[nr_tti_rx].send_harq_status = 1; //pdlsch0_harq->first_tx = 0; } else //normal retransmission { // nothing special to do } } else { pdlsch0_harq->status = ACTIVE; } } pdlsch0_harq->DCINdi = ndi1; pdlsch0_harq->mcs = mcs1; pdlsch0_harq->rvidx = rv1; pdlsch0_harq->nb_rb = NPRB; pdlsch0_harq->codeword = 0; pdlsch0_harq->Nl = 1; pdlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; pdlsch0_harq->dl_power_off = 1; //no power offset pdlsch0_harq->delta_PUCCH = nr_delta_PUCCH_lut[TPC &3]; // compute resource allocation if(dci_format == format1A) { switch (N_RB_DL) { case 6: if (vrb_type == LOCALIZED) { pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT6[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT6[rballoc]; } else { pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; } break; case 25: if (vrb_type == LOCALIZED) { pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT25[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT25[rballoc]; } else { pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; } break; case 50: if (vrb_type == LOCALIZED) { pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT50_0[rballoc]; pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT50_1[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT50_0[rballoc]; pdlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT50_1[rballoc]; // printf("rballoc: %08x.%08x\n",pdlsch0_harq->rb_alloc_even[0],pdlsch0_harq->rb_alloc_even[1]); } else { // DISTRIBUTED if ((rballoc&(1<<10)) == 0) { rballoc = rballoc&(~(1<<10)); pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; } else { rballoc = rballoc&(~(1<<10)); pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; } } break; case 100: if (vrb_type == LOCALIZED) { pdlsch0_harq->rb_alloc_even[0] = localRIV2alloc_LUT100_0[rballoc]; pdlsch0_harq->rb_alloc_even[1] = localRIV2alloc_LUT100_1[rballoc]; pdlsch0_harq->rb_alloc_even[2] = localRIV2alloc_LUT100_2[rballoc]; pdlsch0_harq->rb_alloc_even[3] = localRIV2alloc_LUT100_3[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = localRIV2alloc_LUT100_0[rballoc]; pdlsch0_harq->rb_alloc_odd[1] = localRIV2alloc_LUT100_1[rballoc]; pdlsch0_harq->rb_alloc_odd[2] = localRIV2alloc_LUT100_2[rballoc]; pdlsch0_harq->rb_alloc_odd[3] = localRIV2alloc_LUT100_3[rballoc]; } else { if ((rballoc&(1<<10)) == 0) { //Gap 1 rballoc = rballoc&(~(1<<12)); pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; } else { //Gap 2 rballoc = rballoc&(~(1<<12)); pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; } } break; } } else // format1 { conv_rballoc(rah,rballoc,frame_parms->N_RB_DL,pdlsch0_harq->rb_alloc_even); pdlsch0_harq->rb_alloc_odd[0]= pdlsch0_harq->rb_alloc_even[0]; pdlsch0_harq->rb_alloc_odd[1]= pdlsch0_harq->rb_alloc_even[1]; pdlsch0_harq->rb_alloc_odd[2]= pdlsch0_harq->rb_alloc_even[2]; pdlsch0_harq->rb_alloc_odd[3]= pdlsch0_harq->rb_alloc_even[3]; } if ((rnti==si_rnti) || (rnti==p_rnti) || (rnti==ra_rnti)) { pdlsch0_harq->TBS = TBStable[mcs1][NPRB-1]; pdlsch0_harq->Qm = 2; } else { if(mcs1 < 29) { pdlsch0_harq->TBS = TBStable[get_I_TBS(mcs1)][NPRB-1]; pdlsch0_harq->Qm = get_Qm(mcs1); } } compute_llr_offset(frame_parms, pdcch_vars, pdsch_vars, pdlsch0_harq, nb_rb_alloc, nr_tti_rx); } void prepare_dl_decoding_format1C(uint8_t N_RB_DL, DCI_INFO_EXTRACTED_t *pdci_info_extarcted, NR_DL_FRAME_PARMS *frame_parms, NR_UE_PDCCH *pdcch_vars, NR_UE_PDSCH *pdsch_vars, uint32_t rnti, uint32_t si_rnti, uint32_t ra_rnti, uint32_t p_rnti, uint32_t frame, uint8_t nr_tti_rx, NR_DL_UE_HARQ_t *pdlsch0_harq, NR_UE_DLSCH_t *pdlsch0) { uint8_t harq_pid = pdci_info_extarcted->harq_pid; uint32_t rballoc = pdci_info_extarcted->rballoc; uint8_t mcs1 = pdci_info_extarcted->mcs1; uint8_t Ngap = pdci_info_extarcted->Ngap; pdlsch0_harq->round = 0; pdlsch0_harq->first_tx = 1; pdlsch0_harq->vrb_type = DISTRIBUTED; if (rnti==si_rnti) { // rule from Section 5.3.1 of 36.321 if (((frame&1) == 0) && (nr_tti_rx == 5)) pdlsch0_harq->rvidx = (((3*((frame>>1)&3))+1)>>1)&3; // SIB1 else pdlsch0_harq->rvidx = (((3*(nr_tti_rx&3))+1)>>1)&3; // other SIBs } else if ((rnti==p_rnti) || (rnti==ra_rnti)) { // Section 7.1.7.3 pdlsch0_harq->rvidx = 0; } pdlsch0_harq->Nl = 1; pdlsch0_harq->mimo_mode = frame_parms->mode1_flag == 1 ?SISO : ALAMOUTI; pdlsch0_harq->dl_power_off = 1; //no power offset pdlsch0_harq->codeword = 0; pdlsch0_harq->mcs = mcs1; pdlsch0_harq->TBS = TBStable1C[mcs1]; pdlsch0_harq->Qm = 2; pdlsch0->current_harq_pid = harq_pid; pdlsch0->active = 1; pdlsch0->rnti = rnti; switch (N_RB_DL) { case 6: pdlsch0_harq->nb_rb = RIV2nb_rb_LUT6[rballoc]; pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT6[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT6[rballoc]; break; case 25: pdlsch0_harq->nb_rb = RIV2nb_rb_LUT25[rballoc]; pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_even_LUT25[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_odd_LUT25[rballoc]; break; case 50: pdlsch0_harq->nb_rb = RIV2nb_rb_LUT50[rballoc]; if (Ngap == 0) { pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT50_0[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT50_0[rballoc]; pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT50_1[rballoc]; pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT50_1[rballoc]; } else { pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT50_0[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT50_0[rballoc]; pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT50_1[rballoc]; pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT50_1[rballoc]; } break; case 100: pdlsch0_harq->nb_rb = RIV2nb_rb_LUT100[rballoc]; if (Ngap==0) { pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap0_even_LUT100_0[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap0_odd_LUT100_0[rballoc]; pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap0_even_LUT100_1[rballoc]; pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap0_odd_LUT100_1[rballoc]; pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap0_even_LUT100_2[rballoc]; pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap0_odd_LUT100_2[rballoc]; pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap0_even_LUT100_3[rballoc]; pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap0_odd_LUT100_3[rballoc]; } else { pdlsch0_harq->rb_alloc_even[0] = distRIV2alloc_gap1_even_LUT100_0[rballoc]; pdlsch0_harq->rb_alloc_odd[0] = distRIV2alloc_gap1_odd_LUT100_0[rballoc]; pdlsch0_harq->rb_alloc_even[1] = distRIV2alloc_gap1_even_LUT100_1[rballoc]; pdlsch0_harq->rb_alloc_odd[1] = distRIV2alloc_gap1_odd_LUT100_1[rballoc]; pdlsch0_harq->rb_alloc_even[2] = distRIV2alloc_gap1_even_LUT100_2[rballoc]; pdlsch0_harq->rb_alloc_odd[2] = distRIV2alloc_gap1_odd_LUT100_2[rballoc]; pdlsch0_harq->rb_alloc_even[3] = distRIV2alloc_gap1_even_LUT100_3[rballoc]; pdlsch0_harq->rb_alloc_odd[3] = distRIV2alloc_gap1_odd_LUT100_3[rballoc]; } break; default: AssertFatal(0,"Format 1C: Unknown N_RB_DL %d\n",frame_parms->N_RB_DL); break; } compute_llr_offset(frame_parms, pdcch_vars, pdsch_vars, pdlsch0_harq, pdlsch0_harq->nb_rb, nr_tti_rx); } void compute_precoding_info_2cw(uint8_t tpmi, uint8_t tbswap, uint16_t pmi_alloc, NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq) { switch (tpmi) { case 0: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODING1; dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,0, 1); break; case 1: dlsch0_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; dlsch1_harq->mimo_mode = DUALSTREAM_UNIFORM_PRECODINGj; dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); dlsch1_harq->pmi_alloc = pmi_extend(frame_parms,1, 1); break; case 2: // PUSCH precoding dlsch0_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; dlsch1_harq->mimo_mode = DUALSTREAM_PUSCH_PRECODING; if (tbswap==0){ dlsch0_harq->pmi_alloc = pmi_alloc; dlsch1_harq->pmi_alloc = pmi_alloc^0x1555; } else { dlsch1_harq->pmi_alloc = pmi_alloc; dlsch0_harq->pmi_alloc = pmi_alloc^0x1555; } #ifdef DEBUG_HARQ printf ("\n \n compute_precoding_info_2cw pmi_alloc_new = %d\n", dlsch0_harq->pmi_alloc); #endif break; default: break; } } void compute_precoding_info_1cw(uint8_t tpmi, uint16_t pmi_alloc, NR_DL_FRAME_PARMS *frame_parms, NR_DL_UE_HARQ_t *dlsch_harq) { switch (tpmi) { case 0 : dlsch_harq->mimo_mode = ALAMOUTI; break; case 1: dlsch_harq->mimo_mode = UNIFORM_PRECODING11; dlsch_harq->pmi_alloc = pmi_extend(frame_parms,0, 0); break; case 2: dlsch_harq->mimo_mode = UNIFORM_PRECODING1m1; dlsch_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); break; case 3: dlsch_harq->mimo_mode = UNIFORM_PRECODING1j; dlsch_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); break; case 4: dlsch_harq->mimo_mode = UNIFORM_PRECODING1mj; dlsch_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); break; case 5: dlsch_harq->mimo_mode = PUSCH_PRECODING0; dlsch_harq->pmi_alloc = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,0); break; case 6: dlsch_harq->mimo_mode = PUSCH_PRECODING1; dlsch_harq->pmi_alloc = pmi_alloc;//pmi_convert(frame_parms,dlsch0->pmi_alloc,1); break; } #ifdef DEBUG_HARQ printf ("[DCI UE] I am calling from the UE side pmi_alloc_new = %d with tpmi %d\n", dlsch_harq->pmi_alloc, tpmi); #endif } void compute_precoding_info_format2A(uint8_t tpmi, uint8_t nb_antenna_ports_eNB, uint8_t tb0_active, uint8_t tb1_active, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq) { dlsch0_harq->dl_power_off = 0; dlsch1_harq->dl_power_off = 0; if (nb_antenna_ports_eNB == 2) { if ((tb0_active==1) && (tb1_active==1)) { dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; } else { dlsch0_harq->mimo_mode = ALAMOUTI; dlsch1_harq->mimo_mode = ALAMOUTI; } } else if (nb_antenna_ports_eNB == 4) { // 4 antenna case if ((tb0_active==1) && (tb1_active==1)) { switch (tpmi) { case 0: // one layer per transport block dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; break; case 1: // one-layers on TB 0, two on TB 1 dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch1_harq->Nl = 2; dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; break; case 2: // two-layers on TB 0, two on TB 1 dlsch0_harq->mimo_mode = LARGE_CDD; dlsch1_harq->mimo_mode = LARGE_CDD; dlsch0_harq->Nl = 2; dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; break; case 3: // LOG_E(PHY,"Illegal value (3) for TPMI in Format 2A DCI\n"); break; } } else if (tb0_active == 1) { switch (tpmi) { case 0: // one layer per transport block dlsch0_harq->mimo_mode = ALAMOUTI; dlsch1_harq->mimo_mode = ALAMOUTI; break; case 1: // two-layers on TB 0 dlsch0_harq->mimo_mode = LARGE_CDD; dlsch0_harq->Nl = 2; dlsch0_harq->dl_power_off = 1; break; case 2: // two-layers on TB 0, two on TB 1 case 3: // LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi); break; } } else if (tb1_active == 1) { switch (tpmi) { case 0: // one layer per transport block dlsch0_harq->mimo_mode = ALAMOUTI; dlsch1_harq->mimo_mode = ALAMOUTI; break; case 1: // two-layers on TB 0 dlsch1_harq->mimo_mode = LARGE_CDD; dlsch1_harq->Nl = 2; dlsch0_harq->dl_power_off = 1; break; case 2: // two-layers on TB 0, two on TB 1 case 3: // LOG_E(PHY,"Illegal value %d for TPMI in Format 2A DCI with one transport block enabled\n",tpmi); break; } } } // printf("Format 2A: NPRB=%d (rballoc %x,mcs1 %d, mcs2 %d, frame_type %d N_RB_DL %d,active %d/%d)\n",NPRB,rballoc,mcs1,mcs2,frame_parms->frame_type,frame_parms->N_RB_DL,dlsch0->active,dlsch1->active); //printf("UE (%x/%d): nr_tti_rx %d Format2A DCI: ndi1 %d, old_ndi1 %d, ndi2 %d, old_ndi2 %d (first tx1 %d, first tx2 %d) harq_status1 %d, harq_status2 %d\n",dlsch0->rnti,harq_pid,nr_tti_rx,ndi,dlsch0_harq->DCINdi, // dlsch0_harq->first_tx,dlsch1_harq->first_tx,dlsch0_harq->status,dlsch1_harq->status); //printf("TBS0 %d, TBS1 %d\n",dlsch0_harq->TBS,dlsch1_harq->TBS); } void prepare_dl_decoding_format2_2A(DCI_format_t dci_format, DCI_INFO_EXTRACTED_t *pdci_info_extarcted, NR_DL_FRAME_PARMS *frame_parms, NR_UE_PDCCH *pdcch_vars, NR_UE_PDSCH *pdsch_vars, uint16_t rnti, uint8_t nr_tti_rx, NR_DL_UE_HARQ_t *dlsch0_harq, NR_DL_UE_HARQ_t *dlsch1_harq, NR_UE_DLSCH_t *pdlsch0, NR_UE_DLSCH_t *pdlsch1) { uint8_t rah = pdci_info_extarcted->rah; uint8_t mcs1 = pdci_info_extarcted->mcs1; uint8_t mcs2 = pdci_info_extarcted->mcs2; uint8_t rv1 = pdci_info_extarcted->rv1; uint8_t rv2 = pdci_info_extarcted->rv2; uint8_t harq_pid = pdci_info_extarcted->harq_pid; uint32_t rballoc = pdci_info_extarcted->rballoc; uint8_t tbswap = pdci_info_extarcted->tb_swap; uint8_t tpmi = pdci_info_extarcted->tpmi; uint8_t TPC = pdci_info_extarcted->TPC; uint8_t ndi1 = pdci_info_extarcted->ndi1; uint8_t ndi2 = pdci_info_extarcted->ndi2; uint8_t TB0_active = 1; uint8_t TB1_active = 1; // printf("inside prepare pdlsch1->pmi_alloc %d \n",pdlsch1->pmi_alloc); if ((rv1 == 1) && (mcs1 == 0)) { TB0_active=0; } if ((rv2 == 1) && (mcs2 == 0)) { TB1_active=0; } #ifdef DEBUG_HARQ printf("[DCI UE]: TB0 status %d , TB1 status %d\n", TB0_active, TB1_active); #endif dlsch0_harq->mcs = mcs1; dlsch1_harq->mcs = mcs2; dlsch0_harq->rvidx = rv1; dlsch1_harq->rvidx = rv2; dlsch0_harq->DCINdi = ndi1; dlsch1_harq->DCINdi = ndi2; dlsch0_harq->codeword = 0; dlsch1_harq->codeword = 1; dlsch0_harq->Nl = 1; dlsch1_harq->Nl = 1; dlsch0_harq->delta_PUCCH = nr_delta_PUCCH_lut[TPC&3]; dlsch1_harq->delta_PUCCH = nr_delta_PUCCH_lut[TPC&3]; dlsch0_harq->dl_power_off = 1; dlsch1_harq->dl_power_off = 1; pdlsch0->current_harq_pid = harq_pid; pdlsch0->harq_ack[nr_tti_rx].harq_id = harq_pid; pdlsch1->current_harq_pid = harq_pid; pdlsch1->harq_ack[nr_tti_rx].harq_id = harq_pid; // assume two CW are active dlsch0_harq->status = ACTIVE; dlsch1_harq->status = ACTIVE; pdlsch0->active = 1; pdlsch1->active = 1; pdlsch0->rnti = rnti; pdlsch1->rnti = rnti; if (TB0_active && TB1_active && tbswap==1) { dlsch0_harq->codeword = 1; dlsch1_harq->codeword = 0; } if (!TB0_active && TB1_active){ dlsch1_harq->codeword = 0; } if (TB0_active && !TB1_active){ dlsch0_harq->codeword = 0; } if (TB0_active==0) { dlsch0_harq->status = SCH_IDLE; pdlsch0->active = 0; #ifdef DEBUG_HARQ printf("[DCI UE]: TB0 is deactivated, retransmit TB1 transmit in TM6\n"); #endif } if (TB1_active==0) { dlsch1_harq->status = SCH_IDLE; pdlsch1->active = 0; } #ifdef DEBUG_HARQ printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); #endif // compute resource allocation if (TB0_active == 1){ dlsch0_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL); conv_rballoc(rah, rballoc, frame_parms->N_RB_DL, dlsch0_harq->rb_alloc_even); dlsch0_harq->rb_alloc_odd[0]= dlsch0_harq->rb_alloc_even[0]; dlsch0_harq->rb_alloc_odd[1]= dlsch0_harq->rb_alloc_even[1]; dlsch0_harq->rb_alloc_odd[2]= dlsch0_harq->rb_alloc_even[2]; dlsch0_harq->rb_alloc_odd[3]= dlsch0_harq->rb_alloc_even[3]; if (TB1_active == 1){ dlsch1_harq->rb_alloc_even[0]= dlsch0_harq->rb_alloc_even[0]; dlsch1_harq->rb_alloc_even[1]= dlsch0_harq->rb_alloc_even[1]; dlsch1_harq->rb_alloc_even[2]= dlsch0_harq->rb_alloc_even[2]; dlsch1_harq->rb_alloc_even[3]= dlsch0_harq->rb_alloc_even[3]; dlsch1_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_odd[0]; dlsch1_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_odd[1]; dlsch1_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_odd[2]; dlsch1_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_odd[3]; dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; //dlsch0_harq->Nl = 1; //dlsch1_harq->Nl = 1; } } else if ((TB0_active == 0) && (TB1_active == 1)){ conv_rballoc(rah, rballoc, frame_parms->N_RB_DL, dlsch1_harq->rb_alloc_even); dlsch1_harq->rb_alloc_odd[0]= dlsch1_harq->rb_alloc_even[0]; dlsch1_harq->rb_alloc_odd[1]= dlsch1_harq->rb_alloc_even[1]; dlsch1_harq->rb_alloc_odd[2]= dlsch1_harq->rb_alloc_even[2]; dlsch1_harq->rb_alloc_odd[3]= dlsch1_harq->rb_alloc_even[3]; dlsch1_harq->nb_rb = conv_nprb(rah, rballoc, frame_parms->N_RB_DL); } // compute precoding matrix + mimo mode if(dci_format == format2) { if ((TB0_active) && (TB1_active)){ //two CW active compute_precoding_info_2cw(tpmi, tbswap, pdlsch0->pmi_alloc,frame_parms, dlsch0_harq, dlsch1_harq); // printf("[DCI UE 1]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); } else if ((TB0_active) && (!TB1_active)) { // only CW 0 active compute_precoding_info_1cw(tpmi, pdlsch0->pmi_alloc, frame_parms, dlsch0_harq); } else { compute_precoding_info_1cw(tpmi, pdlsch1->pmi_alloc, frame_parms, dlsch1_harq); // printf("I am doing compute_precoding_info_1cw with tpmi %d \n", tpmi); } //printf(" UE DCI harq0 MIMO mode = %d\n", dlsch0_harq->mimo_mode); if ((frame_parms->mode1_flag == 1) && (TB0_active)) dlsch0_harq->mimo_mode = SISO; } else { compute_precoding_info_format2A( tpmi, frame_parms->nb_antenna_ports_eNB, TB0_active, TB1_active, dlsch0_harq, dlsch1_harq); } // printf("[DCI UE 2]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); // reset round + compute Qm if (TB0_active) { // printf("TB0 ndi1 =%d, dlsch0_harq->DCINdi =%d, dlsch0_harq->first_tx = %d\n", ndi1, dlsch0_harq->DCINdi, dlsch0_harq->first_tx); if ((ndi1!=dlsch0_harq->DCINdi) || (dlsch0_harq->first_tx==1)) { dlsch0_harq->round = 0; dlsch0_harq->status = ACTIVE; dlsch0_harq->DCINdi = ndi1; //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW0 subframe %d (pid %d, round %d)\n", // subframe,harq_pid,dlsch0_harq->round); if ( dlsch0_harq->first_tx==1) { LOG_D(PHY,"Format 2 DCI First TX0: Clearing flag\n"); dlsch0_harq->first_tx = 0; } } /*else if (rv1 != 0 ) //NDI has not been toggled but rv was increased by eNB: retransmission { if(dlsch0_harq->status == SCH_IDLE) { // skip pdsch decoding and report ack //dlsch0_harq->status = SCH_IDLE; pdlsch0->active = 0; pdlsch0->harq_ack[subframe].ack = 1; pdlsch0->harq_ack[subframe].harq_id = harq_pid; pdlsch0->harq_ack[subframe].send_harq_status = 1; }*/ // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest // PDCCH for the same trasport block using Imcs in [0 .. 28] if(dlsch0_harq->mcs <= 28) { dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; LOG_D(PHY,"[UE] DLSCH: New TBS CW0 nr_tti_rx %d (pid %d, round %d) TBS %d \n", nr_tti_rx,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS); } else { LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW0 nr_tti_rx %d (pid %d, round %d) TBS %d \n", nr_tti_rx,harq_pid,dlsch0_harq->round, dlsch0_harq->TBS); } //if(dlsch0_harq->Nl == 2) //dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][(dlsch0_harq->nb_rb<<1)-1]; if (mcs1 <= 28) dlsch0_harq->Qm = get_Qm(mcs1); else if (mcs1<=31) dlsch0_harq->Qm = (mcs1-28)<<1; } // printf("[DCI UE 3]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); if (TB1_active) { // printf("TB1 ndi2 =%d, dlsch1_harq->DCINdi =%d, dlsch1_harq->first_tx = %d\n", ndi2, dlsch1_harq->DCINdi, dlsch1_harq->first_tx); if ((ndi2!=dlsch1_harq->DCINdi) || (dlsch1_harq->first_tx==1)) { dlsch1_harq->round = 0; dlsch1_harq->status = ACTIVE; dlsch1_harq->DCINdi = ndi2; //LOG_I(PHY,"[UE] DLSCH: New Data Indicator CW1 subframe %d (pid %d, round %d)\n", // subframe,harq_pid,dlsch0_harq->round); if (dlsch1_harq->first_tx==1) { LOG_D(PHY,"Format 2 DCI First TX1: Clearing flag\n"); dlsch1_harq->first_tx = 0; } } /*else if (rv1 != 0 ) //NDI has not been toggled but rv was increased by eNB: retransmission { if(dlsch1_harq->status == SCH_IDLE) { // skip pdsch decoding and report ack //dlsch1_harq->status = SCH_IDLE; pdlsch1->active = 0; pdlsch1->harq_ack[subframe].ack = 1; pdlsch1->harq_ack[subframe].harq_id = harq_pid; pdlsch1->harq_ack[subframe].send_harq_status = 1; } }*/ // if Imcs in [29..31] TBS is assumed to be as determined from DCI transported in the latest // PDCCH for the same trasport block using Imcs in [0 .. 28] if(dlsch1_harq->mcs <= 28) { dlsch1_harq->TBS = TBStable[get_I_TBS(dlsch1_harq->mcs)][dlsch1_harq->nb_rb-1]; LOG_D(PHY,"[UE] DLSCH: New TBS CW1 nr_tti_rx %d (pid %d, round %d) TBS %d \n", nr_tti_rx,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS); } else { LOG_D(PHY,"[UE] DLSCH: Keep the same TBS CW1 nr_tti_rx %d (pid %d, round %d) TBS %d \n", nr_tti_rx,harq_pid,dlsch1_harq->round, dlsch1_harq->TBS); } if (mcs2 <= 28) dlsch1_harq->Qm = get_Qm(mcs2); else if (mcs1<=31) dlsch1_harq->Qm = (mcs2-28)<<1; } compute_llr_offset(frame_parms, pdcch_vars, pdsch_vars, dlsch0_harq, dlsch0_harq->nb_rb, nr_tti_rx); /* #ifdef DEBUG_HARQ printf("[DCI UE]: dlsch0_harq status %d , dlsch1_harq status %d\n", dlsch0_harq->status, dlsch1_harq->status); printf("[DCI UE]: TB0_active %d , TB1_active %d\n", TB0_active, TB1_active); if (dlsch0 != NULL && dlsch1 != NULL) printf("[DCI UE] dlsch0_harq status = %d, dlsch1_harq status = %d\n", dlsch0_harq->status, dlsch1_harq->status); else if (dlsch0 == NULL && dlsch1 != NULL) printf("[DCI UE] dlsch0_harq NULL dlsch1_harq status = %d\n", dlsch1_harq->status); else if (dlsch0 != NULL && dlsch1 == NULL) printf("[DCI UE] dlsch1_harq NULL dlsch0_harq status = %d\n", dlsch0_harq->status); #endif*/ } #endif //(0) #ifdef NR_PDCCH_DCI_TOOLS int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue, uint8_t eNB_id, int frame, uint8_t nr_tti_rx, void *dci_pdu, uint16_t rnti, uint8_t dci_length, NR_DCI_format_t dci_format, NR_UE_PDCCH *pdcch_vars, NR_UE_PDSCH *pdsch_vars, NR_UE_DLSCH_t **dlsch, NR_UE_ULSCH_t *ulsch, NR_DL_FRAME_PARMS *frame_parms, PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, uint8_t beamforming_mode, uint8_t dci_fields_sizes[NBR_NR_DCI_FIELDS][NBR_NR_FORMATS], uint16_t n_RB_ULBWP, uint16_t n_RB_DLBWP, uint16_t crc_scrambled_values[TOTAL_NBR_SCRAMBLED_VALUES], NR_DCI_INFO_EXTRACTED_t *nr_dci_info_extracted) { /* * Note only format0_0 and format1_0 are implemented */ uint8_t harq_pid=0; uint8_t frame_type=frame_parms->frame_type; uint8_t tpmi=0; NR_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; NR_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; NR_UE_ULSCH_t *ulsch0=NULL,*ulsch1=NULL; //NR_DCI_INFO_EXTRACTED_t nr_dci_info_extracted; uint8_t status=0,left_shift=0; uint64_t pdu_bitmap = 0xFFFFFFFFFFFFFFFF; pdu_bitmap = (pdu_bitmap << (64 - dci_length)) >> (64 - dci_length); // this variable will help to remove the bits of other fields when left-switching dlsch0 = dlsch[0]; dlsch0->active = 0; if (dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format-15] != 0) { // 27 HARQ_PROCESS_NUMBER (27 is the position in dci_fields_sizes array for field HARQ_PROCESS_NUMBER) for (int i=0; i<=HARQ_PROCESS_NUMBER; i++) left_shift = left_shift + dci_fields_sizes[i][dci_format-15]; nr_dci_info_extracted->harq_process_number = (uint8_t)(((((*(uint64_t *)dci_pdu) << (left_shift - dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format-15]))) & pdu_bitmap) >> (dci_length - dci_fields_sizes[HARQ_PROCESS_NUMBER][dci_format-15])); left_shift = 0; #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> nr_dci_info_extracted->harq_process_number=%x\n",nr_dci_info_extracted->harq_process_number); #endif } dlsch0_harq = dlsch[0]->harq_processes[nr_dci_info_extracted->harq_process_number]; ulsch0 = ulsch; /* printf("nr_dci_info_extracted.harq_process_number = %d\n",nr_dci_info_extracted.harq_process_number); printf("dlsch0 = %d\n",dlsch0); printf("dlsch0_harq = %d\n",dlsch0_harq);*/ if (!dlsch[0]) return -1; if (!ulsch) return -1; memset(&nr_dci_info_extracted,0,sizeof(nr_dci_info_extracted)); // printf("we reach this point\n"); // switch (dci_format) { // case format0_0: #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Entering function nr_extract_dci_info(dci_format=%d) \n",dci_format); #endif status = nr_extract_dci_info(ue, eNB_id, frame_type, dci_length, rnti, dci_pdu, &nr_dci_info_extracted, dci_fields_sizes, dlsch0_harq, dlsch0, ulsch0, dci_format, nr_tti_rx, n_RB_ULBWP, n_RB_DLBWP, crc_scrambled_values); //status = check_dci_format1_1a_coherency(format1_1, frame_parms->N_RB_DL, rnti, tc_rnti, si_rnti, ra_rnti, p_rnti,frame,nr_tti_rx, &nr_dci_info_extracted, dlsch0_harq); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG if(status == 0) { printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> bad DCI %d !!! \n",dci_format); return(-1); } #endif // break; /* case format0_1: #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format); #endif break; case format1_0: #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Entering function nr_extract_dci_info(dci_format=%d)for PDSCH allocation\n",dci_format); #endif status = nr_extract_dci_info(ue, eNB_id, frame_type, dci_length, dci_pdu,rnti, &nr_dci_info_extracted, dci_fields_sizes, dlsch0_harq, dlsch0, ulsch0, dci_format, nr_tti_rx, n_RB_ULBWP, n_RB_DLBWP,crc_scrambled_values); //status = check_dci_format1_1a_coherency(format1_1, frame_parms->N_RB_DL, rnti, tc_rnti, si_rnti, ra_rnti, p_rnti,frame,nr_tti_rx, &nr_dci_info_extracted, dlsch0_harq); #ifdef NR_PDCCH_DCI_TOOLS_DEBUG if(status == 0) { printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> bad DCI %d !!! \n",dci_format); return(-1); } #endif break; case format1_1: #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format); #endif break; case format2_0: #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format); #endif break; case format2_1: #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format); #endif break; case format2_2: #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format); #endif break; case format2_3: #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> format %d not implemented yet\n",dci_format); #endif break; default: printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> we go to the default in switch\n"); //LOG_E(PHY,"format %d not yet implemented\n",dci_format); return(-1); break; }*/ #ifdef NR_PDCCH_DCI_TOOLS_DEBUG printf("\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci) -> Ending function nr_extract_dci_info()\n"); #endif return(0); } #endif #if 0 int generate_ue_dlsch_params_from_dci(int frame, uint8_t nr_tti_rx, void *dci_pdu, uint16_t rnti, DCI_format_t dci_format, NR_UE_PDCCH *pdcch_vars, NR_UE_PDSCH *pdsch_vars, NR_UE_DLSCH_t **dlsch, NR_DL_FRAME_PARMS *frame_parms, PDSCH_CONFIG_DEDICATED *pdsch_config_dedicated, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, uint8_t beamforming_mode, uint16_t tc_rnti) { uint8_t harq_pid=0; uint8_t frame_type=frame_parms->frame_type; uint8_t tpmi=0; NR_UE_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; NR_DL_UE_HARQ_t *dlsch0_harq=NULL,*dlsch1_harq=NULL; DCI_INFO_EXTRACTED_t dci_info_extarcted; uint8_t status=0; //////////////////////////////////////////////////////////////////////////////////////////////////////////////// printf("####################### verifying pointer\n"); dlsch0 = dlsch[0]; dlsch0->active = 0; dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; printf("####################### verifying pointer, dlsch0 = %p, dlsch0_harq = %p\n",dlsch0,dlsch0_harq); //////////////////////////////////////////////////////////////////////////////////////////////////////////////// if (!dlsch[0]) return -1; #ifdef DEBUG_DCI LOG_D(PHY,"dci_tools.c: Filling ue dlsch params -> rnti %x, SFN/SF %d/%d, dci_format %s\n", rnti, frame%1024, nr_tti_rx, (dci_format==format0? "Format 0":( dci_format==format1? "format 1":( dci_format==format1A? "format 1A":( dci_format==format1B? "format 1B":( dci_format==format1C? "format 1C":( dci_format==format1D? "format 1D":( dci_format==format1E_2A_M10PRB? "format 1E_2A_M10PRB":( dci_format==format2? "format 2":( dci_format==format2A? "format 2A":( dci_format==format2B? "format 2B":( dci_format==format2C? "format 2C":( dci_format==format2D? "format 2D":( dci_format==format3? "format 3": "UNKNOWN" )))))))))))))); #endif memset(&dci_info_extarcted,0,sizeof(dci_info_extarcted)); switch (dci_format) { case format0: // This is an ULSCH allocation so nothing here, inform MAC LOG_E(PHY,"format0 not possible\n"); return(-1); break; case format1A: { // extract dci infomation #ifdef DEBUG_DCI LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d extarct dci info \n", frame, nr_tti_rx); #endif extract_dci1A_info(frame_parms->N_RB_DL, frame_type, dci_pdu, &dci_info_extarcted); // check dci content dlsch0 = dlsch[0]; dlsch0->active = 0; dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; #ifdef DEBUG_DCI LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d check dci coherency \n", frame, nr_tti_rx); #endif status = check_dci_format1_1a_coherency(format1A, frame_parms->N_RB_DL, rnti, tc_rnti, si_rnti, ra_rnti, p_rnti,frame,nr_tti_rx, &dci_info_extarcted, dlsch0_harq); if(status == 0) { printf("bad DCI 1A !!! \n"); return(-1); } // dci is correct ==> update internal structure and prepare dl decoding #ifdef DEBUG_DCI LOG_I(PHY,"[DCI-FORMAT-1A] AbsSubframe %d.%d prepare dl decoding \n", frame, nr_tti_rx); #endif prepare_dl_decoding_format1_1A(format1A, frame_parms->N_RB_DL, &dci_info_extarcted, frame_parms, pdcch_vars, pdsch_vars, nr_tti_rx, rnti, tc_rnti, si_rnti, ra_rnti, p_rnti, dlsch0_harq, dlsch0); break; } case format1C: { // extract dci infomation #ifdef DEBUG_DL_DECODING LOG_I(PHY,"[DCI Format-1C] extact dci information \n"); #endif extract_dci1C_info(frame_parms->N_RB_DL, frame_type, dci_pdu, &dci_info_extarcted); // check dci content #ifdef DEBUG_DL_DECODING LOG_I(PHY,"[DCI Format-1C] check dci content \n"); #endif dlsch0 = dlsch[0]; dlsch0->active = 0; dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; status = check_dci_format1c_coherency(frame_parms->N_RB_DL, &dci_info_extarcted, rnti, si_rnti, ra_rnti, p_rnti, dlsch0_harq); if(status == 0) return(-1); // dci is correct ==> update internal structure and prepare dl decoding #ifdef DEBUG_DL_DECODING LOG_I(PHY,"[DCI Format-1C] prepare downlink decoding \n"); #endif prepare_dl_decoding_format1C(frame_parms->N_RB_DL, &dci_info_extarcted, frame_parms, pdcch_vars, pdsch_vars, rnti, si_rnti, ra_rnti, p_rnti, frame, nr_tti_rx, dlsch0_harq, dlsch0); break; } case format1: { // extract dci infomation #ifdef DEBUG_DCI LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d extarct dci info \n", frame, nr_tti_rx); #endif extract_dci1_info(frame_parms->N_RB_DL, frame_type, dci_pdu, &dci_info_extarcted); // check dci content dlsch0 = dlsch[0]; dlsch0->active = 0; dlsch0_harq = dlsch[0]->harq_processes[dci_info_extarcted.harq_pid]; #ifdef DEBUG_DCI LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d check dci coherency \n", frame, nr_tti_rx); #endif status = check_dci_format1_1a_coherency(format1, frame_parms->N_RB_DL, rnti, tc_rnti, si_rnti, ra_rnti, p_rnti,frame,nr_tti_rx, &dci_info_extarcted, dlsch0_harq); if(status == 0) { printf("bad DCI 1 !!! \n"); return(-1); } // dci is correct ==> update internal structure and prepare dl decoding #ifdef DEBUG_DCI LOG_I(PHY,"[DCI-FORMAT-1] AbsSubframe %d.%d prepare dl decoding \n", frame, nr_tti_rx); #endif prepare_dl_decoding_format1_1A(format1, frame_parms->N_RB_DL, &dci_info_extarcted, frame_parms, pdcch_vars, pdsch_vars, nr_tti_rx, rnti, tc_rnti, si_rnti, ra_rnti, p_rnti, dlsch0_harq, dlsch0); break; } case format2: { // extract dci infomation //LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame, subframe); extract_dci2_info(frame_parms->N_RB_DL, frame_type, frame_parms->nb_antenna_ports_eNB, dci_pdu, &dci_info_extarcted); // check dci content dlsch[0]->active = 1; dlsch[1]->active = 1; dlsch0 = dlsch[0]; dlsch1 = dlsch[1]; dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid]; dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid]; // printf("before coherency dlsch[1]->pmi_alloc %d\n",dlsch[1]->pmi_alloc); // printf("before coherency dlsch1->pmi_alloc %d\n",dlsch1->pmi_alloc); // printf("before coherency dlsch1_harq->pmi_alloc %d\n",dlsch1_harq->pmi_alloc); //LOG_I(PHY,"[DCI-format2] check dci content \n"); status = check_dci_format2_2a_coherency(format2, frame_parms->N_RB_DL, &dci_info_extarcted, rnti, si_rnti, ra_rnti, p_rnti, dlsch0_harq, dlsch1_harq); if(status == 0) return(-1); // dci is correct ==> update internal structure and prepare dl decoding //LOG_I(PHY,"[DCI-format2] update internal structure and prepare dl decoding \n"); prepare_dl_decoding_format2_2A(format2, &dci_info_extarcted, frame_parms, pdcch_vars, pdsch_vars, rnti, nr_tti_rx, dlsch0_harq, dlsch1_harq, dlsch0, dlsch1); } break; case format2A: { // extract dci infomation LOG_I(PHY,"[DCI-format2] AbsSubframe %d.%d extract dci infomation \n", frame%1024, nr_tti_rx); extract_dci2A_info(frame_parms->N_RB_DL, frame_type, frame_parms->nb_antenna_ports_eNB, dci_pdu, &dci_info_extarcted); // check dci content //LOG_I(PHY,"[DCI-format2A] check dci content \n"); //LOG_I(PHY,"[DCI-format2A] tb_swap %d harq_pid %d\n", dci_info_extarcted.tb_swap, dci_info_extarcted.harq_pid); //dlsch[0]->active = 0; //dlsch[1]->active = 0; if (dci_info_extarcted.tb_swap == 0) { dlsch0 = dlsch[0]; dlsch1 = dlsch[1]; } else { dlsch0 = dlsch[1]; dlsch1 = dlsch[0]; } dlsch0_harq = dlsch0->harq_processes[dci_info_extarcted.harq_pid]; dlsch1_harq = dlsch1->harq_processes[dci_info_extarcted.harq_pid]; //LOG_I(PHY,"[DCI-format2A] check dci content \n"); status = check_dci_format2_2a_coherency(format2A, frame_parms->N_RB_DL, &dci_info_extarcted, rnti, si_rnti, ra_rnti, p_rnti, dlsch0_harq, dlsch1_harq); if(status == 0) return(-1); // dci is correct ==> update internal structure and prepare dl decoding //LOG_I(PHY,"[DCI-format2A] update internal structure and prepare dl decoding \n"); prepare_dl_decoding_format2_2A(format2A, &dci_info_extarcted, frame_parms, pdcch_vars, pdsch_vars, rnti, nr_tti_rx, dlsch0_harq, dlsch1_harq, dlsch0, dlsch1); } break; case format1E_2A_M10PRB: if (!dlsch[0]) return -1; harq_pid = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->harq_pid; if (harq_pid>=8) { LOG_E(PHY,"Format 1E_2A_M10PRB: harq_pid=%d >= 8\n", harq_pid); return(-1); } dlsch[0]->current_harq_pid = harq_pid; dlsch[0]->harq_ack[nr_tti_rx].harq_id = harq_pid; /* tbswap = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tb_swap; if (tbswap == 0) { dlsch0 = dlsch[0]; dlsch1 = dlsch[1]; } else{ dlsch0 = dlsch[1]; dlsch1 = dlsch[0]; } */ dlsch0 = dlsch[0]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; // Needs to be checked dlsch0_harq->codeword=0; conv_rballoc(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc,frame_parms->N_RB_DL, dlsch0_harq->rb_alloc_even); dlsch0_harq->rb_alloc_odd[0] = dlsch0_harq->rb_alloc_even[0]; dlsch0_harq->rb_alloc_odd[1] = dlsch0_harq->rb_alloc_even[1]; dlsch0_harq->rb_alloc_odd[2] = dlsch0_harq->rb_alloc_even[2]; dlsch0_harq->rb_alloc_odd[3] = dlsch0_harq->rb_alloc_even[3]; /* dlsch1_harq->rb_alloc_even[0] = dlsch0_harq->rb_alloc_even[0]; dlsch1_harq->rb_alloc_even[1] = dlsch0_harq->rb_alloc_even[1]; dlsch1_harq->rb_alloc_even[2] = dlsch0_harq->rb_alloc_even[2]; dlsch1_harq->rb_alloc_even[3] = dlsch0_harq->rb_alloc_even[3]; */ dlsch0_harq->nb_rb = conv_nprb(((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rah, ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rballoc, frame_parms->N_RB_DL); //dlsch1_harq->nb_rb = dlsch0_harq->nb_rb; dlsch0_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs; dlsch0_harq->delta_PUCCH = nr_delta_PUCCH_lut[((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->TPC&3]; /* if (dlsch0_harq->mcs>20) { printf("dci_tools.c: mcs > 20 disabled for now (asked %d)\n",dlsch0_harq->mcs); return(-1); } */ //dlsch1_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs2; dlsch0_harq->rvidx = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv; //dlsch1_harq->rvidx = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->rv2; // check if either TB is disabled (see 36-213 V8.6 p. 26) if ((dlsch0_harq->rvidx == 1) && (dlsch0_harq->mcs == 0)) { dlsch0_harq->status = DISABLED; } //if ((dlsch1_harq->rvidx == 1) && (dlsch1_harq->mcs == 0)) { //dlsch1_harq->status = DISABLED; //} dlsch0_harq->Nl = 1; //dlsch0->layer_index = tbswap; //dlsch1->layer_index = 1-tbswap; // Fix this tpmi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->tpmi; // printf("ue: tpmi %d\n",tpmi); switch (tpmi) { case 0 : dlsch0_harq->mimo_mode = ALAMOUTI; break; case 1: dlsch0_harq->mimo_mode = UNIFORM_PRECODING11; dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,0,0); break; case 2: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1m1; dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,1, 0); break; case 3: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1j; dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,2, 0); break; case 4: dlsch0_harq->mimo_mode = UNIFORM_PRECODING1mj; dlsch0_harq->pmi_alloc = pmi_extend(frame_parms,3, 0); break; case 5: dlsch0_harq->mimo_mode = PUSCH_PRECODING0; // pmi stored from ulsch allocation routine dlsch0_harq->pmi_alloc = dlsch0->pmi_alloc; //LOG_I(PHY,"XXX using PMI %x\n",pmi2hex_2Ar1(dlsch0_harq->pmi_alloc)); break; case 6: dlsch0_harq->mimo_mode = PUSCH_PRECODING1; LOG_E(PHY,"Unsupported TPMI\n"); return(-1); break; } if (frame_parms->mode1_flag == 1) dlsch0_harq->mimo_mode = SISO; if ((dlsch0_harq->DCINdi != ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi) || (dlsch0_harq->first_tx==1)) { dlsch0_harq->round = 0; dlsch0_harq->first_tx = 0; dlsch0_harq->status = ACTIVE; } /* else if (dlsch0_harq->status == SCH_IDLE) { // we got same ndi for a previously decoded process, // this happens if either another harq process in the same // is NAK or an ACK was not received dlsch0->harq_ack[subframe].ack = 1; dlsch0->harq_ack[subframe].harq_id = harq_pid; dlsch0->harq_ack[subframe].send_harq_status = 1; dlsch0->active = 0; return(0); } */ dlsch0_harq->DCINdi = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->ndi; dlsch0_harq->mcs = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->mcs; if (dlsch0_harq->nb_rb>1) { dlsch0_harq->TBS = TBStable[get_I_TBS(dlsch0_harq->mcs)][dlsch0_harq->nb_rb-1]; } else dlsch0_harq->TBS =0; dlsch0->rnti = rnti; //dlsch1->rnti = rnti; dlsch0->active = 1; //dlsch1->active = 1; dlsch0_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off; //dlsch1_harq->dl_power_off = ((DCI1E_5MHz_2A_M10PRB_TDD_t *)dci_pdu)->dl_power_off; break; default: LOG_E(PHY,"format %d not yet implemented\n",dci_format); return(-1); break; } #ifdef UE_DEBUG_TRACE if (dlsch[0] && (dlsch[0]->rnti != 0xffff)) { LOG_I(PHY,"dci_format:%d Abssubframe: %d.%d \n",dci_format,frame%1024,nr_tti_rx); LOG_I(PHY,"PDSCH dlsch0 UE: rnti %x\n",dlsch[0]->rnti); LOG_D(PHY,"PDSCH dlsch0 UE: NBRB %d\n",dlsch0_harq->nb_rb); LOG_D(PHY,"PDSCH dlsch0 UE: rballoc %x\n",dlsch0_harq->rb_alloc_even[0]); LOG_I(PHY,"PDSCH dlsch0 UE: harq_pid %d\n",dci_info_extarcted.harq_pid); LOG_I(PHY,"PDSCH dlsch0 UE: g %d\n",dlsch[0]->g_pucch); LOG_D(PHY,"PDSCH dlsch0 UE: round %d\n",dlsch0_harq->round); LOG_D(PHY,"PDSCH dlsch0 UE: DCINdi %d\n",dlsch0_harq->DCINdi); LOG_D(PHY,"PDSCH dlsch0 UE: rvidx %d\n",dlsch0_harq->rvidx); LOG_D(PHY,"PDSCH dlsch0 UE: TBS %d\n",dlsch0_harq->TBS); LOG_D(PHY,"PDSCH dlsch0 UE: mcs %d\n",dlsch0_harq->mcs); LOG_D(PHY,"PDSCH dlsch0 UE: pwr_off %d\n",dlsch0_harq->dl_power_off); } #endif #if T_TRACER if( (dlsch[0]->rnti != si_rnti) && (dlsch[0]->rnti != ra_rnti) && (dlsch[0]->rnti != p_rnti)) { T(T_UE_PHY_DLSCH_UE_DCI, T_INT(0), T_INT(frame%1024), T_INT(nr_tti_rx), T_INT(0), T_INT(dlsch[0]->rnti), T_INT(dci_format), T_INT(harq_pid), T_INT(dlsch0_harq->mcs), T_INT(dlsch0_harq->TBS)); } #endif // compute DL power control parameters if (dlsch0_harq != NULL){ computeRhoA_UE(pdsch_config_dedicated, dlsch[0],dlsch0_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB); computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[0],dlsch0_harq->dl_power_off); } if (dlsch1_harq != NULL) { computeRhoA_UE(pdsch_config_dedicated, dlsch[1],dlsch1_harq->dl_power_off, frame_parms->nb_antenna_ports_eNB); computeRhoB_UE(pdsch_config_dedicated,&(frame_parms->pdsch_config_common),frame_parms->nb_antenna_ports_eNB,dlsch[1],dlsch1_harq->dl_power_off); } return(0); } #endif //(0) uint8_t nr_subframe2harq_pid(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t nr_tti_rx) { /* #ifdef DEBUG_DCI if (frame_parms->frame_type == TDD) printf("dci_tools.c: subframe2_harq_pid, subframe %d for TDD configuration %d\n",subframe,frame_parms->tdd_config); else printf("dci_tools.c: subframe2_harq_pid, subframe %d for FDD \n",subframe); #endif */ uint8_t ret = 255; uint8_t subframe = nr_tti_rx>>((int)(log2 (frame_parms->ttis_per_subframe))); if (frame_parms->frame_type == FDD) { ret = (((frame<<1)+nr_tti_rx)&7); } else { switch (frame_parms->tdd_config) { case 1: if ((subframe==2) || (subframe==3) || (subframe==7) || (subframe==8)) switch (subframe) { case 2: case 3: ret = (subframe-2); break; case 7: case 8: ret = (subframe-5); break; default: LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); ret = (255); break; } break; case 2: if ((subframe!=2) && (subframe!=7)) { LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); //mac_xface->macphy_exit("subframe2_harq_pid, Illegal subframe"); ret = (255); } ret = (subframe/7); break; case 3: if ((subframe<2) || (subframe>4)) { LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); ret = (255); } ret = (subframe-2); break; case 4: if ((subframe<2) || (subframe>3)) { LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); ret = (255); } ret = (subframe-2); break; case 5: if (subframe!=2) { LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config); ret = (255); } ret = (subframe-2); break; default: LOG_E(PHY,"subframe2_harq_pid, Unsupported TDD mode %d\n",frame_parms->tdd_config); ret = (255); } } if (ret == 255) { LOG_E(PHY, "invalid harq_pid(%d) at SFN/SF = %d/%d\n", ret, frame, subframe); //mac_xface->macphy_exit("invalid harq_pid"); } return ret; } uint8_t nr_pdcch_alloc2ul_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t n) { uint8_t ul_subframe = 255; if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config == 1) && ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5 ul_subframe = ((n+6)%10); else if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config == 6) && ((n==0)||(n==1)||(n==5)||(n==6))) ul_subframe = ((n+7)%10); else if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config == 6) && (n==9)) // tdd_config 6 SF 9 ul_subframe = ((n+5)%10); else ul_subframe = ((n+4)%10); LOG_D(PHY, "subframe %d: PUSCH subframe = %d\n", n, ul_subframe); return ul_subframe; } #if 0 uint8_t ul_subframe2pdcch_alloc_subframe(NR_DL_FRAME_PARMS *frame_parms,uint8_t n) { if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config == 1) && ((n==7)||(n==2))) // tdd_config 0,1 SF 1,5 return((n==7)? 1 : 6); else if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config == 6) && ((n==7)||(n==8)||(n==2)||(n==3))) return((n+3)%10); else if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config == 6) && (n==4)) // tdd_config 6 SF 9 return(9); else return((n+6)%10); } #endif //(0) uint32_t nr_pdcch_alloc2ul_frame(NR_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t n) { uint32_t ul_frame = 255; if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config == 1) && ((n==1)||(n==6))) // tdd_config 0,1 SF 1,5 ul_frame = (frame + (n==1 ? 0 : 1)); else if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config == 6) && ((n==0)||(n==1)||(n==5)||(n==6))) ul_frame = (frame + (n>=5 ? 1 : 0)); else if ((frame_parms->frame_type == TDD) && (frame_parms->tdd_config == 6) && (n==9)) // tdd_config 6 SF 9 ul_frame = (frame+1); else ul_frame = (frame+(n>=6 ? 1 : 0)); LOG_D(PHY, "frame %d subframe %d: PUSCH frame = %d\n", frame, n, ul_frame); return ul_frame; } #if 0 int32_t pmi_convert_rank1_from_rank2(uint16_t pmi_alloc, int tpmi, int nb_rb) { int nb_subbands = 0; int32_t pmi_alloc_new = 0, pmi_new = 0, pmi_old = 0; int i; switch (nb_rb) { case 6: nb_subbands = 6; break; default: case 25: nb_subbands = 7; break; case 50: nb_subbands = 9; break; case 100: nb_subbands = 13; break; } for (i = 0; i < nb_subbands; i++) { pmi_old = (pmi_alloc >> i)&1; if (pmi_old == 0) if (tpmi == 5) pmi_new = 0; else pmi_new = 1; else if (tpmi == 5) pmi_new = 2; else pmi_new = 3; pmi_alloc_new|=pmi_new<<(2*i); } #ifdef DEBUG_HARQ printf(" [DCI UE] pmi_alloc_old %d, pmi_alloc_new %d pmi_old %d , pmi_new %d\n", pmi_alloc, pmi_alloc_new,pmi_old, pmi_new ); #endif return(pmi_alloc_new); } uint16_t quantize_subband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,int nb_rb) { int i, aarx; uint16_t pmiq=0; uint32_t pmivect = 0; uint8_t rank = meas->rank[eNB_id]; int pmi_re,pmi_im; int nb_subbands=0; switch (nb_rb) { case 6: nb_subbands = 6; break; default: case 25: nb_subbands = 7; break; case 50: nb_subbands = 9; break; case 100: nb_subbands = 13; break; } for (i=0; i<nb_subbands; i++) { pmi_re = 0; pmi_im = 0; if (rank == 0) { for (aarx=0; aarx<meas->nb_antennas_rx; aarx++) { pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; } // pmi_re = meas->subband_pmi_re[eNB_id][i][meas->selected_rx_antennas[eNB_id][i]]; // pmi_im = meas->subband_pmi_im[eNB_id][i][meas->selected_rx_antennas[eNB_id][i]]; // printf("pmi => (%d,%d)\n",pmi_re,pmi_im); if ((pmi_re > pmi_im) && (pmi_re > -pmi_im)) pmiq = PMI_2A_11; else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im)) pmiq = PMI_2A_1j; else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im)) pmiq = PMI_2A_1m1; else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im)) pmiq = PMI_2A_1mj; // printf("subband %d, pmi%d \n",i,pmiq); pmivect |= (pmiq<<(2*i)); } else if (rank==1) { for (aarx=0; aarx<meas->nb_antennas_rx; aarx++) { pmi_re += meas->subband_pmi_re[eNB_id][i][aarx]; //printf("meas->subband_pmi_re[eNB_id][i][%d]=%d\n", aarx, meas->subband_pmi_re[eNB_id][i][aarx]); pmi_im += meas->subband_pmi_im[eNB_id][i][aarx]; //printf("meas->subband_pmi_im[eNB_id][i][%d]=%d\n",aarx, meas->subband_pmi_im[eNB_id][i][aarx]); } if (pmi_re >= pmi_im) // this is not orthogonal // this is orthogonal //if (((pmi_re >= pmi_im) && (pmi_re >= -pmi_im)) || ((pmi_re <= pmi_im) && (pmi_re >= -pmi_im))) pmiq = PMI_2A_R1_11; else pmiq = PMI_2A_R1_1j; // printf("subband %d, pmi_re %d, pmi_im %d, pmiq %d \n",i,pmi_re,pmi_im,pmiq); // printf("subband %d, pmi%d \n",i,pmiq); //According to Section 7.2.4 of 36.213 pmivect |= ((pmiq-1)<<(i)); //shift 1 since only one bit } else { LOG_E(PHY,"PMI feedback for rank>1 not supported!\n"); pmivect = 0; } } #ifdef DEBUG_HARQ printf( "quantize_subband_pmi pmivect %d \n", pmivect); #endif return(pmivect); } uint16_t quantize_subband_pmi2(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t a_id,int nb_subbands) { uint8_t i; uint16_t pmiq=0; uint16_t pmivect = 0; uint8_t rank = meas->rank[eNB_id]; int pmi_re,pmi_im; for (i=0; i<nb_subbands; i++) { if (rank == 0) { pmi_re = meas->subband_pmi_re[eNB_id][i][a_id]; pmi_im = meas->subband_pmi_im[eNB_id][i][a_id]; if ((pmi_re > pmi_im) && (pmi_re > -pmi_im)) pmiq = PMI_2A_11; else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im)) pmiq = PMI_2A_1j; else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im)) pmiq = PMI_2A_1m1; else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im)) pmiq = PMI_2A_1mj; pmivect |= (pmiq<<(2*i)); } else { // This needs to be done properly!!! pmivect = 0; } } return(pmivect); } uint16_t quantize_wideband_pmi(PHY_MEASUREMENTS *meas,uint8_t eNB_id) { uint16_t pmiq=0; uint8_t rank = meas->rank[eNB_id]; //int pmi; int pmi_re,pmi_im; if (rank == 1) { //pmi = pmi_re = meas->wideband_pmi_re[eNB_id][meas->selected_rx_antennas[eNB_id][0]]; pmi_im = meas->wideband_pmi_im[eNB_id][meas->selected_rx_antennas[eNB_id][0]]; if ((pmi_re > pmi_im) && (pmi_re > -pmi_im)) pmiq = PMI_2A_11; else if ((pmi_re < pmi_im) && (pmi_re > -pmi_im)) pmiq = PMI_2A_1j; else if ((pmi_re < pmi_im) && (pmi_re < -pmi_im)) pmiq = PMI_2A_1m1; else if ((pmi_re > pmi_im) && (pmi_re < -pmi_im)) pmiq = PMI_2A_1mj; } else { // This needs to be done properly! pmiq = PMI_2A_11; } return(pmiq); } /* uint8_t sinr2cqi(int sinr) { if (sinr<-3) return(0); if (sinr>14) return(10); else return(3+(sinr>>1)); } */ uint8_t sinr2cqi(double sinr,uint8_t trans_mode) { // int flag_LA=0; uint8_t retValue = 0; if(flag_LA==0) { // Ideal Channel Estimation if (sinr<=-4.89) retValue = (0); else if (sinr < -3.53) retValue = (3); else if (sinr <= -1.93) retValue = (4); else if (sinr <= -0.43) retValue = (5); else if (sinr <= 1.11) retValue = (6); else if (sinr <= 3.26) retValue = (7); else if (sinr <= 5.0) retValue = (8); else if (sinr <= 7.0) retValue = (9); else if (sinr <= 9.0) retValue = (10); else if (sinr <= 11.0) retValue = (11); else if (sinr <= 13.0) retValue = (12); else if (sinr <= 15.5) retValue = (13); else if (sinr <= 17.5) retValue = (14); else retValue = (15); } else { int h=0; int trans_mode_tmp; if (trans_mode ==5) trans_mode_tmp=2; else if(trans_mode ==6) trans_mode_tmp=3; else trans_mode_tmp = trans_mode-1; for(h=0; h<16; h++) { if(sinr<=sinr_to_cqi[trans_mode_tmp][h]) retValue = (h); } } LOG_D(PHY, "sinr=%f trans_mode=%d cqi=%d\n", sinr, trans_mode, retValue); return retValue; } //uint32_t fill_subband_cqi(PHY_MEASUREMENTS *meas,uint8_t eNB_id) { // // uint8_t i; //// uint16_t cqivect = 0; // uint32_t cqivect = 0; // //// char diff_cqi; // int diff_cqi=0; // // for (i=0;i<NUMBER_OF_SUBBANDS;i++) { // // diff_cqi = -sinr2cqi(meas->wideband_cqi_dB[eNB_id][0]) + sinr2cqi(meas->subband_cqi_dB[eNB_id][0][i]); // // // Note, this is Table 7.2.1-2 from 36.213 // if (diff_cqi<=-1) // diff_cqi = 3; // else if (diff_cqi>2) // diff_cqi = 2; // cqivect |= (diff_cqi<<(2*i)); // // } // // return(cqivect); //} uint32_t fill_subband_cqi(PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t trans_mode,int nb_subbands) { uint8_t i; uint32_t cqivect = 0,offset=0; int diff_cqi=0; for (i=0; i<nb_subbands; i++) { diff_cqi = -sinr2cqi(meas->wideband_cqi_avg[eNB_id],trans_mode) + sinr2cqi(meas->subband_cqi_tot_dB[eNB_id][i],trans_mode); // Note, this is Table 7.2.1-2 from 36.213 if (diff_cqi<=-1) offset = 3; else if (diff_cqi>=2) offset = 2; else offset=(uint32_t)diff_cqi; cqivect |= (offset<<(2*i)); } return(cqivect); } void fill_CQI(NR_UE_ULSCH_t *ulsch,PHY_MEASUREMENTS *meas,uint8_t eNB_id,uint8_t harq_pid,int N_RB_DL,uint16_t rnti, uint8_t trans_mode, double sinr_eff) { // printf("[PHY][UE] Filling CQI for eNB %d, meas->wideband_cqi_tot[%d] %d\n", // eNB_id,eNB_id,meas->wideband_cqi_tot[eNB_id]); double sinr_tmp; uint8_t *o = ulsch->o; UCI_format_t uci_format = ulsch->uci_format; if(flag_LA==1) sinr_tmp = sinr_eff; else sinr_tmp = (double) meas->wideband_cqi_avg[eNB_id]; //LOG_I(PHY,"[UE][UCI] Filling CQI format %d for eNB %d N_RB_DL %d\n",uci_format,eNB_id,N_RB_DL); switch (N_RB_DL) { case 6: switch (uci_format) { case wideband_cqi_rank1_2A: ((wideband_cqi_rank1_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((wideband_cqi_rank1_2A_1_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,6); break; case wideband_cqi_rank2_2A: ((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi ((wideband_cqi_rank2_2A_1_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi ((wideband_cqi_rank2_2A_1_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,6); break; case HLC_subband_cqi_nopmi: ((HLC_subband_cqi_nopmi_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_nopmi_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6); break; case HLC_subband_cqi_rank1_2A: ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6); ((HLC_subband_cqi_rank1_2A_1_5MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); break; case HLC_subband_cqi_rank2_2A: // This has to be improved!!! ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,6); ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,6); ((HLC_subband_cqi_rank2_2A_1_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,6); break; case HLC_subband_cqi_mcs_CBA: // this is the cba mcs uci for cba transmission ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; ((HLC_subband_cqi_mcs_CBA_1_5MHz *)o)->crnti = rnti; LOG_D(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); break; case ue_selected: LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!"); break; default: LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); mac_xface->macphy_exit("unsupported CQI mode !!!"); break; } break; case 25: switch (uci_format) { case wideband_cqi_rank1_2A: ((wideband_cqi_rank1_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((wideband_cqi_rank1_2A_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,7); break; case wideband_cqi_rank2_2A: ((wideband_cqi_rank2_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi ((wideband_cqi_rank2_2A_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi ((wideband_cqi_rank2_2A_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,7); break; case HLC_subband_cqi_nopmi: ((HLC_subband_cqi_nopmi_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_nopmi_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7); break; case HLC_subband_cqi_rank1_2A: ((HLC_subband_cqi_rank1_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank1_2A_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7); ((HLC_subband_cqi_rank1_2A_5MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); break; case HLC_subband_cqi_rank2_2A: // This has to be improved!!! ((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,7); ((HLC_subband_cqi_rank2_2A_5MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank2_2A_5MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,7); ((HLC_subband_cqi_rank2_2A_5MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,7); break; case HLC_subband_cqi_mcs_CBA: // this is the cba mcs uci for cba transmission ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti = rnti; LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); break; case ue_selected: LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!"); break; default: LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); mac_xface->macphy_exit("unsupported CQI mode !!!"); break; } break; case 50: switch (uci_format) { case wideband_cqi_rank1_2A: ((wideband_cqi_rank1_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((wideband_cqi_rank1_2A_10MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,9); break; case wideband_cqi_rank2_2A: ((wideband_cqi_rank2_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi ((wideband_cqi_rank2_2A_10MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi ((wideband_cqi_rank2_2A_10MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,9); break; case HLC_subband_cqi_nopmi: ((HLC_subband_cqi_nopmi_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_nopmi_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9); break; case HLC_subband_cqi_rank1_2A: ((HLC_subband_cqi_rank1_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank1_2A_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9); ((HLC_subband_cqi_rank1_2A_10MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); break; case HLC_subband_cqi_rank2_2A: // This has to be improved!!! ((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,9); ((HLC_subband_cqi_rank2_2A_10MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank2_2A_10MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,9); ((HLC_subband_cqi_rank2_2A_10MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,9); break; case HLC_subband_cqi_mcs_CBA: // this is the cba mcs uci for cba transmission ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; ((HLC_subband_cqi_mcs_CBA_10MHz *)o)->crnti = rnti; LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); break; case ue_selected: LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!"); break; default: LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); mac_xface->macphy_exit("unsupported CQI mode !!!"); break; } break; case 100: switch (uci_format) { case wideband_cqi_rank1_2A: ((wideband_cqi_rank1_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((wideband_cqi_rank1_2A_20MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,13); break; case wideband_cqi_rank2_2A: ((wideband_cqi_rank2_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi ((wideband_cqi_rank2_2A_20MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); //FIXME: calculate rank2 cqi ((wideband_cqi_rank2_2A_20MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,13); break; case HLC_subband_cqi_nopmi: ((HLC_subband_cqi_nopmi_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_nopmi_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13); break; case HLC_subband_cqi_rank1_2A: ((HLC_subband_cqi_rank1_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank1_2A_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13); ((HLC_subband_cqi_rank1_2A_20MHz *)o)->pmi = quantize_wideband_pmi(meas,eNB_id); break; case HLC_subband_cqi_rank2_2A: // This has to be improved!!! ((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi1 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi1 = fill_subband_cqi(meas,eNB_id,trans_mode,13); ((HLC_subband_cqi_rank2_2A_20MHz *)o)->cqi2 = sinr2cqi(sinr_tmp,trans_mode); ((HLC_subband_cqi_rank2_2A_20MHz *)o)->diffcqi2 = fill_subband_cqi(meas,eNB_id,trans_mode,13); ((HLC_subband_cqi_rank2_2A_20MHz *)o)->pmi = quantize_subband_pmi(meas,eNB_id,13); break; case HLC_subband_cqi_mcs_CBA: // this is the cba mcs uci for cba transmission ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->mcs = ulsch->harq_processes[harq_pid]->mcs; ((HLC_subband_cqi_mcs_CBA_20MHz *)o)->crnti = rnti; LOG_N(PHY,"fill uci for cba rnti %x, mcs %d \n", rnti, ulsch->harq_processes[harq_pid]->mcs); break; case ue_selected: LOG_E(PHY,"fill_CQI ue_selected CQI not supported yet!!!\n"); mac_xface->macphy_exit("fill_CQI ue_selected CQI not supported yet!!!"); break; default: LOG_E(PHY,"unsupported CQI mode (%d)!!!\n",uci_format); mac_xface->macphy_exit("unsupported CQI mode !!!"); break; } break; } } void reset_cba_uci(void *o) { // this is the cba mcs uci for cba transmission ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->mcs = 0; //fixme ((HLC_subband_cqi_mcs_CBA_5MHz *)o)->crnti = 0x0; } uint32_t pmi_extend(NR_DL_FRAME_PARMS *frame_parms,uint8_t wideband_pmi, uint8_t rank) { uint8_t i,wideband_pmi2; uint32_t pmi_ex = 0; if (frame_parms->N_RB_DL!=25) { LOG_E(PHY,"pmi_extend not yet implemented for anything else than 25PRB\n"); return(-1); } if (rank==0) { wideband_pmi2=wideband_pmi&3; for (i=0; i<14; i+=2) pmi_ex|=(wideband_pmi2<<i); } else if (rank==1) { wideband_pmi2=wideband_pmi&1; for (i=0; i<7; i++) pmi_ex|=(wideband_pmi2<<i); } else { LOG_E(PHY,"unsupported rank\n"); return(-1); } return(pmi_ex); } int generate_ue_ulsch_params_from_dci(void *dci_pdu, uint16_t rnti, uint8_t nr_tti_rx, DCI_format_t dci_format, PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, uint16_t cba_rnti, uint8_t eNB_id, uint8_t use_srs) { uint8_t harq_pid; uint8_t transmission_mode = ue->transmission_mode[eNB_id]; ANFBmode_t AckNackFBMode; NR_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; NR_UE_DLSCH_t **dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][0]; PHY_MEASUREMENTS *meas = &ue->measurements; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; // uint32_t current_dlsch_cqi = ue->current_dlsch_cqi[eNB_id]; if(frame_parms->frame_type == TDD) { AckNackFBMode = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode; } else { AckNackFBMode = 1; // 1: multiplexing for FDD } uint32_t cqi_req; uint32_t dai=3; uint32_t cshift; uint32_t TPC; uint32_t ndi; uint32_t mcs; uint32_t rballoc,RIV_max; uint16_t* RIV2first_rb_LUT; uint16_t* RIV2nb_rb_LUT; // uint32_t hopping; // uint32_t type; if (dci_format == format0) { if (!ulsch) return -1; if (rnti == ra_rnti) harq_pid = 0; else harq_pid = nr_subframe2harq_pid(frame_parms, nr_pdcch_alloc2ul_frame(frame_parms,proc->frame_rx,nr_tti_rx), nr_pdcch_alloc2ul_subframe(frame_parms,nr_tti_rx)); if (harq_pid == 255) { LOG_E(PHY, "frame %d, nr_tti_rx %d, rnti %x, format %d: illegal harq_pid!\n", proc->frame_rx, nr_tti_rx, rnti, dci_format); return(-1); } switch (frame_parms->N_RB_DL) { case 6: if (frame_parms->frame_type == TDD) { cqi_req = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; dai = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; cshift = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift; TPC = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; ndi = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->ndi; mcs = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; // hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping; // type = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type; } else { cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req; cshift = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift; TPC = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC; ndi = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->ndi; mcs = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc; // hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping; // type = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type; } RIV_max = RIV_max6; RIV2first_rb_LUT = RIV2first_rb_LUT6; RIV2nb_rb_LUT = RIV2nb_rb_LUT6; break; case 25: if (frame_parms->frame_type == TDD) { cqi_req = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; dai = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai; cshift = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; TPC = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC; ndi = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->ndi; mcs = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; // hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping; // type = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type; } else { cqi_req = ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req; cshift = ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift; TPC = ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC; ndi = ((DCI0_5MHz_FDD_t *)dci_pdu)->ndi; mcs = ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc; // hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping; // type = ((DCI0_5MHz_FDD_t *)dci_pdu)->type; } RIV_max = RIV_max25; RIV2first_rb_LUT = RIV2first_rb_LUT25; RIV2nb_rb_LUT = RIV2nb_rb_LUT25; // printf("***********rballoc %d, first_rb %d, nb_rb %d (dci %p)\n",rballoc,ulsch->harq_processes[harq_pid]->first_rb,ulsch->harq_processes[harq_pid]->nb_rb,dci_pdu); break; case 50: if (frame_parms->frame_type == TDD) { cqi_req = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req; dai = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai; cshift = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift; TPC = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC; ndi = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->ndi; mcs = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc; // hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping; // type = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type; } else { cqi_req = ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req; cshift = ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift; TPC = ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC; ndi = ((DCI0_10MHz_FDD_t *)dci_pdu)->ndi; mcs = ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc; // hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping; // type = ((DCI0_10MHz_FDD_t *)dci_pdu)->type; } RIV_max = RIV_max50; RIV2first_rb_LUT = RIV2first_rb_LUT50; RIV2nb_rb_LUT = RIV2nb_rb_LUT50; break; case 100: if (frame_parms->frame_type == TDD) { cqi_req = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req; dai = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai; cshift = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift; TPC = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC; ndi = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->ndi; mcs = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc; // hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping; // type = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type; } else { cqi_req = ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req; cshift = ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift; TPC = ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC; ndi = ((DCI0_20MHz_FDD_t *)dci_pdu)->ndi; mcs = ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc; // hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping; // type = ((DCI0_20MHz_FDD_t *)dci_pdu)->type; } RIV_max = RIV_max100; RIV2first_rb_LUT = RIV2first_rb_LUT100; RIV2nb_rb_LUT = RIV2nb_rb_LUT100; // printf("rb_alloc (20 MHz dci) %d\n",rballoc); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } if (rballoc > RIV_max) { LOG_E(PHY,"frame %d, nr_tti_rx %d, rnti %x, format %d: FATAL ERROR: generate_ue_ulsch_params_from_dci, rb_alloc[%d] > RIV_max[%d]\n", proc->frame_rx, nr_tti_rx, rnti, dci_format,rballoc,RIV_max); LOG_E(PHY,"Wrong DCI0 detection, do not transmit PUSCH for HARQID: %d\n",harq_pid); ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0; return(-1); } // indicate that this process is to be serviced in subframe n+4 if ((rnti >= cba_rnti) && (rnti < p_rnti)) ulsch->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1; //+=1 this indicates the number of dci / cba group: not supported in the data struct else { ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; //LOG_I(PHY,"[HARQ-UL harqId: %d] DCI0 ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round); } ulsch->harq_processes[harq_pid]->TPC = TPC; ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT[rballoc]; ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT[rballoc]; if (ue->ul_power_control_dedicated[eNB_id].accumulationEnabled == 1) { LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d nr_tti_rx %d: f_pusch (ACC) %d, adjusting by %d (TPC %d)\n", ue->Mod_id,harq_pid,proc->frame_rx,nr_tti_rx,ulsch->f_pusch, nr_delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC], ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC); ulsch->f_pusch += nr_delta_PUSCH_acc[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC]; } else { LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d nr_tti_rx %d: f_pusch (ABS) %d, adjusting to %d (TPC %d)\n", ue->Mod_id,harq_pid,proc->frame_rx,nr_tti_rx,ulsch->f_pusch, nr_delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC], ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC); ulsch->f_pusch = nr_delta_PUSCH_abs[ue->ulsch[eNB_id]->harq_processes[harq_pid]->TPC]; } if (ulsch->harq_processes[harq_pid]->first_tx==1) { // ulsch->harq_processes[harq_pid]->Ndi = 1; ulsch->harq_processes[harq_pid]->first_tx=0; ulsch->harq_processes[harq_pid]->DCINdi= ndi; ulsch->harq_processes[harq_pid]->round = 0; } else { if (ulsch->harq_processes[harq_pid]->DCINdi!=ndi) { // new SDU opportunity // ulsch->harq_processes[harq_pid]->Ndi = 1; ulsch->harq_processes[harq_pid]->DCINdi= ndi; ulsch->harq_processes[harq_pid]->round = 0; } else { // ulsch->harq_processes[harq_pid]->Ndi = 0; //ulsch->harq_processes[harq_pid]->round++; // This is done in phich RX //#ifdef DEBUG_PHICH //LOG_I(PHY,"[UE %d][PUSCH %d] Frame %d subframe %d Adaptative Retrans, NDI not toggled => Nack. maxHARQ_Tx %d \n", // ue->Mod_id,harq_pid, // proc->frame_rx, // subframe, // ulsch->Mlimit); //#endif /* if (ulsch->harq_processes[harq_pid]->round > 0) // NACK detected on phich { // ulsch->harq_processes[harq_pid]->round++; already done on phich_rx // ulsch->harq_processes[harq_pid] = ulsch->harq_processes[8]; // LOG_I(PHY," Adaptative retransmission - copy temporary harq Process to current harq process. [harqId %d round %d] \n",harq_pid, ulsch->harq_processes[8]->round); if (ulsch->harq_processes[harq_pid]->round >= ulsch->Mlimit) //UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx) { ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 0; ulsch->harq_processes[harq_pid]->round = 0; ulsch->harq_processes[harq_pid]->status = IDLE; //LOG_I(PHY," PUSCH MAX Retransmission acheived ==> flush harq buff (%d) \n",harq_pid); //LOG_I(PHY," [HARQ-UL harqId: %d] Adaptative retransmission NACK MAX RETRANS(%d) ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, UE_mac_inst[eNB_id].scheduling_info.maxHARQ_Tx, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->harq_processes[harq_pid]->round); } else { // ulsch->harq_processes[harq_pid]->subframe_scheduling_flag = 1; uint8_t rv_table[4] = {0, 2, 3, 1}; ulsch->harq_processes[harq_pid]->rvidx = rv_table[ulsch->harq_processes[harq_pid]->round&3]; ulsch->O_RI = 0; ulsch->O = 0; ulsch->uci_format = HLC_subband_cqi_nopmi; //LOG_I(PHY," [HARQ-UL harqId: %d] Adaptative retransmission NACK ==> subframe_scheduling_flag = %d round: %d\n", harq_pid, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag,ulsch->harq_processes[harq_pid]->round); } } */ } } ulsch->harq_processes[harq_pid]->n_DMRS = cshift; //printf("nb_rb %d, first_rb %d (RIV %d)\n",ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb,rballoc); if ((rnti >= cba_rnti) && (rnti < p_rnti)) { // ulsch->cba_rnti[0]=rnti; } else { ulsch->rnti = rnti; } // printf("[PHY][UE] DCI format 0: harq_pid %d nb_rb %d, rballoc %d\n",harq_pid,ulsch->harq_processes[harq_pid]->nb_rb, // ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc); //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1) if(cshift == 0) ulsch->harq_processes[harq_pid]->n_DMRS2 = 0; else if(cshift == 1) ulsch->harq_processes[harq_pid]->n_DMRS2 = 6; else if(cshift == 2) ulsch->harq_processes[harq_pid]->n_DMRS2 = 3; else if(cshift == 3) ulsch->harq_processes[harq_pid]->n_DMRS2 = 4; else if(cshift == 4) ulsch->harq_processes[harq_pid]->n_DMRS2 = 2; else if(cshift == 5) ulsch->harq_processes[harq_pid]->n_DMRS2 = 8; else if(cshift == 6) ulsch->harq_processes[harq_pid]->n_DMRS2 = 10; else if(cshift == 7) ulsch->harq_processes[harq_pid]->n_DMRS2 = 9; //reserved for cooperative communication /* if(ulsch->n_DMRS2 == 6) ulsch->cooperation_flag = 2; else ulsch->cooperation_flag = 0; */ if ((ulsch->harq_processes[harq_pid]->nb_rb>0) && (ulsch->harq_processes[harq_pid]->nb_rb < 25)) ulsch->power_offset = ue_power_offsets[ulsch->harq_processes[harq_pid]->nb_rb-1]; // if (ulsch->harq_processes[harq_pid]->Ndi == 1) // ulsch->harq_processes[harq_pid]->status = ACTIVE; if (cqi_req == 1) { if( (AntennaInfoDedicated__transmissionMode_tm3 == transmission_mode) || (AntennaInfoDedicated__transmissionMode_tm4 == transmission_mode) ) { ulsch->O_RI = 1; } else { ulsch->O_RI = 0; } //ulsch->O_RI = 0; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table switch(transmission_mode) { // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling case 1: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_mcs_CBA; ulsch->o_RI[0] = 0; } else if(meas->rank[eNB_id] == 0) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_nopmi; ulsch->o_RI[0] = 0; } else { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_nopmi; ulsch->o_RI[0] = 1; } break; case 2: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_mcs_CBA; ulsch->o_RI[0] = 0; } else if(meas->rank[eNB_id] == 0) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_nopmi; ulsch->o_RI[0] = 0; } else { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_nopmi; ulsch->o_RI[0] = 1; } break; case 3: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_mcs_CBA; ulsch->o_RI[0] = 0; } else if(meas->rank[eNB_id] == 0) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_nopmi; ulsch->o_RI[0] = 0; } else { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_nopmi; ulsch->o_RI[0] = 1; } break; case 4: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_mcs_CBA; ulsch->o_RI[0] = 0; } else if(meas->rank[eNB_id] == 0) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; break; case 25: ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; break; case 50: ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; break; case 100: ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; break; } ulsch->uci_format = wideband_cqi_rank1_2A; ulsch->o_RI[0] = 0; } else { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; break; case 25: ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; break; case 50: ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; break; case 100: ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; break; } ulsch->uci_format = wideband_cqi_rank2_2A; ulsch->o_RI[0] = 1; } break; case 5: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_mcs_CBA; ulsch->o_RI[0] = 0; } else if(meas->rank[eNB_id] == 0) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; break; case 25: ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; break; case 50: ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; break; case 100: ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; break; } ulsch->uci_format = wideband_cqi_rank1_2A; ulsch->o_RI[0] = 0; } else { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; break; case 25: ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; break; case 50: ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; break; case 100: ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; break; } ulsch->uci_format = wideband_cqi_rank2_2A; ulsch->o_RI[0] = 1; } break; case 6: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_mcs_CBA; ulsch->o_RI[0] = 0; } else if(meas->rank[eNB_id] == 0) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_wideband_cqi_rank1_2A_1_5MHz; break; case 25: ulsch->O = sizeof_wideband_cqi_rank1_2A_5MHz; break; case 50: ulsch->O = sizeof_wideband_cqi_rank1_2A_10MHz; break; case 100: ulsch->O = sizeof_wideband_cqi_rank1_2A_20MHz; break; } ulsch->uci_format = wideband_cqi_rank1_2A; ulsch->o_RI[0] = 0; } else { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_wideband_cqi_rank2_2A_1_5MHz; break; case 25: ulsch->O = sizeof_wideband_cqi_rank2_2A_5MHz; break; case 50: ulsch->O = sizeof_wideband_cqi_rank2_2A_10MHz; break; case 100: ulsch->O = sizeof_wideband_cqi_rank2_2A_20MHz; break; } ulsch->uci_format = wideband_cqi_rank2_2A; ulsch->o_RI[0] = 1; } break; case 7: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_mcs_CBA; ulsch->o_RI[0] = 0; } else if(meas->rank[eNB_id] == 0) { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_nopmi; ulsch->o_RI[0] = 0; } else { switch (ue->frame_parms.N_RB_DL) { case 6: ulsch->O = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->O = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->O = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->O = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->uci_format = HLC_subband_cqi_nopmi; ulsch->o_RI[0] = 1; } break; default: LOG_E(PHY,"Incorrect Transmission Mode \n"); break; } } else { ulsch->O_RI = 0; ulsch->O = 0; ulsch->uci_format = HLC_subband_cqi_nopmi; } print_CQI(ulsch->o,ulsch->uci_format,eNB_id,ue->frame_parms.N_RB_DL); ulsch->bundling = 1-AckNackFBMode; if (frame_parms->frame_type == FDD) { //int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); int dl_tti = nr_tti_rx; if (ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id][0]->harq_ack[dl_tti].send_harq_status>0) { // we have downlink transmission ulsch->harq_processes[harq_pid]->O_ACK = 1; } else { ulsch->harq_processes[harq_pid]->O_ACK = 0; } /*LOG_I(PHY,"DCI 0 Processing: dl_subframe %d send_harq_status Odd %d send_harq_status Even %d harq_pid %d O_ACK %d\n", dl_subframe, ue->dlsch[0][eNB_id][0]->harq_ack[dl_subframe].send_harq_status, ue->dlsch[1][eNB_id][0]->harq_ack[dl_subframe].send_harq_status, harq_pid, ulsch->harq_processes[harq_pid]->O_ACK);*/ } else { if (ulsch->bundling) ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1; else ulsch->harq_processes[harq_pid]->O_ACK = (dai >= 2)? 2 : (dai+1)&3; //(dai+1)&3; // ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1; } dlsch[0]->harq_ack[nr_tti_rx].vDAI_UL = dai+1; /*LOG_I(PHY, "[PUSCH %d] Format0 DCI %s, CQI_req=%d, cshift=%d, TPC=%d, DAI=%d, vDAI_UL[sf#%d]=%d, NDI=%d, MCS=%d, RBalloc=%d, first_rb=%d, harq_pid=%d, nb_rb=%d, subframe_scheduling_flag=%d" " ulsch->bundling %d, O_ACK %d \n", harq_pid, (frame_parms->frame_type == TDD? "TDD" : "FDD"), cqi_req, cshift, TPC, dai, subframe, dlsch[0]->harq_ack[subframe].vDAI_UL, ndi, mcs, rballoc, ulsch->harq_processes[harq_pid]->first_rb, harq_pid, ulsch->harq_processes[harq_pid]->nb_rb, ulsch->harq_processes[harq_pid]->subframe_scheduling_flag, ulsch->bundling, ulsch->harq_processes[harq_pid]->O_ACK);*/ ulsch->beta_offset_cqi_times8 = beta_cqi[ue->pusch_config_dedicated[eNB_id].betaOffset_CQI_Index];//18; ulsch->beta_offset_ri_times8 = beta_ri[ue->pusch_config_dedicated[eNB_id].betaOffset_RI_Index];//10; ulsch->beta_offset_harqack_times8 = beta_ack[ue->pusch_config_dedicated[eNB_id].betaOffset_ACK_Index];//16; ulsch->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); ulsch->srs_active = use_srs; if ((rnti >= cba_rnti) && (rnti < p_rnti)) ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE; else ulsch->harq_processes[harq_pid]->status = ACTIVE; ulsch->harq_processes[harq_pid]->rvidx = 0; // ulsch->harq_processes[harq_pid]->calibration_flag =0; if (mcs < 29) { ulsch->harq_processes[harq_pid]->mcs = mcs; // ulsch->harq_processes[harq_pid]->round = 0; } else { ulsch->harq_processes[harq_pid]->rvidx = mcs - 28; if (ulsch->harq_processes[harq_pid]->round == 0) { LOG_W(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round); } else { LOG_D(PHY,"PUSCH::mcs = %d and DCI0::mcs(%d) > 28 and round == %d\n", ulsch->harq_processes[harq_pid]->mcs, mcs, ulsch->harq_processes[harq_pid]->round); } //LOG_E(PHY,"Fatal: mcs(%d) > 28!!! and round == 0\n", mcs); } ulsch->harq_processes[harq_pid]->TBS = TBStableUL[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; /* else if (ulsch->harq_processes[harq_pid]->mcs == 29) { ulsch->harq_processes[harq_pid]->mcs = 4; ulsch->harq_processes[harq_pid]->TBS = TBStable[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; // ulsch->harq_processes[harq_pid]->calibration_flag =1; // printf("Auto-Calibration (UE): mcs %d, TBS %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->TBS,ulsch->harq_processes[harq_pid]->nb_rb); }*/ ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch->harq_processes[harq_pid]->nb_rb; ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->Nsymb_pusch; // a Ndi=1 automatically acknowledges previous PUSCH transmission if (ue->ulsch_Msg3_active[eNB_id] == 1) ue->ulsch_Msg3_active[eNB_id] = 0; LOG_D(PHY,"[UE %d][PUSCH %d] Frame %d, nr_tti_rx %d : Programming PUSCH with n_DMRS2 %d (cshift %d), nb_rb %d, first_rb %d, mcs %d, round %d, rv %d, ulsch_ue_Msg3_active %d\n", ue->Mod_id,harq_pid, proc->frame_rx,nr_tti_rx,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift,ulsch->harq_processes[harq_pid]->nb_rb,ulsch->harq_processes[harq_pid]->first_rb, ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->rvidx, ue->ulsch_Msg3_active[eNB_id]); // ulsch->n_DMRS2 = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; //printf("Format 0 DCI : ulsch (ue): AbsSubframe %d.%d nrb %d harq_pid %d round %d mcs %d\n",proc->frame_rx%1024,nr_tti_rx,ulsch->harq_processes[harq_pid]->nb_rb, // harq_pid,ulsch->harq_processes[harq_pid]->round,ulsch->harq_processes[harq_pid]->mcs); #ifdef UE_DEBUG_TRACE LOG_I(PHY,"Format 0 DCI : ulsch (ue): AbsSubframe %d.%d\n",proc->frame_rx%1024,nr_tti_rx); LOG_D(PHY,"Format 0 DCI : ulsch (ue): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_rb %d\n",ulsch->harq_processes[harq_pid]->first_rb); LOG_D(PHY,"Format 0 DCI :ulsch (ue): rballoc %d\n",rballoc); LOG_D(PHY,"Format 0 DCI :ulsch (ue): harq_pid %d\n",harq_pid); LOG_D(PHY,"Format 0 DCI :ulsch (ue): first_tx %d\n",ulsch->harq_processes[harq_pid]->first_tx); LOG_D(PHY,"Format 0 DCI :ulsch (ue): DCINdi %d\n",ulsch->harq_processes[harq_pid]->DCINdi); LOG_D(PHY,"Format 0 DCI :ulsch (ue): round %d\n",ulsch->harq_processes[harq_pid]->round); //LOG_I(PHY,"Format 0 DCI :ulsch (ue): TBS %d\n",ulsch->harq_processes[harq_pid]->TBS); LOG_D(PHY,"Format 0 DCI :ulsch (ue): mcs %d\n",ulsch->harq_processes[harq_pid]->mcs); //LOG_I(PHY,"Format 0 DCI :ulsch (ue): O %d\n",ulsch->O); //LOG_I(PHY,"Format 0 DCI :ulsch (ue): cqiReq %d\n",cqi_req); //if (frame_parms->frame_type == TDD) // LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK/DAI %d/%d\n",ulsch->harq_processes[harq_pid]->O_ACK,dai); //else // LOG_I(PHY,"Format 0 DCI :ulsch (ue): O_ACK %d\n",ulsch->harq_processes[harq_pid]->O_ACK); LOG_D(PHY,"Format 0 DCI :ulsch (ue): Nsymb_pusch %d\n",ulsch->Nsymb_pusch); LOG_D(PHY,"Format 0 DCI :ulsch (ue): cshift %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2); LOG_D(PHY,"Format 0 DCI :ulsch (ue): phich status %d\n",ulsch->harq_processes[harq_pid]->status); #else UNUSED_VARIABLE(dai); #endif return(0); } else { LOG_E(PHY,"frame %d, nr_tti_rx %d: FATAL ERROR, generate_ue_ulsch_params_from_dci, Illegal dci_format %d\n", proc->frame_rx, nr_tti_rx,dci_format); return(-1); } } int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, void *dci_pdu, uint16_t rnti, DCI_format_t dci_format, uint8_t UE_id, uint16_t si_rnti, uint16_t ra_rnti, uint16_t p_rnti, uint16_t cba_rnti, uint8_t use_srs) { uint8_t harq_pid; uint32_t rb_alloc; uint8_t transmission_mode=eNB->transmission_mode[UE_id]; ANFBmode_t AckNackFBMode = eNB->pucch_config_dedicated[UE_id].tdd_AckNackFeedbackMode; LTE_eNB_ULSCH_t *ulsch=eNB->ulsch[UE_id]; NR_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; int subframe = proc->subframe_tx; uint32_t cqi_req = 0; uint32_t dai = 0; uint32_t cshift = 0; uint32_t TPC = 0; uint32_t mcs = 0; uint32_t rballoc = UINT32_MAX; uint32_t RIV_max = 0; // uint32_t hopping; // uint32_t type; #ifdef DEBUG_DCI printf("filling eNB ulsch params for rnti %x, dci format %d, dci %x, subframe %d\n", rnti,dci_format,*(uint32_t*)dci_pdu,subframe); #endif if (dci_format == format0) { harq_pid = nr_subframe2harq_pid(frame_parms, nr_pdcch_alloc2ul_frame(frame_parms, proc->frame_tx, subframe), nr_pdcch_alloc2ul_subframe(frame_parms,subframe)); switch (frame_parms->N_RB_DL) { case 6: if (frame_parms->frame_type == TDD) { cqi_req = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; dai = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->dai; cshift = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->cshift; TPC = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->TPC; mcs = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; // hopping = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->hopping; // type = ((DCI0_1_5MHz_TDD_1_6_t *)dci_pdu)->type; } else { cqi_req = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cqi_req; cshift = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->cshift; TPC = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->TPC; mcs = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->rballoc; // hopping = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->hopping; // type = ((DCI0_1_5MHz_FDD_t *)dci_pdu)->type; } RIV_max = RIV_max6; ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT6[rballoc]; ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT6[rballoc]; break; case 25: if (frame_parms->frame_type == TDD) { cqi_req = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cqi_req; dai = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->dai; cshift = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->cshift; TPC = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->TPC; mcs = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->rballoc; // hopping = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->hopping; // type = ((DCI0_5MHz_TDD_1_6_t *)dci_pdu)->type; } else { cqi_req = ((DCI0_5MHz_FDD_t *)dci_pdu)->cqi_req; cshift = ((DCI0_5MHz_FDD_t *)dci_pdu)->cshift; TPC = ((DCI0_5MHz_FDD_t *)dci_pdu)->TPC; mcs = ((DCI0_5MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI0_5MHz_FDD_t *)dci_pdu)->rballoc; // hopping = ((DCI0_5MHz_FDD_t *)dci_pdu)->hopping; // type = ((DCI0_5MHz_FDD_t *)dci_pdu)->type; } RIV_max = RIV_max25; ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT25[rballoc]; ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT25[rballoc]; break; case 50: if (frame_parms->frame_type == TDD) { cqi_req = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cqi_req; dai = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->dai; cshift = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->cshift; TPC = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->TPC; mcs = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->rballoc; // hopping = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->hopping; // type = ((DCI0_10MHz_TDD_1_6_t *)dci_pdu)->type; } else { cqi_req = ((DCI0_10MHz_FDD_t *)dci_pdu)->cqi_req; cshift = ((DCI0_10MHz_FDD_t *)dci_pdu)->cshift; TPC = ((DCI0_10MHz_FDD_t *)dci_pdu)->TPC; mcs = ((DCI0_10MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI0_10MHz_FDD_t *)dci_pdu)->rballoc; // hopping = ((DCI0_10MHz_FDD_t *)dci_pdu)->hopping; // type = ((DCI0_10MHz_FDD_t *)dci_pdu)->type; } RIV_max = RIV_max50; ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT50[rballoc]; ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT50[rballoc]; break; case 100: if (frame_parms->frame_type == TDD) { cqi_req = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cqi_req; dai = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->dai; cshift = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->cshift; TPC = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->TPC; mcs = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->mcs; rballoc = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->rballoc; // hopping = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->hopping; // type = ((DCI0_20MHz_TDD_1_6_t *)dci_pdu)->type; } else { cqi_req = ((DCI0_20MHz_FDD_t *)dci_pdu)->cqi_req; cshift = ((DCI0_20MHz_FDD_t *)dci_pdu)->cshift; TPC = ((DCI0_20MHz_FDD_t *)dci_pdu)->TPC; mcs = ((DCI0_20MHz_FDD_t *)dci_pdu)->mcs; rballoc = ((DCI0_20MHz_FDD_t *)dci_pdu)->rballoc; // hopping = ((DCI0_20MHz_FDD_t *)dci_pdu)->hopping; // type = ((DCI0_20MHz_FDD_t *)dci_pdu)->type; } RIV_max = RIV_max100; ulsch->harq_processes[harq_pid]->first_rb = RIV2first_rb_LUT100[rballoc]; ulsch->harq_processes[harq_pid]->nb_rb = RIV2nb_rb_LUT100[rballoc]; //printf("eNB: rb_alloc (20 MHz dci) %d\n",rballoc); break; default: LOG_E(PHY,"Invalid N_RB_DL %d\n", frame_parms->N_RB_DL); DevParam (frame_parms->N_RB_DL, 0, 0); break; } rb_alloc = rballoc; if (rb_alloc>RIV_max) { LOG_E(PHY,"Format 0: rb_alloc (%d) > RIV_max (%d)\n",rb_alloc,RIV_max); mac_xface->macphy_exit("Format 0: error"); return(-1); } #ifdef DEBUG_DCI printf("generate_eNB_ulsch_params_from_dci: subframe %d, rnti %x,harq_pid %d,cqi_req %d\n",subframe,rnti,harq_pid,cqi_req); #endif ulsch->harq_processes[harq_pid]->dci_alloc = 1; ulsch->harq_processes[harq_pid]->rar_alloc = 0; ulsch->harq_processes[harq_pid]->TPC = TPC; ulsch->harq_processes[harq_pid]->n_DMRS = cshift; if (cqi_req == 1) { /* 36.213 7.2.1 (release 10) says: * "RI is only reported for transmission modes 3 and 4, * as well as transmission modes 8 and 9 with PMI/RI reporting" * This is for aperiodic reporting. * TODO: deal with TM 8&9 correctly when they are implemented. * TODO: deal with periodic reporting if we implement it. */ if (transmission_mode == 3 || transmission_mode == 4) ulsch->harq_processes[harq_pid]->O_RI = 1; //we only support 2 antenna ports, so this is always 1 according to 3GPP 36.213 Table else ulsch->harq_processes[harq_pid]->O_RI = 0; switch(transmission_mode) { // The aperiodic CQI reporting mode is fixed for every transmission mode instead of being configured by higher layer signaling case 1: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { ulsch->harq_processes[harq_pid]->Or2 = 0; switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; } else { ulsch->harq_processes[harq_pid]->Or2 = 0; switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; } break; case 2: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { ulsch->harq_processes[harq_pid]->Or2 = 0; switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; } else { ulsch->harq_processes[harq_pid]->Or2 = 0; switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; } break; case 3: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { ulsch->harq_processes[harq_pid]->Or2 = 0; switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; } else { ulsch->harq_processes[harq_pid]->Or2 = 0; switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; } break; case 4: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { ulsch->harq_processes[harq_pid]->Or2 = 0; switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; } else { switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_1_5MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_5MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_10MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_20MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = wideband_cqi_rank1_2A; } break; case 5: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { ulsch->harq_processes[harq_pid]->Or2 = 0; switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; } else { switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_1_5MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_5MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_10MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_20MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = wideband_cqi_rank1_2A; } break; case 6: if ((rnti >= cba_rnti) && (rnti < p_rnti)) { ulsch->harq_processes[harq_pid]->Or2 = 0; switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_mcs_CBA_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_mcs_CBA; } else { switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_1_5MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_5MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_10MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or2 = sizeof_wideband_cqi_rank2_2A_20MHz; ulsch->harq_processes[harq_pid]->Or1 = sizeof_wideband_cqi_rank1_2A_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = wideband_cqi_rank1_2A; } break; case 7: ulsch->harq_processes[harq_pid]->Or2 = 0; switch (frame_parms->N_RB_DL) { case 6: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_1_5MHz; break; case 25: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_5MHz; break; case 50: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_10MHz; break; case 100: ulsch->harq_processes[harq_pid]->Or1 = sizeof_HLC_subband_cqi_nopmi_20MHz; break; } ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; break; default: LOG_E(PHY,"Incorrect Transmission Mode \n"); break; } } else { ulsch->harq_processes[harq_pid]->O_RI = 0; ulsch->harq_processes[harq_pid]->Or2 = 0; ulsch->harq_processes[harq_pid]->Or1 = 0; ulsch->harq_processes[harq_pid]->uci_format = HLC_subband_cqi_nopmi; } ulsch->bundling = 1-AckNackFBMode; if (frame_parms->frame_type == FDD) { int dl_subframe = (subframe<4) ? (subframe+6) : (subframe-4); if (eNB->dlsch[UE_id][0]->subframe_tx[dl_subframe]>0) { // we have downlink transmission ulsch->harq_processes[harq_pid]->O_ACK = 1; } else { ulsch->harq_processes[harq_pid]->O_ACK = 0; } } else { if (ulsch->bundling) ulsch->harq_processes[harq_pid]->O_ACK = (dai == 3)? 0 : 1; else ulsch->harq_processes[harq_pid]->O_ACK = (dai+1)&3; ulsch->harq_processes[harq_pid]->V_UL_DAI = dai+1; } ulsch->beta_offset_cqi_times8 = beta_cqi[eNB->pusch_config_dedicated[UE_id].betaOffset_CQI_Index];//18; ulsch->beta_offset_ri_times8 = beta_ri[eNB->pusch_config_dedicated[UE_id].betaOffset_RI_Index];//10; ulsch->beta_offset_harqack_times8 = beta_ack[eNB->pusch_config_dedicated[UE_id].betaOffset_ACK_Index];//16; ulsch->harq_processes[harq_pid]->Nsymb_pusch = 12-(frame_parms->Ncp<<1)-(use_srs==0?0:1); ulsch->harq_processes[harq_pid]->srs_active = use_srs; //Mapping of cyclic shift field in DCI format0 to n_DMRS2 (3GPP 36.211, Table 5.5.2.1.1-1) if(cshift == 0) ulsch->harq_processes[harq_pid]->n_DMRS2 = 0; else if(cshift == 1) ulsch->harq_processes[harq_pid]->n_DMRS2 = 6; else if(cshift == 2) ulsch->harq_processes[harq_pid]->n_DMRS2 = 3; else if(cshift == 3) ulsch->harq_processes[harq_pid]->n_DMRS2 = 4; else if(cshift == 4) ulsch->harq_processes[harq_pid]->n_DMRS2 = 2; else if(cshift == 5) ulsch->harq_processes[harq_pid]->n_DMRS2 = 8; else if(cshift == 6) ulsch->harq_processes[harq_pid]->n_DMRS2 = 10; else if(cshift == 7) ulsch->harq_processes[harq_pid]->n_DMRS2 = 9; LOG_D(PHY,"[eNB %d][PUSCH %d] Frame %d, subframe %d : Programming PUSCH with n_DMRS2 %d (cshift %d)\n", eNB->Mod_id,harq_pid,proc->frame_tx,subframe,ulsch->harq_processes[harq_pid]->n_DMRS2,cshift); if (ulsch->harq_processes[harq_pid]->round == 0) { if ((rnti >= cba_rnti) && (rnti < p_rnti)) ulsch->harq_processes[harq_pid]->status = CBA_ACTIVE; else ulsch->harq_processes[harq_pid]->status = ACTIVE; ulsch->harq_processes[harq_pid]->rvidx = 0; ulsch->harq_processes[harq_pid]->mcs = mcs; // ulsch->harq_processes[harq_pid]->calibration_flag = 0; //if (ulsch->harq_processes[harq_pid]->mcs) /* if (ulsch->harq_processes[harq_pid]->mcs == 29) { ulsch->harq_processes[harq_pid]->mcs = 4; // ulsch->harq_processes[harq_pid]->calibration_flag = 1; // printf("Auto-Calibration (eNB): mcs %d, nb_rb %d\n",ulsch->harq_processes[harq_pid]->mcs,ulsch->harq_processes[harq_pid]->nb_rb); } */ ulsch->harq_processes[harq_pid]->TBS = TBStableUL[get_I_TBS_UL(ulsch->harq_processes[harq_pid]->mcs)][ulsch->harq_processes[harq_pid]->nb_rb-1]; ulsch->harq_processes[harq_pid]->Msc_initial = 12*ulsch->harq_processes[harq_pid]->nb_rb; ulsch->harq_processes[harq_pid]->Nsymb_initial = ulsch->harq_processes[harq_pid]->Nsymb_pusch; ulsch->harq_processes[harq_pid]->round = 0; } else { if (mcs>28) ulsch->harq_processes[harq_pid]->rvidx = mcs - 28; else { ulsch->harq_processes[harq_pid]->rvidx = 0; ulsch->harq_processes[harq_pid]->mcs = mcs; } // ulsch->harq_processes[harq_pid]->round++; } if ((rnti >= cba_rnti) && (rnti < p_rnti)) { ulsch->cba_rnti[0] = rnti; } else { ulsch->rnti = rnti; } //ulsch->n_DMRS2 = cshift; #ifdef DEBUG_DCI printf("ulsch (eNB): NBRB %d\n",ulsch->harq_processes[harq_pid]->nb_rb); printf("ulsch (eNB): first_rb %d\n",ulsch->harq_processes[harq_pid]->first_rb); printf("ulsch (eNB): harq_pid %d\n",harq_pid); printf("ulsch (eNB): round %d\n",ulsch->harq_processes[harq_pid]->round); printf("ulsch (eNB): TBS %d\n",ulsch->harq_processes[harq_pid]->TBS); printf("ulsch (eNB): mcs %d\n",ulsch->harq_processes[harq_pid]->mcs); printf("ulsch (eNB): Or1 %d\n",ulsch->harq_processes[harq_pid]->Or1); printf("ulsch (eNB): Nsymb_pusch %d\n",ulsch->harq_processes[harq_pid]->Nsymb_pusch); printf("ulsch (eNB): cshift %d\n",ulsch->harq_processes[harq_pid]->n_DMRS2); #else UNUSED_VARIABLE(dai); #endif return(0); } else { LOG_E(PHY,"generate_eNB_ulsch_params_from_dci, Illegal dci_format %d\n",dci_format); return(-1); } } double sinr_eff_cqi_calc(PHY_VARS_NR_UE *ue, uint8_t eNB_id, uint8_t nr_tti_rx) { uint8_t transmission_mode = ue->transmission_mode[eNB_id]; PHY_MEASUREMENTS *meas = &ue->measurements; NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; int32_t **dl_channel_est = ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[nr_tti_rx]].dl_ch_estimates[eNB_id]; double *s_dB; s_dB = ue->sinr_CQI_dB; // NR_UE_ULSCH_t *ulsch = ue->ulsch[eNB_id]; //for the calculation of SINR_eff for CQI calculation int count,a_rx,a_tx; double abs_channel=0; double channelx=0; double channely=0; double channelx_i=0; double channely_i=0; uint16_t q = quantize_subband_pmi(meas,eNB_id,7); uint8_t qq; switch(transmission_mode) { case 1: for (count=0; count<frame_parms->N_RB_DL*12; count++) { for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { s_dB[count] = 10*log10(pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2], 2)) - meas->n0_power_avg_dB; } } } break; case 2: for (count=0; count<frame_parms->N_RB_DL*12; count++) { abs_channel=0; for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { abs_channel += (pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2],2) + pow(((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2],2)); } } s_dB[count] = 10*log10(abs_channel/2) - meas->n0_power_avg_dB; } break; case 5: for (count=0; count<frame_parms->N_RB_DL*12; count++) { channelx=0; channely=0; channelx_i=0; channely_i=0; qq = (q>>(((count/12)>>2)<<1))&3; //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq); for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { switch(qq) { case 0: if (channelx==0 || channely==0) { channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } else { channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channelx_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } break; case 1: if (channelx==0 || channely==0) { channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } else { channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channelx_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } break; case 2: if (channelx==0 || channely==0) { channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } else { channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channelx_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channely_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; } break; case 3: if (channelx==0 || channely==0) { channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channelx_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely_i = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } else { channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channelx_i -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channely_i += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; } break; default: printf("Problem in SINR Calculation for TM5 \n"); break; }//switch(qq) }//a_rx }//a_tx s_dB[count] = 10 * log10 ((pow(channelx,2) + pow(channely,2))/2) - 10 * log10 ((pow(channelx_i,2) + pow(channely_i,2))/2) - meas->n0_power_avg_dB; }//count break; case 6: for (count=0; count<frame_parms->N_RB_DL*12; count++) { channelx=0; channely=0; qq = (q>>(((count/12)>>2)<<1))&3; //printf("pmi_alloc %d: rb %d, pmi %d\n",q,count/12,qq); for(a_tx=0; a_tx<frame_parms->nb_antenna_ports_eNB; a_tx++) { for (a_rx=0; a_rx<frame_parms->nb_antennas_rx; a_rx++) { switch(qq) { case 0: if (channelx==0 || channely==0) { channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } else { channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } break; case 1: if (channelx==0 || channely==0) { channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } else { channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } break; case 2: if (channelx==0 || channely==0) { channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } else { channelx -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channely += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; } break; case 3: if (channelx==0 || channely==0) { channelx = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; channely = ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; } else { channelx += ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+1+(LTE_CE_FILTER_LENGTH)*2]; channely -= ((int16_t *) dl_channel_est[(a_tx<<1)+a_rx])[2*count+(LTE_CE_FILTER_LENGTH)*2]; } break; default: printf("Problem in SINR Calculation for TM6 \n"); break; }//switch(qq) }//a_rx }//a_tx s_dB[count] = 10 * log10 ((pow(channelx,2) + pow(channely,2))/2) - meas->n0_power_avg_dB; }//count break; default: printf("Problem in SINR Calculation for CQI \n"); break; } int ii; double sinr_eff = 0; double sinr_eff_qpsk=0; double sinr_eff_qam16=0; double sinr_eff_qam64=0; double x = 0; double I_qpsk=0; double I_qam16=0; double I_qam64=0; double I_qpsk_avg=0; double I_qam16_avg=0; double I_qam64_avg=0; double qpsk_max=12.2; double qam16_max=19.2; double qam64_max=25.2; double sinr_min = -20; int offset=0; for (offset = 0; offset <= 24; offset++) { for(ii=0; ii<12; ii++) { //x is the sinr_dB in dB x = s_dB[(offset*12)+ii]; if(x<sinr_min) { I_qpsk +=0; I_qam16 +=0; I_qam64 +=0; } else { if(x>qpsk_max) I_qpsk += 1; else I_qpsk += (q_qpsk[0]*pow(x,7) + q_qpsk[1]*pow(x,6) + q_qpsk[2]*pow(x,5) + q_qpsk[3]*pow(x,4) + q_qpsk[4]*pow(x,3) + q_qpsk[5]*pow(x,2) + q_qpsk[6]*x + q_qpsk[7]); if(x>qam16_max) I_qam16 += 1; else I_qam16 += (q_qam16[0]*pow(x,7) + q_qam16[1]*pow(x,6) + q_qam16[2]*pow(x,5) + q_qam16[3]*pow(x,4) + q_qam16[4]*pow(x,3) + q_qam16[5]*pow(x,2) + q_qam16[6]*x + q_qam16[7]); if(x>qam64_max) I_qam64 += 1; else I_qam64 += (q_qam64[0]*pow(x,7) + q_qam64[1]*pow(x,6) + q_qam64[2]*pow(x,5) + q_qam64[3]*pow(x,4) + q_qam64[4]*pow(x,3) + q_qam64[5]*pow(x,2) + q_qam64[6]*x + q_qam64[7]); } } } // averaging of accumulated MI I_qpsk_avg = I_qpsk/(12*frame_parms->N_RB_DL); I_qam16_avg = I_qam16/(12*frame_parms->N_RB_DL); I_qam64_avg = I_qam64/(12*frame_parms->N_RB_DL); // I->SINR_effective Mapping sinr_eff_qpsk = (p_qpsk[0]*pow(I_qpsk_avg,7) + p_qpsk[1]*pow(I_qpsk_avg,6) + p_qpsk[2]*pow(I_qpsk_avg,5) + p_qpsk[3]*pow(I_qpsk_avg,4) + p_qpsk[4]*pow(I_qpsk_avg,3) + p_qpsk[5]*pow(I_qpsk_avg, 2) + p_qpsk[6]*I_qpsk_avg + p_qpsk[7]); sinr_eff_qam16 = (p_qam16[0]*pow(I_qam16_avg,7) + p_qam16[1]*pow(I_qam16_avg,6) + p_qam16[2]*pow(I_qam16_avg,5) + p_qam16[3]*pow(I_qam16_avg,4) + p_qam16[4]*pow(I_qam16_avg, 3) + p_qam16[5]*pow(I_qam16_avg,2) + p_qam16[6]*I_qam16_avg + p_qam16[7]); sinr_eff_qam64 = (p_qam64[0]*pow(I_qam64_avg,7) + p_qam64[1]*pow(I_qam64_avg,6) + p_qam64[2]*pow(I_qam64_avg,5) + p_qam64[3]*pow(I_qam64_avg,4) + p_qam64[4]*pow(I_qam64_avg, 3) + p_qam64[5]*pow(I_qam64_avg,2) + p_qam64[6]*I_qam64_avg + p_qam64[7]); sinr_eff = cmax3(sinr_eff_qpsk,sinr_eff_qam16,sinr_eff_qam64); //printf("SINR_Eff = %e\n",sinr_eff); return(sinr_eff); } // #ifdef DEBUG_DLSCH_TOOLS main() { int i; uint8_t rah; uint32_t rballoc; generate_RIV_tables(); rah = 0; rballoc = 0x1fff; printf("rballoc 0 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); rah = 1; rballoc = 0x1678; printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); rballoc = 0xfffc; printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); rballoc = 0xfffd; printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); rballoc = 0xffff; printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); rballoc = 0xfffe; printf("rballoc 1 %x => %x\n",rballoc,conv_rballoc(rah,rballoc)); } #endif #endif //(0)