lte-softmodem.c 58 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
#include "rt_wrapper.h"
55

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

58
#include "assertions.h"
59
#include "msc.h"
60
61

#include "PHY/types.h"
62

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

knopp's avatar
   
knopp committed
67
68
#include "../../ARCH/COMMON/common_lib.h"

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

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

Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
96
97
98
99
#ifndef OPENAIR2
#include "UTIL/OTG/otg_vars.h"
#endif

100
101
#if defined(ENABLE_ITTI)
# include "intertask_interface_init.h"
102
# include "create_tasks.h"
103
104
# if defined(ENABLE_USE_MME)
#   include "s1ap_eNB.h"
105
#ifdef PDCP_USE_NETLINK
106
107
#   include "SIMULATION/ETH_TRANSPORT/proto.h"
#endif
108
# endif
109
110
#endif

111
112
113
#ifdef XFORMS
#include "PHY/TOOLS/lte_phy_scope.h"
#include "stats.h"
114
115
#endif

116
// In lte-enb.c
117
int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
118

119
120
extern void init_eNB(void);
extern void stop_eNB(void);
121
extern void kill_eNB_proc(void);
122

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

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

138

139

140
141


knopp's avatar
   
knopp committed
142

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

147

148
149


150

151

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

knopp's avatar
   
knopp committed
156
openair0_device openair0;
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

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
286
287
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

knopp's avatar
   
knopp committed
288
char uecap_xer[1024],uecap_xer_in=0;
289
290


knopp's avatar
   
knopp committed
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/*---------------------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
310
void print_difftimes(void)
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
{
#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
}

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

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

342
#if !defined(ENABLE_ITTI)
343
344
345
346
347
348
349
350
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);
351

352
353
354
355
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
356
357
  } else {
    printf("trying to exit gracefully...\n");
358
    oai_exit = 1;
359
360
  }
}
361
#endif
nikaeinn's avatar
nikaeinn committed
362
363
364
365
366
367
368
369
370
371
372
#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");
373
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
nikaeinn's avatar
nikaeinn committed
374
375
376
377
  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
378
379
  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
380
  printf("  --no-L2-connect bypass L2 and upper layers\n");
381
382
383
384
  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");
385
  printf("  -C Set the downlink frequency for all component carriers\n");
nikaeinn's avatar
nikaeinn committed
386
387
388
  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");
389
  printf("  -G Set the global log verbosity \n");
nikaeinn's avatar
nikaeinn committed
390
391
392
393
394
  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
395
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
nikaeinn's avatar
nikaeinn committed
396
397
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
398
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
nikaeinn's avatar
nikaeinn committed
399
400
401
402
  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");
  printf("  -x Set the transmission mode, valid options: 1 \n"RESET);    
403

nikaeinn's avatar
nikaeinn committed
404
}
405

406
407
void exit_fun(const char* s)
{
408
  if (s != NULL) {
409
    printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s);
410
411
412
413
414
  }

  oai_exit = 1;

#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
415
  sleep(1); //allow lte-softmodem threads to exit first
416
  itti_terminate_tasks (TASK_UNKNOWN);
417
#endif
418
419
420

}

421

422
#ifdef XFORMS
423

424
425
void reset_stats(FL_OBJECT *button, long arg)
{
426
427
  int i,j,k;
  PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[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_eNB[i][0]->Mlimit; j++) {
432
433
434
        phy_vars_eNB->eNB_UE_stats[i].dlsch_NAK[k][j]=0;
        phy_vars_eNB->eNB_UE_stats[i].dlsch_ACK[k][j]=0;
        phy_vars_eNB->eNB_UE_stats[i].dlsch_trials[k][j]=0;
435
      }
436

437
438
439
      phy_vars_eNB->eNB_UE_stats[i].dlsch_l2_errors[k]=0;
      phy_vars_eNB->eNB_UE_stats[i].ulsch_errors[k]=0;
      phy_vars_eNB->eNB_UE_stats[i].ulsch_consecutive_errors=0;
440

441
      for (j=0; j<phy_vars_eNB->ulsch_eNB[i]->Mlimit; j++) {
442
443
444
445
        phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts[k][j]=0;
        phy_vars_eNB->eNB_UE_stats[i].ulsch_decoding_attempts_last[k][j]=0;
        phy_vars_eNB->eNB_UE_stats[i].ulsch_round_errors[k][j]=0;
        phy_vars_eNB->eNB_UE_stats[i].ulsch_round_fer[k][j]=0;
446
      }
447
    }
448

449
450
451
    phy_vars_eNB->eNB_UE_stats[i].dlsch_sliding_cnt=0;
    phy_vars_eNB->eNB_UE_stats[i].dlsch_NAK_round0=0;
    phy_vars_eNB->eNB_UE_stats[i].dlsch_mcs_offset=0;
452
453
454
  }
}

455
456
static void *scope_thread(void *arg)
{
knopp's avatar
   
knopp committed
457
  char stats_buffer[16384];
458
# ifdef ENABLE_XFORMS_WRITE_STATS
knopp's avatar
   
knopp committed
459
  FILE *UE_stats, *eNB_stats;
460
# endif
Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
461
  int len = 0;
knopp's avatar
   
knopp committed
462
  struct sched_param sched_param;
463
  int UE_id, CC_id;
464
  int ue_cnt=0;
465

466
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
knopp's avatar
   
knopp committed
467
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
468

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

471
# ifdef ENABLE_XFORMS_WRITE_STATS
472
473

  if (UE_flag==1)
knopp's avatar
   
knopp committed
474
    UE_stats  = fopen("UE_stats.txt", "w");
475
  else
knopp's avatar
   
knopp committed
476
    eNB_stats = fopen("eNB_stats.txt", "w");
477

478
#endif
479

knopp's avatar
   
knopp committed
480
481
  while (!oai_exit) {
    if (UE_flag==1) {
Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
482
      len = dump_ue_stats (PHY_vars_UE_g[0][0], stats_buffer, 0, mode,rx_input_level_dBm);
knopp's avatar
knopp committed
483
484
485
      //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);
486

487
488
489
490
491
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

knopp's avatar
   
knopp committed
492
    } else {
493
494
495
496
497
498
      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
499
      len = dump_eNB_stats (PHY_vars_eNB_g[0][0], stats_buffer, 0);
500

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

kaltenbe's avatar
kaltenbe committed
504
505
506
      //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);
507

508
509
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
510
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
511
	  if ((PHY_vars_eNB_g[0][CC_id]->dlsch_eNB[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) {
gauthier's avatar
gauthier committed
512
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
513
514
515
516
			  PHY_vars_eNB_g[0][CC_id],
			  UE_id);
	    ue_cnt++;
	  }
517
	}
knopp's avatar
   
knopp committed
518
      }
519

520
    }
521

knopp's avatar
   
knopp committed
522
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
523
524
    //usleep(100000); // 100 ms
    sleep(1);
knopp's avatar
   
knopp committed
525
  }
526

527
  //  printf("%s",stats_buffer);
528

529
# ifdef ENABLE_XFORMS_WRITE_STATS
530

531
532
533
534
535
536
  if (UE_flag==1) {
    if (UE_stats) {
      rewind (UE_stats);
      fwrite (stats_buffer, 1, len, UE_stats);
      fclose (UE_stats);
    }
537
  } else {
538
539
540
541
542
543
    if (eNB_stats) {
      rewind (eNB_stats);
      fwrite (stats_buffer, 1, len, eNB_stats);
      fclose (eNB_stats);
    }
  }
544

545
# endif
546

knopp's avatar
   
knopp committed
547
  pthread_exit((void*)arg);
548
549
550
}
#endif

551

552

553

knopp's avatar
   
knopp committed
554
#if defined(ENABLE_ITTI)
555
void *l2l1_task(void *arg)
556
{
knopp's avatar
   
knopp committed
557
558
559
560
561
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
562

knopp's avatar
   
knopp committed
563
564
  if (UE_flag == 0) {
    /* Wait for the initialize message */
565
    printf("Wait for the ITTI initialize message\n");
566
567
568
569
570
    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
571

572
      itti_receive_msg (TASK_L2L1, &message_p);
573

574
575
576
577
578
579
      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;
580

581
582
583
584
585
      case TERMINATE_MESSAGE:
        printf("received terminate message\n");
        oai_exit=1;
        itti_exit_task ();
        break;
586

587
588
589
590
591
      default:
        LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
        break;
      }
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
592

593
594
595
    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  }
596

597
598
599
  do {
    // Wait for a message
    itti_receive_msg (TASK_L2L1, &message_p);
600

601
602
603
604
605
    switch (ITTI_MSG_ID(message_p)) {
    case TERMINATE_MESSAGE:
      oai_exit=1;
      itti_exit_task ();
      break;
knopp's avatar
   
knopp committed
606

607
608
609
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
610

611
612
613
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
614

615
616
617
    case MESSAGE_TEST:
      LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
      break;
618

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

624
625
626
    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);
627

628
629
  return NULL;
}
knopp's avatar
   
knopp committed
630
#endif
631

632

633

634
635


636

637

knopp's avatar
   
knopp committed
638

Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
639

640
641
static void get_options (int argc, char **argv)
{
642
643
644
  int c;
  //  char                          line[1000];
  //  int                           l;
645
  int k,i;//,j,k;
646
#if defined(OAI_USRP) || defined(CPRIGW)
647
  int clock_src;
knopp's avatar
knopp committed
648
#endif
649
  int CC_id;
650
651


652
653

  const Enb_properties_array_t *enb_properties;
654

655
656
  enum long_option_e {
    LONG_OPTION_START = 0x100, /* Start after regular single char options */
657
    LONG_OPTION_RF_CONFIG_FILE,
658
659
660
661
662
    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,
663
    LONG_OPTION_NO_L2_CONNECT,
knopp's avatar
   
knopp committed
664
    LONG_OPTION_CALIB_PRACH_TX,
665
666
    LONG_OPTION_RXGAIN,
    LONG_OPTION_TXGAIN,
667
    LONG_OPTION_SCANCARRIER,
668
669
    LONG_OPTION_MAXPOWER,
    LONG_OPTION_DUMP_FRAME,
670
671
    LONG_OPTION_LOOPMEMORY,
    LONG_OPTION_PHYTEST
672
  };
673

674
  static const struct option long_options[] = {
675
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
676
677
678
679
680
681
    {"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
682
683
684
685
    {"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},
686
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
687
688
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
689
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
690
691
692
    {NULL, 0, NULL, 0}
  };

693
  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) {
694
    switch (c) {
695
    case LONG_OPTION_RF_CONFIG_FILE:
696
697
698
699
700
701
      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 {
702
703
704
705
         printf("Configuration filename is too long\n");
         exit(-1);   
      }
      break;
706
707
708
709
    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];
710
      break;
711
712
713
714
    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;
715

716
717
718
719
720
    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;
721

722
723
724
725
    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
726
      break;
727

728
729
730
731
732
    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;
733

734
735
736
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
737

738
739
740
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
741

knopp's avatar
   
knopp committed
742
743
744
745
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
      break;

746
    case LONG_OPTION_RXGAIN:
747
748
      for (i=0; i<4; i++)
        rx_gain[0][i] = atof(optarg);
749

750
      break;
751

752
753
754
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
755

756
      break;
757

758
759
760
761
762
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

763
764
765
766
767
768
    case LONG_OPTION_LOOPMEMORY:
      mode=loop_through_memory;
      input_fd = fopen(optarg,"r");
      AssertFatal(input_fd != NULL,"Please provide an input file\n");
      break;

769
770
771
772
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
773
774
775
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
776
      
777
778
779
780
    case 'A':
      timing_advance = atoi (optarg);
      break;

781
    case 'C':
782
783
784
785
786
787
      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
788
      }
789

790
      UE_scan=0;
791

792
      break;
793

Florian Kaltenberger's avatar
Florian Kaltenberger committed
794
795
796
797
    case 'a':
      chain_offset = atoi(optarg);
      break;

798
799
800
801
    case 'd':
#ifdef XFORMS
      do_forms=1;
      printf("Running with XFORMS!\n");
knopp's avatar
   
knopp committed
802
#endif
803
      break;
804
805
806
807
      
    case 'E':
      threequarter_fs=1;
      break;
808

809
810
811
    case 'K':
#if defined(ENABLE_ITTI)
      itti_dump_file = strdup(optarg);
812
#else
813
      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
knopp's avatar
   
knopp committed
814
#endif
815
      break;
816

817
818
819
    case 'O':
      conf_config_file_name = optarg;
      break;
820

821
822
823
    case 'U':
      UE_flag = 1;
      break;
824

825
826
827
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
828

829
830
831
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
832

833
834
835
836
837
838
839
    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");
      /*
840
841
842
      if (optarg == NULL){
      in_ip[0] =NULL;
      printf("Enabling OPT for wireshark for local interface");
843
      } else {
844
845
846
      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);
847
848
849
      }
      */
      break;
850

851
    case 'P':
852
853
      opt_type = OPT_PCAP;
      opt_enabled=1;
854
855
856
857
858

      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");
859
      } else {
860
861
862
        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);
863
      }
864
865
866

      break;

knopp's avatar
   
knopp committed
867
868
869
    case 'V':
      ouput_vcd = 1;
      break;
870