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

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


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

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

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

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

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, openair0_rf_map rf_map[MAX_NUM_CCs]);
Raymond Knopp's avatar
Raymond Knopp committed
122
extern void init_eNB(eNB_func_t *, eNB_timing_t *,int,eth_params_t *);
123
extern void stop_eNB(int);
124
extern void kill_eNB_proc(void);
125

126
// In lte-ue.c
127 128
extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
extern void fill_ue_band_info(void);
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
166 167
volatile int                    oai_exit = 0;

168

169

Raymond Knopp's avatar
 
Raymond Knopp committed
170

171
static char                     UE_flag=0;
172
unsigned int                    mmapped_dma=0;
173 174
//static uint8_t                  eNB_id=0,UE_id=0;

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
openair0_rf_map rf_map[MAX_NUM_CCs];
181

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

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

191 192
FILE *input_fd=NULL;

193

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

204 205


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

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

211 212
char   rf_config_file[1024];

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

216

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

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

230

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

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

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 276

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

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
  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");   
387
  printf("  -C Set the downlink frequency for all component carriers\n");
388 389 390
  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");
391
  printf("  -G Set the global log verbosity \n");
392 393 394 395 396
  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
397
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
398 399
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
400
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
401 402 403
  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");
404 405 406 407
  printf("  -x Set the transmission mode, valid options: 1 \n");
#if T_TRACER
  printf("  --T_port [port]    use given port\n");
  printf("  --T_nowait         don't wait for tracer, start immediately\n");
408
  printf("  --T_dont_fork      to ease debugging with gdb\n");
409 410 411
#endif
  printf(RESET);
  fflush(stdout);
412
}
413

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

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

  oai_exit = 1;
Raymond Knopp's avatar
Raymond Knopp committed
423 424 425 426 427 428 429
  
  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);  
  }
430 431

#if defined(ENABLE_ITTI)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
432
  sleep(1); //allow lte-softmodem threads to exit first
433
  itti_terminate_tasks (TASK_UNKNOWN);
434
#endif
435 436 437

}

438

439
#ifdef XFORMS
440

441 442
void reset_stats(FL_OBJECT *button, long arg)
{
443 444
  int i,j,k;
  PHY_VARS_eNB *phy_vars_eNB = PHY_vars_eNB_g[0][0];
445 446 447

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    for (k=0; k<8; k++) { //harq_processes
448 449 450 451
      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;
452
      }
453

454 455 456
      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;
457

458 459 460 461 462
      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;
463
      }
464
    }
465

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

472 473
static void *scope_thread(void *arg)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
474
  char stats_buffer[16384];
475
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
476
  FILE *UE_stats, *eNB_stats;
477
# endif
Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
478
  int len = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
479
  struct sched_param sched_param;
480
  int UE_id, CC_id;
481
  int ue_cnt=0;
482

483
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
Raymond Knopp's avatar
 
Raymond Knopp committed
484
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
485

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

488
# ifdef ENABLE_XFORMS_WRITE_STATS
489 490

  if (UE_flag==1)
Raymond Knopp's avatar
 
Raymond Knopp committed
491
    UE_stats  = fopen("UE_stats.txt", "w");
492
  else
Raymond Knopp's avatar
 
Raymond Knopp committed
493
    eNB_stats = fopen("eNB_stats.txt", "w");
494

495
#endif
496

Raymond Knopp's avatar
 
Raymond Knopp committed
497 498
  while (!oai_exit) {
    if (UE_flag==1) {
499
      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
500 501 502
      //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);
503

504 505 506 507 508
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

Raymond Knopp's avatar
 
Raymond Knopp committed
509
    } else {
510 511 512 513 514 515
      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
516
      len = dump_eNB_stats (PHY_vars_eNB_g[0][0], stats_buffer, 0);
517

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

521 522 523
      //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);
524

525 526
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
527
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
528 529
	  //	  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
530
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
531 532 533 534
			  PHY_vars_eNB_g[0][CC_id],
			  UE_id);
	    ue_cnt++;
	  }
535
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
536
      }
537

538
    }
539

Raymond Knopp's avatar
 
Raymond Knopp committed
540
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
541 542
    //usleep(100000); // 100 ms
    sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
543
  }
544

545
  //  printf("%s",stats_buffer);
546

547
# ifdef ENABLE_XFORMS_WRITE_STATS
548

549 550 551 552 553 554
  if (UE_flag==1) {
    if (UE_stats) {
      rewind (UE_stats);
      fwrite (stats_buffer, 1, len, UE_stats);
      fclose (UE_stats);
    }
555
  } else {
556 557 558 559 560 561
    if (eNB_stats) {
      rewind (eNB_stats);
      fwrite (stats_buffer, 1, len, eNB_stats);
      fclose (eNB_stats);
    }
  }
562

563
# endif
564

Raymond Knopp's avatar
 
Raymond Knopp committed
565
  pthread_exit((void*)arg);
566 567 568
}
#endif

569

570

571

Raymond Knopp's avatar
 
Raymond Knopp committed
572
#if defined(ENABLE_ITTI)
573
void *l2l1_task(void *arg)
574
{
Raymond Knopp's avatar
 
Raymond Knopp committed
575 576 577 578 579
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
580

Raymond Knopp's avatar
 
Raymond Knopp committed
581 582
  if (UE_flag == 0) {
    /* Wait for the initialize message */
583
    printf("Wait for the ITTI initialize message\n");
584 585 586 587 588
    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
589

590
      itti_receive_msg (TASK_L2L1, &message_p);
591

592 593 594 595 596 597
      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;
598

599 600 601 602 603
      case TERMINATE_MESSAGE:
        printf("received terminate message\n");
        oai_exit=1;
        itti_exit_task ();
        break;
604

605 606 607 608 609
      default:
        LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
        break;
      }
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
610

611 612 613
    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  }
614

615 616 617
  do {
    // Wait for a message
    itti_receive_msg (TASK_L2L1, &message_p);
618

619 620 621 622 623
    switch (ITTI_MSG_ID(message_p)) {
    case TERMINATE_MESSAGE:
      oai_exit=1;
      itti_exit_task ();
      break;
Raymond Knopp's avatar
 
Raymond Knopp committed
624

625 626 627
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
628

629 630 631
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
632

633 634 635
    case MESSAGE_TEST:
      LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
      break;
636

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

642 643 644
    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);
645

646 647
  return NULL;
}
Raymond Knopp's avatar
 
Raymond Knopp committed
648
#endif
649

650

651

652

653 654
static void get_options (int argc, char **argv)
{
655 656 657
  int c;
  //  char                          line[1000];
  //  int                           l;
658
  int k,i;//,j,k;
659
#if defined(OAI_USRP) || defined(CPRIGW)
660
  int clock_src;
661
#endif
662
  int CC_id;
663 664


665 666

  const Enb_properties_array_t *enb_properties;
667

668 669
  enum long_option_e {
    LONG_OPTION_START = 0x100, /* Start after regular single char options */
670
    LONG_OPTION_RF_CONFIG_FILE,
671 672 673 674 675
    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,
676
    LONG_OPTION_NO_L2_CONNECT,
Raymond Knopp's avatar
 
Raymond Knopp committed
677
    LONG_OPTION_CALIB_PRACH_TX,
678 679
    LONG_OPTION_RXGAIN,
    LONG_OPTION_TXGAIN,
680
    LONG_OPTION_SCANCARRIER,
681 682
    LONG_OPTION_MAXPOWER,
    LONG_OPTION_DUMP_FRAME,
683
    LONG_OPTION_LOOPMEMORY,
684
    LONG_OPTION_PHYTEST,
Cedric Roux's avatar
Cedric Roux committed
685
    LONG_OPTION_MMAPPED_DMA,
686 687 688
#if T_TRACER
    LONG_OPTION_T_PORT,
    LONG_OPTION_T_NOWAIT,
Cedric Roux's avatar
Cedric Roux committed
689
    LONG_OPTION_T_DONT_FORK,
690
#endif
691
  };
692

693
  static const struct option long_options[] = {
694
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
695 696 697 698 699 700
    {"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
701 702 703 704
    {"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},
705
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
706 707
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
708
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
709
    {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
710 711 712
#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
713
    {"T_dont_fork",            no_argument,       0, LONG_OPTION_T_DONT_FORK},
714
#endif
715 716 717
    {NULL, 0, NULL, 0}
  };

718
  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) {
719
    switch (c) {
720
    case LONG_OPTION_RF_CONFIG_FILE:
721 722 723 724 725 726
      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 {
727 728
	printf("Configuration filename is too long\n");
	exit(-1);   
729 730
      }
      break;
731 732 733 734
    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];
735
      break;
736 737 738 739
    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;
740

741 742 743 744 745
    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;
746

Raymond Knopp's avatar
 
Raymond Knopp committed
747

748 749 750 751
    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
752
      break;
753

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

760 761 762
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
763

764 765 766
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
767

Raymond Knopp's avatar
 
Raymond Knopp committed
768 769 770 771
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
      break;

772
    case LONG_OPTION_RXGAIN:
773 774
      for (i=0; i<4; i++)
        rx_gain[0][i] = atof(optarg);
775

776
      break;
777

778 779 780
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
781

782
      break;
783

784 785 786 787 788
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

789 790 791 792 793 794
    case LONG_OPTION_LOOPMEMORY:
      mode=loop_through_memory;
      input_fd = fopen(optarg,"r");
      AssertFatal(input_fd != NULL,"Please provide an input file\n");
      break;

795 796 797 798
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
799 800 801
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
802

803 804 805 806
    case LONG_OPTION_MMAPPED_DMA:
      mmapped_dma = 1;
      break;
              
807 808 809 810 811 812 813 814 815 816 817 818 819
#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;
    }
820 821 822 823 824 825

    case LONG_OPTION_T_DONT_FORK: {
      extern int T_dont_fork;
      T_dont_fork = 1;
      break;
    }
826 827
#endif

828 829 830 831
    case 'A':
      timing_advance = atoi (optarg);
      break;

832
    case 'C':
833 834 835 836 837 838
      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]);
839
      }
840

841
      UE_scan=0;
842

843
      break;
844

Florian Kaltenberger's avatar
Florian Kaltenberger committed
845 846 847 848
    case 'a':
      chain_offset = atoi(optarg);
      break;

849 850 851 852
    case 'd':
#ifdef XFORMS
      do_forms=1;
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
853
#endif
854
      break;
855 856 857 858
      
    case 'E':
      threequarter_fs=1;
      break;
859

860 861 862
    case 'K':
#if defined(ENABLE_ITTI)
      itti_dump_file = strdup(optarg);
863
#else
864
      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
865
#endif
866
      break;
867

868 869 870
    case 'O':
      conf_config_file_name = optarg;
      break;
871

872 873 874
    case 'U':
      UE_flag = 1;
      break;
875

876 877 878
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
879

880 881 882
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
883

884 885 886 887 888 889 890
    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");
      /*
891 892 893 894 895 896 897 898
	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);
	}
899 900
      */
      break;
901

902
    case 'P':
903 904
      opt_type = OPT_PCAP;
      opt_enabled=1;
905 906 907 908 909

      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");
910
      } else {
911 912 913
        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);
914
      }
915 916 917

      break;

Raymond Knopp's avatar
 
Raymond Knopp committed
918 919 920
    case 'V':
      ouput_vcd = 1;
      break;
921

Raymond Knopp's avatar
 
Raymond Knopp committed
922
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
923 924
      opp_enabled = 1;
      break;
925

Raymond Knopp's avatar
 
Raymond Knopp committed
926 927 928
    case  'R' :
      online_log_messages =1;
      break;
929

Raymond Knopp's avatar
 
Raymond Knopp committed
930
    case 'r':
931
      UE_scan = 0;
932

933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958
      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
959
      }
960

961
      break;
962

Raymond Knopp's avatar
 
Raymond Knopp committed
963
    case 's':
964
#if defined(OAI_USRP) || defined(CPRIGW)
Raymond Knopp's avatar
 
Raymond Knopp committed
965 966

      clock_src = atoi(optarg);
967

Raymond Knopp's avatar
 
Raymond Knopp committed
968
      if (clock_src == 0) {
969 970 971 972 973
        //  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
974
      }
975

Raymond Knopp's avatar
 
Raymond Knopp committed
976 977 978 979
#else
      printf("Note: -s not defined for ExpressMIMO2\n");
#endif
      break;
980

981 982 983 984
    case 'S':
      exit_missed_slots=0;
      printf("Skip exit for missed slots\n");
      break;
985

986
    case 'g':
Raymond Knopp's avatar
 
Raymond Knopp committed
987
      glog_level=atoi(optarg); // value between 1 - 9
988
      break;
989 990 991

    case 'F':
      break;
992

993 994 995
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
996

997 998
    case 'x':
      transmission_mode = atoi(optarg);
999

1000 1001
      if (transmission_mode > 7) {
        printf("Transmission mode %d not supported for the moment\n",transmission_mode);
1002
        exit(-1);
1003
      }
1004
      break;
1005

1006 1007 1008
    case 'T':
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
	frame_parms[CC_id]->frame_type = TDD;
1009
      break;
1010

1011 1012 1013 1014
    case 'h':
      help ();
      exit (-1);
       
Raymond Knopp's avatar
 
Raymond Knopp committed
1015
    default:
1016 1017
      help ();
      exit (-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1018
      break;
1019 1020
    }
  }
1021

Raymond Knopp's avatar
 
Raymond Knopp committed
1022 1023
  if (UE_flag == 0)
    AssertFatal(conf_config_file_name != NULL,"Please provide a configuration file\n");
1024 1025


Raymond Knopp's avatar
 
Raymond Knopp committed
1026
  if ((UE_flag == 0) && (conf_config_file_name != NULL)) {
1027
    int i,j;
1028

Raymond Knopp's avatar
 
Raymond Knopp committed
1029
    NB_eNB_INST = 1;
1030

Raymond Knopp's avatar
 
Raymond Knopp committed
1031 1032
    /* Read eNB configuration file */
    enb_properties = enb_config_init(conf_config_file_name);
1033

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1038
    /* Update some simulation parameters */
1039
    for (i=0; i < enb_properties->number; i++) {
1040
      AssertFatal (MAX_NUM_CCs == enb_properties->properties[i]->nb_cc,
1041 1042
                   "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);
1043 1044
      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));
1045

1046
      for (j=0; j<enb_properties->properties[i]->nb_rrh_gw; j++) {
1047 1048 1049 1050 1051 1052 1053 1054
        	
        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;
1055 1056 1057
          
          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
1058
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif4p5 == 1) {
1059
            (eth_params+j)->transp_preference       = ETH_RAW_IF4p5_MODE;             
Raymond Knopp's avatar
Raymond Knopp committed
1060
          } else if (enb_properties->properties[i]->rrh_gw_config[j].udpif4p5 == 1) {
1061
            (eth_params+j)->transp_preference       = ETH_UDP_IF4p5_MODE;             
1062 1063
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif5_mobipass == 1) {
            (eth_params+j)->transp_preference       = ETH_RAW_IF5_MOBIPASS;             
1064 1065 1066 1067
          } else {
            (eth_params+j)->transp_preference       = ETH_UDP_MODE;	 
          }
          
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
          (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; 
        }
1087 1088 1089
	
      }

1090
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
Raymond Knopp committed
1091 1092
	

1093 1094 1095 1096
        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];

1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108
        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];
Raymond Knopp's avatar
Raymond Knopp committed
1109 1110 1111 1112 1113 1114 1115

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

	frame_parms[CC_id]->mode1_flag         = (transmission_mode == 1) ? 1 : 0;
	frame_parms[CC_id]->threequarter_fs    = threequarter_fs;

1116
        //} // j
Raymond Knopp's avatar
 
Raymond Knopp committed
1117 1118
      }

1119

1120 1121 1122
      init_all_otg(0);
      g_otg->seed = 0;
      init_seeds(g_otg->seed);
1123 1124 1125 1126 1127 1128 1129 1130 1131 1132

      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");
1133
      }
1134

1135
      init_predef_traffic(enb_properties->properties[i]->num_otg_elements, 1);
1136 1137


1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
      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
1152 1153 1154 1155 1156 1157
# 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
1158 1159 1160
#if defined (ENABLE_SECURITY)
      osa_log_level                  = enb_properties->properties[i]->osa_log_level;
      osa_log_verbosity              = enb_properties->properties[i]->osa_log_verbosity;
1161
#endif
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1162

Raymond Knopp's avatar
 
Raymond Knopp committed
1163
      // adjust the log
1164
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1165 1166 1167 1168 1169 1170 1171 1172 1173 1174
        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
1175
      } // CC_id
1176
    }// i
1177 1178 1179 1180 1181 1182 1183 1184
  } 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
1185
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1186
}
1187

1188 1189 1190
#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 */
1191
int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
1192 1193
#endif

Raymond Knopp's avatar
Raymond Knopp committed
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 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 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 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
void set_default_frame_parms() {

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

  }

}

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


    }


  }
}

1344 1345
int main( int argc, char **argv )
{
1346
  int i,aa,card=0;
1347
#if defined (XFORMS)
Raymond Knopp's avatar
 
Raymond Knopp committed
1348
  void *status;
1349
#endif
1350

Raymond Knopp's avatar
 
Raymond Knopp committed
1351
  int CC_id;
Raymond Knopp's avatar
Raymond Knopp committed
1352
  uint8_t  abstraction_flag=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1353
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
1354

Raymond Knopp's avatar
 
Raymond Knopp committed
1355
#if defined (XFORMS)
1356 1357
  int ret;
#endif
1358

1359 1360 1361 1362 1363
#ifdef DEBUG_CONSOLE
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);
#endif

1364 1365 1366
  PHY_VARS_UE *UE[MAX_NUM_CCs];

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

1369
  memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
Raymond Knopp's avatar
 
Raymond Knopp committed
1370
  set_latency_target();
1371

Raymond Knopp's avatar
Raymond Knopp committed
1372 1373
  // set default parameters
  set_default_frame_parms(frame_parms);
1374

Raymond Knopp's avatar
Raymond Knopp committed
1375
  // initialize logging
1376
  logInit();
Raymond Knopp's avatar
Raymond Knopp committed
1377 1378 1379 1380 1381

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


1382
 
Raymond Knopp's avatar
Raymond Knopp committed
1383

1384
  
1385
#if T_TRACER
1386
  T_init(T_port, T_wait, T_dont_fork);
1387 1388
#endif

1389
  // initialize the log (see log.h for details)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1390 1391
  set_glog(glog_level, glog_verbosity);

1392 1393
  //randominit (0);
  set_taus_seed (0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1394

1395 1396
  if (UE_flag==1) {
    printf("configuring for UE\n");
1397

1398 1399
    set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
    set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
1400 1401 1402 1403 1404
    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);
1405
#if defined(ENABLE_ITTI)
1406
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1407
# if defined(ENABLE_USE_MME)
1408
    set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
1409 1410
# endif
#endif
1411 1412
  } else {
    printf("configuring for eNB\n");
1413

1414 1415 1416 1417 1418 1419 1420 1421
    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);
1422
#if defined(ENABLE_ITTI)
1423
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1424
# if defined(ENABLE_USE_MME)
1425 1426 1427 1428
    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);
1429
# endif
1430
#if defined(ENABLE_SECURITY)
1431
    set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
1432
#endif
1433
#endif
1434
#ifdef LOCALIZATION
1435 1436 1437 1438 1439 1440 1441 1442 1443
    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
1444
    }
1445
  }
1446

Raymond Knopp's avatar
 
Raymond Knopp committed
1447 1448
  if (ouput_vcd) {
    if (UE_flag==1)
1449
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1450
    else
1451
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1452
  }
1453

1454
  if (opp_enabled ==1){
1455
    reset_opp_meas();
1456 1457
  }
  cpuf=get_cpu_freq_GHz();
1458

1459
#if defined(ENABLE_ITTI)
1460

Raymond Knopp's avatar
 
Raymond Knopp committed
1461 1462
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
1463
  } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1464 1465
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
1466

Raymond Knopp's avatar
 
Raymond Knopp committed
1467
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
1468
 
1469 1470
  // initialize mscgen log after ITTI
  MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
1471 1472
#endif
 
1473 1474
  if (opt_type != OPT_NONE) {
    radio_type_t radio_type;
1475

1476 1477
    if (frame_parms[0]->frame_type == FDD)
      radio_type = RADIO_TYPE_FDD;
1478
    else
1479
      radio_type = RADIO_TYPE_TDD;
1480

1481 1482 1483
    if (init_opt(in_path, in_ip, NULL, radio_type) == -1)
      LOG_E(OPT,"failed to run OPT \n");
  }
1484

1485
#ifdef PDCP_USE_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
1486
  netlink_init();
1487 1488 1489
#if defined(PDCP_USE_NETLINK_QUEUES)
  pdcp_netlink_init();
#endif
1490 1491
#endif

1492
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1493 1494 1495
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
1496
#endif
1497

1498

Raymond Knopp's avatar
 
Raymond Knopp committed
1499 1500 1501
  check_clock();

  // init the parameters
1502 1503
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

Raymond Knopp's avatar
Raymond Knopp committed
1504
    if (UE_flag==1) {
1505 1506 1507 1508
      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
    }
1509 1510
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
1511 1512
    //   phy_init_top(frame_parms[CC_id]);
    phy_init_lte_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1513 1514 1515
  }


1516
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1517
    //init prach for openair1 test
Raymond Knopp's avatar
Raymond Knopp committed
1518

Raymond Knopp's avatar
 
Raymond Knopp committed
1519
    // 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
1520
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
1521
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1522 1523

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1524 1525 1526
    NB_UE_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
1527 1528
    PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**));
    PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
1529 1530

    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1531 1532 1533 1534

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

1536 1537 1538 1539
      if (phy_test==1)
	UE[CC_id]->mac_enabled = 0;
      else 
	UE[CC_id]->mac_enabled = 1;
1540

1541
      if (UE[CC_id]->mac_enabled == 0) {  //set default UL parameters for testing mode
1542 1543 1544 1545 1546 1547 1548 1549 1550
	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
1551
      }
1552

1553
      UE[CC_id]->UE_scan = UE_scan;
1554
      UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
1555 1556
      UE[CC_id]->mode    = mode;

1557 1558
      compute_prach_seq(&UE[CC_id]->frame_parms.prach_config_common,
                        UE[CC_id]->frame_parms.frame_type,
1559 1560
                        UE[CC_id]->X_u);

1561
      if (UE[CC_id]->mac_enabled == 1) 
1562
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1234;
1563
      else
1564
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1235;
1565 1566

      UE[CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0];
1567 1568
      UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
      UE[CC_id]->N_TA_offset = 0;
1569

Raymond Knopp's avatar
 
Raymond Knopp committed
1570
    }
1571

1572
    //  printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_poHwer,tx_max_power));
1573 1574 1575 1576 1577 1578
  } 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++) {
Raymond Knopp's avatar
Raymond Knopp committed
1579
      PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,0,transmission_mode,abstraction_flag);
1580 1581
      PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;

1582 1583
      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;
1584

1585
      if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode
1586 1587 1588 1589 1590 1591 1592 1593 1594
	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;
	}
1595 1596
      }

1597 1598
      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,
1599
                        PHY_vars_eNB_g[0][CC_id]->X_u);
Raymond Knopp's avatar
 
Raymond Knopp committed
1600

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

1603
      PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0;
1604

1605
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1606 1607


1608 1609 1610 1611
    NB_eNB_INST=1;
    NB_INST=1;

  }
1612

1613 1614
  fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
  cpuf=get_cpu_freq_GHz();
1615

1616

Raymond Knopp's avatar
 
Raymond Knopp committed
1617
  dump_frame_parms(frame_parms[0]);
1618

Raymond Knopp's avatar
Raymond Knopp committed
1619
  init_openair0();
Raymond Knopp's avatar
Raymond Knopp committed
1620 1621


1622

laurent's avatar
laurent committed
1623
#ifndef DEADLINE_SCHEDULER
1624

1625
  /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */
1626 1627 1628 1629 1630
  
  cpu_set_t cpuset;
  int s;
  char cpu_affinity[1024];
  CPU_ZERO(&cpuset);
1631
#ifdef CPU_AFFINITY
1632
  if (get_nprocs() > 2)
1633
    {
1634 1635 1636 1637 1638 1639 1640 1641
      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");
1642
    }
1643
#endif
1644

1645 1646 1647
  /* Check the actual affinity mask assigned to the thread */
  s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
  if (s != 0)
1648 1649 1650 1651
    {
      perror( "pthread_getaffinity_np");
      exit_fun("Error getting processor affinity ");
    }
1652 1653
  memset(cpu_affinity, 0 , sizeof(cpu_affinity));
  for (int j = 0; j < CPU_SETSIZE; j++)
1654 1655 1656 1657 1658 1659 1660
    {
      if (CPU_ISSET(j, &cpuset))
	{  
	  char temp[1024];
	  sprintf(temp, " CPU_%d ", j);    
	  strcat(cpu_affinity, temp);
	}
1661
    }
1662
  LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity);
1663
#endif
1664 1665
  
  openair0_cfg[0].log_level = glog_level;
1666

1667
  
Raymond Knopp's avatar
Raymond Knopp committed
1668

1669

Raymond Knopp's avatar
 
Raymond Knopp committed
1670
  int eMBMS_active=0;
1671 1672
  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
1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683
    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

  }


1684

winckel's avatar
winckel committed
1685
#if defined(ENABLE_ITTI)
1686

Raymond Knopp's avatar
Raymond Knopp committed
1687 1688 1689 1690 1691 1692 1693
  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
    }
1694

Raymond Knopp's avatar
 
Raymond Knopp committed
1695
  printf("ITTI tasks created\n");
winckel's avatar
winckel committed
1696
#endif
Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
1697

1698 1699 1700 1701 1702
  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
1703
    } else if (node_function[0]>NGFI_RRU_IF4p5)
1704 1705
      mac_xface->mrbch_phy_sync_failure (0, 0, 0);
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1706

1707
  number_of_cards = 1;
1708

1709
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1710
    rf_map[CC_id].card=0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1711
    rf_map[CC_id].chain=CC_id+chain_offset;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1712
  }
1713

Raymond Knopp's avatar
 
Raymond Knopp committed
1714 1715
  // connect the TX/RX buffers
  if (UE_flag==1) {
1716 1717 1718 1719

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

    
1720
#ifdef OAI_USRP
1721
      UE[CC_id]->hw_timing_advance = timing_advance;
1722
#else
1723
      UE[CC_id]->hw_timing_advance = 160;
1724
#endif
1725
    }
1726
    if (setup_ue_buffers(UE,&openair0_cfg[0],rf_map)!=0) {
1727 1728 1729
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }
1730 1731 1732



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


1745

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

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

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

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

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

#ifdef XFORMS
1768 1769
  int UE_id;

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

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

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

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

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

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

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

1822 1823
#endif

1824
  rt_sleep_ns(10*100000000ULL);
1825

1826

1827

Raymond Knopp's avatar
 
Raymond Knopp committed
1828
  // start the main thread
Raymond Knopp's avatar
Raymond Knopp committed
1829
  if (UE_flag == 1) init_UE(1);
Raymond Knopp's avatar
Raymond Knopp committed
1830
  else init_eNB(node_function,node_timing,1,eth_params);
Raymond Knopp's avatar
 
Raymond Knopp committed
1831
  // Sleep to allow all threads to setup
1832
  sleep(3);
Raymond Knopp's avatar
 
Raymond Knopp committed
1833

1834

1835
  printf("Sending sync to all threads\n");
1836

Raymond Knopp's avatar
 
Raymond Knopp committed
1837
  pthread_mutex_lock(&sync_mutex);
1838
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1839 1840
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
1841

Raymond Knopp's avatar
 
Raymond Knopp committed
1842 1843 1844
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
1845 1846

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1847 1848
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
1849
  oai_exit=1;
1850
#else
1851

Raymond Knopp's avatar
 
Raymond Knopp committed
1852
  while (oai_exit==0)
1853
    rt_sleep_ns(100000000ULL);
1854

1855
#endif
1856

Raymond Knopp's avatar
 
Raymond Knopp committed
1857
  // stop threads
1858
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
1859
  printf("waiting for XFORMS thread\n");
1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873

  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++) {
1874 1875 1876 1877
	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
1878
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1879
    }
1880 1881
  }

1882 1883
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1886 1887
  // cleanup
  if (UE_flag == 1) {
1888
  } else {
1889
    stop_eNB(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1890
  }
1891

1892

Raymond Knopp's avatar
 
Raymond Knopp committed
1893 1894
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
1895

1896

Raymond Knopp's avatar
Raymond Knopp committed
1897
  // *** Handle per CC_id openair0
Raymond Knopp's avatar
Raymond Knopp committed
1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908
  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);  
    }
1909
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1910
  if (ouput_vcd)
1911
    VCD_SIGNAL_DUMPER_CLOSE();
1912

1913
  if (opt_enabled == 1)
1914
    terminate_opt();
1915

Raymond Knopp's avatar
 
Raymond Knopp committed
1916
  logClean();
1917

Raymond Knopp's avatar
 
Raymond Knopp committed
1918 1919
  return 0;
}