phy_procedures_lte_eNb_nb_iot.c 28.8 KB
Newer Older
1

2

3
#include "PHY/defs.h"
Nick Ho's avatar
Nick Ho committed
4
#include "PHY/defs_nb_iot.h"
5 6 7 8 9 10 11 12 13 14
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "SCHED/extern.h"
#include "PHY/LTE_TRANSPORT/if4_tools.h"
#include "PHY/LTE_TRANSPORT/if5_tools.h"

#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif

15 16 17
// for NB-IoT
#include "SCHED/defs_nb_iot.h"

18 19 20 21 22 23 24 25 26 27 28 29
//#define DEBUG_PHY_PROC (Already defined in cmake)
//#define DEBUG_ULSCH

#include "LAYER2/MAC/extern.h"
#include "LAYER2/MAC/defs.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"

#include "T.h"

#include "assertions.h"
#include "msc.h"
30

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
#include <time.h>

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


#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

//#define DIAG_PHY

#define NS_PER_SLOT 500000

#define PUCCH 1

//DCI_ALLOC_t dci_alloc[8];

#ifdef EMOS
fifo_dump_emos_eNB emos_dump_eNB;
#endif

#if defined(SMBV) 
extern const char smbv_fname[];
extern unsigned short config_frames[4];
extern uint8_t smbv_frame_cnt;
#endif

#ifdef DIAG_PHY
extern int rx_sig_fifo;
#endif


68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

/* For NB-IoT, we put NPBCH in later part, since it would be scheduled by MAC scheduler
* It generates NRS/NPSS/NSSS
*
*/
void NB_common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) 
{
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
  int **txdataF = eNB->common_vars.txdataF[0];
  int subframe = proc->subframe_tx;
  int frame = proc->frame_tx;
  uint16_t Ntti = 10;//ntti = 10
  int RB_IoT_ID;// RB reserved for NB-IoT, PRB index
  int With_NSSS;// With_NSSS = 1; if the frame include a sub-Frame with NSSS signal
  
  /*NSSS only happened in the even frame*/
  if(frame%2==0)
    {
      With_NSSS = 1;
    }
  else
    {
      With_NSSS = 0;
    }
    
  /*NPSS when subframe 5*/
  if(subframe == 5)
    {
      generate_npss_NB_IoT(txdataF,
                 AMP,
                 fp,
                 3,
                 0,
                 RB_IoT_ID);
    }
    
  /*NSSS when subframe 9 on even frame*/
Nick Ho's avatar
Nick Ho committed
105
  else if((subframe == 9)&&(With_NSSS == 1))
106
    {
Nick Ho's avatar
Nick Ho committed
107
      generate_sss_NB_IoT(txdataF,
108 109 110 111 112 113 114 115
                          AMP,
                          fp,
                          3,
                          0,
                          frame,
                          RB_IoT_ID);
    }

Nick Ho's avatar
Nick Ho committed
116 117 118 119 120 121 122 123 124 125
  else
  {
    /*NRS*/
    generate_pilots_NB_IoT(eNB,
               txdataF,
               AMP,
               Ntti,
               RB_IoT_ID,
               With_NSSS);
  }
126 127 128
  
}

Nick Ho's avatar
Nick Ho committed
129
void NB_phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,UL_IND_t *UL_INFO)
130 131
{
  //RX processing for ue-specific resources (i
132

133
  uint32_t ret=0,i,j,k;
134
  uint32_t harq_pid,round;
135 136 137 138 139 140 141 142 143 144
  int sync_pos;
  uint16_t rnti=0;
  uint8_t access_mode;
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;

  const int subframe = proc->subframe_rx;
  const int frame    = proc->frame_rx;
  
  /*NB-IoT IF module Common setting*/

Nick Ho's avatar
Nick Ho committed
145 146 147 148
  UL_INFO->module_id = eNB->Mod_id;
  UL_INFO->CC_id = eNB->CC_id;
  UL_INFO->frame =  frame;
  UL_INFO->subframe = subframe;
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


  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),
    T_BUFFER(&eNB->common_vars.rxdata[0][0][subframe*eNB->frame_parms.samples_per_tti],
             eNB->frame_parms.samples_per_tti * 4));

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


  //check if any RB using in this UL subframe
  eNB->rb_mask_ul[0]=0;
  eNB->rb_mask_ul[1]=0;
  eNB->rb_mask_ul[2]=0;
  eNB->rb_mask_ul[3]=0;

  // 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.
  harq_pid = subframe2harq_pid(fp,frame,subframe);

  // delete the cba
  // delete the srs
  
  /*Loop over the UE, i is the UE ID */
174 175
  for (i=0; i<NUMBER_OF_UE_MAX; i++) 
    {
176

177 178 179 180 181 182 183 184 185 186 187 188
      // delete srs 
      // delete Pucch procedure

      // check for Msg3
      if (eNB->mac_enabled==1) 
        {
          if (eNB->UE_stats[i].mode == RA_RESPONSE) 
            {
	             /*Process Msg3 TODO*/
              //process_Msg3(eNB,proc,i,harq_pid);
            }
        }
189

190 191 192
      eNB->pusch_stats_rb[i][(frame*10)+subframe] = -63;
      eNB->pusch_stats_round[i][(frame*10)+subframe] = 0;
      eNB->pusch_stats_mcs[i][(frame*10)+subframe] = -63;
193

194 195 196 197 198 199 200 201 202 203 204 205 206
      /*Check if this UE is has ULSCH scheduling*/
      if ((eNB->ulsch[i]) &&
          (eNB->ulsch[i]->rnti>0) &&
          (eNB->ulsch[i]->harq_processes[harq_pid]->subframe_scheduling_flag==1)) 
        {
          // UE is has ULSCH scheduling
          round = eNB->ulsch[i]->harq_processes[harq_pid]->round;
          /*NB-IoT The nb_rb always set to 1 */
          for (int rb=0;rb<=eNB->ulsch[i]->harq_processes[harq_pid]->nb_rb;rb++) 
            {
	           int rb2 = rb+eNB->ulsch[i]->harq_processes[harq_pid]->first_rb;
              eNB->rb_mask_ul[rb2>>5] |= (1<<(rb2&31));
            }
207

208
          /*Log for what kind of the ULSCH Reception*/
209

210 211
          /*Calculate for LTE C-RS*/
          //nPRS = fp->pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe<<1];
212

213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
          //eNB->ulsch[i]->cyclicShift = (eNB->ulsch[i]->harq_processes[harq_pid]->n_DMRS2 + fp->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift +nPRS)%12;

          if (fp->frame_type == FDD ) 
            {
              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 */
              if (eNB->dlsch[i][0]->subframe_tx[sf]>0) // we have downlink transmission
                { 
                  eNB->ulsch[i]->harq_processes[harq_pid]->O_ACK = 1;
                } 
              else 
                {
                  eNB->ulsch[i]->harq_processes[harq_pid]->O_ACK = 0;
                }
            }
228

229 230 231
          eNB->pusch_stats_rb[i][(frame*10)+subframe] = eNB->ulsch[i]->harq_processes[harq_pid]->nb_rb;
          eNB->pusch_stats_round[i][(frame*10)+subframe] = eNB->ulsch[i]->harq_processes[harq_pid]->round;
          eNB->pusch_stats_mcs[i][(frame*10)+subframe] = eNB->ulsch[i]->harq_processes[harq_pid]->mcs;
232

233 234 235 236 237
          rx_ulsch(eNB,proc,
                  eNB->UE_stats[i].sector,  // this is the effective sector id
                  i,
                  eNB->ulsch,
                  0);
238

239
          ret = ulsch_decoding(eNB,proc,
240 241 242
                             i,
                             0, // control_only_flag
                             eNB->ulsch[i]->harq_processes[harq_pid]->V_UL_DAI,
243
			                       eNB->ulsch[i]->harq_processes[harq_pid]->nb_rb>20 ? 1 : 0);
244

245 246 247 248 249 250 251 252 253 254 255 256 257
          //compute the expected ULSCH RX power (for the stats)
          eNB->ulsch[(uint32_t)i]->harq_processes[harq_pid]->delta_TF = get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0); // 0 means bw_factor is not considered
          eNB->UE_stats[i].ulsch_decoding_attempts[harq_pid][eNB->ulsch[i]->harq_processes[harq_pid]->round]++;
          eNB->ulsch[i]->harq_processes[harq_pid]->subframe_scheduling_flag=0;
          if (eNB->ulsch[i]->harq_processes[harq_pid]->cqi_crc_status == 1) 
            {
              extract_CQI(eNB->ulsch[i]->harq_processes[harq_pid]->o,
                        eNB->ulsch[i]->harq_processes[harq_pid]->uci_format,
                        &eNB->UE_stats[i],
                      fp->N_RB_DL,
                      &rnti, &access_mode);
              eNB->UE_stats[i].rank = eNB->ulsch[i]->harq_processes[harq_pid]->o_RI[0];
            }
258

259 260 261 262
          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->ulsch[i]->rnti),
                T_INT(harq_pid));
263

264 265 266 267
              eNB->UE_stats[i].ulsch_round_errors[harq_pid][eNB->ulsch[i]->harq_processes[harq_pid]->round]++;
              eNB->ulsch[i]->harq_processes[harq_pid]->phich_active = 1;
              eNB->ulsch[i]->harq_processes[harq_pid]->phich_ACK = 0;
              eNB->ulsch[i]->harq_processes[harq_pid]->round++;
268

269
              LOG_D(PHY,"[eNB][PUSCH %d] Increasing to round %d\n",harq_pid,eNB->ulsch[i]->harq_processes[harq_pid]->round);
270

271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
          if (eNB->ulsch[i]->Msg3_flag == 1) 
            {
	           /*dump_ulsch(eNB,proc,i);
	             exit(-1);*/

            /*In NB-IoT MSG3 */
            // activate retransmission for Msg3 (signalled to UE PHY by DCI
            eNB->ulsch[(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->ulsch[i]->rnti), T_INT(0 /* 0 is for retransmission*/),
                  T_INT(eNB->ulsch[i]->Msg3_frame), T_INT(eNB->ulsch[i]->Msg3_subframe));     
            } // This is Msg3 error
          else 
            { //normal ULSCH
289
              if (eNB->ulsch[i]->harq_processes[harq_pid]->round== eNB->ulsch[i]->Mlimit) 
290
                {
291 292 293
                  eNB->ulsch[i]->harq_processes[harq_pid]->round=0;
                  eNB->ulsch[i]->harq_processes[harq_pid]->phich_active=0;
                  eNB->UE_stats[i].ulsch_errors[harq_pid]++;
294 295 296
                  eNB->UE_stats[i].ulsch_consecutive_errors++; 
                  /*if (eNB->ulsch[i]->harq_processes[harq_pid]->nb_rb > 20) {
		                dump_ulsch(eNB,proc,i);
297
	 	              exit(-1);
298 299 300
                  }*/
	                // indicate error to MAC
	                if (eNB->mac_enabled == 1)
301
                    {
302
                      //instead rx_sdu to report The Uplink data not received successfully to MAC
Nick Ho's avatar
Nick Ho committed
303 304 305 306 307 308 309
                      (UL_INFO->crc_ind.crc_pdu_list+i)->crc_indication_rel8.crc_flag= 1;
                       UL_INFO->crc_ind.number_of_crcs++;
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.rnti= eNB->ulsch[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;
                       UL_INFO->RX_NPUSCH.number_of_pdus++;
310
                    }
311 312 313 314 315 316 317
                }
            }
        }  // ulsch in error
        else 
          {
            T(T_ENB_PHY_ULSCH_UE_ACK, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(i), T_INT(eNB->ulsch[i]->rnti),
              T_INT(harq_pid));
318

319
          // Delete MSG3  log for the PHICH 
320

321
          for (j=0; j<fp->nb_antennas_rx; j++)
322 323 324 325 326 327 328 329
          //this is the RSSI per RB
          eNB->UE_stats[i].UL_rssi[j] =
            dB_fixed(eNB->pusch_vars[i]->ulsch_power[j]*
                     (eNB->ulsch[i]->harq_processes[harq_pid]->nb_rb*12)/
                     fp->ofdm_symbol_size) -
            eNB->rx_total_gain_dB -
            hundred_times_log10_NPRB[eNB->ulsch[i]->harq_processes[harq_pid]->nb_rb-1]/100 -
            get_hundred_times_delta_IF_eNB(eNB,i,harq_pid, 0)/100;
330 331 332 333 334
          //for NB-IoT PHICH not work
	        /*eNB->ulsch[i]->harq_processes[harq_pid]->phich_active = 1;
          eNB->ulsch[i]->harq_processes[harq_pid]->phich_ACK = 1;*/
          eNB->ulsch[i]->harq_processes[harq_pid]->round = 0;
          eNB->UE_stats[i].ulsch_consecutive_errors = 0;
335

336
          if (eNB->ulsch[i]->Msg3_flag == 1) 
337
            {
338 339 340 341 342 343 344
	            if (eNB->mac_enabled==1) 
                {
	                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)
                    {
                      // store successful MSG3 in UL_Info instead rx_sdu
Nick Ho's avatar
Nick Ho committed
345 346 347 348 349 350 351
                      (UL_INFO->crc_ind.crc_pdu_list+i)->crc_indication_rel8.crc_flag= 0;
                      UL_INFO->crc_ind.number_of_crcs++;
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.rnti= eNB->ulsch[i]->rnti;
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->data = eNB->ulsch[i]->harq_processes[harq_pid]->b;
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_indication_rel8.length = eNB->ulsch[i]->harq_processes[harq_pid]->TBS>>3;
                      (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.harq_pid = harq_pid;
                      UL_INFO->RX_NPUSCH.number_of_pdus++;
352
                    }
353

354 355 356 357 358 359 360 361 362 363 364
	                /* 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*/
365
	    
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
	            } // mac_enabled==1

            eNB->UE_stats[i].mode = PUSCH;
            eNB->ulsch[i]->Msg3_flag = 0;

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

            /*Init HARQ parameters, need to check*/
            for (k=0; k<8; k++) 
              { //harq_processes
                for (j=0; j<eNB->dlsch[i][0]->Mlimit; j++) 
                  {
                    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;
                  }

                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;

                for (j=0; j<eNB->ulsch[i]->Mlimit; j++) 
                  {
                    eNB->UE_stats[i].ulsch_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;
                  }
              }
395

396 397 398 399 400 401 402
            eNB->UE_stats[i].dlsch_sliding_cnt=0;
            eNB->UE_stats[i].dlsch_NAK_round0=0;
            eNB->UE_stats[i].dlsch_mcs_offset=0;
          } // Msg3_flag==1
	       else 
          {  // Msg3_flag == 0
	          if (eNB->mac_enabled==1) 
403 404
              {
                  // store successful Uplink data in UL_Info instead rx_sdu
Nick Ho's avatar
Nick Ho committed
405 406 407 408 409 410 411
                  (UL_INFO->crc_ind.crc_pdu_list+i)->crc_indication_rel8.crc_flag= 0;
                  UL_INFO->crc_ind.number_of_crcs++;
                  (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.rnti= eNB->ulsch[i]->rnti;
                  (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->data = eNB->ulsch[i]->harq_processes[harq_pid]->b;
                  (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_indication_rel8.length = eNB->ulsch[i]->harq_processes[harq_pid]->TBS>>3;
                  (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.harq_pid  = harq_pid;
                  UL_INFO->RX_NPUSCH.number_of_pdus++;
412
	    
413 414
	            } // mac_enabled==1
          } // Msg3_flag == 0
415

416
            // estimate timing advance for MAC
417 418 419 420 421
              sync_pos = lte_est_timing_advance_pusch(eNB,i);
              eNB->UE_stats[i].timing_advance_update = sync_pos - fp->nb_prefix_samples/4; //to check

      }  // ulsch not in error

422

423
      // Process HARQ only in NPUSCH
Nick Ho's avatar
Nick Ho committed
424
      /*process_HARQ_feedback(i,
425 426 427 428
                            eNB,proc,
                            1, // pusch_flag
                            0,
                            0,
Nick Ho's avatar
Nick Ho committed
429
                            0);*/
430

431

432 433
      

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

436 437 438 439 440 441

    // update ULSCH statistics for tracing




442
  } // loop i=0 ... NUMBER_OF_UE_MAX-1
443 444 445 446 447

}

#undef DEBUG_PHY_PROC

Nick Ho's avatar
Nick Ho committed
448 449 450 451
/*Generate eNB dlsch params for NB-IoT, modify the input to the Sched Rsp variable*/

void NB_generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t * proc,Sched_Rsp_t *Sched_Rsp,const int UE_id) 
{
452
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
Nick Ho's avatar
Nick Ho committed
453
  int frame = proc->frame_tx;
454
  int subframe = proc->subframe_tx;
455
  DCI_CONTENT DCI_Content[2]; //max number of DCI in a single subframe = 2 (may put this as a global variable)
456

457
  //DCI_Content = (DCI_CONTENT*) malloc(sizeof(DCI_CONTENT));
Nick Ho's avatar
Nick Ho committed
458 459

  // In NB-IoT, there is no DCI for SI, we might use the scheduling infomation from SIB1-NB to get the phyical layer configuration.
460 461 462

  //mapping the fapi parameters to the oai parameters

463
  for (int i = 0; i< Sched_Rsp->NB_DL.NB_DCI.DL_DCI.number_dci; i++){
464 465 466
  switch (Sched_Rsp->NB_DL.NB_DCI.DCI_Format){
    case DCIFormatN1_RAR:
      //DCI format N1 to RAR
Nick Ho's avatar
Nick Ho committed
467
      DCI_Content[i].DCIN1_RAR.type = 1;
468
      //check if this work
Nick Ho's avatar
Nick Ho committed
469 470 471 472 473 474 475
      DCI_Content[i].DCIN1_RAR.orderIndicator = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.npdcch_order_indication;
      DCI_Content[i].DCIN1_RAR.Scheddly = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.scheduling_delay;
      DCI_Content[i].DCIN1_RAR.ResAssign = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.resource_assignment;
      DCI_Content[i].DCIN1_RAR.mcs = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.mcs;
      DCI_Content[i].DCIN1_RAR.ndi = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.new_data_indicator;
      DCI_Content[i].DCIN1_RAR.HARQackRes = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.harq_ack_resource;
      DCI_Content[i].DCIN1_RAR.DCIRep = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.dci_subframe_repetition_number;
476

Nick Ho's avatar
Nick Ho committed
477 478 479
      // configure dlsch parameters and CCE index
      LOG_D(PHY,"Generating dlsch params for RA_RNTI\n");

Nick Ho's avatar
Nick Ho committed
480 481
      NB_generate_eNB_dlsch_params_from_dci(eNB,
                                            frame,
482
                                            subframe,
Nick Ho's avatar
Nick Ho committed
483
											                      &DCI_Content[i],
484
                                            Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list->npdcch_pdu.npdcch_pdu_rel13.rnti,
485 486 487
                                            DCIFormatN1_RAR,
                                            &eNB->dlsch_ra,
                                            fp,
488 489
                                            Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list->npdcch_pdu.npdcch_pdu_rel13.aggregation_level,
											Sched_Rsp->NB_DL.NB_DCI.DL_DCI.number_dci
490 491 492 493
                                            );
      break;
    case DCIFormatN1:
      //DCI format N1 to DLSCH
Nick Ho's avatar
Nick Ho committed
494 495 496 497 498 499 500 501 502 503 504
    	 DCI_Content[i].DCIN1_RAR.type = 1;
    	 DCI_Content[i].DCIN1_RAR.orderIndicator = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.npdcch_order_indication;
    	 DCI_Content[i].DCIN1_RAR.Scheddly = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.scheduling_delay;
    	 DCI_Content[i].DCIN1_RAR.ResAssign = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.resource_assignment;
    	 DCI_Content[i].DCIN1_RAR.mcs = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.mcs;
    	 DCI_Content[i].DCIN1_RAR.ndi = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.new_data_indicator;
    	 DCI_Content[i].DCIN1_RAR.HARQackRes = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.harq_ack_resource;
    	 DCI_Content[i].DCIN1_RAR.DCIRep = Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.dci_subframe_repetition_number;

      NB_generate_eNB_dlsch_params_from_dci(eNB,
                                            frame,
505
                                            subframe,
Nick Ho's avatar
Nick Ho committed
506
											                      &DCI_Content[i],
507
                                            Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list->npdcch_pdu.npdcch_pdu_rel13.rnti,
508 509 510
                                            DCIFormatN0,
                                            eNB->dlsch[(uint8_t)UE_id],
                                            fp,
511 512
                                            Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list->npdcch_pdu.npdcch_pdu_rel13.aggregation_level,
                                            Sched_Rsp->NB_DL.NB_DCI.DL_DCI.number_dci
513 514
                                            );
      break;
515 516 517 518 519 520
    /*TODO reserve for the N2 DCI*/
    case DCIFormatN2_Pag:
    	LOG_I(PHY, "Paging is not implemented, DCIFormatN2_Pag cannot be elaborated\n");
    	break;

  }
521 522 523

  }

Nick Ho's avatar
Nick Ho committed
524 525 526 527 528 529 530


  
}

void NB_generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,Sched_Rsp_t *Sched_Rsp,const int UE_id) {

531
  int harq_pid = 0;
Nick Ho's avatar
Nick Ho committed
532

533 534 535 536
  DCI_CONTENT DCI_Content[2]; //max number of DCI in a single subframe = 2 (may put this as a global variable)

  for(int i = 0; i<Sched_Rsp->NB_DL.NB_DCI.UL_DCI.number_of_dci; i++)
  {
537 538

  //mapping the fapi parameters to the OAI parameters
Nick Ho's avatar
Nick Ho committed
539 540 541 542 543 544 545 546 547
  DCI_Content[i].DCIN0.type = 0;
  DCI_Content[i].DCIN0.scind = Sched_Rsp->NB_DL.NB_DCI.UL_DCI.hi_dci0_pdu_list[i].npdcch_dci_pdu.npdcch_dci_pdu_rel13.subcarrier_indication;
  DCI_Content[i].DCIN0.ResAssign = Sched_Rsp->NB_DL.NB_DCI.UL_DCI.hi_dci0_pdu_list[i].npdcch_dci_pdu.npdcch_dci_pdu_rel13.subcarrier_indication;
  DCI_Content[i].DCIN0.mcs = Sched_Rsp->NB_DL.NB_DCI.UL_DCI.hi_dci0_pdu_list[i].npdcch_dci_pdu.npdcch_dci_pdu_rel13.mcs;
  DCI_Content[i].DCIN0.ndi = Sched_Rsp->NB_DL.NB_DCI.UL_DCI.hi_dci0_pdu_list[i].npdcch_dci_pdu.npdcch_dci_pdu_rel13.new_data_indicator;
  DCI_Content[i].DCIN0.Scheddly = Sched_Rsp->NB_DL.NB_DCI.UL_DCI.hi_dci0_pdu_list[i].npdcch_dci_pdu.npdcch_dci_pdu_rel13.scheduling_delay;
  DCI_Content[i].DCIN0.RepNum = Sched_Rsp->NB_DL.NB_DCI.UL_DCI.hi_dci0_pdu_list[i].npdcch_dci_pdu.npdcch_dci_pdu_rel13.repetition_number;
  DCI_Content[i].DCIN0.rv = Sched_Rsp->NB_DL.NB_DCI.UL_DCI.hi_dci0_pdu_list[i].npdcch_dci_pdu.npdcch_dci_pdu_rel13.redudancy_version;
  DCI_Content[i].DCIN0.DCIRep = Sched_Rsp->NB_DL.NB_DCI.UL_DCI.hi_dci0_pdu_list[i].npdcch_dci_pdu.npdcch_dci_pdu_rel13.dci_subframe_repetition_number;
548 549


Nick Ho's avatar
Nick Ho committed
550 551
  /*Log for generate ULSCH DCI*/

552 553
  NB_generate_eNB_ulsch_params_from_dci(eNB,
                                        proc,
Nick Ho's avatar
Nick Ho committed
554
                                        &DCI_Content[i],
555
                                        Sched_Rsp->NB_DL.NB_DCI.UL_DCI.hi_dci0_pdu_list->npdcch_dci_pdu.npdcch_dci_pdu_rel13.rnti,
556 557
                                        DCIFormatN0,
                                        UE_id,
558 559
                                        Sched_Rsp->NB_DL.NB_DCI.UL_DCI.hi_dci0_pdu_list->npdcch_dci_pdu.npdcch_dci_pdu_rel13.aggregation_level,
										Sched_Rsp->NB_DL.NB_DCI.UL_DCI.number_of_dci
560 561
                                        );  

Nick Ho's avatar
Nick Ho committed
562 563 564
  
  //LOG for ULSCH DCI Resource allocation
  
565 566 567 568
  //CBA is not used in NB-IoT
//  if ((Sched_Rsp->NB_DL.NB_DCI.UL_DCI.npdcch_dci_pdu_rel13.rnti  >= CBA_RNTI) && (Sched_Rsp->NB_DL.NB_DCI.UL_DCI.npdcch_dci_pdu_rel13.rnti < P_RNTI))
//    eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1;
//  else
Nick Ho's avatar
Nick Ho committed
569 570
    eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
  
571
  }
Nick Ho's avatar
Nick Ho committed
572 573
}

574

Nick Ho's avatar
Nick Ho committed
575

576
extern int oai_exit;
577 578 579 580

/*
r_type, rn is only used in PMCH procedure so I remove it.
*/
581
void NB_phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
582
         eNB_rxtx_proc_NB_t *proc,
583 584
         int do_meas)
{
585 586
  int frame = proc->frame_tx;
  int subframe = proc->subframe_tx;
587
  uint32_t i,aa;
588
  uint8_t harq_pid;
589 590
  //DCI_PDU_NB *DCI_pdu;
  //DCI_PDU_NB DCI_pdu_tmp;
591
  LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms;
592
  // DCI_ALLOC_t *dci_alloc = (DCI_ALLOC_t *)NULL;
593 594 595
  int8_t UE_id = 0;
  uint8_t ul_subframe;
  uint32_t ul_frame;
Nick Ho's avatar
Nick Ho committed
596 597 598

  int **txdataF = eNB->common_vars.txdataF[0];

599
  //uint8_t num_npdcch_symbols = 0;
600 601 602

  //for NB-IoT

Nick Ho's avatar
Nick Ho committed
603
  Sched_Rsp_t *Sched_Rsp;
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629

  if(do_meas == 1)
    start_meas(&eNB->phy_proc_tx);

  for(i = 0;i<NUMBER_OF_UE_MAX;i++)
    {
      if((frame==0)&&(subframe==0))
        {
          if(eNB->UE_stats[i].crnti > 0)
              LOG_I(PHY,"UE%d : rnti %x\n",i,eNB->UE_stats[i].crnti);
        }
    }

  // Original scheduler 

  // clear the transmit data array for the current subframe

  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));
    } 


  while(!oai_exit)
    {
630 631
	  //ignore the PMCH part only do the generate PSS/SSS, note: Seperate MIB from here
	  NB_common_signal_procedures(eNB,proc);
632

633
        //Not test yet , mutex_l2, cond_l2, instance_cnt_l2
Nick Ho's avatar
Nick Ho committed
634
        //cond_l2 should be given by sched_rsp after the scheduling
635
        if(wait_on_condition(&proc->mutex_l2,&proc->cond_l2,&proc->instance_cnt_l2,"eNB_L2_thread") < 0) 
636
        break;
637 638 639 640

      /*Take the structures from the shared structures*/
      //Sched_Rsp = ;

Nick Ho's avatar
Nick Ho committed
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
      /*
      broadcast channel for n-FAPI style
      pdu length - 14 (bytes)
      pdu index - 1 
      num segments -1
      segment length 5 bytes
      segment data  34 bits (5 bytes)
      */

      if((subframe==0) && (Sched_Rsp->NB_DL.NB_BCH.MIB_pdu.segments[0].segment_data)!=NULL)
        {
          generate_npbch(&eNB->npbch,
                         txdataF,
                         AMP,
                         fp,
                         &Sched_Rsp->NB_DL.NB_BCH.MIB_pdu.segments[0].segment_data,
657
                         frame%64,
Nick Ho's avatar
Nick Ho committed
658 659 660 661
                         fp->NB_IoT_RB_ID // iD of the resource block may be passed by the config request (phy config structure)
                         );
        }

662 663 664 665 666
      /*clear the existing ulsch dci allocations before applying info from MAC*/
      ul_subframe = (subframe+4)%10;
      ul_frame = frame+(ul_subframe >= 6 ? 1 :0);
      harq_pid = ((ul_frame<<1)+ul_subframe)&7;

667 668 669 670 671

      // check for BCCH
      //rnti_type = 0 BCCH information
      //rnti_type = 1 Other
      if(Sched_Rsp->NB_DL.NB_DLSCH.ndlsch.rnti_type == 0)
Nick Ho's avatar
Nick Ho committed
672
        {
673
            /*TODO: NPDSCH procedures for BCCH for NB-IoT*/
Nick Ho's avatar
Nick Ho committed
674
            //npdsch_procedures_NB();
Nick Ho's avatar
Nick Ho committed
675 676
        }

677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693
      /*clear the DCI allocation maps for new subframe*/
      for(i=0;i<NUMBER_OF_UE_MAX;i++)
        {
          if(eNB->ulsch[i])
            {
              eNB->ulsch[i]->harq_processes[harq_pid]->dci_alloc = 0;
              eNB->ulsch[i]->harq_processes[harq_pid]->rar_alloc = 0;
            }
        }

      /*clear previous allocation information for all UEs*/
      for(i=0;i<NUMBER_OF_UE_MAX;i++)
        {
          if(eNB->dlsch[i][0])
            eNB->dlsch[i][0]->subframe_tx[subframe]=0;
        }

Nick Ho's avatar
Nick Ho committed
694
   if(Sched_Rsp->NB_DL.NB_DCI.DL_DCI.number_dci+Sched_Rsp->NB_DL.NB_DCI.UL_DCI.number_of_dci > 0)
695
    {
696

Nick Ho's avatar
Nick Ho committed
697
      /*Loop over all the dci to generate DLSCH allocation, there is only 1 or 2 DCIs for NB-IoT in the same time*/
Nick Ho's avatar
Nick Ho committed
698
      // Add dci fapi structure for contain two dcis
Nick Ho's avatar
Nick Ho committed
699
      /*Also Packed the DCI here*/
700 701
      for(int i= 0; i< Sched_Rsp->NB_DL.NB_DCI.DL_DCI.number_dci; i++)
      {
Nick Ho's avatar
Nick Ho committed
702
      if (Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.rnti<= P_RNTI)
703
        {
704 705
    	  //is not system iformation but cound be paging
    	  //in any case we generate dlsch for not system information
Nick Ho's avatar
Nick Ho committed
706
          UE_id = find_ue((int16_t)Sched_Rsp->NB_DL.NB_DCI.DL_DCI.dl_config_pdu_list[i].npdcch_pdu.npdcch_pdu_rel13.rnti,eNB);
707 708 709 710
        }
      else 
        UE_id=0;
    
711
      //inside we have nFAPI to OAI parameters
Nick Ho's avatar
Nick Ho committed
712
      NB_generate_eNB_dlsch_params(eNB,proc,Sched_Rsp,UE_id);
713
      
714 715
      }

716 717 718
      /* Apply physicalConfigDedicated if needed, don't know if needed in NB-IoT or not
       This is for UEs that have received this IE, which changes these DL and UL configuration, we apply after a delay for the eNodeB UL parameters
      phy_config_dedicated_eNB_step2(eNB);*/
719

720 721 722
      for (int i = 0; Sched_Rsp->NB_DL.NB_DCI.UL_DCI.number_of_dci; i ++)
      {

723
      if (Sched_Rsp->NB_DL.NB_DCI.DCI_Format == DCIFormatN0) // this is a ULSCH allocation
724
        {  
Nick Ho's avatar
Nick Ho committed
725
          UE_id = find_ue((int16_t)Sched_Rsp->NB_DL.NB_DCI.UL_DCI.hi_dci0_pdu_list[i].npdcch_dci_pdu.npdcch_dci_pdu_rel13.rnti,eNB);
Nick Ho's avatar
Nick Ho committed
726
          NB_generate_eNB_ulsch_params(eNB,proc,Sched_Rsp,UE_id);
727
        }
728

729 730 731 732
      }

      /*If we have DCI to generate do it now TODO : have a generate dci top for NB_IoT */
      //to be modified but inside we have the nuew function for dci transmission
Nick Ho's avatar
Nick Ho committed
733
      //generate_dci_top_NB();
734 735 736 737 738 739 740 741 742 743 744 745 746 747 748

    }

      //now we should check if Sched_Rsp contains data
      //rnti_type = 0 BCCH information
      //rnti_type = 1 Other
      if(Sched_Rsp->NB_DL.NB_DLSCH.ndlsch.rnti_type != 0)
      {

    	  //we not need between RAR PDUS
              /*TODO: NPDSCH procedures for BCCH for NB-IoT*/
              //npdsch_procedures();
      }


749

750

751

752
    }
753
}