lte-softmodem.c 61.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
#   include "SIMULATION/ETH_TRANSPORT/proto.h"
Rohit Gupta's avatar
Rohit Gupta committed
111
extern int netlink_init(void);
112
#endif
113
# endif
114 115
#endif

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

121
// In lte-enb.c
knopp's avatar
knopp committed
122
extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg);
knopp's avatar
knopp committed
123
extern void init_eNB(eNB_func_t *, eNB_timing_t *,int,eth_params_t *,int);
124
extern void stop_eNB(int);
125
extern void kill_eNB_proc(void);
126

127
// In lte-ue.c
knopp's avatar
knopp committed
128
extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
129
extern void fill_ue_band_info(void);
knopp's avatar
knopp committed
130
extern void init_UE(int);
131

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

142

143

144 145


knopp's avatar
 
knopp committed
146

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

151

152 153


154

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

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

162

163
#if defined(ENABLE_ITTI)
164 165
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
166
#endif
knopp's avatar
knopp committed
167
volatile int             oai_exit = 0;
168

169

170

knopp's avatar
 
knopp committed
171

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

176
static char                     threequarter_fs=0;
177

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

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

fnabet's avatar
fnabet committed
204
double rx_gain_off = 0.0;
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 233 234
eNB_func_t node_function[MAX_NUM_CCs];
eNB_timing_t node_timing[MAX_NUM_CCs];
int16_t   node_synch_ref[MAX_NUM_CCs];
235

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

knopp's avatar
 
knopp committed
242

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

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

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

knopp's avatar
 
knopp committed
275

knopp's avatar
knopp committed
276

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

knopp's avatar
 
knopp committed
280

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

286 287 288 289
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

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


knopp's avatar
 
knopp committed
293

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

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

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

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

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

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

354 355 356 357
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
358 359
  } else {
    printf("trying to exit gracefully...\n");
360
    oai_exit = 1;
361 362
  }
}
363
#endif
nikaeinn's avatar
nikaeinn committed
364 365 366 367 368 369 370 371 372 373 374
#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");
375
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
nikaeinn's avatar
nikaeinn committed
376 377 378 379
  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
380 381
  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
382
  printf("  --no-L2-connect bypass L2 and upper layers\n");
383
  printf("  --ue-rxgain set UE RX gain\n");
fnabet's avatar
fnabet committed
384
  printf("  --ue-rxgain-off external UE amplifier offset\n");
385 386 387
  printf("  --ue-txgain set UE TX gain\n");
  printf("  --ue-scan_carrier set UE to scan around carrier\n");
  printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
388 389
  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");  
  printf("  --single-thread runs lte-softmodem in only one thread\n"); 
390
  printf("  -C Set the downlink frequency for all component carriers\n");
nikaeinn's avatar
nikaeinn committed
391 392 393
  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");
394
  printf("  -G Set the global log verbosity \n");
nikaeinn's avatar
nikaeinn committed
395 396 397 398 399
  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
400
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
nikaeinn's avatar
nikaeinn committed
401 402
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
403
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
nikaeinn's avatar
nikaeinn committed
404 405 406
  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");
407
  printf("  -x Set the transmission mode, valid options: 1 \n");
408
  printf("  -E Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n");
409 410 411
#if T_TRACER
  printf("  --T_port [port]    use given port\n");
  printf("  --T_nowait         don't wait for tracer, start immediately\n");
412
  printf("  --T_dont_fork      to ease debugging with gdb\n");
413 414 415
#endif
  printf(RESET);
  fflush(stdout);
nikaeinn's avatar
nikaeinn committed
416
}
417

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

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

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

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

}

448

449
#ifdef XFORMS
450

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

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

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

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

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

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

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

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

498
# ifdef ENABLE_XFORMS_WRITE_STATS
499 500

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

505
#endif
506

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

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

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

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

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

535 536
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
537
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
538 539
	  //	  if ((PHY_vars_eNB_g[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) {
	  if ((ue_cnt<scope_enb_num_ue)) {
gauthier's avatar
gauthier committed
540
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
541 542 543 544
			  PHY_vars_eNB_g[0][CC_id],
			  UE_id);
	    ue_cnt++;
	  }
545
	}
knopp's avatar
 
knopp committed
546
      }
547

548
    }
549

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

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

557
# ifdef ENABLE_XFORMS_WRITE_STATS
558

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

573
# endif
574

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

579

580

581

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
590

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

600
      itti_receive_msg (TASK_L2L1, &message_p);
601

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

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

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

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

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

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

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

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

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

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

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

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

660

661

662

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


675 676

  const Enb_properties_array_t *enb_properties;
677

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

705
  static const struct option long_options[] = {
706
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
707 708 709 710 711 712
    {"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
713 714
    {"calib-prach-tx",   no_argument,        NULL, LONG_OPTION_CALIB_PRACH_TX},
    {"ue-rxgain",   required_argument,  NULL, LONG_OPTION_RXGAIN},
fnabet's avatar
fnabet committed
715
	{"ue-rxgain-off",   required_argument,  NULL, LONG_OPTION_RXGAINOFF},
knopp's avatar
 
knopp committed
716 717
    {"ue-txgain",   required_argument,  NULL, LONG_OPTION_TXGAIN},
    {"ue-scan-carrier",   no_argument,  NULL, LONG_OPTION_SCANCARRIER},
718
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
719 720
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
721
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
722
    {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
knopp's avatar
knopp committed
723
    {"single-thread", no_argument, NULL, LONG_OPTION_SINGLE_THREAD},
724 725 726
#if T_TRACER
    {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
    {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
Cedric Roux's avatar
Cedric Roux committed
727
    {"T_dont_fork",            no_argument,       0, LONG_OPTION_T_DONT_FORK},
728
#endif
729 730 731
    {NULL, 0, NULL, 0}
  };

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

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

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

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

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

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

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

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

790
      break;
791

fnabet's avatar
fnabet committed
792 793 794 795
    case LONG_OPTION_RXGAINOFF:
      rx_gain_off = atof(optarg);
      break;

796 797 798
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
799

800
      break;