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

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


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

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

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

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

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

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

55 56
#include "T.h"

57
#include "rt_wrapper.h"
58

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

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

#include "PHY/types.h"
65

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

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

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

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

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

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

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

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

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

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

120
// In lte-enb.c
121
extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
122
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 173
//static uint8_t                  eNB_id=0,UE_id=0;

174
static char                     threequarter_fs=0;
175

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

179
openair0_rf_map rf_map[MAX_NUM_CCs];
180

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

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

190 191
FILE *input_fd=NULL;

192

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

203 204


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

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

210 211
char   rf_config_file[1024];

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

215

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

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

229

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

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

knopp's avatar
 
knopp committed
239

240 241 242

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

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

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

knopp's avatar
 
knopp committed
273 274 275

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

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

284 285
openair0_config_t openair0_cfg[MAX_CARDS];

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

289 290
double cpuf;

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


knopp's avatar
 
knopp committed
294

295 296 297 298 299 300 301
/*---------------------BMC: timespec helpers -----------------------------*/

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

struct timespec clock_difftime(struct timespec start, struct timespec end)
{
302 303 304 305 306 307 308 309 310
  struct timespec temp;
  if ((end.tv_nsec-start.tv_nsec)<0) {
    temp.tv_sec = end.tv_sec-start.tv_sec-1;
    temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
  } else {
    temp.tv_sec = end.tv_sec-start.tv_sec;
    temp.tv_nsec = end.tv_nsec-start.tv_nsec;
  }
  return temp;
311 312
}

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

void update_difftimes(struct timespec start, struct timespec end)
{
324 325 326 327 328
  struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
  int             changed = 0;
  diff_time = clock_difftime(start, end);
  if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { min_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
  if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { max_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
329
#if 1
330
  if (changed) print_difftimes();
331 332 333 334 335
#endif
}

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

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

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

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

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

void help (void) {
  printf (KGRN "Usage:\n");
  printf("  sudo -E lte-softmodem [options]\n");
  printf("  sudo -E ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.openEPC.conf -S -V -m 26 -t 16 -x 1 --ulsch-max-errors 100 -W\n\n");
  printf("Options:\n");
376
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
nikaeinn's avatar
nikaeinn committed
377 378 379 380
  printf("  --ulsch-max-errors set the max ULSCH erros\n");
  printf("  --calib-ue-rx set UE RX calibration\n");
  printf("  --calib-ue-rx-med \n");
  printf("  --calib-ue-rxbyp\n");
knopp's avatar
 
knopp committed
381 382
  printf("  --debug-ue-prach run normal prach power ramping, but don't continue random-access\n");
  printf("  --calib-prach-tx run normal prach with maximum power, but don't continue random-access\n");
nikaeinn's avatar
nikaeinn committed
383
  printf("  --no-L2-connect bypass L2 and upper layers\n");
384 385 386 387
  printf("  --ue-rxgain set UE RX gain\n");
  printf("  --ue-txgain set UE TX gain\n");
  printf("  --ue-scan_carrier set UE to scan around carrier\n");
  printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
388 389
  printf("  --RCC run using NGFI RCC node function IF4 split\n");
  printf("  --RRU run using NGFI RRU node function  IF4 split\n");
390
  printf("  --eNB run using 3GPP eNB node function\n");   
391 392
  printf("  --BBU run using 3GPP eNB node function with IF5 split\n");   
  printf("  --RRH run using RRH node function with IF5 split\n");   
393
  printf("  -C Set the downlink frequency for all component carriers\n");
nikaeinn's avatar
nikaeinn committed
394 395 396
  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");
397
  printf("  -G Set the global log verbosity \n");
nikaeinn's avatar
nikaeinn committed
398 399 400 401 402
  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
403
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
nikaeinn's avatar
nikaeinn committed
404 405
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
406
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
nikaeinn's avatar
nikaeinn committed
407 408 409
  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");
410 411 412 413 414 415 416
  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
417
}
418

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

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

  oai_exit = 1;
Raymond Knopp's avatar
Raymond Knopp committed
428 429 430 431 432 433 434
  
  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);  
  }
435 436

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

}

443

444
#ifdef XFORMS
445

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

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

459 460 461
      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;
462

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

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

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

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

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

493
# ifdef ENABLE_XFORMS_WRITE_STATS
494 495

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

500
#endif
501

knopp's avatar
 
knopp committed
502 503
  while (!oai_exit) {
    if (UE_flag==1) {
504
      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
505 506 507
      //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);
508

509 510 511 512 513
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

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

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

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

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

542
    }
543

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

549
  //  printf("%s",stats_buffer);
550

551
# ifdef ENABLE_XFORMS_WRITE_STATS
552

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

567
# endif
568

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

573

574

575

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
584

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

594
      itti_receive_msg (TASK_L2L1, &message_p);
595

596 597 598 599 600 601
      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;
602

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

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

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

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

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

629 630 631
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
632

633 634 635
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
636

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

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

646 647 648
    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);
649

650 651
  return NULL;
}
knopp's avatar
 
knopp committed
652
#endif
653

654

655

656

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


669 670

  const Enb_properties_array_t *enb_properties;
671

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

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

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

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

758 759 760 761
    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
762
      break;
763

764 765 766 767 768
    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;
769

770 771 772
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
773

774 775 776
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
777

knopp's avatar
 
knopp committed
778 779 780 781
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
      break;

782
    case LONG_OPTION_RXGAIN:
783 784
      for (i=0; i<4; i++)
        rx_gain[0][i] = atof(optarg);
785

786
      break;
787

788 789 790
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
791

792
      break;
793