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

55 56
#include "T.h"

57
#include "rt_wrapper.h"
58

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

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

#include "PHY/types.h"
65

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

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

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

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

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

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

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

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

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

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

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

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

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

141

142

143 144


Raymond Knopp's avatar
 
Raymond Knopp committed
145

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

150

151 152


153

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

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

161

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

168

169

Raymond Knopp's avatar
 
Raymond Knopp committed
170

Raymond Knopp's avatar
Raymond Knopp committed
171
static char              UE_flag=0;
172
unsigned int                    mmapped_dma=0;
Raymond Knopp's avatar
Raymond Knopp committed
173
int                             single_thread_flag=0;
174

175
static char                     threequarter_fs=0;
176

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

180

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

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

190 191
FILE *input_fd=NULL;

192

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

203 204


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

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

210 211
char   rf_config_file[1024];

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

215

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

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

229

Raymond Knopp's avatar
 
Raymond Knopp committed
230
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
231 232 233
eNB_func_t node_function[MAX_NUM_CCs];
eNB_timing_t node_timing[MAX_NUM_CCs];
int16_t   node_synch_ref[MAX_NUM_CCs];
234

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

Raymond Knopp's avatar
 
Raymond Knopp committed
241

242 243
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
244
//int transmission_mode=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
245

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
274

275

Raymond Knopp's avatar
 
Raymond Knopp committed
276
char *rrh_UE_ip = "127.0.0.1";
277
int rrh_UE_port = 51000;
278

Raymond Knopp's avatar
 
Raymond Knopp committed
279

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

285 286 287 288
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

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


Raymond Knopp's avatar
 
Raymond Knopp committed
292

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

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

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

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

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

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

353 354 355 356
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
357 358
  } else {
    printf("trying to exit gracefully...\n");
359
    oai_exit = 1;
360 361
  }
}
362
#endif
363 364 365 366 367 368 369 370 371 372 373
#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");
374
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
375 376 377 378
  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
379 380
  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");
381
  printf("  --no-L2-connect bypass L2 and upper layers\n");
382 383 384 385
  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");
386 387
  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");  
  printf("  --single-thread runs lte-softmodem in only one thread\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 593 594 595 596
    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
597

598
      itti_receive_msg (TASK_L2L1, &message_p);
599

600 601 602 603 604 605
      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;
606

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

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

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

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

627 628 629 630 631
    switch (ITTI_MSG_ID(message_p)) {
    case TERMINATE_MESSAGE:
      oai_exit=1;
      itti_exit_task ();
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
632

633 634 635
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
636

637 638 639
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
640

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

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

650 651 652
    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);
653

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

658

659

660

661 662
static void get_options (int argc, char **argv)
{
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;
669
#endif
670
  int CC_id;
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 687
    LONG_OPTION_RXGAIN,
    LONG_OPTION_TXGAIN,
688
    LONG_OPTION_SCANCARRIER,
689 690
    LONG_OPTION_MAXPOWER,
    LONG_OPTION_DUMP_FRAME,
691
    LONG_OPTION_LOOPMEMORY,
692
    LONG_OPTION_PHYTEST,
Cedric Roux's avatar
Cedric Roux committed
693
    LONG_OPTION_MMAPPED_DMA,
Raymond Knopp's avatar
Raymond Knopp committed
694
    LONG_OPTION_SINGLE_THREAD,
695 696 697
#if T_TRACER
    LONG_OPTION_T_PORT,
    LONG_OPTION_T_NOWAIT,
Cedric Roux's avatar
Cedric Roux committed
698
    LONG_OPTION_T_DONT_FORK,
699
#endif
700
  };
701

702
  static const struct option long_options[] = {
703
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
704 705 706 707 708 709
    {"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
710 711 712 713
    {"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},
714
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
715 716
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
717
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
718
    {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
Raymond Knopp's avatar
Raymond Knopp committed
719
    {"single-thread", no_argument, NULL, LONG_OPTION_SINGLE_THREAD},
720 721 722
#if T_TRACER
    {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
    {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
Cedric Roux's avatar
Cedric Roux committed
723
    {"T_dont_fork",            no_argument,       0, LONG_OPTION_T_DONT_FORK},
724
#endif
725 726 727
    {NULL, 0, NULL, 0}
  };

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

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

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
777 778 779 780
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
      break;

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

785
      break;
786

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

791
      break;
792

793 794 795 796 797
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

798 799 800 801 802 803
    case LONG_OPTION_LOOPMEMORY:
      mode=loop_through_memory;
      input_fd = fopen(optarg,"r");
      AssertFatal(input_fd != NULL,"Please provide an input file\n");
      break;

804 805 806 807
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
808 809 810
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
811

812 813 814
    case LONG_OPTION_MMAPPED_DMA:
      mmapped_dma = 1;
      break;
Raymond Knopp's avatar
Raymond Knopp committed
815 816 817 818

    case LONG_OPTION_SINGLE_THREAD:
      single_thread_flag = 1;
      break;
819
              
820 821 822 823 824 825 826 827 828 829 830 831 832
#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;
    }
833 834 835 836 837 838

    case LONG_OPTION_T_DONT_FORK: {
      extern int T_dont_fork;
      T_dont_fork = 1;
      break;
    }
839 840
#endif

841 842 843 844
    case 'A':
      timing_advance = atoi (optarg);
      break;

845
    case 'C':
846 847 848 849 850 851
      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]);
852
      }
853

854
      UE_scan=0;
855

856
      break;
857

Florian Kaltenberger's avatar
Florian Kaltenberger committed
858 859 860 861
    case 'a':
      chain_offset = atoi(optarg);
      break;

862 863 864 865
    case 'd':
#ifdef XFORMS
      do_forms=1;
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
866
#endif
867
      break;
868 869 870 871
      
    case 'E':
      threequarter_fs=1;
      break;
872

873 874 875
    case 'K':
#if defined(ENABLE_ITTI)
      itti_dump_file = strdup(optarg);
876
#else
877
      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
878
#endif
879
      break;
880

881 882 883
    case 'O':
      conf_config_file_name = optarg;
      break;
884

885 886 887
    case 'U':
      UE_flag = 1;
      break;
888

889 890 891
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
892

893 894 895
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
896

897 898 899 900 901 902 903
    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");
      /*
904 905 906 907 908 909 910 911
	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);
	}
912 913
      */
      break;
914

915
    case 'P':
916 917
      opt_type = OPT_PCAP;
      opt_enabled=1;
918 919 920 921 922

      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");
923
      } else {
924 925 926
        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);
927
      }
928 929 930

      break;

Raymond Knopp's avatar
 
Raymond Knopp committed
931 932 933
    case 'V':
      ouput_vcd = 1;
      break;
934

Raymond Knopp's avatar
 
Raymond Knopp committed
935
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
936 937
      opp_enabled = 1;
      break;
938

Raymond Knopp's avatar
 
Raymond Knopp committed
939 940 941
    case  'R' :
      online_log_messages =1;
      break;
942

Raymond Knopp's avatar
 
Raymond Knopp committed
943
    case 'r':
944
      UE_scan = 0;
945

946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971
      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
972
      }
973

974
      break;
975

Raymond Knopp's avatar
 
Raymond Knopp committed
976
    case 's':
977
#if defined(OAI_USRP) || defined(CPRIGW)
Raymond Knopp's avatar
 
Raymond Knopp committed
978 979

      clock_src = atoi(optarg);
980

Raymond Knopp's avatar
 
Raymond Knopp committed
981
      if (clock_src == 0) {
982 983 984 985 986
        //  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
987
      }
988

Raymond Knopp's avatar
 
Raymond Knopp committed
989 990 991 992
#else
      printf("Note: -s not defined for ExpressMIMO2\n");
#endif
      break;
993

994 995 996 997
    case 'S':
      exit_missed_slots=0;
      printf("Skip exit for missed slots\n");
      break;
998

999
    case 'g':
Raymond Knopp's avatar
 
Raymond Knopp committed
1000
      glog_level=atoi(optarg); // value between 1 - 9
1001
      break;
1002 1003 1004

    case 'F':
      break;
1005

1006 1007 1008
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
1009

1010
    case 'x':
1011 1012 1013
      printf("Transmission mode should be set in config file now\n");
      exit(-1);
      /*
1014
      transmission_mode = atoi(optarg);
1015

1016 1017
      if (transmission_mode > 7) {
        printf("Transmission mode %d not supported for the moment\n",transmission_mode);
1018
        exit(-1);
1019
      }
1020
      */
1021
      break;
1022

1023 1024 1025
    case 'T':
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
	frame_parms[CC_id]->frame_type = TDD;
1026
      break;
1027

1028 1029 1030 1031
    case 'h':
      help ();
      exit (-1);
       
Raymond Knopp's avatar
 
Raymond Knopp committed
1032
    default:
1033 1034
      help ();
      exit (-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1035
      break;
1036 1037
    }
  }
1038

Raymond Knopp's avatar
 
Raymond Knopp committed
1039 1040
  if (UE_flag == 0)
    AssertFatal(conf_config_file_name != NULL,"Please provide a configuration file\n");
1041 1042


Raymond Knopp's avatar
 
Raymond Knopp committed
1043
  if ((UE_flag == 0) && (conf_config_file_name != NULL)) {
1044
    int i,j;
1045

Raymond Knopp's avatar
 
Raymond Knopp committed
1046
    NB_eNB_INST = 1;
1047

Raymond Knopp's avatar
 
Raymond Knopp committed
1048 1049
    /* Read eNB configuration file */
    enb_properties = enb_config_init(conf_config_file_name);
1050

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1055
    /* Update some simulation parameters */
1056
    for (i=0; i < enb_properties->number; i++) {
1057
      AssertFatal (MAX_NUM_CCs == enb_properties->properties[i]->nb_cc,
1058 1059
                   "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);
1060 1061
      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));
1062

1063
      for (j=0; j<enb_properties->properties[i]->nb_rrh_gw; j++) {
1064 1065 1066 1067 1068 1069 1070 1071
        	
        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;
1072 1073 1074
          
          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
1075
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif4p5 == 1) {
1076
            (eth_params+j)->transp_preference       = ETH_RAW_IF4p5_MODE;             
Raymond Knopp's avatar
Raymond Knopp committed
1077
          } else if (enb_properties->properties[i]->rrh_gw_config[j].udpif4p5 == 1) {
1078
            (eth_params+j)->transp_preference       = ETH_UDP_IF4p5_MODE;             
1079 1080
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif5_mobipass == 1) {
            (eth_params+j)->transp_preference       = ETH_RAW_IF5_MOBIPASS;             
1081 1082 1083 1084
          } else {
            (eth_params+j)->transp_preference       = ETH_UDP_MODE;	 
          }
          
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
          (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; 
        }
1104 1105 1106
	
      }

1107
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
Raymond Knopp committed
1108 1109
	

1110 1111 1112 1113
        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];

1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
        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];
1124
        frame_parms[CC_id]->nb_antennas_tx_eNB  =  enb_properties->properties[i]->nb_antenna_ports[CC_id];
1125
        frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
Raymond Knopp's avatar
Raymond Knopp committed
1126 1127 1128 1129

	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];

1130
	frame_parms[CC_id]->mode1_flag         = (frame_parms[CC_id]->nb_antennas_tx_eNB == 1) ? 1 : 0;
Raymond Knopp's avatar
Raymond Knopp committed
1131 1132
	frame_parms[CC_id]->threequarter_fs    = threequarter_fs;

1133
        //} // j
Raymond Knopp's avatar
 
Raymond Knopp committed
1134 1135
      }

1136

1137 1138 1139
      init_all_otg(0);
      g_otg->seed = 0;
      init_seeds(g_otg->seed);
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149

      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");
1150
      }
1151

1152
      init_predef_traffic(enb_properties->properties[i]->num_otg_elements, 1);
1153 1154


1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168
      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
1169 1170 1171 1172 1173 1174
# 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
1175 1176 1177
#if defined (ENABLE_SECURITY)
      osa_log_level                  = enb_properties->properties[i]->osa_log_level;
      osa_log_verbosity              = enb_properties->properties[i]->osa_log_verbosity;
1178
#endif
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1179

Raymond Knopp's avatar
 
Raymond Knopp committed
1180
      // adjust the log
1181
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191
        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
1192
      } // CC_id
1193
    }// i
1194 1195 1196 1197 1198 1199 1200 1201
  } 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
1202
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1203
}
1204

1205 1206 1207
#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 */
1208
int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
1209 1210
#endif

1211 1212
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
1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257

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

    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]);

  }

}

1258 1259
void init_openair0(void);

Raymond Knopp's avatar
Raymond Knopp committed
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 1286 1287 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 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363
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) {      
      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;    
    } 
    
    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;


    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));

    for (i=0; i<4; i++) {

      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;

      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;

      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]);
      
      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 {
	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB;
      }


    }


  }
}

1364 1365
int main( int argc, char **argv )
{
1366
  int i,aa,card=0;
1367
#if defined (XFORMS)
Raymond Knopp's avatar
 
Raymond Knopp committed
1368
  void *status;
1369
#endif
1370

Raymond Knopp's avatar
 
Raymond Knopp committed
1371
  int CC_id;
Raymond Knopp's avatar
Raymond Knopp committed
1372
  uint8_t  abstraction_flag=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1373
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
1374

Raymond Knopp's avatar
 
Raymond Knopp committed
1375
#if defined (XFORMS)
1376 1377
  int ret;
#endif
1378

1379 1380 1381 1382 1383
#ifdef DEBUG_CONSOLE
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);
#endif

1384 1385 1386
  PHY_VARS_UE *UE[MAX_NUM_CCs];

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

1389
  memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
Raymond Knopp's avatar
 
Raymond Knopp committed
1390
  set_latency_target();
1391

Raymond Knopp's avatar
Raymond Knopp committed
1392 1393
  // set default parameters
  set_default_frame_parms(frame_parms);
1394

Raymond Knopp's avatar
Raymond Knopp committed
1395
  // initialize logging
1396
  logInit();
Raymond Knopp's avatar
Raymond Knopp committed
1397 1398 1399 1400 1401

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


1402
 
Raymond Knopp's avatar
Raymond Knopp committed
1403

1404
  
1405
#if T_TRACER
1406
  T_init(T_port, T_wait, T_dont_fork);
1407 1408
#endif

1409
  // initialize the log (see log.h for details)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1410 1411
  set_glog(glog_level, glog_verbosity);

1412 1413
  //randominit (0);
  set_taus_seed (0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1414

1415 1416
  if (UE_flag==1) {
    printf("configuring for UE\n");
1417

1418 1419
    set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
    set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
1420 1421 1422 1423 1424
    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);
1425
#if defined(ENABLE_ITTI)
1426
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1427
# if defined(ENABLE_USE_MME)
1428
    set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
1429 1430
# endif
#endif
1431 1432
  } else {
    printf("configuring for eNB\n");
1433

1434 1435 1436 1437 1438 1439 1440 1441
    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);
1442
#if defined(ENABLE_ITTI)
1443
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1444
# if defined(ENABLE_USE_MME)
1445 1446 1447 1448
    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);
1449
# endif
1450
#if defined(ENABLE_SECURITY)
1451
    set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
1452
#endif
1453
#endif
1454
#ifdef LOCALIZATION
1455 1456 1457 1458 1459 1460 1461 1462 1463
    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
1464
    }
1465
  }
1466

Raymond Knopp's avatar
 
Raymond Knopp committed
1467 1468
  if (ouput_vcd) {
    if (UE_flag==1)
1469
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1470
    else
1471
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1472
  }
1473

1474
  if (opp_enabled ==1){
1475
    reset_opp_meas();
1476 1477
  }
  cpuf=get_cpu_freq_GHz();
1478

1479
#if defined(ENABLE_ITTI)
1480

Raymond Knopp's avatar
 
Raymond Knopp committed
1481 1482
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
1483
  } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1484 1485
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
1486

Raymond Knopp's avatar
 
Raymond Knopp committed
1487
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
1488
 
1489 1490
  // initialize mscgen log after ITTI
  MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
1491 1492
#endif
 
1493 1494
  if (opt_type != OPT_NONE) {
    radio_type_t radio_type;
1495

1496 1497
    if (frame_parms[0]->frame_type == FDD)
      radio_type = RADIO_TYPE_FDD;
1498
    else
1499
      radio_type = RADIO_TYPE_TDD;
1500

1501 1502 1503
    if (init_opt(in_path, in_ip, NULL, radio_type) == -1)
      LOG_E(OPT,"failed to run OPT \n");
  }
1504

1505
#ifdef PDCP_USE_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
1506
  netlink_init();
1507 1508 1509
#if defined(PDCP_USE_NETLINK_QUEUES)
  pdcp_netlink_init();
#endif
1510 1511
#endif

1512
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1513 1514 1515
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
1516
#endif
1517

1518

Raymond Knopp's avatar
 
Raymond Knopp committed
1519 1520 1521
  check_clock();

  // init the parameters
1522 1523
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

Raymond Knopp's avatar
Raymond Knopp committed
1524
    if (UE_flag==1) {
1525 1526
      frame_parms[CC_id]->nb_antennas_tx     = 1;
      frame_parms[CC_id]->nb_antennas_rx     = 1;
1527
      frame_parms[CC_id]->nb_antennas_tx_eNB = 1; //initial value overwritten by initial sync later
1528 1529
    }

1530 1531
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
1532 1533
    //   phy_init_top(frame_parms[CC_id]);
    phy_init_lte_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1534 1535 1536
  }


1537
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1538
    //init prach for openair1 test
Raymond Knopp's avatar
Raymond Knopp committed
1539

Raymond Knopp's avatar
 
Raymond Knopp committed
1540
    // 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
1541
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
1542
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1543 1544

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1545 1546 1547
    NB_UE_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
1548 1549
    PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**));
    PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
1550 1551

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

1553
      PHY_vars_UE_g[0][CC_id] = init_lte_UE(frame_parms[CC_id], 0,abstraction_flag);
1554 1555
      UE[CC_id] = PHY_vars_UE_g[0][CC_id];
      printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]);
1556

1557 1558 1559 1560
      if (phy_test==1)
	UE[CC_id]->mac_enabled = 0;
      else 
	UE[CC_id]->mac_enabled = 1;
1561

1562
      if (UE[CC_id]->mac_enabled == 0) {  //set default UL parameters for testing mode
1563 1564 1565 1566 1567 1568 1569 1570 1571
	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
1572
      }
1573

1574
      UE[CC_id]->UE_scan = UE_scan;
1575
      UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
1576 1577
      UE[CC_id]->mode    = mode;

1578 1579
      compute_prach_seq(&UE[CC_id]->frame_parms.prach_config_common,
                        UE[CC_id]->frame_parms.frame_type,
1580 1581
                        UE[CC_id]->X_u);

1582
      if (UE[CC_id]->mac_enabled == 1) 
1583
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1234;
1584
      else
1585
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1235;
1586 1587

      UE[CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0];
1588 1589
      UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
      UE[CC_id]->N_TA_offset = 0;
1590

Raymond Knopp's avatar
 
Raymond Knopp committed
1591
    }
1592

1593
    //  printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_poHwer,tx_max_power));
1594 1595 1596 1597 1598 1599
  } 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++) {
1600
      PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,abstraction_flag);
1601 1602
      PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;

1603 1604
      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;
1605

1606
      if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode
1607 1608 1609 1610 1611 1612 1613 1614 1615
	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;
	}
1616 1617
      }

1618 1619
      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,
1620
                        PHY_vars_eNB_g[0][CC_id]->X_u);
Raymond Knopp's avatar
 
Raymond Knopp committed
1621

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

1624
      PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0;
1625

1626
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1627 1628


1629 1630 1631 1632
    NB_eNB_INST=1;
    NB_INST=1;

  }
1633

1634 1635
  fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
  cpuf=get_cpu_freq_GHz();
1636

1637

Raymond Knopp's avatar
 
Raymond Knopp committed
1638
  dump_frame_parms(frame_parms[0]);
1639

Raymond Knopp's avatar
Raymond Knopp committed
1640
  init_openair0();
Raymond Knopp's avatar
Raymond Knopp committed
1641 1642


1643

laurent's avatar
laurent committed
1644
#ifndef DEADLINE_SCHEDULER
1645

1646
  /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */
1647 1648 1649 1650 1651
  
  cpu_set_t cpuset;
  int s;
  char cpu_affinity[1024];
  CPU_ZERO(&cpuset);
1652
#ifdef CPU_AFFINITY
1653
  if (get_nprocs() > 2)
1654
    {
1655 1656 1657 1658 1659 1660 1661 1662
      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");
1663
    }
1664
#endif
1665

1666 1667 1668
  /* Check the actual affinity mask assigned to the thread */
  s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
  if (s != 0)
1669 1670 1671 1672
    {
      perror( "pthread_getaffinity_np");
      exit_fun("Error getting processor affinity ");
    }
1673 1674
  memset(cpu_affinity, 0 , sizeof(cpu_affinity));
  for (int j = 0; j < CPU_SETSIZE; j++)
1675 1676 1677 1678 1679 1680 1681
    {
      if (CPU_ISSET(j, &cpuset))
	{  
	  char temp[1024];
	  sprintf(temp, " CPU_%d ", j);    
	  strcat(cpu_affinity, temp);
	}
1682
    }
1683
  LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity);
1684
#endif
1685 1686
  
  openair0_cfg[0].log_level = glog_level;
1687

1688
  
Raymond Knopp's avatar
Raymond Knopp committed
1689

1690

Raymond Knopp's avatar
 
Raymond Knopp committed
1691
  int eMBMS_active=0;
1692 1693
  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
1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704
    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

  }


1705

winckel's avatar
winckel committed
1706
#if defined(ENABLE_ITTI)
1707

Raymond Knopp's avatar
Raymond Knopp committed
1708 1709 1710 1711 1712 1713 1714
  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
    }
1715

Raymond Knopp's avatar
 
Raymond Knopp committed
1716
  printf("ITTI tasks created\n");
winckel's avatar
winckel committed
1717
#endif
Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
1718

1719 1720 1721 1722 1723
  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
1724
    } else if (node_function[0]>NGFI_RRU_IF4p5)
1725 1726
      mac_xface->mrbch_phy_sync_failure (0, 0, 0);
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1727

1728 1729


Raymond Knopp's avatar
 
Raymond Knopp committed
1730
  mlockall(MCL_CURRENT | MCL_FUTURE);
1731

Raymond Knopp's avatar
 
Raymond Knopp committed
1732 1733
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
1734 1735

#ifdef XFORMS
1736 1737
  int UE_id;

Raymond Knopp's avatar
 
Raymond Knopp committed
1738 1739
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
1740 1741

    if (UE_flag==0) {
1742
      form_stats_l2 = create_form_stats_form();
1743 1744 1745
      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");
1746 1747

      for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759
	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");
	  }
1760 1761
	} // CC_id
      } // UE_id
1762
    } else {
1763 1764 1765 1766 1767 1768 1769
      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);

1770
      /*
1771
	if (openair_daq_vars.use_ia_receiver) {
1772 1773
        fl_set_button(form_ue[UE_id]->button_0,1);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
1774
	} else {
1775 1776
        fl_set_button(form_ue[UE_id]->button_0,0);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
1777
	}*/
1778 1779
      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
1780 1781
    }

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

1784 1785
    if (ret == 0)
      pthread_setname_np( forms_thread, "xforms" );
1786

Raymond Knopp's avatar
 
Raymond Knopp committed
1787 1788
    printf("Scope thread created, ret=%d\n",ret);
  }
1789

1790 1791
#endif

1792
  rt_sleep_ns(10*100000000ULL);
1793

1794

1795

Raymond Knopp's avatar
 
Raymond Knopp committed
1796
  // start the main thread
Raymond Knopp's avatar
Raymond Knopp committed
1797
  if (UE_flag == 1) init_UE(1);
Raymond Knopp's avatar
Raymond Knopp committed
1798 1799
  else { 
    init_eNB(node_function,node_timing,1,eth_params,single_thread_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
1800
  // Sleep to allow all threads to setup
1801

Raymond Knopp's avatar
Raymond Knopp committed
1802 1803 1804 1805 1806 1807
    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;
    }
1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853
  }

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

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

    
#ifdef OAI_USRP
      UE[CC_id]->hw_timing_advance = timing_advance;
#else
      UE[CC_id]->hw_timing_advance = 160;
#endif
    }
    if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) {
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }



    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 {





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

    // 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;
    }
  }
1854
  sleep(3);
Raymond Knopp's avatar
 
Raymond Knopp committed
1855

1856

1857
  printf("Sending sync to all threads\n");
1858

Raymond Knopp's avatar
 
Raymond Knopp committed
1859
  pthread_mutex_lock(&sync_mutex);
1860
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1861 1862
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
1863

Raymond Knopp's avatar
 
Raymond Knopp committed
1864 1865 1866
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
1867 1868

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1869 1870
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
1871
  oai_exit=1;
1872
#else
1873

Raymond Knopp's avatar
 
Raymond Knopp committed
1874
  while (oai_exit==0)
1875
    rt_sleep_ns(100000000ULL);
1876

1877
#endif
1878

Raymond Knopp's avatar
 
Raymond Knopp committed
1879
  // stop threads
1880
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
1881
  printf("waiting for XFORMS thread\n");
1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895

  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++) {
1896 1897 1898 1899
	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
1900
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1901
    }
1902 1903
  }

1904 1905
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1908 1909
  // cleanup
  if (UE_flag == 1) {
1910
  } else {
1911
    stop_eNB(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1912
  }
1913

1914

Raymond Knopp's avatar
 
Raymond Knopp committed
1915 1916
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
1917

1918

Raymond Knopp's avatar
Raymond Knopp committed
1919
  // *** Handle per CC_id openair0
Raymond Knopp's avatar
Raymond Knopp committed
1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930
  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);  
    }
1931
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1932
  if (ouput_vcd)
1933
    VCD_SIGNAL_DUMPER_CLOSE();
1934

1935
  if (opt_enabled == 1)
1936
    terminate_opt();
1937

Raymond Knopp's avatar
 
Raymond Knopp committed
1938
  logClean();
1939

Raymond Knopp's avatar
 
Raymond Knopp committed
1940 1941
  return 0;
}