phy_procedures_lte_eNb.c 105 KB
Newer Older
1

2
/*******************************************************************************
3
    OpenAirInterface
ghaddab's avatar
ghaddab committed
4
    Copyright(c) 1999 - 2014 Eurecom
5

ghaddab's avatar
ghaddab committed
6 7 8 9
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
10 11


ghaddab's avatar
ghaddab committed
12 13 14 15
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
16

ghaddab's avatar
ghaddab committed
17
    You should have received a copy of the GNU General Public License
18 19
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
ghaddab's avatar
ghaddab committed
20
   see <http://www.gnu.org/licenses/>.
21 22

  Contact Information
ghaddab's avatar
ghaddab committed
23 24
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
25
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
26

ghaddab's avatar
ghaddab committed
27
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
28

29
*******************************************************************************/
30 31 32

/*! \file phy_procedures_lte_eNB.c
 * \brief Implementation of eNB procedures from 36.213 LTE specifications
33
 * \author R. Knopp, F. Kaltenberger, N. Nikaein
34 35 36
 * \date 2011
 * \version 0.1
 * \company Eurecom
37
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr,navid.nikaein@eurecom.fr
38 39 40 41 42 43 44 45 46
 * \note
 * \warning
 */

#include "PHY/defs.h"
#include "PHY/extern.h"
#include "SCHED/defs.h"
#include "SCHED/extern.h"

47
#include "PHY/LTE_TRANSPORT/if4_tools.h"
Sandeep Kumar's avatar
Sandeep Kumar committed
48
#include "PHY/LTE_TRANSPORT/if5_tools.h"
49

50 51 52 53
#ifdef EMOS
#include "SCHED/phy_procedures_emos.h"
#endif

54
//#define DEBUG_PHY_PROC (Already defined in cmake)
55 56 57 58 59 60 61
//#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"

62 63
#include "T.h"

64
#include "assertions.h"
gauthier's avatar
gauthier committed
65
#include "msc.h"
66

67 68
#include <time.h>

69
#if defined(ENABLE_ITTI)
gauthier's avatar
For RAL  
gauthier committed
70
#   include "intertask_interface.h"
71 72
#endif

73 74 75 76 77 78
//#define DIAG_PHY

#define NS_PER_SLOT 500000

#define PUCCH 1

79 80
void exit_fun(const char* s);

81 82
extern int exit_openair;

83 84
// Fix per CC openair rf/if device update
// extern openair0_device openair0;
85

86 87 88
unsigned char dlsch_input_buffer[2700] __attribute__ ((aligned(32)));
int eNB_sync_buffer0[640*6] __attribute__ ((aligned(32)));
int eNB_sync_buffer1[640*6] __attribute__ ((aligned(32)));
89 90
int *eNB_sync_buffer[2] = {eNB_sync_buffer0, eNB_sync_buffer1};

91
extern uint16_t hundred_times_log10_NPRB[100];
92

93
unsigned int max_peak_val;
94
int max_sync_pos;
95 96 97 98 99 100 101

//DCI_ALLOC_t dci_alloc[8];

#ifdef EMOS
fifo_dump_emos_eNB emos_dump_eNB;
#endif

102
#if defined(SMBV) 
103 104
extern const char smbv_fname[];
extern unsigned short config_frames[4];
gauthier's avatar
gauthier committed
105
extern uint8_t smbv_frame_cnt;
106 107 108 109 110 111
#endif

#ifdef DIAG_PHY
extern int rx_sig_fifo;
#endif

knopp's avatar
knopp committed
112
uint8_t is_SR_subframe(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id)
113
{
knopp's avatar
 
knopp committed
114

115 116
  const int subframe = proc->subframe_rx;
  const int frame = proc->frame_rx;
117

118
  LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking for SR TXOp(sr_ConfigIndex %d)\n",
119 120
        eNB->Mod_id,eNB->ulsch[UE_id]->rnti,frame,subframe,
        eNB->scheduling_request_config[UE_id].sr_ConfigIndex);
121

122 123
  if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 4) {        // 5 ms SR period
    if ((subframe%5) == eNB->scheduling_request_config[UE_id].sr_ConfigIndex)
124
      return(1);
125 126
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 14) { // 10 ms SR period
    if (subframe==(eNB->scheduling_request_config[UE_id].sr_ConfigIndex-5))
127
      return(1);
128 129
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 34) { // 20 ms SR period
    if ((10*(frame&1)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-15))
130
      return(1);
131 132
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 74) { // 40 ms SR period
    if ((10*(frame&3)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-35))
133
      return(1);
134 135
  } else if (eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 154) { // 80 ms SR period
    if ((10*(frame&7)+subframe) == (eNB->scheduling_request_config[UE_id].sr_ConfigIndex-75))
136
      return(1);
137 138 139 140
  }

  return(0);
}
141

142

143
int32_t add_ue(int16_t rnti, PHY_VARS_eNB *eNB)
144
{
gauthier's avatar
gauthier committed
145
  uint8_t i;
146

147 148

  LOG_D(PHY,"[eNB %d/%d] Adding UE with rnti %x\n",
149 150
        eNB->Mod_id,
        eNB->CC_id,
Cedric Roux's avatar
Cedric Roux committed
151
        (uint16_t)rnti);
152 153

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
154
    if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) {
155
      MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed add ue %"PRIx16" (ENOMEM)", rnti);
156 157
      LOG_E(PHY,"Can't add UE, not enough memory allocated\n");
      return(-1);
158
    } else {
159
      if (eNB->UE_stats[i].crnti==0) {
160
        MSC_LOG_EVENT(MSC_PHY_ENB, "0 Add ue %"PRIx16" ", rnti);
161
        LOG_D(PHY,"UE_id %d associated with rnti %x\n",i, (uint16_t)rnti);
162 163 164
        eNB->dlsch[i][0]->rnti = rnti;
        eNB->ulsch[i]->rnti = rnti;
        eNB->UE_stats[i].crnti = rnti;
knopp's avatar
knopp committed
165

166 167 168
	eNB->UE_stats[i].Po_PUCCH1_below = 0;
	eNB->UE_stats[i].Po_PUCCH1_above = (int32_t)pow(10.0,.1*(eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+eNB->rx_total_gain_dB));
	eNB->UE_stats[i].Po_PUCCH        = (int32_t)pow(10.0,.1*(eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH+eNB->rx_total_gain_dB));
169
	LOG_D(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n",
170 171 172
	      eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
	      eNB->rx_total_gain_dB,
	      eNB->UE_stats[i].Po_PUCCH);
knopp's avatar
knopp committed
173
  
174
        return(i);
175
      }
176
    }
177 178 179 180
  }
  return(-1);
}

181
int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) {
gauthier's avatar
gauthier committed
182
  uint8_t i;
183
  int j,CC_id;
184
  PHY_VARS_eNB *eNB;
185 186

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
187
    eNB = PHY_vars_eNB_g[Mod_idP][CC_id];
188
    for (i=0; i<NUMBER_OF_UE_MAX; i++) {
189
      if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) {
190 191 192 193
	MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (ENOMEM)", rnti);
	LOG_E(PHY,"Can't remove UE, not enough memory allocated\n");
	return(-1);
      } else {
194
	if (eNB->UE_stats[i].crnti==rntiP) {
195
	  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Removed ue %"PRIx16" ", rntiP);
196 197 198

	  LOG_D(PHY,"eNB %d removing UE %d with rnti %x\n",eNB->Mod_id,i,rntiP);

199
	  //LOG_D(PHY,("[PHY] UE_id %d\n",i);
200 201 202 203
	  clean_eNb_dlsch(eNB->dlsch[i][0]);
	  clean_eNb_ulsch(eNB->ulsch[i]);
	  //eNB->UE_stats[i].crnti = 0;
	  memset(&eNB->UE_stats[i],0,sizeof(LTE_eNB_UE_stats));
204 205
	  //  mac_exit_wrapper("Removing UE");
	  
206

207 208
	  return(i);
	}
209
      }
210
    }
211
  }
212
  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (not found)", rntiP);
213 214 215
  return(-1);
}

216
int8_t find_next_ue_index(PHY_VARS_eNB *eNB)
217
{
gauthier's avatar
gauthier committed
218
  uint8_t i;
219

220
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
221 222
    if (eNB->UE_stats[i].crnti==0) {
      /*if ((eNB->dlsch[i]) &&
223 224
	(eNB->dlsch[i][0]) &&
	(eNB->dlsch[i][0]->rnti==0))*/
225 226 227
      LOG_D(PHY,"Next free UE id is %d\n",i);
      return(i);
    }
228
  }
229

230 231 232
  return(-1);
}

gauthier's avatar
gauthier committed
233
int get_ue_active_harq_pid(const uint8_t Mod_id,const uint8_t CC_id,const uint16_t rnti, const int frame, const uint8_t subframe,uint8_t *harq_pid,uint8_t *round,const uint8_t ul_flag)
234 235 236 237
{
  LTE_eNB_DLSCH_t *DLSCH_ptr;
  LTE_eNB_ULSCH_t *ULSCH_ptr;
  uint8_t ulsch_subframe,ulsch_frame;
238
  int i;
knopp's avatar
 
knopp committed
239
  int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
240 241

  if (UE_id==-1) {
242
    LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id);
243 244
    *round=0;
    return(-1);
245 246 247
  }

  if (ul_flag == 0)  {// this is a DL request
248
    DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch[(uint32_t)UE_id][0];
249

250 251
    /* let's go synchronous for the moment - maybe we can change at some point */
    i = (frame * 10 + subframe) % 8;
252

253 254 255 256 257
    if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) {
      *harq_pid = i;
      *round = DLSCH_ptr->harq_processes[i]->round;
    } else if (DLSCH_ptr->harq_processes[i]->status == SCH_IDLE) {
      *harq_pid = i;
258
      *round = 0;
259 260 261
    } else {
      printf("%s:%d: bad state for harq process - PLEASE REPORT!!\n", __FILE__, __LINE__);
      abort();
262
    }
263
  } else { // This is a UL request
264

265 266 267
    ULSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->ulsch[(uint32_t)UE_id];
    ulsch_subframe = pdcch_alloc2ul_subframe(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,subframe);
    ulsch_frame    = pdcch_alloc2ul_frame(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,frame,subframe);
268
    // Note this is for TDD configuration 3,4,5 only
269
    *harq_pid = subframe2harq_pid(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,
270 271
                                  ulsch_frame,
                                  ulsch_subframe);
272
    *round    = ULSCH_ptr->harq_processes[*harq_pid]->round;
273
    LOG_T(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Checking HARQ, round %d\n",Mod_id,*harq_pid,frame,subframe,*round);
274
  }
275

276 277 278
  return(0);
}

knopp's avatar
knopp committed
279
int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
280
{
281
  return PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
282 283
}

knopp's avatar
knopp committed
284 285
int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
{
286
  return PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
knopp's avatar
knopp committed
287 288
}

289
#ifdef EMOS
290
void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *eNB)
291
{
292 293 294 295 296 297

}
#endif



knopp's avatar
knopp committed
298
void phy_procedures_eNB_S_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t abstraction_flag,relaying_type_t r_type)
299 300
{
  UNUSED(r_type);
301
  int subframe = proc->subframe_rx;
302

303
#ifdef DEBUG_PHY_PROC
304
  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_S_RX(%d)\n", eNB->Mod_id,proc->frame_rx, subframe);
305
#endif
306

307

knopp's avatar
 
knopp committed
308
  if (abstraction_flag == 0) {
309
    lte_eNB_I0_measurements(eNB,
310
			    subframe,
311
                            0,
312
                            eNB->first_run_I0_measurements);
knopp's avatar
 
knopp committed
313
  }
314

315
#ifdef PHY_ABSTRACTION
knopp's avatar
 
knopp committed
316
  else {
317
    lte_eNB_I0_measurements_emul(eNB,
318
                                 0);
319
  }
320

knopp's avatar
 
knopp committed
321 322
#endif

323

324 325
}

knopp's avatar
 
knopp committed
326 327


328
#ifdef EMOS
329
void phy_procedures_emos_eNB_RX(unsigned char subframe,PHY_VARS_eNB *eNB)
330 331
{

gauthier's avatar
gauthier committed
332 333
  uint8_t aa;
  uint16_t last_subframe_emos;
334
  uint16_t pilot_pos1 = 3 - eNB->frame_parms.Ncp, pilot_pos2 = 10 - 2*eNB->frame_parms.Ncp;
gauthier's avatar
gauthier committed
335
  uint32_t bytes;
336 337 338

  last_subframe_emos=0;

knopp's avatar
 
knopp committed
339

knopp's avatar
 
knopp committed
340

knopp's avatar
 
knopp committed
341

342
#ifdef EMOS_CHANNEL
343

344
  //if (last_slot%2==1) // this is for all UL subframes
345
  if (subframe==3)
346 347 348 349 350 351 352
    for (aa=0; aa<eNB->frame_parms.nb_antennas_rx; aa++) {
      memcpy(&emos_dump_eNB.channel[aa][last_subframe_emos*2*eNB->frame_parms.N_RB_UL*12],
             &eNB->pusch_vars[0]->drs_ch_estimates[0][aa][eNB->frame_parms.N_RB_UL*12*pilot_pos1],
             eNB->frame_parms.N_RB_UL*12*sizeof(int));
      memcpy(&emos_dump_eNB.channel[aa][(last_subframe_emos*2+1)*eNB->frame_parms.N_RB_UL*12],
             &eNB->pusch_vars[0]->drs_ch_estimates[0][aa][eNB->frame_parms.N_RB_UL*12*pilot_pos2],
             eNB->frame_parms.N_RB_UL*12*sizeof(int));
353
    }
354

355 356
#endif

knopp's avatar
 
knopp committed
357
  if (subframe==4) {
358
    emos_dump_eNB.timestamp = rt_get_time_ns();
359 360 361 362 363
    emos_dump_eNB.frame_tx = eNB->proc[subframe].frame_rx;
    emos_dump_eNB.rx_total_gain_dB = eNB->rx_total_gain_dB;
    emos_dump_eNB.mimo_mode = eNB->transmission_mode[0];
    memcpy(&emos_dump_eNB.measurements,
           &eNB->measurements[0],
364
           sizeof(PHY_MEASUREMENTS_eNB));
365
    memcpy(&emos_dump_eNB.UE_stats[0],&eNB->UE_stats[0],NUMBER_OF_UE_MAX*sizeof(LTE_eNB_UE_stats));
366 367

    bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, &emos_dump_eNB, sizeof(fifo_dump_emos_eNB));
368

369 370
    //bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, "test", sizeof("test"));
    if (bytes!=sizeof(fifo_dump_emos_eNB)) {
knopp's avatar
 
knopp committed
371
      LOG_W(PHY,"[eNB %d] Frame %d, subframe %d, Problem writing EMOS data to FIFO (bytes=%d, size=%d)\n",
372
            eNB->Mod_id,eNB->proc[(subframe+1)%10].frame_rx, subframe,bytes,sizeof(fifo_dump_emos_eNB));
373
    } else {
374
      if (eNB->proc[(subframe+1)%10].frame_tx%100==0) {
knopp's avatar
 
knopp committed
375
        LOG_I(PHY,"[eNB %d] Frame %d (%d), subframe %d, Writing %d bytes EMOS data to FIFO\n",
376
              eNB->Mod_id,eNB->proc[(subframe+1)%10].frame_rx, ((fifo_dump_emos_eNB*)&emos_dump_eNB)->frame_tx, subframe, bytes);
377
      }
378
    }
379 380 381 382 383 384 385
  }
}
#endif


#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
#define AMP_OVER_2 (AMP>>1)
386 387
int QPSK[4]= {AMP_OVER_SQRT2|(AMP_OVER_SQRT2<<16),AMP_OVER_SQRT2|((65536-AMP_OVER_SQRT2)<<16),((65536-AMP_OVER_SQRT2)<<16)|AMP_OVER_SQRT2,((65536-AMP_OVER_SQRT2)<<16)|(65536-AMP_OVER_SQRT2)};
int QPSK2[4]= {AMP_OVER_2|(AMP_OVER_2<<16),AMP_OVER_2|((65536-AMP_OVER_2)<<16),((65536-AMP_OVER_2)<<16)|AMP_OVER_2,((65536-AMP_OVER_2)<<16)|(65536-AMP_OVER_2)};
388

gauthier's avatar
For RAL  
gauthier committed
389

knopp's avatar
 
knopp committed
390

Cedric Roux's avatar
Cedric Roux committed
391
unsigned int taus(void);
392
DCI_PDU DCI_pdu_tmp;
knopp's avatar
 
knopp committed
393

knopp's avatar
 
knopp committed
394

knopp's avatar
knopp committed
395
void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,PHY_VARS_RN *rn, int abstraction_flag,relaying_type_t r_type) {
396

knopp's avatar
 
knopp committed
397

398
#ifdef Rel10
399 400
  MCH_PDU *mch_pduP;
  MCH_PDU  mch_pdu;
401
  //  uint8_t sync_area=255;
402
#endif
403

404
  int subframe = proc->subframe_tx;
405

knopp's avatar
 
knopp committed
406
  if (abstraction_flag==0) {
407 408
    // This is DL-Cell spec pilots in Control region
    generate_pilots_slot(eNB,
409
			 eNB->common_vars.txdataF[0],
410 411
			 AMP,
			 subframe<<1,1);
knopp's avatar
 
knopp committed
412
  }
413
  
414
#ifdef Rel10
415 416 417 418
  // if mcch is active, send regardless of the node type: eNB or RN
  // when mcch is active, MAC sched does not allow MCCH and MTCH multiplexing
  mch_pduP = mac_xface->get_mch_sdu(eNB->Mod_id,
				    eNB->CC_id,
419
				    proc->frame_tx,
420 421 422 423 424 425
				    subframe);
  
  switch (r_type) {
  case no_relay:
    if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0
      LOG_I(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n",
426 427
	    eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->mcs,
	    eNB->dlsch_MCH->harq_processes[0]->TBS>>3);
428 429
    else {
      LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n",
430
	    eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->sync_area,
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
	    (mch_pduP->Pdu_size == 0)? "Empty MCH PDU":"Let RN transmit for the moment");
      mch_pduP = NULL;
    }
    
    break;
    
  case multicast_relay:
    if ((mch_pduP->Pdu_size > 0) && ((mch_pduP->mcch_active == 1) || mch_pduP->msi_active==1)) {
      LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Got the MCH PDU for MBSFN  sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n",
	    rn->Mod_id,rn->frame, subframe,
	    mch_pduP->sync_area,mch_pduP->mcs,mch_pduP->Pdu_size);
    } else if (rn->mch_avtive[subframe%5] == 1) { // SF2 -> SF7, SF3 -> SF8
      mch_pduP= &mch_pdu;
      memcpy(&mch_pduP->payload, // could be a simple copy
	     rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->b,
	     rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
      mch_pduP->Pdu_size = (uint16_t) (rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->TBS>>3);
      mch_pduP->mcs = rn->dlsch_rn_MCH[subframe%5]->harq_processes[0]->mcs;
      LOG_I(PHY,"[RN %"PRIu8"] Frame %d subframe %d: Forward the MCH PDU for MBSFN received on SF %d sync area %"PRIu8" (MCS %"PRIu8", TBS %"PRIu16")\n",
	    rn->Mod_id,rn->frame, subframe,subframe%5,
	    rn->sync_area[subframe%5],mch_pduP->mcs,mch_pduP->Pdu_size);
knopp's avatar
 
knopp committed
452
    } else {
453
      mch_pduP=NULL;
454
    }
455 456 457 458 459 460
    
    rn->mch_avtive[subframe]=0;
    break;
    
  default:
    LOG_W(PHY,"[eNB %"PRIu8"] Frame %d subframe %d: unknown relaying type %d \n",
461
	  eNB->Mod_id,proc->frame_tx,subframe,r_type);
462 463 464 465 466 467 468
    mch_pduP=NULL;
    break;
  }// switch
  
  if (mch_pduP) {
    fill_eNB_dlsch_MCH(eNB,mch_pduP->mcs,1,0, abstraction_flag);
    // Generate PMCH
knopp's avatar
knopp committed
469
    generate_mch(eNB,proc,(uint8_t*)mch_pduP->payload,abstraction_flag);
470
  } else {
471
    LOG_D(PHY,"[eNB/RN] Frame %d subframe %d: MCH not generated \n",proc->frame_tx,subframe);
knopp's avatar
 
knopp committed
472
  }
473 474 475
  
#endif
}
476

knopp's avatar
knopp committed
477
void common_signal_procedures (PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,int abstraction_flag) {
478

479 480
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
  int **txdataF = eNB->common_vars.txdataF[0];
481
  uint8_t *pbch_pdu=&eNB->pbch_pdu[0];
482 483
  int subframe = proc->subframe_tx;
  int frame = proc->frame_tx;
484

485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
  // generate Cell-Specific Reference Signals for both slots
  if (abstraction_flag==0) {
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,1);
    generate_pilots_slot(eNB,
			 txdataF,
			 AMP,
			 subframe<<1,0);
    // check that 2nd slot is for DL
    if (subframe_select(fp,subframe) == SF_DL)
      generate_pilots_slot(eNB,
			   txdataF,
			   AMP,
			   (subframe<<1)+1,0);
    
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_RS_TX,0);
  }    
knopp's avatar
 
knopp committed
501

502
  // First half of PSS/SSS (FDD, slot 0)
knopp's avatar
 
knopp committed
503
  if (subframe == 0) {
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
    if ((fp->frame_type == FDD) &&
	(abstraction_flag==0)) {
      generate_pss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 6 : 5,
		   0);
      generate_sss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 5 : 4,
		   0);
      
    }
    
519
    // generate PBCH (Physical Broadcast CHannel) info
520
    if ((frame&3) == 0) {
521
      pbch_pdu[2] = 0;
522
      
523
      // FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators
524
      switch (fp->N_RB_DL) {
knopp's avatar
 
knopp committed
525
      case 6:
526 527 528
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5);
	break;
	
knopp's avatar
 
knopp committed
529
      case 15:
530 531 532
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5);
	break;
	
knopp's avatar
 
knopp committed
533
      case 25:
534 535 536
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
	break;
	
knopp's avatar
 
knopp committed
537
      case 50:
538 539 540
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5);
	break;
	
knopp's avatar
 
knopp committed
541
      case 75:
542 543 544
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5);
	break;
	
knopp's avatar
 
knopp committed
545
      case 100:
546 547 548
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5);
	break;
	
knopp's avatar
 
knopp committed
549
      default:
550 551 552
	// FIXME if we get here, this should be flagged as an error, right?
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
	break;
knopp's avatar
 
knopp committed
553
      }
554
      
555
      pbch_pdu[2] = (pbch_pdu[2]&0xef) |
556 557 558
	((fp->phich_config_common.phich_duration << 4)&0x10);
      
      switch (fp->phich_config_common.phich_resource) {
knopp's avatar
 
knopp committed
559
      case oneSixth:
560 561 562
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2);
	break;
	
knopp's avatar
 
knopp committed
563
      case half:
564 565 566
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2);
	break;
	
knopp's avatar
 
knopp committed
567
      case one:
568 569 570
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2);
	break;
	
knopp's avatar
 
knopp committed
571
      case two:
572 573 574
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2);
	break;
	
knopp's avatar
 
knopp committed
575
      default:
576 577
	// unreachable
	break;
knopp's avatar
 
knopp committed
578
      }
579
      
580 581
      pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((frame>>8)&0x3);
      pbch_pdu[1] = frame&0xfc;
582
      pbch_pdu[0] = 0;
knopp's avatar
 
knopp committed
583
    }
584 585 586 587 588 589 590 591 592 593 594
      
    /// First half of SSS (TDD, slot 1)
    
    if ((fp->frame_type == TDD)&&
	(abstraction_flag==0)){
      generate_sss(txdataF,
		   AMP,
		   fp,
		   (fp->Ncp==NORMAL) ? 6 : 5,
		   1);
    }
595

596
    /// generate PBCH
knopp's avatar
 
knopp committed
597
    if (abstraction_flag==0) {
598
      generate_pbch(&eNB->pbch,
599 600 601 602
                    txdataF,
                    AMP,
                    fp,
                    pbch_pdu,
603
                    frame&3);
604 605 606 607 608 609
    }
#ifdef PHY_ABSTRACTION
    else {
      generate_pbch_emul(eNB,pbch_pdu);
    }
#endif
610

611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
  }
  else if ((subframe == 1) &&
	   (fp->frame_type == TDD)&&
	   (abstraction_flag==0)) {
    generate_pss(txdataF,
		 AMP,
		 fp,
		 2,
		 2);
  }
  
  // Second half of PSS/SSS (FDD, slot 10)
  else if ((subframe == 5) && 
	   (fp->frame_type == FDD) &&
	   (abstraction_flag==0)) {
626 627 628 629 630 631 632 633 634 635
    generate_pss(txdataF,
		 AMP,
		 &eNB->frame_parms,
		 (fp->Ncp==NORMAL) ? 6 : 5,
		 10);
    generate_sss(txdataF,
		 AMP,
		 &eNB->frame_parms,
		 (fp->Ncp==NORMAL) ? 5 : 4,
		 10);
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662

  }

  //  Second-half of SSS (TDD, slot 11)
  else if ((subframe == 5) &&
	   (fp->frame_type == TDD) &&
	   (abstraction_flag==0)) {
    generate_sss(txdataF,
		 AMP,
		 fp,
		 (fp->Ncp==NORMAL) ? 6 : 5,
		 11);
  }

  // Second half of PSS (TDD, slot 12)
  else if ((subframe == 6) &&
	   (fp->frame_type == TDD) &&
	   (abstraction_flag==0)) {
    generate_pss(txdataF,
		 AMP,
		 fp,
		 2,
		 12);
  }

}

knopp's avatar
knopp committed
663
void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) {
664

665
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
666 667
  int frame = proc->frame_tx;
  int subframe = proc->subframe_tx;
668 669 670 671 672 673 674 675 676

  // if we have SI_RNTI, configure dlsch parameters and CCE index
  if (dci_alloc->rnti == SI_RNTI) {
    LOG_D(PHY,"Generating dlsch params for SI_RNTI\n");
    generate_eNB_dlsch_params_from_dci(frame,
				       subframe,
				       &dci_alloc->dci_pdu[0],
				       dci_alloc->rnti,
				       dci_alloc->format,
677
				       &eNB->dlsch_SI,
678 679 680 681 682
				       fp,
				       eNB->pdsch_config_dedicated,
				       SI_RNTI,
				       0,
				       P_RNTI,
683
				       eNB->UE_stats[0].DL_pmi_single);
684 685
    
    
686
    eNB->dlsch_SI->nCCE[subframe] = dci_alloc->firstCCE;
687
    
688
    LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (SI)  => %"PRIu8"\n",eNB->Mod_id,frame,subframe,
689
	  eNB->dlsch_SI->nCCE[subframe]);
690 691 692 693
    
#if defined(SMBV) 
    
    // configure SI DCI
694 695
    if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, SI in SF %d DCI %"PRIu32"\n",frame,subframe,i);
696 697 698 699 700 701 702 703 704 705 706 707 708 709
      smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "SI", dci_alloc, i);
    }
    
#endif
    
    
  } else if (dci_alloc->ra_flag == 1) {  // This is format 1A allocation for RA
    // configure dlsch parameters and CCE index
    LOG_D(PHY,"Generating dlsch params for RA_RNTI\n");    
    generate_eNB_dlsch_params_from_dci(frame,
				       subframe,
				       &dci_alloc->dci_pdu[0],
				       dci_alloc->rnti,
				       dci_alloc->format,
710
				       &eNB->dlsch_ra,
711 712 713 714 715
				       fp,
				       eNB->pdsch_config_dedicated,
				       SI_RNTI,
				       dci_alloc->rnti,
				       P_RNTI,
716
				       eNB->UE_stats[0].DL_pmi_single);
717 718
    
    
719
    eNB->dlsch_ra->nCCE[subframe] = dci_alloc->firstCCE;
720
    
721
    LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (RA)  => %"PRIu8"\n",eNB->Mod_id,frame,subframe,
722
	  eNB->dlsch_ra->nCCE[subframe]);
723 724 725
#if defined(SMBV) 
    
    // configure RA DCI
726 727
    if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, RA in SF %d DCI %"PRIu32"\n",frame,subframe,i);
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744
      smbv_configure_common_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), "RA", dci_alloc, i);
    }
    
#endif
    
  }
  
  else if ((dci_alloc->format != format0)&&
	   (dci_alloc->format != format3)&&
	   (dci_alloc->format != format3A)&&
	   (dci_alloc->format != format4)){ // this is a normal DLSCH allocation
    

    
    if (UE_id>=0) {
#if defined(SMBV) 
      // Configure this user
745 746
      if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
	LOG_D(PHY,"[SMBV] Frame %3d, SF %d (SMBV SF %d) Configuring user %d with RNTI %"PRIu16" in TM%"PRIu8"\n",frame,subframe,(smbv_frame_cnt*10) + (subframe),UE_id+1,
747 748 749 750 751 752 753 754 755 756 757 758
              dci_alloc->rnti,eNB->transmission_mode[(uint8_t)UE_id]);
	smbv_configure_user(smbv_fname,UE_id+1,eNB->transmission_mode[(uint8_t)UE_id],dci_alloc->rnti);
      }
      
#endif

      LOG_D(PHY,"Generating dlsch params for RNTI %x\n",dci_alloc->rnti);      
      generate_eNB_dlsch_params_from_dci(frame,
					 subframe,
					 &dci_alloc->dci_pdu[0],
					 dci_alloc->rnti,
					 dci_alloc->format,
759
					 eNB->dlsch[(uint8_t)UE_id],
760 761 762 763 764
					 fp,
					 eNB->pdsch_config_dedicated,
					 SI_RNTI,
					 0,
					 P_RNTI,
765
					 eNB->UE_stats[(uint8_t)UE_id].DL_pmi_single);
766
      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n",
767
	    eNB->Mod_id,dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->current_harq_pid,frame,subframe);
768 769
      
      
770
      eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe] = dci_alloc->firstCCE;
771
      
772
      LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16")  => %"PRIu8"/%u\n",eNB->Mod_id,frame,subframe,
773
	    dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe]);
774 775 776 777
      
#if defined(SMBV) 
      
      // configure UE-spec DCI
778 779
      if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
	LOG_D(PHY,"[SMBV] Frame %3d, PDSCH in SF %d DCI %"PRIu32"\n",frame,subframe,i);
780
	smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1,dci_alloc, i);
knopp's avatar
 
knopp committed
781
      }
782 783 784 785 786
      
#endif
      
      LOG_D(PHY,"[eNB %"PRIu8"][DCI][PDSCH %"PRIx16"] Frame %d subframe %d UE_id %"PRId8" Generated DCI format %d, aggregation %d\n",
	    eNB->Mod_id, dci_alloc->rnti,
787
	    frame, subframe,UE_id,
788 789 790 791
	    dci_alloc->format,
	    1<<dci_alloc->L);
    } else {
      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH] Frame %d : No UE_id with corresponding rnti %"PRIx16", dropping DLSCH\n",
792
	    eNB->Mod_id,frame,dci_alloc->rnti);
knopp's avatar
 
knopp committed
793
    }
794 795 796
  }
  
}
797

knopp's avatar
knopp committed
798
void generate_eNB_ulsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) {
799

800
  int harq_pid;
801
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
802
  int frame = proc->frame_tx;
knopp's avatar
knopp committed
803
  int subframe = proc->subframe_tx;
804

805
  LOG_D(PHY,
806 807 808
	"[eNB %"PRIu8"][PUSCH %"PRIu8"] Frame %d subframe %d UL Frame %"PRIu32", UL Subframe %"PRIu8", Generated ULSCH (format0) DCI (rnti %"PRIx16", dci %"PRIx8"), aggregation %d\n",
	eNB->Mod_id,
	subframe2harq_pid(fp,
809
			  pdcch_alloc2ul_frame(fp,frame,subframe),
810
			  pdcch_alloc2ul_subframe(fp,subframe)),
811
	frame,