lte-softmodem.c 40.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22
23
/*! \file lte-enb.c
 * \brief Top-level threads for eNodeB
24
 * \author R. Knopp, F. Kaltenberger, Navid Nikaein
knopp's avatar
   
knopp committed
25
26
27
 * \date 2012
 * \version 0.1
 * \company Eurecom
28
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
knopp's avatar
   
knopp committed
29
30
31
 * \note
 * \warning
 */
32

33

34

35
36
#include "T.h"

37
#include "rt_wrapper.h"
38

39

40
41
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all

42
#include "assertions.h"
43
#include "msc.h"
44
45

#include "PHY/types.h"
46

47
#include "PHY/defs.h"
48
#include "common/ran_context.h"
49
#include "common/config/config_userapi.h"
50

51
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
knopp's avatar
   
knopp committed
52
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
53

knopp's avatar
   
knopp committed
54
#include "../../ARCH/COMMON/common_lib.h"
55
#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
knopp's avatar
   
knopp committed
56

knopp's avatar
   
knopp committed
57
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
58
59
60
61
62
63
64
65
66

#include "PHY/vars.h"
#include "SCHED/vars.h"
#include "LAYER2/MAC/vars.h"

#include "../../SIMU/USER/init_lte.h"

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/vars.h"
67
#include "LAYER2/MAC/proto.h"
68
69
70
71
72
73
74
75
#include "RRC/LITE/vars.h"
#include "PHY_INTERFACE/vars.h"

#ifdef SMBV
#include "PHY/TOOLS/smbv.h"
unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "UTIL/LOG/log_extern.h"
nikaeinn's avatar
nikaeinn committed
76
#include "UTIL/OTG/otg_tx.h"
77
#include "UTIL/OTG/otg_externs.h"
78
79
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
80
#include "UTIL/OPT/opt.h"
81
#include "enb_config.h"
nikaeinn's avatar
nikaeinn committed
82
//#include "PHY/TOOLS/time_meas.h"
83

Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
84
85
86
87
#ifndef OPENAIR2
#include "UTIL/OTG/otg_vars.h"
#endif

88
#if defined(ENABLE_ITTI)
89
90
#include "intertask_interface_init.h"
#include "create_tasks.h"
91
92
#endif

93
94
#include "system.h"

95
96
97
#ifdef XFORMS
#include "PHY/TOOLS/lte_phy_scope.h"
#include "stats.h"
98
#endif
99
#include "lte-softmodem.h"
100

101

102
#ifdef XFORMS
103
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
gauthier's avatar
gauthier committed
104
// at eNB 0, an UL scope for every UE
105
FD_lte_phy_scope_ue  *form_ue[NUMBER_OF_UE_MAX];
106
FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
107
FD_stats_form                  *form_stats=NULL,*form_stats_l2=NULL;
108
char title[255];
109
unsigned char                   scope_enb_num_ue = 2;
110
static pthread_t                forms_thread; //xforms
111
112
#endif //XFORMS

knopp's avatar
   
knopp committed
113
114
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
115
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
116

117
118
uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
knopp's avatar
   
knopp committed
119

120
#if defined(ENABLE_ITTI)
121
122
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
123
#endif
knopp's avatar
knopp committed
124
volatile int             oai_exit = 0;
125

126
static clock_source_t clock_source = internal;
127
static int wait_for_sync = 0;
knopp's avatar
   
knopp committed
128

knopp's avatar
knopp committed
129
static char              UE_flag=0;
130
unsigned int                    mmapped_dma=0;
131
int                             single_thread_flag=1;
132

133
static char                     threequarter_fs=0;
134

135
uint32_t                 downlink_frequency[MAX_NUM_CCs][4];
136
int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
gauthier's avatar
gauthier committed
137

138

oai's avatar
oai committed
139

140
#if defined(ENABLE_ITTI)
141
static char                    *itti_dump_file = NULL;
knopp's avatar
   
knopp committed
142
143
#endif

144
int UE_scan = 1;
145
int UE_scan_carrier = 0;
146
147
runmode_t mode = normal_txrx;

148
149
FILE *input_fd=NULL;

150

151
152
#if MAX_NUM_CCs == 1
rx_gain_t                rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}};
kortke's avatar
kortke committed
153
154
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}};
155
156
157
158
#else
rx_gain_t                rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain},{max_gain,max_gain,max_gain,max_gain}};
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}};
gauthier's avatar
gauthier committed
159
#endif
knopp's avatar
   
knopp committed
160

fnabet's avatar
fnabet committed
161
double rx_gain_off = 0.0;
162

knopp's avatar
   
knopp committed
163
double sample_rate=30.72e6;
164
double bw = 10.0e6;
165

166
static int                      tx_max_power[MAX_NUM_CCs]; /* =  {0,0}*/;
167

168
169
char   rf_config_file[1024];

Florian Kaltenberger's avatar
Florian Kaltenberger committed
170
int chain_offset=0;
171
int phy_test = 0;
172
uint8_t usim_test = 0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
173

174
175
176
uint8_t dci_Format = 0;
uint8_t agregation_Level =0xFF;

177
178
uint8_t nb_antenna_tx = 1;
uint8_t nb_antenna_rx = 1;
179

knopp's avatar
   
knopp committed
180
181
182
char ref[128] = "internal";
char channels[128] = "0";

183
int                      rx_input_level_dBm;
184
static int                      online_log_messages=0;
185
#ifdef XFORMS
186
extern int                      otg_enabled;
187
static char                     do_forms=0;
188
#else
189
int                             otg_enabled;
190
#endif
knopp's avatar
   
knopp committed
191
//int                             number_of_cards =   1;
192

193
194

static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
Florian Kaltenberger's avatar
Florian Kaltenberger committed
195
uint32_t target_dl_mcs = 28; //maximum allowed mcs
196
uint32_t target_ul_mcs = 20;
197
uint32_t timing_advance = 0;
198
199
uint8_t exit_missed_slots=1;
uint64_t num_missed_slots=0; // counter for the number of missed slots
200

201

202
203
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
204

205
int transmission_mode=1;
knopp's avatar
   
knopp committed
206

207
int16_t           glog_level         = LOG_INFO;
gauthier's avatar
   
gauthier committed
208
int16_t           glog_verbosity     = LOG_MED;
209
int16_t           hw_log_level       = LOG_INFO;
gauthier's avatar
   
gauthier committed
210
int16_t           hw_log_verbosity   = LOG_MED;
211
int16_t           phy_log_level      = LOG_DEBUG;
gauthier's avatar
   
gauthier committed
212
int16_t           phy_log_verbosity  = LOG_MED;
213
int16_t           mac_log_level      = LOG_DEBUG;
gauthier's avatar
   
gauthier committed
214
int16_t           mac_log_verbosity  = LOG_MED;
215
int16_t           rlc_log_level      = LOG_INFO;
gauthier's avatar
   
gauthier committed
216
int16_t           rlc_log_verbosity  = LOG_MED;
217
int16_t           pdcp_log_level     = LOG_INFO;
gauthier's avatar
   
gauthier committed
218
int16_t           pdcp_log_verbosity = LOG_MED;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
219
int16_t           rrc_log_level      = LOG_INFO;
gauthier's avatar
   
gauthier committed
220
int16_t           rrc_log_verbosity  = LOG_MED;
221
222
223
int16_t           opt_log_level      = LOG_INFO;
int16_t           opt_log_verbosity  = LOG_MED;

gauthier's avatar
   
gauthier committed
224
225
226
227
228
229
# if defined(ENABLE_USE_MME)
int16_t           gtpu_log_level     = LOG_DEBUG;
int16_t           gtpu_log_verbosity = LOG_MED;
int16_t           udp_log_level      = LOG_DEBUG;
int16_t           udp_log_verbosity  = LOG_MED;
#endif
230
231
232
#if defined (ENABLE_SECURITY)
int16_t           osa_log_level      = LOG_INFO;
int16_t           osa_log_verbosity  = LOG_MED;
233
#endif
234

235
236
237
/* struct for ethernet specific parameters given in eNB conf file */
eth_params_t *eth_params;

238
239
240
241
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

242
243
extern char uecap_xer[1024];
char uecap_xer_in=0;
244

245
int oaisim_flag=0;
246
threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
knopp's avatar
   
knopp committed
247

Cedric Roux's avatar
Cedric Roux committed
248
249
250
251
/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
 * this is very hackish - find a proper solution
 */
uint8_t abstraction_flag=0;
knopp's avatar
   
knopp committed
252

253
254
255
256
257
/*---------------------BMC: timespec helpers -----------------------------*/

struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 };

258
struct timespec clock_difftime(struct timespec start, struct timespec end) {
259
260
261
262
263
264
265
266
267
  struct timespec temp;
  if ((end.tv_nsec-start.tv_nsec)<0) {
    temp.tv_sec = end.tv_sec-start.tv_sec-1;
    temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
  } else {
    temp.tv_sec = end.tv_sec-start.tv_sec;
    temp.tv_nsec = end.tv_nsec-start.tv_nsec;
  }
  return temp;
268
269
}

270
void print_difftimes(void) {
271
#ifdef DEBUG
272
  printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
273
#else
274
  LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
275
276
277
#endif
}

278
void update_difftimes(struct timespec start, struct timespec end) {
279
280
281
  struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
  int             changed = 0;
  diff_time = clock_difftime(start, end);
282
283
284
285
286
287
288
289
  if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) {
    min_diff_time.tv_nsec = diff_time.tv_nsec;
    changed = 1;
  }
  if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) {
    max_diff_time.tv_nsec = diff_time.tv_nsec;
    changed = 1;
  }
290
#if 1
291
  if (changed) print_difftimes();
292
293
294
295
296
#endif
}

/*------------------------------------------------------------------------*/

297
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) {
knopp's avatar
   
knopp committed
298
  return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
299
}
300
unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) {
knopp's avatar
   
knopp committed
301
  return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
302
303
}

304
#if !defined(ENABLE_ITTI)
305
void signal_handler(int sig) {
306
307
308
309
310
311
  void *array[10];
  size_t size;

  if (sig==SIGSEGV) {
    // get void*'s for all entries on the stack
    size = backtrace(array, 10);
312

313
314
315
316
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
317
318
  } else {
    printf("trying to exit gracefully...\n");
319
    oai_exit = 1;
320
321
  }
}
322
#endif
nikaeinn's avatar
nikaeinn committed
323
324
325
326
327
328
#define KNRM  "\x1B[0m"
#define KRED  "\x1B[31m"
#define KGRN  "\x1B[32m"
#define KBLU  "\x1B[34m"
#define RESET "\033[0m"

329

Raymond Knopp's avatar
Raymond Knopp committed
330

331
332
void exit_fun(const char* s)
{
Raymond Knopp's avatar
Raymond Knopp committed
333
  int CC_id;
334
  int ru_id;
Raymond Knopp's avatar
Raymond Knopp committed
335

336
  if (s != NULL) {
337
    printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s);
338
339
340
  }

  oai_exit = 1;
341
342
343
344
345
346
347
348
349
350

  if (UE_flag==0) {
    for (ru_id=0; ru_id<RC.nb_RU;ru_id++) {
      if (RC.ru[ru_id]->rfdevice.trx_end_func)
	RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);
      if (RC.ru[ru_id]->ifdevice.trx_end_func)
	RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);  
    }
  }

Raymond Knopp's avatar
Raymond Knopp committed
351
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
352
353
354
355

    oai_exit = 1;

    for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
356
357
358
359
360
      if (UE_flag == 0) {
      } else {
	if (PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func)
	  PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice);
      }
knopp's avatar
knopp committed
361
    }
362
363

#if defined(ENABLE_ITTI)
364
365
    sleep(1); //allow lte-softmodem threads to exit first
    itti_terminate_tasks (TASK_UNKNOWN);
366
#endif
367

368
  }
369

370
}
371

372
#ifdef XFORMS
373

374

375
376
void reset_stats(FL_OBJECT *button, long arg)
{
377
  int i,j,k;
378
  PHY_VARS_eNB *phy_vars_eNB = RC.eNB[0][0];
379
380
381

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    for (k=0; k<8; k++) { //harq_processes
382
      for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) {
383
384
385
	phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0;
	phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0;
	phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0;
386
      }
387

388
389
390
      phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0;
      phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0;
      phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0;
391
392


393
394
395
      phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0;
      phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0;
      phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0;
396
397
398
399
    }
  }
}

400
static void *scope_thread(void *arg) {
knopp's avatar
   
knopp committed
401
  char stats_buffer[16384];
402
# ifdef ENABLE_XFORMS_WRITE_STATS
knopp's avatar
   
knopp committed
403
  FILE *UE_stats, *eNB_stats;
404
# endif
knopp's avatar
   
knopp committed
405
  struct sched_param sched_param;
406
  int UE_id, CC_id;
407
  int ue_cnt=0;
408

409
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
knopp's avatar
   
knopp committed
410
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
411

knopp's avatar
   
knopp committed
412
  printf("Scope thread has priority %d\n",sched_param.sched_priority);
413

414
# ifdef ENABLE_XFORMS_WRITE_STATS
415
416

  if (UE_flag==1)
knopp's avatar
   
knopp committed
417
    UE_stats  = fopen("UE_stats.txt", "w");
418
  else
knopp's avatar
   
knopp committed
419
    eNB_stats = fopen("eNB_stats.txt", "w");
420

421
#endif
422

knopp's avatar
   
knopp committed
423
424
  while (!oai_exit) {
    if (UE_flag==1) {
oai's avatar
oai committed
425
      dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm);
knopp's avatar
knopp committed
426
427
428
      //fl_set_object_label(form_stats->stats_text, stats_buffer);
      fl_clear_browser(form_stats->stats_text);
      fl_add_browser_line(form_stats->stats_text, stats_buffer);
429

430
      phy_scope_UE(form_ue[0],
431
432
433
434
		   PHY_vars_UE_g[0][0],
		   0,
		   0,7);

435

knopp's avatar
   
knopp committed
436
    } else {
437
      /*
438
	if (RC.eNB[0][0]->mac_enabled==1) {
439
440
441
442
	len = dump_eNB_l2_stats (stats_buffer, 0);
	//fl_set_object_label(form_stats_l2->stats_text, stats_buffer);
	fl_clear_browser(form_stats_l2->stats_text);
	fl_add_browser_line(form_stats_l2->stats_text, stats_buffer);
443
444
	}
	len = dump_eNB_stats (RC.eNB[0][0], stats_buffer, 0);
445

446
447
	if (MAX_NUM_CCs>1)
	len += dump_eNB_stats (RC.eNB[0][1], &stats_buffer[len], 0);
448

449
450
451
	//fl_set_object_label(form_stats->stats_text, stats_buffer);
	fl_clear_browser(form_stats->stats_text);
	fl_add_browser_line(form_stats->stats_text, stats_buffer);
452
      */
453
454
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
455
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
456
	  //	  if ((RC.eNB[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) {
457
	  if ((ue_cnt<scope_enb_num_ue)) {
gauthier's avatar
gauthier committed
458
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
459
			  RC.eNB[0][CC_id],
460
461
462
			  UE_id);
	    ue_cnt++;
	  }
463
	}
knopp's avatar
   
knopp committed
464
      }
465

466
    }
467
	
knopp's avatar
   
knopp committed
468
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
469
470
    //usleep(100000); // 100 ms
    sleep(1);
knopp's avatar
   
knopp committed
471
  }
472

473
  //  printf("%s",stats_buffer);
474

475
# ifdef ENABLE_XFORMS_WRITE_STATS
476

477
478
479
480
481
482
  if (UE_flag==1) {
    if (UE_stats) {
      rewind (UE_stats);
      fwrite (stats_buffer, 1, len, UE_stats);
      fclose (UE_stats);
    }
483
  } else {
484
485
486
487
488
489
    if (eNB_stats) {
      rewind (eNB_stats);
      fwrite (stats_buffer, 1, len, eNB_stats);
      fclose (eNB_stats);
    }
  }
490

491
# endif
492

knopp's avatar
   
knopp committed
493
  pthread_exit((void*)arg);
494
495
496
}
#endif

497

498

499

knopp's avatar
   
knopp committed
500
#if defined(ENABLE_ITTI)
501
void *l2l1_task(void *arg) {
knopp's avatar
   
knopp committed
502
503
504
505
506
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
507

knopp's avatar
   
knopp committed
508
509
  if (UE_flag == 0) {
    /* Wait for the initialize message */
510
    printf("Wait for the ITTI initialize message\n");
511
    do {
knopp's avatar
   
knopp committed
512
      if (message_p != NULL) {
513
514
	result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
	AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
knopp's avatar
   
knopp committed
515
      }
516

517
518
519
      itti_receive_msg (TASK_L2L1, &message_p);

      switch (ITTI_MSG_ID(message_p)) {
knopp's avatar
   
knopp committed
520
      case INITIALIZE_MESSAGE:
521
522
523
524
	/* Start eNB thread */
	LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p));
	start_eNB = 1;
	break;
knopp's avatar
   
knopp committed
525
526

      case TERMINATE_MESSAGE:
527
528
529
530
	printf("received terminate message\n");
	oai_exit=1;
	itti_exit_task ();
	break;
knopp's avatar
   
knopp committed
531
532

      default:
533
534
	LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
	break;
535
      }
knopp's avatar
   
knopp committed
536
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
537

knopp's avatar
   
knopp committed
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  }

  do {
    // Wait for a message
    itti_receive_msg (TASK_L2L1, &message_p);

    switch (ITTI_MSG_ID(message_p)) {
    case TERMINATE_MESSAGE:
      oai_exit=1;
      itti_exit_task ();
      break;

    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;

    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
559

knopp's avatar
   
knopp committed
560
561
562
563
564
565
566
567
568
569
570
    case MESSAGE_TEST:
      LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
      break;

    default:
      LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
      break;
    }

    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
thomasl's avatar
thomasl committed
571
  } while(!oai_exit);
572

knopp's avatar
   
knopp committed
573
  return NULL;
574
575
576
}
#endif

577

578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
static void get_options(void) {
  int CC_id;
  int tddflag;
  char *loopfile=NULL;
  int dumpframe;
  paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;

  config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); 

  if (strlen(in_path) > 0) {
      opt_type = OPT_PCAP;
      opt_enabled=1;
      printf("Enabling OPT for PCAP  with the following file %s \n",in_path);
  }
  if (strlen(in_ip) > 0) {
      opt_enabled=1;
      opt_type = OPT_WIRESHARK;
      printf("Enabling OPT for wireshark for local interface");
  }
  if (UE_flag > 0) {
     paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC;
     paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC;
oai's avatar
oai committed
600
601
602



603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
     config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL);
     config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
      if (loopfile != NULL) {
  	  printf("Input file for hardware emulation: %s",loopfile);
  	  mode=loop_through_memory;
  	  input_fd = fopen(loopfile,"r");
  	  AssertFatal(input_fd != NULL,"Please provide a valid input file\n");
      }
      if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue;
      if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med;
      if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp;
      if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach;
      if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0)  mode = no_L2_connect;
      if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; 
      if (dumpframe  > 0)  mode = rx_dump_frame;
      
      if ( downlink_frequency[0][0] > 0) {
  	  for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
  	    downlink_frequency[CC_id][1] = downlink_frequency[0][0];
  	    downlink_frequency[CC_id][2] = downlink_frequency[0][0];
  	    downlink_frequency[CC_id][3] = downlink_frequency[0][0];
  	    printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
  	  }
      UE_scan=0;
      } 

oai's avatar
oai committed
629
630
631
632
      if (tddflag > 0) {
         for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
	     frame_parms[CC_id]->frame_type = TDD;
      }
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670

      if (frame_parms[0]->N_RB_DL !=0) {
  	  if ( frame_parms[0]->N_RB_DL < 6 ) {
  	     frame_parms[0]->N_RB_DL = 6;
  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL);
  	  }
  	  if ( frame_parms[0]->N_RB_DL > 100 ) {
  	     frame_parms[0]->N_RB_DL = 100;
  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL);
  	  }
  	  if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) {
  	     frame_parms[0]->N_RB_DL = 50;
  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL);
  	  }
  	  if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) {
  	     frame_parms[0]->N_RB_DL = 25;
  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL);
  	  }
  	  UE_scan = 0;
  	  frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL;
  	  for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
  	      frame_parms[CC_id]->N_RB_DL=frame_parms[0]->N_RB_DL;
  	      frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL;
  	  }
      }


      for (CC_id=1;CC_id<MAX_NUM_CCs;CC_id++) {
  	    tx_max_power[CC_id]=tx_max_power[0];
	    rx_gain[0][CC_id] = rx_gain[0][0];
	    tx_gain[0][CC_id] = tx_gain[0][0];
      }
  } /* UE_flag > 0 */
#if T_TRACER
  paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ;
  config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL);   
#endif

671
672
673
674
  if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) {
    if (UE_flag == 0) {
      memset((void*)&RC,0,sizeof(RC));
      /* Read RC configuration file */
675
      RCConfig();
676
677
678
      NB_eNB_INST = RC.nb_inst;
      NB_RU	  = RC.nb_RU;
      printf("Configuration: nb_inst %d, nb_ru %d\n",NB_eNB_INST,NB_RU);
679
    }
680
681
682
683
684
685
  } else if (UE_flag == 1 && (CONFIG_GETCONFFILE != NULL)) {
    // Here the configuration file is the XER encoded UE capabilities
    // Read it in and store in asn1c data structures
    strcpy(uecap_xer,CONFIG_GETCONFFILE);
    uecap_xer_in=1;
  } /* UE with config file  */
686
687
688
}


689
  
690
691
692
#if T_TRACER
int T_wait = 1;       /* by default we wait for the tracer */
int T_port = 2021;    /* default port to listen to to wait for the tracer */
693
int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
694
695
#endif

696

knopp's avatar
knopp committed
697
698
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
knopp's avatar
knopp committed
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713

  int CC_id;

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS));
    /* Set some default values that may be overwritten while reading options */
    frame_parms[CC_id]->frame_type          = FDD;
    frame_parms[CC_id]->tdd_config          = 3;
    frame_parms[CC_id]->tdd_config_S        = 0;
    frame_parms[CC_id]->N_RB_DL             = 100;
    frame_parms[CC_id]->N_RB_UL             = 100;
    frame_parms[CC_id]->Ncp                 = NORMAL;
    frame_parms[CC_id]->Ncp_UL              = NORMAL;
    frame_parms[CC_id]->Nid_cell            = 0;
    frame_parms[CC_id]->num_MBSFN_config    = 0;
714
    frame_parms[CC_id]->nb_antenna_ports_eNB  = 1;
knopp's avatar
knopp committed
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
    frame_parms[CC_id]->nb_antennas_tx      = 1;
    frame_parms[CC_id]->nb_antennas_rx      = 1;

    frame_parms[CC_id]->nushift             = 0;

    frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
    frame_parms[CC_id]->phich_config_common.phich_duration = normal;
    // UL RS Config
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0;
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;

    frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;

    downlink_frequency[CC_id][0] = 2680000000; // Use float to avoid issue with frequency over 2^31.
    downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0];
    downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0];
    downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0];
    //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);

  }

}

knopp's avatar
knopp committed
744
745
void init_openair0(void);

knopp's avatar
knopp committed
746
747
748
749
750
751
752
753
754
755
756
757
758
void init_openair0() {

  int card;
  int i;

  for (card=0; card<MAX_CARDS; card++) {

    openair0_cfg[card].mmapped_dma=mmapped_dma;
    openair0_cfg[card].configFilename = NULL;

    if(frame_parms[0]->N_RB_DL == 100) {
      if (frame_parms[0]->threequarter_fs) {
	openair0_cfg[card].sample_rate=23.04e6;
759
	openair0_cfg[card].samples_per_frame = 230400;
knopp's avatar
knopp committed
760
761
	openair0_cfg[card].tx_bw = 10e6;
	openair0_cfg[card].rx_bw = 10e6;
762
      } else {
knopp's avatar
knopp committed
763
	openair0_cfg[card].sample_rate=30.72e6;
764
	openair0_cfg[card].samples_per_frame = 307200;
knopp's avatar
knopp committed
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
	openair0_cfg[card].tx_bw = 10e6;
	openair0_cfg[card].rx_bw = 10e6;
      }
    } else if(frame_parms[0]->N_RB_DL == 50) {
      openair0_cfg[card].sample_rate=15.36e6;
      openair0_cfg[card].samples_per_frame = 153600;
      openair0_cfg[card].tx_bw = 5e6;
      openair0_cfg[card].rx_bw = 5e6;
    } else if (frame_parms[0]->N_RB_DL == 25) {
      openair0_cfg[card].sample_rate=7.68e6;
      openair0_cfg[card].samples_per_frame = 76800;
      openair0_cfg[card].tx_bw = 2.5e6;
      openair0_cfg[card].rx_bw = 2.5e6;
    } else if (frame_parms[0]->N_RB_DL == 6) {
      openair0_cfg[card].sample_rate=1.92e6;
      openair0_cfg[card].samples_per_frame = 19200;
      openair0_cfg[card].tx_bw = 1.5e6;
      openair0_cfg[card].rx_bw = 1.5e6;
    }




    if (frame_parms[0]->frame_type==TDD)
      openair0_cfg[card].duplex_mode = duplex_mode_TDD;
    else //FDD
      openair0_cfg[card].duplex_mode = duplex_mode_FDD;

    printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
794
795
	   ((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx),
	   ((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx));
knopp's avatar
knopp committed
796
797
798
    openair0_cfg[card].Mod_id = 0;

    openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
799

800
    openair0_cfg[card].clock_source = clock_source;
801

802

803
804
    openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx));
    openair0_cfg[card].rx_num_channels=min(2,((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx));
805

knopp's avatar
knopp committed
806
    for (i=0; i<4; i++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
807

knopp's avatar
knopp committed
808
809
810
811
      if (i<openair0_cfg[card].tx_num_channels)
	openair0_cfg[card].tx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] : downlink_frequency[0][i]+uplink_frequency_offset[0][i];
      else
	openair0_cfg[card].tx_freq[i]=0.0;
812

knopp's avatar
knopp committed
813
814
815
816
817
818
819
820
      if (i<openair0_cfg[card].rx_num_channels)
	openair0_cfg[card].rx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] + uplink_frequency_offset[0][i] : downlink_frequency[0][i];
      else
	openair0_cfg[card].rx_freq[i]=0.0;

      openair0_cfg[card].autocal[i] = 1;
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
      if (UE_flag == 0) {
821
	openair0_cfg[card].rx_gain[i] = RC.eNB[0][0]->rx_total_gain_dB;
knopp's avatar
knopp committed
822
823
      }
      else {
fnabet's avatar
fnabet committed
824
	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off;
knopp's avatar
knopp committed
825
826
      }

827
      openair0_cfg[card].configFilename = rf_config_file;
828
      printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
829
830
831
832
	     card,i, openair0_cfg[card].tx_gain[i],
	     openair0_cfg[card].rx_gain[i],
	     openair0_cfg[card].tx_freq[i],
	     openair0_cfg[card].rx_freq[i]);
833
    }
knopp's avatar
   
knopp committed
834
  }
knopp's avatar
   
knopp committed
835
}
836

837

838
void wait_RUs(void) {
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853

  LOG_I(PHY,"Waiting for RUs to be configured ...\n");

  // wait for all RUs to be configured over fronthaul
  pthread_mutex_lock(&RC.ru_mutex);



  while (RC.ru_mask>0) {
    pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex);
  }

  LOG_I(PHY,"RUs configured\n");
}

854
void wait_eNBs(void) {
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872

  int i,j;
  int waiting=1;


  while (waiting==1) {
    printf("Waiting for eNB L1 instances to all get configured ... sleeping 500ms (nb_L1_inst %d)\n",RC.nb_L1_inst);
    usleep(500000);
    waiting=0;
    for (i=0;i<RC.nb_L1_inst;i++)
      for (j=0;j<RC.nb_L1_CC[i];j++)
	if (RC.eNB[i][j]->configured==0) {
	  waiting=1;
	  break;
	}
  }
  printf("eNB L1 are configured\n");
}
873

874
875
int main( int argc, char **argv )
{
876
  int i;
877
#if defined (XFORMS)
knopp's avatar
   
knopp committed
878
  void *status;
879
#endif
880

knopp's avatar
   
knopp committed
881
  int CC_id;
882
  int ru_id;
knopp's avatar
knopp committed
883
  uint8_t  abstraction_flag=0;
knopp's avatar
   
knopp committed
884
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
885

knopp's avatar
   
knopp committed
886
#if defined (XFORMS)
887
888
  int ret;
#endif
889

890
  start_background_system();
891
892
893
  if ( load_configmodule(argc,argv) == NULL) {
    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
  } 
894

895
      
896
897
898
899
900
#ifdef DEBUG_CONSOLE
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);
#endif

901
902
903
  PHY_VARS_UE *UE[MAX_NUM_CCs];

  mode = normal_txrx;
904
  memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS);
905

906
  memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
907

knopp's avatar
   
knopp committed
908
  set_latency_target();
909
910


knopp's avatar
knopp committed
911
  // set default parameters
912
  if (UE_flag == 1) set_default_frame_parms(frame_parms);
913

914
  logInit();
knopp's avatar
knopp committed
915

916
  printf("Reading in command-line options\n");
917

918
  get_options (); 
oai's avatar
oai committed
919
920
921
  if (CONFIG_ISFLAGSET(CONFIG_ABORT)) {
      fprintf(stderr,"Getting configuration failed\n");
      exit(-1);
922
  }
knopp's avatar
knopp committed
923
924
925



926
#if T_TRACER
927
  T_init(T_port, T_wait, T_dont_fork);
928
929
#endif

nikaeinn's avatar
nikaeinn committed
930
  // initialize the log (see log.h for details)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
931
932
  set_glog(glog_level, glog_verbosity);

nikaeinn's avatar
nikaeinn committed
933
934
  //randominit (0);
  set_taus_seed (0);
knopp's avatar
   
knopp committed
935

936
937
  if (UE_flag==1) {
    printf("configuring for UE\n");
938

939
940
    set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
    set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
941
    set_comp_log(MAC,     LOG_INFO,   LOG_HIGH, 1);
942
    set_comp_log(RLC,     LOG_INFO,   LOG_HIGH | FLAG_THREAD, 1);
943
944
945
    set_comp_log(PDCP,    LOG_INFO,   LOG_HIGH, 1);
    set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);
    set_comp_log(RRC,     LOG_INFO,   LOG_HIGH, 1);
946
#if defined(ENABLE_ITTI)
947
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
948
# if defined(ENABLE_USE_MME)
949
    set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
950
951
# endif
#endif
952

953
  } else {
954
    printf("configuring for RAU/RRU\n");
955

956
957
958
959
960
961
962
963
    set_comp_log(HW,      hw_log_level, hw_log_verbosity, 1);
    set_comp_log(PHY,     phy_log_level,   phy_log_verbosity, 1);
    if (opt_enabled == 1 )
      set_comp_log(OPT,   opt_log_level,      opt_log_verbosity, 1);
    set_comp_log(MAC,     mac_log_level,  mac_log_verbosity, 1);
    set_comp_log(RLC,     rlc_log_level,   rlc_log_verbosity, 1);
    set_comp_log(PDCP,    pdcp_log_level,  pdcp_log_verbosity, 1);
    set_comp_log(RRC,     rrc_log_level,  rrc_log_verbosity, 1);
964
#if defined(ENABLE_ITTI)
965
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
966
# if defined(ENABLE_USE_MME)
967
968
969
970
    set_comp_log(UDP_,    udp_log_level,   udp_log_verbosity, 1);
    set_comp_log(GTPU,    gtpu_log_level,   gtpu_log_verbosity, 1);
    set_comp_log(S1AP,    LOG_DEBUG,   LOG_HIGH, 1);
    set_comp_log(SCTP,    LOG_INFO,   LOG_HIGH, 1);
971
# endif
972
#if defined(ENABLE_SECURITY)
973
    set_comp_log(OSA,    osa_log_level,   osa_log_verbosity,