lte-softmodem.c 56.5 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

139
static char                    *conf_config_file_name = NULL;
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
uint8_t nb_antenna_tx = 1;
uint8_t nb_antenna_rx = 1;
176

knopp's avatar
   
knopp committed
177
178
179
char ref[128] = "internal";
char channels[128] = "0";

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

190
191

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

198

199
200
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
201

202
int transmission_mode=1;
knopp's avatar
   
knopp committed
203

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

gauthier's avatar
   
gauthier committed
221
222
223
224
225
226
# 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
227
228
229
#if defined (ENABLE_SECURITY)
int16_t           osa_log_level      = LOG_INFO;
int16_t           osa_log_verbosity  = LOG_MED;
230
#endif
231

232
233
234
/* struct for ethernet specific parameters given in eNB conf file */
eth_params_t *eth_params;

235
236
237
238
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

239
240
extern char uecap_xer[1024];
char uecap_xer_in=0;
241

242
int oaisim_flag=0;
243
threads_t threads= {-1,-1,-1};
knopp's avatar
   
knopp committed
244

Cedric Roux's avatar
Cedric Roux committed
245
246
247
248
/* 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
249

250
251
252
253
254
/*---------------------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 };

255
struct timespec clock_difftime(struct timespec start, struct timespec end) {
256
257
258
259
260
261
262
263
264
  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;
265
266
}

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

275
void update_difftimes(struct timespec start, struct timespec end) {
276
277
278
  struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
  int             changed = 0;
  diff_time = clock_difftime(start, end);
279
280
281
282
283
284
285
286
  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;
  }
287
#if 1
288
  if (changed) print_difftimes();
289
290
291
292
293
#endif
}

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

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

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

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

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

void help (void) {
  printf (KGRN "Usage:\n");
  printf("  sudo -E lte-softmodem [options]\n");
  printf("  sudo -E ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.openEPC.conf -S -V -m 26 -t 16 -x 1 --ulsch-max-errors 100 -W\n\n");
  printf("Options:\n");
331
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
nikaeinn's avatar
nikaeinn committed
332
333
334
335
  printf("  --ulsch-max-errors set the max ULSCH erros\n");
  printf("  --calib-ue-rx set UE RX calibration\n");
  printf("  --calib-ue-rx-med \n");
  printf("  --calib-ue-rxbyp\n");
knopp's avatar
   
knopp committed
336
337
  printf("  --debug-ue-prach run normal prach power ramping, but don't continue random-access\n");
  printf("  --calib-prach-tx run normal prach with maximum power, but don't continue random-access\n");
nikaeinn's avatar
nikaeinn committed
338
  printf("  --no-L2-connect bypass L2 and upper layers\n");
339
  printf("  --ue-rxgain set UE RX gain\n");
fnabet's avatar
fnabet committed
340
  printf("  --ue-rxgain-off external UE amplifier offset\n");
341
  printf("  --ue-txgain set UE TX gain\n");
Cedric Roux's avatar
Cedric Roux committed
342
343
  printf("  --ue-nb-ant-rx  set UE number of rx antennas\n");
  printf("  --ue-scan-carrier set UE to scan around carrier\n");
344
  printf("  --dlsch-demod-shift dynamic shift for LLR compuation for TM3/4 (default 0)\n");
345
  printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
346
  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");  
347
  printf("  --external-clock tells hardware to use an external clock reference\n");
348
  printf("  --usim-test use XOR autentication algo in case of test usim mode\n"); 
349
  printf("  --single-thread-disable. Disables single-thread mode in lte-softmodem\n"); 
350
  printf("  -A Set timing_advance\n");
351
  printf("  -C Set the downlink frequency for all component carriers\n");
nikaeinn's avatar
nikaeinn committed
352
353
354
  printf("  -d Enable soft scope and L1 and L2 stats (Xforms)\n");
  printf("  -F Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n");
  printf("  -g Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n");
355
  printf("  -G Set the global log verbosity \n");
nikaeinn's avatar
nikaeinn committed
356
357
358
359
360
  printf("  -h provides this help message!\n");
  printf("  -K Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n");
  printf("  -m Set the maximum downlink MCS\n");
  printf("  -O eNB configuration file (located in targets/PROJECTS/GENERIC-LTE-EPC/CONF\n");
  printf("  -q Enable processing timing measurement of lte softmodem on per subframe basis \n");
kaltenbe's avatar
kaltenbe committed
361
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
nikaeinn's avatar
nikaeinn committed
362
363
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
364
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
nikaeinn's avatar
nikaeinn committed
365
366
367
  printf("  -U Set the lte softmodem as a UE\n");
  printf("  -W Enable L2 wireshark messages on localhost \n");
  printf("  -V Enable VCD (generated file will be located atopenair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n");
368
  printf("  -x Set the transmission mode, valid options: 1 \n");
369
  printf("  -E Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n");
370
371
372
#if T_TRACER
  printf("  --T_port [port]    use given port\n");
  printf("  --T_nowait         don't wait for tracer, start immediately\n");
373
  printf("  --T_dont_fork      to ease debugging with gdb\n");
374
375
376
#endif
  printf(RESET);
  fflush(stdout);
nikaeinn's avatar
nikaeinn committed
377
}
378

Raymond Knopp's avatar
Raymond Knopp committed
379

380
381
void exit_fun(const char* s)
{
Raymond Knopp's avatar
Raymond Knopp committed
382
  int CC_id;
383
  int ru_id;
Raymond Knopp's avatar
Raymond Knopp committed
384

385
  if (s != NULL) {
386
    printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s);
387
388
389
  }

  oai_exit = 1;
390
391
392
393
394
395
396
397
398
399

  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
400
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
401
402
403
404

    oai_exit = 1;

    for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
405
406
407
408
409
      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
410
    }
411
412

#if defined(ENABLE_ITTI)
413
414
    sleep(1); //allow lte-softmodem threads to exit first
    itti_terminate_tasks (TASK_UNKNOWN);
415
#endif
416

417
  }
418

419
}
420

421
#ifdef XFORMS
422

423

424
425
void reset_stats(FL_OBJECT *button, long arg)
{
426
  int i,j,k;
427
  PHY_VARS_eNB *phy_vars_eNB = RC.eNB[0][0];
428
429
430

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    for (k=0; k<8; k++) { //harq_processes
431
      for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) {
432
433
434
	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;
435
      }
436

437
438
439
      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;
440
441


442
443
444
      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;
445
446
447
448
    }
  }
}

449
static void *scope_thread(void *arg) {
knopp's avatar
   
knopp committed
450
  char stats_buffer[16384];
451
# ifdef ENABLE_XFORMS_WRITE_STATS
knopp's avatar
   
knopp committed
452
  FILE *UE_stats, *eNB_stats;
453
# endif
Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
454
  int len = 0;
knopp's avatar
   
knopp committed
455
  struct sched_param sched_param;
456
  int UE_id, CC_id;
457
  int ue_cnt=0;
458

459
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
knopp's avatar
   
knopp committed
460
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
461

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

464
# ifdef ENABLE_XFORMS_WRITE_STATS
465
466

  if (UE_flag==1)
knopp's avatar
   
knopp committed
467
    UE_stats  = fopen("UE_stats.txt", "w");
468
  else
knopp's avatar
   
knopp committed
469
    eNB_stats = fopen("eNB_stats.txt", "w");
470

471
#endif
472

knopp's avatar
   
knopp committed
473
474
  while (!oai_exit) {
    if (UE_flag==1) {
475
      len = 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
476
477
478
      //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);
479

480
      phy_scope_UE(form_ue[0],
481
482
483
484
		   PHY_vars_UE_g[0][0],
		   0,
		   0,7);

485

knopp's avatar
   
knopp committed
486
    } else {
487
      /*
488
	if (RC.eNB[0][0]->mac_enabled==1) {
489
490
491
492
	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);
493
494
	}
	len = dump_eNB_stats (RC.eNB[0][0], stats_buffer, 0);
495

496
497
	if (MAX_NUM_CCs>1)
	len += dump_eNB_stats (RC.eNB[0][1], &stats_buffer[len], 0);
498

499
500
501
	//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);
502
      */
503
504
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
505
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
506
	  //	  if ((RC.eNB[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) {
507
	  if ((ue_cnt<scope_enb_num_ue)) {
gauthier's avatar
gauthier committed
508
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
509
			  RC.eNB[0][CC_id],
510
511
512
			  UE_id);
	    ue_cnt++;
	  }
513
	}
knopp's avatar
   
knopp committed
514
      }
515

516
    }
517
	
knopp's avatar
   
knopp committed
518
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
519
520
    //usleep(100000); // 100 ms
    sleep(1);
knopp's avatar
   
knopp committed
521
  }
522

523
  //  printf("%s",stats_buffer);
524

525
# ifdef ENABLE_XFORMS_WRITE_STATS
526

527
528
529
530
531
532
  if (UE_flag==1) {
    if (UE_stats) {
      rewind (UE_stats);
      fwrite (stats_buffer, 1, len, UE_stats);
      fclose (UE_stats);
    }
533
  } else {
534
535
536
537
538
539
    if (eNB_stats) {
      rewind (eNB_stats);
      fwrite (stats_buffer, 1, len, eNB_stats);
      fclose (eNB_stats);
    }
  }
540

541
# endif
542

knopp's avatar
   
knopp committed
543
  pthread_exit((void*)arg);
544
545
546
}
#endif

547

548

549

knopp's avatar
   
knopp committed
550
#if defined(ENABLE_ITTI)
551
void *l2l1_task(void *arg) {
knopp's avatar
   
knopp committed
552
553
554
555
556
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
557

knopp's avatar
   
knopp committed
558
559
  if (UE_flag == 0) {
    /* Wait for the initialize message */
560
    printf("Wait for the ITTI initialize message\n");
561
    do {
knopp's avatar
   
knopp committed
562
      if (message_p != NULL) {
563
564
	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
565
      }
566

567
568
569
      itti_receive_msg (TASK_L2L1, &message_p);

      switch (ITTI_MSG_ID(message_p)) {
knopp's avatar
   
knopp committed
570
      case INITIALIZE_MESSAGE:
571
572
573
574
	/* 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
575
576

      case TERMINATE_MESSAGE:
577
578
579
580
	printf("received terminate message\n");
	oai_exit=1;
	itti_exit_task ();
	break;
knopp's avatar
   
knopp committed
581
582

      default:
583
584
	LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
	break;
585
      }
knopp's avatar
   
knopp committed
586
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
587

knopp's avatar
   
knopp committed
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
    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;
609

knopp's avatar
   
knopp committed
610
611
612
613
614
615
616
617
618
619
620
    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
621
  } while(!oai_exit);
622

knopp's avatar
   
knopp committed
623
  return NULL;
624
625
626
}
#endif

627
628
629
630
631
632
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
671
672
673
674
675
676
677
678
679
680
681
682
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
712
713
714
715
716
717
static void get_options(void) {
  int CC_id;
  int clock_src;
  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 (tddflag > 0) {
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
	frame_parms[CC_id]->frame_type = TDD;
  }

  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;
     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;
      } 


      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

718
719
720
721
722
723
724
725
  if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) {
    if (UE_flag == 0) {
      memset((void*)&RC,0,sizeof(RC));
      /* Read RC configuration file */
      RCConfig(NULL);
      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);
knopp's avatar
   
knopp committed
726

727
      
728
729
730
731
732
733
734
    } else if (UE_flag == 1) {
      if (conf_config_file_name != NULL) {
  	
  	// Here the configuration file is the XER encoded UE capabilities
  	// Read it in and store in asn1c data structures
  	strcpy(uecap_xer,conf_config_file_name);
  	uecap_xer_in=1;
735

736
      }
737
    }
738
  } /* CONFIG_ABORT not set */
739
740
741
742
}


static void old_get_options (int argc, char **argv) {
743
744
745
  int c;
  //  char                          line[1000];
  //  int                           l;
746
  int i;
747
#if defined(OAI_USRP) || defined(CPRIGW)
748
  int clock_src;
knopp's avatar
   
knopp committed
749
#endif
750
  int CC_id;
knopp's avatar
   
knopp committed
751
752


753

754
755
  enum long_option_e {
    LONG_OPTION_START = 0x100, /* Start after regular single char options */
756
    LONG_OPTION_RF_CONFIG_FILE,
757
758
759
760
761
    LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS,
    LONG_OPTION_CALIB_UE_RX,
    LONG_OPTION_CALIB_UE_RX_MED,
    LONG_OPTION_CALIB_UE_RX_BYP,
    LONG_OPTION_DEBUG_UE_PRACH,
762
    LONG_OPTION_NO_L2_CONNECT,
knopp's avatar
   
knopp committed
763
    LONG_OPTION_CALIB_PRACH_TX,
764
    LONG_OPTION_RXGAIN,
765
    LONG_OPTION_RXGAINOFF,
766
    LONG_OPTION_TXGAIN,
767
768
    LONG_OPTION_NBRXANT,
    LONG_OPTION_NBTXANT,
769
    LONG_OPTION_SCANCARRIER,
770
771
    LONG_OPTION_MAXPOWER,
    LONG_OPTION_DUMP_FRAME,
772
    LONG_OPTION_LOOPMEMORY,
773
    LONG_OPTION_PHYTEST,
774
    LONG_OPTION_USIMTEST,
Cedric Roux's avatar
Cedric Roux committed
775
    LONG_OPTION_MMAPPED_DMA,
776
    LONG_OPTION_EXTERNAL_CLOCK,
777
    LONG_OPTION_WAIT_FOR_SYNC,
778
    LONG_OPTION_SINGLE_THREAD_DISABLE,
779
780
781
782
    LONG_OPTION_THREADIQ,
    LONG_OPTION_THREADODDSUBFRAME,
    LONG_OPTION_THREADEVENSUBFRAME,
    LONG_OPTION_DEMOD_SHIFT,
783
784
785
#if T_TRACER
    LONG_OPTION_T_PORT,
    LONG_OPTION_T_NOWAIT,
Cedric Roux's avatar
Cedric Roux committed
786
    LONG_OPTION_T_DONT_FORK,
787
#endif
788

789
  };
790

791
  static const struct option long_options[] = {
792
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
793
794
795
796
797
798
    {"ulsch-max-errors",required_argument,  NULL, LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS},
    {"calib-ue-rx",     required_argument,  NULL, LONG_OPTION_CALIB_UE_RX},
    {"calib-ue-rx-med", required_argument,  NULL, LONG_OPTION_CALIB_UE_RX_MED},
    {"calib-ue-rx-byp", required_argument,  NULL, LONG_OPTION_CALIB_UE_RX_BYP},
    {"debug-ue-prach",  no_argument,        NULL, LONG_OPTION_DEBUG_UE_PRACH},
    {"no-L2-connect",   no_argument,        NULL, LONG_OPTION_NO_L2_CONNECT},
knopp's avatar
   
knopp committed
799
800
    {"calib-prach-tx",   no_argument,        NULL, LONG_OPTION_CALIB_PRACH_TX},
    {"ue-rxgain",   required_argument,  NULL, LONG_OPTION_RXGAIN},
801
    {"ue-rxgain-off",   required_argument,  NULL, LONG_OPTION_RXGAINOFF},
knopp's avatar
   
knopp committed
802
    {"ue-txgain",   required_argument,  NULL, LONG_OPTION_TXGAIN},
803
804
    {"ue-nb-ant-rx", required_argument,  NULL, LONG_OPTION_NBRXANT},
    {"ue-nb-ant-tx", required_argument,  NULL, LONG_OPTION_NBTXANT},
knopp's avatar
   
knopp committed
805
    {"ue-scan-carrier",   no_argument,  NULL, LONG_OPTION_SCANCARRIER},
806
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
807
808
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
809
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
810
    {"usim-test", no_argument, NULL, LONG_OPTION_USIMTEST},
811
    {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
812
    {"external-clock", no_argument, NULL, LONG_OPTION_EXTERNAL_CLOCK},
813
    {"wait-for-sync", no_argument, NULL, LONG_OPTION_WAIT_FOR_SYNC},
814
    {"single-thread-disable", no_argument, NULL, LONG_OPTION_SINGLE_THREAD_DISABLE},
815
816
817
818
    {"threadIQ",  required_argument, NULL, LONG_OPTION_THREADIQ},
    {"threadOddSubframe",  required_argument, NULL, LONG_OPTION_THREADODDSUBFRAME},
    {"threadEvenSubframe",  required_argument, NULL, LONG_OPTION_THREADEVENSUBFRAME},
    {"dlsch-demod-shift", required_argument,  NULL, LONG_OPTION_DEMOD_SHIFT},
819
820
821
#if T_TRACER
    {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
    {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
822
    {"T_dont_fork",            no_argument,       0, LONG_OPTION_T_DONT_FORK},
823
#endif
824
825
826
    {NULL, 0, NULL, 0}
  };

827
  while ((c = getopt_long (argc, argv, "A:a:C:dEK:g:F:G:hqO:m:SUVRM:r:P:Ws:t:Tx:",long_options,NULL)) != -1) {
828
    switch (c) {
829
    case LONG_OPTION_RF_CONFIG_FILE:
830
831
832
833
834
835
      if ((strcmp("null", optarg) == 0) || (strcmp("NULL", optarg) == 0)) {
	printf("no configuration filename is provided\n");
      }
      else if (strlen(optarg)<=1024){
	strcpy(rf_config_file,optarg);
      }else {
836
837
	printf("Configuration filename is too long\n");
	exit(-1);   
838
839
      }
      break;
840
841
842
843
    case LONG_OPTION_MAXPOWER:
      tx_max_power[0]=atoi(optarg);
      for (CC_id=1;CC_id<MAX_NUM_CCs;CC_id++)
	tx_max_power[CC_id]=tx_max_power[0];
844
      break;
845
846
847
848
    case LONG_OPTION_ULSCH_MAX_CONSECUTIVE_ERRORS:
      ULSCH_max_consecutive_errors = atoi(optarg);
      printf("Set ULSCH_max_consecutive_errors = %d\n",ULSCH_max_consecutive_errors);
      break;
849

850
851
852
853
854
    case LONG_OPTION_CALIB_UE_RX:
      mode = rx_calib_ue;
      rx_input_level_dBm = atoi(optarg);
      printf("Running with UE calibration on (LNA max), input level %d dBm\n",rx_input_level_dBm);
      break;
855

856
857
858
859
    case LONG_OPTION_CALIB_UE_RX_MED:
      mode = rx_calib_ue_med;
      rx_input_level_dBm = atoi(optarg);
      printf("Running with UE calibration on (LNA med), input level %d dBm\n",rx_input_level_dBm);
knopp's avatar
   
knopp committed
860
      break;
861

862
863
864
865
866
    case LONG_OPTION_CALIB_UE_RX_BYP:
      mode = rx_calib_ue_byp;
      rx_input_level_dBm = atoi(optarg);
      printf("Running with UE calibration on (LNA byp), input level %d dBm\n",rx_input_level_dBm);
      break;
867

868
869
870
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
871

872
873
874
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
875

knopp's avatar
   
knopp committed
876
877
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
Rohit Gupta's avatar
Rohit Gupta committed
878
      printf("Setting mode to calib_prach_tx (%d)\n",mode);
knopp's avatar
   
knopp committed
879
880
      break;

881
    case LONG_OPTION_RXGAIN:
882
      for (i=0; i<4; i++)
883
	rx_gain[0][i] = atof(optarg);
884

885
      break;
886

fnabet's avatar
fnabet committed
887
888
889
890
    case LONG_OPTION_RXGAINOFF:
      rx_gain_off = atof(optarg);
      break;

891
892
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)