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

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


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

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

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

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

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

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

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

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

#include "PHY/types.h"
62

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

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

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

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

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

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/vars.h"
79
#include "LAYER2/MAC/proto.h"
80 81 82 83 84 85 86 87
#include "RRC/LITE/vars.h"
#include "PHY_INTERFACE/vars.h"

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

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

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

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

116
// In lte-enb.c
117
extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
118 119
extern void init_eNB(void);
extern void stop_eNB(void);
120
extern void kill_eNB_proc(void);
121

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

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

137

138

139 140


knopp's avatar
 
knopp committed
141

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

146

147 148


149

150

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

knopp's avatar
 
knopp committed
155
openair0_device openair0;
156

157 158
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
159

160

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

167

168

knopp's avatar
 
knopp committed
169

170
static char                     UE_flag=0;
171 172
//static uint8_t                  eNB_id=0,UE_id=0;

173
static char                     threequarter_fs=0;
174

175
uint32_t                 downlink_frequency[MAX_NUM_CCs][4];
176
int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
gauthier's avatar
gauthier committed
177

178
openair0_rf_map rf_map[MAX_NUM_CCs];
179

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

185
int UE_scan = 1;
186
int UE_scan_carrier = 0;
187 188
runmode_t mode = normal_txrx;

189 190
FILE *input_fd=NULL;

191

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

202 203


knopp's avatar
 
knopp committed
204
double sample_rate=30.72e6;
205
double bw = 10.0e6;
206

207
static int                      tx_max_power[MAX_NUM_CCs]; /* =  {0,0}*/;
208

209 210
char   rf_config_file[1024];

Florian Kaltenberger's avatar
Florian Kaltenberger committed
211
int chain_offset=0;
212
int phy_test = 0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
213

214

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

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

228

knopp's avatar
 
knopp committed
229
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
230

231

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

knopp's avatar
 
knopp committed
238

239 240 241

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

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

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

knopp's avatar
 
knopp committed
272 273 274

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

278 279 280 281 282
/* 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;

283 284 285 286
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

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


knopp's avatar
 
knopp committed
290

291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
/*---------------------BMC: timespec helpers -----------------------------*/

struct timespec min_diff_time = { .tv_sec = 0, .tv_nsec = 0 };
struct timespec max_diff_time = { .tv_sec = 0, .tv_nsec = 0 };

struct timespec clock_difftime(struct timespec start, struct timespec end)
{
    struct timespec temp;
    if ((end.tv_nsec-start.tv_nsec)<0) {
        temp.tv_sec = end.tv_sec-start.tv_sec-1;
	temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
    } else {
        temp.tv_sec = end.tv_sec-start.tv_sec;
	temp.tv_nsec = end.tv_nsec-start.tv_nsec;
    }
    return temp;
}

Cedric Roux's avatar
Cedric Roux committed
309
void print_difftimes(void)
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
{
#ifdef DEBUG
    printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
#else
    LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
#endif
}

void update_difftimes(struct timespec start, struct timespec end)
{
    struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
    int             changed = 0;
    diff_time = clock_difftime(start, end);
    if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { min_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
    if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { max_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
#if 1
    if (changed) print_difftimes();
#endif
}

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

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

341
#if !defined(ENABLE_ITTI)
342 343 344 345 346 347 348 349
void signal_handler(int sig)
{
  void *array[10];
  size_t size;

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

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

void help (void) {
  printf (KGRN "Usage:\n");
  printf("  sudo -E lte-softmodem [options]\n");
  printf("  sudo -E ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.openEPC.conf -S -V -m 26 -t 16 -x 1 --ulsch-max-errors 100 -W\n\n");
  printf("Options:\n");
372
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
nikaeinn's avatar
nikaeinn committed
373 374 375 376
  printf("  --ulsch-max-errors set the max ULSCH erros\n");
  printf("  --calib-ue-rx set UE RX calibration\n");
  printf("  --calib-ue-rx-med \n");
  printf("  --calib-ue-rxbyp\n");
knopp's avatar
 
knopp committed
377 378
  printf("  --debug-ue-prach run normal prach power ramping, but don't continue random-access\n");
  printf("  --calib-prach-tx run normal prach with maximum power, but don't continue random-access\n");
nikaeinn's avatar
nikaeinn committed
379
  printf("  --no-L2-connect bypass L2 and upper layers\n");
380 381 382 383
  printf("  --ue-rxgain set UE RX gain\n");
  printf("  --ue-txgain set UE TX gain\n");
  printf("  --ue-scan_carrier set UE to scan around carrier\n");
  printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
384
  printf("  -C Set the downlink frequency for all component carriers\n");
nikaeinn's avatar
nikaeinn committed
385 386 387
  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");
388
  printf("  -G Set the global log verbosity \n");
nikaeinn's avatar
nikaeinn committed
389 390 391 392 393
  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
394
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
nikaeinn's avatar
nikaeinn committed
395 396
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
397
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
nikaeinn's avatar
nikaeinn committed
398 399 400 401
  printf("  -U Set the lte softmodem as a UE\n");
  printf("  -W Enable L2 wireshark messages on localhost \n");
  printf("  -V Enable VCD (generated file will be located atopenair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n");
  printf("  -x Set the transmission mode, valid options: 1 \n"RESET);    
402

nikaeinn's avatar
nikaeinn committed
403
}
404

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

  oai_exit = 1;

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

}

420

421
#ifdef XFORMS
422

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

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    for (k=0; k<8; k++) { //harq_processes
430
      for (j=0; j<phy_vars_eNB->dlsch_eNB[i][0]->Mlimit; j++) {
431 432 433
        phy_vars_eNB->eNB_UE_stats[i].dlsch_NAK[k][j]=0;
        phy_vars_eNB->eNB_UE_stats[i].dlsch_ACK[k][j]=0;
        phy_vars_eNB->eNB_UE_stats[i].dlsch_trials[k][j]=0;
434
      }
435

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

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

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

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

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

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

470
# ifdef ENABLE_XFORMS_WRITE_STATS
471 472

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

477
#endif
478

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

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

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

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

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

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

519
    }
520

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

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

528
# ifdef ENABLE_XFORMS_WRITE_STATS
529

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

544
# endif
545

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

550

551

552

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
561

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

571
      itti_receive_msg (TASK_L2L1, &message_p);
572

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

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

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

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

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

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

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

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

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

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

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

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

631

632

633 634


635

636

knopp's avatar
 
knopp committed
637

Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
638

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


651 652

  const Enb_properties_array_t *enb_properties;
653

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

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

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

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

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

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

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

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

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

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

749
      break;
750

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

755
      break;
756

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

      break;

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

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

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

789
      UE_scan=0;
790

791
      break;
792

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

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

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

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

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

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

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

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