lte-softmodem.c 63.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22 23
/*! \file lte-enb.c
 * \brief Top-level threads for eNodeB
24
 * \author R. Knopp, F. Kaltenberger, Navid Nikaein
Raymond Knopp's avatar
 
Raymond Knopp committed
25 26 27
 * \date 2012
 * \version 0.1
 * \company Eurecom
28
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
Raymond Knopp's avatar
 
Raymond Knopp committed
29 30 31
 * \note
 * \warning
 */
Raymond Knopp's avatar
 
Raymond Knopp committed
32
#define _GNU_SOURCE
33 34 35 36 37 38 39 40
#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>
41
#include <linux/sched.h>
42 43 44
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>
45
#include <sys/sysinfo.h>
46

47 48
#include "T.h"

49
#include "rt_wrapper.h"
50

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

53
#include "assertions.h"
54
#include "msc.h"
55 56

#include "PHY/types.h"
57

58
#include "PHY/defs.h"
59
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
Raymond Knopp's avatar
 
Raymond Knopp committed
60
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
61

Raymond Knopp's avatar
 
Raymond Knopp committed
62
#include "../../ARCH/COMMON/common_lib.h"
63
#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
64

Raymond Knopp's avatar
 
Raymond Knopp committed
65
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
66 67 68 69 70 71 72 73 74

#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"
75
#include "LAYER2/MAC/proto.h"
76 77 78 79 80 81 82 83
#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"
Navid Nikaein's avatar
Navid Nikaein committed
84
#include "UTIL/OTG/otg_tx.h"
85
#include "UTIL/OTG/otg_externs.h"
86 87
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
88
#include "UTIL/OPT/opt.h"
89
#include "enb_config.h"
Navid Nikaein's avatar
Navid Nikaein committed
90
//#include "PHY/TOOLS/time_meas.h"
91

Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
92 93 94 95
#ifndef OPENAIR2
#include "UTIL/OTG/otg_vars.h"
#endif

96 97
#if defined(ENABLE_ITTI)
# include "intertask_interface_init.h"
98
# include "create_tasks.h"
99 100
# if defined(ENABLE_USE_MME)
#   include "s1ap_eNB.h"
101
#ifdef PDCP_USE_NETLINK
102
#   include "SIMULATION/ETH_TRANSPORT/proto.h"
Rohit Gupta's avatar
Rohit Gupta committed
103
extern int netlink_init(void);
104
#endif
105
# endif
106 107
#endif

108 109 110
#ifdef XFORMS
#include "PHY/TOOLS/lte_phy_scope.h"
#include "stats.h"
111 112
#endif

113
// In lte-enb.c
114
extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg);
115
extern void init_eNB(eNB_func_t *, eNB_timing_t *,int,eth_params_t *,int,int);
116
extern void stop_eNB(int);
117
extern void kill_eNB_proc(void);
Raymond Knopp's avatar
 
Raymond Knopp committed
118

119
// In lte-ue.c
120
extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
121
extern void fill_ue_band_info(void);
Raymond Knopp's avatar
Raymond Knopp committed
122
extern void init_UE(int);
123

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

134 135


136

137

Raymond Knopp's avatar
 
Raymond Knopp committed
138

Raymond Knopp's avatar
 
Raymond Knopp committed
139 140
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
141
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
142

143

144 145


146

147
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
148
static pthread_t                forms_thread; //xforms
149
#endif
150

151 152
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]
Raymond Knopp's avatar
 
Raymond Knopp committed
153

154

155
#if defined(ENABLE_ITTI)
156 157
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
158
#endif
Raymond Knopp's avatar
Raymond Knopp committed
159
volatile int             oai_exit = 0;
160 161 162



163
static clock_source_t clock_source = internal;
Raymond Knopp's avatar
 
Raymond Knopp committed
164

165
static wait_for_sync = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
166

Raymond Knopp's avatar
Raymond Knopp committed
167
static char              UE_flag=0;
168
unsigned int                    mmapped_dma=0;
169
int                             single_thread_flag=1;
170

171
static char                     threequarter_fs=0;
172

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

176

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

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

186 187
FILE *input_fd=NULL;

188

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

199
double rx_gain_off = 0.0;
200

Raymond Knopp's avatar
 
Raymond Knopp committed
201
double sample_rate=30.72e6;
202
double bw = 10.0e6;
203

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

206 207
char   rf_config_file[1024];

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

212

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

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

226

Raymond Knopp's avatar
 
Raymond Knopp committed
227
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
228 229 230
eNB_func_t node_function[MAX_NUM_CCs];
eNB_timing_t node_timing[MAX_NUM_CCs];
int16_t   node_synch_ref[MAX_NUM_CCs];
231

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

Raymond Knopp's avatar
 
Raymond Knopp committed
238

239 240
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
241
int transmission_mode=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
242

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
271

272

273 274
char *rrh_UE_ip = "127.0.0.1";
int rrh_UE_port = 51000;
275

276 277 278 279 280 281

/* 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;

282 283 284 285
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

Raymond Knopp's avatar
 
Raymond Knopp committed
286
char uecap_xer[1024],uecap_xer_in=0;
287 288


Raymond Knopp's avatar
 
Raymond Knopp committed
289

290 291 292 293 294 295 296
/*---------------------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)
{
297 298 299 300 301 302 303 304 305
  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;
306 307
}

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

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

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

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

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

350 351 352 353
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
354 355
  } else {
    printf("trying to exit gracefully...\n");
356
    oai_exit = 1;
357 358
  }
}
359
#endif
360 361 362 363 364 365 366 367 368 369 370
#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");
371
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
372 373 374 375
  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");
Raymond Knopp's avatar
 
Raymond Knopp committed
376 377
  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");
378
  printf("  --no-L2-connect bypass L2 and upper layers\n");
379
  printf("  --ue-rxgain set UE RX gain\n");
380
  printf("  --ue-rxgain-off external UE amplifier offset\n");
381 382 383
  printf("  --ue-txgain set UE TX gain\n");
  printf("  --ue-scan_carrier set UE to scan around carrier\n");
  printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
384
  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");  
385
  printf("  --external-clock tells hardware to use an external clock reference\n");
386
  printf("  --usim-test use XOR autentication algo in case of test usim mode\n"); 
387
  printf("  --single-thread-disable. Disables single-thread mode in lte-softmodem\n"); 
388
  printf("  -C Set the downlink frequency for all component carriers\n");
389 390 391
  printf("  -d Enable soft scope and L1 and L2 stats (Xforms)\n");
  printf("  -F Calibrate the EXMIMO borad, available files: exmimo2_2arxg.lime exmimo2_2brxg.lime \n");
  printf("  -g Set the global log level, valide options: (9:trace, 8/7:debug, 6:info, 4:warn, 3:error)\n");
392
  printf("  -G Set the global log verbosity \n");
393 394 395 396 397
  printf("  -h provides this help message!\n");
  printf("  -K Generate ITTI analyzser logs (similar to wireshark logs but with more details)\n");
  printf("  -m Set the maximum downlink MCS\n");
  printf("  -O eNB configuration file (located in targets/PROJECTS/GENERIC-LTE-EPC/CONF\n");
  printf("  -q Enable processing timing measurement of lte softmodem on per subframe basis \n");
kaltenbe's avatar
kaltenbe committed
398
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
399 400
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
401
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
402 403 404
  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");
405
  printf("  -x Set the transmission mode, valid options: 1 \n");
406
  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");
407 408 409
#if T_TRACER
  printf("  --T_port [port]    use given port\n");
  printf("  --T_nowait         don't wait for tracer, start immediately\n");
410
  printf("  --T_dont_fork      to ease debugging with gdb\n");
411 412 413
#endif
  printf(RESET);
  fflush(stdout);
414
}
415

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

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

  oai_exit = 1;
Raymond Knopp's avatar
Raymond Knopp committed
425 426
  
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
Raymond Knopp committed
427 428 429 430 431 432 433 434 435 436
    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
437
  }
438 439

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

}

446

447
#ifdef XFORMS
448

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

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

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

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

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

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

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

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

496
# ifdef ENABLE_XFORMS_WRITE_STATS
497 498

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

503
#endif
504

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

512 513 514 515 516
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

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

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

529 530 531
      //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);
532

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

546
    }
547

Raymond Knopp's avatar
 
Raymond Knopp committed
548
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
549 550
    //usleep(100000); // 100 ms
    sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
551
  }
552

553
  //  printf("%s",stats_buffer);
554

555
# ifdef ENABLE_XFORMS_WRITE_STATS
556

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

571
# endif
572

Raymond Knopp's avatar
 
Raymond Knopp committed
573
  pthread_exit((void*)arg);
574 575 576
}
#endif

577

578

579

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
588

Raymond Knopp's avatar
 
Raymond Knopp committed
589 590
  if (UE_flag == 0) {
    /* Wait for the initialize message */
591
    printf("Wait for the ITTI initialize message\n");
592
    do {
Raymond Knopp's avatar
 
Raymond Knopp committed
593
      if (message_p != NULL) {
594 595
        result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
        AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
Raymond Knopp's avatar
 
Raymond Knopp committed
596
      }
597

598 599 600
      itti_receive_msg (TASK_L2L1, &message_p);

      switch (ITTI_MSG_ID(message_p)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
601
      case INITIALIZE_MESSAGE:
602 603 604 605
        /* Start eNB thread */
        LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p));
        start_eNB = 1;
        break;
Raymond Knopp's avatar
 
Raymond Knopp committed
606 607

      case TERMINATE_MESSAGE:
608 609 610 611
        printf("received terminate message\n");
        oai_exit=1;
        itti_exit_task ();
        break;
Raymond Knopp's avatar
 
Raymond Knopp committed
612 613

      default:
614 615
        LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
        break;
616
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
617
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
618

Raymond Knopp's avatar
 
Raymond Knopp committed
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639
    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  }

  do {
    // Wait for a message
    itti_receive_msg (TASK_L2L1, &message_p);

    switch (ITTI_MSG_ID(message_p)) {
    case TERMINATE_MESSAGE:
      oai_exit=1;
      itti_exit_task ();
      break;

    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;

    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
640

Raymond Knopp's avatar
 
Raymond Knopp committed
641 642 643 644 645 646 647 648 649 650 651
    case MESSAGE_TEST:
      LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
      break;

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

    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
652
  } while(!oai_exit);
653

Raymond Knopp's avatar
 
Raymond Knopp committed
654
  return NULL;
655 656 657
}
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
658

659
 
Raymond Knopp's avatar
 
Raymond Knopp committed
660

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


673

674
  const Enb_properties_array_t *enb_properties;
675

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

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

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

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

765 766 767 768
    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);
Raymond Knopp's avatar
 
Raymond Knopp committed
769
      break;
770

771 772 773 774 775
    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;
776

777 778 779
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
780

781 782 783
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
784

Raymond Knopp's avatar
 
Raymond Knopp committed
785 786
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
Rohit Gupta's avatar
Rohit Gupta committed
787
      printf("Setting mode to calib_prach_tx (%d)\n",mode);
Raymond Knopp's avatar
 
Raymond Knopp committed
788 789
      break;

790
    case LONG_OPTION_RXGAIN:
791 792
      for (i=0; i<4; i++)
        rx_gain[0][i] = atof(optarg);
793

794
      break;
795

796 797 798 799
    case LONG_OPTION_RXGAINOFF:
      rx_gain_off = atof(optarg);
      break;

800 801 802
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
803

804
      break;
805

806 807 808 809 810
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

811 812 813 814 815 816
    case LONG_OPTION_LOOPMEMORY:
      mode=loop_through_memory;
      input_fd = fopen(optarg,"r");
      AssertFatal(input_fd != NULL,"Please provide an input file\n");
      break;

817 818 819 820
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
821 822 823
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
824

825 826 827
    case LONG_OPTION_USIMTEST:
        usim_test = 1;
      break;
828 829 830
    case LONG_OPTION_MMAPPED_DMA:
      mmapped_dma = 1;
      break;
Raymond Knopp's avatar
Raymond Knopp committed
831

832 833
    case LONG_OPTION_SINGLE_THREAD_DISABLE:
      single_thread_flag = 0;
Raymond Knopp's avatar
Raymond Knopp committed
834
      break;
835 836 837 838 839

    case LONG_OPTION_EXTERNAL_CLOCK:
      clock_source = external;
      break;

840 841 842 843
    case LONG_OPTION_WAIT_FOR_SYNC:
      wait_for_sync = 1;
      break;

844 845 846 847 848 849 850 851 852 853 854 855 856
#if T_TRACER
    case LONG_OPTION_T_PORT: {
      extern int T_port;
      if (optarg == NULL) abort();  /* should not happen */
      T_port = atoi(optarg);
      break;
    }

    case LONG_OPTION_T_NOWAIT: {
      extern int T_wait;
      T_wait = 0;
      break;
    }
857 858 859 860 861 862

    case LONG_OPTION_T_DONT_FORK: {
      extern int T_dont_fork;
      T_dont_fork = 1;
      break;
    }
863 864
#endif

865 866 867 868
    case 'A':
      timing_advance = atoi (optarg);
      break;

869
    case 'C':
870 871 872 873 874 875
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
        downlink_frequency[CC_id][0] = atof(optarg); // Use float to avoid issue with frequency over 2^31.
        downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0];
        downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0];
        downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0];
        printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
876
      }
877

878
      UE_scan=0;
879

880
      break;
881

Florian Kaltenberger's avatar
Florian Kaltenberger committed
882 883 884 885
    case 'a':
      chain_offset = atoi(optarg);
      break;

886 887 888 889
    case 'd':
#ifdef XFORMS
      do_forms=1;
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
890
#endif
891
      break;
892 893 894 895
      
    case 'E':
      threequarter_fs=1;
      break;
896

897 898 899
    case 'K':
#if defined(ENABLE_ITTI)
      itti_dump_file = strdup(optarg);
900
#else
901
      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
902
#endif
903
      break;
904

905 906 907
    case 'O':
      conf_config_file_name = optarg;
      break;
908

909 910 911
    case 'U':
      UE_flag = 1;
      break;
912

913 914 915
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
916

917 918 919
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
920

921 922 923 924 925 926 927
    case 'W':
      opt_enabled=1;
      opt_type = OPT_WIRESHARK;
      strncpy(in_ip, "127.0.0.1", sizeof(in_ip));
      in_ip[sizeof(in_ip) - 1] = 0; // terminate string
      printf("Enabling OPT for wireshark for local interface");
      /*
928 929 930 931 932 933 934 935
	if (optarg == NULL){
	in_ip[0] =NULL;
	printf("Enabling OPT for wireshark for local interface");
	} else {
	strncpy(in_ip, optarg, sizeof(in_ip));
	in_ip[sizeof(in_ip) - 1] = 0; // terminate string
	printf("Enabling OPT for wireshark with %s \n",in_ip);
	}
936 937
      */
      break;
938

939
    case 'P':
940 941
      opt_type = OPT_PCAP;
      opt_enabled=1;
942 943 944 945 946

      if (optarg == NULL) {
        strncpy(in_path, "/tmp/oai_opt.pcap", sizeof(in_path));
        in_path[sizeof(in_path) - 1] = 0; // terminate string
        printf("Enabling OPT for PCAP with the following path /tmp/oai_opt.pcap");
947
      } else {
948 949 950
        strncpy(in_path, optarg, sizeof(in_path));
        in_path[sizeof(in_path) - 1] = 0; // terminate string
        printf("Enabling OPT for PCAP  with the following file %s \n",in_path);
951
      }
952 953 954

      break;

Raymond Knopp's avatar
 
Raymond Knopp committed
955 956 957
    case 'V':
      ouput_vcd = 1;
      break;
958

Raymond Knopp's avatar
 
Raymond Knopp committed
959
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
960 961
      opp_enabled = 1;
      break;
962

Raymond Knopp's avatar
 
Raymond Knopp committed
963 964 965
    case  'R' :
      online_log_messages =1;
      break;
966

Raymond Knopp's avatar
 
Raymond Knopp committed
967
    case 'r':
968
      UE_scan = 0;
969

970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
        switch(atoi(optarg)) {
        case 6:
          frame_parms[CC_id]->N_RB_DL=6;
          frame_parms[CC_id]->N_RB_UL=6;
          break;

        case 25:
          frame_parms[CC_id]->N_RB_DL=25;
          frame_parms[CC_id]->N_RB_UL=25;
          break;

        case 50:
          frame_parms[CC_id]->N_RB_DL=50;
          frame_parms[CC_id]->N_RB_UL=50;
          break;

        case 100:
          frame_parms[CC_id]->N_RB_DL=100;
          frame_parms[CC_id]->N_RB_UL=100;
          break;

        default:
          printf("Unknown N_RB_DL %d, switching to 25\n",atoi(optarg));
          break;
        }
Raymond Knopp's avatar
 
Raymond Knopp committed
996
      }
997

998
      break;
999

Raymond Knopp's avatar
 
Raymond Knopp committed
1000
    case 's':
1001
#if defined(OAI_USRP) || defined(CPRIGW)
Raymond Knopp's avatar
 
Raymond Knopp committed
1002 1003

      clock_src = atoi(optarg);
1004

Raymond Knopp's avatar
 
Raymond Knopp committed
1005
      if (clock_src == 0) {
1006 1007 1008 1009 1010
        //  char ref[128] = "internal";
        //strncpy(uhd_ref, ref, strlen(ref)+1);
      } else if (clock_src == 1) {
        //char ref[128] = "external";
        //strncpy(uhd_ref, ref, strlen(ref)+1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1011
      }
1012

Raymond Knopp's avatar
 
Raymond Knopp committed
1013 1014 1015 1016
#else
      printf("Note: -s not defined for ExpressMIMO2\n");
#endif
      break;
1017

1018 1019 1020 1021
    case 'S':
      exit_missed_slots=0;
      printf("Skip exit for missed slots\n");
      break;
1022

1023
    case 'g':
Raymond Knopp's avatar
 
Raymond Knopp committed
1024
      glog_level=atoi(optarg); // value between 1 - 9
1025
      break;
1026 1027 1028

    case 'F':
      break;
1029

1030 1031 1032
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
1033

1034
    case 'x':
1035 1036 1037
      printf("Transmission mode should be set in config file now\n");
      exit(-1);
      /*
1038
      transmission_mode = atoi(optarg);
1039

1040 1041
      if (transmission_mode > 7) {
        printf("Transmission mode %d not supported for the moment\n",transmission_mode);
1042
        exit(-1);
1043
      }
1044
      */
1045
      break;
1046

1047 1048 1049
    case 'T':
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
	frame_parms[CC_id]->frame_type = TDD;
1050
      break;
1051

1052 1053 1054 1055
    case 'h':
      help ();
      exit (-1);
       
Raymond Knopp's avatar
 
Raymond Knopp committed
1056
    default:
1057 1058
      help ();
      exit (-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1059
      break;
1060 1061
    }
  }
1062

Raymond Knopp's avatar
 
Raymond Knopp committed
1063 1064
  if (UE_flag == 0)
    AssertFatal(conf_config_file_name != NULL,"Please provide a configuration file\n");
1065

Raymond Knopp's avatar
 
Raymond Knopp committed
1066
  if ((UE_flag == 0) && (conf_config_file_name != NULL)) {
1067
    int i,j;
1068

Raymond Knopp's avatar
 
Raymond Knopp committed
1069
    NB_eNB_INST = 1;
1070

Raymond Knopp's avatar
 
Raymond Knopp committed
1071 1072
    /* Read eNB configuration file */
    enb_properties = enb_config_init(conf_config_file_name);
1073

Raymond Knopp's avatar
 
Raymond Knopp committed
1074
    AssertFatal (NB_eNB_INST <= enb_properties->number,
1075 1076
                 "Number of eNB is greater than eNB defined in configuration file %s (%d/%d)!",
                 conf_config_file_name, NB_eNB_INST, enb_properties->number);
1077

Raymond Knopp's avatar
 
Raymond Knopp committed
1078
    /* Update some simulation parameters */
1079
    for (i=0; i < enb_properties->number; i++) {
1080
      AssertFatal (MAX_NUM_CCs == enb_properties->properties[i]->nb_cc,
1081 1082
                   "lte-softmodem compiled with MAX_NUM_CCs=%d, but only %d CCs configured for eNB %d!",
                   MAX_NUM_CCs, enb_properties->properties[i]->nb_cc, i);
1083 1084
      eth_params = (eth_params_t*)malloc(enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t));
      memset(eth_params, 0, enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t));
1085

1086
      for (j=0; j<enb_properties->properties[i]->nb_rrh_gw; j++) {
1087 1088 1089
        	
        if (enb_properties->properties[i]->rrh_gw_config[j].active == 1 ) {
          local_remote_radio = BBU_REMOTE_RADIO_HEAD;
1090
          (eth_params+j)->local_if_name             = enb_properties->properties[i]->rrh_gw_config[j].rrh_gw_if_name;
1091 1092 1093 1094
          (eth_params+j)->my_addr                   = enb_properties->properties[i]->rrh_gw_config[j].local_address;
          (eth_params+j)->my_port                   = enb_properties->properties[i]->rrh_gw_config[j].local_port;
          (eth_params+j)->remote_addr               = enb_properties->properties[i]->rrh_gw_config[j].remote_address;
          (eth_params+j)->remote_port               = enb_properties->properties[i]->rrh_gw_config[j].remote_port;
1095 1096 1097
          
          if (enb_properties->properties[i]->rrh_gw_config[j].raw == 1) {
            (eth_params+j)->transp_preference       = ETH_RAW_MODE; 
Raymond Knopp's avatar
Raymond Knopp committed
1098
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif4p5 == 1) {
1099
            (eth_params+j)->transp_preference       = ETH_RAW_IF4p5_MODE;             
Raymond Knopp's avatar
Raymond Knopp committed
1100
          } else if (enb_properties->properties[i]->rrh_gw_config[j].udpif4p5 == 1) {
1101
            (eth_params+j)->transp_preference       = ETH_UDP_IF4p5_MODE;             
1102 1103
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif5_mobipass == 1) {
            (eth_params+j)->transp_preference       = ETH_RAW_IF5_MOBIPASS;             
1104 1105 1106 1107
          } else {
            (eth_params+j)->transp_preference       = ETH_UDP_MODE;	 
          }
          
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126
          (eth_params+j)->iq_txshift                = enb_properties->properties[i]->rrh_gw_config[j].iq_txshift;
          (eth_params+j)->tx_sample_advance         = enb_properties->properties[i]->rrh_gw_config[j].tx_sample_advance;
          (eth_params+j)->tx_scheduling_advance     = enb_properties->properties[i]->rrh_gw_config[j].tx_scheduling_advance;
          if (enb_properties->properties[i]->rrh_gw_config[j].exmimo == 1) {
            (eth_params+j)->rf_preference          = EXMIMO_DEV;
          } else if (enb_properties->properties[i]->rrh_gw_config[j].usrp_b200 == 1) {
            (eth_params+j)->rf_preference          = USRP_B200_DEV;
          } else if (enb_properties->properties[i]->rrh_gw_config[j].usrp_x300 == 1) {
            (eth_params+j)->rf_preference          = USRP_X300_DEV;
          } else if (enb_properties->properties[i]->rrh_gw_config[j].bladerf == 1) {
            (eth_params+j)->rf_preference          = BLADERF_DEV;
          } else if (enb_properties->properties[i]->rrh_gw_config[j].lmssdr == 1) {
            //(eth_params+j)->rf_preference          = LMSSDR_DEV;
          } else {
            (eth_params+j)->rf_preference          = 0;
          } 
        } else {
          local_remote_radio = BBU_LOCAL_RADIO_HEAD; 
        }
1127 1128 1129
	
      }

1130
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
Raymond Knopp committed
1131 1132
	

1133 1134 1135 1136
        node_function[CC_id]  = enb_properties->properties[i]->cc_node_function[CC_id];
        node_timing[CC_id]    = enb_properties->properties[i]->cc_node_timing[CC_id];
        node_synch_ref[CC_id] = enb_properties->properties[i]->cc_node_synch_ref[CC_id];

1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
        frame_parms[CC_id]->frame_type =       enb_properties->properties[i]->frame_type[CC_id];
        frame_parms[CC_id]->tdd_config =       enb_properties->properties[i]->tdd_config[CC_id];
        frame_parms[CC_id]->tdd_config_S =     enb_properties->properties[i]->tdd_config_s[CC_id];
        frame_parms[CC_id]->Ncp =              enb_properties->properties[i]->prefix_type[CC_id];

        //for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){
        frame_parms[CC_id]->Nid_cell            =  enb_properties->properties[i]->Nid_cell[CC_id];
        frame_parms[CC_id]->N_RB_DL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
        frame_parms[CC_id]->N_RB_UL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
        frame_parms[CC_id]->nb_antennas_tx      =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
1147
        frame_parms[CC_id]->nb_antenna_ports_eNB  =  enb_properties->properties[i]->nb_antenna_ports[CC_id];
1148
        frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
Raymond Knopp's avatar
Raymond Knopp committed
1149 1150 1151 1152

	frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = enb_properties->properties[i]->prach_config_index[CC_id];
	frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset  = enb_properties->properties[i]->prach_freq_offset[CC_id];

1153
	frame_parms[CC_id]->mode1_flag         = (frame_parms[CC_id]->nb_antenna_ports_eNB == 1) ? 1 : 0;
Raymond Knopp's avatar
Raymond Knopp committed
1154 1155
	frame_parms[CC_id]->threequarter_fs    = threequarter_fs;

1156
        //} // j
Raymond Knopp's avatar
 
Raymond Knopp committed
1157 1158
      }

1159

1160 1161 1162
      init_all_otg(0);
      g_otg->seed = 0;
      init_seeds(g_otg->seed);
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172

      for (k=0; k<enb_properties->properties[i]->num_otg_elements; k++) {
        j=enb_properties->properties[i]->otg_ue_id[k]; // ue_id
        g_otg->application_idx[i][j] = 1;
        //g_otg->packet_gen_type=SUBSTRACT_STRING;
        g_otg->background[i][j][0] =enb_properties->properties[i]->otg_bg_traffic[k];
        g_otg->application_type[i][j][0] =enb_properties->properties[i]->otg_app_type[k];// BCBR; //MCBR, BCBR

        printf("[OTG] configuring traffic type %d for  eNB %d UE %d (Background traffic is %s)\n",
               g_otg->application_type[i][j][0], i, j,(g_otg->background[i][j][0]==1)?"Enabled":"Disabled");
1173
      }
1174

1175
      init_predef_traffic(enb_properties->properties[i]->num_otg_elements, 1);
1176 1177


1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191
      glog_level                     = enb_properties->properties[i]->glog_level;
      glog_verbosity                 = enb_properties->properties[i]->glog_verbosity;
      hw_log_level                   = enb_properties->properties[i]->hw_log_level;
      hw_log_verbosity               = enb_properties->properties[i]->hw_log_verbosity ;
      phy_log_level                  = enb_properties->properties[i]->phy_log_level;
      phy_log_verbosity              = enb_properties->properties[i]->phy_log_verbosity;
      mac_log_level                  = enb_properties->properties[i]->mac_log_level;
      mac_log_verbosity              = enb_properties->properties[i]->mac_log_verbosity;
      rlc_log_level                  = enb_properties->properties[i]->rlc_log_level;
      rlc_log_verbosity              = enb_properties->properties[i]->rlc_log_verbosity;
      pdcp_log_level                 = enb_properties->properties[i]->pdcp_log_level;
      pdcp_log_verbosity             = enb_properties->properties[i]->pdcp_log_verbosity;
      rrc_log_level                  = enb_properties->properties[i]->rrc_log_level;
      rrc_log_verbosity              = enb_properties->properties[i]->rrc_log_verbosity;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1192 1193 1194 1195 1196 1197
# if defined(ENABLE_USE_MME)
      gtpu_log_level                 = enb_properties->properties[i]->gtpu_log_level;
      gtpu_log_verbosity             = enb_properties->properties[i]->gtpu_log_verbosity;
      udp_log_level                  = enb_properties->properties[i]->udp_log_level;
      udp_log_verbosity              = enb_properties->properties[i]->udp_log_verbosity;
#endif
1198 1199 1200
#if defined (ENABLE_SECURITY)
      osa_log_level                  = enb_properties->properties[i]->osa_log_level;
      osa_log_verbosity              = enb_properties->properties[i]->osa_log_verbosity;
1201
#endif
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1202

Raymond Knopp's avatar
 
Raymond Knopp committed
1203
      // adjust the log
1204
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
        for (k = 0 ; k < 4; k++) {
          downlink_frequency[CC_id][k]      =       enb_properties->properties[i]->downlink_frequency[CC_id];
          uplink_frequency_offset[CC_id][k] =  enb_properties->properties[i]->uplink_frequency_offset[CC_id];
          rx_gain[CC_id][k]                 =  (double)enb_properties->properties[i]->rx_gain[CC_id];
          tx_gain[CC_id][k]                 =  (double)enb_properties->properties[i]->tx_gain[CC_id];
        }

        printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id,
               enb_properties->properties[i]->downlink_frequency[CC_id],
               enb_properties->properties[i]->uplink_frequency_offset[CC_id]);
1215

Raymond Knopp's avatar
 
Raymond Knopp committed
1216
      } // CC_id
1217
    }// i
1218 1219 1220 1221

    //this is needed for phy-test option
    transmission_mode = enb_properties->properties[0]->ue_TransmissionMode[0]+1;

1222 1223 1224 1225 1226 1227 1228 1229
  } else if (UE_flag == 1) {
    if (conf_config_file_name != NULL) {
      
      // Here the configuration file is the XER encoded UE capabilities
      // Read it in and store in asn1c data structures
      strcpy(uecap_xer,conf_config_file_name);
      uecap_xer_in=1;
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1230
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1231
}
1232

1233 1234 1235
#if T_TRACER
int T_wait = 1;       /* by default we wait for the tracer */
int T_port = 2021;    /* default port to listen to to wait for the tracer */
1236
int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
1237 1238
#endif

1239 1240
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
Raymond Knopp's avatar
Raymond Knopp committed
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255

  int CC_id;

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS));
    /* Set some default values that may be overwritten while reading options */
    frame_parms[CC_id]->frame_type          = FDD;
    frame_parms[CC_id]->tdd_config          = 3;
    frame_parms[CC_id]->tdd_config_S        = 0;
    frame_parms[CC_id]->N_RB_DL             = 100;
    frame_parms[CC_id]->N_RB_UL             = 100;
    frame_parms[CC_id]->Ncp                 = NORMAL;
    frame_parms[CC_id]->Ncp_UL              = NORMAL;
    frame_parms[CC_id]->Nid_cell            = 0;
    frame_parms[CC_id]->num_MBSFN_config    = 0;
1256
    frame_parms[CC_id]->nb_antenna_ports_eNB  = 1;
Raymond Knopp's avatar
Raymond Knopp committed
1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285
    frame_parms[CC_id]->nb_antennas_tx      = 1;
    frame_parms[CC_id]->nb_antennas_rx      = 1;

    frame_parms[CC_id]->nushift             = 0;

    frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
    frame_parms[CC_id]->phich_config_common.phich_duration = normal;
    // UL RS Config
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0;
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;

    frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;

    downlink_frequency[CC_id][0] = 2680000000; // Use float to avoid issue with frequency over 2^31.
    downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0];
    downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0];
    downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0];
    //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);

  }

}

1286 1287
void init_openair0(void);

Raymond Knopp's avatar
Raymond Knopp committed
1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334
void init_openair0() {

  int card;
  int i;

  for (card=0; card<MAX_CARDS; card++) {

    openair0_cfg[card].mmapped_dma=mmapped_dma;
    openair0_cfg[card].configFilename = NULL;

    if(frame_parms[0]->N_RB_DL == 100) {
      if (frame_parms[0]->threequarter_fs) {
	openair0_cfg[card].sample_rate=23.04e6;
	openair0_cfg[card].samples_per_frame = 230400; 
	openair0_cfg[card].tx_bw = 10e6;
	openair0_cfg[card].rx_bw = 10e6;
      }
      else {
	openair0_cfg[card].sample_rate=30.72e6;
	openair0_cfg[card].samples_per_frame = 307200; 
	openair0_cfg[card].tx_bw = 10e6;
	openair0_cfg[card].rx_bw = 10e6;
      }
    } else if(frame_parms[0]->N_RB_DL == 50) {
      openair0_cfg[card].sample_rate=15.36e6;
      openair0_cfg[card].samples_per_frame = 153600;
      openair0_cfg[card].tx_bw = 5e6;
      openair0_cfg[card].rx_bw = 5e6;
    } else if (frame_parms[0]->N_RB_DL == 25) {
      openair0_cfg[card].sample_rate=7.68e6;
      openair0_cfg[card].samples_per_frame = 76800;
      openair0_cfg[card].tx_bw = 2.5e6;
      openair0_cfg[card].rx_bw = 2.5e6;
    } else if (frame_parms[0]->N_RB_DL == 6) {
      openair0_cfg[card].sample_rate=1.92e6;
      openair0_cfg[card].samples_per_frame = 19200;
      openair0_cfg[card].tx_bw = 1.5e6;
      openair0_cfg[card].rx_bw = 1.5e6;
    }

    if (frame_parms[0]->frame_type==TDD)
      openair0_cfg[card].duplex_mode = duplex_mode_TDD;
    else //FDD
      openair0_cfg[card].duplex_mode = duplex_mode_FDD;

    
    if (local_remote_radio == BBU_REMOTE_RADIO_HEAD) {      
1335 1336 1337 1338
      openair0_cfg[card].remote_addr    = (eth_params+card)->remote_addr;
      openair0_cfg[card].remote_port    = (eth_params+card)->remote_port;
      openair0_cfg[card].my_addr        = (eth_params+card)->my_addr;
      openair0_cfg[card].my_port        = (eth_params+card)->my_port;    
Raymond Knopp's avatar
Raymond Knopp committed
1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
    } 
    
    printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
           ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx),
           ((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx));
    openair0_cfg[card].Mod_id = 0;

    if (UE_flag) {
      printf("ETHERNET: Configuring UE ETH for %s:%d\n",rrh_UE_ip,rrh_UE_port);
      openair0_cfg[card].remote_addr   = &rrh_UE_ip[0];
      openair0_cfg[card].remote_port = rrh_UE_port;
    } 

    openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
1353

1354
    openair0_cfg[card].clock_source = clock_source;
1355

Raymond Knopp's avatar
Raymond Knopp committed
1356 1357
    openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx));
    openair0_cfg[card].rx_num_channels=min(2,((UE_flag==0) ? PHY_vars_eNB_g[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx));
1358

Raymond Knopp's avatar
Raymond Knopp committed
1359
    for (i=0; i<4; i++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1360

Raymond Knopp's avatar
Raymond Knopp committed
1361 1362 1363 1364
      if (i<openair0_cfg[card].tx_num_channels)
	openair0_cfg[card].tx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] : downlink_frequency[0][i]+uplink_frequency_offset[0][i];
      else
	openair0_cfg[card].tx_freq[i]=0.0;
1365

Raymond Knopp's avatar
Raymond Knopp committed
1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376
      if (i<openair0_cfg[card].rx_num_channels)
	openair0_cfg[card].rx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] + uplink_frequency_offset[0][i] : downlink_frequency[0][i];
      else
	openair0_cfg[card].rx_freq[i]=0.0;

      openair0_cfg[card].autocal[i] = 1;
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
      if (UE_flag == 0) {
	openair0_cfg[card].rx_gain[i] = PHY_vars_eNB_g[0][0]->rx_total_gain_dB;
      }
      else {
1377
	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off;
Raymond Knopp's avatar
Raymond Knopp committed
1378 1379
      }

1380
      openair0_cfg[card].configFilename = rf_config_file;
1381 1382 1383 1384 1385
      printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
             card,i, openair0_cfg[card].tx_gain[i],
             openair0_cfg[card].rx_gain[i],
             openair0_cfg[card].tx_freq[i],
             openair0_cfg[card].rx_freq[i]);
1386
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1387
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1388
}
1389

1390 1391
int main( int argc, char **argv )
{
1392
  int i,j,k,aa,re;
1393
#if defined (XFORMS)
Raymond Knopp's avatar
 
Raymond Knopp committed
1394
  void *status;
1395
#endif
1396

Raymond Knopp's avatar
 
Raymond Knopp committed
1397
  int CC_id;
Raymond Knopp's avatar
Raymond Knopp committed
1398
  uint8_t  abstraction_flag=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1399
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
1400

Raymond Knopp's avatar
 
Raymond Knopp committed
1401
#if defined (XFORMS)
1402 1403
  int ret;
#endif
1404

1405 1406 1407 1408 1409
#ifdef DEBUG_CONSOLE
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);
#endif

1410 1411 1412
  PHY_VARS_UE *UE[MAX_NUM_CCs];

  mode = normal_txrx;
1413
  memset(&openair0_cfg[0],0,sizeof(openair0_config_t)*MAX_CARDS);
1414

1415
  memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
Raymond Knopp's avatar
 
Raymond Knopp committed
1416
  set_latency_target();
1417

Raymond Knopp's avatar
Raymond Knopp committed
1418 1419
  // set default parameters
  set_default_frame_parms(frame_parms);
1420

Raymond Knopp's avatar
Raymond Knopp committed
1421
  // initialize logging
1422
  logInit();
Raymond Knopp's avatar
Raymond Knopp committed
1423 1424 1425 1426 1427

  // get options and fill parameters from configuration file
  get_options (argc, argv); //Command-line options, enb_properties


1428
 
Raymond Knopp's avatar
Raymond Knopp committed
1429

1430
  
1431
#if T_TRACER
1432
  T_init(T_port, T_wait, T_dont_fork);
1433 1434
#endif

1435
  // initialize the log (see log.h for details)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1436 1437
  set_glog(glog_level, glog_verbosity);

1438 1439
  //randominit (0);
  set_taus_seed (0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1440

1441 1442
  if (UE_flag==1) {
    printf("configuring for UE\n");
1443

1444 1445
    set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
    set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
1446 1447 1448 1449 1450
    set_comp_log(MAC,     LOG_INFO,   LOG_HIGH, 1);
    set_comp_log(RLC,     LOG_INFO,   LOG_HIGH, 1);
    set_comp_log(PDCP,    LOG_INFO,   LOG_HIGH, 1);
    set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);
    set_comp_log(RRC,     LOG_INFO,   LOG_HIGH, 1);
1451
#if defined(ENABLE_ITTI)
1452
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1453
# if defined(ENABLE_USE_MME)
1454
    set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
1455 1456
# endif
#endif
1457 1458
  } else {
    printf("configuring for eNB\n");
1459

1460 1461 1462 1463 1464 1465 1466 1467
    set_comp_log(HW,      hw_log_level, hw_log_verbosity, 1);
    set_comp_log(PHY,     phy_log_level,   phy_log_verbosity, 1);
    if (opt_enabled == 1 )
      set_comp_log(OPT,   opt_log_level,      opt_log_verbosity, 1);
    set_comp_log(MAC,     mac_log_level,  mac_log_verbosity, 1);
    set_comp_log(RLC,     rlc_log_level,   rlc_log_verbosity, 1);
    set_comp_log(PDCP,    pdcp_log_level,  pdcp_log_verbosity, 1);
    set_comp_log(RRC,     rrc_log_level,  rrc_log_verbosity, 1);
1468
#if defined(ENABLE_ITTI)
1469
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1470
# if defined(ENABLE_USE_MME)
1471 1472 1473 1474
    set_comp_log(UDP_,    udp_log_level,   udp_log_verbosity, 1);
    set_comp_log(GTPU,    gtpu_log_level,   gtpu_log_verbosity, 1);
    set_comp_log(S1AP,    LOG_DEBUG,   LOG_HIGH, 1);
    set_comp_log(SCTP,    LOG_INFO,   LOG_HIGH, 1);
1475
# endif
1476
#if defined(ENABLE_SECURITY)
1477
    set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
1478
#endif
1479
#endif
1480
#ifdef LOCALIZATION
1481 1482 1483 1484 1485 1486 1487 1488 1489
    set_comp_log(LOCALIZE, LOG_DEBUG, LOG_LOW, 1);
    set_component_filelog(LOCALIZE);
#endif
    set_comp_log(ENB_APP, LOG_INFO, LOG_HIGH, 1);
    set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);

    if (online_log_messages == 1) {
      set_component_filelog(RRC);
      set_component_filelog(PDCP);
Raymond Knopp's avatar
 
Raymond Knopp committed
1490
    }
1491
  }
1492

Raymond Knopp's avatar
 
Raymond Knopp committed
1493 1494
  if (ouput_vcd) {
    if (UE_flag==1)
1495
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1496
    else
1497
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1498
  }
1499

1500
  if (opp_enabled ==1){
1501
    reset_opp_meas();
1502 1503
  }
  cpuf=get_cpu_freq_GHz();
1504

1505
#if defined(ENABLE_ITTI)
1506

Raymond Knopp's avatar
 
Raymond Knopp committed
1507 1508
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
1509
  } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1510 1511
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
1512

Raymond Knopp's avatar
 
Raymond Knopp committed
1513
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
1514
 
1515 1516
  // initialize mscgen log after ITTI
  MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
1517 1518
#endif
 
1519 1520
  if (opt_type != OPT_NONE) {
    radio_type_t radio_type;
1521

1522 1523
    if (frame_parms[0]->frame_type == FDD)
      radio_type = RADIO_TYPE_FDD;
1524
    else
1525
      radio_type = RADIO_TYPE_TDD;
1526

1527 1528 1529
    if (init_opt(in_path, in_ip, NULL, radio_type) == -1)
      LOG_E(OPT,"failed to run OPT \n");
  }
1530

1531
#ifdef PDCP_USE_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
1532
  netlink_init();
1533 1534 1535
#if defined(PDCP_USE_NETLINK_QUEUES)
  pdcp_netlink_init();
#endif
1536 1537
#endif

1538
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1539 1540 1541
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
1542
#endif
1543

1544

Raymond Knopp's avatar
 
Raymond Knopp committed
1545 1546 1547
  check_clock();

  // init the parameters
1548 1549
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

Raymond Knopp's avatar
Raymond Knopp committed
1550
    if (UE_flag==1) {
1551 1552
      frame_parms[CC_id]->nb_antennas_tx     = 1;
      frame_parms[CC_id]->nb_antennas_rx     = 1;
1553
      frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later
1554 1555
    }

1556 1557
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
1558 1559
    //   phy_init_top(frame_parms[CC_id]);
    phy_init_lte_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1560 1561 1562
  }


1563
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1564
    //init prach for openair1 test
Raymond Knopp's avatar
Raymond Knopp committed
1565

Raymond Knopp's avatar
 
Raymond Knopp committed
1566
    // prach_fmt = get_prach_fmt(frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, frame_parms->frame_type);
Raymond Knopp's avatar
 
Raymond Knopp committed
1567
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
1568
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1569 1570

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1571 1572 1573
    NB_UE_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
1574 1575
    PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**));
    PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
1576 1577

    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1578

1579
      PHY_vars_UE_g[0][CC_id] = init_lte_UE(frame_parms[CC_id], 0,abstraction_flag);
1580 1581
      UE[CC_id] = PHY_vars_UE_g[0][CC_id];
      printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]);
1582

1583 1584 1585 1586
      if (phy_test==1)
	UE[CC_id]->mac_enabled = 0;
      else 
	UE[CC_id]->mac_enabled = 1;
1587

1588
      if (UE[CC_id]->mac_enabled == 0) {  //set default UL parameters for testing mode
1589 1590 1591 1592 1593 1594 1595 1596 1597
	for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
	  UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
	  UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index  = beta_RI;
	  UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI;
	  
	  UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0;
	  UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3);
	  UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4;
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1598
      }
1599

1600
      UE[CC_id]->UE_scan = UE_scan;
1601
      UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
1602
      UE[CC_id]->mode    = mode;
Rohit Gupta's avatar
Rohit Gupta committed
1603
      printf("UE[%d]->mode = %d\n",CC_id,mode);
1604

1605 1606
      compute_prach_seq(&UE[CC_id]->frame_parms.prach_config_common,
                        UE[CC_id]->frame_parms.frame_type,
1607 1608
                        UE[CC_id]->X_u);

1609
      if (UE[CC_id]->mac_enabled == 1) 
1610
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1234;
1611
      else
1612
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1235;
1613

1614
      UE[CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0] + rx_gain_off;
1615
      UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626
      
      if (frame_parms[CC_id]->frame_type==FDD) {
	UE[CC_id]->N_TA_offset = 0;
      }
      else {
	if (frame_parms[CC_id]->N_RB_DL == 100)
	  UE[CC_id]->N_TA_offset = 624;
	else if (frame_parms[CC_id]->N_RB_DL == 50)
	  UE[CC_id]->N_TA_offset = 624/2;
	else if (frame_parms[CC_id]->N_RB_DL == 25)
	  UE[CC_id]->N_TA_offset = 624/4;
1627
      }
1628

Raymond Knopp's avatar
 
Raymond Knopp committed
1629
    }
1630

1631
    //  printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_poHwer,tx_max_power));
1632 1633 1634 1635 1636 1637
  } else {
    //this is eNB
    PHY_vars_eNB_g = malloc(sizeof(PHY_VARS_eNB**));
    PHY_vars_eNB_g[0] = malloc(sizeof(PHY_VARS_eNB*));

    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1638
      PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,node_function[CC_id],abstraction_flag);
1639 1640 1641 1642
      PHY_vars_eNB_g[0][CC_id]->ue_dl_rb_alloc=0x1fff;
      PHY_vars_eNB_g[0][CC_id]->target_ue_dl_mcs=target_dl_mcs;
      PHY_vars_eNB_g[0][CC_id]->ue_ul_nb_rb=6;
      PHY_vars_eNB_g[0][CC_id]->target_ue_ul_mcs=target_ul_mcs;
1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653
      // initialization for phy-test
      for (k=0;k<NUMBER_OF_UE_MAX;k++) {
	PHY_vars_eNB_g[0][CC_id]->transmission_mode[k] = transmission_mode;
	if (transmission_mode==7) 
	  lte_gold_ue_spec_port5(PHY_vars_eNB_g[0][CC_id]->lte_gold_uespec_port5_table[k],frame_parms[CC_id]->Nid_cell,0x1235+k);
      }
      if ((transmission_mode==1) || (transmission_mode==7)) {
	  for (j=0; j<frame_parms[CC_id]->nb_antennas_tx; j++) 
	    for (re=0; re<frame_parms[CC_id]->ofdm_symbol_size; re++) 
	      PHY_vars_eNB_g[0][CC_id]->common_vars.beam_weights[0][0][j][re] = 0x00007fff/frame_parms[CC_id]->nb_antennas_tx; 
      }
1654

1655 1656
      if (phy_test==1) PHY_vars_eNB_g[0][CC_id]->mac_enabled = 0;
      else PHY_vars_eNB_g[0][CC_id]->mac_enabled = 1;
1657
      
1658
      if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode
1659
	for (i=0; i<NUMBER_OF_UE_MAX; i++) {
1660 1661 1662 1663 1664 1665 1666
	    PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
	    PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index  = beta_RI;
	    PHY_vars_eNB_g[0][CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI;
	    
	    PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = i;
	    PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(i%3);
	    PHY_vars_eNB_g[0][CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4;
1667
	}
1668
      }
1669
      
1670
      compute_prach_seq(&PHY_vars_eNB_g[0][CC_id]->frame_parms.prach_config_common,
1671 1672 1673 1674
			PHY_vars_eNB_g[0][CC_id]->frame_parms.frame_type,
			PHY_vars_eNB_g[0][CC_id]->X_u);
    
      
1675
      PHY_vars_eNB_g[0][CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0];
1676

1677
      if (frame_parms[CC_id]->frame_type==FDD) {
1678
        PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0;
1679 1680
      }
      else {
1681 1682 1683 1684 1685 1686
        if (frame_parms[CC_id]->N_RB_DL == 100)
          PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624;
        else if (frame_parms[CC_id]->N_RB_DL == 50)
          PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/2;
        else if (frame_parms[CC_id]->N_RB_DL == 25)
          PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 624/4;
1687
      }
1688

1689
    }
1690
  
1691 1692 1693 1694

    NB_eNB_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
1695
  }
1696

1697 1698
  fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
  cpuf=get_cpu_freq_GHz();
1699

1700

Raymond Knopp's avatar
 
Raymond Knopp committed
1701
  dump_frame_parms(frame_parms[0]);
1702

Raymond Knopp's avatar
Raymond Knopp committed
1703
  init_openair0();
Raymond Knopp's avatar
Raymond Knopp committed
1704 1705


1706

laurent's avatar
laurent committed
1707
#ifndef DEADLINE_SCHEDULER
1708

1709
  /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */
1710 1711 1712 1713 1714
  
  cpu_set_t cpuset;
  int s;
  char cpu_affinity[1024];
  CPU_ZERO(&cpuset);
1715
#ifdef CPU_AFFINITY
1716
  if (get_nprocs() > 2)
1717
    {
1718 1719 1720 1721 1722 1723 1724 1725
      CPU_SET(0, &cpuset);
      s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
      if (s != 0)
	{
	  perror( "pthread_setaffinity_np");
	  exit_fun("Error setting processor affinity");
	}
      LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n");
1726
    }
1727
#endif
1728

1729 1730 1731
  /* Check the actual affinity mask assigned to the thread */
  s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
  if (s != 0)
1732 1733 1734 1735
    {
      perror( "pthread_getaffinity_np");
      exit_fun("Error getting processor affinity ");
    }
1736 1737
  memset(cpu_affinity, 0 , sizeof(cpu_affinity));
  for (int j = 0; j < CPU_SETSIZE; j++)
1738 1739 1740 1741 1742 1743 1744
    {
      if (CPU_ISSET(j, &cpuset))
	{  
	  char temp[1024];
	  sprintf(temp, " CPU_%d ", j);    
	  strcat(cpu_affinity, temp);
	}
1745
    }
1746
  LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity);
1747
#endif
1748
  
navid's avatar
navid committed
1749
  openair0_cfg[0].log_level = glog_level;
1750

1751
  
1752 1753


Raymond Knopp's avatar
 
Raymond Knopp committed
1754
  int eMBMS_active=0;
1755 1756
  if (node_function[0] <= NGFI_RAU_IF4p5) { // don't initialize L2 for RRU
    LOG_I(PHY,"Intializing L2\n");
Raymond Knopp's avatar
Raymond Knopp committed
1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767
    mac_xface = malloc(sizeof(MAC_xface));  
    l2_init(frame_parms[0],eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,
	    0,// cba_group_active
	    0); // HO flag
    mac_xface->macphy_exit = &exit_fun;
  }
  else if (node_function[0] == NGFI_RRU_IF4p5) { // Initialize PRACH in this case

  }


1768

winckel's avatar
winckel committed
1769
#if defined(ENABLE_ITTI)
1770

Raymond Knopp's avatar
Raymond Knopp committed
1771 1772 1773 1774 1775 1776 1777
  if ((UE_flag == 1)||
      (node_function[0]<NGFI_RAU_IF4p5))
    // don't create if node doesn't connect to RRC/S1/GTP
    if (create_tasks(UE_flag ? 0 : 1, UE_flag ? 1 : 0) < 0) {
      printf("cannot create ITTI tasks\n");
      exit(-1); // need a softer mode
    }
1778

Raymond Knopp's avatar
 
Raymond Knopp committed
1779
  printf("ITTI tasks created\n");
winckel's avatar
winckel committed
1780
#endif
Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
1781

1782 1783 1784 1785 1786
  if (phy_test==0) {
    if (UE_flag==1) {
      printf("Filling UE band info\n");
      fill_ue_band_info();
      mac_xface->dl_phy_sync_success (0, 0, 0, 1);
Raymond Knopp's avatar
Raymond Knopp committed
1787
    } else if (node_function[0]>NGFI_RRU_IF4p5)
1788 1789
      mac_xface->mrbch_phy_sync_failure (0, 0, 0);
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1790

1791

1792

Raymond Knopp's avatar
 
Raymond Knopp committed
1793
  mlockall(MCL_CURRENT | MCL_FUTURE);
1794

Raymond Knopp's avatar
 
Raymond Knopp committed
1795 1796
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
1797 1798

#ifdef XFORMS
1799 1800
  int UE_id;

Raymond Knopp's avatar
 
Raymond Knopp committed
1801 1802
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
1803 1804

    if (UE_flag==0) {
1805
      form_stats_l2 = create_form_stats_form();
1806 1807 1808
      fl_show_form (form_stats_l2->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "l2 stats");
      form_stats = create_form_stats_form();
      fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
1809 1810

      for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
	  form_enb[CC_id][UE_id] = create_lte_phy_scope_enb();
	  sprintf (title, "LTE UL SCOPE eNB for CC_id %d, UE %d",CC_id,UE_id);
	  fl_show_form (form_enb[CC_id][UE_id]->lte_phy_scope_enb, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);

	  if (otg_enabled) {
	    fl_set_button(form_enb[CC_id][UE_id]->button_0,1);
	    fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic ON");
	  } else {
	    fl_set_button(form_enb[CC_id][UE_id]->button_0,0);
	    fl_set_object_label(form_enb[CC_id][UE_id]->button_0,"DL Traffic OFF");
	  }
1823 1824
	} // CC_id
      } // UE_id
1825
    } else {
1826 1827 1828 1829 1830 1831 1832
      form_stats = create_form_stats_form();
      fl_show_form (form_stats->stats_form, FL_PLACE_HOTSPOT, FL_FULLBORDER, "stats");
      UE_id = 0;
      form_ue[UE_id] = create_lte_phy_scope_ue();
      sprintf (title, "LTE DL SCOPE UE");
      fl_show_form (form_ue[UE_id]->lte_phy_scope_ue, FL_PLACE_HOTSPOT, FL_FULLBORDER, title);

1833
      /*
1834
	if (openair_daq_vars.use_ia_receiver) {
1835 1836
        fl_set_button(form_ue[UE_id]->button_0,1);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
1837
	} else {
1838 1839
        fl_set_button(form_ue[UE_id]->button_0,0);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
1840
	}*/
1841 1842
      fl_set_button(form_ue[UE_id]->button_0,0);
      fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
Raymond Knopp's avatar
 
Raymond Knopp committed
1843 1844
    }

Raymond Knopp's avatar
 
Raymond Knopp committed
1845
    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
1846

1847 1848
    if (ret == 0)
      pthread_setname_np( forms_thread, "xforms" );
1849

Raymond Knopp's avatar
 
Raymond Knopp committed
1850 1851
    printf("Scope thread created, ret=%d\n",ret);
  }
1852

1853 1854
#endif

1855
  rt_sleep_ns(10*100000000ULL);
1856

Raymond Knopp's avatar
 
Raymond Knopp committed
1857

1858

Raymond Knopp's avatar
 
Raymond Knopp committed
1859 1860
  // start the main thread
  if (UE_flag == 1) {
1861 1862 1863 1864 1865 1866
    init_UE(1);
    number_of_cards = 1;
    
    for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
      PHY_vars_UE_g[0][CC_id]->rf_map.card=0;
      PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset;
Raymond Knopp's avatar
 
Raymond Knopp committed
1867
    }
1868
  }
Raymond Knopp's avatar
Raymond Knopp committed
1869
  else { 
1870
    printf("Initializing eNB threads\n");
1871
    init_eNB(node_function,node_timing,1,eth_params,single_thread_flag,wait_for_sync);
1872

Raymond Knopp's avatar
Raymond Knopp committed
1873 1874 1875 1876 1877
    number_of_cards = 1;
    
    for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
      PHY_vars_eNB_g[0][CC_id]->rf_map.card=0;
      PHY_vars_eNB_g[0][CC_id]->rf_map.chain=CC_id+chain_offset;
Raymond Knopp's avatar
 
Raymond Knopp committed
1878
    }
1879
  }
1880

1881 1882
  // connect the TX/RX buffers
  if (UE_flag==1) {
1883

1884
    for (CC_id=0;CC_id<MAX_NUM_CCs; CC_id++) {
1885

1886 1887 1888 1889 1890
    
#ifdef OAI_USRP
      UE[CC_id]->hw_timing_advance = timing_advance;
#else
      UE[CC_id]->hw_timing_advance = 160;
1891
#endif
1892 1893 1894 1895
    }
    if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) {
      printf("Error setting up eNB buffer\n");
      exit(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1896
    }
1897 1898 1899



1900 1901 1902 1903 1904 1905 1906 1907 1908 1909
    if (input_fd) {
      printf("Reading in from file to antenna buffer %d\n",0);
      if (fread(UE[0]->common_vars.rxdata[0],
	        sizeof(int32_t),
	        frame_parms[0]->samples_per_tti*10,
	        input_fd) != frame_parms[0]->samples_per_tti*10)
        printf("error reading from file\n");
    }
    //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
  } else {
1910

Raymond Knopp's avatar
 
Raymond Knopp committed
1911

1912

1913

1914

1915
    printf("Setting eNB buffer to all-RX\n");
navid's avatar
navid committed
1916

1917 1918 1919 1920 1921 1922 1923 1924
    // Set LSBs for antenna switch (ExpressMIMO)
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
      PHY_vars_eNB_g[0][CC_id]->hw_timing_advance = 0;
      for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
        for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
          PHY_vars_eNB_g[0][CC_id]->common_vars.txdata[0][aa][i] = 0x00010001;
    }
  }
1925
  sleep(3);
1926

1927

1928
  printf("Sending sync to all threads\n");
1929

Raymond Knopp's avatar
 
Raymond Knopp committed
1930
  pthread_mutex_lock(&sync_mutex);
1931
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1932 1933
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
1934

Raymond Knopp's avatar
 
Raymond Knopp committed
1935 1936 1937
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
1938 1939

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1940 1941
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
1942
  oai_exit=1;
1943
#else
1944

Raymond Knopp's avatar
 
Raymond Knopp committed
1945
  while (oai_exit==0)
1946
    rt_sleep_ns(100000000ULL);
1947

1948
#endif
1949

Raymond Knopp's avatar
 
Raymond Knopp committed
1950
  // stop threads
1951
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
1952
  printf("waiting for XFORMS thread\n");
1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966

  if (do_forms==1) {
    pthread_join(forms_thread,&status);
    fl_hide_form(form_stats->stats_form);
    fl_free_form(form_stats->stats_form);

    if (UE_flag==1) {
      fl_hide_form(form_ue[0]->lte_phy_scope_ue);
      fl_free_form(form_ue[0]->lte_phy_scope_ue);
    } else {
      fl_hide_form(form_stats_l2->stats_form);
      fl_free_form(form_stats_l2->stats_form);

      for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
1967 1968 1969 1970
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
	  fl_hide_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb);
	  fl_free_form(form_enb[CC_id][UE_id]->lte_phy_scope_enb);
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1971
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1972
    }
1973 1974
  }

1975 1976
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
1977
  printf("stopping MODEM threads\n");
1978

Raymond Knopp's avatar
 
Raymond Knopp committed
1979 1980
  // cleanup
  if (UE_flag == 1) {
1981
  } else {
1982
    stop_eNB(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1983
  }
1984

1985

Raymond Knopp's avatar
 
Raymond Knopp committed
1986 1987
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
1988

1989

Raymond Knopp's avatar
Raymond Knopp committed
1990
  // *** Handle per CC_id openair0
Raymond Knopp's avatar
Raymond Knopp committed
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001
  if (UE_flag==1) {
    if (PHY_vars_UE_g[0][0]->rfdevice.trx_end_func)
      PHY_vars_UE_g[0][0]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][0]->rfdevice);
  }
  else {
    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);  
    }
2002
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
2003
  if (ouput_vcd)
2004
    VCD_SIGNAL_DUMPER_CLOSE();
2005

2006
  if (opt_enabled == 1)
2007
    terminate_opt();
2008

Raymond Knopp's avatar
 
Raymond Knopp committed
2009
  logClean();
2010

Raymond Knopp's avatar
 
Raymond Knopp committed
2011 2012
  return 0;
}