lte-softmodem.c 40.8 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
 */
32

33

34

35 36
#include "T.h"

37
#include "rt_wrapper.h"
38

39

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

42
#include "assertions.h"
43
#include "msc.h"
44 45

#include "PHY/types.h"
46

47
#include "PHY/defs.h"
48
#include "common/ran_context.h"
49
#include "common/config/config_userapi.h"
50

51
#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
52
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
53

Raymond Knopp's avatar
 
Raymond Knopp committed
54
#include "../../ARCH/COMMON/common_lib.h"
55
#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
Raymond Knopp's avatar
 
Raymond Knopp committed
56

Raymond Knopp's avatar
 
Raymond Knopp committed
57
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
58 59 60 61 62 63 64 65 66

#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"
67
#include "LAYER2/MAC/proto.h"
68 69 70 71 72 73 74 75
#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
76
#include "UTIL/OTG/otg_tx.h"
77
#include "UTIL/OTG/otg_externs.h"
78 79
#include "UTIL/MATH/oml.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
80
#include "UTIL/OPT/opt.h"
81
#include "enb_config.h"
Navid Nikaein's avatar
Navid Nikaein committed
82
//#include "PHY/TOOLS/time_meas.h"
83

Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
84 85 86 87
#ifndef OPENAIR2
#include "UTIL/OTG/otg_vars.h"
#endif

88
#if defined(ENABLE_ITTI)
89 90
#include "intertask_interface_init.h"
#include "create_tasks.h"
91 92
#endif

93 94
#include "system.h"

95 96 97
#ifdef XFORMS
#include "PHY/TOOLS/lte_phy_scope.h"
#include "stats.h"
98
#endif
99
#include "lte-softmodem.h"
100

101

102
#ifdef XFORMS
103
// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0)
104
// at eNB 0, an UL scope for every UE
105
FD_lte_phy_scope_ue  *form_ue[NUMBER_OF_UE_MAX];
106
FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
107
FD_stats_form                  *form_stats=NULL,*form_stats_l2=NULL;
108
char title[255];
109
unsigned char                   scope_enb_num_ue = 2;
110
static pthread_t                forms_thread; //xforms
111 112
#endif //XFORMS

Raymond Knopp's avatar
 
Raymond Knopp committed
113 114
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
115
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
116

117 118
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
119

120
#if defined(ENABLE_ITTI)
121 122
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
123
#endif
Raymond Knopp's avatar
Raymond Knopp committed
124
volatile int             oai_exit = 0;
125

126
static clock_source_t clock_source = internal;
127
static int wait_for_sync = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
128

Raymond Knopp's avatar
Raymond Knopp committed
129
static char              UE_flag=0;
130
unsigned int                    mmapped_dma=0;
131
int                             single_thread_flag=1;
132

133
static char                     threequarter_fs=0;
134

135
uint32_t                 downlink_frequency[MAX_NUM_CCs][4];
136
int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
Lionel Gauthier's avatar
Lionel Gauthier committed
137

138

139
static char                    *conf_config_file_name = NULL;
140
#if defined(ENABLE_ITTI)
141
static char                    *itti_dump_file = NULL;
Raymond Knopp's avatar
 
Raymond Knopp committed
142 143
#endif

144
int UE_scan = 1;
145
int UE_scan_carrier = 0;
146 147
runmode_t mode = normal_txrx;

148 149
FILE *input_fd=NULL;

150

151 152
#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
153 154
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}};
155 156 157 158
#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
159
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
160

161
double rx_gain_off = 0.0;
162

Raymond Knopp's avatar
 
Raymond Knopp committed
163
double sample_rate=30.72e6;
164
double bw = 10.0e6;
165

166
static int                      tx_max_power[MAX_NUM_CCs]; /* =  {0,0}*/;
167

168 169
char   rf_config_file[1024];

Florian Kaltenberger's avatar
Florian Kaltenberger committed
170
int chain_offset=0;
171
int phy_test = 0;
172
uint8_t usim_test = 0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
173

174 175 176
uint8_t dci_Format = 0;
uint8_t agregation_Level =0xFF;

177 178
uint8_t nb_antenna_tx = 1;
uint8_t nb_antenna_rx = 1;
179

Raymond Knopp's avatar
 
Raymond Knopp committed
180 181 182
char ref[128] = "internal";
char channels[128] = "0";

183
int                      rx_input_level_dBm;
184
static int                      online_log_messages=0;
185
#ifdef XFORMS
186
extern int                      otg_enabled;
187
static char                     do_forms=0;
188
#else
189
int                             otg_enabled;
190
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
191
//int                             number_of_cards =   1;
192

193 194

static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
Florian Kaltenberger's avatar
Florian Kaltenberger committed
195
uint32_t target_dl_mcs = 28; //maximum allowed mcs
196
uint32_t target_ul_mcs = 20;
197
uint32_t timing_advance = 0;
198 199
uint8_t exit_missed_slots=1;
uint64_t num_missed_slots=0; // counter for the number of missed slots
200

201

202 203
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
204

205
int transmission_mode=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
206

207
int16_t           glog_level         = LOG_INFO;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
208
int16_t           glog_verbosity     = LOG_MED;
209
int16_t           hw_log_level       = LOG_INFO;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
210
int16_t           hw_log_verbosity   = LOG_MED;
211
int16_t           phy_log_level      = LOG_DEBUG;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
212
int16_t           phy_log_verbosity  = LOG_MED;
213
int16_t           mac_log_level      = LOG_DEBUG;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
214
int16_t           mac_log_verbosity  = LOG_MED;
215
int16_t           rlc_log_level      = LOG_INFO;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
216
int16_t           rlc_log_verbosity  = LOG_MED;
217
int16_t           pdcp_log_level     = LOG_INFO;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
218
int16_t           pdcp_log_verbosity = LOG_MED;
219
int16_t           rrc_log_level      = LOG_INFO;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
220
int16_t           rrc_log_verbosity  = LOG_MED;
221 222 223
int16_t           opt_log_level      = LOG_INFO;
int16_t           opt_log_verbosity  = LOG_MED;

Lionel Gauthier's avatar
 
Lionel Gauthier committed
224 225 226 227 228 229
# 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
230 231 232
#if defined (ENABLE_SECURITY)
int16_t           osa_log_level      = LOG_INFO;
int16_t           osa_log_verbosity  = LOG_MED;
233
#endif
234

235 236 237
/* struct for ethernet specific parameters given in eNB conf file */
eth_params_t *eth_params;

238 239 240 241
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

242 243
extern char uecap_xer[1024];
char uecap_xer_in=0;
244

245
int oaisim_flag=0;
246
threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
Raymond Knopp's avatar
 
Raymond Knopp committed
247

Cedric Roux's avatar
Cedric Roux committed
248 249 250 251
/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed
 * this is very hackish - find a proper solution
 */
uint8_t abstraction_flag=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
252

253 254 255 256 257
/*---------------------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 };

258
struct timespec clock_difftime(struct timespec start, struct timespec end) {
259 260 261 262 263 264 265 266 267
  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;
268 269
}

270
void print_difftimes(void) {
271
#ifdef DEBUG
272
  printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
273
#else
274
  LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
275 276 277
#endif
}

278
void update_difftimes(struct timespec start, struct timespec end) {
279 280 281
  struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
  int             changed = 0;
  diff_time = clock_difftime(start, end);
282 283 284 285 286 287 288 289
  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;
  }
290
#if 1
291
  if (changed) print_difftimes();
292 293 294 295 296
#endif
}

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

297
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) {
Raymond Knopp's avatar
 
Raymond Knopp committed
298
  return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
299
}
300
unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) {
Raymond Knopp's avatar
 
Raymond Knopp committed
301
  return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
302 303
}

304
#if !defined(ENABLE_ITTI)
305
void signal_handler(int sig) {
306 307 308 309 310 311
  void *array[10];
  size_t size;

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

313 314 315 316
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
317 318
  } else {
    printf("trying to exit gracefully...\n");
319
    oai_exit = 1;
320 321
  }
}
322
#endif
323 324 325 326 327 328
#define KNRM  "\x1B[0m"
#define KRED  "\x1B[31m"
#define KGRN  "\x1B[32m"
#define KBLU  "\x1B[34m"
#define RESET "\033[0m"

329

Raymond Knopp's avatar
Raymond Knopp committed
330

331 332
void exit_fun(const char* s)
{
Raymond Knopp's avatar
Raymond Knopp committed
333
  int CC_id;
334
  int ru_id;
Raymond Knopp's avatar
Raymond Knopp committed
335

336
  if (s != NULL) {
337
    printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s);
338 339 340
  }

  oai_exit = 1;
341 342 343 344 345 346 347 348 349 350

  if (UE_flag==0) {
    for (ru_id=0; ru_id<RC.nb_RU;ru_id++) {
      if (RC.ru[ru_id]->rfdevice.trx_end_func)
	RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);
      if (RC.ru[ru_id]->ifdevice.trx_end_func)
	RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);  
    }
  }

Raymond Knopp's avatar
Raymond Knopp committed
351
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
352 353 354 355

    oai_exit = 1;

    for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
356 357 358 359 360
      if (UE_flag == 0) {
      } 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
361
    }
362 363

#if defined(ENABLE_ITTI)
364 365
    sleep(1); //allow lte-softmodem threads to exit first
    itti_terminate_tasks (TASK_UNKNOWN);
366
#endif
367

368
  }
369

370
}
371

372
#ifdef XFORMS
373

374

375 376
void reset_stats(FL_OBJECT *button, long arg)
{
377
  int i,j,k;
378
  PHY_VARS_eNB *phy_vars_eNB = RC.eNB[0][0];
379 380 381

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    for (k=0; k<8; k++) { //harq_processes
382
      for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) {
383 384 385
	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;
386
      }
387

388 389 390
      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;
391 392


393 394 395
      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;
396 397 398 399
    }
  }
}

400
static void *scope_thread(void *arg) {
Raymond Knopp's avatar
 
Raymond Knopp committed
401
  char stats_buffer[16384];
402
# ifdef ENABLE_XFORMS_WRITE_STATS
Raymond Knopp's avatar
 
Raymond Knopp committed
403
  FILE *UE_stats, *eNB_stats;
404
# endif
Florian Kaltenberger's avatar
 
Florian Kaltenberger committed
405
  int len = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
406
  struct sched_param sched_param;
407
  int UE_id, CC_id;
408
  int ue_cnt=0;
409

410
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
Raymond Knopp's avatar
 
Raymond Knopp committed
411
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
412

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

415
# ifdef ENABLE_XFORMS_WRITE_STATS
416 417

  if (UE_flag==1)
Raymond Knopp's avatar
 
Raymond Knopp committed
418
    UE_stats  = fopen("UE_stats.txt", "w");
419
  else
Raymond Knopp's avatar
 
Raymond Knopp committed
420
    eNB_stats = fopen("eNB_stats.txt", "w");
421

422
#endif
423

Raymond Knopp's avatar
 
Raymond Knopp committed
424 425
  while (!oai_exit) {
    if (UE_flag==1) {
426
      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
427 428 429
      //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);
430

431
      phy_scope_UE(form_ue[0],
432 433 434 435
		   PHY_vars_UE_g[0][0],
		   0,
		   0,7);

436

Raymond Knopp's avatar
 
Raymond Knopp committed
437
    } else {
438
      /*
439
	if (RC.eNB[0][0]->mac_enabled==1) {
440 441 442 443
	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);
444 445
	}
	len = dump_eNB_stats (RC.eNB[0][0], stats_buffer, 0);
446

447 448
	if (MAX_NUM_CCs>1)
	len += dump_eNB_stats (RC.eNB[0][1], &stats_buffer[len], 0);
449

450 451 452
	//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);
453
      */
454 455
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
456
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
457
	  //	  if ((RC.eNB[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) {
458
	  if ((ue_cnt<scope_enb_num_ue)) {
gauthier's avatar
gauthier committed
459
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
460
			  RC.eNB[0][CC_id],
461 462 463
			  UE_id);
	    ue_cnt++;
	  }
464
	}
Raymond Knopp's avatar
 
Raymond Knopp committed
465
      }
466

467
    }
468
	
Raymond Knopp's avatar
 
Raymond Knopp committed
469
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
470 471
    //usleep(100000); // 100 ms
    sleep(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
472
  }
473

474
  //  printf("%s",stats_buffer);
475

476
# ifdef ENABLE_XFORMS_WRITE_STATS
477

478 479 480 481 482 483
  if (UE_flag==1) {
    if (UE_stats) {
      rewind (UE_stats);
      fwrite (stats_buffer, 1, len, UE_stats);
      fclose (UE_stats);
    }
484
  } else {
485 486 487 488 489 490
    if (eNB_stats) {
      rewind (eNB_stats);
      fwrite (stats_buffer, 1, len, eNB_stats);
      fclose (eNB_stats);
    }
  }
491

492
# endif
493

Raymond Knopp's avatar
 
Raymond Knopp committed
494
  pthread_exit((void*)arg);
495 496 497
}
#endif

498

499

500

Raymond Knopp's avatar
 
Raymond Knopp committed
501
#if defined(ENABLE_ITTI)
502
void *l2l1_task(void *arg) {
Raymond Knopp's avatar
 
Raymond Knopp committed
503 504 505 506 507
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
508

Raymond Knopp's avatar
 
Raymond Knopp committed
509 510
  if (UE_flag == 0) {
    /* Wait for the initialize message */
511
    printf("Wait for the ITTI initialize message\n");
512
    do {
Raymond Knopp's avatar
 
Raymond Knopp committed
513
      if (message_p != NULL) {
514 515
	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
516
      }
517

518 519 520
      itti_receive_msg (TASK_L2L1, &message_p);

      switch (ITTI_MSG_ID(message_p)) {
Raymond Knopp's avatar
 
Raymond Knopp committed
521
      case INITIALIZE_MESSAGE:
522 523 524 525
	/* 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
526 527

      case TERMINATE_MESSAGE:
528 529 530 531
	printf("received terminate message\n");
	oai_exit=1;
	itti_exit_task ();
	break;
Raymond Knopp's avatar
 
Raymond Knopp committed
532 533

      default:
534 535
	LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
	break;
536
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
537
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
538

Raymond Knopp's avatar
 
Raymond Knopp committed
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
    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;
560

Raymond Knopp's avatar
 
Raymond Knopp committed
561 562 563 564 565 566 567 568 569 570 571
    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);
572
  } while(!oai_exit);
573

Raymond Knopp's avatar
 
Raymond Knopp committed
574
  return NULL;
575 576 577
}
#endif

578

579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
static void get_options(void) {
  int CC_id;
  int clock_src;
  int tddflag;
  char *loopfile=NULL;
  int dumpframe;
  paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;

  config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); 
  if (tddflag > 0) {
      for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
	frame_parms[CC_id]->frame_type = TDD;
  }

  if (strlen(in_path) > 0) {
      opt_type = OPT_PCAP;
      opt_enabled=1;
      printf("Enabling OPT for PCAP  with the following file %s \n",in_path);
  }
  if (strlen(in_ip) > 0) {
      opt_enabled=1;
      opt_type = OPT_WIRESHARK;
      printf("Enabling OPT for wireshark for local interface");
  }
  if (UE_flag > 0) {
     paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC;
     paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC;
     config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL);
     config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL);
      if (loopfile != NULL) {
  	  printf("Input file for hardware emulation: %s",loopfile);
  	  mode=loop_through_memory;
  	  input_fd = fopen(loopfile,"r");
  	  AssertFatal(input_fd != NULL,"Please provide a valid input file\n");
      }
      if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue;
      if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med;
      if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp;
      if ( *(cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].uptr) > 0) mode = debug_prach;
      if ( *(cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].uptr) > 0)  mode = no_L2_connect;
      if ( *(cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].uptr) > 0) mode = calib_prach_tx; 
      if (dumpframe  > 0)  mode = rx_dump_frame;
      
      if ( downlink_frequency[0][0] > 0) {
  	  for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
  	    downlink_frequency[CC_id][1] = downlink_frequency[0][0];
  	    downlink_frequency[CC_id][2] = downlink_frequency[0][0];
  	    downlink_frequency[CC_id][3] = downlink_frequency[0][0];
  	    printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
  	  }
      UE_scan=0;
      } 


      if (frame_parms[0]->N_RB_DL !=0) {
  	  if ( frame_parms[0]->N_RB_DL < 6 ) {
  	     frame_parms[0]->N_RB_DL = 6;
  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",frame_parms[0]->N_RB_DL);
  	  }
  	  if ( frame_parms[0]->N_RB_DL > 100 ) {
  	     frame_parms[0]->N_RB_DL = 100;
  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",frame_parms[0]->N_RB_DL);
  	  }
  	  if ( frame_parms[0]->N_RB_DL > 50 && frame_parms[0]->N_RB_DL < 100 ) {
  	     frame_parms[0]->N_RB_DL = 50;
  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",frame_parms[0]->N_RB_DL);
  	  }
  	  if ( frame_parms[0]->N_RB_DL > 25 && frame_parms[0]->N_RB_DL < 50 ) {
  	     frame_parms[0]->N_RB_DL = 25;
  	     printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",frame_parms[0]->N_RB_DL);
  	  }
  	  UE_scan = 0;
  	  frame_parms[0]->N_RB_UL=frame_parms[0]->N_RB_DL;
  	  for (CC_id=1; CC_id<MAX_NUM_CCs; CC_id++) {
  	      frame_parms[CC_id]->N_RB_DL=frame_parms[0]->N_RB_DL;
  	      frame_parms[CC_id]->N_RB_UL=frame_parms[0]->N_RB_UL;
  	  }
      }


      for (CC_id=1;CC_id<MAX_NUM_CCs;CC_id++) {
  	    tx_max_power[CC_id]=tx_max_power[0];
	    rx_gain[0][CC_id] = rx_gain[0][0];
	    tx_gain[0][CC_id] = tx_gain[0][0];
      }
  } /* UE_flag > 0 */
#if T_TRACER
  paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ;
  config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL);   
#endif

670 671 672 673
  if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) {
    if (UE_flag == 0) {
      memset((void*)&RC,0,sizeof(RC));
      /* Read RC configuration file */
674
      RCConfig();
675 676 677
      NB_eNB_INST = RC.nb_inst;
      NB_RU	  = RC.nb_RU;
      printf("Configuration: nb_inst %d, nb_ru %d\n",NB_eNB_INST,NB_RU);
678
    }
679 680 681 682 683 684
  } else if (UE_flag == 1 && (CONFIG_GETCONFFILE != NULL)) {
    // Here the configuration file is the XER encoded UE capabilities
    // Read it in and store in asn1c data structures
    strcpy(uecap_xer,CONFIG_GETCONFFILE);
    uecap_xer_in=1;
  } /* UE with config file  */
685 686 687
}


688
  
689 690 691
#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 */
692
int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
693 694
#endif

695

696 697
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
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712

  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;
713
    frame_parms[CC_id]->nb_antenna_ports_eNB  = 1;
Raymond Knopp's avatar
Raymond Knopp committed
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742
    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]);

  }

}

743 744
void init_openair0(void);

Raymond Knopp's avatar
Raymond Knopp committed
745 746 747 748 749 750 751 752 753 754 755 756 757
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;
758
	openair0_cfg[card].samples_per_frame = 230400;
Raymond Knopp's avatar
Raymond Knopp committed
759 760
	openair0_cfg[card].tx_bw = 10e6;
	openair0_cfg[card].rx_bw = 10e6;
761
      } else {
Raymond Knopp's avatar
Raymond Knopp committed
762
	openair0_cfg[card].sample_rate=30.72e6;
763
	openair0_cfg[card].samples_per_frame = 307200;
Raymond Knopp's avatar
Raymond Knopp committed
764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
	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;

    printf("HW: Configuring card %d, nb_antennas_tx/rx %d/%d\n",card,
793 794
	   ((UE_flag==0) ? RC.eNB[0][0]->frame_parms.nb_antennas_tx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_tx),
	   ((UE_flag==0) ? RC.eNB[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
795 796 797
    openair0_cfg[card].Mod_id = 0;

    openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
798

799
    openair0_cfg[card].clock_source = clock_source;
800

801

802 803
    openair0_cfg[card].tx_num_channels=min(2,((UE_flag==0) ? RC.eNB[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) ? RC.eNB[0][0]->frame_parms.nb_antennas_rx : PHY_vars_UE_g[0][0]->frame_parms.nb_antennas_rx));
804

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

Raymond Knopp's avatar
Raymond Knopp committed
807 808 809 810
      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;
811

Raymond Knopp's avatar
Raymond Knopp committed
812 813 814 815 816 817 818 819
      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;

      openair0_cfg[card].autocal[i] = 1;
      openair0_cfg[card].tx_gain[i] = tx_gain[0][i];
      if (UE_flag == 0) {
820
	openair0_cfg[card].rx_gain[i] = RC.eNB[0][0]->rx_total_gain_dB;
Raymond Knopp's avatar
Raymond Knopp committed
821 822
      }
      else {
823
	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
824 825
      }

826
      openair0_cfg[card].configFilename = rf_config_file;
827
      printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
828 829 830 831
	     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]);
832
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
833
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
834
}
835

836

837
void wait_RUs(void) {
838 839 840 841 842 843 844 845 846 847 848 849 850 851 852

  LOG_I(PHY,"Waiting for RUs to be configured ...\n");

  // wait for all RUs to be configured over fronthaul
  pthread_mutex_lock(&RC.ru_mutex);



  while (RC.ru_mask>0) {
    pthread_cond_wait(&RC.ru_cond,&RC.ru_mutex);
  }

  LOG_I(PHY,"RUs configured\n");
}

853
void wait_eNBs(void) {
854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871

  int i,j;
  int waiting=1;


  while (waiting==1) {
    printf("Waiting for eNB L1 instances to all get configured ... sleeping 500ms (nb_L1_inst %d)\n",RC.nb_L1_inst);
    usleep(500000);
    waiting=0;
    for (i=0;i<RC.nb_L1_inst;i++)
      for (j=0;j<RC.nb_L1_CC[i];j++)
	if (RC.eNB[i][j]->configured==0) {
	  waiting=1;
	  break;
	}
  }
  printf("eNB L1 are configured\n");
}
872

873 874
int main( int argc, char **argv )
{
875
  int i;
876
#if defined (XFORMS)
Raymond Knopp's avatar
 
Raymond Knopp committed
877
  void *status;
878
#endif
879

Raymond Knopp's avatar
 
Raymond Knopp committed
880
  int CC_id;
881
  int ru_id;
Raymond Knopp's avatar
Raymond Knopp committed
882
  uint8_t  abstraction_flag=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
883
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
884

Raymond Knopp's avatar
 
Raymond Knopp committed
885
#if defined (XFORMS)
886 887
  int ret;
#endif
888

889
  start_background_system();
890 891 892
  if ( load_configmodule(argc,argv) == NULL) {
    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
  } 
893

894
      
895 896 897 898 899
#ifdef DEBUG_CONSOLE
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);
#endif

900 901 902
  PHY_VARS_UE *UE[MAX_NUM_CCs];

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

905
  memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
906

Raymond Knopp's avatar
 
Raymond Knopp committed
907
  set_latency_target();
908 909


Raymond Knopp's avatar
Raymond Knopp committed
910
  // set default parameters
911
  if (UE_flag == 1) set_default_frame_parms(frame_parms);
912

913
  logInit();
Raymond Knopp's avatar
Raymond Knopp committed
914

915
  printf("Reading in command-line options\n");
Raymond Knopp's avatar
Raymond Knopp committed
916
  // get options and fill parameters from configuration file
917 918
  // temporary test to allow legacy config or config module */
  
919 920
  get_options (); 
  
Raymond Knopp's avatar
Raymond Knopp committed
921

922
#if T_TRACER
923
  T_init(T_port, T_wait, T_dont_fork);
924 925
#endif

926
  // initialize the log (see log.h for details)
927 928
  set_glog(glog_level, glog_verbosity);

929 930
  //randominit (0);
  set_taus_seed (0);
Raymond Knopp's avatar
 
Raymond Knopp committed
931

932 933
  if (UE_flag==1) {
    printf("configuring for UE\n");
934

935 936
    set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
    set_comp_log(PHY,     LOG_DEBUG,   LOG_HIGH, 1);
937
    set_comp_log(MAC,     LOG_INFO,   LOG_HIGH, 1);
938
    set_comp_log(RLC,     LOG_INFO,   LOG_HIGH | FLAG_THREAD, 1);
939 940 941
    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);
942
#if defined(ENABLE_ITTI)
943
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
944
# if defined(ENABLE_USE_MME)
945
    set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
946 947
# endif
#endif
948

949
  } else {
950
    printf("configuring for RAU/RRU\n");
951

952 953 954 955 956 957 958 959
    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);
960
#if defined(ENABLE_ITTI)
961
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
962
# if defined(ENABLE_USE_MME)
963 964 965 966
    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);
967
# endif
968
#if defined(ENABLE_SECURITY)
969
    set_comp_log(OSA,    osa_log_level,   osa_log_verbosity, 1);
970
#endif
971
#endif
972
#ifdef LOCALIZATION
973 974 975 976 977 978 979 980 981
    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
982
    }
983
  }
984

Raymond Knopp's avatar
 
Raymond Knopp committed
985 986
  if (ouput_vcd) {
    if (UE_flag==1)
987
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
988
    else
989
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
990
  }
991

992
  if (opp_enabled ==1) {
993
    reset_opp_meas();
994 995
  }
  cpuf=get_cpu_freq_GHz();
996

997
#if defined(ENABLE_ITTI)
998

Raymond Knopp's avatar
 
Raymond Knopp committed
999 1000
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
1001
  } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1002 1003
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
1004

Raymond Knopp's avatar
 
Raymond Knopp committed
1005
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
1006

1007 1008
  // initialize mscgen log after ITTI
  MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
1009
#endif
1010

1011 1012
  if (opt_type != OPT_NONE) {
    radio_type_t radio_type;
1013

1014 1015
    if (frame_parms[0]->frame_type == FDD)
      radio_type = RADIO_TYPE_FDD;
1016
    else
1017
      radio_type = RADIO_TYPE_TDD;
1018

1019 1020 1021
    if (init_opt(in_path, in_ip, NULL, radio_type) == -1)
      LOG_E(OPT,"failed to run OPT \n");
  }
1022

1023
#ifdef PDCP_USE_NETLINK
Raymond Knopp's avatar
 
Raymond Knopp committed
1024
  netlink_init();
1025 1026 1027
#if defined(PDCP_USE_NETLINK_QUEUES)
  pdcp_netlink_init();
#endif
1028 1029
#endif

1030
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1031 1032 1033
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
1034
#endif
1035

1036

Raymond Knopp's avatar
 
Raymond Knopp committed
1037 1038
  check_clock();

1039 1040 1041 1042 1043 1044
#ifndef PACKAGE_VERSION
#  define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif

  LOG_I(HW, "Version: %s\n", PACKAGE_VERSION);

Raymond Knopp's avatar
 
Raymond Knopp committed
1045
  // init the parameters
1046 1047
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

Raymond Knopp's avatar
Raymond Knopp committed
1048
    if (UE_flag==1) {
1049 1050
      frame_parms[CC_id]->nb_antennas_tx     = nb_antenna_tx;
      frame_parms[CC_id]->nb_antennas_rx     = nb_antenna_rx;
1051
      frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later
1052
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1053 1054 1055
  }


Raymond Knopp's avatar
 
Raymond Knopp committed
1056

1057

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

1060

1061 1062 1063 1064 1065 1066 1067 1068
    if (UE_flag==1) {     
      NB_UE_INST=1;     
      NB_INST=1;     
      PHY_vars_UE_g = malloc(sizeof(PHY_VARS_UE**));     
      PHY_vars_UE_g[0] = malloc(sizeof(PHY_VARS_UE*)*MAX_NUM_CCs);
      
      
      
1069
      PHY_vars_UE_g[0][CC_id] = init_ue_vars(frame_parms[CC_id], 0,abstraction_flag);
1070 1071
      UE[CC_id] = PHY_vars_UE_g[0][CC_id];
      printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]);
1072
      
1073 1074 1075 1076
      if (phy_test==1)
	UE[CC_id]->mac_enabled = 0;
      else 
	UE[CC_id]->mac_enabled = 1;
1077
      
1078
      if (UE[CC_id]->mac_enabled == 0) {  //set default UL parameters for testing mode
1079 1080 1081 1082 1083 1084 1085 1086 1087
	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
1088
      }
1089
      
1090
      UE[CC_id]->UE_scan = UE_scan;
1091
      UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
1092
      UE[CC_id]->mode    = mode;
Rohit Gupta's avatar
Rohit Gupta committed
1093
      printf("UE[%d]->mode = %d\n",CC_id,mode);
1094 1095 1096 1097 1098 1099 1100 1101
      
      if (UE[CC_id]->mac_enabled == 1) { 
	UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1234;
	UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1234;
      }else {
	UE[CC_id]->pdcch_vars[0][0]->crnti = 0x1235;
	UE[CC_id]->pdcch_vars[1][0]->crnti = 0x1235;
      }
1102
      UE[CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0] + rx_gain_off;
1103
      UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
      
      if (frame_parms[CC_id]->frame_type==FDD) {
	UE[CC_id]->N_TA_offset = 0;
      }
      else {
	if (frame_parms[CC_id]->N_RB_DL == 100)
	  UE[CC_id]->N_TA_offset = 624;
	else if (frame_parms[CC_id]->N_RB_DL == 50)
	  UE[CC_id]->N_TA_offset = 624/2;
	else if (frame_parms[CC_id]->N_RB_DL == 25)
	  UE[CC_id]->N_TA_offset = 624/4;
1115
      }
1116
      
Raymond Knopp's avatar
 
Raymond Knopp committed
1117
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1118
  }
1119

1120 1121
  fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
  cpuf=get_cpu_freq_GHz();
1122 1123 1124
  
  
  
laurent's avatar
laurent committed
1125
#ifndef DEADLINE_SCHEDULER
1126
  
1127
  /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */
1128 1129 1130 1131 1132
  
  cpu_set_t cpuset;
  int s;
  char cpu_affinity[1024];
  CPU_ZERO(&cpuset);
1133
#ifdef CPU_AFFINITY
1134 1135 1136
  if (get_nprocs() > 2) {
    CPU_SET(0, &cpuset);
    s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
1137
    if (s != 0) {
1138 1139
      perror( "pthread_setaffinity_np");
      exit_fun("Error setting processor affinity");
1140
    }
1141 1142
    LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n");
  }
1143
#endif
1144
  
1145 1146
  /* Check the actual affinity mask assigned to the thread */
  s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
1147 1148 1149 1150
  if (s != 0) {
    perror( "pthread_getaffinity_np");
    exit_fun("Error getting processor affinity ");
  }
1151
  memset(cpu_affinity, 0 , sizeof(cpu_affinity));
1152 1153 1154 1155 1156
  for (int j = 0; j < CPU_SETSIZE; j++) {
    if (CPU_ISSET(j, &cpuset)) {
      char temp[1024];
      sprintf(temp, " CPU_%d ", j);
      strcat(cpu_affinity, temp);
1157
    }
1158
  }
1159
  LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity);
1160
#endif
1161
  
navid's avatar
navid committed
1162
  openair0_cfg[0].log_level = glog_level;
1163
  
1164
  
winckel's avatar
winckel committed
1165
#if defined(ENABLE_ITTI)
1166 1167
  
  
Raymond Knopp's avatar
Raymond Knopp committed
1168
  if ((UE_flag == 1)||
1169
      (RC.nb_inst > 0))  {
1170
    
Raymond Knopp's avatar
Raymond Knopp committed
1171 1172 1173 1174 1175
    // 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
    }
1176
    
1177 1178 1179
    printf("ITTI tasks created\n");
  }
  else {
1180 1181
    printf("No ITTI, Initializing L1\n");
    RCconfig_L1();
1182
  }
winckel's avatar
winckel committed
1183
#endif
1184
  
1185 1186 1187 1188
  if (phy_test==0) {
    if (UE_flag==1) {
      printf("Filling UE band info\n");
      fill_ue_band_info();
1189
      dl_phy_sync_success (0, 0, 0, 1);
1190
    } 
1191
  }
1192 1193 1194 1195
  
  
  
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1196
  mlockall(MCL_CURRENT | MCL_FUTURE);
1197
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1198 1199
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
1200
  
1201
#ifdef XFORMS
1202
  int UE_id;
1203
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1204 1205
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
1206
    
1207
    if (UE_flag==0) {
1208
      form_stats_l2 = create_form_stats_form();
1209 1210 1211
      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");
1212
      
1213
      for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
1214 1215 1216 1217
	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);
1218
	  
1219 1220 1221 1222 1223 1224 1225
	  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");
	  }
1226 1227
	} // CC_id
      } // UE_id
1228
    } else {
1229 1230 1231 1232 1233 1234
      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);
1235
      
1236
      /*
1237
	if (openair_daq_vars.use_ia_receiver) {
1238 1239
	fl_set_button(form_ue[UE_id]->button_0,1);
	fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
1240
	} else {
1241 1242
	fl_set_button(form_ue[UE_id]->button_0,0);
	fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
1243
	}*/
1244 1245
      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
1246
    }
1247
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1248
    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
1249
    
1250 1251
    if (ret == 0)
      pthread_setname_np( forms_thread, "xforms" );
1252
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1253 1254
    printf("Scope thread created, ret=%d\n",ret);
  }
1255
  
1256
#endif
1257
  
1258
  rt_sleep_ns(10*100000000ULL);
1259 1260 1261 1262
  
  
  
  
1263
  // start the main threads
Raymond Knopp's avatar
 
Raymond Knopp committed
1264
  if (UE_flag == 1) {
1265 1266
    int eMBMS_active = 0;
    init_UE(1,eMBMS_active,uecap_xer_in);
1267 1268 1269 1270 1271
    number_of_cards = 1;
    
    for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
      PHY_vars_UE_g[0][CC_id]->rf_map.card=0;
      PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset;
Raymond Knopp's avatar
 
Raymond Knopp committed
1272
    }
1273
  }
Raymond Knopp's avatar
Raymond Knopp committed
1274
  else { 
1275
    number_of_cards = 1;    
1276
    if (RC.nb_L1_inst > 0) {
1277 1278
      printf("Initializing eNB threads\n");
      init_eNB(single_thread_flag,wait_for_sync);
1279 1280
      //      for (inst=0;inst<RC.nb_L1_inst;inst++)
      //	for (CC_id=0;CC_id<RC.nb_L1_CC[inst];CC_id++) phy_init_lte_eNB(RC.eNB[inst][CC_id],0,0);
Raymond Knopp's avatar
 
Raymond Knopp committed
1281
    }
1282 1283 1284

    wait_eNBs();

1285 1286 1287 1288 1289 1290 1291 1292
    if (RC.nb_RU >0) {
      printf("Initializing RU threads\n");
      init_RU(rf_config_file);
      for (ru_id=0;ru_id<RC.nb_RU;ru_id++) {
	RC.ru[ru_id]->rf_map.card=0;
	RC.ru[ru_id]->rf_map.chain=CC_id+chain_offset;
      }
    }
1293

1294
    wait_RUs();
1295
    // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration)
1296
    init_eNB_afterRU();
1297
    
1298
  }
1299 1300
  
  
1301 1302 1303
  // connect the TX/RX buffers
  if (UE_flag==1) {
    
1304 1305 1306
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
      
      
1307 1308 1309 1310
#ifdef OAI_USRP
      UE[CC_id]->hw_timing_advance = timing_advance;
#else
      UE[CC_id]->hw_timing_advance = 160;
1311
#endif
1312 1313 1314 1315
    }
    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
1316
    }
1317 1318 1319
    
    
    
1320 1321 1322
    if (input_fd) {
      printf("Reading in from file to antenna buffer %d\n",0);
      if (fread(UE[0]->common_vars.rxdata[0],
1323 1324 1325 1326
		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");
1327 1328 1329
    }
    //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
  } else {
1330 1331 1332 1333 1334
    
    
    
    
    
1335
  }
1336 1337 1338 1339
  
  
  
  
1340
  printf("Sending sync to all threads\n");
1341 1342 1343
  
  
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1344
  pthread_mutex_lock(&sync_mutex);
1345
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1346 1347
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
1348
  end_configmodule();
1349

1350
  // wait for end of program
Raymond Knopp's avatar
 
Raymond Knopp committed
1351 1352
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
1353 1354 1355


#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1356 1357
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
1358
  oai_exit=1;
1359
#else
1360

Raymond Knopp's avatar
 
Raymond Knopp committed
1361
  while (oai_exit==0)
1362
    rt_sleep_ns(100000000ULL);
1363

1364
#endif
1365

Raymond Knopp's avatar
 
Raymond Knopp committed
1366
  // stop threads
1367
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
1368
  printf("waiting for XFORMS thread\n");
1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382

  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++) {
1383 1384 1385 1386
	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
1387
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1388
    }
1389 1390
  }

1391 1392
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1395 1396
  // cleanup
  if (UE_flag == 1) {
1397
  } else {
1398
    stop_eNB(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1399
  }
1400

1401

Raymond Knopp's avatar
 
Raymond Knopp committed
1402 1403
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
1404

1405

1406

Raymond Knopp's avatar
Raymond Knopp committed
1407
  // *** Handle per CC_id openair0
Raymond Knopp's avatar
Raymond Knopp committed
1408 1409 1410 1411 1412
  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 {
1413 1414 1415 1416 1417
    for(ru_id=0; ru_id<NB_RU; ru_id++) {
      if (RC.ru[ru_id]->rfdevice.trx_end_func)
	RC.ru[ru_id]->rfdevice.trx_end_func(&RC.ru[ru_id]->rfdevice);  
      if (RC.ru[ru_id]->ifdevice.trx_end_func)
	RC.ru[ru_id]->ifdevice.trx_end_func(&RC.ru[ru_id]->ifdevice);  
1418

Raymond Knopp's avatar
Raymond Knopp committed
1419
    }
1420
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1421
  if (ouput_vcd)
1422
    VCD_SIGNAL_DUMPER_CLOSE();
1423
  
1424
  if (opt_enabled == 1)
1425
    terminate_opt();
1426
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1427
  logClean();
1428
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1429 1430
  return 0;
}