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

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


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

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

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

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

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

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

55 56
#include "T.h"

57
#include "rt_wrapper.h"
58

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

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

#include "PHY/types.h"
65

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

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

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

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

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

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

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

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

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

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

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

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

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

141

142

143 144


knopp's avatar
 
knopp committed
145

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

150

151 152


153

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

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

161

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

168

169

knopp's avatar
 
knopp committed
170

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

175
static char                     threequarter_fs=0;
176

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

180
openair0_rf_map rf_map[MAX_NUM_CCs];
181

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

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

191 192
FILE *input_fd=NULL;

193

194 195
#if MAX_NUM_CCs == 1
rx_gain_t                rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}};
kortke's avatar
kortke committed
196 197
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}};
198 199 200 201
#else
rx_gain_t                rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain},{max_gain,max_gain,max_gain,max_gain}};
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}};
gauthier's avatar
gauthier committed
202
#endif
knopp's avatar
 
knopp committed
203

204 205


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

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

211 212
char   rf_config_file[1024];

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

216

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

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

230

knopp's avatar
 
knopp committed
231
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
232
eNB_func_t node_function=eNodeB_3GPP;
233

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

knopp's avatar
 
knopp committed
240

241 242 243

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

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

gauthier's avatar
 
gauthier committed
263 264 265 266 267 268
# if defined(ENABLE_USE_MME)
int16_t           gtpu_log_level     = LOG_DEBUG;
int16_t           gtpu_log_verbosity = LOG_MED;
int16_t           udp_log_level      = LOG_DEBUG;
int16_t           udp_log_verbosity  = LOG_MED;
#endif
269 270 271
#if defined (ENABLE_SECURITY)
int16_t           osa_log_level      = LOG_INFO;
int16_t           osa_log_verbosity  = LOG_MED;
272
#endif
273

knopp's avatar
 
knopp committed
274 275 276

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

280 281 282 283 284
/* flag set by eNB conf file to specify if the radio head is local or remote (default option is local) */
uint8_t local_remote_radio = BBU_LOCAL_RADIO_HEAD;
/* struct for ethernet specific parameters given in eNB conf file */
eth_params_t *eth_params;

285 286
openair0_config_t openair0_cfg[MAX_CARDS];

287 288 289
// Change to openair_global to handle UE
openair0_device openair0;

290 291
double cpuf;

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


knopp's avatar
 
knopp committed
295

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

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

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

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

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

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

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

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

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

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

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

}

445

446
#ifdef XFORMS
447

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

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

461 462 463
      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;
464

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

473 474 475
    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;
476 477 478
  }
}

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

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

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

495
# ifdef ENABLE_XFORMS_WRITE_STATS
496 497

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

502
#endif
503

knopp's avatar
 
knopp committed
504 505
  while (!oai_exit) {
    if (UE_flag==1) {
506
      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
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 513 514 515
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

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

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

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

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

544
    }
545

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

551
  //  printf("%s",stats_buffer);
552

553
# ifdef ENABLE_XFORMS_WRITE_STATS
554

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

569
# endif
570

knopp's avatar
 
knopp committed
571
  pthread_exit((void*)arg);
572 573 574
}
#endif

575

576

577

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
586

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

596
      itti_receive_msg (TASK_L2L1, &message_p);
597

598 599 600 601 602 603
      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;
604

605 606 607 608 609
      case TERMINATE_MESSAGE:
        printf("received terminate message\n");
        oai_exit=1;
        itti_exit_task ();
        break;
610

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

617 618 619
    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  }
620

621 622 623
  do {
    // Wait for a message
    itti_receive_msg (TASK_L2L1, &message_p);
624

625 626 627 628 629
    switch (ITTI_MSG_ID(message_p)) {
    case TERMINATE_MESSAGE:
      oai_exit=1;
      itti_exit_task ();
      break;
knopp's avatar
 
knopp committed
630

631 632 633
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
634

635 636 637
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
638

639 640 641
    case MESSAGE_TEST:
      LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
      break;
642

643 644 645
    default:
      LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
      break;
646
    }
647

648 649 650
    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);
651

652 653
  return NULL;
}
knopp's avatar
 
knopp committed
654
#endif
655

656

657

658

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


671 672

  const Enb_properties_array_t *enb_properties;
673

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

704
  static const struct option long_options[] = {
705
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
706 707 708 709 710 711
    {"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
712 713 714 715
    {"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},
716
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
717 718
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
719
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
720
    {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
721 722 723
    {"RCC", no_argument, NULL, LONG_OPTION_RCC},
    {"RRU", no_argument, NULL, LONG_OPTION_RRU},
    {"eNB", no_argument, NULL, LONG_OPTION_ENB},
724
    {"BBU", no_argument, NULL, LONG_OPTION_ENB_BBU},
725
    {"RRH", no_argument, NULL, LONG_OPTION_RRH},
726 727 728 729
#if T_TRACER
    {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
    {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
#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 784 785
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
      break;

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

790
      break;