phy_procedures_lte_eNb_NB_IoT.c 64.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
21

22 23 24 25 26 27 28 29 30 31
/*! \file phy_procedures_lte_eNB.c
 * \brief Implementation of eNB procedures from 36.213 LTE specifications
 * \author R. Knopp, F. Kaltenberger, N. Nikaein, X. Foukas, Michele Paffetti, Nick Ho
 * \date 2011
 * \version 0.1
 * \company Eurecom
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr, x.foukas@sms.ed.ac.uk, michele.paffetti@studio.unibo.it, nick133371@gmail.com
 * \note
 * \warning
 */
32

33
#include "PHY/defs.h"
34
#include "PHY/defs_NB_IoT.h"
35
#include "PHY/LTE_ESTIMATION/defs_NB_IoT.h"
36
#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h"
37
#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h"
38
//#include "PHY/extern_NB_IoT.h" //where we get the global Sched_Rsp_t structure filled
39
//#include "SCHED/defs.h"
40 41 42
#include "SCHED/extern_NB_IoT.h"
//#include "PHY/LTE_TRANSPORT/if4_tools.h"
//#include "PHY/LTE_TRANSPORT/if5_tools.h"
43
#include "RRC/LITE/proto_NB_IoT.h"
44 45 46 47
#include "SIMULATION/TOOLS/defs.h"  // purpose: included for taus() function
//#ifdef EMOS
//#include "SCHED/phy_procedures_emos.h"
//#endif
48

49
// for NB-IoT
50
#include "SCHED/defs_NB_IoT.h"
51
#include "openair2/RRC/LITE/proto_NB_IoT.h"
52 53
#include "openair2/RRC/LITE/extern_NB_IoT.h"
#include "RRC/LITE/MESSAGES/asn1_msg_NB_IoT.h"
54 55 56
//#define DEBUG_PHY_PROC (Already defined in cmake)
//#define DEBUG_ULSCH

57 58
//#include "LAYER2/MAC/extern.h"
//#include "LAYER2/MAC/defs.h"
59 60 61 62 63 64 65
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"

#include "T.h"

#include "assertions.h"
#include "msc.h"
66

67 68 69 70 71 72
#include <time.h>

#if defined(ENABLE_ITTI)
#   include "intertask_interface.h"
#endif

73
/*
74 75 76 77 78 79 80

#if defined(FLEXRAN_AGENT_SB_IF)
//Agent-related headers
#include "ENB_APP/flexran_agent_extern.h"
#include "ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h"
#include "LAYER2/MAC/flexran_agent_mac_proto.h"
#endif
81
*/
82 83 84

//#define DIAG_PHY

85
///#define NS_PER_SLOT 500000
86

87
///#define PUCCH 1
88 89 90

//DCI_ALLOC_t dci_alloc[8];

91 92 93
///#ifdef EMOS
///fifo_dump_emos_eNB emos_dump_eNB;
///#endif
94

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
int npdsch_rep_to_array[3]      = {4,8,16}; //TS 36.213 Table 16.4.1.3-3
int sib1_startFrame_to_array[4] = {0,16,32,48};//TS 36.213 Table 16.4.1.3-4

//New----------------------------------------------------
//return -1 whenever no SIB1-NB transmission occur.
//return sib1_startFrame when transmission occur in the current frame
uint32_t is_SIB1_NB_IoT(const frame_t          frameP,
                        long                   schedulingInfoSIB1,   //from the mib
                        int                    physCellId,           //by configuration
                        NB_IoT_eNB_NDLSCH_t   *ndlsch_SIB1
                        )
{
  uint8_t    nb_rep=0; // number of sib1-nb repetitions within the 256 radio frames
  uint32_t   sib1_startFrame;
  uint32_t   sib1_period_NB_IoT = 256;//from specs TS 36.331 (rf)
  uint8_t    index;
  int        offset;
  int        period_nb; // the number of the actual period over the 1024 frames

        if(schedulingInfoSIB1 > 11 || schedulingInfoSIB1 < 0){
          LOG_E(RRC, "is_SIB1_NB_IoT: schedulingInfoSIB1 value not allowed");
          return 0;
        }


        //SIB1-NB period number
        period_nb = (int) frameP/sib1_period_NB_IoT;


        //number of repetitions
        nb_rep = npdsch_rep_to_array[schedulingInfoSIB1%3];

        //based on number of rep. and the physical cell id we derive the starting radio frame (TS 36.213 Table 16.4.1.3-3/4)
        switch(nb_rep)
        {
        case 4:
          //physCellId%4 possible value are 0,1,2,3
          sib1_startFrame = sib1_startFrame_to_array[physCellId%4];
          break;
        case 8:
          //physCellId%2possible value are 0,1
          sib1_startFrame = sib1_startFrame_to_array[physCellId%2];
          break;
        case 16:
          //physCellId%2 possible value are 0,1
          if(physCellId%2 == 0)
            sib1_startFrame = 0;
          else
            sib1_startFrame = 1; // the only case in which the starting frame is odd
          break;
        default:
          LOG_E(RRC, "Number of repetitions %d not allowed", nb_rep);
          return -1;
        }

        //check the actual frame w.r.t SIB1-NB starting frame
        if(frameP < sib1_startFrame + period_nb*256){
          LOG_T(RRC, "the actual frame %d is before the SIB1-NB starting frame %d of the period--> bcch_sdu_legnth = 0", frameP, sib1_startFrame + period_nb*256);
          return -1;
        }


        //calculate offset between SIB1-NB repetitions (repetitions are equally spaced)
        offset = (sib1_period_NB_IoT-(16*nb_rep))/nb_rep;

        //loop over the SIB1-NB period
        for( int i = 0; i < nb_rep; i++)
        {
          //find the correct sib1-nb repetition interval in which the actual frame is

          //this is the start frame of a repetition
          index = sib1_startFrame+ i*(16+offset) + period_nb*256;

          //the actual frame is in a gap between two consecutive repetitions
          if(frameP < index)
          {
              ndlsch_SIB1->sib1_rep_start      = 0;
              ndlsch_SIB1->relative_sib1_frame = 0;
                return -1;
          }
          //this is needed for ndlsch_procedure
          else if(frameP == index)
          {
            //the actual frame is the start of a new repetition (SIB1-NB should be retransmitted)
            ndlsch_SIB1->sib1_rep_start      = 1;
            ndlsch_SIB1->relative_sib1_frame = 1;
            return sib1_startFrame;
          }
          else
            ndlsch_SIB1->sib1_rep_start = 0;

          //check in the current SIB1_NB repetition
          if(frameP>= index && frameP <= (index+15))
          {
            //find if the actual frame is one of the "every other frame in 16 continuous frame" in which SIB1-NB is transmitted

            for(int y = 0; y < 16; y += 2) //every other frame (increment by 2)
            {
              if(frameP == index + y)
              {
                //this flag tell which is the number of the current frame w.r.t the 8th (over the continuous 16) in a repetition
                ndlsch_SIB1->relative_sib1_frame = y/2 + 1; //1st, 2nd, 3rd,...
                return sib1_startFrame;
              }
            }

            //if we are here means that the frame was inside the repetition interval but not considered for SIB1-NB transmission
            ndlsch_SIB1->relative_sib1_frame = 0;
            return -1;
         }

        }

        return -1;
}
210 211


212

213 214 215



216 217 218 219
/* For NB-IoT, we put NPBCH in later part, since it would be scheduled by MAC scheduler
* It generates NRS/NPSS/NSSS
*
*/
220
void common_signal_procedures_NB_IoT(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) 
221
{
222 223
  //LTE_DL_FRAME_PARMS   *fp       =  &eNB->frame_parms_NB_IoT;
  LTE_DL_FRAME_PARMS   *fp       =  &eNB->frame_parms;
224
  NB_IoT_eNB_NPBCH_t   *broadcast_str = &eNB->npbch;
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
225 226 227
  //NB_IoT_eNB_NDLSCH_t  *sib1          = &eNB->ndlsch_SIB;
  NB_IoT_DL_eNB_SIB_t  *sib1          = &eNB->ndlsch_SIB.content_sib1;
  NB_IoT_DL_eNB_SIB_t  *sib23          = &eNB->ndlsch_SIB.content_sib23;
228 229
  int                     **txdataF =  eNB->common_vars.txdataF[0];
  int                     subframe  =  proc->subframe_tx;
Matthieu Kanj's avatar
Matthieu Kanj committed
230
  uint32_t                frame     =  proc->frame_tx;
231
  //uint16_t                Ntti      =  10;                      //ntti = 10
Matthieu Kanj's avatar
Matthieu Kanj committed
232
  int                     RB_IoT_ID=22 ;                          // XXX should be initialized (RB reserved for NB-IoT, PRB index)
233
  int                     With_NSSS=0;                            // With_NSSS = 1; if the frame include a sub-Frame with NSSS signal
Matthieu Kanj's avatar
Matthieu Kanj committed
234 235 236 237 238 239 240 241 242 243 244 245 246 247

 
  uint32_t                hyper_frame=proc->HFN;
////////////////////////////////////////////////////////////////////////////////////
  rrc_eNB_carrier_data_NB_IoT_t *carrier = &eNB_rrc_inst_NB_IoT->carrier[0];
      if(frame%64==0 && subframe ==0)
      {//printf("dooooo MIB");

     
       do_MIB_NB_IoT(carrier,1,frame,hyper_frame);
       /* for(int i = 0; i<5;i++)
         printf("%02X ",eNB_rrc_inst_NB_IoT->carrier[0].MIB_NB_IoT[i]);
        printf("\n");*/
      }
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
248

249
     if(frame%64==1 && subframe ==0)
Matthieu Kanj's avatar
Matthieu Kanj committed
250
      {     
Matthieu Kanj's avatar
Matthieu Kanj committed
251
       do_SIB1_NB_IoT_x(0,0,carrier,208,92,1,3584,28,2,hyper_frame);
252
      }
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
253
      
Matthieu Kanj's avatar
Matthieu Kanj committed
254
/////////////////////////////////////////////////////////////////////////////////
255
  //uint8_t      *control_region_size = get_NB_IoT_SIB1_eutracontrolregionsize();
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
256
  //int           G=0;
Matthieu Kanj's avatar
Matthieu Kanj committed
257
  
258

259
 //NSSS only happened in the even frame
260 261 262 263 264 265 266 267
  if(frame%2==0)
    {
      With_NSSS = 1;
    }
  else
    {
      With_NSSS = 0;
    }
268
   
269
    
270 271
  if(subframe == 5)
    {
272

273
      generate_npss_NB_IoT(txdataF,
274 275 276
                           AMP,
                           fp,
                           3,
277
                           10,
278
                           RB_IoT_ID);
279 280
   }
   else if((subframe == 9)&&(With_NSSS == 1))
281
    {
282 283
    
      generate_sss_NB_IoT(txdataF,
284 285 286
                          AMP,
                          fp,
                          3,
287
                          18,
288 289 290 291
                          frame,
                          RB_IoT_ID);
    }

Matthieu Kanj's avatar
Matthieu Kanj committed
292 293
  uint8_t      *npbch_pdu =  get_NB_IoT_MIB();
  uint8_t      *sib1_pdu = get_NB_IoT_SIB1();
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
294
  uint8_t      *sib23_pdu = get_NB_IoT_SIB23();
Matthieu Kanj's avatar
Matthieu Kanj committed
295
   
296 297 298

    if(subframe == 0)
    {
Matthieu Kanj's avatar
Matthieu Kanj committed
299

300 301 302 303 304 305 306 307
      generate_npbch(broadcast_str,
                     txdataF,
                     AMP,
                     fp,
                     npbch_pdu,
                     frame%64,
                     RB_IoT_ID);
    }
Matthieu Kanj's avatar
Matthieu Kanj committed
308 309


310
      ///////////////////////////////////////////////////////// SIB1 ////////////////////////////////////
Matthieu Kanj's avatar
Matthieu Kanj committed
311
    if((subframe == 4)  && (frame%2==0) && (frame%32<16) )   ////if((subframe != 0)  && (subframe != 4) && (subframe != 9) ) 
312 313
    {
        if( frame%32 == 0 )
Matthieu Kanj's avatar
Matthieu Kanj committed
314
        {
315 316 317
            dlsch_encoding_NB_IoT(sib1_pdu,
                                  sib1,
                                  8,                      ///// number_of_subframes_required
Matthieu Kanj's avatar
Matthieu Kanj committed
318 319
                                  236,
                                  1);                   //////////// G*2
320 321
        
        
322
             dlsch_sib_scrambling_NB_IoT(fp,
323
                                         sib1,
324
                                         1888,
325
                                         frame,
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
326
                                         subframe*2);
327
        }
Matthieu Kanj's avatar
Matthieu Kanj committed
328

329 330 331 332 333 334
        dlsch_modulation_NB_IoT(txdataF,
                                AMP,
                                fp,
                                3,                          // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
                                sib1,
                                236,                       // number of bits per subframe
335 336
                               ((frame%32)/2),
                               4,       
337 338
                                RB_IoT_ID);
        
Matthieu Kanj's avatar
Matthieu Kanj committed
339
        }
340
        ///////////////////////////////////////////////////////// END ////////////////////////////////////////////////////////
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
341 342
        
  //////////////////////////////////////////////////// SIB23 ////////////////////////////////////////////////////////////////////////
Matthieu Kanj's avatar
Matthieu Kanj committed
343
  if( (subframe >0) && (subframe !=5) && (With_NSSS == 0) && (frame%2==1) && (frame%64<16) )   ////if((subframe != 0)  && (subframe != 4) && (subframe != 9) ) 
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
344 345 346 347 348 349
  {
        if( subframe == 1 )
        {
            dlsch_encoding_NB_IoT(sib23_pdu,
                                  sib23,
                                  8,                      ///// number_of_subframes_required
Matthieu Kanj's avatar
Matthieu Kanj committed
350 351
                                  236,
                                  2);                   //////////// G*2
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
        
        
            dlsch_sib_scrambling_NB_IoT(fp,                    // is called only in subframe 4
                                         sib23,
                                         1888,            //////   total_bits
                                         frame,
                                         subframe*2);
        }

        if( subframe < 5 )
        {

        dlsch_modulation_NB_IoT(txdataF,
                                AMP,
                                fp,
                                3,                          // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
                                sib23,
                                236,                       // number of bits per subframe
                               (subframe-1),///npdsch_data_subframe, data per subframe//subframe index of the data table of npdsch channel (G*Nsf) ((frame%32)/2),values are between 0..Nsf        
                                subframe,
                                RB_IoT_ID);
       } else {

         dlsch_modulation_NB_IoT(txdataF,
                                AMP,
                                fp,
                                3,                          // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
379
                                sib23,
Matthieu Kanj's avatar
SIB23  
Matthieu Kanj committed
380 381 382 383 384 385 386 387 388 389
                                236,                       // number of bits per subframe
                               (subframe-2),///npdsch_data_subframe, data per subframe//subframe index of the data table of npdsch channel (G*Nsf) ((frame%32)/2),values are between 0..Nsf        
                                subframe,
                                RB_IoT_ID);

       }
        
  }
  //////////////////////////////////////////////////// END ////////////////////////////////////////////////////////////////////////

Matthieu Kanj's avatar
Matthieu Kanj committed
390 391 392 393 394 395
 generate_pilots_NB_IoT(eNB,
                           txdataF,
                           AMP,
                           subframe,
                           RB_IoT_ID,
                           With_NSSS);
Matthieu Kanj's avatar
Matthieu Kanj committed
396

Matthieu Kanj's avatar
Matthieu Kanj committed
397 398 399 400 401 402 403 404 405 406
   if(frame==1023 && subframe==9)
  {
  //printf("%d",hyper_frame);
  if(proc->HFN==1023)
        {             
    proc->HFN=0;
  }else{ 
    proc->HFN++;
  }
  }
Matthieu Kanj's avatar
Matthieu Kanj committed
407

408
  
409 410
}

411
void phy_procedures_eNB_uespec_RX_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,eNB_rxtx_proc_t *proc,UL_IND_NB_IoT_t *UL_INFO)
412 413
{
  //RX processing for ue-specific resources (i
414

415
  uint32_t                  ret=0,i,j,k;
416
  uint32_t                  harq_pid;   // round;
417 418 419 420
  int                       sync_pos;
  uint16_t                  rnti=0;
  uint8_t                   access_mode;
  NB_IoT_DL_FRAME_PARMS     *fp=&eNB->frame_parms_NB_IoT;
421

422 423
  const int subframe    =   proc->subframe_rx;
  const int frame       =   proc->frame_rx;
424 425

  // add hyper subframe here
426 427 428
  
  /*NB-IoT IF module Common setting*/

429 430 431 432
  UL_INFO->module_id    = eNB->Mod_id;
  UL_INFO->CC_id        = eNB->CC_id;
  UL_INFO->frame        =  frame;
  UL_INFO->subframe     = subframe;
433 434 435 436

  T(T_ENB_PHY_UL_TICK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe));

  T(T_ENB_PHY_INPUT_SIGNAL, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(0),
437 438
    T_BUFFER(&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms_NB_IoT.samples_per_tti],
             eNB->frame_parms_NB_IoT.samples_per_tti * 4));
439 440 441 442

  //if ((fp->frame_type == TDD) && (subframe_select(fp,subframe)!=SF_UL)) return;

  //check if any RB using in this UL subframe
443 444 445 446
  eNB->rb_mask_ul[0] = 0;
  eNB->rb_mask_ul[1] = 0;
  eNB->rb_mask_ul[2] = 0;
  eNB->rb_mask_ul[3] = 0;
447 448 449

  // Check for active processes in current subframe
  // NB-IoT subframe2harq_pid is in dci_tools, always set the frame type to FDD, this would become simpler.
450
  harq_pid = subframe2harq_pid_NB_IoT(fp,frame,subframe);
451 452 453
  // delete the cba
  // delete the srs
  /*Loop over the UE, i is the UE ID */
454
  for (i=0; i<NUMBER_OF_UE_MAX_NB_IoT; i++) 
455
    {
456

457 458 459 460 461
      // delete srs 
      // delete Pucch procedure
      // check for Msg3
      if (eNB->mac_enabled==1) 
        {
462
          if (eNB->UE_stats[i].mode == RA_RESPONSE_NB_IoT) 
463
            {
464
               /*Process Msg3 TODO*/
465 466 467
              //process_Msg3(eNB,proc,i,harq_pid);
            }
        }
468

469
      eNB->pusch_stats_rb[i][(frame*10)+subframe]    = -63;
470
      eNB->pusch_stats_round[i][(frame*10)+subframe] = 0;
471
      eNB->pusch_stats_mcs[i][(frame*10)+subframe]   = -63;
472

473
      /*Check if this UE is has ULSCH scheduling*/
474 475 476
      if ((eNB->nulsch[i]) &&
          (eNB->nulsch[i]->rnti>0) &&
          (eNB->nulsch[i]->harq_process->subframe_scheduling_flag==1)) 
477 478
        {
          // UE is has ULSCH scheduling
479
          //////////////////////////////////////round = eNB->nulsch[i]->harq_process->round; //commented to remove warning, to be added if round is used
480
          /*NB-IoT The nb_rb always set to 1 */
481
          for (int rb=0;rb<=eNB->nulsch[i]->harq_process->nb_rb;rb++) 
482
            {
483
               int rb2 = rb+eNB->nulsch[i]->harq_process->first_rb;
484
               eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
485
            }
486

487
          /*Log for what kind of the ULSCH Reception*/
488

489 490
          /*Calculate for LTE C-RS*/
          //nPRS = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1];
491

492 493
          //eNB->ulsch[i]->cyclicShift = (eNB->ulsch[i]->harq_processes[harq_pid]->n_DMRS2 + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +nPRS)%12;

494
          if (fp->frame_type == FDD_NB_IoT ) 
495 496 497
            {
              int sf = (subframe<4) ? (subframe+6) : (subframe-4);
              /*After Downlink Data transmission, simply have a notice to received ACK from PUCCH, I think it's not use for now */
498
              if (eNB->ndlsch[i]->subframe_tx[sf]>0) // we have downlink transmission
499
                { 
500
                  eNB->nulsch[i]->harq_process->O_ACK = 1;
501 502 503
                } 
              else 
                {
504
                  eNB->nulsch[i]->harq_process->O_ACK = 0;
505 506
                }
            }
507

508
          eNB->pusch_stats_rb[i][(frame*10)+subframe]    = eNB->nulsch[i]->harq_process->nb_rb;
509
          eNB->pusch_stats_round[i][(frame*10)+subframe] = eNB->nulsch[i]->harq_process->round;
510
          eNB->pusch_stats_mcs[i][(frame*10)+subframe]   = eNB->nulsch[i]->harq_process->mcs;
511

512 513
  

514 515
          rx_ulsch_NB_IoT(eNB,
                          proc,
516 517 518 519 520
                          eNB->UE_stats[i].sector,  // this is the effective sector id
                          i,
                          eNB->nulsch,
                          0);

521
          ret = ulsch_decoding_NB_IoT(eNB,proc,
522 523 524
                                      i,
                                      0, // control_only_flag
                                      eNB->nulsch[i]->harq_process->V_UL_DAI,
525
                                      eNB->nulsch[i]->harq_process->nb_rb>20 ? 1 : 0);
526

527
          //compute the expected ULSCH RX power (for the stats)
528 529 530
          eNB->nulsch[(uint32_t)i]->harq_process->delta_TF = get_hundred_times_delta_IF_eNB_NB_IoT(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
          eNB->UE_stats[i].nulsch_decoding_attempts[harq_pid][eNB->nulsch[i]->harq_process->round]++;
          eNB->nulsch[i]->harq_process->subframe_scheduling_flag=0;
531 532
          if (eNB->nulsch[i]->harq_process->cqi_crc_status == 1) {

533 534 535 536 537
              extract_CQI_NB_IoT(eNB->nulsch[i]->harq_process->o,
                                 eNB->nulsch[i]->harq_process->uci_format,
                                 &eNB->UE_stats[i],
                                 fp->N_RB_DL,
                                 &rnti, &access_mode);
538
            
539
              eNB->UE_stats[i].rank = eNB->nulsch[i]->harq_process->o_RI[0];
540
          }
541

542 543 544 545 546 547 548 549
          if (ret == (1+MAX_TURBO_ITERATIONS)) {

              T(T_ENB_PHY_ULSCH_UE_NACK,
                T_INT(eNB->Mod_id),
                T_INT(frame),
                T_INT(subframe),
                T_INT(i),
                T_INT(eNB->nulsch[i]->rnti),
550
                T_INT(harq_pid));
551

552 553 554 555
              eNB->UE_stats[i].ulsch_round_errors[harq_pid][eNB->nulsch[i]->harq_process->round]++;
              eNB->nulsch[i]->harq_process->phich_active = 1;
              eNB->nulsch[i]->harq_process->phich_ACK = 0;
              eNB->nulsch[i]->harq_process->round++;
556

557
              LOG_D(PHY,"[eNB][PUSCH %d] Increasing to round %d\n",harq_pid,eNB->nulsch[i]->harq_process->round);
558

559 560
          if (eNB->nulsch[i]->Msg3_flag == 1) 
          {
561 562
               /*dump_ulsch(eNB,proc,i);
               exit(-1);*/
563

564 565 566 567 568 569 570 571 572 573 574
               /*In NB-IoT MSG3 */
                // activate retransmission for Msg3 (signalled to UE PHY by DCI
                eNB->nulsch[(uint32_t)i]->Msg3_active = 1;
                /* Need to check the procedure for NB-IoT (MSG3) retransmission
                get_Msg3_alloc_ret(fp,subframe,frame,&eNB->ulsch[i]->Msg3_frame,&eNB->ulsch[i]->Msg3_subframe);
                mac_xface->set_msg3_subframe(eNB->Mod_id, eNB->CC_id, frame, subframe, eNB->ulsch[i]->rnti,eNB->ulsch[i]->Msg3_frame, eNB->ulsch[i]->Msg3_subframe);
                */
                T(T_ENB_PHY_MSG3_ALLOCATION, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe),
                  T_INT(i), T_INT(eNB->nulsch[i]->rnti), T_INT(0 /* 0 is for retransmission*/),
                  T_INT(eNB->nulsch[i]->Msg3_frame), T_INT(eNB->nulsch[i]->Msg3_subframe));     
          } // This is Msg3 error
575
          else 
576 577
          { //normal ULSCH
              if (eNB->nulsch[i]->harq_process->round== eNB->nulsch[i]->Mlimit) 
578
                {
579 580
                  eNB->nulsch[i]->harq_process->round=0;
                  eNB->nulsch[i]->harq_process->phich_active=0;
581
                  eNB->UE_stats[i].ulsch_errors[harq_pid]++;
582 583
                  eNB->UE_stats[i].ulsch_consecutive_errors++; 
                  /*if (eNB->ulsch[i]->harq_processes[harq_pid]->nb_rb > 20) {
584 585
                    dump_ulsch(eNB,proc,i);
                  exit(-1);
586
                  }*/
587 588
                  // indicate error to MAC
                  if (eNB->mac_enabled == 1)
589
                    {
590
                      //instead rx_sdu to report The Uplink data not received successfully to MAC
591
                      (UL_INFO->crc_ind.crc_pdu_list+i)->crc_indication_rel8.crc_flag = 1;
Nick Ho's avatar
Nick Ho committed
592
                       UL_INFO->crc_ind.number_of_crcs++;
593 594 595 596
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.rnti      = eNB->nulsch[i]->rnti;
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->data                        = NULL;
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_indication_rel8.length   = 0;
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.harq_pid  = harq_pid;
Nick Ho's avatar
Nick Ho committed
597
                       UL_INFO->RX_NPUSCH.number_of_pdus++;
598
                    }
599 600 601 602 603
                }
            }
        }  // ulsch in error
        else 
          {
604
            T(T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(eNB->nulsch[i]->rnti),
605
              T_INT(harq_pid));
606

607
          // Delete MSG3  log for the PHICH 
608

609
          for (j=0; j<fp->nb_antennas_rx; j++)
610 611
          //this is the RSSI per RB
          eNB->UE_stats[i].UL_rssi[j] =
612
            dB_fixed(eNB->pusch_vars[i]->ulsch_power[j] * (eNB->nulsch[i]->harq_process->nb_rb*12) / fp->ofdm_symbol_size) - eNB->rx_total_gain_dB -
613
            hundred_times_log10_NPRB_NB_IoT[eNB->nulsch[i]->harq_process->nb_rb-1]/100 -
614
            get_hundred_times_delta_IF_eNB_NB_IoT(eNB,i,harq_pid, 0)/100;
615
          //for NB-IoT PHICH not work
616
          /*eNB->ulsch[i]->harq_processes[harq_pid]->phich_active = 1;
617
          eNB->ulsch[i]->harq_processes[harq_pid]->phich_ACK = 1;*/
618
          eNB->nulsch[i]->harq_process->round = 0;
619
          eNB->UE_stats[i].ulsch_consecutive_errors = 0;
620

621
          if (eNB->nulsch[i]->Msg3_flag == 1) 
622
            {
623
              if (eNB->mac_enabled==1) 
624
                {
625 626 627
                  LOG_I(PHY,"[eNB %d][RAPROC] Frame %d Terminating ra_proc for harq %d, UE %d\n",
                        eNB->Mod_id,frame,harq_pid,i);
                  if (eNB->mac_enabled)
628 629
                    {
                      // store successful MSG3 in UL_Info instead rx_sdu
630
                      (UL_INFO->crc_ind.crc_pdu_list+i)->crc_indication_rel8.crc_flag  = 0;
Nick Ho's avatar
Nick Ho committed
631
                      UL_INFO->crc_ind.number_of_crcs++;
632 633 634 635
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.rnti       = eNB->nulsch[i]->rnti;
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->data                         = eNB->nulsch[i]->harq_process->b;
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_indication_rel8.length    = eNB->nulsch[i]->harq_process->TBS>>3;
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.harq_pid   = harq_pid;
Nick Ho's avatar
Nick Ho committed
636
                      UL_INFO->RX_NPUSCH.number_of_pdus++;
637
                    }
638

639 640 641 642 643 644 645 646 647 648 649 650 651
                  /* Need check if this needed in NB-IoT
                  // one-shot msg3 detection by MAC: empty PDU (e.g. CRNTI)
                  if (eNB->ulsch[i]->Msg3_flag == 0 ) {
                 eNB->UE_stats[i].mode = PRACH;
                 mac_xface->cancel_ra_proc(eNB->Mod_id,
                 eNB->CC_id,
                 frame,
                 eNB->UE_stats[i].crnti);
                 mac_phy_remove_ue(eNB->Mod_id,eNB->UE_stats[i].crnti);
                 eNB->ulsch[(uint32_t)i]->Msg3_active = 0;
                 } // Msg3_flag == 0*/
      
              } // mac_enabled==1
652

653
            eNB->UE_stats[i].mode     = PUSCH;
654
            eNB->nulsch[i]->Msg3_flag = 0;
655

656
            LOG_D(PHY,"[eNB %d][RAPROC] Frame %d : RX Subframe %d Setting UE %d mode to PUSCH\n",eNB->Mod_id,frame,subframe,i);
657 658 659 660

            /*Init HARQ parameters, need to check*/
            for (k=0; k<8; k++) 
              { //harq_processes
661
                for (j=0; j<eNB->ndlsch[i]->Mlimit; j++) 
662
                  {
663 664 665
                    eNB->UE_stats[i].dlsch_NAK[k][j]    = 0;
                    eNB->UE_stats[i].dlsch_ACK[k][j]    = 0;
                    eNB->UE_stats[i].dlsch_trials[k][j] = 0;
666 667
                  }

668 669 670
                eNB->UE_stats[i].dlsch_l2_errors[k]       = 0;
                eNB->UE_stats[i].ulsch_errors[k]          = 0;
                eNB->UE_stats[i].ulsch_consecutive_errors = 0;
671

672
                for (j=0; j<eNB->nulsch[i]->Mlimit; j++) 
673
                  {
674 675 676 677
                    eNB->UE_stats[i].nulsch_decoding_attempts[k][j]     = 0;
                    eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j] = 0;
                    eNB->UE_stats[i].ulsch_round_errors[k][j]           = 0;
                    eNB->UE_stats[i].ulsch_round_fer[k][j]              = 0;
678 679
                  }
              }
680

681 682 683
            eNB->UE_stats[i].dlsch_sliding_cnt  = 0;
            eNB->UE_stats[i].dlsch_NAK_round0   = 0;
            eNB->UE_stats[i].dlsch_mcs_offset   = 0;
684
          } // Msg3_flag==1
685
         else 
686
          {  // Msg3_flag == 0
687
            if (eNB->mac_enabled == 1) 
688 689
              {
                  // store successful Uplink data in UL_Info instead rx_sdu
690
                  (UL_INFO->crc_ind.crc_pdu_list+i)->crc_indication_rel8.crc_flag  = 0;
Nick Ho's avatar
Nick Ho committed
691
                  UL_INFO->crc_ind.number_of_crcs++;
692 693 694 695
                  (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.rnti       = eNB->nulsch[i]->rnti;
                  (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->data                         = eNB->nulsch[i]->harq_process->b;
                  (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_indication_rel8.length    = eNB->nulsch[i]->harq_process->TBS>>3;
                  (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.harq_pid   = harq_pid;
Nick Ho's avatar
Nick Ho committed
696
                  UL_INFO->RX_NPUSCH.number_of_pdus++;
697 698
      
              } // mac_enabled==1
699
          } // Msg3_flag == 0
700

701
            // estimate timing advance for MAC
702
              sync_pos                               = NB_IoT_est_timing_advance_pusch(eNB,i);
703 704 705 706
              eNB->UE_stats[i].timing_advance_update = sync_pos - fp->nb_prefix_samples/4; //to check

      }  // ulsch not in error

707

708
      // Process HARQ only in NPUSCH
Nick Ho's avatar
Nick Ho committed
709
      /*process_HARQ_feedback(i,
710 711 712 713
                            eNB,proc,
                            1, // pusch_flag
                            0,
                            0,
Nick Ho's avatar
Nick Ho committed
714
                            0);*/
715

716

717 718
      

719
    } // ulsch[0] && ulsch[0]->rnti>0 && ulsch[0]->subframe_scheduling_flag == 1
Nick Ho's avatar
Nick Ho committed
720

721 722 723 724 725 726

    // update ULSCH statistics for tracing




727
  } // loop i=0 ... NUMBER_OF_UE_MAX-1
728 729 730 731 732

}

#undef DEBUG_PHY_PROC

733
/*Generate eNB ndlsch params for NB-IoT from the NPDCCH PDU of the DCI, modify the input to the Sched Rsp variable*/
Nick Ho's avatar
Nick Ho committed
734

735
void generate_eNB_dlsch_params_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,eNB_rxtx_proc_t * proc,nfapi_dl_config_request_pdu_t *dl_config_pdu) 
Nick Ho's avatar
Nick Ho committed
736
{
737 738 739 740 741 742 743 744
  int                      UE_id         =  -1;
  NB_IoT_DL_FRAME_PARMS    *fp           =  &eNB->frame_parms_NB_IoT;
  int                      frame         =  proc->frame_tx;
  int                      subframe      =  proc->subframe_tx;
  DCI_CONTENT              *DCI_Content; 
  DCI_format_NB_IoT_t      DCI_format;
  NB_IoT_eNB_NDLSCH_t      *ndlsch;
  NB_IoT_eNB_NPDCCH_t      *npdcch;
745

Nick Ho's avatar
Nick Ho committed
746

747

748 749
  DCI_Content = (DCI_CONTENT*) malloc(sizeof(DCI_CONTENT));

750
  // check DCI format is N1 (format 0)
751 752
  if(dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.dci_format == 0)
    {
753
      //check DCI format N1 is for RAR  rnti_type  in FAPI specs table 4-45
754
      if(dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.rnti_type == 1)
755
        {
756

757
        //mapping the fapi parameters to the oai parameters
758 759

          DCI_format = DCIFormatN1_RAR;
760 761 762 763 764 765 766

          //DCI format N1 to RAR
          DCI_Content->DCIN1_RAR.type           = 1;
          DCI_Content->DCIN1_RAR.orderIndicator = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.npdcch_order_indication;
          DCI_Content->DCIN1_RAR.Scheddly       = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.scheduling_delay;
          DCI_Content->DCIN1_RAR.ResAssign      = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.resource_assignment;
          DCI_Content->DCIN1_RAR.mcs            = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.mcs;
767
          DCI_Content->DCIN1_RAR.RepNum         = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.repetition_number;
768 769 770 771
          DCI_Content->DCIN1_RAR.ndi            = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.new_data_indicator;
          DCI_Content->DCIN1_RAR.HARQackRes     = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.harq_ack_resource;
          DCI_Content->DCIN1_RAR.DCIRep         = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.dci_subframe_repetition_number;

772 773
          //TODO calculate the number of common repetitions
          //fp->nprach_config_common.number_repetition_RA = see TS 36.213 Table 16.1-3
774

775
          // fill the dlsch_ra_NB structure for RAR, and packed the DCI PDU
776

777 778
          ndlsch               =  eNB->ndlsch_ra;
          ndlsch->ndlsch_type  =  RAR;
779 780

          LOG_D(PHY,"Generating dlsch params for RA_RNTI and packing DCI\n");
781 782 783 784 785 786 787 788 789
          generate_eNB_dlsch_params_from_dci_NB_IoT(eNB,
                                                    frame,
                                                    subframe,
                                                    DCI_Content,
                                                    dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.rnti,
                                                    DCI_format,
                                                    ndlsch,
                                                    fp,
                                                    dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.aggregation_level,
790
                                                    dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.start_symbol);
791 792

          //eNB->dlsch_ra_NB->nCCE[subframe] = eNB->DCI_pdu->dci_alloc.firstCCE;
793
        }
794
      else
795 796
        { //managing data

797 798 799
        //TODO target/SIMU/USER?init_lte/init_lte_eNB we should allocate the ndlsch structures
        UE_id = find_ue_NB_IoT(dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.rnti, eNB);
        AssertFatal(UE_id != -1, "no ndlsch context available or no ndlsch context corresponding to that rnti\n");
800

801

802
            //mapping the fapi parameters to the oai parameters
803

804
            DCI_format = DCIFormatN1;
805

806 807 808 809 810 811
              //DCI format N1 to DLSCH
              DCI_Content->DCIN1.type           = 1;
              DCI_Content->DCIN1.orderIndicator = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.npdcch_order_indication;
              DCI_Content->DCIN1.Scheddly       = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.scheduling_delay;
              DCI_Content->DCIN1.ResAssign      = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.resource_assignment;
              DCI_Content->DCIN1.mcs            = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.mcs;
812
              DCI_Content->DCIN1.RepNum         = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.repetition_number;
813 814 815 816
              DCI_Content->DCIN1.ndi            = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.new_data_indicator;
              DCI_Content->DCIN1.HARQackRes     = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.harq_ack_resource;
              DCI_Content->DCIN1.DCIRep         = dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.dci_subframe_repetition_number;

817 818 819 820 821 822 823 824 825 826

              //set the NPDCCH UE-specific structure  (calculate R)
              npdcch=eNB->npdcch[(uint8_t)UE_id];
              AssertFatal(npdcch != NULL, "NPDCCH structure for UE specific is not exist\n");
              npdcch->repetition_idx = 0; //this is used for the encoding mechanism to understand that is the first transmission

              if(dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.aggregation_level) //whenever aggregation level is =1 we have only 1 repetition for USS
              npdcch->repetition_number = 1;
              else
              {
827
                //see TS 36.213 Table 16.1-1
828 829 830
              }


831 832
              //fill the ndlsch structure for UE and packed the DCI PD

833 834
            ndlsch = eNB->ndlsch[(uint8_t)UE_id]; //in the old implementation they also consider UE_id = 1;
            ndlsch->ndlsch_type = UE_Data;
835

836
              //parameters we don't consider pdsch config dedicated since not calling the phy config dedicated step2
837

838
            LOG_D(PHY,"Generating dlsch params for DCIN1 data and packing DCI\n");
839 840 841 842 843 844 845 846 847
            generate_eNB_dlsch_params_from_dci_NB_IoT(eNB,
                                                      frame,
                                                      subframe,
                                                      DCI_Content,
                                                      dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.rnti,
                                                      DCI_format,
                                                      ndlsch,
                                                      fp,
                                                      dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.aggregation_level,
848
                                                      dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.start_symbol); 
849 850

              //eNB->ndlsch[(uint8_t)UE_id]->nCCE[subframe] = eNB->DCI_pdu->dci_alloc[i].firstCCE;
851 852


853 854 855 856 857 858 859 860 861
        }
    }
  else if(dl_config_pdu->npdcch_pdu.npdcch_pdu_rel13.dci_format == 1)
    { 
      DCI_format = DCIFormatN2;
      LOG_D(PHY,"Paging procedure not implemented\n");
    }
  else
    LOG_E(PHY,"unknown DCI format for NB-IoT DL\n");
Nick Ho's avatar
Nick Ho committed
862 863 864 865 866 867


}



868
void generate_eNB_ulsch_params_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,eNB_rxtx_proc_t *proc,nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu) {
869

870
  int UE_id = -1;
871
  //int harq_pid = 0;
Nick Ho's avatar
Nick Ho committed
872

873 874
  DCI_CONTENT *DCI_Content;
  DCI_Content = (DCI_CONTENT*) malloc(sizeof(DCI_CONTENT));
875 876

  //mapping the fapi parameters to the OAI parameters
877 878 879 880 881 882 883 884 885
  DCI_Content->DCIN0.type       = 0;
  DCI_Content->DCIN0.scind      = hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.subcarrier_indication;
  DCI_Content->DCIN0.ResAssign  = hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.subcarrier_indication;
  DCI_Content->DCIN0.mcs        = hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.mcs;
  DCI_Content->DCIN0.ndi        = hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.new_data_indicator;
  DCI_Content->DCIN0.Scheddly   = hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.scheduling_delay;
  DCI_Content->DCIN0.RepNum     = hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.repetition_number;
  DCI_Content->DCIN0.rv         = hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.redudancy_version;
  DCI_Content->DCIN0.DCIRep     = hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.dci_subframe_repetition_number;
886 887


888

889
  UE_id = find_ue_NB_IoT(hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.rnti, eNB);
890
  AssertFatal(UE_id == -1, "no ndlsch context available or no ndlsch context corresponding to that rnti\n");
891 892


Nick Ho's avatar
Nick Ho committed
893 894
  /*Log for generate ULSCH DCI*/

895 896 897 898 899 900 901
  generate_eNB_ulsch_params_from_dci_NB_IoT(eNB,
                                            proc,
                                            DCI_Content,
                                            hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.rnti,
                                            DCIFormatN0,
                                            UE_id,
                                            hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.aggregation_level,
902
                                            hi_dci0_pdu->npdcch_dci_pdu.npdcch_dci_pdu_rel13.start_symbol);  
903

Nick Ho's avatar
Nick Ho committed
904 905
  
  //LOG for ULSCH DCI Resource allocation
906
  //CBA is not used in NB-IoT
907
    eNB->nulsch[UE_id]->harq_process->subframe_scheduling_flag = 1;
Nick Ho's avatar
Nick Ho committed
908 909 910
  
}

911 912


913 914 915
/*
 * for NB-IoT ndlsch procedure
 * this function is called by the PHy procedure TX in 3 possible occasion:
916
 * 1) we manage BCCH pdu (SI)
917 918
 * 2) we manage RA dlsch pdu
 * 3) UE-specific dlsch pdu
919 920 921 922
 * ** we need to know if exist and which value has the eutracontrolRegionSize (TS 36.213 ch 16.4.1.4) whenever we are in In-band mode
 * ** CQI and PMI are not present in NB-IoT
 * ** redundancy version exist only in UL for NB-IoT and not in DL
 */
923
void npdsch_procedures(PHY_VARS_eNB_NB_IoT      *eNB,
924 925 926 927 928
                       eNB_rxtx_proc_t   *proc,     //Context data structure for RX/TX portion of subframe processing
                       NB_IoT_eNB_NDLSCH_t      *ndlsch,
                       //int num_pdcch_symbols,            //(BCOM says are not needed
                       uint8_t                  *pdu
                       )
929
{
930 931 932 933 934 935 936 937
  int                     frame                   =   proc->frame_tx;
  int                     subframe                =   proc->subframe_tx;
  NB_IoT_DL_eNB_HARQ_t    *ndlsch_harq            =   ndlsch->harq_process;
  int                     input_buffer_length     =   ndlsch_harq->TBS/8;         // get in byte //the TBS is set in generate_dlsch_param
  NB_IoT_DL_FRAME_PARMS   *fp                     =   &eNB->frame_parms_NB_IoT;
  int                     G;
  uint8_t                 *DLSCH_pdu              =   NULL;
  uint8_t                 DLSCH_pdu_tmp[input_buffer_length+4];                   //[768*8];
938
  //uint8_t DLSCH_pdu_rar[256];
939
  int                     i;
940 941

  LOG_D(PHY,
942 943 944 945 946 947
        "[eNB %"PRIu8"][PDSCH rnti%"PRIx16"] Frame %d, subframe %d: Generating PDSCH/DLSCH with input size = %"PRIu16", mcs %"PRIu8"(round %"PRIu8")\n",
        eNB->Mod_id,
        ndlsch->rnti,
        frame, subframe, input_buffer_length,
        ndlsch_harq->mcs,
        ndlsch_harq->round
948
        );
949

950
  if(ndlsch_harq->round == 0) { //first transmission so we encode... because we generate the sequence
951

952
    if (eNB->mac_enabled == 1) { // set in lte-softmodem/main line 1646
953

954
        DLSCH_pdu = pdu;
955

956 957 958 959 960 961
      /*
       * we don't need to manage the RAR here since should be managed in the MAC layer for two reasons:
       * 1)we should receive directly the pdu containing the RAR from the MAC in the schedule_response
       * 2)all the parameters for getting the MSG3 should be given by the UL_CONFIG.request (all inside the next schedule_response function)
       *
       */
962

963 964 965 966 967
        //fill_rar shouduld be in the MAC
        //cancel ra procedure should be in the mac
        //scheduling request not implemented in NB-IoT
        //nulsch_param configuration for MSG3 should be considered in handling UL_Config.request
        //(in particular the nulsch structure for RAR is distinguished based on the harq_process->rar_alloc and the particular subframe in which we should have Msg3)
968 969 970
    }

    else {  //XXX we should change taus function???
971

972
      DLSCH_pdu = DLSCH_pdu_tmp;
973

974
      for (i=0; i<input_buffer_length; i++)
975

976
         DLSCH_pdu[i] = (unsigned char)(taus()&0xff);
977 978 979
    }
  }
  else {
980
    //We are doing a retransmission (harq round > 0
981 982
    #ifdef DEBUG_PHY_PROC
    #ifdef DEBUG_DLSCH
983
    LOG_D(PHY,"[eNB] This DLSCH is a retransmission\n");
984 985
    #endif
    #endif
986 987 988 989 990
  }

  if (eNB->abstraction_flag==0) { // used for simulation of the PHY??


991 992 993 994 995 996 997 998 999 1000 1001 1002
    //we can distinguish among the different kind of NDLSCH structure (example)
    switch(ndlsch->ndlsch_type)
    {
    case SIB1:
      break;
    case SI_Message:
      break;
    case RAR: //maybe not needed
      break;
    case UE_Data: //maybe not needed
      break;
    }
1003 1004


1005 1006 1007 1008 1009
   /*
    * in any case inside the encoding procedure is re-checked if this is round 0 or no
    * in the case of harq_process round = 0 --> generate the sequence and put it into the parameter *c[r]
    * otherwise do nothing(only rate maching)
    */
1010 1011


1012 1013 1014 1015 1016 1017 1018
  /*
   * REASONING:
   * Encoding procedure will generate a Table with encoded data ( in ndlsch structure)
   * The table will go in input to the scrambling
   * --we should take care if there are repetitions of data or not because scrambling should be called at the first frame and subframe in which each repetition
   * begin (see params Nf, Ns)
   */
1019 1020 1021 1022 1023 1024


    // 36-212
    //encoding---------------------------

    /*
1025 1026
     *
     * REASONING:
1027 1028 1029 1030
   * Encoding procedure will generate a Table with encoded data ( in ndlsch structure)
   * The table will go in input to the scrambling
   * --we should take care if there are repetitions of data or not because scrambling should be called at the first frame and subframe in which each repetition
   *  begin (see params Nf, Ns)
1031 1032
     *
     * we should have as an iput parameter also G for the encoding based on the switch/case over eutracontrolRegionSize (if exist) and operationModeInfo if defined
1033 1034
     * NB: switch case of G is the same for npdsch and npdcch
     *
1035 1036 1037
     * npdsch_start symbol index
     * -refers to TS 36.213 ch 16.4.1.4:
     * -if subframe k is a subframe for receiving the SIB1-NB
1038 1039
     *  -- if operationModeInfo set to 00 or 01 (in band) --> npdsch_start_sysmbol = 3
     *  -- otherwise --> npdsch_start_symbol = 0
1040
     * -if the k subframe is not for SIB1-NB
1041
     *  --npdsch_start_symbol = eutracontrolregionsize (defined for in-band operating mode (mode 0,1 for FAPI specs) and take values 1,2,3 [units in number of OFDM symbol])
1042
     * - otherwise --> npdsch_start_symbol = 0
1043
     * (is the starting OFDM for the NPDSCH transmission in the first slot in a subframe k)
1044 1045
     * FAPI style:
     * npdsch_start symbol is stored in the ndlsch structure from the reception of the NPDLSCH PDU in the DL_CONFIG.request (so should be set by the MAC and put inside the schedule response)
1046 1047 1048 1049 1050
     * Nsf needed as an input (number of subframe)-->inside harq_process of ndlsch
     */

    switch(ndlsch->npdsch_start_symbol)
    {
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065
      case 0:
        G = 304;
      break;
      case 1:
        G = 240;
      break;
      case 2:
        G = 224;
      break;
      case 3:
        G =200;
      break;
      default:
        LOG_E (PHY,"npdsch_start_index has unwanted value\n");
      break;
1066 1067

    }
1068
    //start_meas_NB_IoT(&eNB->dlsch_encoding_stats);
1069 1070
    LOG_I(PHY, "NB-IoT Encoding step\n");

1071
    //    eNB->te(eNB,
1072 1073 1074 1075 1076 1077 1078
    //      DLSCH_pdu,
    //      num_pdcch_symbols,
    //      dlsch,
    //      frame,subframe,
    //      &eNB->dlsch_rate_matching_stats,
    //      &eNB->dlsch_turbo_encoding_stats,
    //      &eNB->dlsch_interleaving_stats);
1079 1080


1081
   // stop_meas_NB_IoT(&eNB->dlsch_encoding_stats);
1082 1083 1084 1085

    // 36-211
    //scrambling-------------------------------------------

1086
   // start_meas_NB_IoT(&eNB->dlsch_scrambling_stats);
1087 1088
    LOG_I(PHY, "NB-IoT Scrambling step\n");

1089 1090 1091 1092 1093 1094
    /*
     * SOME RELEVANT FACTS:
     *
     *
     */

1095
      //    dlsch_scrambling(fp,
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107
      //         0,
      //         dlsch,
      //         get_G(fp,
      //         dlsch_harq->nb_rb,
      //         dlsch_harq->rb_alloc,
      //         get_Qm(dlsch_harq->mcs),
      //         dlsch_harq->Nl,
      //         num_pdcch_symbols,
      //         frame,subframe,
      //         0),
      //         0,
      //         subframe<<1);
1108

1109
    //stop_meas_NB_IoT(&eNB->dlsch_scrambling_stats);
1110 1111 1112


    //modulation-------------------------------------------
1113
    //start_meas_NB_IoT(&eNB->dlsch_modulation_stats);
1114 1115
    LOG_I(PHY, "NB-IoT Modulation step\n");

1116
    //    dlsch_modulation(eNB,
1117 1118 1119 1120 1121 1122
    //         eNB->common_vars.txdataF[0],
    //         AMP,
    //         subframe,
    //         num_pdcch_symbols,
    //         dlsch,
    //         dlsch1);
1123

1124
    //stop_meas_NB_IoT(&eNB->dlsch_modulation_stats);
1125 1126 1127 1128 1129
  }


#ifdef PHY_ABSTRACTION
  else {
1130
    //start_meas_NB_IoT(&eNB->dlsch_encoding_stats);
1131
    //dlsch_encoding_emul(eNB,
1132 1133
      //DLSCH_pdu,
      //dlsch);
1134
   // stop_meas_NB_IoT(&eNB->dlsch_encoding_stats);
1135 1136 1137 1138 1139
  }

#endif
  ndlsch->active = 0;
}
1140 1141


1142
extern int oai_exit;
1143 1144

/*
1145
 * ASSUMPTION
1146 1147 1148
 *
 * The MAC schedule the schedule_response in a SUBFRAME BASE (at least because otherwise we have problem with our assumptions on SI transmission)
 *
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160
 *Since in FAPI specs seems to not manage the information for the sceduling of system information:
 * Assume that the MAC layer manage the scheduling for the System information (SI messages) transmission while MIB and SIB1 are done directly at PHY layer
 * This means that the MAC scheduler will send to the PHY the NDLSCH PDU and MIB PDU (DL_CONFIG.request)each time they should be transmitted. In particular:
 ***MIB-NB
 *schedule_response containing a n-BCH PDU is transmitted only at the beginning of the MIB period, then repetitions are made directly by the PHY layer (see FAPI specs pag 94 N-BCH 3.2.4.2)
 *if no new N-BCH PDU is trasmitted at SFN mod 64=0 then stop MIB transmission
 ***SIB1-NB
 *schedule response containing a NDLSCH pdu (with appropiate configuration) will be transmitted only at the beginning of each SIB1-NB period (256 rf)
 *then repetitions are managed directly by the PHY layer
 *if no new NDLSCH pdu (configured for SIB1-NB) at SFN mod 256 = 0 is transmitted. stop SIB1-NB transmission
 ****SI Messages
 * -schedule_response is transmitted by the MAC in every subframe needed for the SI transmission (NDLSCH should have a proper configuration)
1161
 * -if the schedule_response carry any SDU for SI-Message (SDU!= NULL)--> put the SDU in the PHY buffer to be encoded ecc... and start the transmission
1162 1163
 * -if the schedule_response not carry any SDU (SDU == NULL) but NDLSCH is properly set for SI, then PHY continue transmit the remaining part of the previous SDU
 * (this because the PHY layer have no logic of repetition_pattern, si_window ecc.. so should be continuously instructed the PHY when to transmit.
1164
 *
1165 1166 1167 1168
 * Furthermore, SI messages are transmitted in more that 1 subframe (2 or 8) and therefore MAC layer need to count how many subframes are available in the current frame for transmit it
 * and take in consideration that other frames are needed before starting the transmission of a new one)
 *
 *
1169
 *We assume that whenever the NDLSCH pdu is a BCCH type, we consider as if it's a SIB1 while in other case can be data or SI-message depending on the RNTI
1170 1171 1172
 *
 * **relevant aspects for the System information Transmission (Table 4-47 NDLSCH FAPi specs)
 * 1)RNTI type = 0 (contains a BCCH)
1173 1174
 * 2)Repetition number == scheduling info SIB1 mapped into 4-8-16
 * 3)RNTI (0xFFFF = SI-RNTI)
1175 1176 1177
 * (see schedule_response implementation)
 *
 */
1178 1179 1180 1181 1182 1183 1184

/*
 * This function is triggered by the schedule_response
 * (the frequency at which is transmitted to the PHY depends on the MAC scheduler implementation)
 * (in OAI in principle is every subframe)
 */

1185
void phy_procedures_eNB_TX_NB_IoT(PHY_VARS_eNB_NB_IoT     *eNB,
1186 1187
                                  eNB_rxtx_proc_t  *proc,
                                  int                     do_meas)
1188
{
1189 1190 1191 1192 1193 1194 1195 1196
  int                    frame           = proc->frame_tx;
  int                    subframe        = proc->subframe_tx;
  uint32_t               aa;
  DCI_PDU_NB_IoT         *dci_pdu        = eNB->DCI_pdu;
  NB_IoT_DL_FRAME_PARMS  *fp             = &eNB->frame_parms_NB_IoT;
  int8_t                 UE_id           = 0;
  int                    **txdataF       = eNB->common_vars.txdataF[0];
  uint32_t               sib1_startFrame = -1;
1197
  //NB_IoT_eNB_NPDCCH_t*npdcch;
1198

1199
  if(do_meas == 1)
1200
    //start_meas_NB_IoT(&eNB->phy_proc_tx);
1201 1202


1203
  /*the original scheduler "eNB_dlsch_ulsch_scheduler" now is no more done here but is triggered directly from UL_Indication (IF-Module Function)*/
1204

1205
  // clear the transmit data array for the current subframe
1206 1207 1208 1209 1210 1211
  for (aa=0; aa<fp->nb_antenna_ports_eNB; aa++) 
    {      
      memset(&eNB->common_vars.txdataF[0][aa][subframe*fp->ofdm_symbol_size*(fp->symbols_per_tti)],
                  0,fp->ofdm_symbol_size*(fp->symbols_per_tti)*sizeof(int32_t));
    } 

1212
  //generate NPSS/NSSS
1213
 // common_signal_procedures_NB_IoT(eNB,proc);  // to uncomment after NB-IoT testing
1214

1215
    //Generate MIB
1216
    if(subframe ==0 && (eNB->npbch != NULL))
1217 1218
     {
          if(eNB->npbch->pdu != NULL)
1219
          {
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231
            //BCOM function
            /*
             * -the function get the MIB pdu and schedule the transmission over the 64 radio frame
             * -need to check the subframe #0 (since encoding functions only check the frame)
             * this functions should be called every frame (the function will transmit the remaining part of MIB)
             * ( XXX Should check when the schedule_responce is transmitted by MAC scheduler)
             * RB-ID only for the case of in-band operation but should be always considered
             * (in stand alone i can put whatever the number)in other case consider the PRB index in the Table R&Shwartz pag 9
             *
             */

            generate_npbch(eNB->npbch,
1232 1233 1234
                           txdataF,
                           AMP,
                           fp,
1235
                           eNB->npbch->pdu,
1236 1237
                           frame%64,
                           fp->NB_IoT_RB_ID);
1238
                        
1239 1240 1241 1242 1243
          }

          //In the last frame in which the MIB-NB should be transmitted after we point to NULL since maybe we stop MIB trasnmission
          //this should be in line with FAPI specs pag 94 (BCH procedure in Downlink 3.2.4.2 for NB-IoT)
          if(frame%64 == 63)
1244
          {
1245
            eNB->npbch->pdu = NULL;
1246
          }
1247
      }
Nick Ho's avatar
Nick Ho committed
1248

1249

1250
    //Check for SIB1-NB transmission
1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
    /*
     *
     * the function should be called for each frame
     * Parameters needed:
     * -sib1-NB pdu if new one (should be given by the MAC at the start of each SIB1-NB period)
     * -when start a new SIB1-NB repetition (sib1_rep_start)
     * -the frame number relative to the 16 continuous frame within a repetition (relative_sib1_frame) 1st, 2nd ...
     *
     * we check that the transmission should occurr in subframe #4
     *
     * consider that if at the start of the new SIB1-NB period the MAC will not send an NPDSCH for the SIB1-NB transmission then SIB1-NB will be not transmitted (pdu = NULL)
     *
     */
1264
    if(subframe == 4 && eNB->ndlsch_SIB1 != NULL && eNB->ndlsch_SIB1->harq_process->status == ACTIVE_NB_IoT)
1265
    {
1266
      //check if current frame is for SIB1-NB transmission (if yes get the starting frame of SIB1-NB) and set the flag for the encoding
1267
      sib1_startFrame = is_SIB1_NB_IoT(frame,
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286
                                       (long)eNB->ndlsch_SIB1->harq_process->repetition_number,
                                       fp->Nid_cell,
                                       eNB->ndlsch_SIB1); //set the flags
                                   
      if(sib1_startFrame != -1 && eNB->ndlsch_SIB1->harq_process->pdu != NULL)
      {
         npdsch_procedures(eNB,
                           proc,
                           eNB->ndlsch_SIB1, //since we have no DCI for system information, this is filled directly when we receive the NDLSCH pdu from DL_CONFIG.request message
                           eNB->ndlsch_SIB1->harq_process->pdu);
      }

      //at the end of the period we put the PDU to NULL since we have to wait for the new one from the MAC for starting the next SIB1-NB transmission
      if((frame-sib1_startFrame)%256 == 255)
      {
          //whenever we will not receive a new sdu from MAC at the start of the next SIB1-NB period we prevent future SIB1-NB transmission (may just only of the two condition is necessary)
          eNB->ndlsch_SIB1->harq_process->status = DISABLED;
          eNB->ndlsch_SIB1->harq_process->pdu = NULL;
      }
1287

1288
    }
1289

1290 1291

    //Check for SI transmission
1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304
    /*
     *Parameters needed:
     * -total number of subframes for the transmission (2-8) (inside the NDLSCH structure --> HARQ process -->resource_assignment)
     * XXX: in reality this flag is not needed because is enough to check if the PDU is NULL (continue the transmission) or not (new SI transmission)
     * -SI_start (inside ndlsch structure): flag for indicate the starting of the SI transmission within the SI window (new PDU is received by the MAC) otherwise the PHY continue to transmit
     *  what have in its buffer (so check the remaining encoded data continuously)
     *
     * SI transmission should not occurr in reserved subframes
     * subframe = 0 (MIB-NB)
     * subframe = 4 (SIB1-NB) but depends on the frame
     * subframe = 5 (NPSS)
     * subframe = 9 (NSSS) but depends on the frame (if is even)
     *
1305 1306
     * [This condition should be known by the MAC layer so it should trigger an DLSCH pdu only at proper instants]
     *
1307 1308 1309 1310
     * XXX Important: in the case the SI-window finish the PHY layer should have also being able to conclude all the SI transmission in time
     * (because this is managed by the MAC layer that stops transmitting the SDU to PHY in advance because is counting the remaining subframe for the transmission)
     *
     *
1311
     *XXX important: set the flag HARQ process->status to DISABLE when PHY finished the SI-transmission over the 2 or 8 subframes
1312 1313 1314
     *XXX important: whenever we enter for some error in the ndlsch_procedure with a pdu that is NULL but all the data of the SI have been transmitted (pdu_buffer_index = 0)
     *XXX  --> generate error
     *XXX: the npdlsch_procedure in this case should be only called when is triggered by the MAC schedule_response (use the status flag set by the schedule_response)
1315
     *
1316
     */
1317

1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347
  if(eNB->ndlsch_SI->harq_process->status == ACTIVE_NB_IoT && (eNB->ndlsch_SIB1->harq_process->status != ACTIVE_NB_IoT || subframe != 4)) //condition on SIB1-NB
  {
      if(frame%2 == 0)//condition on NSSS (subframe 9 not available)
      {
        if(eNB->ndlsch_SI != NULL &&  subframe!= 0 && subframe != 5 && subframe != 9)
         {
          //check if the PDU != NULL will be done inside just for understanding if a new SI message need to be transmitted or not
          npdsch_procedures(eNB,
                            proc,
                            eNB->ndlsch_SI, //since we have no DCI for system information, this is filled directly when we receive the DL_CONFIG.request message
                            eNB->ndlsch_SI->harq_process->pdu);

          eNB->ndlsch_SI->harq_process->status = DISABLED_NB_IoT;
        }

       } else {//this frame not foresee the transmission of NSSS (subframe 9 is available)
      
              if(eNB->ndlsch_SI != NULL &&  subframe!= 0 && subframe != 5)
              {
                   npdsch_procedures(eNB,
                                     proc,
                                     eNB->ndlsch_SI, //since we have no DCI for system information, this is filled directly when we receive the DL_CONFIG.request message
                                     eNB->ndlsch_SI->harq_process->pdu);

                   eNB->ndlsch_SI->harq_process->status = DISABLED_NB_IoT;

              }
           }

  }
1348

1349
      ///check for RAR transmission
1350
      if(eNB->ndlsch_ra != NULL && eNB->ndlsch_ra->active == 1 && (eNB->ndlsch_SIB1->harq_process->status != ACTIVE_NB_IoT || subframe != 4)) //condition on SIB1-NB
1351
      {
1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379
        if(frame%2 == 0)//condition on NSSS (subframe 9 not available)
         {
          if(eNB->ndlsch_SI != NULL &&  subframe!= 0 && subframe != 5 && subframe != 9)
           {

            npdsch_procedures(eNB,
                              proc,
                              eNB->ndlsch_ra, //should be filled ?? (in the old implementation was filled when from DCI we generate_dlsch_params
                              eNB->ndlsch_ra->harq_process->pdu);

            //it should be activated only when we receive the proper DCIN1_RAR
            eNB->ndlsch_ra->active= 0;
           }
         }
      else //this frame not foresee the transmission of NSSS (subframe 9 is available)
      {
        if(eNB->ndlsch_SI != NULL &&  subframe!= 0 && subframe != 5)
           {
              npdsch_procedures(eNB,
                                proc,
                                eNB->ndlsch_ra, //should be filled ?? (in the old implementation was filled when from DCI we generate_dlsch_params
                                eNB->ndlsch_ra->harq_process->pdu);

              //it should be activated only when we receive the proper DCIN1_RAR
              eNB->ndlsch_ra->active= 0; // maybe this is already done inside the ndlsch_procedure

           }
      }
1380
      }
1381 1382


1383
      //check for UE specific transmission
1384 1385
      /*
       * Delays between DCI transmission and NDLSCH transmission are taken in consideration by the MAC scheduler by sending in the proper subframe the scheduler_response
1386 1387
       * (TS 36.213 ch 16.4.1: DCI format N1, N2, ending in subframe n intended for the UE, the UE shall decode, starting from subframe n+5 DL subframe,
       * the corresponding NPDSCH transmission over the N consecutive NB/IoT DL subframes according to NPDCCH information)
1388 1389 1390 1391
       * Transmission over more subframe and Repetitions are managed directly by the PHY layer
       * We should have only 1 ue-specific ndlsch structure active at each time (active flag is set = 1 only at the corresponding NDLSCH pdu reception and not at the DCI time
       * (NDLSCH transmission should be compliant with the FAPI procedure Figure 3-49)
       *
1392 1393 1394 1395 1396 1397 1398 1399
       * XXX how are managed the transmission and repetitions over the NPDSCH:
       * -repetitions over the NPDSCH channel are defined inside the DCI
       * -need to know the repetition number R (see specs)
       * -repetition are made following a pattern rule (e.g. 00, 11 ...) (see specs)
       * --whenever R>4 then repetition pattern rule changes
       * -possibility to have DL-GAP (OPTIONAL) otherwise no gap in DCI transmission
       *
       * XXX During repetitions of DCI or NDLSCH we receive no schedule_response form MAC
1400 1401
       *
       */
1402

1403
      //this should give only 1 result (since only 1 ndlsch procedure is activated at once) so we brak after the transmission
1404
      for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX_NB_IoT; UE_id++)
1405
      {
1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431
        if(eNB->ndlsch[(uint8_t)UE_id] != NULL && eNB->ndlsch[(uint8_t)UE_id]->active == 1 && (eNB->ndlsch_SIB1->harq_process->status != ACTIVE_NB_IoT || subframe != 4)) //condition on sib1-NB
        {
          if(frame%2 == 0)//condition on NSSS (subframe 9 not available)
            {
              if( subframe!= 0 && subframe != 5 && subframe != 9)
               {
                npdsch_procedures(eNB,
                                  proc,
                                  eNB->ndlsch[(uint8_t)UE_id],
                                  eNB->ndlsch[(uint8_t)UE_id]->harq_process->pdu);
                break;
                 }
               }
          else //this frame not foresee the transmission of NSSS (subframe 9 is available)
          {
            if( subframe!= 0 && subframe != 5)
               {
                npdsch_procedures(eNB,
                                  proc,
                                  eNB->ndlsch[(uint8_t)UE_id],
                                  eNB->ndlsch[(uint8_t)UE_id]->harq_process->pdu);
                break;

               }
          }
        }
1432

1433

1434
      }
1435 1436


1437 1438 1439
      //no dedicated phy config


1440 1441 1442
      /*If we have DCI to generate do it now
       *
       * DCI in NB-IoT are transmitted over NPDCCH search spaces as described in TS 36.213 ch 16.6
1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456
       *
       * Don-t care about the concept of search space since will be managed by the MAC.
       * MAC also evaluate the starting position of NPDCCH transmission and will send the corresponding scheduling_response
       *
       *
       * The PHY layer should evaluate R (repetitions of DCI) based on:
       *  -L (aggregation level) --> inside the NPDCCH PDU
       *  -Rmax
       *  -DCI subframe repetition number (2 bits) --> inside the NPDCCH PDU
       *  -TS 36.213 Table 16.6/1/2/3
       *
       *
       *  The higher layer parms (Rmax):
       * -npdcch-NumRepetitions (UE-specific) [inside the NPDCCH UE-specific strucuture] --> configured through phyconfigDedicated
1457
       * -npdcch-NumRepetitionPaging (common)
1458
       * -npdcch-NumRepetitions-RA (common) [inside the NB_IoT_DL_FRAME_PARMS-> nprach_ParametersList] --> configured in phy_config_sib2
1459
       *
1460
       *  PROBLEM: in FAPI specs seems there is no way to trasnmit Rmax to the PHY (waiting for answers)
1461
       *
1462
       * *Rmax is also needed for evaluate the scheduling delay for NDLSCH (see scheduling delay field in NPDCCH PDU FAPI)
1463
       *
1464 1465 1466 1467 1468
       * *Scrambling re-initialization is needed at the beginning of the Search Space or every 4th NPDCCH subframe (See TS 36.211)
       * (this is taken in cosideration by the NPDCCH parameter "scrambling re-initialization batch index" in FAPI specs (Table 4-45)
       *
       ****whenever we have aggregation level = 1 for UE-specific the R is always = 1 (see table 16.6-1)
       ****DCI DL transmission should not happen in case of reference signals or SI messages (this function should be triggered every subframe)
1469 1470 1471
       *
       * */

1472

1473
      for(UE_id = 0 ; UE_id < NUMBER_OF_UE_MAX_NB_IoT; UE_id++)
1474
      {
1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507
        if(eNB->npdcch[(uint8_t)UE_id] != NULL && eNB->npdcch[(uint8_t)UE_id]->rnti == dci_pdu->dci_alloc->rnti && (eNB->ndlsch_SIB1->harq_process->status != ACTIVE_NB_IoT || subframe != 4))
        {
            if(frame%2 == 0)//condition on NSSS (subframe 9 not available)
              {
                if( subframe!= 0 && subframe != 5 && subframe != 9)
                 {

                  generate_dci_top_NB_IoT(eNB->npdcch[(uint8_t)UE_id],
                                          dci_pdu->Num_dci,
                                          dci_pdu->dci_alloc,
                                          AMP,
                                          fp,
                                          eNB->common_vars.txdataF[0],
                                          subframe,
                                          dci_pdu->npdcch_start_symbol); //this parameter depends by eutraControlRegionSize (see TS36.213 16.6.1)
                                          eNB->npdcch[(uint8_t)UE_id]->repetition_idx++; //can do also inside also the management

                  break;
                 }
              }
          else //this frame not foresee the transmission of NSSS (subframe 9 is available)
             {
             if( subframe!= 0 && subframe != 5)
              {
                generate_dci_top_NB_IoT(eNB->npdcch[(uint8_t)UE_id],
                                        dci_pdu->Num_dci,
                                        dci_pdu->dci_alloc,
                                        AMP,
                                        fp,
                                        eNB->common_vars.txdataF[0],
                                        subframe,
                                        dci_pdu->npdcch_start_symbol); //this parameter depends by eutraControlRegionSize (see TS36.213 16.6.1)
                
1508
                eNB->npdcch[(uint8_t)UE_id]->repetition_idx++; //can do also inside also the management
1509

1510 1511
              break;
              }
1512

1513 1514 1515
             }
           }
        }
1516

1517 1518
}

1519
uint32_t nprach_procedures_NB_IoT(PHY_VARS_eNB *eNB) {
1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535

  uint32_t estimated_TA; 
  int subframe,frame,frame_mod; 

  
  subframe = eNB->proc.subframe_prach; 
  frame = eNB->proc.frame_prach;

  //printf("frame = %i \n sf = %i\n",frame,subframe); 
  frame_mod = 0;//(frame)%32; 
  //if (subframe==1 && frame_mod==0 && frame!=0){
 if (frame_mod==0 && frame!=0){
    //printf("\n frame_in = %i\n",frame); 
    estimated_TA = RX_NPRACH_NB_IoT(eNB,frame);
    //printf("estim = %i\n",estimated_TA);
  }
1536
  return estimated_TA;
1537
}