lte-softmodem.c 61 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

Raymond Knopp's avatar
 
Raymond Knopp committed
28
*******************************************************************************/
29

30 31
/*! \file lte-enb.c
 * \brief Top-level threads for eNodeB
32
 * \author R. Knopp, F. Kaltenberger, Navid Nikaein
Raymond Knopp's avatar
 
Raymond 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
Raymond Knopp's avatar
 
Raymond Knopp committed
37 38 39
 * \note
 * \warning
 */
Raymond Knopp's avatar
 
Raymond Knopp committed
40
#define _GNU_SOURCE
41 42 43 44 45 46 47 48
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sched.h>
49
#include <linux/sched.h>
50 51 52
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>
53
#include <sys/sysinfo.h>
54
#include "rt_wrapper.h"
55

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

58
#include "assertions.h"
59
#include "msc.h"
60 61

#include "PHY/types.h"
62

63
#include "PHY/defs.h"
64
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
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

Raymond Knopp's avatar
 
Raymond Knopp committed
67 68
#include "../../ARCH/COMMON/common_lib.h"

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

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

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

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

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

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

122
// In lte-ue.c
123 124
extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
extern void fill_ue_band_info(void);
125 126
extern void init_UE(void);

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

137

138

139 140


Raymond Knopp's avatar
 
Raymond Knopp committed
141

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

146

147 148


149

150

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

155 156
uint16_t runtime_phy_rx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
uint16_t runtime_phy_tx[29][6]; // SISO [MCS 0-28][RBs 0-5 : 6, 15, 25, 50, 75, 100]
Raymond Knopp's avatar
 
Raymond Knopp committed
157

158

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

165

166

Raymond Knopp's avatar
 
Raymond Knopp committed
167

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

171
static char                     threequarter_fs=0;
172

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

176
openair0_rf_map rf_map[MAX_NUM_CCs];
177

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

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

187 188
FILE *input_fd=NULL;

189

190 191
#if MAX_NUM_CCs == 1
rx_gain_t                rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}};
kortke's avatar
kortke committed
192 193
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}};
194 195 196 197
#else
rx_gain_t                rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain},{max_gain,max_gain,max_gain,max_gain}};
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0},{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0},{20,0,0,0}};
Lionel Gauthier's avatar
Lionel Gauthier committed
198
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
199

200 201


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

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

207 208
char   rf_config_file[1024];

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

212

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
eNB_func_t node_function=eNodeB_3GPP;
229

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

Raymond Knopp's avatar
 
Raymond Knopp committed
236

237 238 239

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

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

Lionel Gauthier's avatar
 
Lionel Gauthier committed
259 260 261 262 263 264
# if defined(ENABLE_USE_MME)
int16_t           gtpu_log_level     = LOG_DEBUG;
int16_t           gtpu_log_verbosity = LOG_MED;
int16_t           udp_log_level      = LOG_DEBUG;
int16_t           udp_log_verbosity  = LOG_MED;
#endif
265 266 267
#if defined (ENABLE_SECURITY)
int16_t           osa_log_level      = LOG_INFO;
int16_t           osa_log_verbosity  = LOG_MED;
268
#endif
269

Raymond Knopp's avatar
 
Raymond Knopp committed
270 271 272

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

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

281 282
openair0_config_t openair0_cfg[MAX_CARDS];

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

286 287
double cpuf;

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


Raymond Knopp's avatar
 
Raymond Knopp committed
291

292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
/*---------------------BMC: timespec helpers -----------------------------*/

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

struct timespec clock_difftime(struct timespec start, struct timespec end)
{
    struct timespec temp;
    if ((end.tv_nsec-start.tv_nsec)<0) {
        temp.tv_sec = end.tv_sec-start.tv_sec-1;
	temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
    } else {
        temp.tv_sec = end.tv_sec-start.tv_sec;
	temp.tv_nsec = end.tv_nsec-start.tv_nsec;
    }
    return temp;
}

Cedric Roux's avatar
Cedric Roux committed
310
void print_difftimes(void)
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
{
#ifdef DEBUG
    printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
#else
    LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
#endif
}

void update_difftimes(struct timespec start, struct timespec end)
{
    struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
    int             changed = 0;
    diff_time = clock_difftime(start, end);
    if ((min_diff_time.tv_nsec == 0) || (diff_time.tv_nsec < min_diff_time.tv_nsec)) { min_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
    if ((max_diff_time.tv_nsec == 0) || (diff_time.tv_nsec > max_diff_time.tv_nsec)) { max_diff_time.tv_nsec = diff_time.tv_nsec; changed = 1; }
#if 1
    if (changed) print_difftimes();
#endif
}

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

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

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

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

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

void help (void) {
  printf (KGRN "Usage:\n");
  printf("  sudo -E lte-softmodem [options]\n");
  printf("  sudo -E ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.openEPC.conf -S -V -m 26 -t 16 -x 1 --ulsch-max-errors 100 -W\n\n");
  printf("Options:\n");
373
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
374 375 376 377
  printf("  --ulsch-max-errors set the max ULSCH erros\n");
  printf("  --calib-ue-rx set UE RX calibration\n");
  printf("  --calib-ue-rx-med \n");
  printf("  --calib-ue-rxbyp\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
378 379
  printf("  --debug-ue-prach run normal prach power ramping, but don't continue random-access\n");
  printf("  --calib-prach-tx run normal prach with maximum power, but don't continue random-access\n");
380
  printf("  --no-L2-connect bypass L2 and upper layers\n");
381 382 383 384
  printf("  --ue-rxgain set UE RX gain\n");
  printf("  --ue-txgain set UE TX gain\n");
  printf("  --ue-scan_carrier set UE to scan around carrier\n");
  printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
385 386 387
  printf("  --RCC run using NGFI RCC node function\n");
  printf("  --RRU run using NGFI RRU node function\n");
  printf("  --eNB run using 3GPP eNB node function\n");   
388
  printf("  -C Set the downlink frequency for all component carriers\n");
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 405
  printf("  -U Set the lte softmodem as a UE\n");
  printf("  -W Enable L2 wireshark messages on localhost \n");
  printf("  -V Enable VCD (generated file will be located atopenair_dump_eNB.vcd, read it with target/RT/USER/eNB.gtkw\n");
  printf("  -x Set the transmission mode, valid options: 1 \n"RESET);    
406

407
}
408

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

  oai_exit = 1;

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

}

424

425
#ifdef XFORMS
426

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

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    for (k=0; k<8; k++) { //harq_processes
434 435 436 437
      for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) {
        phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0;
        phy_vars_eNB->UE_stats[i].dlsch_ACK[k][j]=0;
        phy_vars_eNB->UE_stats[i].dlsch_trials[k][j]=0;
438
      }
439

440 441 442
      phy_vars_eNB->UE_stats[i].dlsch_l2_errors[k]=0;
      phy_vars_eNB->UE_stats[i].ulsch_errors[k]=0;
      phy_vars_eNB->UE_stats[i].ulsch_consecutive_errors=0;
443

444 445 446 447 448
      for (j=0; j<phy_vars_eNB->ulsch[i]->Mlimit; j++) {
        phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts[k][j]=0;
        phy_vars_eNB->UE_stats[i].ulsch_decoding_attempts_last[k][j]=0;
        phy_vars_eNB->UE_stats[i].ulsch_round_errors[k][j]=0;
        phy_vars_eNB->UE_stats[i].ulsch_round_fer[k][j]=0;
449
      }
450
    }
451

452 453 454
    phy_vars_eNB->UE_stats[i].dlsch_sliding_cnt=0;
    phy_vars_eNB->UE_stats[i].dlsch_NAK_round0=0;
    phy_vars_eNB->UE_stats[i].dlsch_mcs_offset=0;
455 456 457
  }
}

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

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

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

474
# ifdef ENABLE_XFORMS_WRITE_STATS
475 476

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

481
#endif
482

Raymond Knopp's avatar
 
Raymond Knopp committed
483 484
  while (!oai_exit) {
    if (UE_flag==1) {
Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
485
      len = dump_ue_stats (PHY_vars_UE_g[0][0], stats_buffer, 0, mode,rx_input_level_dBm);
knopp's avatar
knopp committed
486 487 488
      //fl_set_object_label(form_stats->stats_text, stats_buffer);
      fl_clear_browser(form_stats->stats_text);
      fl_add_browser_line(form_stats->stats_text, stats_buffer);
489

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

Raymond Knopp's avatar
 
Raymond Knopp committed
495
    } else {
496 497 498 499 500 501
      if (PHY_vars_eNB_g[0][0]->mac_enabled==1) {
	len = dump_eNB_l2_stats (stats_buffer, 0);
	//fl_set_object_label(form_stats_l2->stats_text, stats_buffer);
	fl_clear_browser(form_stats_l2->stats_text);
	fl_add_browser_line(form_stats_l2->stats_text, stats_buffer);
      }
Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
502
      len = dump_eNB_stats (PHY_vars_eNB_g[0][0], stats_buffer, 0);
503

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

507 508 509
      //fl_set_object_label(form_stats->stats_text, stats_buffer);
      fl_clear_browser(form_stats->stats_text);
      fl_add_browser_line(form_stats->stats_text, stats_buffer);
510

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

523
    }
524

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

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

532
# ifdef ENABLE_XFORMS_WRITE_STATS
533

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

548
# endif
549

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

554

555

556

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
565

Raymond Knopp's avatar
 
Raymond Knopp committed
566 567
  if (UE_flag == 0) {
    /* Wait for the initialize message */
568
    printf("Wait for the ITTI initialize message\n");
569 570 571 572 573
    do {
      if (message_p != NULL) {
        result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
        AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
574

575
      itti_receive_msg (TASK_L2L1, &message_p);
576

577 578 579 580 581 582
      switch (ITTI_MSG_ID(message_p)) {
      case INITIALIZE_MESSAGE:
        /* Start eNB thread */
        LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p));
        start_eNB = 1;
        break;
583

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

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

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

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

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

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

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

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

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

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

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

635

636

637 638


639

640

Raymond Knopp's avatar
 
Raymond Knopp committed
641

Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
642

643 644
static void get_options (int argc, char **argv)
{
645 646 647
  int c;
  //  char                          line[1000];
  //  int                           l;
648
  int k,i;//,j,k;
649
#if defined(OAI_USRP) || defined(CPRIGW)
650
  int clock_src;
651
#endif
652
  int CC_id;
653 654


655 656

  const Enb_properties_array_t *enb_properties;
657

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

680
  static const struct option long_options[] = {
681
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
682 683 684 685 686 687
    {"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
688 689 690 691
    {"calib-prach-tx",   no_argument,        NULL, LONG_OPTION_CALIB_PRACH_TX},
    {"ue-rxgain",   required_argument,  NULL, LONG_OPTION_RXGAIN},
    {"ue-txgain",   required_argument,  NULL, LONG_OPTION_TXGAIN},
    {"ue-scan-carrier",   no_argument,  NULL, LONG_OPTION_SCANCARRIER},
692
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
693 694
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
695
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
696 697 698
    {"RCC", no_argument, NULL, LONG_OPTION_RCC},
    {"RRU", no_argument, NULL, LONG_OPTION_RRU},
    {"eNB", no_argument, NULL, LONG_OPTION_ENB},
699 700 701
    {NULL, 0, NULL, 0}
  };

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

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

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

737 738 739 740 741
    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;
742

743 744 745
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
746

747 748 749
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
750

Raymond Knopp's avatar
 
Raymond Knopp committed
751 752 753 754
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
      break;

755
    case LONG_OPTION_RXGAIN:
756 757
      for (i=0; i<4; i++)
        rx_gain[0][i] = atof(optarg);
758

759
      break;
760

761 762 763
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
764

765
      break;
766

767 768 769 770 771
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

772 773 774 775 776 777
    case LONG_OPTION_LOOPMEMORY:
      mode=loop_through_memory;
      input_fd = fopen(optarg,"r");
      AssertFatal(input_fd != NULL,"Please provide an input file\n");
      break;

778 779 780 781
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
782 783 784
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
785 786 787 788 789 790 791 792 793 794 795 796

    case LONG_OPTION_RCC:
      node_function = NGFI_RCC_IF4;
      break;

    case LONG_OPTION_RRU:
      node_function = NGFI_RRU_IF4;
      break;

    case LONG_OPTION_ENB:
      node_function = eNodeB_3GPP;
      break;
797
      
798 799 800 801
    case 'A':
      timing_advance = atoi (optarg);
      break;

802
    case 'C':
803 804 805 806 807 808
      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]);
809
      }
810

811
      UE_scan=0;
812

813
      break;
814

Florian Kaltenberger's avatar
Florian Kaltenberger committed
815 816 817 818
    case 'a':
      chain_offset = atoi(optarg);
      break;

819 820 821 822
    case 'd':
#ifdef XFORMS
      do_forms=1;
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
823
#endif
824
      break;
825 826 827 828
      
    case 'E':
      threequarter_fs=1;
      break;
829

830 831 832
    case 'K':
#if defined(ENABLE_ITTI)
      itti_dump_file = strdup(optarg);
833
#else
834
      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
835
#endif
836
      break;
837

838 839 840
    case 'O':
      conf_config_file_name = optarg;
      break;
841

842 843 844
    case 'U':
      UE_flag = 1;
      break;
845

846 847 848
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
849

850 851 852
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
853

854 855 856 857 858 859 860
    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");
      /*
861 862 863
      if (optarg == NULL){
      in_ip[0] =NULL;
      printf("Enabling OPT for wireshark for local interface");
864
      } else {
865 866 867
      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);
868 869 870
      }
      */
      break;
871

872
    case 'P':
873 874
      opt_type = OPT_PCAP;
      opt_enabled=1;
875 876 877 878 879

      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");
880
      } else {
881 882 883
        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);
884
      }
885 886 887

      break;

Raymond Knopp's avatar
 
Raymond Knopp committed
888 889 890
    case 'V':
      ouput_vcd = 1;
      break;
891

Raymond Knopp's avatar
 
Raymond Knopp committed
892
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
893 894
      opp_enabled = 1;
      break;
895

Raymond Knopp's avatar
 
Raymond Knopp committed
896 897 898
    case  'R' :
      online_log_messages =1;
      break;
899

Raymond Knopp's avatar
 
Raymond Knopp committed
900
    case 'r':
901
      UE_scan = 0;
902

903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
      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
929
      }
930

931
      break;
932

Raymond Knopp's avatar
 
Raymond Knopp committed
933
    case 's':
934
#if defined(OAI_USRP) || defined(CPRIGW)
Raymond Knopp's avatar
 
Raymond Knopp committed
935 936

      clock_src = atoi(optarg);
937

Raymond Knopp's avatar
 
Raymond Knopp committed
938
      if (clock_src == 0) {
939 940 941 942 943
        //  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
944
      }
945

Raymond Knopp's avatar
 
Raymond Knopp committed
946 947 948 949
#else
      printf("Note: -s not defined for ExpressMIMO2\n");
#endif
      break;
950

951 952 953 954
    case 'S':
      exit_missed_slots=0;
      printf("Skip exit for missed slots\n");
      break;
955

956
    case 'g':
Raymond Knopp's avatar
 
Raymond Knopp committed
957
      glog_level=atoi(optarg); // value between 1 - 9
958
      break;
959 960 961

    case 'F':
      break;
962

963 964 965
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
966

967 968
    case 'x':
      transmission_mode = atoi(optarg);
969

970 971
      if (transmission_mode > 7) {
        printf("Transmission mode %d not supported for the moment\n",transmission_mode);
972
        exit(-1);
973
      }
974
      break;
975

976 977 978
    case 'T':
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
	frame_parms[CC_id]->frame_type = TDD;
979
      break;
980

981 982 983 984
    case 'h':
      help ();
      exit (-1);
       
Raymond Knopp's avatar
 
Raymond Knopp committed
985
    default:
986 987
      help ();
      exit (-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
988
      break;
989 990
    }
  }
991

Raymond Knopp's avatar
 
Raymond Knopp committed
992 993
  if (UE_flag == 0)
    AssertFatal(conf_config_file_name != NULL,"Please provide a configuration file\n");
994 995


Raymond Knopp's avatar
 
Raymond Knopp committed
996
  if ((UE_flag == 0) && (conf_config_file_name != NULL)) {
997
    int i,j;
998

Raymond Knopp's avatar
 
Raymond Knopp committed
999
    NB_eNB_INST = 1;
1000

Raymond Knopp's avatar
 
Raymond Knopp committed
1001 1002
    /* Read eNB configuration file */
    enb_properties = enb_config_init(conf_config_file_name);
1003

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1008
    /* Update some simulation parameters */
1009
    for (i=0; i < enb_properties->number; i++) {
1010
      AssertFatal (MAX_NUM_CCs == enb_properties->properties[i]->nb_cc,
1011 1012
                   "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);
1013 1014
      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));
1015

1016
      for (j=0; j<enb_properties->properties[i]->nb_rrh_gw; j++) {
1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
        	
        if (enb_properties->properties[i]->rrh_gw_config[j].active == 1 ) {
          local_remote_radio = BBU_REMOTE_RADIO_HEAD;
          (eth_params+j)->local_if_name             = enb_properties->properties[i]->rrh_gw_if_name;
          (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;
          (eth_params+j)->transp_preference         = enb_properties->properties[i]->rrh_gw_config[j].raw;	 
          (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; 
        }
1045 1046 1047
	
      }

1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
        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];
        frame_parms[CC_id]->nb_antennas_tx_eNB  =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
        frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
        //} // j
Raymond Knopp's avatar
 
Raymond Knopp committed
1062 1063
      }

1064

1065 1066 1067
      init_all_otg(0);
      g_otg->seed = 0;
      init_seeds(g_otg->seed);
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077

      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");
1078
      }
1079

1080
      init_predef_traffic(enb_properties->properties[i]->num_otg_elements, 1);
1081 1082


1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
      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
1097 1098 1099 1100 1101 1102
# 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
1103 1104 1105
#if defined (ENABLE_SECURITY)
      osa_log_level                  = enb_properties->properties[i]->osa_log_level;
      osa_log_verbosity              = enb_properties->properties[i]->osa_log_verbosity;
1106
#endif
1107

Raymond Knopp's avatar
 
Raymond Knopp committed
1108
      // adjust the log
1109
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119
        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]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1120
      } // CC_id
1121
    }// i
1122 1123 1124 1125 1126 1127 1128 1129
  } 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
1130
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1131
}
1132

1133 1134
int main( int argc, char **argv )
{
1135
  int i,aa,card=0;
1136
#if defined (XFORMS)
Raymond Knopp's avatar
 
Raymond Knopp committed
1137
  void *status;
1138
#endif
1139

Raymond Knopp's avatar
 
Raymond Knopp committed
1140
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1141
  uint16_t Nid_cell = 0;
1142
  uint8_t  cooperation_flag=0,  abstraction_flag=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1143
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
1144

Raymond Knopp's avatar
 
Raymond Knopp committed
1145
#if defined (XFORMS)
1146 1147
  int ret;
#endif
1148

1149 1150 1151 1152 1153
#ifdef DEBUG_CONSOLE
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);
#endif

1154 1155 1156
  PHY_VARS_UE *UE[MAX_NUM_CCs];

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

1159
  memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
Raymond Knopp's avatar
 
Raymond Knopp committed
1160
  set_latency_target();
1161

1162
  // det defaults
1163
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1164 1165
    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 */
1166
    frame_parms[CC_id]->frame_type          = FDD;
Raymond Knopp's avatar
 
Raymond Knopp committed
1167 1168
    frame_parms[CC_id]->tdd_config          = 3;
    frame_parms[CC_id]->tdd_config_S        = 0;
1169 1170
    frame_parms[CC_id]->N_RB_DL             = 100;
    frame_parms[CC_id]->N_RB_UL             = 100;
Raymond Knopp's avatar
 
Raymond Knopp committed
1171
    frame_parms[CC_id]->Ncp                 = NORMAL;
Raymond Knopp's avatar
 
Raymond Knopp committed
1172 1173
    frame_parms[CC_id]->Ncp_UL              = NORMAL;
    frame_parms[CC_id]->Nid_cell            = Nid_cell;
Raymond Knopp's avatar
 
Raymond Knopp committed
1174
    frame_parms[CC_id]->num_MBSFN_config    = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1175 1176 1177
    frame_parms[CC_id]->nb_antennas_tx_eNB  = 1;
    frame_parms[CC_id]->nb_antennas_tx      = 1;
    frame_parms[CC_id]->nb_antennas_rx      = 1;
Raymond Knopp's avatar
 
Raymond Knopp committed
1178
  }
1179

1180 1181 1182 1183 1184
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    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];
1185
    //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
1186
  }
1187 1188
  logInit();
 
1189
  rf_config_file[0]='\0';
1190
  get_options (argc, argv); //Command-line options
1191 1192 1193 1194
  if (rf_config_file[0] == '\0')
    openair0_cfg[0].configFilename = NULL;
  else
    openair0_cfg[0].configFilename = rf_config_file;
1195 1196
  
  // initialize the log (see log.h for details)
1197 1198
  set_glog(glog_level, glog_verbosity);

1199 1200
  //randominit (0);
  set_taus_seed (0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1201

1202 1203
  if (UE_flag==1) {
    printf("configuring for UE\n");
1204

1205 1206
    set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
    set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
1207 1208 1209 1210 1211
    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);
1212
#if defined(ENABLE_ITTI)
1213
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1214
# if defined(ENABLE_USE_MME)
1215
    set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
1216 1217
# endif
#endif
1218 1219
  } else {
    printf("configuring for eNB\n");
1220

1221 1222 1223 1224 1225 1226 1227 1228
    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);
1229
#if defined(ENABLE_ITTI)
1230
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1231
# if defined(ENABLE_USE_MME)
1232 1233 1234 1235
    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);
1236
# endif
1237
#if defined(ENABLE_SECURITY)
1238
    set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
1239
#endif
1240
#endif
1241
#ifdef LOCALIZATION
1242 1243 1244 1245 1246 1247 1248 1249 1250
    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
1251
    }
1252
  }
1253

Raymond Knopp's avatar
 
Raymond Knopp committed
1254 1255
  if (ouput_vcd) {
    if (UE_flag==1)
1256
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1257
    else
1258
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1259
  }
1260

1261
  if (opp_enabled ==1){
1262
    reset_opp_meas();
1263 1264
  }
  cpuf=get_cpu_freq_GHz();
1265

1266
#if defined(ENABLE_ITTI)
1267

Raymond Knopp's avatar
 
Raymond Knopp committed
1268 1269
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
1270
  } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1271 1272
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
1273

Raymond Knopp's avatar
 
Raymond Knopp committed
1274
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
1275
 
1276 1277
  // initialize mscgen log after ITTI
  MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
1278 1279
#endif
 
1280 1281
  if (opt_type != OPT_NONE) {
    radio_type_t radio_type;
1282

1283 1284
    if (frame_parms[0]->frame_type == FDD)
      radio_type = RADIO_TYPE_FDD;
1285
    else
1286
      radio_type = RADIO_TYPE_TDD;
1287

1288 1289 1290
    if (init_opt(in_path, in_ip, NULL, radio_type) == -1)
      LOG_E(OPT,"failed to run OPT \n");
  }
1291

1292
#ifdef PDCP_USE_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
1293
  netlink_init();
1294 1295 1296
#if defined(PDCP_USE_NETLINK_QUEUES)
  pdcp_netlink_init();
#endif
1297 1298
#endif

1299
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1300 1301 1302
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
1303
#endif
1304

1305

Raymond Knopp's avatar
 
Raymond Knopp committed
1306 1307 1308
  check_clock();

  // init the parameters
1309
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1310
    frame_parms[CC_id]->nushift            = 0;
1311

1312 1313 1314 1315 1316 1317 1318 1319 1320
    if (UE_flag==0) {

    } else {
      //UE_flag==1
      frame_parms[CC_id]->nb_antennas_tx     = 1;
      frame_parms[CC_id]->nb_antennas_rx     = 1;
      frame_parms[CC_id]->nb_antennas_tx_eNB = (transmission_mode == 1) ? 1 : 2; //initial value overwritten by initial sync later
    }

Raymond Knopp's avatar
 
Raymond Knopp committed
1321 1322 1323 1324 1325 1326 1327 1328
    frame_parms[CC_id]->mode1_flag         = (transmission_mode == 1) ? 1 : 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;
1329
    frame_parms[CC_id]->threequarter_fs = threequarter_fs;
1330 1331
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
1332 1333
    //   phy_init_top(frame_parms[CC_id]);
    phy_init_lte_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1334 1335 1336
  }


1337
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1338
    //init prach for openair1 test
1339
    frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
Raymond Knopp's avatar
 
Raymond Knopp committed
1340
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
1341
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1342 1343 1344
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;
    // 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
1345
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
1346
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1347 1348

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1349 1350 1351
    NB_UE_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
1352 1353
    PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**));
    PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
1354 1355

    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1356 1357 1358 1359

      PHY_vars_UE_g[0][CC_id] = init_lte_UE(frame_parms[CC_id], 0,abstraction_flag,transmission_mode);
      UE[CC_id] = PHY_vars_UE_g[0][CC_id];
      printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]);
1360

1361 1362 1363 1364
      if (phy_test==1)
	UE[CC_id]->mac_enabled = 0;
      else 
	UE[CC_id]->mac_enabled = 1;
1365

1366
      if (UE[CC_id]->mac_enabled == 0) {  //set default UL parameters for testing mode
1367 1368 1369 1370 1371 1372 1373 1374 1375
	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
1376
      }
1377

1378
      UE[CC_id]->UE_scan = UE_scan;
1379
      UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
1380 1381
      UE[CC_id]->mode    = mode;

1382 1383
      compute_prach_seq(&UE[CC_id]->frame_parms.prach_config_common,
                        UE[CC_id]->frame_parms.frame_type,
1384 1385
                        UE[CC_id]->X_u);

1386
      if (UE[CC_id]->mac_enabled == 1) 
1387
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1234;
1388
      else
1389
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1235;
1390 1391

      UE[CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0];
1392 1393
      UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
      UE[CC_id]->N_TA_offset = 0;
1394

Raymond Knopp's avatar
 
Raymond Knopp committed
1395
    }
1396

Raymond Knopp's avatar
 
Raymond Knopp committed
1397
    //  printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_power,tx_max_power));
1398 1399 1400 1401 1402 1403
  } 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++) {
1404
      PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,cooperation_flag,transmission_mode,abstraction_flag);
1405 1406
      PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;

1407 1408
      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;
1409

1410
      if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode
1411 1412 1413 1414 1415 1416 1417 1418 1419
	for (i=0; i<NUMBER_OF_UE_MAX; i++) {
	  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;
	}
1420 1421
      }

1422 1423
      compute_prach_seq(&PHY_vars_eNB_g[0][CC_id]->frame_parms.prach_config_common,
                        PHY_vars_eNB_g[0][CC_id]->frame_parms.frame_type,
1424
                        PHY_vars_eNB_g[0][CC_id]->X_u);
Raymond Knopp's avatar
 
Raymond Knopp committed
1425

1426
      PHY_vars_eNB_g[0][CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0];
Raymond Knopp's avatar
 
Raymond Knopp committed
1427

1428
      PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0;
1429

1430
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1431 1432


1433 1434 1435 1436
    NB_eNB_INST=1;
    NB_INST=1;

  }
1437

1438 1439
  fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
  cpuf=get_cpu_freq_GHz();
1440

1441

Raymond Knopp's avatar
 
Raymond Knopp committed
1442
  dump_frame_parms(frame_parms[0]);
1443

1444 1445 1446
  for (card=0; card<MAX_CARDS; card++) {

    if(frame_parms[0]->N_RB_DL == 100) {
1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458
      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;
      }
1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474
    } 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;
    }
1475 1476 1477 1478 1479 1480

    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;

1481
    
1482 1483 1484 1485 1486
    if (local_remote_radio == BBU_REMOTE_RADIO_HEAD) {      
      openair0_cfg[card].remote_addr    = eth_params->remote_addr;
      openair0_cfg[card].remote_port    = eth_params->remote_port;
      openair0_cfg[card].my_addr        = eth_params->my_addr;
      openair0_cfg[card].my_port        = eth_params->my_port;    
1487 1488 1489 1490 1491 1492 1493 1494
    } 
    
    //if (node_function == NGFI_RCC_IF4 || node_function == NGFI_RRU_IF4) {
      //openair0_cfg[card].remote_addr    = eth_params->remote_addr;
      //openair0_cfg[card].remote_port    = eth_params->remote_port;
      //openair0_cfg[card].my_addr        = eth_params->my_addr;
      //openair0_cfg[card].my_port        = eth_params->my_port;    
    //}
1495

1496
    printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
1497 1498
           ((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));
Raymond Knopp's avatar
 
Raymond Knopp committed
1499 1500
    openair0_cfg[card].Mod_id = 0;
#ifdef ETHERNET
1501 1502

    if (UE_flag) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1503
      printf("ETHERNET: Configuring UE ETH for %s:%d\n",rrh_UE_ip,rrh_UE_port);
1504
      openair0_cfg[card].remote_addr   = &rrh_UE_ip[0];
1505
      openair0_cfg[card].remote_port = rrh_UE_port;
1506 1507
    } 

1508
    openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
Raymond Knopp's avatar
 
Raymond Knopp committed
1509
#endif
1510

1511
    // in the case of the USRP, the following variables need to be initialized before the init
1512
    // since the USRP only supports one CC (for the moment), we initialize all the cards with first CC.
1513
    // in the case of EXMIMO2, these values are overwirtten in the function setup_eNB/UE_buffer
1514

1515 1516
    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));
1517 1518

    for (i=0; i<4; i++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1519

1520 1521 1522 1523 1524 1525 1526 1527
      openair0_cfg[card].tx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] : downlink_frequency[0][i]+uplink_frequency_offset[0][i];
      openair0_cfg[card].rx_freq[i] = (UE_flag==0) ? downlink_frequency[0][i] + uplink_frequency_offset[0][i] : downlink_frequency[0][i];
      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]);
      
1528
      openair0_cfg[card].autocal[i] = 1;
1529
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
1530
      if (UE_flag == 0) {
1531
	openair0_cfg[card].rx_gain[i] = PHY_vars_eNB_g[0][0]->rx_total_gain_dB;
1532 1533
      }
      else {
1534
	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB;
1535
      }
1536 1537


Raymond Knopp's avatar
 
Raymond Knopp committed
1538
    }
1539

1540

Raymond Knopp's avatar
 
Raymond Knopp committed
1541
  }
1542 1543

#ifndef LOWLATENCY
1544

1545
  /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */
1546 1547 1548 1549 1550 1551
  
  cpu_set_t cpuset;
  int s;
  char cpu_affinity[1024];
  CPU_ZERO(&cpuset);
  #ifdef CPU_AFFINITY
1552
  if (get_nprocs() > 2)
1553
  {
1554 1555 1556 1557 1558 1559 1560
    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");
    }
1561 1562 1563
    LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n");
  }
  #endif
1564

1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579
  /* Check the actual affinity mask assigned to the thread */
  s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
  if (s != 0)
  {
    perror( "pthread_getaffinity_np");
    exit_fun("Error getting processor affinity ");
  }
  memset(cpu_affinity, 0 , sizeof(cpu_affinity));
  for (int j = 0; j < CPU_SETSIZE; j++)
  {
    if (CPU_ISSET(j, &cpuset))
    {  
      char temp[1024];
      sprintf(temp, " CPU_%d ", j);    
      strcat(cpu_affinity, temp);
1580 1581
    }
  }
1582
  LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity);
1583
#endif
1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596
  
  openair0_cfg[0].log_level = glog_level;
  
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = BBU_HOST;
    PHY_vars_eNB_g[0][CC_id]->rfdevice.type = NONE_DEV;
    PHY_vars_eNB_g[0][CC_id]->rfdevice.transp_type = NONE_TP;
       
    PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = BBU_HOST;
    PHY_vars_eNB_g[0][CC_id]->ifdevice.type = NONE_DEV;
    PHY_vars_eNB_g[0][CC_id]->ifdevice.transp_type = NONE_TP;
  }
  
1597
  /* device host type is set*/
1598
  openair0.host_type = BBU_HOST;
1599
  /* device type is initialized NONE_DEV (no RF device) when the RF device will be initiated device type will be set */
1600
  openair0.type = NONE_DEV;
1601
  /* transport type is initialized NONE_TP (no transport protocol) when the transport protocol will be initiated transport protocol type will be set */
1602
  openair0.transp_type = NONE_TP;
1603
  //openair0_cfg[0].log_level = glog_level;
1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633
  
  // Legacy BBU - RRH init  
  //int returns=-1;
  ///* BBU can have either a local or a remote radio head */  
  //if (local_remote_radio == BBU_LOCAL_RADIO_HEAD) { //local radio head active  - load library of radio head and initiate it
    //if (mode!=loop_through_memory) {
      //returns=openair0_device_load(&openair0, &openair0_cfg[0]);
      //printf("openair0_device_init returns %d\n",returns);
      //if (returns<0) {
	//printf("Exiting, cannot initialize device\n");
	//exit(-1);
      //}
    //}
    //else if (mode==loop_through_memory) {    
    //}
  //}  else { //remote radio head active - load library of transport protocol and initiate it 
    //if (mode!=loop_through_memory) {
      //returns=openair0_transport_load(&openair0, &openair0_cfg[0], eth_params);
      //printf("openair0_transport_init returns %d\n",returns);
      //if (returns<0) { 
	//printf("Exiting, cannot initialize transport protocol\n");
	//exit(-1);
      //}
    //}
    //else if (mode==loop_through_memory) {    
    //}
  //}   
  
  //printf("Done\n");
  
1634
  int returns=-1;
1635 1636
    
  // Handle spatially distributed MIMO antenna ports   
1637
  // Load RF device and initialize
1638
  if (node_function != NGFI_RCC_IF4) { 
1639 1640 1641 1642 1643 1644 1645 1646
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {  
      if (mode!=loop_through_memory) {
        returns=openair0_device_load(&(PHY_vars_eNB_g[0][CC_id]->rfdevice), &openair0_cfg[0]);
        printf("openair0_device_init returns %d for CC_id %d\n",returns,CC_id);
        if (returns<0) {
	        printf("Exiting, cannot initialize device\n");
	        exit(-1);
        }
1647
      }
1648 1649
      else if (mode==loop_through_memory) {    
      }    
1650
    }
1651 1652 1653
  }  
  
  // Load transport protocol and initialize
1654
  if (node_function != eNodeB_3GPP){ 
1655 1656 1657 1658 1659 1660 1661 1662
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {  
      if (mode!=loop_through_memory) {
        returns=openair0_transport_load(&(PHY_vars_eNB_g[0][CC_id]->ifdevice), &openair0_cfg[0], (eth_params+CC_id));
        printf("openair0_transport_init returns %d for CC_id %d\n",returns,CC_id);
        if (returns<0) {
	        printf("Exiting, cannot initialize transport protocol\n");
	        exit(-1);
        }
1663
      }
1664 1665
      else if (mode==loop_through_memory) {    
      }    
1666
    }
1667
  }
1668

1669
  printf("Done initializing RF and IF devices\n");
1670
  
1671 1672
  mac_xface = malloc(sizeof(MAC_xface));

Raymond Knopp's avatar
 
Raymond Knopp committed
1673
  int eMBMS_active=0;
1674
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1675
  l2_init(frame_parms[0],eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,
1676 1677 1678
	  0,// cba_group_active
	  0); // HO flag
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1679
  mac_xface->macphy_exit = &exit_fun;
1680

winckel's avatar
winckel committed
1681
#if defined(ENABLE_ITTI)
1682

Raymond Knopp's avatar
 
Raymond Knopp committed
1683
  if (create_tasks(UE_flag ? 0 : 1, UE_flag ? 1 : 0) < 0) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1684
    printf("cannot create ITTI tasks\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1685 1686
    exit(-1); // need a softer mode
  }
1687

Raymond Knopp's avatar
 
Raymond Knopp committed
1688
  printf("ITTI tasks created\n");
winckel's avatar
winckel committed
1689
#endif
Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
1690

1691 1692 1693 1694 1695 1696 1697 1698
  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);
    } else
      mac_xface->mrbch_phy_sync_failure (0, 0, 0);
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1699

1700
  number_of_cards = 1;
1701

1702

1703
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1704
    rf_map[CC_id].card=0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1705
    rf_map[CC_id].chain=CC_id+chain_offset;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1706
  }
1707

Raymond Knopp's avatar
 
Raymond Knopp committed
1708 1709
  // connect the TX/RX buffers
  if (UE_flag==1) {
1710 1711 1712 1713

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

    
1714
#ifdef OAI_USRP
1715
      UE[CC_id]->hw_timing_advance = timing_advance;
1716
#else
1717
      UE[CC_id]->hw_timing_advance = 160;
1718
#endif
1719
    }
1720
    if (setup_ue_buffers(UE,&openair0_cfg[0],rf_map)!=0) {
1721 1722 1723
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }
1724

1725
    printf("Setting UE buffer to all-RX\n");
1726

1727
    // Set LSBs for antenna switch (ExpressMIMO)
1728
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1729
      for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
1730
        for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
1731
          UE[CC_id]->common_vars.txdata[aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
1732
    }
1733

1734 1735
    if (input_fd) {
      printf("Reading in from file to antenna buffer %d\n",0);
1736
      if (fread(UE[0]->common_vars.rxdata[0],
1737 1738 1739 1740
	        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");
1741
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1742
    //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
1743
  } else {
1744 1745


1746

1747 1748 1749 1750
    if (setup_eNB_buffers(PHY_vars_eNB_g[0],&openair0_cfg[0],rf_map)!=0) {
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }
1751

1752
    printf("Setting eNB buffer to all-RX\n");
1753

1754
    // Set LSBs for antenna switch (ExpressMIMO)
1755
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1756
      PHY_vars_eNB_g[0][CC_id]->hw_timing_advance = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1757
      for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
1758
        for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
1759
          PHY_vars_eNB_g[0][CC_id]->common_vars.txdata[0][aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
1760
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1761
  }
1762

Raymond Knopp's avatar
 
Raymond Knopp committed
1763
  mlockall(MCL_CURRENT | MCL_FUTURE);
1764

Raymond Knopp's avatar
 
Raymond Knopp committed
1765 1766
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
1767 1768

#ifdef XFORMS
1769 1770
  int UE_id;

Raymond Knopp's avatar
 
Raymond Knopp committed
1771 1772
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
1773 1774

    if (UE_flag==0) {
1775
      form_stats_l2 = create_form_stats_form();
1776 1777 1778
      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");
1779 1780

      for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793
	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");
	  }
	}
1794
      }
1795
    } else {
1796 1797 1798 1799 1800 1801 1802
      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);

1803
      /*
Raymond Knopp's avatar
 
Raymond Knopp committed
1804
      if (openair_daq_vars.use_ia_receiver) {
1805 1806 1807 1808 1809
        fl_set_button(form_ue[UE_id]->button_0,1);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
      } else {
        fl_set_button(form_ue[UE_id]->button_0,0);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
1810 1811 1812
	}*/
        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
1813 1814
    }

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

1817 1818
    if (ret == 0)
      pthread_setname_np( forms_thread, "xforms" );
1819

Raymond Knopp's avatar
 
Raymond Knopp committed
1820 1821
    printf("Scope thread created, ret=%d\n",ret);
  }
1822

1823 1824
#endif

1825
  rt_sleep_ns(10*100000000ULL);
1826

1827

1828

1829

Raymond Knopp's avatar
 
Raymond Knopp committed
1830
  // start the main thread
1831
  if (UE_flag == 1) init_UE();
1832
  else init_eNB(node_function);
1833

Raymond Knopp's avatar
 
Raymond Knopp committed
1834
  // Sleep to allow all threads to setup
Raymond Knopp's avatar
 
Raymond Knopp committed
1835
  sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1836

1837

1838

1839

1840
// *** Handle per CC_id openair0
Raymond Knopp's avatar
 
Raymond Knopp committed
1841
#ifndef USRP_DEBUG
1842
  if ((UE_flag==1) && (mode!=loop_through_memory))
navid's avatar
navid committed
1843 1844 1845
    if (openair0.trx_start_func(&openair0) != 0 ) 
      LOG_E(HW,"Could not start the device\n");

Raymond Knopp's avatar
 
Raymond Knopp committed
1846
#endif
1847

1848

1849
  printf("Sending sync to all threads\n");
1850

Raymond Knopp's avatar
 
Raymond Knopp committed
1851
  pthread_mutex_lock(&sync_mutex);
1852
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1853 1854
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
1855

Raymond Knopp's avatar
 
Raymond Knopp committed
1856 1857 1858
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
1859 1860

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1861 1862
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
1863
  oai_exit=1;
1864
#else
1865

Raymond Knopp's avatar
 
Raymond Knopp committed
1866
  while (oai_exit==0)
1867
    rt_sleep_ns(100000000ULL);
1868

1869
#endif
1870

Raymond Knopp's avatar
 
Raymond Knopp committed
1871
  // stop threads
1872
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
1873
  printf("waiting for XFORMS thread\n");
1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887

  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++) {
1888 1889 1890 1891
	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
1892
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1893
    }
1894 1895
  }

1896 1897
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1900 1901
  // cleanup
  if (UE_flag == 1) {
1902
  } else {
1903
    stop_eNB();
Raymond Knopp's avatar
 
Raymond Knopp committed
1904
  }
1905

1906

Raymond Knopp's avatar
 
Raymond Knopp committed
1907 1908
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
1909

1910
  // *** Handle per CC_id openair0
navid's avatar
navid committed
1911
  openair0.trx_end_func(&openair0);
1912

Raymond Knopp's avatar
 
Raymond Knopp committed
1913
  if (ouput_vcd)
1914
    VCD_SIGNAL_DUMPER_CLOSE();
1915

1916
  if (opt_enabled == 1)
1917
    terminate_opt();
1918

Raymond Knopp's avatar
 
Raymond Knopp committed
1919
  logClean();
1920

Raymond Knopp's avatar
 
Raymond Knopp committed
1921 1922
  return 0;
}
1923 1924


1925

1926

1927 1928 1929