phy_procedures_lte_eNb.c 122 KB
Newer Older
1
/*******************************************************************************
2
    OpenAirInterface
ghaddab's avatar
ghaddab committed
3
    Copyright(c) 1999 - 2014 Eurecom
4

ghaddab's avatar
ghaddab committed
5
6
7
8
    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.
9
10


ghaddab's avatar
ghaddab committed
11
12
13
14
    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.
15

ghaddab's avatar
ghaddab committed
16
    You should have received a copy of the GNU General Public License
17
18
    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
19
   see <http://www.gnu.org/licenses/>.
20
21

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

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

ghaddab's avatar
ghaddab committed
28
 *******************************************************************************/
29
30
31

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

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

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

50
//#define DEBUG_PHY_PROC (Already defined in cmake)
51
52
53
54
55
56
57
//#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"

58
#include "assertions.h"
gauthier's avatar
gauthier committed
59
#include "msc.h"
60

61
#if defined(ENABLE_ITTI)
gauthier's avatar
For RAL    
gauthier committed
62
#   include "intertask_interface.h"
63
#   if ENABLE_RAL
gauthier's avatar
For RAL    
gauthier committed
64
65
#     include "timer.h"
#   endif
66
67
#endif

68
69
70
71
72
73
74
75
76
//#define DIAG_PHY

#define NS_PER_SLOT 500000

#define PUCCH 1

extern int exit_openair;


77
78
79
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)));
80
81
int *eNB_sync_buffer[2] = {eNB_sync_buffer0, eNB_sync_buffer1};

82
extern uint16_t hundred_times_log10_NPRB[100];
83

84
unsigned int max_peak_val;
85
int max_sync_pos;
86
87
88
89
90
91
92

//DCI_ALLOC_t dci_alloc[8];

#ifdef EMOS
fifo_dump_emos_eNB emos_dump_eNB;
#endif

93
#if defined(SMBV) 
94
95
extern const char smbv_fname[];
extern unsigned short config_frames[4];
gauthier's avatar
gauthier committed
96
extern uint8_t smbv_frame_cnt;
97
98
99
100
101
102
#endif

#ifdef DIAG_PHY
extern int rx_sig_fifo;
#endif

103
104
uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,uint8_t UE_id,uint8_t sched_subframe)
{
knopp's avatar
   
knopp committed
105

gauthier's avatar
gauthier committed
106
107
  const int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
  const int frame = phy_vars_eNB->proc[sched_subframe].frame_rx;
108

109
  LOG_D(PHY,"[eNB %d][SR %x] Frame %d subframe %d Checking for SR TXOp(sr_ConfigIndex %d)\n",
110
111
112
        phy_vars_eNB->Mod_id,phy_vars_eNB->ulsch_eNB[UE_id]->rnti,frame,subframe,
        phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex);

113
  if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 4) {        // 5 ms SR period
114
115
    if ((subframe%5) == phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex)
      return(1);
116
  } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 14) { // 10 ms SR period
117
118
    if (subframe==(phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-5))
      return(1);
119
  } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 34) { // 20 ms SR period
knopp's avatar
   
knopp committed
120
    if ((10*(frame&1)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-15))
121
      return(1);
122
  } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 74) { // 40 ms SR period
knopp's avatar
   
knopp committed
123
    if ((10*(frame&3)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-35))
124
      return(1);
125
  } else if (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex <= 154) { // 80 ms SR period
knopp's avatar
   
knopp committed
126
    if ((10*(frame&7)+subframe) == (phy_vars_eNB->scheduling_request_config[UE_id].sr_ConfigIndex-75))
127
      return(1);
128
129
130
131
  }

  return(0);
}
132

133
134
135
136
137
138
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
139
void remove_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
140
141
142
143
144
{
  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
145
146
147
148
149
150
151
152
153
  /* 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();
  }
154
155
156
  DLSCH_ptr->head_freelist = (DLSCH_ptr->head_freelist + 1) % 10;
}

157
158
int32_t add_ue(int16_t rnti, PHY_VARS_eNB *phy_vars_eNB)
{
gauthier's avatar
gauthier committed
159
  uint8_t i;
160

knopp's avatar
   
knopp committed
161
#ifdef DEBUG_PHY_PROC
Cedric Roux's avatar
Cedric Roux committed
162
163
164
165
  LOG_I(PHY,"[eNB %d/%d] Adding UE with rnti %x\n",
        phy_vars_eNB->Mod_id,
        phy_vars_eNB->CC_id,
        (uint16_t)rnti);
knopp's avatar
   
knopp committed
166
#endif
167
168

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
169
    if ((phy_vars_eNB->dlsch_eNB[i]==NULL) || (phy_vars_eNB->ulsch_eNB[i]==NULL)) {
170
      MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed add ue %"PRIx16" (ENOMEM)", rnti);
171
172
      LOG_E(PHY,"Can't add UE, not enough memory allocated\n");
      return(-1);
173
    } else {
174
      if (phy_vars_eNB->eNB_UE_stats[i].crnti==0) {
175
        MSC_LOG_EVENT(MSC_PHY_ENB, "0 Add ue %"PRIx16" ", rnti);
176
        LOG_D(PHY,"UE_id %d associated with rnti %x\n",i, (uint16_t)rnti);
177
178
179
        phy_vars_eNB->dlsch_eNB[i][0]->rnti = rnti;
        phy_vars_eNB->ulsch_eNB[i]->rnti = rnti;
        phy_vars_eNB->eNB_UE_stats[i].crnti = rnti;
knopp's avatar
knopp committed
180
181
182
183

	phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_below = 0;
	phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH1_above = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB));
	phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH        = (int32_t)pow(10.0,.1*(phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH+phy_vars_eNB->rx_total_gain_eNB_dB));
184
	LOG_D(PHY,"Initializing Po_PUCCH: p0_NominalPUCCH %d, gain %d => %d\n",
knopp's avatar
knopp committed
185
186
187
188
	      phy_vars_eNB->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH,
	      phy_vars_eNB->rx_total_gain_eNB_dB,
	      phy_vars_eNB->eNB_UE_stats[i].Po_PUCCH);
  
189
        return(i);
190
      }
191
    }
192
193
194
195
  }
  return(-1);
}

196
int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) {
gauthier's avatar
gauthier committed
197
  uint8_t i;
198
199
200
201
202
203
204
205
206
207
208
209
210
  int j,CC_id;
  PHY_VARS_eNB *phy_vars_eNB;

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    phy_vars_eNB = PHY_vars_eNB_g[Mod_idP][CC_id];
    for (i=0; i<NUMBER_OF_UE_MAX; i++) {
      if ((phy_vars_eNB->dlsch_eNB[i]==NULL) || (phy_vars_eNB->ulsch_eNB[i]==NULL)) {
	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 {
	if (phy_vars_eNB->eNB_UE_stats[i].crnti==rntiP) {
	  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Removed ue %"PRIx16" ", rntiP);
211
#ifdef DEBUG_PHY_PROC
212
213
	  LOG_I(PHY,"eNB %d removing UE %d with rnti %x\n",phy_vars_eNB->Mod_id,i,rnti);
#endif
214
	  //LOG_D(PHY,("[PHY] UE_id %d\n",i);
215
216
217
218
219
220
221
222
223
224
225
226
227
228
	  clean_eNb_dlsch(phy_vars_eNB->dlsch_eNB[i][0]);
	  clean_eNb_ulsch(phy_vars_eNB->ulsch_eNB[i]);
	  //phy_vars_eNB->eNB_UE_stats[i].crnti = 0;
	  memset(&phy_vars_eNB->eNB_UE_stats[i],0,sizeof(LTE_eNB_UE_stats));
	  //  mac_exit_wrapper("Removing UE");
	  
	  /* clear the harq pid freelist */
	  phy_vars_eNB->dlsch_eNB[i][0]->head_freelist = 0;
	  phy_vars_eNB->dlsch_eNB[i][0]->tail_freelist = 0;
	  for (j = 0; j < 8; j++)
	    put_harq_pid_in_freelist(phy_vars_eNB->dlsch_eNB[i][0], j);
	  
	  return(i);
	}
229
      }
230
    }
231
  }
232
  MSC_LOG_EVENT(MSC_PHY_ENB, "0 Failed remove ue %"PRIx16" (not found)", rntiP);
233
234
235
  return(-1);
}

236
237
int8_t find_next_ue_index(PHY_VARS_eNB *phy_vars_eNB)
{
gauthier's avatar
gauthier committed
238
  uint8_t i;
239

240
  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
241
    if (phy_vars_eNB->eNB_UE_stats[i].crnti==0) {
242
243
244
      /*if ((phy_vars_eNB->dlsch_eNB[i]) &&
      (phy_vars_eNB->dlsch_eNB[i][0]) &&
      (phy_vars_eNB->dlsch_eNB[i][0]->rnti==0))*/
245
246
247
      LOG_D(PHY,"Next free UE id is %d\n",i);
      return(i);
    }
248
  }
249

250
251
252
  return(-1);
}

gauthier's avatar
gauthier committed
253
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)
254
255
256
257
{
  LTE_eNB_DLSCH_t *DLSCH_ptr;
  LTE_eNB_ULSCH_t *ULSCH_ptr;
  uint8_t ulsch_subframe,ulsch_frame;
gauthier's avatar
gauthier committed
258
  uint8_t i;
knopp's avatar
   
knopp committed
259
  int8_t UE_id = find_ue(rnti,PHY_vars_eNB_g[Mod_id][CC_id]);
260
  int sf1=(10*frame)+subframe,sf2,sfdiff,sfdiff_max=7;
261
262

  if (UE_id==-1) {
263
    LOG_D(PHY,"Cannot find UE with rnti %x (Mod_id %d, CC_id %d)\n",rnti, Mod_id, CC_id);
264
265
    *round=0;
    return(-1);
266
267
268
  }

  if (ul_flag == 0)  {// this is a DL request
knopp's avatar
   
knopp committed
269
    DLSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->dlsch_eNB[(uint32_t)UE_id][0];
270

271
272
273
274
275
    // set to no available process first
    *harq_pid = -1;

    for (i=0; i<DLSCH_ptr->Mdlharq; i++) {
      if (DLSCH_ptr->harq_processes[i]!=NULL) {
276
	if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) {
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
	  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);
293
      }
294
    }
295
296
297
298
299
300
301
302

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

303
304
    LOG_D(PHY,"get_ue_active_harq_pid DL => Frame %d, Subframe %d : harq_pid %d\n",
	  frame,subframe,*harq_pid);
305
  } else { // This is a UL request
306

knopp's avatar
   
knopp committed
307
308
309
    ULSCH_ptr = PHY_vars_eNB_g[Mod_id][CC_id]->ulsch_eNB[(uint32_t)UE_id];
    ulsch_subframe = pdcch_alloc2ul_subframe(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,subframe);
    ulsch_frame    = pdcch_alloc2ul_frame(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,frame,subframe);
310
    // Note this is for TDD configuration 3,4,5 only
knopp's avatar
   
knopp committed
311
    *harq_pid = subframe2harq_pid(&PHY_vars_eNB_g[Mod_id][CC_id]->lte_frame_parms,
312
313
                                  ulsch_frame,
                                  ulsch_subframe);
314
    *round    = ULSCH_ptr->harq_processes[*harq_pid]->round;
315
    LOG_T(PHY,"[eNB %d][PUSCH %d] Frame %d subframe %d Checking HARQ, round %d\n",Mod_id,*harq_pid,frame,subframe,*round);
316
  }
317

318
319
320
  return(0);
}

knopp's avatar
knopp committed
321
int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
322
{
323
324
  //return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm;
  return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
325
326
}

knopp's avatar
knopp committed
327
328
329
330
331
332
int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
{
  //return PHY_vars_eNB_g[module_idP][CC_id]->PHY_measurements_eNB[0].n0_power_tot_dBm;
  return PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
}

333
#ifdef EMOS
334
335
void phy_procedures_emos_eNB_TX(unsigned char subframe, PHY_VARS_eNB *phy_vars_eNB)
{
336
337
338
339
340
341

}
#endif



342
343
344
void phy_procedures_eNB_S_RX(unsigned char sched_subframe,PHY_VARS_eNB *phy_vars_eNB,uint8_t abstraction_flag,relaying_type_t r_type)
{
  UNUSED(r_type);
345

346
  int subframe = phy_vars_eNB->proc[sched_subframe].subframe_rx;
347

348
#ifdef DEBUG_PHY_PROC
349
  LOG_D(PHY,"[eNB %d] Frame %d: Doing phy_procedures_eNB_S_RX(%d)\n", phy_vars_eNB->Mod_id,phy_vars_eNB->proc[sched_subframe].frame_rx, subframe);
350
#endif
351

352

knopp's avatar
   
knopp committed
353
354
  if (abstraction_flag == 0) {
    lte_eNB_I0_measurements(phy_vars_eNB,
355
			    subframe,
356
357
                            0,
                            phy_vars_eNB->first_run_I0_measurements);
knopp's avatar
   
knopp committed
358
  }
359

360
#ifdef PHY_ABSTRACTION
knopp's avatar
   
knopp committed
361
362
  else {
    lte_eNB_I0_measurements_emul(phy_vars_eNB,
363
                                 0);
364
  }
365

knopp's avatar
   
knopp committed
366
367
#endif

368

369
370
}

knopp's avatar
   
knopp committed
371
372


373
#ifdef EMOS
374
375
376
void phy_procedures_emos_eNB_RX(unsigned char subframe,PHY_VARS_eNB *phy_vars_eNB)
{

gauthier's avatar
gauthier committed
377
378
379
380
  uint8_t aa;
  uint16_t last_subframe_emos;
  uint16_t pilot_pos1 = 3 - phy_vars_eNB->lte_frame_parms.Ncp, pilot_pos2 = 10 - 2*phy_vars_eNB->lte_frame_parms.Ncp;
  uint32_t bytes;
381
382
383

  last_subframe_emos=0;

knopp's avatar
   
knopp committed
384

knopp's avatar
   
knopp committed
385

knopp's avatar
   
knopp committed
386

387
#ifdef EMOS_CHANNEL
388

389
  //if (last_slot%2==1) // this is for all UL subframes
390
  if (subframe==3)
391
    for (aa=0; aa<phy_vars_eNB->lte_frame_parms.nb_antennas_rx; aa++) {
392
393
394
395
396
397
      memcpy(&emos_dump_eNB.channel[aa][last_subframe_emos*2*phy_vars_eNB->lte_frame_parms.N_RB_UL*12],
             &phy_vars_eNB->lte_eNB_pusch_vars[0]->drs_ch_estimates[0][aa][phy_vars_eNB->lte_frame_parms.N_RB_UL*12*pilot_pos1],
             phy_vars_eNB->lte_frame_parms.N_RB_UL*12*sizeof(int));
      memcpy(&emos_dump_eNB.channel[aa][(last_subframe_emos*2+1)*phy_vars_eNB->lte_frame_parms.N_RB_UL*12],
             &phy_vars_eNB->lte_eNB_pusch_vars[0]->drs_ch_estimates[0][aa][phy_vars_eNB->lte_frame_parms.N_RB_UL*12*pilot_pos2],
             phy_vars_eNB->lte_frame_parms.N_RB_UL*12*sizeof(int));
398
    }
399

400
401
#endif

knopp's avatar
   
knopp committed
402
  if (subframe==4) {
403
    emos_dump_eNB.timestamp = rt_get_time_ns();
jiangx's avatar
jiangx committed
404
    emos_dump_eNB.frame_tx = phy_vars_eNB->proc[subframe].frame_rx;
405
406
407
408
409
410
411
412
    emos_dump_eNB.rx_total_gain_dB = phy_vars_eNB->rx_total_gain_eNB_dB;
    emos_dump_eNB.mimo_mode = phy_vars_eNB->transmission_mode[0];
    memcpy(&emos_dump_eNB.PHY_measurements_eNB,
           &phy_vars_eNB->PHY_measurements_eNB[0],
           sizeof(PHY_MEASUREMENTS_eNB));
    memcpy(&emos_dump_eNB.eNB_UE_stats[0],&phy_vars_eNB->eNB_UE_stats[0],NUMBER_OF_UE_MAX*sizeof(LTE_eNB_UE_stats));

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

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


#define AMP_OVER_SQRT2 ((AMP*ONE_OVER_SQRT2_Q15)>>15)
#define AMP_OVER_2 (AMP>>1)
431
432
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)};
433

gauthier's avatar
For RAL    
gauthier committed
434
435

#if defined(ENABLE_ITTI)
436
#   if ENABLE_RAL
gauthier's avatar
For RAL    
gauthier committed
437
438
extern PHY_MEASUREMENTS PHY_measurements;

439
440
void phy_eNB_lte_measurement_thresholds_test_and_report(instance_t instanceP, ral_threshold_phy_t* threshold_phy_pP, uint16_t valP)
{
knopp's avatar
   
knopp committed
441
  MessageDef *message_p = NULL;
442

knopp's avatar
   
knopp committed
443
  if (
444
445
446
447
448
449
    (
      ((threshold_phy_pP->threshold.threshold_val <  valP) && (threshold_phy_pP->threshold.threshold_xdir == RAL_ABOVE_THRESHOLD)) ||
      ((threshold_phy_pP->threshold.threshold_val >  valP) && (threshold_phy_pP->threshold.threshold_xdir == RAL_BELOW_THRESHOLD))
    )  ||
    (threshold_phy_pP->threshold.threshold_xdir == RAL_NO_THRESHOLD)
  ) {
knopp's avatar
   
knopp committed
450
451
452
453
    message_p = itti_alloc_new_message(TASK_PHY_ENB , PHY_MEAS_REPORT_IND);
    memset(&PHY_MEAS_REPORT_IND(message_p), 0, sizeof(PHY_MEAS_REPORT_IND(message_p)));

    memcpy(&PHY_MEAS_REPORT_IND (message_p).threshold,
454
455
           &threshold_phy_pP->threshold,
           sizeof(PHY_MEAS_REPORT_IND (message_p).threshold));
knopp's avatar
   
knopp committed
456
457

    memcpy(&PHY_MEAS_REPORT_IND (message_p).link_param,
458
459
460
           &threshold_phy_pP->link_param,
           sizeof(PHY_MEAS_REPORT_IND (message_p).link_param));
    \
knopp's avatar
   
knopp committed
461
462
463
464
465

    switch (threshold_phy_pP->link_param.choice) {
    case RAL_LINK_PARAM_CHOICE_LINK_PARAM_VAL:
      PHY_MEAS_REPORT_IND (message_p).link_param._union.link_param_val = valP;
      break;
466

knopp's avatar
   
knopp committed
467
468
469
470
    case RAL_LINK_PARAM_CHOICE_QOS_PARAM_VAL:
      //PHY_MEAS_REPORT_IND (message_p).link_param._union.qos_param_val.
      AssertFatal (1 == 0, "TO DO RAL_LINK_PARAM_CHOICE_QOS_PARAM_VAL\n");
      break;
471
    }
472

knopp's avatar
   
knopp committed
473
474
    itti_send_msg_to_task(TASK_RRC_ENB, instanceP, message_p);
  }
gauthier's avatar
For RAL    
gauthier committed
475
476
}

477
478
void phy_eNB_lte_check_measurement_thresholds(instance_t instanceP, ral_threshold_phy_t* threshold_phy_pP)
{
knopp's avatar
   
knopp committed
479
480
481
482
483
484
485
486
487
488
489
  unsigned int  mod_id;

  mod_id = instanceP;

  switch (threshold_phy_pP->link_param.link_param_type.choice) {

  case RAL_LINK_PARAM_TYPE_CHOICE_GEN:
    switch (threshold_phy_pP->link_param.link_param_type._union.link_param_gen) {
    case RAL_LINK_PARAM_GEN_DATA_RATE:
      phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0);
      break;
490

knopp's avatar
   
knopp committed
491
492
493
    case RAL_LINK_PARAM_GEN_SIGNAL_STRENGTH:
      phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0);
      break;
494

knopp's avatar
   
knopp committed
495
496
497
    case RAL_LINK_PARAM_GEN_SINR:
      phy_eNB_lte_measurement_thresholds_test_and_report(instanceP, threshold_phy_pP, 0);
      break;
498

knopp's avatar
   
knopp committed
499
500
    case RAL_LINK_PARAM_GEN_THROUGHPUT:
      break;
501

knopp's avatar
   
knopp committed
502
503
    case RAL_LINK_PARAM_GEN_PACKET_ERROR_RATE:
      break;
504
505
506

    default:
      ;
gauthier's avatar
For RAL    
gauthier committed
507
    }
508

knopp's avatar
   
knopp committed
509
510
511
512
513
514
    break;

  case RAL_LINK_PARAM_TYPE_CHOICE_LTE:
    switch (threshold_phy_pP->link_param.link_param_type._union.link_param_gen) {
    case RAL_LINK_PARAM_LTE_UE_RSRP:
      break;
515

knopp's avatar
   
knopp committed
516
517
    case RAL_LINK_PARAM_LTE_UE_RSRQ:
      break;
518

knopp's avatar
   
knopp committed
519
520
    case RAL_LINK_PARAM_LTE_UE_CQI:
      break;
521

knopp's avatar
   
knopp committed
522
523
    case RAL_LINK_PARAM_LTE_AVAILABLE_BW:
      break;
524

knopp's avatar
   
knopp committed
525
526
    case RAL_LINK_PARAM_LTE_PACKET_DELAY:
      break;
527

knopp's avatar
   
knopp committed
528
529
    case RAL_LINK_PARAM_LTE_PACKET_LOSS_RATE:
      break;
530

knopp's avatar
   
knopp committed
531
532
    case RAL_LINK_PARAM_LTE_L2_BUFFER_STATUS:
      break;
533

knopp's avatar
   
knopp committed
534
535
    case RAL_LINK_PARAM_LTE_MOBILE_NODE_CAPABILITIES:
      break;
536

knopp's avatar
   
knopp committed
537
538
    case RAL_LINK_PARAM_LTE_EMBMS_CAPABILITY:
      break;
539

knopp's avatar
   
knopp committed
540
541
    case RAL_LINK_PARAM_LTE_JUMBO_FEASIBILITY:
      break;
542

knopp's avatar
   
knopp committed
543
544
    case RAL_LINK_PARAM_LTE_JUMBO_SETUP_STATUS:
      break;
545

knopp's avatar
   
knopp committed
546
547
    case RAL_LINK_PARAM_LTE_NUM_ACTIVE_EMBMS_RECEIVERS_PER_FLOW:
      break;
548
549
550

    default:
      ;
knopp's avatar
   
knopp committed
551
    }
552

knopp's avatar
   
knopp committed
553
554
    break;

555
556
  default:
    ;
knopp's avatar
   
knopp committed
557
  }
gauthier's avatar
For RAL    
gauthier committed
558
559
560
561
}
#   endif
#endif

knopp's avatar
   
knopp committed
562

Cedric Roux's avatar
Cedric Roux committed
563
unsigned int taus(void);
knopp's avatar
   
knopp committed
564

565
566
void pmch_procedures(PHY_VARS_eNB *eNB,PHY_VARS_RN *rn, int subframe,int sched_subframe,int abstraction_flag,relaying_type_t r_type) {

567
#ifdef Rel10
568
569
  MCH_PDU *mch_pduP;
  MCH_PDU  mch_pdu;
570
  //  uint8_t sync_area=255;
571
#endif
572

knopp's avatar
   
knopp committed
573
  if (abstraction_flag==0) {
574
575
576
577
578
    // This is DL-Cell spec pilots in Control region
    generate_pilots_slot(eNB,
			 eNB->lte_eNB_common_vars.txdataF[0],
			 AMP,
			 subframe<<1,1);
knopp's avatar
   
knopp committed
579
  }
580
  
581
#ifdef Rel10
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
  // 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,
				    eNB->proc[sched_subframe].frame_tx,
				    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",
	    eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,mch_pduP->mcs,
	    eNB->dlsch_eNB_MCH->harq_processes[0]->TBS>>3);
    else {
      LOG_D(PHY,"[DeNB %"PRIu8"] Frame %d subframe %d : Do not transmit MCH pdu for MBSFN sync area %"PRIu8" (%s)\n",
	    eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,mch_pduP->sync_area,
	    (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
619
    } else {
620
      mch_pduP=NULL;
621
    }
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
    
    rn->mch_avtive[subframe]=0;
    break;
    
  default:
    LOG_W(PHY,"[eNB %"PRIu8"] Frame %d subframe %d: unknown relaying type %d \n",
	  eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,r_type);
    mch_pduP=NULL;
    break;
  }// switch
  
  if (mch_pduP) {
    fill_eNB_dlsch_MCH(eNB,mch_pduP->mcs,1,0, abstraction_flag);
    // Generate PMCH
    generate_mch(eNB,sched_subframe,(uint8_t*)mch_pduP->payload,abstraction_flag);
  } else {
    LOG_D(PHY,"[eNB/RN] Frame %d subframe %d: MCH not generated \n",eNB->proc[sched_subframe].frame_tx,subframe);
knopp's avatar
   
knopp committed
639
  }
640
641
642
  
#endif
}
643

644
void common_signal_procedures (int subframe,int sched_subframe,PHY_VARS_eNB *eNB,int abstraction_flag) {
645

646
647
648
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
  int **txdataF = eNB->lte_eNB_common_vars.txdataF[0];
  uint8_t *pbch_pdu=&eNB->pbch_pdu[0];
649

650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
  // 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
666

667
  // First half of PSS/SSS (FDD, slot 0)
knopp's avatar
   
knopp committed
668
  if (subframe == 0) {
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
    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);
      
    }
    
684
    // generate PBCH (Physical Broadcast CHannel) info
685
    if ((eNB->proc[sched_subframe].frame_tx&3) == 0) {
686
      pbch_pdu[2] = 0;
687
      
688
      // FIXME setting pbch_pdu[2] to zero makes the switch statement easier: remove all the or-operators
689
      switch (fp->N_RB_DL) {
knopp's avatar
   
knopp committed
690
      case 6:
691
692
693
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (0<<5);
	break;
	
knopp's avatar
   
knopp committed
694
      case 15:
695
696
697
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (1<<5);
	break;
	
knopp's avatar
   
knopp committed
698
      case 25:
699
700
701
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (2<<5);
	break;
	
knopp's avatar
   
knopp committed
702
      case 50:
703
704
705
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (3<<5);
	break;
	
knopp's avatar
   
knopp committed
706
      case 75:
707
708
709
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (4<<5);
	break;
	
knopp's avatar
   
knopp committed
710
      case 100:
711
712
713
	pbch_pdu[2] = (pbch_pdu[2]&0x1f) | (5<<5);
	break;
	
knopp's avatar
   
knopp committed
714
      default:
715
716
717
	// 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
718
      }
719
      
720
      pbch_pdu[2] = (pbch_pdu[2]&0xef) |
721
722
723
	((fp->phich_config_common.phich_duration << 4)&0x10);
      
      switch (fp->phich_config_common.phich_resource) {
knopp's avatar
   
knopp committed
724
      case oneSixth:
725
726
727
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (0<<2);
	break;
	
knopp's avatar
   
knopp committed
728
      case half:
729
730
731
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (1<<2);
	break;
	
knopp's avatar
   
knopp committed
732
      case one:
733
734
735
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (2<<2);
	break;
	
knopp's avatar
   
knopp committed
736
      case two:
737
738
739
	pbch_pdu[2] = (pbch_pdu[2]&0xf3) | (3<<2);
	break;
	
knopp's avatar
   
knopp committed
740
      default:
741
742
	// unreachable
	break;
knopp's avatar
   
knopp committed
743
      }
744
745
746
      
      pbch_pdu[2] = (pbch_pdu[2]&0xfc) | ((eNB->proc[sched_subframe].frame_tx>>8)&0x3);
      pbch_pdu[1] = eNB->proc[sched_subframe].frame_tx&0xfc;
747
      pbch_pdu[0] = 0;
knopp's avatar
   
knopp committed
748
    }
749
750
751
752
753
754
755
756
757
758
759
      
    /// 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);
    }
760

761
    /// generate PBCH
knopp's avatar
   
knopp committed
762
    if (abstraction_flag==0) {
763
764
765
766
767
768
769
770
771
772
773
774
      generate_pbch(&eNB->lte_eNB_pbch,
                    txdataF,
                    AMP,
                    fp,
                    pbch_pdu,
                    eNB->proc[sched_subframe].frame_tx&3);
    }
#ifdef PHY_ABSTRACTION
    else {
      generate_pbch_emul(eNB,pbch_pdu);
    }
#endif
775

776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
  }
  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,
792
                     AMP,
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
                     &eNB->lte_frame_parms,
                     (fp->Ncp==NORMAL) ? 6 : 5,
                     10);
        generate_sss(txdataF,
                     AMP,
                     &eNB->lte_frame_parms,
                     (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);
  }

}

void generate_eNB_dlsch_params(const int frame,const int subframe,int sched_subframe,PHY_VARS_eNB *eNB,DCI_ALLOC_t *dci_alloc,const int UE_id) {

  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;

  // 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,
				       &eNB->dlsch_eNB_SI,
				       fp,
				       eNB->pdsch_config_dedicated,
				       SI_RNTI,
				       0,
				       P_RNTI,
				       eNB->eNB_UE_stats[0].DL_pmi_single);
    
    
    eNB->dlsch_eNB_SI->nCCE[subframe] = dci_alloc->firstCCE;
    
    LOG_T(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (SI)  => %"PRIu8"\n",eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,
	  eNB->dlsch_eNB_SI->nCCE[subframe]);
    
#if defined(SMBV) 
    
    // configure SI DCI
    if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, SI in SF %d DCI %"PRIu32"\n",eNB->proc[sched_subframe].frame_tx,subframe,i);
      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,
				       &eNB->dlsch_eNB_ra,
				       fp,
				       eNB->pdsch_config_dedicated,
				       SI_RNTI,
				       dci_alloc->rnti,
				       P_RNTI,
				       eNB->eNB_UE_stats[0].DL_pmi_single);
    
    
    eNB->dlsch_eNB_ra->nCCE[subframe] = dci_alloc->firstCCE;
    
    LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for common DCI (RA)  => %"PRIu8"\n",eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,
	  eNB->dlsch_eNB_ra->nCCE[subframe]);
#if defined(SMBV) 
    
    // configure RA DCI
    if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
      LOG_D(PHY,"[SMBV] Frame %3d, RA in SF %d DCI %"PRIu32"\n",eNB->proc[sched_subframe].frame_tx,subframe,i);
      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
      if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (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",eNB->proc[sched_subframe].frame_tx,subframe,(smbv_frame_cnt*10) + (subframe),UE_id+1,
              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,
					 eNB->dlsch_eNB[(uint8_t)UE_id],
					 fp,
					 eNB->pdsch_config_dedicated,
					 SI_RNTI,
					 0,
					 P_RNTI,
					 eNB->eNB_UE_stats[(uint8_t)UE_id].DL_pmi_single);
      LOG_D(PHY,"[eNB %"PRIu8"][PDSCH %"PRIx16"/%"PRIu8"] Frame %d subframe %d: Generated dlsch params\n",
	    eNB->Mod_id,dci_alloc->rnti,eNB->dlsch_eNB[(uint8_t)UE_id][0]->current_harq_pid,eNB->proc[sched_subframe].frame_tx,subframe);
      
      
      eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe] = dci_alloc->firstCCE;
      
      LOG_D(PHY,"[eNB %"PRIu8"] Frame %d subframe %d : CCE resource for ue DCI (PDSCH %"PRIx16")  => %"PRIu8"/%u\n",eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,
	    dci_alloc->rnti,eNB->dlsch_eNB[(uint8_t)UE_id][0]->nCCE[subframe]);
      
#if defined(SMBV) 
      
      // configure UE-spec DCI
      if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
	LOG_D(PHY,"[SMBV] Frame %3d, PDSCH in SF %d DCI %"PRIu32"\n",eNB->proc[sched_subframe].frame_tx,subframe,i);
	smbv_configure_ue_spec_dci(smbv_fname,(smbv_frame_cnt*10) + (subframe), UE_id+1,dci_alloc, i);
knopp's avatar
   
knopp committed
944
      }
945
946
947
948
949
950
951
952
953
954
955
      
#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,
	    eNB->proc[sched_subframe].frame_tx, subframe,UE_id,
	    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",
	    eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,dci_alloc->rnti);
knopp's avatar
   
knopp committed
956
    }
957
958
959
  }
  
}
960

961
void generate_eNB_ulsch_params(const int frame,const int subframe,int sched_subframe,PHY_VARS_eNB *eNB,DCI_ALLOC_t *dci_alloc,const int UE_id) {
962

963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
  int harq_pid;
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
  
  LOG_D(PHY,
	"[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,
			  pdcch_alloc2ul_frame(fp,eNB->proc[sched_subframe].frame_tx,subframe),
			  pdcch_alloc2ul_subframe(fp,subframe)),
	eNB->proc[sched_subframe].frame_tx,
	subframe,
	pdcch_alloc2ul_frame(fp,eNB->proc[sched_subframe].frame_tx,subframe),
	pdcch_alloc2ul_subframe(fp,subframe),
	dci_alloc->rnti,
	dci_alloc->dci_pdu[0],
	1<<dci_alloc->L);
  
  generate_eNB_ulsch_params_from_dci(&dci_alloc->dci_pdu[0],
				     dci_alloc->rnti,
				     sched_subframe,
				     format0,
				     UE_id,
				     eNB,
				     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",
	eNB->Mod_id,eNB->proc[sched_subframe].frame_tx,subframe,dci_alloc->rnti,
	dci_alloc->firstCCE);
  
#if defined(SMBV) 
  
  // configure UE-spec DCI for UL Grant
  if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
    LOG_D(PHY,"[SMBV] Frame %3d, SF %d UL DCI %"PRIu32"\n",eNB->proc[sched_subframe].frame_tx,subframe,i);
    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,
			       pdcch_alloc2ul_frame(fp,eNB->proc[sched_subframe].frame_tx,subframe),
			       pdcch_alloc2ul_subframe(fp,subframe));
  
  if (harq_pid==255) { // should not happen, log an error and exit, this is a fatal error
    LOG_E(PHY,"[eNB %"PRIu8"] Frame %d: Bad harq_pid for ULSCH allocation\n",eNB->Mod_id,eNB->proc[sched_subframe].frame_tx);
    mac_xface->macphy_exit("FATAL\n"); 
  }
  
  if ((dci_alloc->rnti  >= CBA_RNTI) && (dci_alloc->rnti < P_RNTI))
    eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_cba_scheduling_flag = 1;
  else
    eNB->ulsch_eNB[(uint32_t)UE_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1;
  
}
1023

1024
void pdsch_procedures(PHY_VARS_eNB *eNB,LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch1,LTE_eNB_UE_stats *ue_stats,int ra_flag,int subframe,int sched_subframe,int num_pdcch_symbols,int abstraction_flag) {
1025

1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
  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;
  LTE_DL_FRAME_PARMS *fp=&eNB->lte_frame_parms;
  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,
	eNB->proc[sched_subframe].frame_tx, subframe, input_buffer_length,
	get_G(fp,
	      dlsch_harq->nb_rb,
	      dlsch_harq->rb_alloc,
	      get_Qm(dlsch_harq->mcs),
	      dlsch_harq->Nl,
	      num_pdcch_symbols,eNB->proc[sched_subframe].frame_tx,subframe),
	dlsch_harq->nb_rb,
	dlsch_harq->mcs,
	pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
	dlsch_harq->rvidx,
	dlsch_harq->round);
1050

1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
#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")",
        eNB->proc[sched_subframe].frame_tx, subframe,
        input_buffer_length,
        get_G(fp,
        		dlsch_harq->nb_rb,
        		dlsch_harq->rb_alloc,
        		get_Qm(dlsch_harq->mcs),
        		dlsch_harq->Nl,
        		num_pdcch_symbols,eNB->proc[sched_subframe].frame_tx,subframe),
        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,
						 eNB->proc[sched_subframe].frame_tx,
						 dlsch->rnti,
						 0);
	  }
	  else {
	    int16_t crnti = mac_xface->fill_rar(eNB->Mod_id,
						eNB->CC_id,
						eNB->proc[sched_subframe].frame_tx,
						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,
					eNB->proc[sched_subframe].frame_tx,
					crnti);
	    } else {
	      eNB->eNB_UE_stats[(uint32_t)UE_id].mode = RA_RESPONSE;
	      // 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,
						 eNB->proc[sched_subframe].frame_tx,
						 (subframe),
						 eNB->ulsch_eNB[(uint32_t)UE_id],
						 fp);
	      
	      eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_active = 1;
	      
	      get_Msg3_alloc(fp,
			     subframe,
			     eNB->proc[sched_subframe].frame_tx,
			     &eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame,
			     &eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe);
	      LOG_D(PHY,"[eNB][RAPROC] Frame %d subframe %d, Activated Msg3 demodulation for UE %"PRId8" in frame %"PRIu32", subframe %"PRIu8"\n",
		    eNB->proc[sched_subframe].frame_tx,
		    subframe,
		    UE_id,
		    eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_frame,
		    eNB->ulsch_eNB[(uint32_t)UE_id]->Msg3_subframe);
	    }
	    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) 
1144

1145
1146
1147
1148
1149
        // Configures the data source of allocation (allocation is configured by DCI)
        if (smbv_is_config_frame(eNB->proc[sched_subframe].frame_tx) && (smbv_frame_cnt < 4)) {
          LOG_D(PHY,"[SMBV] Frame %3d, Configuring PDSCH payload in SF %d alloc %"PRIu8"\n",eNB->proc[sched_subframe].frame_tx,(smbv_frame_cnt*10) + (subframe),smbv_alloc_cnt);
          smbv_configure_datalist_for_user(smbv_fname, find_ue(dlsch->rnti,eNB)+1, DLSCH_pdu, input_buffer_length);
        }
1150

1151
#endif
1152

1153
1154
1155
1156
1157
1158
1159
1160
1161

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

        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
1162
#endif
1163
1164
1165
1166
1167
1168
1169
1170
1171
#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
      }
1172

1173
      if (abstraction_flag==0) {
1174

1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
	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,
                       eNB->proc[sched_subframe].frame_tx,subframe,
                       &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,
                               num_pdcch_symbols,eNB->proc[sched_subframe].frame_tx,subframe),
                         0,
                         subframe<<1);
        stop_meas(&eNB->dlsch_scrambling_stats);
        start_meas(&eNB->dlsch_modulation_stats);
1202
1203


1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
        dlsch_modulation(eNB->lte_eNB_common_vars.txdataF[0],
			 AMP,
			 subframe,
			 fp,
			 num_pdcch_symbols,
			 dlsch,
			 dlsch1);
	
        stop_meas(&eNB->dlsch_modulation_stats);
      }
1214

1215
1216
1217
1218
1219
1220
1221
#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
1222
      }
1223

1224
1225
1226
#endif
      dlsch->active = 0;
}
1227

1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
void phy_procedures_eNB_TX(unsigned char sched_subframe,
			   PHY_VARS_eNB *eNB,
			   uint8_t abstraction_flag,