[GITLAB] - UPGRADE TO v12 on Wednesday the 18th of December at 11.30AM

phy_procedures_lte_eNb.c 119 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

ghaddab's avatar
ghaddab committed
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
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];
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 144 145 146 147
void put_harq_pid_in_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
{
  DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->tail_freelist] = harq_pid;
  DLSCH_ptr->tail_freelist = (DLSCH_ptr->tail_freelist + 1) % 10;
}

Cedric Roux's avatar
Cedric Roux committed
148
void remove_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
149 150 151 152 153
{
  if (DLSCH_ptr->head_freelist == DLSCH_ptr->tail_freelist) {
    LOG_E(PHY, "%s:%d: you cannot read this!\n", __FILE__, __LINE__);
    abort();
  }
Cedric Roux's avatar
Cedric Roux committed
154 155 156 157 158 159 160 161 162
  /* basic check, in case several threads deal with the free list at the same time
   * in normal situations it should not happen, that's also why we don't use any
   * locking mechanism to protect the free list
   * to be refined in case things don't work properly
   */
  if (harq_pid != DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist]) {
    LOG_E(PHY, "%s:%d: critical error, get in touch with the authors\n", __FILE__, __LINE__);
    abort();
  }
163 164 165
  DLSCH_ptr->head_freelist = (DLSCH_ptr->head_freelist + 1) % 10;
}

166
int32_t add_ue(int16_t rnti, PHY_VARS_eNB *eNB)
167
{
168
  uint8_t i;
169

170 171

  LOG_D(PHY,"[eNB %d/%d] Adding UE with rnti %x\n",
172 173
        eNB->Mod_id,
        eNB->CC_id,
174
        (uint16_t)rnti);
175 176

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
177
    if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) {
178
      MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed add ue %"PRIx16" (ENOMEM)", rnti);
179 180
      LOG_E(PHY,"Can't add UE, not enough memory allocated\n");
      return(-1);
181
    } else {
182
      if (eNB->UE_stats[i].crnti==0) {
183
        MSC_LOG_EVENT(MSC_PHY_ENB, "0 Add ue %"PRIx16" ", rnti);
184
        LOG_D(PHY,"UE_id %d associated with rnti %x\n",i, (uint16_t)rnti);
185 186 187
        eNB->dlsch[i][0]->rnti = rnti;
        eNB->ulsch[i]->rnti = rnti;
        eNB->UE_stats[i].crnti = rnti;
188

189 190 191
	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));
192
	LOG_D(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n",
193 194 195
	      eNB->frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
	      eNB->rx_total_gain_dB,
	      eNB->UE_stats[i].Po_PUCCH);
196
  
197
        return(i);
198
      }
199
    }
200 201 202 203
  }
  return(-1);
}

204
int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) {
205
  uint8_t i;
206
  int j,CC_id;
207
  PHY_VARS_eNB *eNB;
208 209

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
210
    eNB = PHY_vars_eNB_g[Mod_idP][CC_id];
211
    for (i=0; i<NUMBER_OF_UE_MAX; i++) {
212
      if ((eNB->dlsch[i]==NULL) || (eNB->ulsch[i]==NULL)) {
213 214 215 216
	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 {
217
	if (eNB->UE_stats[i].crnti==rntiP) {
218
	  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Removed ue %"PRIx16" ", rntiP);
219 220 221

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

222
	  //LOG_D(PHY,("[PHY] UE_id %d\n",i);
223 224 225 226
	  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));
227 228 229
	  //  mac_exit_wrapper("Removing UE");
	  
	  /* clear the harq pid freelist */
230 231
	  eNB->dlsch[i][0]->head_freelist = 0;
	  eNB->dlsch[i][0]->tail_freelist = 0;
232
	  for (j = 0; j < 8; j++)
233
	    put_harq_pid_in_freelist(eNB->dlsch[i][0], j);
234 235 236
	  
	  return(i);
	}
237
      }
238
    }
239
  }
240
  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (not found)", rntiP);
241 242 243
  return(-1);
}

244
int8_t find_next_ue_index(PHY_VARS_eNB *eNB)
245
{
246
  uint8_t i;
247

248
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
249 250 251 252
    if (eNB->UE_stats[i].crnti==0) {
      /*if ((eNB->dlsch[i]) &&
      (eNB->dlsch[i][0]) &&
      (eNB->dlsch[i][0]->rnti==0))*/
253 254 255
      LOG_D(PHY,"Next free UE id is %d\n",i);
      return(i);
    }
256
  }
257

258 259 260
  return(-1);
}

gauthier's avatar
gauthier committed
261
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)
262 263 264 265
{
  LTE_eNB_DLSCH_t *DLSCH_ptr;
  LTE_eNB_ULSCH_t *ULSCH_ptr;
  uint8_t ulsch_subframe,ulsch_frame;
266
  uint8_t i;
knopp's avatar
knopp committed
267
  int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
268
  int sf1=(10*frame)+subframe,sf2,sfdiff,sfdiff_max=7;
269 270

  if (UE_id==-1) {
271
    LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id);
272 273
    *round=0;
    return(-1);
274 275 276
  }

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

279 280 281 282 283
    // set to no available process first
    *harq_pid = -1;

    for (i=0; i<DLSCH_ptr->Mdlharq; i++) {
      if (DLSCH_ptr->harq_processes[i]!=NULL) {
284
	if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) {
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
	  sf2 = (DLSCH_ptr->harq_processes[i]->frame*10) + DLSCH_ptr->harq_processes[i]->subframe;
	  if (sf2<=sf1)
	    sfdiff = sf1-sf2;
	  else // this happens when wrapping around 1024 frame barrier
	    sfdiff = 10240 + sf1-sf2;
	  LOG_D(PHY,"process %d is active, round %d (waiting %d)\n",i,DLSCH_ptr->harq_processes[i]->round,sfdiff);

	  if (sfdiff>sfdiff_max) { // this is an active process that is waiting longer than the others (and longer than 7 ms)
	    sfdiff_max = sfdiff; 
	    *harq_pid = i;
	    *round = DLSCH_ptr->harq_processes[i]->round;
	  }
	}
      } else { // a process is not defined
	LOG_E(PHY,"[eNB %d] DLSCH process %d for rnti %x (UE_id %d) not allocated\n",Mod_id,i,rnti,UE_id);
	return(-1);
301
      }
302
    }
303 304 305 306 307 308 309 310

    /* if no active harq pid, get the oldest in the freelist, if any */
    if (*harq_pid == 255 && DLSCH_ptr->head_freelist != DLSCH_ptr->tail_freelist) {
      *harq_pid = DLSCH_ptr->harq_pid_freelist[DLSCH_ptr->head_freelist];
      *round = 0;
      LOG_D(PHY,"process %d is first free process\n", *harq_pid);
    }

311 312
    LOG_D(PHY,"get_ue_active_harq_pid DL => Frame %d, Subframe %d : harq_pid %d\n",
	  frame,subframe,*harq_pid);
313
  } else { // This is a UL request
314

315 316 317
    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);
318
    // Note this is for TDD configuration 3,4,5 only
319
    *harq_pid = subframe2harq_pid(&PHY_vars_eNB_g[Mod_id][CC_id]->frame_parms,
320 321
                                  ulsch_frame,
                                  ulsch_subframe);
322
    *round    = ULSCH_ptr->harq_processes[*harq_pid]->round;
323
    LOG_T(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Checking HARQ, round %d\n",Mod_id,*harq_pid,frame,subframe,*round);
324
  }
325

326 327 328
  return(0);
}

329
int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
330
{
331
  return PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
332 333
}

334 335
int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
{
336
  return PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
337 338
}

339
#ifdef EMOS
340
void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *eNB)
341
{
342 343 344 345 346 347

}
#endif



knopp's avatar
knopp committed
348
void phy_procedures_eNB_S_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t abstraction_flag,relaying_type_t r_type)
349 350
{
  UNUSED(r_type);
351
  int subframe = proc->subframe_rx;
352

353
#ifdef DEBUG_PHY_PROC
354
  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_S_RX(%d)\n", eNB->Mod_id,proc->frame_rx, subframe);
355
#endif
356

357

knopp's avatar
knopp committed
358
  if (abstraction_flag == 0) {
359
    lte_eNB_I0_measurements(eNB,
360
			    subframe,
361
                            0,
362
                            eNB->first_run_I0_measurements);
knopp's avatar
knopp committed
363
  }
364

365
#ifdef PHY_ABSTRACTION
knopp's avatar
knopp committed
366
  else {
367
    lte_eNB_I0_measurements_emul(eNB,
368
                                 0);
369
  }
370

knopp's avatar
knopp committed
371 372
#endif

373

374 375
}

knopp's avatar
knopp committed
376 377


378
#ifdef EMOS
379
void phy_procedures_emos_eNB_RX(unsigned char subframe,PHY_VARS_eNB *eNB)
380 381
{

382 383
  uint8_t aa;
  uint16_t last_subframe_emos;
384
  uint16_t pilot_pos1 = 3 - eNB->frame_parms.Ncp, pilot_pos2 = 10 - 2*eNB->frame_parms.Ncp;
385
  uint32_t bytes;
386 387 388

  last_subframe_emos=0;

knopp's avatar
knopp committed
389

knopp's avatar
knopp committed
390

knopp's avatar
knopp committed
391

392
#ifdef EMOS_CHANNEL
393

394
  //if (last_slot%2==1) // this is for all UL subframes
395
  if (subframe==3)
396 397 398 399 400 401 402
    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));
403
    }
404

405 406
#endif

knopp's avatar
knopp committed
407
  if (subframe==4) {
408
    emos_dump_eNB.timestamp = rt_get_time_ns();
409 410 411 412 413
    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],
414
           sizeof(PHY_MEASUREMENTS_eNB));
415
    memcpy(&emos_dump_eNB.UE_stats[0],&eNB->UE_stats[0],NUMBER_OF_UE_MAX*sizeof(LTE_eNB_UE_stats));
416 417

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

419 420
    //bytes = rtf_put(CHANSOUNDER_FIFO_MINOR, "test", sizeof("test"));
    if (bytes!=sizeof(fifo_dump_emos_eNB)) {
knopp's avatar
knopp committed
421
      LOG_W(PHY,"[eNB %d] Frame %d, subframe %d, Problem writing EMOS data to FIFO (bytes=%d, size=%d)\n",
422
            eNB->Mod_id,eNB->proc[(subframe+1)%10].frame_rx, subframe,bytes,sizeof(fifo_dump_emos_eNB));
423
    } else {
424
      if (eNB->proc[(subframe+1)%10].frame_tx%100==0) {
knopp's avatar
knopp committed
425
        LOG_I(PHY,"[eNB %d] Frame %d (%d), subframe %d, Writing %d bytes EMOS data to FIFO\n",
426
              eNB->Mod_id,eNB->proc[(subframe+1)%10].frame_rx, ((fifo_dump_emos_eNB*)&emos_dump_eNB)->frame_tx, subframe, bytes);
427
      }
428
    }
429 430 431 432 433 434 435
  }
}
#endif


#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
#define AMP_OVER_2 (AMP>>1)
436 437
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)};
438

gauthier's avatar
gauthier committed
439

knopp's avatar
knopp committed
440

Cedric Roux's avatar
Cedric Roux committed
441
unsigned int taus(void);
442
DCI_PDU DCI_pdu_tmp;
knopp's avatar
knopp committed
443

knopp's avatar
knopp committed
444

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

knopp's avatar
knopp committed
447

448
#ifdef Rel10
449 450
  MCH_PDU *mch_pduP;
  MCH_PDU  mch_pdu;
451
  //  uint8_t sync_area=255;
452
#endif
453

454
  int subframe = proc->subframe_tx;
455

knopp's avatar
knopp committed
456
  if (abstraction_flag==0) {
457 458
    // This is DL-Cell spec pilots in Control region
    generate_pilots_slot(eNB,
459
			 eNB->common_vars.txdataF[0],
460 461
			 AMP,
			 subframe<<1,1);
knopp's avatar
knopp committed
462
  }
463
  
464
#ifdef Rel10
465 466 467 468
  // 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,
469
				    proc->frame_tx,
470 471 472 473 474 475
				    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",
476 477
	    eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->mcs,
	    eNB->dlsch_MCH->harq_processes[0]->TBS>>3);
478 479
    else {
      LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n",
480
	    eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->sync_area,
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501
	    (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
502
    } else {
503
      mch_pduP=NULL;
504
    }
505 506 507 508 509 510
    
    rn->mch_avtive[subframe]=0;
    break;
    
  default:
    LOG_W(PHY,"[eNB %"PRIu8"] Frame %d subframe %d: unknown relaying type %d \n",
511
	  eNB->Mod_id,proc->frame_tx,subframe,r_type);
512 513 514 515 516 517 518
    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
519
    generate_mch(eNB,proc,(uint8_t*)mch_pduP->payload,abstraction_flag);
520
  } else {
521
    LOG_D(PHY,"[eNB/RN] Frame %d subframe %d: MCH not generated \n",proc->frame_tx,subframe);
knopp's avatar
knopp committed
522
  }
523 524 525
  
#endif
}
526

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

529 530
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
  int **txdataF = eNB->common_vars.txdataF[0];
531
  uint8_t *pbch_pdu=&eNB->pbch_pdu[0];
532 533
  int subframe = proc->subframe_tx;
  int frame = proc->frame_tx;
534

535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
  // 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
551

552
  // First half of PSS/SSS (FDD, slot 0)
knopp's avatar
knopp committed
553
  if (subframe == 0) {
554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
    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);
      
    }
    
569
    // generate PBCH (Physical Broadcast CHannel) info
570
    if ((frame&3) == 0) {
571
      pbch_pdu[2] = 0;
572
      
573
      // FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators
574
      switch (fp->N_RB_DL) {
knopp's avatar
knopp committed
575
      case 6:
576 577 578
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5);
	break;
	
knopp's avatar
knopp committed
579
      case 15:
580 581 582
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5);
	break;
	
knopp's avatar
knopp committed
583
      case 25:
584 585 586
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
	break;
	
knopp's avatar
knopp committed
587
      case 50:
588 589 590
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5);
	break;
	
knopp's avatar
knopp committed
591
      case 75:
592 593 594
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5);
	break;
	
knopp's avatar
knopp committed
595
      case 100:
596 597 598
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5);
	break;
	
knopp's avatar
knopp committed
599
      default:
600 601 602
	// 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
603
      }
604
      
605
      pbch_pdu[2] = (pbch_pdu[2]&0xef) |
606 607 608
	((fp->phich_config_common.phich_duration << 4)&0x10);
      
      switch (fp->phich_config_common.phich_resource) {
knopp's avatar
knopp committed
609
      case oneSixth:
610 611 612
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2);
	break;
	
knopp's avatar
knopp committed
613
      case half:
614 615 616
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2);
	break;
	
knopp's avatar
knopp committed
617
      case one:
618 619 620
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2);
	break;
	
knopp's avatar
knopp committed
621
      case two:
622 623 624
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2);
	break;
	
knopp's avatar
knopp committed
625
      default:
626 627
	// unreachable
	break;
knopp's avatar
knopp committed
628
      }
629
      
630 631
      pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((frame>>8)&0x3);
      pbch_pdu[1] = frame&0xfc;
632
      pbch_pdu[0] = 0;
knopp's avatar
knopp committed
633
    }
634 635 636 637 638 639 640 641 642 643 644
      
    /// 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);
    }
645

646
    /// generate PBCH
knopp's avatar
knopp committed
647
    if (abstraction_flag==0) {
648
      generate_pbch(&eNB->pbch,
649 650 651 652
                    txdataF,
                    AMP,
                    fp,
                    pbch_pdu,
653
                    frame&3);
654 655 656 657 658 659
    }
#ifdef PHY_ABSTRACTION
    else {
      generate_pbch_emul(eNB,pbch_pdu);
    }
#endif
660

661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
  }
  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)) {
        generate_pss(txdataF,
677
                     AMP,
678
                     &eNB->frame_parms,
679 680 681 682
                     (fp->Ncp==NORMAL) ? 6 : 5,
                     10);
        generate_sss(txdataF,
                     AMP,
683
                     &eNB->frame_parms,
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712
                     (fp->Ncp==NORMAL) ? 5 : 4,
                     10);

  }

  //  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
713
void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) {
714

715
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
716 717
  int frame = proc->frame_tx;
  int subframe = proc->subframe_tx;
718 719 720 721 722 723 724 725 726

  // 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,
727
				       &eNB->dlsch_SI,
728 729 730 731 732
				       fp,
				       eNB->pdsch_config_dedicated,
				       SI_RNTI,
				       0,
				       P_RNTI,
733
				       eNB->UE_stats[0].DL_pmi_single);
734 735
    
    
736
    eNB->dlsch_SI->nCCE[subframe] = dci_alloc->firstCCE;
737
    
738
    LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (SI)  => %"PRIu8"\n",eNB->Mod_id,frame,subframe,
739
	  eNB->dlsch_SI->nCCE[subframe]);
740 741 742 743
    
#if defined(SMBV) 
    
    // configure SI DCI
744 745
    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);
746 747 748 749 750 751 752 753 754 755 756 757 758 759
      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,
760
				       &eNB->dlsch_ra,
761 762 763 764 765
				       fp,
				       eNB->pdsch_config_dedicated,
				       SI_RNTI,
				       dci_alloc->rnti,
				       P_RNTI,
766
				       eNB->UE_stats[0].DL_pmi_single);
767 768
    
    
769
    eNB->dlsch_ra->nCCE[subframe] = dci_alloc->firstCCE;
770
    
771
    LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (RA)  => %"PRIu8"\n",eNB->Mod_id,frame,subframe,
772
	  eNB->dlsch_ra->nCCE[subframe]);
773 774 775
#if defined(SMBV) 
    
    // configure RA DCI
776 777
    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);
778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
      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
795 796
      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,
797 798 799 800 801 802 803 804 805 806 807 808
              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,
809
					 eNB->dlsch[(uint8_t)UE_id],
810 811 812 813 814
					 fp,
					 eNB->pdsch_config_dedicated,
					 SI_RNTI,
					 0,
					 P_RNTI,
815
					 eNB->UE_stats[(uint8_t)UE_id].DL_pmi_single);
816
      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n",
817
	    eNB->Mod_id,dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->current_harq_pid,frame,subframe);
818 819
      
      
820
      eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe] = dci_alloc->firstCCE;
821
      
822
      LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16")  => %"PRIu8"/%u\n",eNB->Mod_id,frame,subframe,
823
	    dci_alloc->rnti,eNB->dlsch[(uint8_t)UE_id][0]->nCCE[subframe]);
824 825 826 827
      
#if defined(SMBV) 
      
      // configure UE-spec DCI
828 829
      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);
830
	smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1,dci_alloc, i);
knopp's avatar
knopp committed
831
      }
832 833 834 835 836
      
#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,
837
	    frame, subframe,UE_id,
838 839 840 841
	    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",
842
	    eNB->Mod_id,frame,dci_alloc->rnti);
knopp's avatar
knopp committed
843
    }
844 845 846
  }
  
}
847

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

850
  int harq_pid;
851
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
852
  int frame = proc->frame_tx;
knopp's avatar
knopp committed
853
  int subframe = proc->subframe_tx;
854

855
  LOG_D(PHY,
856 857 858
	"[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,
859
			  pdcch_alloc2ul_frame(fp,frame,subframe),
860
			  pdcch_alloc2ul_subframe(fp,subframe)),
861
	frame,
862
	subframe,
863
	pdcch_alloc2ul_frame(fp,frame,subframe),
864 865 866 867 868
	pdcch_alloc2ul_subframe(fp,subframe),
	dci_alloc->rnti,
	dci_alloc->dci_pdu[0],
	1<<dci_alloc->L);
  
869
  generate_eNB_ulsch_params_from_dci(eNB,
knopp's avatar
knopp committed
870
				     proc,
871
				     &dci_alloc->dci_pdu[0],
872 873 874 875 876 877 878 879 880 881
				     dci_alloc->rnti,
				     format0,
				     UE_id,
				     SI_RNTI,
				     0,
				     P_RNTI,
				     CBA_RNTI,
				     0);  // do_srs
  
  LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resources for UE spec DCI (PUSCH %"PRIx16") => %d\n",
882
	eNB->Mod_id,frame,subframe,dci_alloc->rnti,
883 884 885 886 887
	dci_alloc->firstCCE);
  
#if defined(SMBV) 
  
  // configure UE-spec DCI for UL Grant
888 889
  if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
    LOG_D(PHY,"[SMBV] Frame %3d, SF %d UL DCI %"PRIu32"\n",frame,subframe,i);
890 891 892 893 894 895 896 897
    smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1, &DCI_pdu->dci_alloc[i], i);
  }
  
#endif
  
  
  // get the hard_pid for this subframe 
  harq_pid = subframe2harq_pid(fp,
898
			       pdcch_alloc2ul_frame(fp,frame,subframe),
899 900 901
			       pdcch_alloc2ul_subframe(fp,subframe));
  
  if (harq_pid==255) { // should not happen, log an error and exit, this is a fatal error
902
    LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Bad harq_pid for ULSCH allocation\n",eNB->Mod_id,frame);
903 904 905 906
    mac_xface->macphy_exit("FATAL\n"); 
  }
  
  if ((dci_alloc->rnti  >= CBA_RNTI) && (dci_alloc->rnti < P_RNTI))
907
    eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1;
908
  else
909
    eNB->ulsch[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
910 911
  
}
912

knopp's avatar
knopp committed
913
void pdsch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch1,LTE_eNB_UE_stats *ue_stats,int ra_flag,int num_pdcch_symbols,int abstraction_flag) {
914

915 916
  int frame=proc->frame_tx;
  int subframe=proc->subframe_tx;
917 918 919
  int harq_pid = dlsch->current_harq_pid;
  LTE_DL_eNB_HARQ_t *dlsch_harq=dlsch->harq_processes[harq_pid];
  int input_buffer_length = dlsch_harq->TBS/8;
920
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
921 922 923 924 925 926 927 928
  uint8_t *DLSCH_pdu=NULL;
  uint8_t DLSCH_pdu_tmp[768*8];
  uint8_t DLSCH_pdu_rar[256];
  int i;

  LOG_D(PHY,
	"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d, subframe %d: Generating PDSCH/DLSCH with input size = %"PRIu16", G %d, nb_rb %"PRIu16", mcs %"PRIu8", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")\n",
	eNB->Mod_id, dlsch->rnti,harq_pid,
929
	frame, subframe, input_buffer_length,
930 931 932 933 934
	get_G(fp,
	      dlsch_harq->nb_rb,
	      dlsch_harq->rb_alloc,
	      get_Qm(dlsch_harq->mcs),
	      dlsch_harq->Nl,
935
	      num_pdcch_symbols,frame,subframe),
936 937 938 939 940
	dlsch_harq->nb_rb,
	dlsch_harq->mcs,
	pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
	dlsch_harq->rvidx,
	dlsch_harq->round);
941

942 943 944 945 946
#if defined(MESSAGE_CHART_GENERATOR_PHY)
      MSC_LOG_TX_MESSAGE(
        MSC_PHY_ENB,MSC_PHY_UE,
        NULL,0,
        "%05u:%02u PDSCH/DLSCH input size = %"PRIu16", G %d, nb_rb %"PRIu16", mcs %"PRIu8", pmi_alloc %"PRIx16", rv %"PRIu8" (round %"PRIu8")",
947
        frame, subframe,
948 949 950 951 952 953
        input_buffer_length,
        get_G(fp,
        		dlsch_harq->nb_rb,
        		dlsch_harq->rb_alloc,
        		get_Qm(dlsch_harq->mcs),
        		dlsch_harq->Nl,
954
        		num_pdcch_symbols,frame,subframe),
955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972
        dlsch_harq->nb_rb,
        dlsch_harq->mcs,
        pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
        dlsch_harq->rvidx,
        dlsch_harq->round);
#endif

      if (ue_stats) ue_stats->dlsch_sliding_cnt++;

      if (dlsch_harq->round == 0) {

	if (ue_stats)
	  ue_stats->dlsch_trials[harq_pid][0]++;

	if (eNB->mac_enabled==1) {
	  if (ra_flag == 0) {
	    DLSCH_pdu = mac_xface->get_dlsch_sdu(eNB->Mod_id,
						 eNB->CC_id,
973
						 frame,
974 975 976 977 978 979
						 dlsch->rnti,
						 0);
	  }
	  else {
	    int16_t crnti = mac_xface->fill_rar(eNB->Mod_id,
						eNB->CC_id,
980
						frame,
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996
						DLSCH_pdu_rar,
						fp->N_RB_UL,
						input_buffer_length);
	    DLSCH_pdu = DLSCH_pdu_rar;

	    int UE_id;

	    if (crnti!=0) 
	      UE_id = add_ue(crnti,eNB);
	    else 
	      UE_id = -1;
	    
	    if (UE_id==-1) {
	      LOG_W(PHY,"[eNB] Max user count reached.\n");
	      mac_xface->cancel_ra_proc(eNB->Mod_id,
					eNB->CC_id,
997
					frame,
998 999
					crnti);
	    } else {
1000
	      eNB->UE_stats[(uint32_t)UE_id].mode = RA_RESPONSE;
1001 1002 1003 1004
	      // Initialize indicator for first SR (to be cleared after ConnectionSetup is acknowledged)
	      eNB->first_sr[(uint32_t)UE_id] = 1;
	      
	      generate_eNB_ulsch_params_from_rar(DLSCH_pdu,
1005
						 frame,
1006
						 (subframe),
1007
						 eNB->ulsch[(uint32_t)UE_id],
1008 1009
						 fp);
	      
1010
	      eNB->ulsch[(uint32_t)UE_id]->Msg3_active = 1;
1011 1012 1013
	      
	      get_Msg3_alloc(fp,
			     subframe,
1014
			     frame,
1015 1016
			     &eNB->ulsch[(uint32_t)UE_id]->Msg3_frame,
			     &eNB->ulsch[(uint32_t)UE_id]->Msg3_subframe);
1017
	      LOG_D(PHY,"[eNB][RAPROC] Frame %d subframe %d, Activated Msg3 demodulation for UE %"PRId8" in frame %"PRIu32", subframe %"PRIu8"\n",
1018
		    frame,
1019 1020
		    subframe,
		    UE_id,
1021 1022
		    eNB->ulsch[(uint32_t)UE_id]->Msg3_frame,
		    eNB->ulsch[(uint32_t)UE_id]->Msg3_subframe);
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
	    }
	    if (ue_stats) ue_stats->total_TBS_MAC += dlsch_harq->TBS;
	  }
	}
	else {
	  DLSCH_pdu = DLSCH_pdu_tmp;
	  
	  for (i=0; i<input_buffer_length; i++)
	    DLSCH_pdu[i] = (unsigned char)(taus()&0xff);
	}
	
#if defined(SMBV) 
1035

1036
        // Configures the data source of allocation (allocation is configured by DCI)
1037 1038
        if (smbv_is_config_frame(frame) && (smbv_frame_cnt < 4)) {
          LOG_D(PHY,"[SMBV] Frame %3d, Configuring PDSCH payload in SF %d alloc %"PRIu8"\n",frame,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
1039
	  //          smbv_configure_datalist_for_user(smbv_fname, find_ue(dlsch->rnti,eNB)+1, DLSCH_pdu, input_buffer_length);
1040
        }
1041

1042
#endif
1043

1044

1045

1046 1047 1048 1049
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_DLSCH
        LOG_T(PHY,"eNB DLSCH SDU: \n");

1050
        T(T_ENB_PHY_DLSCH_UE_DCI, T_INT(phy_vars_eNB->Mod_id), T_INT(frame), T_INT(subframe), T_INT(UE_id),
1051 1052 1053
          T_INT(DCI_pdu->dci_alloc[i].rnti), T_INT(DCI_pdu->dci_alloc[i].format),
          T_INT(phy_vars_eNB->dlsch_eNB[(int)UE_id][0]->current_harq_pid));

1054
        phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe] = DCI_pdu->dci_alloc[i].firstCCE;
1055

1056
	LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16")  => %"PRIu8"/%u\n",phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_tx,subframe,
1057
	      DCI_pdu->dci_alloc[i].rnti,phy_vars_eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe],DCI_pdu->dci_alloc[i].firstCCE);
1058 1059


1060 1061 1062 1063
        for (i=0; i<dlsch_harq->TBS>>3; i++)
          LOG_T(PHY,"%"PRIx8".",DLSCH_pdu[i]);

        LOG_T(PHY,"\n");
knopp's avatar
knopp committed
1064
#endif
1065 1066 1067 1068 1069 1070 1071 1072 1073
#endif
      } else {
        ue_stats->dlsch_trials[harq_pid][dlsch_harq->round]++;
#ifdef DEBUG_PHY_PROC
#ifdef DEBUG_DLSCH
        LOG_D(PHY,"[eNB] This DLSCH is a retransmission\n");
#endif
#endif
      }
1074

1075
      if (abstraction_flag==0) {
1076

1077 1078 1079 1080 1081 1082 1083
	LOG_D(PHY,"Generating DLSCH/PDSCH %d\n",ra_flag);
        // 36-212
        start_meas(&eNB->dlsch_encoding_stats);
        dlsch_encoding(DLSCH_pdu,
                       fp,
                       num_pdcch_symbols,
                       dlsch,
1084
                       frame,subframe,
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098
                       &eNB->dlsch_rate_matching_stats,
                       &eNB->dlsch_turbo_encoding_stats,
                       &eNB->dlsch_interleaving_stats);
        stop_meas(&eNB->dlsch_encoding_stats);
        // 36-211
        start_meas(&eNB->dlsch_scrambling_stats);
        dlsch_scrambling(fp,
                         0,
                         dlsch,
                         get_G(fp,
                               dlsch_harq->nb_rb,
                               dlsch_harq->rb_alloc,
                               get_Qm(dlsch_harq->mcs),
                               dlsch_harq->Nl,
1099
                               num_pdcch_symbols,frame,subframe),
1100 1101 1102 1103
                         0,
                         subframe<<1);
        stop_meas(&eNB->dlsch_scrambling_stats);
        start_meas(&eNB->dlsch_modulation_stats);
1104 1105


1106
        dlsch_modulation(eNB->common_vars.txdataF[0],
1107 1108 1109 1110 1111 1112 1113 1114 1115
			 AMP,
			 subframe,
			 fp,
			 num_pdcch_symbols,
			 dlsch,
			 dlsch1);
	
        stop_meas(&eNB->dlsch_modulation_stats);
      }
1116 1117


1118 1119 1120 1121 1122 1123 1124
#ifdef PHY_ABSTRACTION
      else {
        start_meas(&eNB->dlsch_encoding_stats);
        dlsch_encoding_emul(eNB,
                            DLSCH_pdu,
                            dlsch);
        stop_meas(&eNB->dlsch_encoding_stats);
knopp's avatar
knopp committed
1125
      }
1126

1127 1128 1129
#endif
      dlsch->active = 0;
}
1130

1131
void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB,
knopp's avatar
knopp committed
1132
			   eNB_rxtx_proc_t *proc,
1133 1134 1135 1136 1137
			   uint8_t abstraction_flag,
                           relaying_type_t r_type,
			   PHY_VARS_RN *rn)
{
  UNUSED(rn);
1138 1139
  int frame=proc->frame_tx;
  int subframe=proc->subframe_tx;
1140
  //  uint16_t input_buffer_length;
1141 1142 1143 1144
  uint32_t i,aa;
  uint8_t harq_pid;
  DCI_PDU *DCI_pdu;
  DCI_PDU DCI_pdu_tmp;
1145
  int8_t UE_id=0;
1146 1147 1148
  uint8_t num_pdcch_symbols=0;
  uint8_t ul_subframe;
  uint32_t ul_frame;
1149
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
1150
  DCI_ALLOC_t *dci_alloc=(DCI_ALLOC_t *)NULL;
1151

1152 1153 1154 1155 1156
#if defined(SMBV) 
  // counts number of allocations in subframe
  // there is at least one allocation for PDCCH
  uint8_t smbv_alloc_cnt = 1;
#endif
1157

1158 1159
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX,1);
  start_meas(&eNB->phy_proc_tx);
1160

1161 1162
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    // If we've dropped the UE, go back to PRACH mode for this UE
1163 1164 1165 1166 1167
    if ((frame==0)