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

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


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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
28
*******************************************************************************/
29

30 31
/*! \file lte-enb.c
 * \brief Top-level threads for eNodeB
32
 * \author R. Knopp, F. Kaltenberger, Navid Nikaein
Raymond Knopp's avatar
 
Raymond Knopp committed
33 34 35
 * \date 2012
 * \version 0.1
 * \company Eurecom
36
 * \email: knopp@eurecom.fr,florian.kaltenberger@eurecom.fr, navid.nikaein@eurecom.fr
Raymond Knopp's avatar
 
Raymond Knopp committed
37 38 39
 * \note
 * \warning
 */
Raymond Knopp's avatar
 
Raymond Knopp committed
40
#define _GNU_SOURCE
41 42 43 44 45 46 47 48
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sched.h>
49
#include <linux/sched.h>
50 51 52
#include <signal.h>
#include <execinfo.h>
#include <getopt.h>
53
#include <sys/sysinfo.h>
54

55 56
#include "T.h"

57
#include "rt_wrapper.h"
58

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

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

#include "PHY/types.h"
65

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

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

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

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

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

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

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

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

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

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

120
// In lte-enb.c
121
extern int setup_eNB_buffers(PHY_VARS_eNB **phy_vars_eNB, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
122
extern void init_eNB(eNB_func_t);
123
extern void stop_eNB(void);
124
extern void kill_eNB_proc(void);
125

126
// In lte-ue.c
127 128
extern int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg, openair0_rf_map rf_map[MAX_NUM_CCs]);
extern void fill_ue_band_info(void);
129 130
extern void init_UE(void);

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

141

142

143 144


Raymond Knopp's avatar
 
Raymond Knopp committed
145

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

150

151 152


153

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

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

161

162
#if defined(ENABLE_ITTI)
163 164
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
165
#endif
166 167
volatile int                    oai_exit = 0;

168

169

Raymond Knopp's avatar
 
Raymond Knopp committed
170

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

175
static char                     threequarter_fs=0;
176

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

180
openair0_rf_map rf_map[MAX_NUM_CCs];
181

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

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

191 192
FILE *input_fd=NULL;

193

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

204 205


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

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

211 212
char   rf_config_file[1024];

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

216

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

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

230

Raymond Knopp's avatar
 
Raymond Knopp committed
231
static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
232
eNB_func_t node_function=eNodeB_3GPP;
233

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

Raymond Knopp's avatar
 
Raymond Knopp committed
240

241 242 243

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
274 275 276

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

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

285 286
openair0_config_t openair0_cfg[MAX_CARDS];

287 288 289
// Change to openair_global to handle UE
openair0_device openair0;

290 291
double cpuf;

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


Raymond Knopp's avatar
 
Raymond Knopp committed
295

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

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

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

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

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

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

356 357 358 359
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
360 361
  } else {
    printf("trying to exit gracefully...\n");
362
    oai_exit = 1;
363 364
  }
}
365
#endif
366 367 368 369 370 371 372 373 374 375 376
#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");
377
  printf("  --rf-config-file Configuration file for front-end (e.g. LMS7002M)\n");
378 379 380 381
  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
382 383
  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");
384
  printf("  --no-L2-connect bypass L2 and upper layers\n");
385 386 387 388
  printf("  --ue-rxgain set UE RX gain\n");
  printf("  --ue-txgain set UE TX gain\n");
  printf("  --ue-scan_carrier set UE to scan around carrier\n");
  printf("  --loop-memory get softmodem (UE) to loop through memory instead of acquiring from HW\n");
389
  printf("  --mmapped-dma sets flag for improved EXMIMO UE performance\n");   
390 391
  printf("  --RCC run using NGFI RCC node function IF4 split\n");
  printf("  --RRU run using NGFI RRU node function  IF4 split\n");
392
  printf("  --eNB run using 3GPP eNB node function\n");   
393
  printf("  --BBU run using 3GPP eNB node function with IF5 split\n");   
394
  printf("  --RRH run using RRH node function with IF5 split\n");
395
  printf("  -C Set the downlink frequency for all component carriers\n");
396 397 398
  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");
399
  printf("  -G Set the global log verbosity \n");
400 401 402 403 404
  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
405
  printf("  -r Set the PRB, valid values: 6, 25, 50, 100  \n");    
406 407
  printf("  -S Skip the missed slots/subframes \n");    
  printf("  -t Set the maximum uplink MCS\n");
408
  printf("  -T Set hardware to TDD mode (default: FDD). Used only with -U (otherwise set in config file).\n");
409 410 411
  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");
412 413 414 415 416 417 418
  printf("  -x Set the transmission mode, valid options: 1 \n");
#if T_TRACER
  printf("  --T_port [port]    use given port\n");
  printf("  --T_nowait         don't wait for tracer, start immediately\n");
#endif
  printf(RESET);
  fflush(stdout);
419
}
420

421 422
void exit_fun(const char* s)
{
Raymond Knopp's avatar
Raymond Knopp committed
423 424
  int CC_id;

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

  oai_exit = 1;
Raymond Knopp's avatar
Raymond Knopp committed
430 431 432 433 434 435 436
  
  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);  
  }
437 438

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

}

445

446
#ifdef XFORMS
447

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

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

461 462 463
      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;
464

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

473 474 475
    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;
476 477 478
  }
}

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

490
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
Raymond Knopp's avatar
 
Raymond Knopp committed
491
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
492

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

495
# ifdef ENABLE_XFORMS_WRITE_STATS
496 497

  if (UE_flag==1)
Raymond Knopp's avatar
 
Raymond Knopp committed
498
    UE_stats  = fopen("UE_stats.txt", "w");
499
  else
Raymond Knopp's avatar
 
Raymond Knopp committed
500
    eNB_stats = fopen("eNB_stats.txt", "w");
501

502
#endif
503

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

511 512 513 514 515
      phy_scope_UE(form_ue[0],
                   PHY_vars_UE_g[0][0],
                   0,
                   0,7);

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

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

528 529 530
      //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);
531

532 533
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
534
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
535
	  if ((PHY_vars_eNB_g[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) {
gauthier's avatar
gauthier committed
536
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
537 538 539 540
			  PHY_vars_eNB_g[0][CC_id],
			  UE_id);
	    ue_cnt++;
	  }
541
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
542
      }
543

544
    }
545

Raymond Knopp's avatar
 
Raymond Knopp committed
546
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
547 548
    //usleep(100000); // 100 ms
    sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
549
  }
550

551
  //  printf("%s",stats_buffer);
552

553
# ifdef ENABLE_XFORMS_WRITE_STATS
554

555 556 557 558 559 560
  if (UE_flag==1) {
    if (UE_stats) {
      rewind (UE_stats);
      fwrite (stats_buffer, 1, len, UE_stats);
      fclose (UE_stats);
    }
561
  } else {
562 563 564 565 566 567
    if (eNB_stats) {
      rewind (eNB_stats);
      fwrite (stats_buffer, 1, len, eNB_stats);
      fclose (eNB_stats);
    }
  }
568

569
# endif
570

Raymond Knopp's avatar
 
Raymond Knopp committed
571
  pthread_exit((void*)arg);
572 573 574
}
#endif

575

576

577

Raymond Knopp's avatar
 
Raymond Knopp committed
578
#if defined(ENABLE_ITTI)
579
void *l2l1_task(void *arg)
580
{
Raymond Knopp's avatar
 
Raymond Knopp committed
581 582 583 584 585
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
586

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

596
      itti_receive_msg (TASK_L2L1, &message_p);
597

598 599 600 601 602 603
      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;
604

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

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

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

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

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

631 632 633
    case ACTIVATE_MESSAGE:
      start_UE = 1;
      break;
634

635 636 637
    case DEACTIVATE_MESSAGE:
      start_UE = 0;
      break;
638

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

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

648 649 650
    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);
651

652 653
  return NULL;
}
Raymond Knopp's avatar
 
Raymond Knopp committed
654
#endif
655

656

657

658

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


671 672

  const Enb_properties_array_t *enb_properties;
673

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

704
  static const struct option long_options[] = {
705
    {"rf-config-file",required_argument,  NULL, LONG_OPTION_RF_CONFIG_FILE},
706 707 708 709 710 711
    {"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
712 713 714 715
    {"calib-prach-tx",   no_argument,        NULL, LONG_OPTION_CALIB_PRACH_TX},
    {"ue-rxgain",   required_argument,  NULL, LONG_OPTION_RXGAIN},
    {"ue-txgain",   required_argument,  NULL, LONG_OPTION_TXGAIN},
    {"ue-scan-carrier",   no_argument,  NULL, LONG_OPTION_SCANCARRIER},
716
    {"ue-max-power",   required_argument,  NULL, LONG_OPTION_MAXPOWER},
717 718
    {"ue-dump-frame", no_argument, NULL, LONG_OPTION_DUMP_FRAME},
    {"loop-memory", required_argument, NULL, LONG_OPTION_LOOPMEMORY},
719
    {"phy-test", no_argument, NULL, LONG_OPTION_PHYTEST},
720
    {"mmapped-dma", no_argument, NULL, LONG_OPTION_MMAPPED_DMA},
721 722 723
    {"RCC", no_argument, NULL, LONG_OPTION_RCC},
    {"RRU", no_argument, NULL, LONG_OPTION_RRU},
    {"eNB", no_argument, NULL, LONG_OPTION_ENB},
724
    {"BBU", no_argument, NULL, LONG_OPTION_ENB_BBU},
725
    {"RRH", no_argument, NULL, LONG_OPTION_RRH},
726 727 728 729
#if T_TRACER
    {"T_port",                 required_argument, 0, LONG_OPTION_T_PORT},
    {"T_nowait",               no_argument,       0, LONG_OPTION_T_NOWAIT},
#endif
730 731 732
    {NULL, 0, NULL, 0}
  };

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

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

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
782 783 784 785
    case LONG_OPTION_CALIB_PRACH_TX:
      mode = calib_prach_tx;
      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
    case LONG_OPTION_TXGAIN:
      for (i=0; i<4; i++)
        tx_gain[0][i] = atof(optarg);
795

796
      break;
797

798 799 800 801 802
    case LONG_OPTION_SCANCARRIER:
      UE_scan_carrier=1;

      break;

803 804 805 806 807 808
    case LONG_OPTION_LOOPMEMORY:
      mode=loop_through_memory;
      input_fd = fopen(optarg,"r");
      AssertFatal(input_fd != NULL,"Please provide an input file\n");
      break;

809 810 811 812
    case LONG_OPTION_DUMP_FRAME:
      mode = rx_dump_frame;
      break;
      
813 814 815
    case LONG_OPTION_PHYTEST:
      phy_test = 1;
      break;
816

817 818 819 820
    case LONG_OPTION_MMAPPED_DMA:
      mmapped_dma = 1;
      break;

821 822 823 824 825 826 827 828 829 830 831
    case LONG_OPTION_RCC:
      node_function = NGFI_RCC_IF4;
      break;

    case LONG_OPTION_RRU:
      node_function = NGFI_RRU_IF4;
      break;

    case LONG_OPTION_ENB:
      node_function = eNodeB_3GPP;
      break;
832 833 834 835

    case LONG_OPTION_ENB_BBU:
      node_function = eNodeB_3GPP_BBU;
      break;
836 837 838 839

    case LONG_OPTION_RRH:
      node_function = NGFI_RRU_IF5;
      break;
840
              
841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
#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;
    }
#endif

856 857 858 859
    case 'A':
      timing_advance = atoi (optarg);
      break;

860
    case 'C':
861 862 863 864 865 866
      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]);
867
      }
868

869
      UE_scan=0;
870

871
      break;
872

Florian Kaltenberger's avatar
Florian Kaltenberger committed
873 874 875 876
    case 'a':
      chain_offset = atoi(optarg);
      break;

877 878 879 880
    case 'd':
#ifdef XFORMS
      do_forms=1;
      printf("Running with XFORMS!\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
881
#endif
882
      break;
883 884 885 886
      
    case 'E':
      threequarter_fs=1;
      break;
887

888 889 890
    case 'K':
#if defined(ENABLE_ITTI)
      itti_dump_file = strdup(optarg);
891
#else
892
      printf("-K option is disabled when ENABLE_ITTI is not defined\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
893
#endif
894
      break;
895

896 897 898
    case 'O':
      conf_config_file_name = optarg;
      break;
899

900 901 902
    case 'U':
      UE_flag = 1;
      break;
903

904 905 906
    case 'm':
      target_dl_mcs = atoi (optarg);
      break;
907

908 909 910
    case 't':
      target_ul_mcs = atoi (optarg);
      break;
911

912 913 914 915 916 917 918
    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");
      /*
919 920 921 922 923 924 925 926
	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);
	}
927 928
      */
      break;
929

930
    case 'P':
931 932
      opt_type = OPT_PCAP;
      opt_enabled=1;
933 934 935 936 937

      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");
938
      } else {
939 940 941
        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);
942
      }
943 944 945

      break;

Raymond Knopp's avatar
 
Raymond Knopp committed
946 947 948
    case 'V':
      ouput_vcd = 1;
      break;
949

Raymond Knopp's avatar
 
Raymond Knopp committed
950
    case  'q':
Raymond Knopp's avatar
 
Raymond Knopp committed
951 952
      opp_enabled = 1;
      break;
953

Raymond Knopp's avatar
 
Raymond Knopp committed
954 955 956
    case  'R' :
      online_log_messages =1;
      break;
957

Raymond Knopp's avatar
 
Raymond Knopp committed
958
    case 'r':
959
      UE_scan = 0;
960

961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986
      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
987
      }
988

989
      break;
990

Raymond Knopp's avatar
 
Raymond Knopp committed
991
    case 's':
992
#if defined(OAI_USRP) || defined(CPRIGW)
Raymond Knopp's avatar
 
Raymond Knopp committed
993 994

      clock_src = atoi(optarg);
995

Raymond Knopp's avatar
 
Raymond Knopp committed
996
      if (clock_src == 0) {
997 998 999 1000 1001
        //  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
1002
      }
1003

Raymond Knopp's avatar
 
Raymond Knopp committed
1004 1005 1006 1007
#else
      printf("Note: -s not defined for ExpressMIMO2\n");
#endif
      break;
1008

1009 1010 1011 1012
    case 'S':
      exit_missed_slots=0;
      printf("Skip exit for missed slots\n");
      break;
1013

1014
    case 'g':
Raymond Knopp's avatar
 
Raymond Knopp committed
1015
      glog_level=atoi(optarg); // value between 1 - 9
1016
      break;
1017 1018 1019

    case 'F':
      break;
1020

1021 1022 1023
    case 'G':
      glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
      break;
1024

1025 1026
    case 'x':
      transmission_mode = atoi(optarg);
1027

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

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

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

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


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

Raymond Knopp's avatar
 
Raymond Knopp committed
1057
    NB_eNB_INST = 1;
1058

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

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

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

1074
      for (j=0; j<enb_properties->properties[i]->nb_rrh_gw; j++) {
1075 1076 1077 1078 1079 1080 1081 1082
        	
        if (enb_properties->properties[i]->rrh_gw_config[j].active == 1 ) {
          local_remote_radio = BBU_REMOTE_RADIO_HEAD;
          (eth_params+j)->local_if_name             = enb_properties->properties[i]->rrh_gw_if_name;
          (eth_params+j)->my_addr                   = enb_properties->properties[i]->rrh_gw_config[j].local_address;
          (eth_params+j)->my_port                   = enb_properties->properties[i]->rrh_gw_config[j].local_port;
          (eth_params+j)->remote_addr               = enb_properties->properties[i]->rrh_gw_config[j].remote_address;
          (eth_params+j)->remote_port               = enb_properties->properties[i]->rrh_gw_config[j].remote_port;
1083 1084 1085 1086 1087 1088 1089
          
          if (enb_properties->properties[i]->rrh_gw_config[j].raw == 1) {
            (eth_params+j)->transp_preference       = ETH_RAW_MODE; 
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif4 == 1) {
            (eth_params+j)->transp_preference       = ETH_RAW_IF4_MODE;             
          } else if (enb_properties->properties[i]->rrh_gw_config[j].udpif4 == 1) {
            (eth_params+j)->transp_preference       = ETH_UDP_IF4_MODE;             
1090 1091
          } else if (enb_properties->properties[i]->rrh_gw_config[j].rawif5_mobipass == 1) {
            (eth_params+j)->transp_preference       = ETH_RAW_IF5_MOBIPASS;             
1092 1093 1094 1095
          } else {
            (eth_params+j)->transp_preference       = ETH_UDP_MODE;	 
          }
          
1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
          (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; 
        }
1115 1116 1117
	
      }

1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
        frame_parms[CC_id]->frame_type =       enb_properties->properties[i]->frame_type[CC_id];
        frame_parms[CC_id]->tdd_config =       enb_properties->properties[i]->tdd_config[CC_id];
        frame_parms[CC_id]->tdd_config_S =     enb_properties->properties[i]->tdd_config_s[CC_id];
        frame_parms[CC_id]->Ncp =              enb_properties->properties[i]->prefix_type[CC_id];

        //for (j=0; j < enb_properties->properties[i]->nb_cc; j++ ){
        frame_parms[CC_id]->Nid_cell            =  enb_properties->properties[i]->Nid_cell[CC_id];
        frame_parms[CC_id]->N_RB_DL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
        frame_parms[CC_id]->N_RB_UL             =  enb_properties->properties[i]->N_RB_DL[CC_id];
        frame_parms[CC_id]->nb_antennas_tx      =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
        frame_parms[CC_id]->nb_antennas_tx_eNB  =  enb_properties->properties[i]->nb_antennas_tx[CC_id];
        frame_parms[CC_id]->nb_antennas_rx      =  enb_properties->properties[i]->nb_antennas_rx[CC_id];
        //} // j
Raymond Knopp's avatar
 
Raymond Knopp committed
1132 1133
      }

1134

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

      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");
1148
      }
1149

1150
      init_predef_traffic(enb_properties->properties[i]->num_otg_elements, 1);
1151 1152


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

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

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 */
#endif

1208 1209
int main( int argc, char **argv )
{
1210
  int i,aa,card=0;
1211
#if defined (XFORMS)
Raymond Knopp's avatar
 
Raymond Knopp committed
1212
  void *status;
1213
#endif
1214

Raymond Knopp's avatar
 
Raymond Knopp committed
1215
  int CC_id;
Raymond Knopp's avatar
 
Raymond Knopp committed
1216
  uint16_t Nid_cell = 0;
1217
  uint8_t  cooperation_flag=0,  abstraction_flag=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1218
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
1219

Raymond Knopp's avatar
 
Raymond Knopp committed
1220
#if defined (XFORMS)
1221 1222
  int ret;
#endif
1223

1224 1225 1226 1227 1228
#ifdef DEBUG_CONSOLE
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);
#endif

1229 1230 1231
  PHY_VARS_UE *UE[MAX_NUM_CCs];

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

1234
  memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
Raymond Knopp's avatar
 
Raymond Knopp committed
1235
  set_latency_target();
1236

1237
  // det defaults
1238
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1239 1240
    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 */
1241
    frame_parms[CC_id]->frame_type          = FDD;
Raymond Knopp's avatar
 
Raymond Knopp committed
1242 1243
    frame_parms[CC_id]->tdd_config          = 3;
    frame_parms[CC_id]->tdd_config_S        = 0;
1244 1245
    frame_parms[CC_id]->N_RB_DL             = 100;
    frame_parms[CC_id]->N_RB_UL             = 100;
Raymond Knopp's avatar
 
Raymond Knopp committed
1246
    frame_parms[CC_id]->Ncp                 = NORMAL;
Raymond Knopp's avatar
 
Raymond Knopp committed
1247 1248
    frame_parms[CC_id]->Ncp_UL              = NORMAL;
    frame_parms[CC_id]->Nid_cell            = Nid_cell;
Raymond Knopp's avatar
 
Raymond Knopp committed
1249
    frame_parms[CC_id]->num_MBSFN_config    = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1250 1251 1252
    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;
Raymond Knopp's avatar
 
Raymond Knopp committed
1253
  }
1254

1255 1256 1257 1258 1259
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    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];
1260
    //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
1261
  }
1262 1263
  logInit();
 
1264
  rf_config_file[0]='\0';
1265
  get_options (argc, argv); //Command-line options
1266 1267 1268 1269
  if (rf_config_file[0] == '\0')
    openair0_cfg[0].configFilename = NULL;
  else
    openair0_cfg[0].configFilename = rf_config_file;
1270
  
1271 1272 1273 1274
#if T_TRACER
  T_init(T_port, T_wait);
#endif

1275
  // initialize the log (see log.h for details)
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1276 1277
  set_glog(glog_level, glog_verbosity);

1278 1279
  //randominit (0);
  set_taus_seed (0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1280

1281 1282
  if (UE_flag==1) {
    printf("configuring for UE\n");
1283

1284 1285
    set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
    set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
1286 1287 1288 1289 1290
    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);
1291
#if defined(ENABLE_ITTI)
1292
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1293
# if defined(ENABLE_USE_MME)
1294
    set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
1295 1296
# endif
#endif
1297 1298
  } else {
    printf("configuring for eNB\n");
1299

1300 1301 1302 1303 1304 1305 1306 1307
    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);
1308
#if defined(ENABLE_ITTI)
1309
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1310
# if defined(ENABLE_USE_MME)
1311 1312 1313 1314
    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);
1315
# endif
1316
#if defined(ENABLE_SECURITY)
1317
    set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
1318
#endif
1319
#endif
1320
#ifdef LOCALIZATION
1321 1322 1323 1324 1325 1326 1327 1328 1329
    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
1330
    }
1331
  }
1332

Raymond Knopp's avatar
 
Raymond Knopp committed
1333 1334
  if (ouput_vcd) {
    if (UE_flag==1)
1335
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1336
    else
1337
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1338
  }
1339

1340
  if (opp_enabled ==1){
1341
    reset_opp_meas();
1342 1343
  }
  cpuf=get_cpu_freq_GHz();
1344

1345
#if defined(ENABLE_ITTI)
1346

Raymond Knopp's avatar
 
Raymond Knopp committed
1347 1348
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
1349
  } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1350 1351
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
1352

Raymond Knopp's avatar
 
Raymond Knopp committed
1353
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
1354
 
1355 1356
  // initialize mscgen log after ITTI
  MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
1357 1358
#endif
 
1359 1360
  if (opt_type != OPT_NONE) {
    radio_type_t radio_type;
1361

1362 1363
    if (frame_parms[0]->frame_type == FDD)
      radio_type = RADIO_TYPE_FDD;
1364
    else
1365
      radio_type = RADIO_TYPE_TDD;
1366

1367 1368 1369
    if (init_opt(in_path, in_ip, NULL, radio_type) == -1)
      LOG_E(OPT,"failed to run OPT \n");
  }
1370

1371
#ifdef PDCP_USE_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
1372
  netlink_init();
1373 1374 1375
#if defined(PDCP_USE_NETLINK_QUEUES)
  pdcp_netlink_init();
#endif
1376 1377
#endif

1378
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1379 1380 1381
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
1382
#endif
1383

1384

Raymond Knopp's avatar
 
Raymond Knopp committed
1385 1386 1387
  check_clock();

  // init the parameters
1388
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1389
    frame_parms[CC_id]->nushift            = 0;
1390

1391 1392 1393 1394 1395 1396 1397 1398 1399
    if (UE_flag==0) {

    } else {
      //UE_flag==1
      frame_parms[CC_id]->nb_antennas_tx     = 1;
      frame_parms[CC_id]->nb_antennas_rx     = 1;
      frame_parms[CC_id]->nb_antennas_tx_eNB = (transmission_mode == 1) ? 1 : 2; //initial value overwritten by initial sync later
    }

Raymond Knopp's avatar
 
Raymond Knopp committed
1400 1401 1402 1403 1404 1405 1406 1407
    frame_parms[CC_id]->mode1_flag         = (transmission_mode == 1) ? 1 : 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;
1408
    frame_parms[CC_id]->threequarter_fs = threequarter_fs;
1409 1410
    init_ul_hopping(frame_parms[CC_id]);
    init_frame_parms(frame_parms[CC_id],1);
1411 1412
    //   phy_init_top(frame_parms[CC_id]);
    phy_init_lte_top(frame_parms[CC_id]);
Raymond Knopp's avatar
 
Raymond Knopp committed
1413 1414 1415
  }


1416
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1417
    //init prach for openair1 test
1418
    frame_parms[CC_id]->prach_config_common.rootSequenceIndex=22;
Raymond Knopp's avatar
 
Raymond Knopp committed
1419
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.zeroCorrelationZoneConfig=1;
1420
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_ConfigIndex=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1421 1422 1423
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.highSpeedFlag=0;
    frame_parms[CC_id]->prach_config_common.prach_ConfigInfo.prach_FreqOffset=0;
    // 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
1424
    // N_ZC = (prach_fmt <4)?839:139;
Raymond Knopp's avatar
 
Raymond Knopp committed
1425
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1426 1427

  if (UE_flag==1) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1428 1429 1430
    NB_UE_INST=1;
    NB_INST=1;

Raymond Knopp's avatar
 
Raymond Knopp committed
1431 1432
    PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**));
    PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
1433 1434

    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1435 1436 1437 1438

      PHY_vars_UE_g[0][CC_id] = init_lte_UE(frame_parms[CC_id], 0,abstraction_flag,transmission_mode);
      UE[CC_id] = PHY_vars_UE_g[0][CC_id];
      printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]);
1439

1440 1441 1442 1443
      if (phy_test==1)
	UE[CC_id]->mac_enabled = 0;
      else 
	UE[CC_id]->mac_enabled = 1;
1444

1445
      if (UE[CC_id]->mac_enabled == 0) {  //set default UL parameters for testing mode
1446 1447 1448 1449 1450 1451 1452 1453 1454
	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
1455
      }
1456

1457
      UE[CC_id]->UE_scan = UE_scan;
1458
      UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
1459 1460
      UE[CC_id]->mode    = mode;

1461 1462
      compute_prach_seq(&UE[CC_id]->frame_parms.prach_config_common,
                        UE[CC_id]->frame_parms.frame_type,
1463 1464
                        UE[CC_id]->X_u);

1465
      if (UE[CC_id]->mac_enabled == 1) 
1466
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1234;
1467
      else
1468
	UE[CC_id]->pdcch_vars[0]->crnti = 0x1235;
1469 1470

      UE[CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0];
1471 1472
      UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
      UE[CC_id]->N_TA_offset = 0;
1473

Raymond Knopp's avatar
 
Raymond Knopp committed
1474
    }
1475

Raymond Knopp's avatar
 
Raymond Knopp committed
1476
    //  printf("tx_max_power = %d -> amp %d\n",tx_max_power,get_tx_amp(tx_max_power,tx_max_power));
1477 1478 1479 1480 1481 1482
  } 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++) {
1483
      PHY_vars_eNB_g[0][CC_id] = init_lte_eNB(frame_parms[CC_id],0,frame_parms[CC_id]->Nid_cell,cooperation_flag,transmission_mode,abstraction_flag);
1484 1485
      PHY_vars_eNB_g[0][CC_id]->CC_id = CC_id;

1486 1487
      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;
1488

1489
      if (PHY_vars_eNB_g[0][CC_id]->mac_enabled == 0) { //set default parameters for testing mode
1490 1491 1492 1493 1494 1495 1496 1497 1498
	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;
	}
1499 1500
      }

1501 1502
      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,
1503
                        PHY_vars_eNB_g[0][CC_id]->X_u);
Raymond Knopp's avatar
 
Raymond Knopp committed
1504

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

1507
      PHY_vars_eNB_g[0][CC_id]->N_TA_offset = 0;
1508

1509
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1510 1511


1512 1513 1514 1515
    NB_eNB_INST=1;
    NB_INST=1;

  }
1516

1517 1518
  fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
  cpuf=get_cpu_freq_GHz();
1519

1520

Raymond Knopp's avatar
 
Raymond Knopp committed
1521
  dump_frame_parms(frame_parms[0]);
1522

1523 1524
  for (card=0; card<MAX_CARDS; card++) {

1525
    openair0_cfg[card].mmapped_dma=mmapped_dma;
1526

1527
    if(frame_parms[0]->N_RB_DL == 100) {
1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539
      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;
      }
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555
    } 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;
    }
1556 1557 1558 1559 1560 1561

    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;

1562
    
1563 1564 1565 1566 1567
    if (local_remote_radio == BBU_REMOTE_RADIO_HEAD) {      
      openair0_cfg[card].remote_addr    = eth_params->remote_addr;
      openair0_cfg[card].remote_port    = eth_params->remote_port;
      openair0_cfg[card].my_addr        = eth_params->my_addr;
      openair0_cfg[card].my_port        = eth_params->my_port;    
1568 1569
    } 
    
1570
    printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
1571 1572
           ((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));
Raymond Knopp's avatar
 
Raymond Knopp committed
1573 1574
    openair0_cfg[card].Mod_id = 0;
#ifdef ETHERNET
1575 1576

    if (UE_flag) {
Raymond Knopp's avatar
 
Raymond Knopp committed
1577
      printf("ETHERNET: Configuring UE ETH for %s:%d\n",rrh_UE_ip,rrh_UE_port);
1578
      openair0_cfg[card].remote_addr   = &rrh_UE_ip[0];
1579
      openair0_cfg[card].remote_port = rrh_UE_port;
1580 1581
    } 

1582
    openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
Raymond Knopp's avatar
 
Raymond Knopp committed
1583
#endif
1584

1585
    // in the case of the USRP, the following variables need to be initialized before the init
1586
    // since the USRP only supports one CC (for the moment), we initialize all the cards with first CC.
1587
    // in the case of EXMIMO2, these values are overwirtten in the function setup_eNB/UE_buffer
1588

1589 1590
    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));
1591 1592

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

Raymond Knopp's avatar
Raymond Knopp committed
1594 1595 1596 1597 1598 1599 1600 1601 1602 1603
      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;

1604 1605 1606 1607 1608 1609
      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]);
      
1610
      openair0_cfg[card].autocal[i] = 1;
1611
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
1612
      if (UE_flag == 0) {
1613
	openair0_cfg[card].rx_gain[i] = PHY_vars_eNB_g[0][0]->rx_total_gain_dB;
1614 1615
      }
      else {
1616
	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB;
1617
      }
1618 1619


Raymond Knopp's avatar
 
Raymond Knopp committed
1620
    }
1621

1622

Raymond Knopp's avatar
 
Raymond Knopp committed
1623
  }
1624

laurent's avatar
laurent committed
1625
#ifndef DEADLINE_SCHEDULER
1626

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

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

  if (UE_flag == 0) {
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1671 1672 1673
      if (node_function == NGFI_RRU_IF4 || node_function == NGFI_RRU_IF5) {
        PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = RRH_HOST;
        PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = RRH_HOST;
1674
      } else {
1675 1676
        PHY_vars_eNB_g[0][CC_id]->rfdevice.host_type = BBU_HOST;
        PHY_vars_eNB_g[0][CC_id]->ifdevice.host_type = BBU_HOST;
1677
      }
1678
    }
1679
  }
1680 1681 1682 1683 1684 1685
  /* device host type is set*/
  openair0.host_type = BBU_HOST;
  /* device type is initialized NONE_DEV (no RF device) when the RF device will be initiated device type will be set */
  openair0.type = NONE_DEV;
  /* transport type is initialized NONE_TP (no transport protocol) when the transport protocol will be initiated transport protocol type will be set */
  openair0.transp_type = NONE_TP;
1686 1687 1688 1689 1690
  
  // Legacy BBU - RRH init  
  //int returns=-1;
  ///* BBU can have either a local or a remote radio head */  
  //if (local_remote_radio == BBU_LOCAL_RADIO_HEAD) { //local radio head active  - load library of radio head and initiate it
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700
  //if (mode!=loop_through_memory) {
  //returns=openair0_device_load(&openair0, &openair0_cfg[0]);
  //printf("openair0_device_init returns %d\n",returns);
  //if (returns<0) {
  //printf("Exiting, cannot initialize device\n");
  //exit(-1);
  //}
  //}
  //else if (mode==loop_through_memory) {    
  //}
1701
  //}  else { //remote radio head active - load library of transport protocol and initiate it 
1702 1703 1704 1705 1706 1707 1708 1709 1710 1711
  //if (mode!=loop_through_memory) {
  //returns=openair0_transport_load(&openair0, &openair0_cfg[0], eth_params);
  //printf("openair0_transport_init returns %d\n",returns);
  //if (returns<0) { 
  //printf("Exiting, cannot initialize transport protocol\n");
  //exit(-1);
  //}
  //}
  //else if (mode==loop_through_memory) {    
  //}
1712
  //}   
1713
    
1714
  int returns=-1;
1715 1716
    
  // Handle spatially distributed MIMO antenna ports   
1717
  // Load RF device and initialize
1718
  if (node_function == NGFI_RRU_IF5 || node_function == NGFI_RRU_IF4 || node_function == eNodeB_3GPP) { 
1719 1720
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {  
      if (mode!=loop_through_memory) {
1721 1722
        returns= (UE_flag == 0) ? 
	  openair0_device_load(&(PHY_vars_eNB_g[0][CC_id]->rfdevice), &openair0_cfg[0]) :
1723
	  openair0_device_load(&openair0, &openair0_cfg[0]);
1724

1725 1726
        printf("openair0_device_init returns %d for CC_id %d\n",returns,CC_id);
        if (returns<0) {
1727 1728
	  printf("Exiting, cannot initialize device\n");
	  exit(-1);
1729
        }
1730
      }
1731 1732
      else if (mode==loop_through_memory) {    
      }    
1733
    }
1734 1735 1736
  }  
  
  // Load transport protocol and initialize
1737

1738
  if ((UE_flag==0) && (node_function != eNodeB_3GPP)){ 
1739 1740 1741 1742 1743
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {  
      if (mode!=loop_through_memory) {
        returns=openair0_transport_load(&(PHY_vars_eNB_g[0][CC_id]->ifdevice), &openair0_cfg[0], (eth_params+CC_id));
        printf("openair0_transport_init returns %d for CC_id %d\n",returns,CC_id);
        if (returns<0) {
1744 1745
	  printf("Exiting, cannot initialize transport protocol\n");
	  exit(-1);
1746
        }
1747
      }
1748 1749
      else if (mode==loop_through_memory) {    
      }    
1750
    }
1751
  }
1752

1753
  printf("Done initializing RF and IF devices\n");
1754
  
1755 1756
  mac_xface = malloc(sizeof(MAC_xface));

Raymond Knopp's avatar
 
Raymond Knopp committed
1757
  int eMBMS_active=0;
1758
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1759
  l2_init(frame_parms[0],eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,
1760 1761 1762
	  0,// cba_group_active
	  0); // HO flag
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1763
  mac_xface->macphy_exit = &exit_fun;
1764

winckel's avatar
winckel committed
1765
#if defined(ENABLE_ITTI)
1766

Raymond Knopp's avatar
 
Raymond Knopp committed
1767
  if (create_tasks(UE_flag ? 0 : 1, UE_flag ? 1 : 0) < 0) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1768
    printf("cannot create ITTI tasks\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1769 1770
    exit(-1); // need a softer mode
  }
1771

Raymond Knopp's avatar
 
Raymond Knopp committed
1772
  printf("ITTI tasks created\n");
winckel's avatar
winckel committed
1773
#endif
Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
1774

1775 1776 1777 1778 1779 1780 1781 1782
  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);
    } else
      mac_xface->mrbch_phy_sync_failure (0, 0, 0);
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1783

1784
  number_of_cards = 1;
1785

1786

1787
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1788
    rf_map[CC_id].card=0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1789
    rf_map[CC_id].chain=CC_id+chain_offset;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1790
  }
1791

Raymond Knopp's avatar
 
Raymond Knopp committed
1792 1793
  // connect the TX/RX buffers
  if (UE_flag==1) {
1794 1795 1796 1797

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

    
1798
#ifdef OAI_USRP
1799
      UE[CC_id]->hw_timing_advance = timing_advance;
1800
#else
1801
      UE[CC_id]->hw_timing_advance = 160;
1802
#endif
1803
    }
1804
    if (setup_ue_buffers(UE,&openair0_cfg[0],rf_map)!=0) {
1805 1806 1807
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }
1808 1809 1810



1811 1812
    if (input_fd) {
      printf("Reading in from file to antenna buffer %d\n",0);
1813
      if (fread(UE[0]->common_vars.rxdata[0],
1814 1815 1816 1817
	        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");
1818
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1819
    //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
1820
  } else {
1821 1822


1823

1824 1825 1826 1827
    if (setup_eNB_buffers(PHY_vars_eNB_g[0],&openair0_cfg[0],rf_map)!=0) {
      printf("Error setting up eNB buffer\n");
      exit(-1);
    }
1828

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

1831
    // Set LSBs for antenna switch (ExpressMIMO)
1832
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
1833
      PHY_vars_eNB_g[0][CC_id]->hw_timing_advance = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1834
      for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
1835
        for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
1836
          PHY_vars_eNB_g[0][CC_id]->common_vars.txdata[0][aa][i] = 0x00010001;
Raymond Knopp's avatar
 
Raymond Knopp committed
1837
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1838
  }
1839

Raymond Knopp's avatar
 
Raymond Knopp committed
1840
  mlockall(MCL_CURRENT | MCL_FUTURE);
1841

Raymond Knopp's avatar
 
Raymond Knopp committed
1842 1843
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
1844 1845

#ifdef XFORMS
1846 1847
  int UE_id;

Raymond Knopp's avatar
 
Raymond Knopp committed
1848 1849
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
1850 1851

    if (UE_flag==0) {
1852
      form_stats_l2 = create_form_stats_form();
1853 1854 1855
      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");
1856 1857

      for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869
	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");
	  }
1870 1871
	} // CC_id
      } // UE_id
1872
    } else {
1873 1874 1875 1876 1877 1878 1879
      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);

1880
      /*
1881
	if (openair_daq_vars.use_ia_receiver) {
1882 1883
        fl_set_button(form_ue[UE_id]->button_0,1);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
1884
	} else {
1885 1886
        fl_set_button(form_ue[UE_id]->button_0,0);
        fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
1887
	}*/
1888 1889
      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
1890 1891
    }

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

1894 1895
    if (ret == 0)
      pthread_setname_np( forms_thread, "xforms" );
1896

Raymond Knopp's avatar
 
Raymond Knopp committed
1897 1898
    printf("Scope thread created, ret=%d\n",ret);
  }
1899

1900 1901
#endif

1902
  rt_sleep_ns(10*100000000ULL);
1903

1904

1905

Raymond Knopp's avatar
 
Raymond Knopp committed
1906
  // start the main thread
1907
  if (UE_flag == 1) init_UE();
1908
  else init_eNB(node_function);
1909

Raymond Knopp's avatar
 
Raymond Knopp committed
1910
  // Sleep to allow all threads to setup
1911
  sleep(3);
Raymond Knopp's avatar
 
Raymond Knopp committed
1912

1913

1914

1915

1916
  // *** Handle per CC_id openair0
1917

1918

1919
  printf("Sending sync to all threads\n");
1920

Raymond Knopp's avatar
 
Raymond Knopp committed
1921
  pthread_mutex_lock(&sync_mutex);
1922
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1923 1924
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
1925

Raymond Knopp's avatar
 
Raymond Knopp committed
1926 1927 1928
  // wait for end of program
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
1929 1930

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1931 1932
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
1933
  oai_exit=1;
1934
#else
1935

Raymond Knopp's avatar
 
Raymond Knopp committed
1936
  while (oai_exit==0)
1937
    rt_sleep_ns(100000000ULL);
1938

1939
#endif
1940

Raymond Knopp's avatar
 
Raymond Knopp committed
1941
  // stop threads
1942
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
1943
  printf("waiting for XFORMS thread\n");
1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957

  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++) {
1958 1959 1960 1961
	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
1962
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1963
    }
1964 1965
  }

1966 1967
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1970 1971
  // cleanup
  if (UE_flag == 1) {
1972
  } else {
1973
    stop_eNB();
Raymond Knopp's avatar
 
Raymond Knopp committed
1974
  }
1975

1976

Raymond Knopp's avatar
 
Raymond Knopp committed
1977 1978
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
1979

Raymond Knopp's avatar
Raymond Knopp committed
1980 1981 1982
  // *** Handle per CC_id openair0
  if (UE_flag==1)
    openair0.trx_end_func(&openair0);
1983

1984
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
Raymond Knopp's avatar
Raymond Knopp committed
1985 1986 1987 1988
    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);  
1989
  }
1990

Raymond Knopp's avatar
 
Raymond Knopp committed
1991
  if (ouput_vcd)
1992
    VCD_SIGNAL_DUMPER_CLOSE();
1993

1994
  if (opt_enabled == 1)
1995
    terminate_opt();
1996

Raymond Knopp's avatar
 
Raymond Knopp committed
1997
  logClean();
1998

Raymond Knopp's avatar
 
Raymond Knopp committed
1999 2000
  return 0;
}
2001 2002


2003

2004

2005 2006 2007