lte-softmodem.c 61.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.0  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */

22 23
/*! \file lte-enb.c
 * \brief Top-level threads for eNodeB
24
 * \author R. Knopp, F. Kaltenberger, Navid Nikaein
Raymond Knopp's avatar
 
Raymond Knopp committed
25 26 27
 * \date 2012
 * \version 0.1
 * \company Eurecom
28
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
Raymond Knopp's avatar
 
Raymond Knopp committed
29 30 31
 * \note
 * \warning
 */
Raymond Knopp's avatar
 
Raymond Knopp committed
32
#define _GNU_SOURCE
33 34 35 36 37 38 39 40
#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>
41
#include <linux/sched.h>
42 43 44
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>
45
#include <sys/sysinfo.h>
46

47 48
#include "T.h"

49
#include "rt_wrapper.h"
50

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

53
#include "assertions.h"
54
#include "msc.h"
55 56

#include "PHY/types.h"
57

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

Raymond Knopp's avatar
 
Raymond Knopp committed
62
#include "../../ARCH/COMMON/common_lib.h"
63
#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
64

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

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

Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
92 93 94 95
#ifndef OPENAIR2
#include "UTIL/OTG/otg_vars.h"
#endif

96 97
#if defined(ENABLE_ITTI)
# include "intertask_interface_init.h"
98
# include "create_tasks.h"
99 100
# if defined(ENABLE_USE_MME)
#   include "s1ap_eNB.h"
101
#ifdef PDCP_USE_NETLINK
102
#   include "SIMULATION/ETH_TRANSPORT/proto.h"
Rohit Gupta's avatar
Rohit Gupta committed
103
extern int netlink_init(void);
104
#endif
105
# endif
106 107
#endif

108 109 110
#ifdef XFORMS
#include "PHY/TOOLS/lte_phy_scope.h"
#include "stats.h"
111 112
#endif

113
// In lte-enb.c
114
extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg);
Raymond Knopp's avatar
Raymond Knopp committed
115
extern void init_eNB(eNB_func_t *, eNB_timing_t *,int,eth_params_t *,int);
116
extern void stop_eNB(int);
117
extern void kill_eNB_proc(void);
Raymond Knopp's avatar
 
Raymond Knopp committed
118

119
// In lte-ue.c
120
extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
121
extern void fill_ue_band_info(void);
Raymond Knopp's avatar
Raymond Knopp committed
122
extern void init_UE(int);
123

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

134 135


136

137

Raymond Knopp's avatar
 
Raymond Knopp committed
138

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

143

144 145


146

147
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
148
static pthread_t                forms_thread; //xforms
149
#endif
150

151 152
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
153

154

155
#if defined(ENABLE_ITTI)
156 157
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
158
#endif
Raymond Knopp's avatar
Raymond Knopp committed
159
volatile int             oai_exit = 0;
160 161 162



Raymond Knopp's avatar
 
Raymond Knopp committed
163

Raymond Knopp's avatar
Raymond Knopp committed
164
static char              UE_flag=0;
165
unsigned int                    mmapped_dma=0;
166
int                             single_thread_flag=1;
167

168
static char                     threequarter_fs=0;
169

170
uint32_t                 downlink_frequency[MAX_NUM_CCs][4];
171
int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
Lionel Gauthier's avatar
Lionel Gauthier committed
172

173

174
static char                    *conf_config_file_name = NULL;
175
#if defined(ENABLE_ITTI)
176
static char                    *itti_dump_file = NULL;
Raymond Knopp's avatar
 
Raymond Knopp committed
177 178
#endif

179
int UE_scan = 1;
180
int UE_scan_carrier = 0;
181 182
runmode_t mode = normal_txrx;

183 184
FILE *input_fd=NULL;

185

186 187
#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
188 189
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}};
190 191 192 193
#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
194
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
195

196
double rx_gain_off = 0.0;
197

Raymond Knopp's avatar
 
Raymond Knopp committed
198
double sample_rate=30.72e6;
199
double bw = 10.0e6;
200

201
static int                      tx_max_power[MAX_NUM_CCs]; /* =  {0,0}*/;
202

203 204
char   rf_config_file[1024];

Florian Kaltenberger's avatar
Florian Kaltenberger committed
205
int chain_offset=0;
206
int phy_test = 0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
207

208

Raymond Knopp's avatar
 
Raymond Knopp committed
209 210 211
char ref[128] = "internal";
char channels[128] = "0";

212
int                      rx_input_level_dBm;
213
static int                      online_log_messages=0;
214
#ifdef XFORMS
215
extern int                      otg_enabled;
216
static char                     do_forms=0;
217
#else
218
int                             otg_enabled;
219
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
220
//int                             number_of_cards =   1;
221

222

Raymond Knopp's avatar
 
Raymond Knopp committed
223
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
224 225 226
eNB_func_t node_function[MAX_NUM_CCs];
eNB_timing_t node_timing[MAX_NUM_CCs];
int16_t   node_synch_ref[MAX_NUM_CCs];
227

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

Raymond Knopp's avatar
 
Raymond Knopp committed
234

235 236
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
237
//int transmission_mode=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
238

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

Lionel Gauthier's avatar
 
Lionel Gauthier committed
256 257 258 259 260 261
# 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
262 263 264
#if defined (ENABLE_SECURITY)
int16_t           osa_log_level      = LOG_INFO;
int16_t           osa_log_verbosity  = LOG_MED;
265
#endif
266

Raymond Knopp's avatar
 
Raymond Knopp committed
267

268

269 270
char *rrh_UE_ip = "127.0.0.1";
int rrh_UE_port = 51000;
271

272 273 274 275 276 277

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

278 279 280 281
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

Raymond Knopp's avatar
 
Raymond Knopp committed
282
char uecap_xer[1024],uecap_xer_in=0;
283 284


Raymond Knopp's avatar
 
Raymond Knopp committed
285

286 287 288 289 290 291 292
/*---------------------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)
{
293 294 295 296 297 298 299 300 301
  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;
302 303
}

Cedric Roux's avatar
Cedric Roux committed
304
void print_difftimes(void)
305 306
{
#ifdef DEBUG
307
  printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
308
#else
309
  LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
310 311 312 313 314
#endif
}

void update_difftimes(struct timespec start, struct timespec end)
{
315 316 317 318 319
  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; }
320
#if 1
321
  if (changed) print_difftimes();
322 323 324 325 326
#endif
}

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

327
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq)
328
{
Raymond Knopp's avatar
 
Raymond Knopp committed
329
  return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
330 331 332
}
unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe)
{
Raymond Knopp's avatar
 
Raymond Knopp committed
333
  return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
334 335
}

336
#if !defined(ENABLE_ITTI)
337 338 339 340 341 342 343 344
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);
345

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

410 411
void exit_fun(const char* s)
{
Raymond Knopp's avatar
Raymond Knopp committed
412 413
  int CC_id;

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

  oai_exit = 1;
Raymond Knopp's avatar
Raymond Knopp committed
419 420
  
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
Raymond Knopp committed
421 422 423 424 425 426 427 428 429 430
    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
431
  }
432 433

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

}

440

441
#ifdef XFORMS
442

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

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

456 457 458
      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;
459

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

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

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

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

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

490
# ifdef ENABLE_XFORMS_WRITE_STATS
491 492

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

497
#endif
498

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

506 507 508 509 510
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

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

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

523 524 525
      //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);
526

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

540
    }
541

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

547
  //  printf("%s",stats_buffer);
548

549
# ifdef ENABLE_XFORMS_WRITE_STATS
550

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

565
# endif
566

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

571

572

573

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
582

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

592 593 594
      itti_receive_msg (TASK_L2L1, &message_p);

      switch (ITTI_MSG_ID(message_p)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
595
      case INITIALIZE_MESSAGE:
596 597 598 599
        /* Start eNB thread */
        LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p));
        start_eNB = 1;
        break;
Raymond Knopp's avatar
 
Raymond Knopp committed
600 601

      case TERMINATE_MESSAGE:
602 603 604 605
        printf("received terminate message\n");
        oai_exit=1;
        itti_exit_task ();
        break;
Raymond Knopp's avatar
 
Raymond Knopp committed
606 607

      default:
608 609
        LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
        break;
610
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
611
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
612

Raymond Knopp's avatar
 
Raymond Knopp committed
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
    result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
  }

  do {
    // Wait for a message
    itti_receive_msg (TASK_L2L1, &message_p);

    switch (ITTI_MSG_ID(message_p)) {
    case TERMINATE_MESSAGE:
      oai_exit=1;
      itti_exit_task ();
      break;

    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;

    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
634

Raymond Knopp's avatar
 
Raymond Knopp committed
635 636 637 638 639 640 641 642 643 644 645
    case MESSAGE_TEST:
      LOG_I(EMU, "Received %s\n", ITTI_MSG_NAME(message_p));
      break;

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
648
  return NULL;
649 650 651
}
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
652

653

Raymond Knopp's avatar
 
Raymond Knopp committed
654

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


667

668
  const Enb_properties_array_t *enb_properties;
669

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

697
  static const struct option long_options[] = {
698
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
699 700 701 702 703 704
    {"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
705 706
    {"calib-prach-tx",   no_argument,        NULL, LONG_OPTION_CALIB_PRACH_TX},
    {"ue-rxgain",   required_argument,  NULL, LONG_OPTION_RXGAIN},
707
	{"ue-rxgain-off",   required_argument,  NULL, LONG_OPTION_RXGAINOFF},
Raymond Knopp's avatar
 
Raymond Knopp committed
708 709
    {"ue-txgain",   required_argument,  NULL, LONG_OPTION_TXGAIN},
    {"ue-scan-carrier",   no_argument,  NULL, LONG_OPTION_SCANCARRIER},
710
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
711 712
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
713
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
714
    {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
715
    {"single-thread-disable", no_argument, NULL, LONG_OPTION_SINGLE_THREAD_DISABLE},
716 717 718
#if T_TRACER
    {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
    {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
719
    {"T_dont_fork",            no_argument,       0, LONG_OPTION_T_DONT_FORK},
720
#endif
721 722 723
    {NULL, 0, NULL, 0}
  };

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

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

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

759 760 761 762 763
    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;
764

765 766 767
    case LONG_OPTION_DEBUG_UE_PRACH:
      mode = debug_prach;
      break;
768

769 770 771
    case LONG_OPTION_NO_L2_CONNECT:
      mode = no_L2_connect;
      break;
772

Raymond Knopp's avatar
 
Raymond Knopp committed
773 774
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
Rohit Gupta's avatar
Rohit Gupta committed
775
      printf("Setting mode to calib_prach_tx (%d)\n",mode);
Raymond Knopp's avatar
 
Raymond Knopp committed
776 777
      break;

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

782
      break;
783

784 785 786 787
    case LONG_OPTION_RXGAINOFF:
      rx_gain_off = atof(optarg);
      break;

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

792
      break;
793

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

      break;

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

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

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

817 818
    case LONG_OPTION_SINGLE_THREAD_DISABLE:
      single_thread_flag = 0;
Raymond Knopp's avatar
Raymond Knopp committed
819
      break;
820
              
821 822 823 824 825 826 827 828 829 830 831 832 833
#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;
    }
834 835 836 837 838 839

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

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

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

855
      UE_scan=0;
856

857
      break;
858

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

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

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

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

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

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

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

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

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

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

      break;

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

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

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

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

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

975
      break;
976

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

      clock_src = atoi(optarg);
981

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

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

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

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

    case 'F':
      break;
1006

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

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

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

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

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

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

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1055
    /* Update some simulation parameters */
1056
    for (i=0; i < enb_properties->number; i++) {
1057
      AssertFatal (MAX_NUM_CCs == enb_properties->properties[i]->nb_cc,
1058 1059
                   "lte-softmodem compiled with MAX_NUM_CCs=%d, but only %d CCs configured for eNB %d!",
                   MAX_NUM_CCs, enb_properties->properties[i]->nb_cc, i);
1060 1061
      eth_params = (eth_params_t*)malloc(enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t));
      memset(eth_params, 0, enb_properties->properties[i]->nb_rrh_gw * sizeof(eth_params_t));
1062

1063
      for (j=0; j<enb_properties->properties[i]->nb_rrh_gw; j++) {
1064 1065 1066
        	
        if (enb_properties->properties[i]->rrh_gw_config[j].active == 1 ) {
          local_remote_radio = BBU_REMOTE_RADIO_HEAD;
1067
          (eth_params+j)->local_if_name             = enb_properties->properties[i]->rrh_gw_config[j].rrh_gw_if_name;
1068 1069 1070 1071
          (eth_params+j)->my_addr                   = enb_properties->properties[i]->rrh_gw_config[j].local_address;
          (eth_params+j)->my_port                   = enb_properties->properties[i]->rrh_gw_config[j].local_port;
          (eth_params+j)->remote_addr               = enb_properties->properties[i]->rrh_gw_config[j].remote_address;
          (eth_params+j)->remote_port               = enb_properties->properties[i]->rrh_gw_config[j].remote_port;
1072 1073 1074
          
          if (enb_properties->properties[i]->rrh_gw_config[j].raw == 1) {
            (eth_params+j)->transp_preference       = ETH_RAW_MODE; 
Raymond Knopp's avatar
Raymond Knopp committed
1075
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif4p5 == 1) {
1076
            (eth_params+j)->transp_preference       = ETH_RAW_IF4p5_MODE;             
Raymond Knopp's avatar
Raymond Knopp committed
1077
          } else if (enb_properties->properties[i]->rrh_gw_config[j].udpif4p5 == 1) {
1078
            (eth_params+j)->transp_preference       = ETH_UDP_IF4p5_MODE;             
1079 1080
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif5_mobipass == 1) {
            (eth_params+j)->transp_preference       = ETH_RAW_IF5_MOBIPASS;             
1081 1082 1083 1084
          } else {
            (eth_params+j)->transp_preference       = ETH_UDP_MODE;	 
          }
          
1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
          (eth_params+j)->iq_txshift                = enb_properties->properties[i]->rrh_gw_config[j].iq_txshift;
          (eth_params+j)->tx_sample_advance         = enb_properties->properties[i]->rrh_gw_config[j].tx_sample_advance;
          (eth_params+j)->tx_scheduling_advance     = enb_properties->properties[i]->rrh_gw_config[j].tx_scheduling_advance;
          if (enb_properties->properties[i]->rrh_gw_config[j].exmimo == 1) {
            (eth_params+j)->rf_preference          = EXMIMO_DEV;
          } else if (enb_properties->properties[i]->rrh_gw_config[j].usrp_b200 == 1) {
            (eth_params+j)->rf_preference          = USRP_B200_DEV;
          } else if (enb_properties->properties[i]->rrh_gw_config[j].usrp_x300 == 1) {
            (eth_params+j)->rf_preference          = USRP_X300_DEV;
          } else if (enb_properties->properties[i]->rrh_gw_config[j].bladerf == 1) {
            (eth_params+j)->rf_preference          = BLADERF_DEV;
          } else if (enb_properties->properties[i]->rrh_gw_config[j].lmssdr == 1) {
            //(eth_params+j)->rf_preference          = LMSSDR_DEV;
          } else {
            (eth_params+j)->rf_preference          = 0;
          } 
        } else {
          local_remote_radio = BBU_LOCAL_RADIO_HEAD; 
        }
1104 1105 1106
	
      }

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

1110 1111 1112 1113
        node_function[CC_id]  = enb_properties->properties[i]->cc_node_function[CC_id];
        node_timing[CC_id]    = enb_properties->properties[i]->cc_node_timing[CC_id];
        node_synch_ref[CC_id] = enb_properties->properties[i]->cc_node_synch_ref[CC_id];

1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
        frame_parms[CC_id]->frame_type =       enb_properties->properties[i]->frame_type[CC_id];
        frame_parms[CC_id]->tdd_config =       enb_properties->properties[i]->tdd_config[CC_id];
        frame_parms[CC_id]->tdd_config_S =     enb_properties->properties[i]->tdd_config_s[CC_id];
        frame_parms[CC_id]->Ncp =              enb_properties->properties[i]->prefix_type[CC_id];

        //for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){
        frame_parms[CC_id]->Nid_cell            =  enb_properties->properties[i]->Nid_cell[CC_id];
        frame_parms[CC_id]->N_RB_DL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
        frame_parms[CC_id]->N_RB_UL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
        frame_parms[CC_id]->nb_antennas_tx      =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
1124
        frame_parms[CC_id]->nb_antennas_tx_eNB  =  enb_properties->properties[i]->nb_antenna_ports[CC_id];
1125
        frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
Raymond Knopp's avatar
Raymond Knopp committed
1126 1127 1128 1129

	frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex = enb_properties->properties[i]->prach_config_index[CC_id];
	frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset  = enb_properties->properties[i]->prach_freq_offset[CC_id];

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

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

1136

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

      for (k=0; k<enb_properties->properties[i]->num_otg_elements; k++) {
        j=enb_properties->properties[i]->otg_ue_id[k]; // ue_id
        g_otg->application_idx[i][j] = 1;
        //g_otg->packet_gen_type=SUBSTRACT_STRING;
        g_otg->background[i][j][0] =enb_properties->properties[i]->otg_bg_traffic[k];
        g_otg->application_type[i][j][0] =enb_properties->properties[i]->otg_app_type[k];// BCBR; //MCBR, BCBR

        printf("[OTG] configuring traffic type %d for  eNB %d UE %d (Background traffic is %s)\n",
               g_otg->application_type[i][j][0], i, j,(g_otg->background[i][j][0]==1)?"Enabled":"Disabled");
1150
      }
1151

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


1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168
      glog_level                     = enb_properties->properties[i]->glog_level;
      glog_verbosity                 = enb_properties->properties[i]->glog_verbosity;
      hw_log_level                   = enb_properties->properties[i]->hw_log_level;
      hw_log_verbosity               = enb_properties->properties[i]->hw_log_verbosity ;
      phy_log_level                  = enb_properties->properties[i]->phy_log_level;
      phy_log_verbosity              = enb_properties->properties[i]->phy_log_verbosity;
      mac_log_level                  = enb_properties->properties[i]->mac_log_level;
      mac_log_verbosity              = enb_properties->properties[i]->mac_log_verbosity;
      rlc_log_level                  = enb_properties->properties[i]->rlc_log_level;
      rlc_log_verbosity              = enb_properties->properties[i]->rlc_log_verbosity;
      pdcp_log_level                 = enb_properties->properties[i]->pdcp_log_level;
      pdcp_log_verbosity             = enb_properties->properties[i]->pdcp_log_verbosity;
      rrc_log_level                  = enb_properties->properties[i]->rrc_log_level;
      rrc_log_verbosity              = enb_properties->properties[i]->rrc_log_verbosity;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1169 1170 1171 1172 1173 1174
# if defined(ENABLE_USE_MME)
      gtpu_log_level                 = enb_properties->properties[i]->gtpu_log_level;
      gtpu_log_verbosity             = enb_properties->properties[i]->gtpu_log_verbosity;
      udp_log_level                  = enb_properties->properties[i]->udp_log_level;
      udp_log_verbosity              = enb_properties->properties[i]->udp_log_verbosity;
#endif
1175 1176 1177
#if defined (ENABLE_SECURITY)
      osa_log_level                  = enb_properties->properties[i]->osa_log_level;
      osa_log_verbosity              = enb_properties->properties[i]->osa_log_verbosity;
1178
#endif
1179

Raymond Knopp's avatar
 
Raymond Knopp committed
1180
      // adjust the log
1181
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191
        for (k = 0 ; k < 4; k++) {
          downlink_frequency[CC_id][k]      =       enb_properties->properties[i]->downlink_frequency[CC_id];
          uplink_frequency_offset[CC_id][k] =  enb_properties->properties[i]->uplink_frequency_offset[CC_id];
          rx_gain[CC_id][k]                 =  (double)enb_properties->properties[i]->rx_gain[CC_id];
          tx_gain[CC_id][k]                 =  (double)enb_properties->properties[i]->tx_gain[CC_id];
        }

        printf("Downlink frequency/ uplink offset of CC_id %d set to %ju/%d\n", CC_id,
               enb_properties->properties[i]->downlink_frequency[CC_id],
               enb_properties->properties[i]->uplink_frequency_offset[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1192
      } // CC_id
1193
    }// i
1194 1195 1196 1197 1198 1199 1200 1201
  } else if (UE_flag == 1) {
    if (conf_config_file_name != NULL) {
      
      // Here the configuration file is the XER encoded UE capabilities
      // Read it in and store in asn1c data structures
      strcpy(uecap_xer,conf_config_file_name);
      uecap_xer_in=1;
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1202
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1203
}
1204

1205 1206 1207
#if T_TRACER
int T_wait = 1;       /* by default we wait for the tracer */
int T_port = 2021;    /* default port to listen to to wait for the tracer */
1208
int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
1209 1210
#endif

1211 1212
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
Raymond Knopp's avatar
Raymond Knopp committed
1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257

  int CC_id;

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    frame_parms[CC_id] = (LTE_DL_FRAME_PARMS*) malloc(sizeof(LTE_DL_FRAME_PARMS));
    /* Set some default values that may be overwritten while reading options */
    frame_parms[CC_id]->frame_type          = FDD;
    frame_parms[CC_id]->tdd_config          = 3;
    frame_parms[CC_id]->tdd_config_S        = 0;
    frame_parms[CC_id]->N_RB_DL             = 100;
    frame_parms[CC_id]->N_RB_UL             = 100;
    frame_parms[CC_id]->Ncp                 = NORMAL;
    frame_parms[CC_id]->Ncp_UL              = NORMAL;
    frame_parms[CC_id]->Nid_cell            = 0;
    frame_parms[CC_id]->num_MBSFN_config    = 0;
    frame_parms[CC_id]->nb_antennas_tx_eNB  = 1;
    frame_parms[CC_id]->nb_antennas_tx      = 1;
    frame_parms[CC_id]->nb_antennas_rx      = 1;

    frame_parms[CC_id]->nushift             = 0;

    frame_parms[CC_id]->phich_config_common.phich_resource = oneSixth;
    frame_parms[CC_id]->phich_config_common.phich_duration = normal;
    // UL RS Config
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift = 0;//n_DMRS1 set to 0
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupHoppingEnabled = 0;
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled = 0;
    frame_parms[CC_id]->pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0;

    frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;

    downlink_frequency[CC_id][0] = 2680000000; // Use float to avoid issue with frequency over 2^31.
    downlink_frequency[CC_id][1] = downlink_frequency[CC_id][0];
    downlink_frequency[CC_id][2] = downlink_frequency[CC_id][0];
    downlink_frequency[CC_id][3] = downlink_frequency[CC_id][0];
    //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);

  }

}

1258 1259
void init_openair0(void);

Raymond Knopp's avatar
Raymond Knopp committed
1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306
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) {      
1307 1308 1309 1310
      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
1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
    } 
    
    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;
1325 1326


Raymond Knopp's avatar
Raymond Knopp committed
1327 1328
    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));
1329

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

Raymond Knopp's avatar
Raymond Knopp committed
1332 1333 1334 1335
      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;
1336

Raymond Knopp's avatar
Raymond Knopp committed
1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
      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]);
1347
      
Raymond Knopp's avatar
Raymond Knopp committed
1348 1349 1350 1351 1352 1353
      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 {
1354
	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
1355 1356 1357
      }


1358
    }
Raymond Knopp's avatar
Raymond Knopp committed
1359 1360


Raymond Knopp's avatar
 
Raymond Knopp committed
1361
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1362
}
1363

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

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

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

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

1384 1385 1386
  PHY_VARS_UE *UE[MAX_NUM_CCs];

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

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

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

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

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


1402
 
Raymond Knopp's avatar
Raymond Knopp committed
1403

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

1409
  // initialize the log (see log.h for details)
1410 1411
  set_glog(glog_level, glog_verbosity);

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

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

1418 1419
    set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
    set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
1420 1421 1422 1423 1424
    set_comp_log(MAC,     LOG_INFO,   LOG_HIGH, 1);
    set_comp_log(RLC,     LOG_INFO,   LOG_HIGH, 1);
    set_comp_log(PDCP,    LOG_INFO,   LOG_HIGH, 1);
    set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);
    set_comp_log(RRC,     LOG_INFO,   LOG_HIGH, 1);
1425
#if defined(ENABLE_ITTI)
1426
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1427
# if defined(ENABLE_USE_MME)
1428
    set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
1429 1430
# endif
#endif
1431 1432
  } else {
    printf("configuring for eNB\n");
1433

1434 1435 1436 1437 1438 1439 1440 1441
    set_comp_log(HW,      hw_log_level, hw_log_verbosity, 1);
    set_comp_log(PHY,     phy_log_level,   phy_log_verbosity, 1);
    if (opt_enabled == 1 )
      set_comp_log(OPT,   opt_log_level,      opt_log_verbosity, 1);
    set_comp_log(MAC,     mac_log_level,  mac_log_verbosity, 1);
    set_comp_log(RLC,     rlc_log_level,   rlc_log_verbosity, 1);
    set_comp_log(PDCP,    pdcp_log_level,  pdcp_log_verbosity, 1);
    set_comp_log(RRC,     rrc_log_level,  rrc_log_verbosity, 1);
1442
#if defined(ENABLE_ITTI)
1443
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1444
# if defined(ENABLE_USE_MME)
1445 1446 1447 1448
    set_comp_log(UDP_,    udp_log_level,   udp_log_verbosity, 1);
    set_comp_log(GTPU,    gtpu_log_level,   gtpu_log_verbosity, 1);
    set_comp_log(S1AP,    LOG_DEBUG,   LOG_HIGH, 1);
    set_comp_log(SCTP,    LOG_INFO,   LOG_HIGH, 1);
1449
# endif
1450
#if defined(ENABLE_SECURITY)
1451
    set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
1452
#endif
1453
#endif
1454
#ifdef LOCALIZATION
1455 1456 1457 1458 1459 1460 1461 1462 1463
    set_comp_log(LOCALIZE, LOG_DEBUG, LOG_LOW, 1);
    set_component_filelog(LOCALIZE);
#endif
    set_comp_log(ENB_APP, LOG_INFO, LOG_HIGH, 1);
    set_comp_log(OTG,     LOG_INFO,   LOG_HIGH, 1);

    if (online_log_messages == 1) {
      set_component_filelog(RRC);
      set_component_filelog(PDCP);
Raymond Knopp's avatar
 
Raymond Knopp committed
1464
    }
1465
  }
1466

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

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

1479
#if defined(ENABLE_ITTI)
1480

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

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

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

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

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

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

1518

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

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

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

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


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

Raymond Knopp's avatar
 
Raymond Knopp committed
1540
    // prach_fmt = get_prach_fmt(frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, frame_parms->frame_type);
Raymond Knopp's avatar
 
Raymond Knopp committed
1541
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
1542
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1543 1544

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

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

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

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

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

1562
      if (UE[CC_id]->mac_enabled == 0) {  //set default UL parameters for testing mode
1563 1564 1565 1566 1567 1568 1569 1570 1571
	for (i=0; i<NUMBER_OF_CONNECTED_eNB_MAX; i++) {
	  UE[CC_id]->pusch_config_dedicated[i].betaOffset_ACK_Index = beta_ACK;
	  UE[CC_id]->pusch_config_dedicated[i].betaOffset_RI_Index  = beta_RI;
	  UE[CC_id]->pusch_config_dedicated[i].betaOffset_CQI_Index = beta_CQI;
	  
	  UE[CC_id]->scheduling_request_config[i].sr_PUCCH_ResourceIndex = 0;
	  UE[CC_id]->scheduling_request_config[i].sr_ConfigIndex = 7+(0%3);
	  UE[CC_id]->scheduling_request_config[i].dsr_TransMax = sr_n4;
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
1572
      }
1573

1574
      UE[CC_id]->UE_scan = UE_scan;
1575
      UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
1576
      UE[CC_id]->mode    = mode;
Rohit Gupta's avatar
Rohit Gupta committed
1577
      printf("UE[%d]->mode = %d\n",CC_id,mode);
1578

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1592
    }
1593

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

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

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

1619 1620
      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,
1621 1622
                        PHY_vars_eNB_g[0][CC_id]->X_u);

1623
      PHY_vars_eNB_g[0][CC_id]->rx_total_gain_dB = (int)rx_gain[CC_id][0];
1624 1625

      PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0;
1626

1627 1628 1629 1630 1631 1632
    }


    NB_eNB_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
1633
  }
1634

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

1638

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

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


1644

laurent's avatar
laurent committed
1645
#ifndef DEADLINE_SCHEDULER
1646

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

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

1689
  
1690 1691


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

  }


1706

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

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

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

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

1729

1730

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

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

#ifdef XFORMS
1737 1738
  int UE_id;

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

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

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

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

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

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

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

1791 1792
#endif

1793
  rt_sleep_ns(10*100000000ULL);
1794

Raymond Knopp's avatar
 
Raymond Knopp committed
1795

1796

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

Raymond Knopp's avatar
Raymond Knopp committed
1803 1804 1805 1806 1807
    number_of_cards = 1;
    
    for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
      PHY_vars_eNB_g[0][CC_id]->rf_map.card=0;
      PHY_vars_eNB_g[0][CC_id]->rf_map.chain=CC_id+chain_offset;
Raymond Knopp's avatar
 
Raymond Knopp committed
1808
    }
1809
  }
1810

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

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

1816 1817 1818 1819 1820
    
#ifdef OAI_USRP
      UE[CC_id]->hw_timing_advance = timing_advance;
#else
      UE[CC_id]->hw_timing_advance = 160;
1821
#endif
1822 1823 1824 1825
    }
    if (setup_ue_buffers(UE,&openair0_cfg[0])!=0) {
      printf("Error setting up eNB buffer\n");
      exit(-1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1826
    }
1827 1828 1829



1830 1831 1832 1833 1834 1835 1836 1837 1838 1839
    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 {
1840

Raymond Knopp's avatar
 
Raymond Knopp committed
1841

1842

1843

1844

1845
    printf("Setting eNB buffer to all-RX\n");
navid's avatar
navid committed
1846

1847 1848 1849 1850 1851 1852 1853 1854
    // 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;
    }
  }
1855
  sleep(3);
1856

1857

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

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

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

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

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

1878
#endif
1879

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

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

1905 1906
#endif

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

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

1915

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

1919

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

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

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

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