lte-softmodem.c 61.7 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
#include "../../ARCH/COMMON/common_lib.h"
68
#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
knopp's avatar
 
knopp committed
69

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

#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"
80
#include "LAYER2/MAC/proto.h"
81 82 83 84 85 86 87 88
#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
89
#include "UTIL/OTG/otg_tx.h"
90
#include "UTIL/OTG/otg_externs.h"
91 92
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
93
#include "UTIL/OPT/opt.h"
94
#include "enb_config.h"
nikaeinn's avatar
nikaeinn committed
95
//#include "PHY/TOOLS/time_meas.h"
96

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

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

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

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

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

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

138

139

140 141


knopp's avatar
 
knopp committed
142

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

147

148 149


150

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

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

158

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

165

166

knopp's avatar
 
knopp committed
167

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

171
static char                     threequarter_fs=0;
172

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

176
openair0_rf_map rf_map[MAX_NUM_CCs];
177

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

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

187 188
FILE *input_fd=NULL;

189

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

200 201


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

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

207 208
char   rf_config_file[1024];

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

212

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

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

226

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

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

knopp's avatar
 
knopp committed
236

237 238 239

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

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

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

knopp's avatar
 
knopp committed
270 271 272

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

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

281 282
openair0_config_t openair0_cfg[MAX_CARDS];

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

286 287
double cpuf;

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


knopp's avatar
 
knopp committed
291

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

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

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

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

352 353 354 355
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
356 357
  } else {
    printf("trying to exit gracefully...\n");
358
    oai_exit = 1;
359 360
  }
}
361
#endif
nikaeinn's avatar
nikaeinn committed
362 363 364 365 366 367 368 369 370 371 372
#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");
373
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
nikaeinn's avatar
nikaeinn committed
374 375 376 377
  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
378 379
  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
380
  printf("  --no-L2-connect bypass L2 and upper layers\n");
381 382 383 384
  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");
385 386 387
  printf("  --RCC run using NGFI RCC node function\n");
  printf("  --RRU run using NGFI RRU node function\n");
  printf("  --eNB run using 3GPP eNB node function\n");   
388
  printf("  -C Set the downlink frequency for all component carriers\n");
nikaeinn's avatar
nikaeinn committed
389 390 391
  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");
392
  printf("  -G Set the global log verbosity \n");
nikaeinn's avatar
nikaeinn committed
393 394 395 396 397
  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
398
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
nikaeinn's avatar
nikaeinn committed
399 400
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
401
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
nikaeinn's avatar
nikaeinn committed
402 403 404 405
  printf("  -U Set the lte softmodem as a UE\n");
  printf("  -W Enable L2 wireshark messages on localhost \n");
  printf("  -V Enable VCD (generated file will be located atopenair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n");
  printf("  -x Set the transmission mode, valid options: 1 \n"RESET);    
406

nikaeinn's avatar
nikaeinn committed
407
}
408

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

  oai_exit = 1;

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

}

424

425
#ifdef XFORMS
426

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

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

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

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

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

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

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

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

474
# ifdef ENABLE_XFORMS_WRITE_STATS
475 476

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

481
#endif
482

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

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

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

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

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

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

523
    }
524

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

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

532
# ifdef ENABLE_XFORMS_WRITE_STATS
533

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

548
# endif
549

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

554

555

556

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
565

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

575
      itti_receive_msg (TASK_L2L1, &message_p);
576

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

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

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

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

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

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

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

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

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

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

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

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

635

636

637

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


650 651

  const Enb_properties_array_t *enb_properties;
652

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

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

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

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

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

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

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

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

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

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

754
      break;
755

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

760
      break;
761

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

      break;

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

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

    case LONG_OPTION_RCC:
      node_function = NGFI_RCC_IF4;
      break;

    case LONG_OPTION_RRU:
      node_function = NGFI_RRU_IF4;
      break;

    case LONG_OPTION_ENB:
      node_function = eNodeB_3GPP;
      break;
792
      
793 794 795 796
    case 'A':
      timing_advance = atoi (optarg);
      break;

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

806
      UE_scan=0;
807

808
      break;
809

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

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