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

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


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

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

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

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

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

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

55
56
#include "T.h"

57
#include "rt_wrapper.h"
58

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

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

#include "PHY/types.h"
65

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

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

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

#include "PHY/vars.h"
#include "SCHED/vars.h"
#include "LAYER2/MAC/vars.h"

#include "../../SIMU/USER/init_lte.h"

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/vars.h"
83
#include "LAYER2/MAC/proto.h"
84
85
86
87
88
89
90
91
#include "RRC/LITE/vars.h"
#include "PHY_INTERFACE/vars.h"

#ifdef SMBV
#include "PHY/TOOLS/smbv.h"
unsigned short config_frames[4] = {2,9,11,13};
#endif
#include "UTIL/LOG/log_extern.h"
nikaeinn's avatar
nikaeinn committed
92
#include "UTIL/OTG/otg_tx.h"
93
#include "UTIL/OTG/otg_externs.h"
94
95
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
96
#include "UTIL/OPT/opt.h"
97
#include "enb_config.h"
nikaeinn's avatar
nikaeinn committed
98
//#include "PHY/TOOLS/time_meas.h"
99

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

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

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

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

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

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

141

142

143
144


knopp's avatar
   
knopp committed
145

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

150

151
152


153

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

158
159
uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
knopp's avatar
   
knopp committed
160

161

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

168

169

knopp's avatar
   
knopp committed
170

171
static char                     UE_flag=0;
172
unsigned int                    mmapped_dma=0;
173
174
//static uint8_t                  eNB_id=0,UE_id=0;

175
static char                     threequarter_fs=0;
176

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

180
openair0_rf_map rf_map[MAX_NUM_CCs];
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

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

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

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

knopp's avatar
   
knopp committed
274
275
276

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

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

285
286
287
288
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

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


knopp's avatar
   
knopp committed
292

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

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

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

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

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

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

353
354
355
356
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
357
358
  } else {
    printf("trying to exit gracefully...\n");
359
    oai_exit = 1;
360
361
  }
}
362
#endif
nikaeinn's avatar
nikaeinn committed
363
364
365
366
367
368
369
370
371
372
373
#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");
374
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
nikaeinn's avatar
nikaeinn committed
375
376
377
378
  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
379
380
  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
381
  printf("  --no-L2-connect bypass L2 and upper layers\n");
382
383
384
385
  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");
386
  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\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
  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");
404
405
406
407
  printf("  -x Set the transmission mode, valid options: 1 \n");
#if T_TRACER
  printf("  --T_port [port]    use given port\n");
  printf("  --T_nowait         don't wait for tracer, start immediately\n");
408
  printf("  --T_dont_fork      to ease debugging with gdb\n");
409
410
411
#endif
  printf(RESET);
  fflush(stdout);
nikaeinn's avatar
nikaeinn committed
412
}
413

414
415
void exit_fun(const char* s)
{
Raymond Knopp's avatar
Raymond Knopp committed
416
417
  int CC_id;

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

  oai_exit = 1;
Raymond Knopp's avatar
Raymond Knopp committed
423
424
425
426
427
428
429
  
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    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);  
  }
430
431

#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
432
  sleep(1); //allow lte-softmodem threads to exit first
433
  itti_terminate_tasks (TASK_UNKNOWN);
434
#endif
435
436
437

}

438

439
#ifdef XFORMS
440

441
442
void reset_stats(FL_OBJECT *button, long arg)
{
443
444
  int i,j,k;
  PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
445
446
447

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    for (k=0; k<8; k++) { //harq_processes
448
449
450
451
      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;
452
      }
453

454
455
456
      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;
457

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

466
467
468
    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;
469
470
471
  }
}

472
473
static void *scope_thread(void *arg)
{
knopp's avatar
   
knopp committed
474
  char stats_buffer[16384];
475
# ifdef ENABLE_XFORMS_WRITE_STATS
knopp's avatar
   
knopp committed
476
  FILE *UE_stats, *eNB_stats;
477
# endif
Florian Kaltenberger's avatar
   
Florian Kaltenberger committed
478
  int len = 0;
knopp's avatar
   
knopp committed
479
  struct sched_param sched_param;
480
  int UE_id, CC_id;
481
  int ue_cnt=0;
482

483
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
knopp's avatar
   
knopp committed
484
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
485

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

488
# ifdef ENABLE_XFORMS_WRITE_STATS
489
490

  if (UE_flag==1)
knopp's avatar
   
knopp committed
491
    UE_stats  = fopen("UE_stats.txt", "w");
492
  else
knopp's avatar
   
knopp committed
493
    eNB_stats = fopen("eNB_stats.txt", "w");
494

495
#endif
496

knopp's avatar
   
knopp committed
497
498
  while (!oai_exit) {
    if (UE_flag==1) {
499
      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
500
501
502
      //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);
503

504
505
506
507
508
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

knopp's avatar
   
knopp committed
509
    } else {
510
511
512
513
514
515
      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
516
      len = dump_eNB_stats (PHY_vars_eNB_g[0][0], stats_buffer, 0);
517

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

kaltenbe's avatar
kaltenbe committed
521
522
523
      //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);
524

525
526
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
527
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
528
	  if ((PHY_vars_eNB_g[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) {
529
	  //if ((ue_cnt<scope_enb_num_ue)) {
gauthier's avatar
gauthier committed
530
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
531
532
533
534
			  PHY_vars_eNB_g[0][CC_id],
			  UE_id);
	    ue_cnt++;
	  }
535
	}
knopp's avatar
   
knopp committed
536
      }
537

538
    }
539

knopp's avatar
   
knopp committed
540
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
541
542
    //usleep(100000); // 100 ms
    sleep(1);
knopp's avatar
   
knopp committed
543
  }
544

545
  //  printf("%s",stats_buffer);
546

547
# ifdef ENABLE_XFORMS_WRITE_STATS
548

549
550
551
552
553
554
  if (UE_flag==1) {
    if (UE_stats) {
      rewind (UE_stats);
      fwrite (stats_buffer, 1, len, UE_stats);
      fclose (UE_stats);
    }
555
  } else {
556
557
558
559
560
561
    if (eNB_stats) {
      rewind (eNB_stats);
      fwrite (stats_buffer, 1, len, eNB_stats);
      fclose (eNB_stats);
    }
  }
562

563
# endif
564

knopp's avatar
   
knopp committed
565
  pthread_exit((void*)arg);
566
567
568
}
#endif

569

570

571

knopp's avatar
   
knopp committed
572
#if defined(ENABLE_ITTI)
573
void *l2l1_task(void *arg)
574
{
knopp's avatar
   
knopp committed
575
576
577
578
579
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
580

knopp's avatar
   
knopp committed
581
582
  if (UE_flag == 0) {
    /* Wait for the initialize message */
583
    printf("Wait for the ITTI initialize message\n");
584
585
586
587
588
    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
589

590
      itti_receive_msg (TASK_L2L1, &message_p);
591

592
593
594
595
596
597
      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;
598

599
600
601
602
603
      case TERMINATE_MESSAGE:
        printf("received terminate message\n");
        oai_exit=1;
        itti_exit_task ();
        break;
604

605
606
607
608
609
      default:
        LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
        break;
      }
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
610

611
612
613
    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  }
614

615
616
617
  do {
    // Wait for a message
    itti_receive_msg (TASK_L2L1, &message_p);
618

619
620
621
622
623
    switch (ITTI_MSG_ID(message_p)) {
    case TERMINATE_MESSAGE:
      oai_exit=1;
      itti_exit_task ();
      break;
knopp's avatar
   
knopp committed
624

625
626
627
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
628

629
630
631
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
632

633
634
635
    case MESSAGE_TEST:
      LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
      break;
636

637
638
639
    default:
      LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
      break;
640
    }
641

642
643
644
    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);
645

646
647
  return NULL;
}
knopp's avatar
   
knopp committed
648
#endif
649

650

651

652

653
654
static void get_options (int argc, char **argv)
{
655
656
657
  int c;
  //  char                          line[1000];
  //  int                           l;
658
  int k,i;//,j,k;
659
#if defined(OAI_USRP) || defined(CPRIGW)
660
  int clock_src;
knopp's avatar
knopp committed
661
#endif
662
  int CC_id;
663
664


665
666

  const Enb_properties_array_t *enb_properties;
667

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

693
  static const struct option long_options[] = {
694
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
695
696
697
698
699
700
    {"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
701
702
703
704
    {"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},
705
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
706
707
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
708
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
709
    {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
710
711
712
713
#if T_TRACER
    {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
    {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
#endif
714
715
716
    {NULL, 0, NULL, 0}
  };

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

740
741
742
743
744
    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;
745

knopp's avatar
   
knopp committed
746

747
748
749
750
    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
751
      break;
752

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

759
760
761
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
762

763
764
765
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
766

knopp's avatar
   
knopp committed
767
768
769
770
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
      break;

771
    case LONG_OPTION_RXGAIN:
772
773
      for (i=0; i<4; i++)
        rx_gain[0][i] = atof(optarg);
774

775
      break;
776

777
778
779
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
780

781
      break;
782

783
784
785
786
787
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

788
789
790
791
792
793
    case LONG_OPTION_LOOPMEMORY:
      mode=loop_through_memory;
      input_fd = fopen(optarg,"r");
      AssertFatal(input_fd != NULL,"Please provide an input file\n");
      break;

794
795
796
797
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
798
799
800
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
801

802
803
804
805
    case LONG_OPTION_MMAPPED_DMA:
      mmapped_dma = 1;
      break;
              
806
807
808
809
810
811
812
813
814
815
816
817
818
#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;
    }
819
820
821
822
823
824

    case LONG_OPTION_T_DONT_FORK: {
      extern int T_dont_fork;
      T_dont_fork = 1;
      break;
    }
825
826
#endif

827
828
829
830
    case 'A':
      timing_advance = atoi (optarg);
      break;

831
    case 'C':
832
833
834
835
836
837
      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
838
      }
839

840
      UE_scan=0;
841

842
      break;
843

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

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

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

867
868
869
    case 'O':
      conf_config_file_name = optarg;
      break;
870

871
872
873
    case 'U':
      UE_flag = 1;
      break;
874

875
876
877
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
878

879
880
881
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
882

883
884
885
886
887
888
889
    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");
      /*
890
891
892
893
894
895
896
897
	if (optarg == NULL){
	in_ip[0] =NULL;
	printf("Enabling OPT for wireshark for local interface");
	} else {
	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);
	}
898
899
      */
      break;
900

901
    case 'P':