lte-softmodem.c 61.1 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
#   include "SIMULATION/ETH_TRANSPORT/proto.h"
Rohit Gupta's avatar
Rohit Gupta committed
111
extern int netlink_init(void);
112
#endif
113
# endif
114
115
#endif

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

121
// In lte-enb.c
knopp's avatar
knopp committed
122
extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg);
knopp's avatar
knopp committed
123
extern void init_eNB(eNB_func_t *, eNB_timing_t *,int,eth_params_t *,int);
124
extern void stop_eNB(int);
125
extern void kill_eNB_proc(void);
126

127
// In lte-ue.c
knopp's avatar
knopp committed
128
extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
129
extern void fill_ue_band_info(void);
knopp's avatar
knopp committed
130
extern void init_UE(int);
131

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

142

143

144
145


knopp's avatar
   
knopp committed
146

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

151

152
153


154

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

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

162

163
#if defined(ENABLE_ITTI)
164
165
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
166
#endif
knopp's avatar
knopp committed
167
volatile int             oai_exit = 0;
168

169

170

knopp's avatar
   
knopp committed
171

knopp's avatar
knopp committed
172
static char              UE_flag=0;
173
unsigned int                    mmapped_dma=0;
knopp's avatar
knopp committed
174
int                             single_thread_flag=0;
175

176
static char                     threequarter_fs=0;
177

178
uint32_t                 downlink_frequency[MAX_NUM_CCs][4];
179
int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
gauthier's avatar
gauthier committed
180

181

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

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

191
192
FILE *input_fd=NULL;

193

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

204
205


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

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

211
212
char   rf_config_file[1024];

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

216

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

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

230

knopp's avatar
   
knopp committed
231
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
232
233
234
eNB_func_t node_function[MAX_NUM_CCs];
eNB_timing_t node_timing[MAX_NUM_CCs];
int16_t   node_synch_ref[MAX_NUM_CCs];
235

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

knopp's avatar
   
knopp committed
242

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

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

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

knopp's avatar
   
knopp committed
275

knopp's avatar
knopp committed
276

knopp's avatar
   
knopp committed
277
char *rrh_UE_ip = "127.0.0.1";
278
int rrh_UE_port = 51000;
knopp's avatar
knopp committed
279

knopp's avatar
   
knopp committed
280

281
282
283
284
285
/* 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;

286
287
288
289
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

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


knopp's avatar
   
knopp committed
293

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

Cedric Roux's avatar
Cedric Roux committed
312
void print_difftimes(void)
313
314
{
#ifdef DEBUG
315
  printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
316
#else
317
  LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
318
319
320
321
322
#endif
}

void update_difftimes(struct timespec start, struct timespec end)
{
323
324
325
326
327
  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; }
328
#if 1
329
  if (changed) print_difftimes();
330
331
332
333
334
#endif
}

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

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

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

354
355
356
357
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
358
359
  } else {
    printf("trying to exit gracefully...\n");
360
    oai_exit = 1;
361
362
  }
}
363
#endif
nikaeinn's avatar
nikaeinn committed
364
365
366
367
368
369
370
371
372
373
374
#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");
375
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
nikaeinn's avatar
nikaeinn committed
376
377
378
379
  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
380
381
  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
382
  printf("  --no-L2-connect bypass L2 and upper layers\n");
383
384
385
386
  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");
387
388
  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");  
  printf("  --single-thread runs lte-softmodem in only one thread\n"); 
389
  printf("  -C Set the downlink frequency for all component carriers\n");
nikaeinn's avatar
nikaeinn committed
390
391
392
  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");
393
  printf("  -G Set the global log verbosity \n");
nikaeinn's avatar
nikaeinn committed
394
395
396
397
398
  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
399
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
nikaeinn's avatar
nikaeinn committed
400
401
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
402
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
nikaeinn's avatar
nikaeinn committed
403
404
405
  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");
406
  printf("  -x Set the transmission mode, valid options: 1 \n");
407
  printf("  -E Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n");
408
409
410
#if T_TRACER
  printf("  --T_port [port]    use given port\n");
  printf("  --T_nowait         don't wait for tracer, start immediately\n");
411
  printf("  --T_dont_fork      to ease debugging with gdb\n");
412
413
414
#endif
  printf(RESET);
  fflush(stdout);
nikaeinn's avatar
nikaeinn committed
415
}
416

417
418
void exit_fun(const char* s)
{
Raymond Knopp's avatar
Raymond Knopp committed
419
420
  int CC_id;

421
  if (s != NULL) {
422
    printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s);
423
424
425
  }

  oai_exit = 1;
Raymond Knopp's avatar
Raymond Knopp committed
426
427
  
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
knopp committed
428
429
430
431
432
433
434
435
436
437
    if (UE_flag == 0) {
      if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func)
	PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice);
      if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func)
	PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice);  
    }
    else {
      if (PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func)
	PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice);
    }
Raymond Knopp's avatar
Raymond Knopp committed
438
  }
439
440

#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
441
  sleep(1); //allow lte-softmodem threads to exit first
442
  itti_terminate_tasks (TASK_UNKNOWN);
443
#endif
444
445
446

}

447

448
#ifdef XFORMS
449

450
451
void reset_stats(FL_OBJECT *button, long arg)
{
452
453
  int i,j,k;
  PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
454
455
456

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    for (k=0; k<8; k++) { //harq_processes
457
458
459
460
      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;
461
      }
462

463
464
465
      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;
466

467
468
469
470
471
      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;
472
      }
473
    }
474

475
476
477
    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;
478
479
480
  }
}

481
482
static void *scope_thread(void *arg)
{
knopp's avatar
   
knopp committed
483
  char stats_buffer[16384];
484
# ifdef ENABLE_XFORMS_WRITE_STATS
knopp's avatar
   
knopp committed
485
  FILE *UE_stats, *eNB_stats;
486
# endif
Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
487
  int len = 0;
knopp's avatar
   
knopp committed
488
  struct sched_param sched_param;
489
  int UE_id, CC_id;
490
  int ue_cnt=0;
491

492
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
knopp's avatar
   
knopp committed
493
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
494

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

497
# ifdef ENABLE_XFORMS_WRITE_STATS
498
499

  if (UE_flag==1)
knopp's avatar
   
knopp committed
500
    UE_stats  = fopen("UE_stats.txt", "w");
501
  else
knopp's avatar
   
knopp committed
502
    eNB_stats = fopen("eNB_stats.txt", "w");
503

504
#endif
505

knopp's avatar
   
knopp committed
506
507
  while (!oai_exit) {
    if (UE_flag==1) {
508
      len = dump_ue_stats (PHY_vars_UE_g[0][0], &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0],stats_buffer, 0, mode,rx_input_level_dBm);
knopp's avatar
knopp committed
509
510
511
      //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);
512

513
514
515
516
517
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

knopp's avatar
   
knopp committed
518
    } else {
519
520
521
522
523
524
      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
525
      len = dump_eNB_stats (PHY_vars_eNB_g[0][0], stats_buffer, 0);
526

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

kaltenbe's avatar
kaltenbe committed
530
531
532
      //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);
533

534
535
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
536
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
537
538
	  //	  if ((PHY_vars_eNB_g[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) {
	  if ((ue_cnt<scope_enb_num_ue)) {
gauthier's avatar
gauthier committed
539
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
540
541
542
543
			  PHY_vars_eNB_g[0][CC_id],
			  UE_id);
	    ue_cnt++;
	  }
544
	}
knopp's avatar
   
knopp committed
545
      }
546

547
    }
548

knopp's avatar
   
knopp committed
549
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
550
551
    //usleep(100000); // 100 ms
    sleep(1);
knopp's avatar
   
knopp committed
552
  }
553

554
  //  printf("%s",stats_buffer);
555

556
# ifdef ENABLE_XFORMS_WRITE_STATS
557

558
559
560
561
562
563
  if (UE_flag==1) {
    if (UE_stats) {
      rewind (UE_stats);
      fwrite (stats_buffer, 1, len, UE_stats);
      fclose (UE_stats);
    }
564
  } else {
565
566
567
568
569
570
    if (eNB_stats) {
      rewind (eNB_stats);
      fwrite (stats_buffer, 1, len, eNB_stats);
      fclose (eNB_stats);
    }
  }
571

572
# endif
573

knopp's avatar
   
knopp committed
574
  pthread_exit((void*)arg);
575
576
577
}
#endif

578

579

580

knopp's avatar
   
knopp committed
581
#if defined(ENABLE_ITTI)
582
void *l2l1_task(void *arg)
583
{
knopp's avatar
   
knopp committed
584
585
586
587
588
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
589

knopp's avatar
   
knopp committed
590
591
  if (UE_flag == 0) {
    /* Wait for the initialize message */
592
    printf("Wait for the ITTI initialize message\n");
593
594
595
596
597
    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
598

599
      itti_receive_msg (TASK_L2L1, &message_p);
600

601
602
603
604
605
606
      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;
607

608
609
610
611
612
      case TERMINATE_MESSAGE:
        printf("received terminate message\n");
        oai_exit=1;
        itti_exit_task ();
        break;
613

614
615
616
617
618
      default:
        LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
        break;
      }
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
619

620
621
622
    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  }
623

624
625
626
  do {
    // Wait for a message
    itti_receive_msg (TASK_L2L1, &message_p);
627

628
629
630
631
632
    switch (ITTI_MSG_ID(message_p)) {
    case TERMINATE_MESSAGE:
      oai_exit=1;
      itti_exit_task ();
      break;
knopp's avatar
   
knopp committed
633

634
635
636
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
637

638
639
640
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
641

642
643
644
    case MESSAGE_TEST:
      LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
      break;
645

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

651
652
653
    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);
654

655
656
  return NULL;
}
knopp's avatar
   
knopp committed
657
#endif
658

659

660

661

662
663
static void get_options (int argc, char **argv)
{
664
665
666
  int c;
  //  char                          line[1000];
  //  int                           l;
667
  int k,i;//,j,k;
668
#if defined(OAI_USRP) || defined(CPRIGW)
669
  int clock_src;
knopp's avatar
knopp committed
670
#endif
671
  int CC_id;
672
673


674
675

  const Enb_properties_array_t *enb_properties;
676

677
678
  enum long_option_e {
    LONG_OPTION_START = 0x100, /* Start after regular single char options */
679
    LONG_OPTION_RF_CONFIG_FILE,
680
681
682
683
684
    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,
685
    LONG_OPTION_NO_L2_CONNECT,
knopp's avatar
   
knopp committed
686
    LONG_OPTION_CALIB_PRACH_TX,
687
688
    LONG_OPTION_RXGAIN,
    LONG_OPTION_TXGAIN,
689
    LONG_OPTION_SCANCARRIER,
690
691
    LONG_OPTION_MAXPOWER,
    LONG_OPTION_DUMP_FRAME,
692
    LONG_OPTION_LOOPMEMORY,
693
    LONG_OPTION_PHYTEST,
Cedric Roux's avatar
Cedric Roux committed
694
    LONG_OPTION_MMAPPED_DMA,
knopp's avatar
knopp committed
695
    LONG_OPTION_SINGLE_THREAD,
696
697
698
#if T_TRACER
    LONG_OPTION_T_PORT,
    LONG_OPTION_T_NOWAIT,
Cedric Roux's avatar
Cedric Roux committed
699
    LONG_OPTION_T_DONT_FORK,
700
#endif
701
  };
702

703
  static const struct option long_options[] = {
704
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
705
706
707
708
709
710
    {"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
711
712
713
714
    {"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},
715
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
716
717
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
718
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
719
    {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
knopp's avatar
knopp committed
720
    {"single-thread", no_argument, NULL, LONG_OPTION_SINGLE_THREAD},
721
722
723
#if T_TRACER
    {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
    {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
Cedric Roux's avatar
Cedric Roux committed
724
    {"T_dont_fork",            no_argument,       0, LONG_OPTION_T_DONT_FORK},
725
#endif
726
727
728
    {NULL, 0, NULL, 0}
  };

729
  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) {
730
    switch (c) {
731
    case LONG_OPTION_RF_CONFIG_FILE:
732
733
734
735
736
737
      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 {
738
739
	printf("Configuration filename is too long\n");
	exit(-1);   
740
741
      }
      break;
742
743
744
745
    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];
746
      break;
747
748
749
750
    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;
751

752
753
754
755
756
    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;
757

758
759
760
761
    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
762
      break;
763

764
765
766
767
768
    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;
769

770
771
772
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
773

774
775
776
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
777

knopp's avatar
   
knopp committed
778
779
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
Rohit Gupta's avatar
Rohit Gupta committed
780
      printf("Setting mode to calib_prach_tx (%d)\n",mode);
knopp's avatar
   
knopp committed
781
782
      break;

783
    case LONG_OPTION_RXGAIN:
784
785
      for (i=0; i<4; i++)
        rx_gain[0][i] = atof(optarg);
786

787
      break;
788

789
790
791
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
792

793
      break;
794

795
796
797
798
799
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

800
801
802
803
804
805
    case LONG_OPTION_LOOPMEMORY:
      mode=loop_through_memory;
      input_fd = fopen(optarg,"r");
      AssertFatal(input_fd != NULL,"Please provide an input file\n");
      break;

806
807
808
809
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
810
811
812
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
813

814
815
816
    case LONG_OPTION_MMAPPED_DMA:
      mmapped_dma = 1;
      break;
knopp's avatar
knopp committed
817
818
819
820

    case LONG_OPTION_SINGLE_THREAD:
      single_thread_flag = 1;
      break;
821
              
822
823
824
825
826
827
828
829
830
831
832
833
834
#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;
    }
835
836
837
838
839
840

    case LONG_OPTION_T_DONT_FORK: {
      extern int T_dont_fork;
      T_dont_fork = 1;
      break;
    }
841
842
#endif

843
844
845
846
    case 'A':
      timing_advance = atoi (optarg);
      break;

847
    case 'C':
848
849
850
851
852
853
      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
854
      }
855

856
      UE_scan=0;
857

858
      break;
859

Florian Kaltenberger's avatar
Florian Kaltenberger committed
860
861
862
863
    case 'a':
      chain_offset = atoi(optarg);
      break;

864
865
866
867
    case 'd':
#ifdef XFORMS
      do_forms=1;
      printf("Running with XFORMS!\n");
knopp's avatar
   
knopp committed
868
#endif
869
      break;
870
871
872
873
      
    case 'E':
      threequarter_fs=1;
      break;
874

875
876
877
    case 'K':
#if defined(ENABLE_ITTI)
      itti_dump_file = strdup(optarg);
878
#else
879
      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
knopp's avatar
   
knopp committed
880
#endif
881
      break;