lte-softmodem.c 61 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
extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
118
extern void init_eNB(eNB_func_t);
119
extern void stop_eNB(void);
120
extern void kill_eNB_proc(void);
121

122
// In lte-ue.c
123
124
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);
125
126
extern void init_UE(void);

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

137

138

139
140


knopp's avatar
   
knopp committed
141

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

146

147
148


149

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

154
155
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
156

157

158
#if defined(ENABLE_ITTI)
159
160
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
161
#endif
162
163
volatile int                    oai_exit = 0;

164

165

knopp's avatar
   
knopp committed
166

167
static char                     UE_flag=0;
168
169
//static uint8_t                  eNB_id=0,UE_id=0;

170
static char                     threequarter_fs=0;
171

172
uint32_t                 downlink_frequency[MAX_NUM_CCs][4];
173
int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
gauthier's avatar
gauthier committed
174

175
openair0_rf_map rf_map[MAX_NUM_CCs];
176

177
static char                    *conf_config_file_name = NULL;
178
#if defined(ENABLE_ITTI)
179
static char                    *itti_dump_file = NULL;
knopp's avatar
   
knopp committed
180
181
#endif

182
int UE_scan = 1;
183
int UE_scan_carrier = 0;
184
185
runmode_t mode = normal_txrx;

186
187
FILE *input_fd=NULL;

188

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

199
200


knopp's avatar
   
knopp committed
201
double sample_rate=30.72e6;
202
double bw = 10.0e6;
203

204
static int                      tx_max_power[MAX_NUM_CCs]; /* =  {0,0}*/;
205

206
207
char   rf_config_file[1024];

Florian Kaltenberger's avatar
Florian Kaltenberger committed
208
int chain_offset=0;
209
int phy_test = 0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
210

211

knopp's avatar
   
knopp committed
212
213
214
char ref[128] = "internal";
char channels[128] = "0";

215
int                      rx_input_level_dBm;
216
static int                      online_log_messages=0;
217
#ifdef XFORMS
218
extern int                      otg_enabled;
219
static char                     do_forms=0;
220
#else
221
int                             otg_enabled;
222
#endif
knopp's avatar
   
knopp committed
223
//int                             number_of_cards =   1;
224

225

knopp's avatar
   
knopp committed
226
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
227
eNB_func_t node_function=eNodeB_3GPP;
228

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

knopp's avatar
   
knopp committed
235

236
237
238

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

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

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

knopp's avatar
   
knopp committed
269
270
271

#ifdef ETHERNET
char *rrh_UE_ip = "127.0.0.1";
272
int rrh_UE_port = 51000;
knopp's avatar
   
knopp committed
273
274
#endif

275
276
277
278
279
/* 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;

280
281
openair0_config_t openair0_cfg[MAX_CARDS];

282
283
284
// Change to openair_global to handle UE
openair0_device openair0;

285
286
double cpuf;

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


knopp's avatar
   
knopp committed
290

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

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

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

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

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

nikaeinn's avatar
nikaeinn committed
406
}
407

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

  oai_exit = 1;

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

}

423

424
#ifdef XFORMS
425

426
427
void reset_stats(FL_OBJECT *button, long arg)
{
428
429
  int i,j,k;
  PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
430
431
432

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    for (k=0; k<8; k++) { //harq_processes
433
434
435
436
      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;
437
      }
438

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

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

451
452
453
    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;
454
455
456
  }
}

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

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

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

473
# ifdef ENABLE_XFORMS_WRITE_STATS
474
475

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

480
#endif
481

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

489
490
491
492
493
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

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

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

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

510
511
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
512
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
513
	  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
514
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
515
516
517
518
			  PHY_vars_eNB_g[0][CC_id],
			  UE_id);
	    ue_cnt++;
	  }
519
	}
knopp's avatar
   
knopp committed
520
      }
521

522
    }
523

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

529
  //  printf("%s",stats_buffer);
530

531
# ifdef ENABLE_XFORMS_WRITE_STATS
532

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

547
# endif
548

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

553

554

555

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
564

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

574
      itti_receive_msg (TASK_L2L1, &message_p);
575

576
577
578
579
580
581
      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;
582

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

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

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

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

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

609
610
611
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
612

613
614
615
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
616

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

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

626
627
628
    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);
629

630
631
  return NULL;
}
knopp's avatar
   
knopp committed
632
#endif
633

634

635

636

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


649
650

  const Enb_properties_array_t *enb_properties;
651

652
653
  enum long_option_e {
    LONG_OPTION_START = 0x100, /* Start after regular single char options */
654
    LONG_OPTION_RF_CONFIG_FILE,
655
656
657
658
659
    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,
660
    LONG_OPTION_NO_L2_CONNECT,
knopp's avatar
   
knopp committed
661
    LONG_OPTION_CALIB_PRACH_TX,
662
663
    LONG_OPTION_RXGAIN,
    LONG_OPTION_TXGAIN,
664
    LONG_OPTION_SCANCARRIER,
665
666
    LONG_OPTION_MAXPOWER,
    LONG_OPTION_DUMP_FRAME,
667
    LONG_OPTION_LOOPMEMORY,
668
669
670
671
    LONG_OPTION_PHYTEST,
    LONG_OPTION_RCC,
    LONG_OPTION_RRU,
    LONG_OPTION_ENB
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
    {"RCC", no_argument, NULL, LONG_OPTION_RCC},
    {"RRU", no_argument, NULL, LONG_OPTION_RRU},
    {"eNB", no_argument, NULL, LONG_OPTION_ENB},
693
694
695
    {NULL, 0, NULL, 0}
  };

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

719
720
721
722
723
    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;
724

725
726
727
728
    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
729
      break;
730

731
732
733
734
735
    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;
736

737
738
739
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
740

741
742
743
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
744

knopp's avatar
   
knopp committed
745
746
747
748
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
      break;

749
    case LONG_OPTION_RXGAIN:
750
751
      for (i=0; i<4; i++)
        rx_gain[0][i] = atof(optarg);
752

753
      break;
754

755
756
757
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
758

759
      break;
760

761
762
763
764
765
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

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

772
773
774
775
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
776
777
778
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
779
780
781
782
783
784
785
786
787
788
789
790

    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;
791
      
792
793
794
795
    case 'A':
      timing_advance = atoi (optarg);
      break;

796
    case 'C':
797
798
799
800
801
802
      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
803
      }
804

805
      UE_scan=0;
806

807
      break;
808

Florian Kaltenberger's avatar
Florian Kaltenberger committed
809
810
811
812
    case 'a':
      chain_offset = atoi(optarg);
      break;

813
814
815
816
    case 'd':
#ifdef XFORMS
      do_forms=1;
      printf("Running with XFORMS!\n");
knopp's avatar
   
knopp committed
817
#endif
818
      break;
819
820
821
822
      
    case 'E':
      threequarter_fs=1;
      break;
823

824
825
826
    case 'K':
#if defined(ENABLE_ITTI)
      itti_dump_file = strdup(optarg);
827
#else
828
      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
knopp's avatar
   
knopp committed
829
#endif
830
      break;
831

832
833
834
    case 'O':
      conf_config_file_name = optarg;
      break;
835

836
837
838
    case 'U':
      UE_flag = 1;
      break;
839

840
841
842
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
843

844
845
846
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
847

848
849
850
851
852
853
854
    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");
      /*
855
856
857
      if (optarg == NULL){
      in_ip[0] =NULL;
      printf("Enabling OPT for wireshark for local interface");
858
      } else {
859
860
861
      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);
862
863
864
      }
      */
      break;
865

866
    case 'P':
867
868
      opt_type = OPT_PCAP;
      opt_enabled=1;
869
870
871
872
873

      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");
874
      } else {
875
876
877
        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);
878
      }
879
880
881

      break;

knopp's avatar
   
knopp committed
882
883
884
    case 'V':
      ouput_vcd = 1;
      break;
885

knopp's avatar
   
knopp committed
886
    case  'q':
knopp's avatar
   
knopp committed
887
888
      opp_enabled = 1;
      break;
889

knopp's avatar
   
knopp committed
890
891
892
    case  'R' :
      online_log_messages =1;
      break;
893

knopp's avatar
   
knopp committed
894
    case 'r':
895
      UE_scan = 0;
896

897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
        switch(atoi(optarg)) {
        case 6:
          frame_parms[CC_id]->N_RB_DL=6;
          frame_parms[CC_id]->N_RB_UL=6;
          break;

        case 25:
          frame_parms[CC_id]->N_RB_DL=25;
          frame_parms[CC_id]->N_RB_UL=25;
          break;

        case 50:
          frame_parms[CC_id]->N_RB_DL=50;
          frame_parms[CC_id]->N_RB_UL=50;
          break;

        case 100:
          frame_parms[CC_id]->N_RB_DL=100;
          frame_parms[CC_id]->N_RB_UL=100;
          break;

        default:
          printf("Unknown N_RB_DL %d, switching to 25\n",atoi(optarg));
          break;
        }
knopp's avatar
   
knopp committed
923
      }
924

925
      break;
926

knopp's avatar
   
knopp committed