lte-softmodem.c 60.2 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 *);
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
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

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
273

274

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

Raymond Knopp's avatar
 
Raymond Knopp committed
278

279 280 281 282 283
/* 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;

284 285 286 287
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

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


Raymond Knopp's avatar
 
Raymond Knopp committed
291

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

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

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

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

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

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

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

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

void help (void) {
  printf (KGRN "Usage:\n");
  printf("  sudo -E lte-softmodem [options]\n");
  printf("  sudo -E ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.exmimo2.openEPC.conf -S -V -m 26 -t 16 -x 1 --ulsch-max-errors 100 -W\n\n");
  printf("Options:\n");
373
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
374 375 376 377
  printf("  --ulsch-max-errors set the max ULSCH erros\n");
  printf("  --calib-ue-rx set UE RX calibration\n");
  printf("  --calib-ue-rx-med \n");
  printf("  --calib-ue-rxbyp\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
378 379
  printf("  --debug-ue-prach run normal prach power ramping, but don't continue random-access\n");
  printf("  --calib-prach-tx run normal prach with maximum power, but don't continue random-access\n");
380
  printf("  --no-L2-connect bypass L2 and upper layers\n");
381 382 383 384
  printf("  --ue-rxgain set UE RX gain\n");
  printf("  --ue-txgain set UE TX gain\n");
  printf("  --ue-scan_carrier set UE to scan around carrier\n");
  printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
385
  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");   
386
  printf("  -C Set the downlink frequency for all component carriers\n");
387 388 389
  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");
390
  printf("  -G Set the global log verbosity \n");
391 392 393 394 395
  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
396
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
397 398
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
399
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
400 401 402
  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");
403 404 405 406
  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");
407
  printf("  --T_dont_fork      to ease debugging with gdb\n");
408 409 410
#endif
  printf(RESET);
  fflush(stdout);
411
}
412

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

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

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

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

}

437

438
#ifdef XFORMS
439

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

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

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

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

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

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

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

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

487
# ifdef ENABLE_XFORMS_WRITE_STATS
488 489

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

494
#endif
495

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

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

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

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

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

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

537
    }
538

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

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

546
# ifdef ENABLE_XFORMS_WRITE_STATS
547

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

562
# endif
563

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

568

569

570

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
579

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

589
      itti_receive_msg (TASK_L2L1, &message_p);
590

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

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

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

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

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

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

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

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

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

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

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

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

649

650

651

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


664 665

  const Enb_properties_array_t *enb_properties;
666

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
746

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

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

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

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

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

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

775
      break;
776

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

781
      break;
782

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

      break;

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

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

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

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

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

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

840
      UE_scan=0;
841

842
      break;
843

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

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

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

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

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

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

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

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

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

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

      break;

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

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

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

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

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
      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
958
      }
959

960
      break;
961

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

      clock_src = atoi(optarg);
966

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

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

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

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

    case 'F':
      break;
991

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

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

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

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

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

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


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

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

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

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

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

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

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

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

1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107
        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
1108 1109 1110 1111 1112 1113 1114

	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;

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

1118

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

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

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


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

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

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

Raymond Knopp's avatar
Raymond Knopp committed
1193 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
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;
      }


    }


  }
}

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

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

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

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

1363 1364 1365
  PHY_VARS_UE *UE[MAX_NUM_CCs];

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

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

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

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

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


1381
 
Raymond Knopp's avatar
Raymond Knopp committed
1382

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

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

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

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

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

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

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

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

1458
#if defined(ENABLE_ITTI)
1459

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

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

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

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

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

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

1497

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1569
    }
1570

1571
    //  printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_poHwer,tx_max_power));
1572 1573 1574 1575 1576 1577
  } 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
1578
      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);
1579 1580
      PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;

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

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

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

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

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

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


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

  }
1611

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

1615

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

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


1621

laurent's avatar
laurent committed
1622
#ifndef DEADLINE_SCHEDULER
1623

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

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

1666
  
Raymond Knopp's avatar
Raymond Knopp committed
1667

1668

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

  }


1683

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

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

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

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

1706 1707


Raymond Knopp's avatar
 
Raymond Knopp committed
1708
  mlockall(MCL_CURRENT | MCL_FUTURE);
1709

Raymond Knopp's avatar
 
Raymond Knopp committed
1710 1711
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
1712 1713

#ifdef XFORMS
1714 1715
  int UE_id;

Raymond Knopp's avatar
 
Raymond Knopp committed
1716 1717
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
1718 1719

    if (UE_flag==0) {
1720
      form_stats_l2 = create_form_stats_form();
1721 1722 1723
      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");
1724 1725

      for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737
	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");
	  }
1738 1739
	} // CC_id
      } // UE_id
1740
    } else {
1741 1742 1743 1744 1745 1746 1747
      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);

1748
      /*
1749
	if (openair_daq_vars.use_ia_receiver) {
1750 1751
        fl_set_button(form_ue[UE_id]->button_0,1);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
1752
	} else {
1753 1754
        fl_set_button(form_ue[UE_id]->button_0,0);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
1755
	}*/
1756 1757
      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
1758 1759
    }

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

1762 1763
    if (ret == 0)
      pthread_setname_np( forms_thread, "xforms" );
1764

Raymond Knopp's avatar
 
Raymond Knopp committed
1765 1766
    printf("Scope thread created, ret=%d\n",ret);
  }
1767

1768 1769
#endif

1770
  rt_sleep_ns(10*100000000ULL);
1771

1772

1773

Raymond Knopp's avatar
 
Raymond Knopp committed
1774
  // start the main thread
Raymond Knopp's avatar
Raymond Knopp committed
1775
  if (UE_flag == 1) init_UE(1);
Raymond Knopp's avatar
Raymond Knopp committed
1776
  else init_eNB(node_function,node_timing,1,eth_params);
Raymond Knopp's avatar
 
Raymond Knopp committed
1777
  // Sleep to allow all threads to setup
1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829

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

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

1832

1833
  printf("Sending sync to all threads\n");
1834

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

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

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

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

1853
#endif
1854

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

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

1880 1881
#endif

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

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

1890

Raymond Knopp's avatar
 
Raymond Knopp committed
1891 1892
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
1893

1894

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

1911
  if (opt_enabled == 1)
1912
    terminate_opt();
1913

Raymond Knopp's avatar
 
Raymond Knopp committed
1914
  logClean();
1915

Raymond Knopp's avatar
 
Raymond Knopp committed
1916 1917
  return 0;
}