phy_procedures_lte_eNb.c 117 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
48
#include "PHY/LTE_TRANSPORT/if4_tools.h"

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

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

61
62
#include "T.h"

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

66
67
#include <time.h>

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

72
73
74
75
76
77
//#define DIAG_PHY

#define NS_PER_SLOT 500000

#define PUCCH 1

78
79
void exit_fun(const char* s);

80
81
extern int exit_openair;

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

85
86
87
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)));
88
89
int *eNB_sync_buffer[2] = {eNB_sync_buffer0, eNB_sync_buffer1};

90
extern uint16_t hundred_times_log10_NPRB[100];
91

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

//DCI_ALLOC_t dci_alloc[8];

#ifdef EMOS
fifo_dump_emos_eNB emos_dump_eNB;
#endif

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

#ifdef DIAG_PHY
extern int rx_sig_fifo;
#endif

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

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

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

121
122
  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)
123
      return(1);
124
125
  } 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))
126
      return(1);
127
128
  } 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))
129
      return(1);
130
131
  } 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))
132
      return(1);
133
134
  } 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))
135
      return(1);
136
137
138
139
  }

  return(0);
}
140

141
142
143
144
145
146
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
147
void remove_harq_pid_from_freelist(LTE_eNB_DLSCH_t *DLSCH_ptr, int harq_pid)
148
149
150
151
152
{
  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
153
154
155
156
157
158
159
160
161
  /* 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();
  }
162
163
164
  DLSCH_ptr->head_freelist = (DLSCH_ptr->head_freelist + 1) % 10;
}

165
int32_t add_ue(int16_t rnti, PHY_VARS_eNB *eNB)
166
{
gauthier's avatar
gauthier committed
167
  uint8_t i;
168

169
170

  LOG_D(PHY,"[eNB %d/%d] Adding UE with rnti %x\n",
171
172
        eNB->Mod_id,
        eNB->CC_id,
Cedric Roux's avatar
Cedric Roux committed
173
        (uint16_t)rnti);
174
175

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

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

203
int mac_phy_remove_ue(module_id_t Mod_idP,rnti_t rntiP) {
gauthier's avatar
gauthier committed
204
  uint8_t i;
205
  int j,CC_id;
206
  PHY_VARS_eNB *eNB;
207
208

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

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

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

243
int8_t find_next_ue_index(PHY_VARS_eNB *eNB)
244
{
gauthier's avatar
gauthier committed
245
  uint8_t i;
246

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

257
258
259
  return(-1);
}

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

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

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

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

    for (i=0; i<DLSCH_ptr->Mdlharq; i++) {
      if (DLSCH_ptr->harq_processes[i]!=NULL) {
283
	if (DLSCH_ptr->harq_processes[i]->status == ACTIVE) {
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
	  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);
300
      }
301
    }
302
303
304
305
306
307
308
309

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

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

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

325
326
327
  return(0);
}

knopp's avatar
knopp committed
328
int16_t get_target_pusch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
329
{
330
  return PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUSCH;
331
332
}

knopp's avatar
knopp committed
333
334
int16_t get_target_pucch_rx_power(const module_id_t module_idP, const uint8_t CC_id)
{
335
  return PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.ul_power_control_config_common.p0_NominalPUCCH;
knopp's avatar
knopp committed
336
337
}

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

}
#endif



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

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

356

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

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

knopp's avatar
   
knopp committed
370
371
#endif

372

373
374
}

knopp's avatar
   
knopp committed
375
376


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

gauthier's avatar
gauthier committed
381
382
  uint8_t aa;
  uint16_t last_subframe_emos;
383
  uint16_t pilot_pos1 = 3 - eNB->frame_parms.Ncp, pilot_pos2 = 10 - 2*eNB->frame_parms.Ncp;
gauthier's avatar
gauthier committed
384
  uint32_t bytes;
385
386
387

  last_subframe_emos=0;

knopp's avatar
   
knopp committed
388

knopp's avatar
   
knopp committed
389

knopp's avatar
   
knopp committed
390

391
#ifdef EMOS_CHANNEL
392

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

404
405
#endif

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

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

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


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

gauthier's avatar
For RAL    
gauthier committed
438

knopp's avatar
   
knopp committed
439

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

knopp's avatar
   
knopp committed
443

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

knopp's avatar
   
knopp committed
446

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

453
  int subframe = proc->subframe_tx;
454

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

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

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

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

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

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

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
  }
  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,
676
                     AMP,
677
                     &eNB->frame_parms,
678
679
680
681
                     (fp->Ncp==NORMAL) ? 6 : 5,
                     10);
        generate_sss(txdataF,
                     AMP,
682
                     &eNB->frame_parms,
683
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
                     (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
712
void generate_eNB_dlsch_params(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,const int UE_id) {
713

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

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

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

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

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

knopp's avatar
knopp committed
912
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) {
913

914
915
  int frame=proc->frame_tx;
  int subframe=proc->subframe_tx;
916
917
918
  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;
919
  LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
920
921
922
923
924
925
926
927
  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,
928
	frame, subframe, input_buffer_length,
929
930
931
932
933
	get_G(fp,
	      dlsch_harq->nb_rb,
	      dlsch_harq->rb_alloc,
	      get_Qm(dlsch_harq->mcs),
	      dlsch_harq->Nl,
934
	      num_pdcch_symbols,frame,subframe),
935
936
937
938
939
	dlsch_harq->nb_rb,
	dlsch_harq->mcs,
	pmi2hex_2Ar1(dlsch_harq->pmi_alloc),
	dlsch_harq->rvidx,
	dlsch_harq->round);
940

941
942
943
944
945
#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")",
946
        frame, subframe,
947
948
949
950
951
952
        input_buffer_length,
        get_G(fp,
        		dlsch_harq->nb_rb,
        		dlsch_harq->rb_alloc,
        		get_Qm(dlsch_harq->mcs),
        		dlsch_harq->Nl,
953
        		num_pdcch_symbols,frame,subframe),