lte-softmodem.c 62.7 KB
Newer Older
1
/*******************************************************************************
2
    OpenAirInterface
3
    Copyright(c) 1999 - 2014 Eurecom
4

5
6
7
8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9
10


11
12
13
14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

16
    You should have received a copy of the GNU General Public License
17
18
    along with OpenAirInterface.The full GNU General Public License is
    included in this distribution in the file called "COPYING". If not,
19
    see <http://www.gnu.org/licenses/>.
20

21
22
23
   Contact Information
   OpenAirInterface Admin: openair_admin@eurecom.fr
   OpenAirInterface Tech : openair_tech@eurecom.fr
24
   OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

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

knopp's avatar
   
knopp committed
28
*******************************************************************************/
29

30
31
/*! \file lte-enb.c
 * \brief Top-level threads for eNodeB
32
 * \author R. Knopp, F. Kaltenberger, Navid Nikaein
knopp's avatar
   
knopp committed
33
34
35
 * \date 2012
 * \version 0.1
 * \company Eurecom
36
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
knopp's avatar
   
knopp committed
37
38
39
 * \note
 * \warning
 */
knopp's avatar
   
knopp committed
40
#define _GNU_SOURCE
41
42
43
44
45
46
47
48
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sched.h>
49
#include <linux/sched.h>
50
51
52
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>
53
#include <sys/sysinfo.h>
54

55
56
#include "T.h"

57
#include "rt_wrapper.h"
58

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

61
#include "assertions.h"
62
#include "msc.h"
63
64

#include "PHY/types.h"
65

66
#include "PHY/defs.h"
67
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
knopp's avatar
   
knopp committed
68
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
69

knopp's avatar
   
knopp committed
70
#include "../../ARCH/COMMON/common_lib.h"
71
#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
knopp's avatar
   
knopp committed
72

knopp's avatar
   
knopp committed
73
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
74
75
76
77
78
79
80
81
82

#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"
83
#include "LAYER2/MAC/proto.h"
84
85
86
87
88
89
90
91
#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
92
#include "UTIL/OTG/otg_tx.h"
93
#include "UTIL/OTG/otg_externs.h"
94
95
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
96
#include "UTIL/OPT/opt.h"
97
#include "enb_config.h"
nikaeinn's avatar
nikaeinn committed
98
//#include "PHY/TOOLS/time_meas.h"
99

Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
100
101
102
103
#ifndef OPENAIR2
#include "UTIL/OTG/otg_vars.h"
#endif

104
105
#if defined(ENABLE_ITTI)
# include "intertask_interface_init.h"
106
# include "create_tasks.h"
107
108
# if defined(ENABLE_USE_MME)
#   include "s1ap_eNB.h"
109
#ifdef PDCP_USE_NETLINK
110
111
#   include "SIMULATION/ETH_TRANSPORT/proto.h"
#endif
112
# endif
113
114
#endif

115
116
117
#ifdef XFORMS
#include "PHY/TOOLS/lte_phy_scope.h"
#include "stats.h"
118
119
#endif

120
// In lte-enb.c
121
extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
122
extern void init_eNB(eNB_func_t);
123
extern void stop_eNB(void);
124
extern void kill_eNB_proc(void);
125

126
// In lte-ue.c
127
128
extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
extern void fill_ue_band_info(void);
129
130
extern void init_UE(void);

131
#ifdef XFORMS
132
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
gauthier's avatar
gauthier committed
133
// at eNB 0, an UL scope for every UE
134
FD_lte_phy_scope_ue  *form_ue[NUMBER_OF_UE_MAX];
135
FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
136
FD_stats_form                  *form_stats=NULL,*form_stats_l2=NULL;
137
char title[255];
138
unsigned char                   scope_enb_num_ue = 2;
139
140
#endif //XFORMS

141

142

143
144


knopp's avatar
   
knopp committed
145

knopp's avatar
   
knopp committed
146
147
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
148
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
149

150

151
152


153

154
#ifdef XFORMS
knopp's avatar
   
knopp committed
155
static pthread_t                forms_thread; //xforms
156
#endif
157

158
159
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
160

161

162
#if defined(ENABLE_ITTI)
163
164
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
165
#endif
166
167
volatile int                    oai_exit = 0;

168

169

knopp's avatar
   
knopp committed
170

171
static char                     UE_flag=0;
172
173
//static uint8_t                  eNB_id=0,UE_id=0;

174
static char                     threequarter_fs=0;
175

176
uint32_t                 downlink_frequency[MAX_NUM_CCs][4];
177
int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
gauthier's avatar
gauthier committed
178

179
openair0_rf_map rf_map[MAX_NUM_CCs];
180

181
static char                    *conf_config_file_name = NULL;
182
#if defined(ENABLE_ITTI)
183
static char                    *itti_dump_file = NULL;
knopp's avatar
   
knopp committed
184
185
#endif

186
int UE_scan = 1;
187
int UE_scan_carrier = 0;
188
189
runmode_t mode = normal_txrx;

190
191
FILE *input_fd=NULL;

192

193
194
#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
195
196
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}};
197
198
199
200
#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
201
#endif
knopp's avatar
   
knopp committed
202

203
204


knopp's avatar
   
knopp committed
205
double sample_rate=30.72e6;
206
double bw = 10.0e6;
207

208
static int                      tx_max_power[MAX_NUM_CCs]; /* =  {0,0}*/;
209

210
211
char   rf_config_file[1024];

Florian Kaltenberger's avatar
Florian Kaltenberger committed
212
int chain_offset=0;
213
int phy_test = 0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
214

215

knopp's avatar
   
knopp committed
216
217
218
char ref[128] = "internal";
char channels[128] = "0";

219
int                      rx_input_level_dBm;
220
static int                      online_log_messages=0;
221
#ifdef XFORMS
222
extern int                      otg_enabled;
223
static char                     do_forms=0;
224
#else
225
int                             otg_enabled;
226
#endif
knopp's avatar
   
knopp committed
227
//int                             number_of_cards =   1;
228

229

knopp's avatar
   
knopp committed
230
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
231
eNB_func_t node_function=eNodeB_3GPP;
232

Florian Kaltenberger's avatar
Florian Kaltenberger committed
233
uint32_t target_dl_mcs = 28; //maximum allowed mcs
234
uint32_t target_ul_mcs = 20;
235
uint32_t timing_advance = 0;
236
237
uint8_t exit_missed_slots=1;
uint64_t num_missed_slots=0; // counter for the number of missed slots
238

knopp's avatar
   
knopp committed
239

240
241
242

extern void reset_opp_meas(void);
extern void print_opp_meas(void);
243
int transmission_mode=1;
knopp's avatar
   
knopp committed
244

245
int16_t           glog_level         = LOG_INFO;
gauthier's avatar
   
gauthier committed
246
int16_t           glog_verbosity     = LOG_MED;
247
int16_t           hw_log_level       = LOG_INFO;
gauthier's avatar
   
gauthier committed
248
int16_t           hw_log_verbosity   = LOG_MED;
249
int16_t           phy_log_level      = LOG_INFO;
gauthier's avatar
   
gauthier committed
250
int16_t           phy_log_verbosity  = LOG_MED;
251
int16_t           mac_log_level      = LOG_INFO;
gauthier's avatar
   
gauthier committed
252
int16_t           mac_log_verbosity  = LOG_MED;
253
int16_t           rlc_log_level      = LOG_INFO;
gauthier's avatar
   
gauthier committed
254
int16_t           rlc_log_verbosity  = LOG_MED;
255
int16_t           pdcp_log_level     = LOG_INFO;
gauthier's avatar
   
gauthier committed
256
int16_t           pdcp_log_verbosity = LOG_MED;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
257
int16_t           rrc_log_level      = LOG_INFO;
gauthier's avatar
   
gauthier committed
258
int16_t           rrc_log_verbosity  = LOG_MED;
259
260
261
int16_t           opt_log_level      = LOG_INFO;
int16_t           opt_log_verbosity  = LOG_MED;

gauthier's avatar
   
gauthier committed
262
263
264
265
266
267
# 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
268
269
270
#if defined (ENABLE_SECURITY)
int16_t           osa_log_level      = LOG_INFO;
int16_t           osa_log_verbosity  = LOG_MED;
271
#endif
272

knopp's avatar
   
knopp committed
273
274
275

#ifdef ETHERNET
char *rrh_UE_ip = "127.0.0.1";
276
int rrh_UE_port = 51000;
knopp's avatar
   
knopp committed
277
278
#endif

279
280
281
282
283
/* flag set by eNB conf file to specify if the radio head is local or remote (default option is local) */
uint8_t local_remote_radio = BBU_LOCAL_RADIO_HEAD;
/* struct for ethernet specific parameters given in eNB conf file */
eth_params_t *eth_params;

284
285
openair0_config_t openair0_cfg[MAX_CARDS];

286
287
288
// Change to openair_global to handle UE
openair0_device openair0;

289
290
double cpuf;

knopp's avatar
   
knopp committed
291
char uecap_xer[1024],uecap_xer_in=0;
292
293


knopp's avatar
   
knopp committed
294

295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
/*---------------------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 };

struct timespec clock_difftime(struct timespec start, struct timespec end)
{
    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;
}

Cedric Roux's avatar
Cedric Roux committed
313
void print_difftimes(void)
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
{
#ifdef DEBUG
    printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
#else
    LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
#endif
}

void update_difftimes(struct timespec start, struct timespec end)
{
    struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
    int             changed = 0;
    diff_time = clock_difftime(start, end);
    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; }
#if 1
    if (changed) print_difftimes();
#endif
}

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

336
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq)
337
{
knopp's avatar
   
knopp committed
338
  return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
339
340
341
}
unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe)
{
knopp's avatar
   
knopp committed
342
  return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
343
344
}

345
#if !defined(ENABLE_ITTI)
346
347
348
349
350
351
352
353
void signal_handler(int sig)
{
  void *array[10];
  size_t size;

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

355
356
357
358
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
359
360
  } else {
    printf("trying to exit gracefully...\n");
361
    oai_exit = 1;
362
363
  }
}
364
#endif
nikaeinn's avatar
nikaeinn committed
365
366
367
368
369
370
371
372
373
374
375
#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");
376
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
nikaeinn's avatar
nikaeinn committed
377
378
379
380
  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
381
382
  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
383
  printf("  --no-L2-connect bypass L2 and upper layers\n");
384
385
386
387
  printf("  --ue-rxgain set UE RX gain\n");
  printf("  --ue-txgain set UE TX gain\n");
  printf("  --ue-scan_carrier set UE to scan around carrier\n");
  printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
388
389
390
  printf("  --RCC run using NGFI RCC node function\n");
  printf("  --RRU run using NGFI RRU node function\n");
  printf("  --eNB run using 3GPP eNB node function\n");   
391
  printf("  -C Set the downlink frequency for all component carriers\n");
nikaeinn's avatar
nikaeinn committed
392
393
394
  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");
395
  printf("  -G Set the global log verbosity \n");
nikaeinn's avatar
nikaeinn committed
396
397
398
399
400
  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
401
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
nikaeinn's avatar
nikaeinn committed
402
403
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
404
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
nikaeinn's avatar
nikaeinn committed
405
406
407
  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");
408
409
410
411
412
413
414
  printf("  -x Set the transmission mode, valid options: 1 \n");
#if T_TRACER
  printf("  --T_port [port]    use given port\n");
  printf("  --T_nowait         don't wait for tracer, start immediately\n");
#endif
  printf(RESET);
  fflush(stdout);
nikaeinn's avatar
nikaeinn committed
415
}
416

417
418
void exit_fun(const char* s)
{
419
  if (s != NULL) {
420
    printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s);
421
422
423
424
425
  }

  oai_exit = 1;

#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
426
  sleep(1); //allow lte-softmodem threads to exit first
427
  itti_terminate_tasks (TASK_UNKNOWN);
428
#endif
429
430
431

}

432

433
#ifdef XFORMS
434

435
436
void reset_stats(FL_OBJECT *button, long arg)
{
437
438
  int i,j,k;
  PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
439
440
441

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    for (k=0; k<8; k++) { //harq_processes
442
443
444
445
      for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) {
        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;
446
      }
447

448
449
450
      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;
451

452
453
454
455
456
      for (j=0; j<phy_vars_eNB->ulsch[i]->Mlimit; j++) {
        phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts[k][j]=0;
        phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j]=0;
        phy_vars_eNB->UE_stats[i].ulsch_round_errors[k][j]=0;
        phy_vars_eNB->UE_stats[i].ulsch_round_fer[k][j]=0;
457
      }
458
    }
459

460
461
462
    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;
463
464
465
  }
}

466
467
static void *scope_thread(void *arg)
{
knopp's avatar
   
knopp committed
468
  char stats_buffer[16384];
469
# ifdef ENABLE_XFORMS_WRITE_STATS
knopp's avatar
   
knopp committed
470
  FILE *UE_stats, *eNB_stats;
471
# endif
Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
472
  int len = 0;
knopp's avatar
   
knopp committed
473
  struct sched_param sched_param;
474
  int UE_id, CC_id;
475
  int ue_cnt=0;
476

477
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
knopp's avatar
   
knopp committed
478
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
479

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

482
# ifdef ENABLE_XFORMS_WRITE_STATS
483
484

  if (UE_flag==1)
knopp's avatar
   
knopp committed
485
    UE_stats  = fopen("UE_stats.txt", "w");
486
  else
knopp's avatar
   
knopp committed
487
    eNB_stats = fopen("eNB_stats.txt", "w");
488

489
#endif
490

knopp's avatar
   
knopp committed
491
492
  while (!oai_exit) {
    if (UE_flag==1) {
Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
493
      len = dump_ue_stats (PHY_vars_UE_g[0][0], stats_buffer, 0, mode,rx_input_level_dBm);
knopp's avatar
knopp committed
494
495
496
      //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);
497

498
499
500
501
502
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

knopp's avatar
   
knopp committed
503
    } else {
504
505
506
507
508
509
      if (PHY_vars_eNB_g[0][0]->mac_enabled==1) {
	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);
      }
Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
510
      len = dump_eNB_stats (PHY_vars_eNB_g[0][0], stats_buffer, 0);
511

Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
512
      if (MAX_NUM_CCs>1)
513
514
        len += dump_eNB_stats (PHY_vars_eNB_g[0][1], &stats_buffer[len], 0);

kaltenbe's avatar
kaltenbe committed
515
516
517
      //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);
518

519
520
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
521
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
522
	  if ((PHY_vars_eNB_g[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) {
gauthier's avatar
gauthier committed
523
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
524
525
526
527
			  PHY_vars_eNB_g[0][CC_id],
			  UE_id);
	    ue_cnt++;
	  }
528
	}
knopp's avatar
   
knopp committed
529
      }
530

531
    }
532

knopp's avatar
   
knopp committed
533
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
534
535
    //usleep(100000); // 100 ms
    sleep(1);
knopp's avatar
   
knopp committed
536
  }
537

538
  //  printf("%s",stats_buffer);
539

540
# ifdef ENABLE_XFORMS_WRITE_STATS
541

542
543
544
545
546
547
  if (UE_flag==1) {
    if (UE_stats) {
      rewind (UE_stats);
      fwrite (stats_buffer, 1, len, UE_stats);
      fclose (UE_stats);
    }
548
  } else {
549
550
551
552
553
554
    if (eNB_stats) {
      rewind (eNB_stats);
      fwrite (stats_buffer, 1, len, eNB_stats);
      fclose (eNB_stats);
    }
  }
555

556
# endif
557

knopp's avatar
   
knopp committed
558
  pthread_exit((void*)arg);
559
560
561
}
#endif

562

563

564

knopp's avatar
   
knopp committed
565
#if defined(ENABLE_ITTI)
566
void *l2l1_task(void *arg)
567
{
knopp's avatar
   
knopp committed
568
569
570
571
572
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
573

knopp's avatar
   
knopp committed
574
575
  if (UE_flag == 0) {
    /* Wait for the initialize message */
576
    printf("Wait for the ITTI initialize message\n");
577
578
579
580
581
    do {
      if (message_p != NULL) {
        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
582

583
      itti_receive_msg (TASK_L2L1, &message_p);
584

585
586
587
588
589
590
      switch (ITTI_MSG_ID(message_p)) {
      case INITIALIZE_MESSAGE:
        /* Start eNB thread */
        LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p));
        start_eNB = 1;
        break;
591

592
593
594
595
596
      case TERMINATE_MESSAGE:
        printf("received terminate message\n");
        oai_exit=1;
        itti_exit_task ();
        break;
597

598
599
600
601
602
      default:
        LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
        break;
      }
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
603

604
605
606
    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  }
607

608
609
610
  do {
    // Wait for a message
    itti_receive_msg (TASK_L2L1, &message_p);
611

612
613
614
615
616
    switch (ITTI_MSG_ID(message_p)) {
    case TERMINATE_MESSAGE:
      oai_exit=1;
      itti_exit_task ();
      break;
knopp's avatar
   
knopp committed
617

618
619
620
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
621

622
623
624
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
625

626
627
628
    case MESSAGE_TEST:
      LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
      break;
629

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

635
636
637
    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  } while(!oai_exit);
638

639
640
  return NULL;
}
knopp's avatar
   
knopp committed
641
#endif
642

643

644

645

646
647
static void get_options (int argc, char **argv)
{
648
649
650
  int c;
  //  char                          line[1000];
  //  int                           l;
651
  int k,i;//,j,k;
652
#if defined(OAI_USRP) || defined(CPRIGW)
653
  int clock_src;
knopp's avatar
knopp committed
654
#endif
655
  int CC_id;
656
657


658
659

  const Enb_properties_array_t *enb_properties;
660

661
662
  enum long_option_e {
    LONG_OPTION_START = 0x100, /* Start after regular single char options */
663
    LONG_OPTION_RF_CONFIG_FILE,
664
665
666
667
668
    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,
669
    LONG_OPTION_NO_L2_CONNECT,
knopp's avatar
   
knopp committed
670
    LONG_OPTION_CALIB_PRACH_TX,
671
672
    LONG_OPTION_RXGAIN,
    LONG_OPTION_TXGAIN,
673
    LONG_OPTION_SCANCARRIER,
674
675
    LONG_OPTION_MAXPOWER,
    LONG_OPTION_DUMP_FRAME,
676
    LONG_OPTION_LOOPMEMORY,
677
678
679
680
    LONG_OPTION_PHYTEST,
    LONG_OPTION_RCC,
    LONG_OPTION_RRU,
    LONG_OPTION_ENB
681
#if T_TRACER
682
    ,
683
684
685
    LONG_OPTION_T_PORT,
    LONG_OPTION_T_NOWAIT,
#endif
686
  };
687

688
  static const struct option long_options[] = {
689
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
690
691
692
693
694
695
    {"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
696
697
698
699
    {"calib-prach-tx",   no_argument,        NULL, LONG_OPTION_CALIB_PRACH_TX},
    {"ue-rxgain",   required_argument,  NULL, LONG_OPTION_RXGAIN},
    {"ue-txgain",   required_argument,  NULL, LONG_OPTION_TXGAIN},
    {"ue-scan-carrier",   no_argument,  NULL, LONG_OPTION_SCANCARRIER},
700
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
701
702
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
703
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
704
705
706
    {"RCC", no_argument, NULL, LONG_OPTION_RCC},
    {"RRU", no_argument, NULL, LONG_OPTION_RRU},
    {"eNB", no_argument, NULL, LONG_OPTION_ENB},
707
708
709
710
#if T_TRACER
    {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
    {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
#endif
711
712
713
    {NULL, 0, NULL, 0}
  };

714
  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) {
715
    switch (c) {
716
    case LONG_OPTION_RF_CONFIG_FILE:
717
718
719
720
721
722
      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 {
723
724
725
726
         printf("Configuration filename is too long\n");
         exit(-1);   
      }
      break;
727
728
729
730
    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];
731
      break;
732
733
734
735
    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;
736

737
738
739
740
741
    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;
742

743
744
745
746
    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
747
      break;
748

749
750
751
752
753
    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;
754

755
756
757
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
758

759
760
761
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
762

knopp's avatar
   
knopp committed
763
764
765
766
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
      break;

767
    case LONG_OPTION_RXGAIN:
768
769
      for (i=0; i<4; i++)
        rx_gain[0][i] = atof(optarg);
770

771
      break;
772

773
774
775
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
776

777
      break;
778

779
780
781
782
783
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

784
785
786
787
788
789
    case LONG_OPTION_LOOPMEMORY:
      mode=loop_through_memory;
      input_fd = fopen(optarg,"r");
      AssertFatal(input_fd != NULL,"Please provide an input file\n");
      break;

790
791
792
793
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
794
795
796
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
797
798
799
800
801
802
803
804
805
806
807
808

    case LONG_OPTION_RCC:
      node_function = NGFI_RCC_IF4;
      break;

    case LONG_OPTION_RRU:
      node_function = NGFI_RRU_IF4;
      break;

    case LONG_OPTION_ENB:
      node_function = eNodeB_3GPP;
      break;
809
      
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
#if T_TRACER
    case LONG_OPTION_T_PORT: {
      extern int T_port;
      if (optarg == NULL) abort();  /* should not happen */
      T_port = atoi(optarg);
      break;
    }

    case LONG_OPTION_T_NOWAIT: {
      extern int T_wait;
      T_wait = 0;
      break;
    }
#endif

825
826
827
828
    case 'A':
      timing_advance = atoi (optarg);
      break;

829
    case 'C':
830
831
832
833
834
835
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
        downlink_frequency[CC_id][0] = atof(optarg); // 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
836
      }
837

838
      UE_scan=0;
839

840
      break;
841

Florian Kaltenberger's avatar
Florian Kaltenberger committed
842
843
844
845
    case 'a':
      chain_offset = atoi(optarg);
      break;

846
847
848
849
    case 'd':
#ifdef XFORMS
      do_forms=1;
      printf("Running with XFORMS!\n");
knopp's avatar
   
knopp committed
850
#endif
851
      break;
852
853
854
855
      
    case 'E':
      threequarter_fs=1;
      break;
856

857
858
859
    case 'K':
#if defined(ENABLE_ITTI)
      itti_dump_file = strdup(optarg);
860
#else
861
      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
knopp's avatar
   
knopp committed
862
#endif
863
      break;
864

865
866
867
    case 'O':
      conf_config_file_name = optarg;
      break;
868

869
870
871
    case 'U':
      UE_flag = 1;
      break;
872

873
874
875
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
876

877
878
879
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
880

881
882
883
884
885
886
887
    case 'W':
      opt_enabled=1;
      opt_type = OPT_WIRESHARK;
      strncpy(in_ip, "127.0.0.1", sizeof(in_ip));
      in_ip[sizeof(in_ip) - 1] = 0; // terminate string
      printf("Enabling OPT for wireshark for local interface");
      /*
888
889
890
      if (optarg == NULL){
      in_ip[0] =NULL;
      printf("Enabling OPT for wireshark for local interface");
891
      } else {
892
893
894
      strncpy(in_ip, optarg, sizeof(in_ip));
      in_ip[sizeof(in_ip) - 1] = 0; // terminate string
      printf("Enabling OPT for wireshark with %s \n",in_ip);
895
896
897
      }
      */
      break;
898

899
    case 'P':
900
901
      opt_type = OPT_PCAP;
      opt_enabled=1;
902
903
904
905
906

      if (optarg == NULL) {
        strncpy(in_path, "/tmp/oai_opt.pcap", sizeof(in_path));
        in_path[sizeof(in_path) - 1] = 0; // terminate string
        printf("Enabling OPT for PCAP with the following path /tmp/oai_opt.pcap");
907
      } else {
908
909
910
        strncpy(in_path, optarg, sizeof(in_path));
        in_path[sizeof(in_path) - 1] = 0; // terminate string
        printf("Enabling OPT for PCAP  with the following file %s \n",in_path);
911
      }
912
913
914

      break;

knopp's avatar
   
knopp committed
915
916
917
    case 'V':
      ouput_vcd = 1;
      break;
918

knopp's avatar
   
knopp committed
919
    case  'q':
knopp's avatar
   
knopp committed
920
921
      opp_enabled = 1;
      break;
922

knopp's avatar
   
knopp committed
923
924
925
    case  'R' :
      online_log_messages =1;
      break;
926

knopp's avatar