lte-softmodem.c 61.5 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

171
static clock_source_t clock_source = internal;
knopp's avatar
   
knopp committed
172

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

177
static char                     threequarter_fs=0;
178

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

182

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

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

192
193
FILE *input_fd=NULL;

194

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

205
206


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

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

212
213
char   rf_config_file[1024];

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

217

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

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

231

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

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

knopp's avatar
   
knopp committed
243

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

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

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

knopp's avatar
   
knopp committed
276

knopp's avatar
knopp committed
277

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

knopp's avatar
   
knopp committed
281

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

287
288
289
290
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

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


knopp's avatar
   
knopp committed
294

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

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

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

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

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

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

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

355
356
357
358
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
359
360
  } else {
    printf("trying to exit gracefully...\n");
361
    oai_exit = 1;
362
363
  }
}
364
#endif
nikaeinn's avatar
nikaeinn committed
365
366
367
368
369
370
371
372
373
374
375
#define KNRM  "\x1B[0m"
#define KRED  "\x1B[31m"
#define KGRN  "\x1B[32m"
#define KBLU  "\x1B[34m"
#define RESET "\033[0m"

void help (void) {
  printf (KGRN "Usage:\n");
  printf("  sudo -E lte-softmodem [options]\n");
  printf("  sudo -E ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.openEPC.conf -S -V -m 26 -t 16 -x 1 --ulsch-max-errors 100 -W\n\n");
  printf("Options:\n");
376
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
nikaeinn's avatar
nikaeinn committed
377
378
379
380
  printf("  --ulsch-max-errors set the max ULSCH erros\n");
  printf("  --calib-ue-rx set UE RX calibration\n");
  printf("  --calib-ue-rx-med \n");
  printf("  --calib-ue-rxbyp\n");
knopp's avatar
   
knopp committed
381
382
  printf("  --debug-ue-prach run normal prach power ramping, but don't continue random-access\n");
  printf("  --calib-prach-tx run normal prach with maximum power, but don't continue random-access\n");
nikaeinn's avatar
nikaeinn committed
383
  printf("  --no-L2-connect bypass L2 and upper layers\n");
384
385
386
387
  printf("  --ue-rxgain set UE RX gain\n");
  printf("  --ue-txgain set UE TX gain\n");
  printf("  --ue-scan_carrier set UE to scan around carrier\n");
  printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
388
389
  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");  
  printf("  --single-thread runs lte-softmodem in only one thread\n"); 
390
  printf("  --external-clock tells hardware to use an external clock reference\n");
391
  printf("  -C Set the downlink frequency for all component carriers\n");
nikaeinn's avatar
nikaeinn committed
392
393
394
  printf("  -d Enable soft scope and L1 and L2 stats (Xforms)\n");
  printf("  -F Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n");
  printf("  -g Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n");
395
  printf("  -G Set the global log verbosity \n");
nikaeinn's avatar
nikaeinn committed
396
397
398
399
400
  printf("  -h provides this help message!\n");
  printf("  -K Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n");
  printf("  -m Set the maximum downlink MCS\n");
  printf("  -O eNB configuration file (located in targets/PROJECTS/GENERIC-LTE-EPC/CONF\n");
  printf("  -q Enable processing timing measurement of lte softmodem on per subframe basis \n");
kaltenbe's avatar
kaltenbe committed
401
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
nikaeinn's avatar
nikaeinn committed
402
403
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
404
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
nikaeinn's avatar
nikaeinn committed
405
406
407
  printf("  -U Set the lte softmodem as a UE\n");
  printf("  -W Enable L2 wireshark messages on localhost \n");
  printf("  -V Enable VCD (generated file will be located atopenair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n");
408
  printf("  -x Set the transmission mode, valid options: 1 \n");
409
  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");
410
411
412
#if T_TRACER
  printf("  --T_port [port]    use given port\n");
  printf("  --T_nowait         don't wait for tracer, start immediately\n");
413
  printf("  --T_dont_fork      to ease debugging with gdb\n");
414
415
416
#endif
  printf(RESET);
  fflush(stdout);
nikaeinn's avatar
nikaeinn committed
417
}
418

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

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

  oai_exit = 1;
Raymond Knopp's avatar
Raymond Knopp committed
428
429
  
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
knopp committed
430
431
432
433
434
435
436
437
438
439
    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
440
  }
441
442

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

}

449

450
#ifdef XFORMS
451

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

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

465
466
467
      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;
468

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

477
478
479
    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;
480
481
482
  }
}

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

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

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

499
# ifdef ENABLE_XFORMS_WRITE_STATS
500
501

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

506
#endif
507

knopp's avatar
   
knopp committed
508
509
  while (!oai_exit) {
    if (UE_flag==1) {
510
      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
511
512
513
      //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);
514

515
516
517
518
519
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

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

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

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

536
537
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
538
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
539
540
	  //	  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
541
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
542
543
544
545
			  PHY_vars_eNB_g[0][CC_id],
			  UE_id);
	    ue_cnt++;
	  }
546
	}
knopp's avatar
   
knopp committed
547
      }
548

549
    }
550

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

556
  //  printf("%s",stats_buffer);
557

558
# ifdef ENABLE_XFORMS_WRITE_STATS
559

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

574
# endif
575

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

580

581

582

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
591

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

601
      itti_receive_msg (TASK_L2L1, &message_p);
602

603
604
605
606
607
608
      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;
609

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

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

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

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

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

636
637
638
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
639

640
641
642
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
643

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

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

653
654
655
    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);
656

657
658
  return NULL;
}
knopp's avatar
   
knopp committed
659
#endif
660

661

662
 
663

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


676
677

  const Enb_properties_array_t *enb_properties;
678

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

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

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

756
757
758
759
760
    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;
761

762
763
764
765
    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
766
      break;
767

768
769
770
771
772
    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;
773

774
775
776
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
777

778
779
780
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
781

knopp's avatar
   
knopp committed
782
783
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
Rohit Gupta's avatar
Rohit Gupta committed
784
      printf("Setting mode to calib_prach_tx (%d)\n",mode);
knopp's avatar
   
knopp committed
785
786
      break;

787
    case LONG_OPTION_RXGAIN:
788
789
      for (i=0; i<4; i++)
        rx_gain[0][i] = atof(optarg);
790

791
      break;
792

793
794
795
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
796

797
      break;
798

799
800
801
802
803
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

804
805
806
807
808
809
    case LONG_OPTION_LOOPMEMORY:
      mode=loop_through_memory;
      input_fd = fopen(optarg,"r");
      AssertFatal(input_fd != NULL,"Please provide an input file\n");
      break;

810
811
812
813
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
814
815
816
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
817

818
819
820
    case LONG_OPTION_MMAPPED_DMA:
      mmapped_dma = 1;
      break;
knopp's avatar
knopp committed
821
822
823
824

    case LONG_OPTION_SINGLE_THREAD:
      single_thread_flag = 1;
      break;
825
826
827
828
829

    case LONG_OPTION_EXTERNAL_CLOCK:
      clock_source = external;
      break;

830
831
832
833
834
835
836
837
838
839
840
841
842
#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;
    }
843
844
845
846
847
848

    case LONG_OPTION_T_DONT_FORK: {
      extern int T_dont_fork;
      T_dont_fork = 1;
      break;
    }
Cedric Roux's avatar