lte-softmodem.c 61.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
#   include "SIMULATION/ETH_TRANSPORT/proto.h"
Rohit Gupta's avatar
Rohit Gupta committed
111
extern int netlink_init(void);
112
#endif
113
# endif
114 115
#endif

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

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

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

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

142

143

144 145


Raymond Knopp's avatar
 
Raymond Knopp committed
146

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

151

152 153


154

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

159 160
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
161

162

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

169

170

Raymond Knopp's avatar
 
Raymond Knopp committed
171

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

176
static char                     threequarter_fs=0;
177

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

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
double rx_gain_off = 0.0;
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

Raymond Knopp's avatar
 
Raymond Knopp committed
242

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
275

276

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

Raymond Knopp's avatar
 
Raymond Knopp committed
280

281 282 283 284 285
/* 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;

286 287 288 289
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

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


Raymond Knopp's avatar
 
Raymond Knopp committed
293

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

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

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

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

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

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

354 355 356 357
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
358 359
  } else {
    printf("trying to exit gracefully...\n");
360
    oai_exit = 1;
361 362
  }
}
363
#endif
364 365 366 367 368 369 370 371 372 373 374
#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");
375
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
376 377 378 379
  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
380 381
  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");
382
  printf("  --no-L2-connect bypass L2 and upper layers\n");
383
  printf("  --ue-rxgain set UE RX gain\n");
384
  printf("  --ue-rxgain-off external UE amplifier offset\n");
385 386 387
  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");
388 389
  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");  
  printf("  --single-thread runs lte-softmodem in only one thread\n"); 
390
  printf("  -C Set the downlink frequency for all component carriers\n");
391 392 393
  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");
394
  printf("  -G Set the global log verbosity \n");
395 396 397 398 399
  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
400
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
401 402
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
403
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
404 405 406
  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");
407
  printf("  -x Set the transmission mode, valid options: 1 \n");
408
  printf("  -E Apply three-quarter of sampling frequency, 23.04 Msps to reduce the data rate on USB/PCIe transfers (only valid for 20 MHz)\n");
409 410 411
#if T_TRACER
  printf("  --T_port [port]    use given port\n");
  printf("  --T_nowait         don't wait for tracer, start immediately\n");
412
  printf("  --T_dont_fork      to ease debugging with gdb\n");
413 414 415
#endif
  printf(RESET);
  fflush(stdout);
416
}
417

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

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

  oai_exit = 1;
Raymond Knopp's avatar
Raymond Knopp committed
427 428
  
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
Raymond Knopp committed
429 430 431 432 433 434 435 436 437 438
    if (UE_flag == 0) {
      if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func)
	PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice);
      if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func)
	PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_end_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice);  
    }
    else {
      if (PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func)
	PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice);
    }
Raymond Knopp's avatar
Raymond Knopp committed
439
  }
440 441

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

}

448

449
#ifdef XFORMS
450

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

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

464 465 466
      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;
467

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

476 477 478
    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;
479 480 481
  }
}

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

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

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

498
# ifdef ENABLE_XFORMS_WRITE_STATS
499 500

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

505
#endif
506

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

514 515 516 517 518
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

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

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

531 532 533
      //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);
534

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

548
    }
549

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

555
  //  printf("%s",stats_buffer);
556

557
# ifdef ENABLE_XFORMS_WRITE_STATS
558

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

573
# endif
574

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

579

580

581

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
590

Raymond Knopp's avatar
 
Raymond Knopp committed
591 592
  if (UE_flag == 0) {
    /* Wait for the initialize message */
593
    printf("Wait for the ITTI initialize message\n");
594 595 596 597 598
    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
599

600
      itti_receive_msg (TASK_L2L1, &message_p);
601

602 603 604 605 606 607
      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;
608

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

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

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

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

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

635 636 637
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
638

639 640 641
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
642

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

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

652 653 654
    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);
655

656 657
  return NULL;
}
Raymond Knopp's avatar
 
Raymond Knopp committed
658
#endif
659

660

661

662

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


675 676

  const Enb_properties_array_t *enb_properties;
677

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

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

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

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

761 762 763 764
    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
765
      break;
766

767 768 769 770 771
    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;
772

773 774 775
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
776

777 778 779
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
780

Raymond Knopp's avatar
 
Raymond Knopp committed
781 782
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
Rohit Gupta's avatar
Rohit Gupta committed
783
      printf("Setting mode to calib_prach_tx (%d)\n",mode);
Raymond Knopp's avatar
 
Raymond Knopp committed
784 785
      break;

786
    case LONG_OPTION_RXGAIN:
787 788
      for (i=0; i<4; i++)
        rx_gain[0][i] = atof(optarg);
789

790
      break;
791

792 793 794 795
    case LONG_OPTION_RXGAINOFF:
      rx_gain_off = atof(optarg);
      break;

796 797 798
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
799

800
      break;
801

802 803 804 805 806
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

807 808 809 810 811 812
    case LONG_OPTION_LOOPMEMORY:
      mode=loop_through_memory;
      input_fd = fopen(optarg,"r");
      AssertFatal(input_fd != NULL,"Please provide an input file\n");
      break;

813 814 815 816
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
817 818 819
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
820

821 822 823
    case LONG_OPTION_MMAPPED_DMA:
      mmapped_dma = 1;
      break;
Raymond Knopp's avatar
Raymond Knopp committed
824 825 826 827

    case LONG_OPTION_SINGLE_THREAD:
      single_thread_flag = 1;
      break;
828
              
829 830 831 832 833 834 835 836 837 838 839 840 841
#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;
    }
842 843 844 845 846 847

    case LONG_OPTION_T_DONT_FORK: {
      extern int T_dont_fork;
      T_dont_fork = 1;
      break;
    }
848 849
#endif

850 851 852 853
    case 'A':
      timing_advance = atoi (optarg);
      break;

854
    case 'C':
855 856 857 858 859 860
      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]);
861
      }
862

863
      UE_scan=0;
864

865
      break;
866

Florian Kaltenberger's avatar
Florian Kaltenberger committed
867 868 869 870
    case 'a':
      chain_offset = atoi(optarg);
      break;

871 872 873 874
    case 'd':
#ifdef XFORMS
      do_forms=1;
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
875
#endif
876
      break;
877 878 879 880
      
    case 'E':
      threequarter_fs=1;
      break;
881

882 883 884
    case 'K':
#if defined(ENABLE_ITTI)
      itti_dump_file = strdup(optarg);
885
#else
886
      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
887
#endif
888
      break;
889

890 891 892
    case 'O':
      conf_config_file_name = optarg;
      break;
893

894 895 896
    case 'U':
      UE_flag = 1;
      break;
897

898 899 900
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
901

902 903 904
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
905

906 907 908 909 910 911 912
    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");
      /*
913 914 915 916 917 918 919 920
	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);
	}
921 922
      */
      break;
923

924
    case 'P':
925 926
      opt_type = OPT_PCAP;
      opt_enabled=1;
927 928 929 930 931

      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");
932
      } else {
933 934 935
        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);
936
      }
937 938 939

      break;

Raymond Knopp's avatar
 
Raymond Knopp committed
940 941 942
    case 'V':
      ouput_vcd = 1;
      break;
943

Raymond Knopp's avatar
 
Raymond Knopp committed
944
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
945 946
      opp_enabled = 1;
      break;
947

Raymond Knopp's avatar
 
Raymond Knopp committed
948 949 950
    case  'R' :
      online_log_messages =1;
      break;
951

Raymond Knopp's avatar
 
Raymond Knopp committed
952
    case 'r':
953
      UE_scan = 0;
954

955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980
      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
981
      }
982

983
      break;
984

Raymond Knopp's avatar
 
Raymond Knopp committed
985
    case 's':
986
#if defined(OAI_USRP) || defined(CPRIGW)
Raymond Knopp's avatar
 
Raymond Knopp committed
987 988

      clock_src = atoi(optarg);
989

Raymond Knopp's avatar
 
Raymond Knopp committed
990
      if (clock_src == 0) {
991 992 993 994 995
        //  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
996
      }
997

Raymond Knopp's avatar
 
Raymond Knopp committed
998 999 1000 1001
#else
      printf("Note: -s not defined for ExpressMIMO2\n");
#endif
      break;
1002

1003 1004 1005 1006
    case 'S':
      exit_missed_slots=0;
      printf("Skip exit for missed slots\n");
      break;
1007

1008
    case 'g':
Raymond Knopp's avatar
 
Raymond Knopp committed
1009
      glog_level=atoi(optarg); // value between 1 - 9
1010
      break;
1011 1012 1013

    case 'F':
      break;
1014

1015 1016 1017
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
1018

1019
    case 'x':
1020 1021 1022
      printf("Transmission mode should be set in config file now\n");
      exit(-1);
      /*
1023
      transmission_mode = atoi(optarg);
1024

1025 1026
      if (transmission_mode > 7) {
        printf("Transmission mode %d not supported for the moment\n",transmission_mode);
1027
        exit(-1);
1028
      }
1029
      */
1030
      break;
1031

1032 1033 1034
    case 'T':
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
	frame_parms[CC_id]->frame_type = TDD;
1035
      break;
1036

1037 1038 1039 1040
    case 'h':
      help ();
      exit (-1);
       
Raymond Knopp's avatar
 
Raymond Knopp committed
1041
    default:
1042 1043
      help ();
      exit (-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1044
      break;
1045 1046
    }
  }
1047

Raymond Knopp's avatar
 
Raymond Knopp committed
1048 1049
  if (UE_flag == 0)
    AssertFatal(conf_config_file_name != NULL,"Please provide a configuration file\n");
1050 1051


Raymond Knopp's avatar
 
Raymond Knopp committed
1052
  if ((UE_flag == 0) && (conf_config_file_name != NULL)) {
1053
    int i,j;
1054

Raymond Knopp's avatar
 
Raymond Knopp committed
1055
    NB_eNB_INST = 1;
1056

Raymond Knopp's avatar
 
Raymond Knopp committed
1057 1058
    /* Read eNB configuration file */
    enb_properties = enb_config_init(conf_config_file_name);
1059

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1064
    /* Update some simulation parameters */
1065
    for (i=0; i < enb_properties->number; i++) {
1066
      AssertFatal (MAX_NUM_CCs == enb_properties->properties[i]->nb_cc,
1067 1068
                   "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);
1069 1070
      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));
1071

1072
      for (j=0; j<enb_properties->properties[i]->nb_rrh_gw; j++) {
1073 1074 1075
        	
        if (enb_properties->properties[i]->rrh_gw_config[j].active == 1 ) {
          local_remote_radio = BBU_REMOTE_RADIO_HEAD;
1076
          (eth_params+j)->local_if_name             = enb_properties->properties[i]->rrh_gw_config[j].rrh_gw_if_name;
1077 1078 1079 1080
          (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;
1081 1082 1083
          
          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
1084
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif4p5 == 1) {
1085
            (eth_params+j)->transp_preference       = ETH_RAW_IF4p5_MODE;             
Raymond Knopp's avatar
Raymond Knopp committed
1086
          } else if (enb_properties->properties[i]->rrh_gw_config[j].udpif4p5 == 1) {
1087
            (eth_params+j)->transp_preference       = ETH_UDP_IF4p5_MODE;             
1088 1089
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif5_mobipass == 1) {
            (eth_params+j)->transp_preference       = ETH_RAW_IF5_MOBIPASS;             
1090 1091 1092 1093
          } else {
            (eth_params+j)->transp_preference       = ETH_UDP_MODE;	 
          }
          
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
          (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; 
        }
1113 1114 1115
	
      }

1116
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
Raymond Knopp committed
1117 1118
	

1119 1120 1121 1122
        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];

1123 1124 1125 1126 1127 1128 1129 1130 1131 1132
        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];
1133
        frame_parms[CC_id]->nb_antennas_tx_eNB  =  enb_properties->properties[i]->nb_antenna_ports[CC_id];
1134
        frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
Raymond Knopp's avatar
Raymond Knopp committed
1135 1136 1137 1138

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

1139
	frame_parms[CC_id]->mode1_flag         = (frame_parms[CC_id]->nb_antennas_tx_eNB == 1) ? 1 : 0;
Raymond Knopp's avatar
Raymond Knopp committed
1140 1141
	frame_parms[CC_id]->threequarter_fs    = threequarter_fs;

1142
        //} // j
Raymond Knopp's avatar
 
Raymond Knopp committed
1143 1144
      }

1145

1146 1147 1148
      init_all_otg(0);
      g_otg->seed = 0;
      init_seeds(g_otg->seed);
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158

      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");
1159
      }
1160

1161
      init_predef_traffic(enb_properties->properties[i]->num_otg_elements, 1);
1162 1163


1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177
      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
1178 1179 1180 1181 1182 1183
# 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
1184 1185 1186
#if defined (ENABLE_SECURITY)
      osa_log_level                  = enb_properties->properties[i]->osa_log_level;
      osa_log_verbosity              = enb_properties->properties[i]->osa_log_verbosity;
1187
#endif
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1188

Raymond Knopp's avatar
 
Raymond Knopp committed
1189
      // adjust the log
1190
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200
        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
1201
      } // CC_id
1202
    }// i
1203 1204 1205 1206 1207 1208 1209 1210
  } 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
1211
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1212
}
1213

1214 1215 1216
#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 */
1217
int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
1218 1219
#endif

1220 1221
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
Raymond Knopp's avatar
Raymond Knopp committed
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

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

  }

}

1267 1268
void init_openair0(void);

Raymond Knopp's avatar
Raymond Knopp committed
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
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) {      
1316 1317 1318 1319
      openair0_cfg[card].remote_addr    = (eth_params+card)->remote_addr;
      openair0_cfg[card].remote_port    = (eth_params+card)->remote_port;
      openair0_cfg[card].my_addr        = (eth_params+card)->my_addr;
      openair0_cfg[card].my_port        = (eth_params+card)->my_port;    
Raymond Knopp's avatar
Raymond Knopp committed
1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362
    } 
    
    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 {
1363
	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off;
Raymond Knopp's avatar
Raymond Knopp committed
1364 1365 1366 1367 1368 1369 1370 1371 1372
      }


    }


  }
}

1373 1374
int main( int argc, char **argv )
{
Rohit Gupta's avatar
Rohit Gupta committed
1375
  int i,aa;
1376
#if defined (XFORMS)
Raymond Knopp's avatar
 
Raymond Knopp committed
1377
  void *status;
1378
#endif
1379

Raymond Knopp's avatar
 
Raymond Knopp committed
1380
  int CC_id;
Raymond Knopp's avatar
Raymond Knopp committed
1381
  uint8_t  abstraction_flag=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1382
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
1383

Raymond Knopp's avatar
 
Raymond Knopp committed
1384
#if defined (XFORMS)
1385 1386
  int ret;
#endif
1387

1388 1389 1390 1391 1392
#ifdef DEBUG_CONSOLE
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);
#endif

1393 1394 1395
  PHY_VARS_UE *UE[MAX_NUM_CCs];

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

1398
  memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
Raymond Knopp's avatar
 
Raymond Knopp committed
1399
  set_latency_target();
1400

Raymond Knopp's avatar
Raymond Knopp committed
1401 1402
  // set default parameters
  set_default_frame_parms(frame_parms);
1403

Raymond Knopp's avatar
Raymond Knopp committed
1404
  // initialize logging
1405
  logInit();
Raymond Knopp's avatar
Raymond Knopp committed
1406 1407 1408 1409 1410

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


1411
 
Raymond Knopp's avatar
Raymond Knopp committed
1412

1413
  
1414
#if T_TRACER
1415
  T_init(T_port, T_wait, T_dont_fork);
1416 1417
#endif

1418
  // initialize the log (see log.h for details)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1419 1420
  set_glog(glog_level, glog_verbosity);

1421 1422
  //randominit (0);
  set_taus_seed (0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1423

1424 1425
  if (UE_flag==1) {
    printf("configuring for UE\n");
1426

1427 1428
    set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
    set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
1429 1430 1431 1432 1433
    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);
1434
#if defined(ENABLE_ITTI)
1435
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1436
# if defined(ENABLE_USE_MME)
1437
    set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
1438 1439
# endif
#endif
1440 1441
  } else {
    printf("configuring for eNB\n");
1442

1443 1444 1445 1446 1447 1448 1449 1450
    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);
1451
#if defined(ENABLE_ITTI)
1452
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1453
# if defined(ENABLE_USE_MME)
1454 1455 1456 1457
    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);
1458
# endif
1459
#if defined(ENABLE_SECURITY)
1460
    set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
1461
#endif
1462
#endif
1463
#ifdef LOCALIZATION
1464 1465 1466 1467 1468 1469 1470 1471 1472
    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
1473
    }
1474
  }
1475

Raymond Knopp's avatar
 
Raymond Knopp committed
1476 1477
  if (ouput_vcd) {
    if (UE_flag==1)
1478
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1479
    else
1480
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1481
  }
1482

1483
  if (opp_enabled ==1){
1484
    reset_opp_meas();
1485 1486
  }
  cpuf=get_cpu_freq_GHz();
1487

1488
#if defined(ENABLE_ITTI)
1489

Raymond Knopp's avatar
 
Raymond Knopp committed
1490 1491
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
1492
  } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1493 1494
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
1495

Raymond Knopp's avatar
 
Raymond Knopp committed
1496
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
1497
 
1498 1499
  // initialize mscgen log after ITTI
  MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
1500 1501
#endif
 
1502 1503
  if (opt_type != OPT_NONE) {
    radio_type_t radio_type;
1504

1505 1506
    if (frame_parms[0]->frame_type == FDD)
      radio_type = RADIO_TYPE_FDD;
1507
    else
1508
      radio_type = RADIO_TYPE_TDD;
1509

1510 1511 1512
    if (init_opt(in_path, in_ip, NULL, radio_type) == -1)
      LOG_E(OPT,"failed to run OPT \n");
  }
1513

1514
#ifdef PDCP_USE_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
1515
  netlink_init();
1516 1517 1518
#if defined(PDCP_USE_NETLINK_QUEUES)
  pdcp_netlink_init();
#endif
1519 1520
#endif

1521
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1522 1523 1524
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
1525
#endif
1526

1527

Raymond Knopp's avatar
 
Raymond Knopp committed
1528 1529 1530
  check_clock();

  // init the parameters
1531 1532
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

Raymond Knopp's avatar
Raymond Knopp committed
1533
    if (UE_flag==1) {
1534 1535
      frame_parms[CC_id]->nb_antennas_tx     = 1;
      frame_parms[CC_id]->nb_antennas_rx     = 1;
1536
      frame_parms[CC_id]->nb_antennas_tx_eNB = 1; //initial value overwritten by initial sync later
1537 1538
    }

1539 1540
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
1541 1542
    //   phy_init_top(frame_parms[CC_id]);
    phy_init_lte_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1543 1544 1545
  }


1546
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1547
    //init prach for openair1 test
Raymond Knopp's avatar
Raymond Knopp committed
1548

Raymond Knopp's avatar
 
Raymond Knopp committed
1549
    // 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
1550
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
1551
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1552 1553

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1554 1555 1556
    NB_UE_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
1557 1558
    PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**));
    PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
1559 1560

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

1562
      PHY_vars_UE_g[0][CC_id] = init_lte_UE(frame_parms[CC_id], 0,abstraction_flag);
1563 1564
      UE[CC_id] = PHY_vars_UE_g[0][CC_id];
      printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]);
1565

1566 1567 1568 1569
      if (phy_test==1)
	UE[CC_id]->mac_enabled = 0;
      else 
	UE[CC_id]->mac_enabled = 1;
1570

1571
      if (UE[CC_id]->mac_enabled == 0) {  //set default UL parameters for testing mode
1572 1573 1574 1575 1576 1577 1578 1579 1580
	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
1581
      }
1582

1583
      UE[CC_id]->UE_scan = UE_scan;
1584
      UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
1585
      UE[CC_id]->mode    = mode;
Rohit Gupta's avatar
Rohit Gupta committed
1586
      printf("UE[%d]->mode = %d\n",CC_id,mode);
1587

1588 1589
      compute_prach_seq(&UE[CC_id]->frame_parms.prach_config_common,
                        UE[CC_id]->frame_parms.frame_type,
1590 1591
                        UE[CC_id]->X_u);

1592
      if (UE[CC_id]->mac_enabled == 1) 
1593
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1234;
1594
      else
1595
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1235;
1596

1597
      UE[CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0] + rx_gain_off;
1598 1599
      UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
      UE[CC_id]->N_TA_offset = 0;
1600

Raymond Knopp's avatar
 
Raymond Knopp committed
1601
    }
1602

1603
    //  printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_poHwer,tx_max_power));
1604 1605 1606 1607 1608 1609
  } 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++) {
1610
      PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,abstraction_flag);
1611 1612
      PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;

1613 1614
      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;
1615

1616
      if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode
1617 1618 1619 1620 1621 1622 1623 1624 1625
	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;
	}
1626 1627
      }

1628 1629
      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,
1630
                        PHY_vars_eNB_g[0][CC_id]->X_u);
Raymond Knopp's avatar
 
Raymond Knopp committed
1631

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

1634
      PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0;
1635

1636
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1637 1638


1639 1640 1641 1642
    NB_eNB_INST=1;
    NB_INST=1;

  }
1643

1644 1645
  fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
  cpuf=get_cpu_freq_GHz();
1646

1647

Raymond Knopp's avatar
 
Raymond Knopp committed
1648
  dump_frame_parms(frame_parms[0]);
1649

Raymond Knopp's avatar
Raymond Knopp committed
1650
  init_openair0();
Raymond Knopp's avatar
Raymond Knopp committed
1651 1652


1653

laurent's avatar
laurent committed
1654
#ifndef DEADLINE_SCHEDULER
1655

1656
  /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */
1657 1658 1659 1660 1661
  
  cpu_set_t cpuset;
  int s;
  char cpu_affinity[1024];
  CPU_ZERO(&cpuset);
1662
#ifdef CPU_AFFINITY
1663
  if (get_nprocs() > 2)
1664
    {
1665 1666 1667 1668 1669 1670 1671 1672
      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");
1673
    }
1674
#endif
1675

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

1698
  
Raymond Knopp's avatar
Raymond Knopp committed
1699

1700

Raymond Knopp's avatar
 
Raymond Knopp committed
1701
  int eMBMS_active=0;
1702 1703
  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
1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714
    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

  }


1715

winckel's avatar
winckel committed
1716
#if defined(ENABLE_ITTI)
1717

Raymond Knopp's avatar
Raymond Knopp committed
1718 1719 1720 1721 1722 1723 1724
  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
    }
1725

Raymond Knopp's avatar
 
Raymond Knopp committed
1726
  printf("ITTI tasks created\n");
winckel's avatar
winckel committed
1727
#endif
Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
1728

1729 1730 1731 1732 1733
  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
1734
    } else if (node_function[0]>NGFI_RRU_IF4p5)
1735 1736
      mac_xface->mrbch_phy_sync_failure (0, 0, 0);
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1737

1738 1739


Raymond Knopp's avatar
 
Raymond Knopp committed
1740
  mlockall(MCL_CURRENT | MCL_FUTURE);
1741

Raymond Knopp's avatar
 
Raymond Knopp committed
1742 1743
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
1744 1745

#ifdef XFORMS
1746 1747
  int UE_id;

Raymond Knopp's avatar
 
Raymond Knopp committed
1748 1749
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
1750 1751

    if (UE_flag==0) {
1752
      form_stats_l2 = create_form_stats_form();
1753 1754 1755
      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");
1756 1757

      for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769
	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");
	  }
1770 1771
	} // CC_id
      } // UE_id
1772
    } else {
1773 1774 1775 1776 1777 1778 1779
      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);

1780
      /*
1781
	if (openair_daq_vars.use_ia_receiver) {
1782 1783
        fl_set_button(form_ue[UE_id]->button_0,1);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
1784
	} else {
1785 1786
        fl_set_button(form_ue[UE_id]->button_0,0);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
1787
	}*/
1788 1789
      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
1790 1791
    }

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

1794 1795
    if (ret == 0)
      pthread_setname_np( forms_thread, "xforms" );
1796

Raymond Knopp's avatar
 
Raymond Knopp committed
1797 1798
    printf("Scope thread created, ret=%d\n",ret);
  }
1799

1800 1801
#endif

1802
  rt_sleep_ns(10*100000000ULL);
1803

1804

1805

Raymond Knopp's avatar
 
Raymond Knopp committed
1806
  // start the main thread
Raymond Knopp's avatar
Raymond Knopp committed
1807
  if (UE_flag == 1) init_UE(1);
Raymond Knopp's avatar
Raymond Knopp committed
1808 1809
  else { 
    init_eNB(node_function,node_timing,1,eth_params,single_thread_flag);
Raymond Knopp's avatar
 
Raymond Knopp committed
1810
  // Sleep to allow all threads to setup
1811

Raymond Knopp's avatar
Raymond Knopp committed
1812 1813 1814 1815 1816 1817
    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;
    }
1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863
  }

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

1866

1867
  printf("Sending sync to all threads\n");
1868

Raymond Knopp's avatar
 
Raymond Knopp committed
1869
  pthread_mutex_lock(&sync_mutex);
1870
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1871 1872
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
1873

Raymond Knopp's avatar
 
Raymond Knopp committed
1874 1875 1876
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
1877 1878

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1879 1880
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
1881
  oai_exit=1;
1882
#else
1883

Raymond Knopp's avatar
 
Raymond Knopp committed
1884
  while (oai_exit==0)
1885
    rt_sleep_ns(100000000ULL);
1886

1887
#endif
1888

Raymond Knopp's avatar
 
Raymond Knopp committed
1889
  // stop threads
1890
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
1891
  printf("waiting for XFORMS thread\n");
1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905

  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++) {
1906 1907 1908 1909
	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
1910
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1911
    }
1912 1913
  }

1914 1915
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1918 1919
  // cleanup
  if (UE_flag == 1) {
1920
  } else {
1921
    stop_eNB(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1922
  }
1923

1924

Raymond Knopp's avatar
 
Raymond Knopp committed
1925 1926
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
1927

1928

Raymond Knopp's avatar
Raymond Knopp committed
1929
  // *** Handle per CC_id openair0
Raymond Knopp's avatar
Raymond Knopp committed
1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940
  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);  
    }
1941
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1942
  if (ouput_vcd)
1943
    VCD_SIGNAL_DUMPER_CLOSE();
1944

1945
  if (opt_enabled == 1)
1946
    terminate_opt();
1947

Raymond Knopp's avatar
 
Raymond Knopp committed
1948
  logClean();
1949

Raymond Knopp's avatar
 
Raymond Knopp committed
1950 1951
  return 0;
}