lte-softmodem.c 46.5 KB
Newer Older
1 2 3 4 5
/*
 * 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
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 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
knopp's avatar
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
knopp's avatar
knopp committed
29 30 31
 * \note
 * \warning
 */
32

33

Cedric Roux's avatar
Cedric Roux committed
34 35 36
#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <sched.h>

37

38 39
#include "T.h"

40
#include "rt_wrapper.h"
41

42

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

45
#include "assertions.h"
46
#include "msc.h"
47 48

#include "PHY/types.h"
49

50
#include "PHY/defs.h"
51
#include "common/ran_context.h"
52
#include "common/config/config_userapi.h"
oai's avatar
oai committed
53
#include "common/utils/load_module_shlib.h"
54
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
knopp's avatar
knopp committed
55
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
56

knopp's avatar
knopp committed
57
#include "../../ARCH/COMMON/common_lib.h"
58
#include "../../ARCH/ETHERNET/USERSPACE/LIB/if_defs.h"
knopp's avatar
knopp committed
59

knopp's avatar
knopp committed
60
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
61 62 63 64 65 66 67 68 69

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

Florian Kaltenberger's avatar
Florian Kaltenberger committed
87 88 89 90
#ifndef OPENAIR2
#include "UTIL/OTG/otg_vars.h"
#endif

91
#if defined(ENABLE_ITTI)
92 93
#include "intertask_interface_init.h"
#include "create_tasks.h"
94 95
#endif

96 97
#include "system.h"

98 99 100
#ifdef XFORMS
#include "PHY/TOOLS/lte_phy_scope.h"
#include "stats.h"
101
#endif
102
#include "lte-softmodem.h"
103

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

115 116 117 118 119 120
pthread_cond_t nfapi_sync_cond;
pthread_mutex_t nfapi_sync_mutex;
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex

uint8_t nfapi_mode = 0; // Default to monolithic mode

knopp's avatar
knopp committed
121 122
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
123
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
124
int config_sync_var=-1;
125

126 127
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]
knopp's avatar
knopp committed
128

129
#if defined(ENABLE_ITTI)
130 131
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
132
#endif
knopp's avatar
knopp committed
133
volatile int             oai_exit = 0;
134

135
static clock_source_t clock_source = internal;
136
static int wait_for_sync = 0;
knopp's avatar
knopp committed
137

knopp's avatar
knopp committed
138
static char              UE_flag=0;
139
unsigned int                    mmapped_dma=0;
140
int                             single_thread_flag=1;
141

142
static char                     threequarter_fs=0;
143

144
uint32_t                 downlink_frequency[MAX_NUM_CCs][4];
145
int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
gauthier's avatar
gauthier committed
146

147

148

149
#if defined(ENABLE_ITTI)
150
static char                    *itti_dump_file = NULL;
knopp's avatar
knopp committed
151 152
#endif

153
int UE_scan = 1;
154
int UE_scan_carrier = 0;
155 156
runmode_t mode = normal_txrx;

157 158
FILE *input_fd=NULL;

159

160 161
#if MAX_NUM_CCs == 1
rx_gain_t                rx_gain_mode[MAX_NUM_CCs][4] = {{max_gain,max_gain,max_gain,max_gain}};
162 163
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}};
164 165 166 167
#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}};
gauthier's avatar
gauthier committed
168
#endif
knopp's avatar
knopp committed
169

170
double rx_gain_off = 0.0;
171

knopp's avatar
knopp committed
172
double sample_rate=30.72e6;
173
double bw = 10.0e6;
174

175
static int                      tx_max_power[MAX_NUM_CCs]; /* =  {0,0}*/;
176

177 178
char   rf_config_file[1024];

Florian Kaltenberger's avatar
Florian Kaltenberger committed
179
int chain_offset=0;
180
int phy_test = 0;
181
uint8_t usim_test = 0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
182

183 184 185
uint8_t dci_Format = 0;
uint8_t agregation_Level =0xFF;

186 187
uint8_t nb_antenna_tx = 1;
uint8_t nb_antenna_rx = 1;
188

knopp's avatar
knopp committed
189 190 191
char ref[128] = "internal";
char channels[128] = "0";

192
int                      rx_input_level_dBm;
193

194
#ifdef XFORMS
195
extern int                      otg_enabled;
196
static char                     do_forms=0;
197
#else
198
int                             otg_enabled;
199
#endif
knopp's avatar
knopp committed
200
//int                             number_of_cards =   1;
201

202 203

static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
Florian Kaltenberger's avatar
Florian Kaltenberger committed
204
uint32_t target_dl_mcs = 28; //maximum allowed mcs
205
uint32_t target_ul_mcs = 20;
206
uint32_t timing_advance = 0;
207 208
uint8_t exit_missed_slots=1;
uint64_t num_missed_slots=0; // counter for the number of missed slots
209

210

211 212
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
213

214 215 216 217 218 219
extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
			  uint8_t UE_id,
			  uint8_t abstraction_flag);

extern void init_eNB_afterRU(void);

220
int transmission_mode=1;
knopp's avatar
knopp committed
221

222

223

224 225 226
/* struct for ethernet specific parameters given in eNB conf file */
eth_params_t *eth_params;

227 228 229 230
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

231 232
extern char uecap_xer[1024];
char uecap_xer_in=0;
233

234
int oaisim_flag=0;
235
threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
knopp's avatar
knopp committed
236

Cedric Roux's avatar
Cedric Roux committed
237 238 239 240
/* 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;
knopp's avatar
knopp committed
241

242 243 244
/* forward declarations */
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);

245 246 247 248 249
/*---------------------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 };

250
struct timespec clock_difftime(struct timespec start, struct timespec end) {
251 252 253 254 255 256 257 258 259
  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;
260 261
}

262
void print_difftimes(void) {
263
#ifdef DEBUG
264
  printf("difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
265
#else
266
  LOG_I(HW,"difftimes min = %lu ns ; max = %lu ns\n", min_diff_time.tv_nsec, max_diff_time.tv_nsec);
267 268 269
#endif
}

270
void update_difftimes(struct timespec start, struct timespec end) {
271 272 273
  struct timespec diff_time = { .tv_sec = 0, .tv_nsec = 0 };
  int             changed = 0;
  diff_time = clock_difftime(start, end);
274 275 276 277 278 279 280 281
  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;
  }
282
#if 1
283
  if (changed) print_difftimes();
284 285 286 287 288
#endif
}

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

289
unsigned int build_rflocal(int txi, int txq, int rxi, int rxq) {
knopp's avatar
knopp committed
290
  return (txi + (txq<<6) + (rxi<<12) + (rxq<<18));
291
}
292
unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) {
knopp's avatar
knopp committed
293
  return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
294 295
}

296
#if !defined(ENABLE_ITTI)
297
void signal_handler(int sig) {
298 299 300 301 302 303
  void *array[10];
  size_t size;

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

305 306 307 308
    // print out all the frames to stderr
    fprintf(stderr, "Error: signal %d:\n", sig);
    backtrace_symbols_fd(array, size, 2);
    exit(-1);
309 310
  } else {
    printf("trying to exit gracefully...\n");
311
    oai_exit = 1;
312 313
  }
}
314
#endif
315 316 317 318 319 320
#define KNRM  "\x1B[0m"
#define KRED  "\x1B[31m"
#define KGRN  "\x1B[32m"
#define KBLU  "\x1B[34m"
#define RESET "\033[0m"

321

Raymond Knopp's avatar
Raymond Knopp committed
322

323 324
void exit_fun(const char* s)
{
Raymond Knopp's avatar
Raymond Knopp committed
325
  int CC_id;
326
  int ru_id;
Raymond Knopp's avatar
Raymond Knopp committed
327

328
  if (s != NULL) {
329
    printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s);
330 331 332
  }

  oai_exit = 1;
333 334 335 336 337 338 339 340 341 342

  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
343
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
344 345 346 347

    oai_exit = 1;

    for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
348 349 350 351 352
      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);
      }
knopp's avatar
knopp committed
353
    }
354 355

#if defined(ENABLE_ITTI)
356 357
    sleep(1); //allow lte-softmodem threads to exit first
    itti_terminate_tasks (TASK_UNKNOWN);
358
#endif
359

360
  }
361

362
}
363

364
#ifdef XFORMS
365

366

367 368
void reset_stats(FL_OBJECT *button, long arg)
{
369
  int i,j,k;
370
  PHY_VARS_eNB *phy_vars_eNB = RC.eNB[0][0];
371 372 373

  for (i=0; i<NUMBER_OF_UE_MAX; i++) {
    for (k=0; k<8; k++) { //harq_processes
374
      for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) {
375 376 377
	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;
378
      }
379

380 381 382
      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;
383 384


385 386 387
      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;
388 389 390 391
    }
  }
}

392
static void *scope_thread(void *arg) {
knopp's avatar
knopp committed
393
  char stats_buffer[16384];
394
# ifdef ENABLE_XFORMS_WRITE_STATS
knopp's avatar
knopp committed
395
  FILE *UE_stats, *eNB_stats;
396
# endif
knopp's avatar
knopp committed
397
  struct sched_param sched_param;
398
  int UE_id, CC_id;
399
  int ue_cnt=0;
400

401
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
knopp's avatar
knopp committed
402
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
403

knopp's avatar
knopp committed
404
  printf("Scope thread has priority %d\n",sched_param.sched_priority);
405

406
# ifdef ENABLE_XFORMS_WRITE_STATS
407 408

  if (UE_flag==1)
knopp's avatar
knopp committed
409
    UE_stats  = fopen("UE_stats.txt", "w");
410
  else
knopp's avatar
knopp committed
411
    eNB_stats = fopen("eNB_stats.txt", "w");
412

413
#endif
414

knopp's avatar
knopp committed
415 416
  while (!oai_exit) {
    if (UE_flag==1) {
417
      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
418 419 420
      //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);
421

422
      phy_scope_UE(form_ue[0],
423 424 425 426
		   PHY_vars_UE_g[0][0],
		   0,
		   0,7);

427

knopp's avatar
knopp committed
428
    } else {
429
      /*
430
	if (RC.eNB[0][0]->mac_enabled==1) {
431 432 433 434
	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);
435 436
	}
	len = dump_eNB_stats (RC.eNB[0][0], stats_buffer, 0);
437

438 439
	if (MAX_NUM_CCs>1)
	len += dump_eNB_stats (RC.eNB[0][1], &stats_buffer[len], 0);
440

441 442 443
	//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);
444
      */
445 446
      ue_cnt=0;
      for(UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
447
	for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
448
	  //	  if ((RC.eNB[0][CC_id]->dlsch[UE_id][0]->rnti>0) && (ue_cnt<scope_enb_num_ue)) {
449
	  if ((ue_cnt<scope_enb_num_ue)) {
gauthier's avatar
gauthier committed
450
	    phy_scope_eNB(form_enb[CC_id][ue_cnt],
451
			  RC.eNB[0][CC_id],
452 453 454
			  UE_id);
	    ue_cnt++;
	  }
455
	}
knopp's avatar
knopp committed
456
      }
457

458
    }
459
	
knopp's avatar
knopp committed
460
    //printf("doing forms\n");
Florian Kaltenberger's avatar
Florian Kaltenberger committed
461 462
    //usleep(100000); // 100 ms
    sleep(1);
knopp's avatar
knopp committed
463
  }
464

465
  //  printf("%s",stats_buffer);
466

467
# ifdef ENABLE_XFORMS_WRITE_STATS
468

469 470 471 472 473 474
  if (UE_flag==1) {
    if (UE_stats) {
      rewind (UE_stats);
      fwrite (stats_buffer, 1, len, UE_stats);
      fclose (UE_stats);
    }
475
  } else {
476 477 478 479 480 481
    if (eNB_stats) {
      rewind (eNB_stats);
      fwrite (stats_buffer, 1, len, eNB_stats);
      fclose (eNB_stats);
    }
  }
482

483
# endif
484

knopp's avatar
knopp committed
485
  pthread_exit((void*)arg);
486 487 488
}
#endif

489

490

491

knopp's avatar
knopp committed
492
#if defined(ENABLE_ITTI)
493
void *l2l1_task(void *arg) {
knopp's avatar
knopp committed
494 495 496 497 498
  MessageDef *message_p = NULL;
  int         result;

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
499

knopp's avatar
knopp committed
500 501
  if (UE_flag == 0) {
    /* Wait for the initialize message */
502
    printf("Wait for the ITTI initialize message\n");
503
    do {
knopp's avatar
knopp committed
504
      if (message_p != NULL) {
505 506
	result = itti_free (ITTI_MSG_ORIGIN_ID(message_p), message_p);
	AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
knopp's avatar
knopp committed
507
      }
508

509 510 511
      itti_receive_msg (TASK_L2L1, &message_p);

      switch (ITTI_MSG_ID(message_p)) {
knopp's avatar
knopp committed
512
      case INITIALIZE_MESSAGE:
513 514 515 516
	/* Start eNB thread */
	LOG_D(EMU, "L2L1 TASK received %s\n", ITTI_MSG_NAME(message_p));
	start_eNB = 1;
	break;
knopp's avatar
knopp committed
517 518

      case TERMINATE_MESSAGE:
519 520
	printf("received terminate message\n");
	oai_exit=1;
521
        start_eNB = 0;
522 523
	itti_exit_task ();
	break;
knopp's avatar
knopp committed
524 525

      default:
526 527
	LOG_E(EMU, "Received unexpected message %s\n", ITTI_MSG_NAME(message_p));
	break;
528
      }
knopp's avatar
knopp committed
529
    } while (ITTI_MSG_ID(message_p) != INITIALIZE_MESSAGE);
530

knopp's avatar
knopp committed
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
    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;
552

knopp's avatar
knopp committed
553 554 555 556 557 558 559 560 561 562 563
    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);
564
  } while(!oai_exit);
565

knopp's avatar
knopp committed
566
  return NULL;
567 568 569
}
#endif

570

571 572 573 574 575
static void get_options(void) {
  int CC_id;
  int tddflag;
  char *loopfile=NULL;
  int dumpframe;
576 577
  uint32_t online_log_messages;
  uint32_t glog_level, glog_verbosity;
oai's avatar
oai committed
578
  uint32_t start_telnetsrv;
579

580
  paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
581
  paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ;
582 583 584 585 586 587 588 589 590 591 592 593 594

  config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); 

  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");
  }
595 596 597 598 599 600 601 602

  config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL);
  if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) {
      set_glog_onlinelog(online_log_messages);
  }
  if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) {
      set_glog(glog_level, -1);
  }
603
  if(config_isparamset(cmdline_logparams,CMDLINE_GLOGVERBO_IDX)) {
604 605
      set_glog(-1, glog_verbosity);
  }
oai's avatar
oai committed
606
  if (start_telnetsrv) {
607
     load_module_shlib("telnetsrv",NULL,0);
oai's avatar
oai committed
608 609
  }

610
  
611
  if (UE_flag > 0) {
oai's avatar
oai committed
612
     uint8_t n_rb_dl;
613 614
     paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC;
     paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC;
oai's avatar
oai committed
615

Florian Kaltenberger's avatar
Florian Kaltenberger committed
616
     set_default_frame_parms(frame_parms);
oai's avatar
oai committed
617

618 619 620 621 622 623 624 625
     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");
      }
oai's avatar
oai committed
626

627 628 629
      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;
630 631
      if ( (cmdline_uemodeparams[CMDLINE_DEBUGUEPRACH_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = debug_prach;
      if ( (cmdline_uemodeparams[CMDLINE_NOL2CONNECT_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0)  mode = no_L2_connect;
Guy De Souza's avatar
Guy De Souza committed
632 633
      if ( (cmdline_uemodeparams[CMDLINE_CALIBPRACHTX_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = calib_prach_tx;
      if ( (cmdline_uemodeparams[CMDLINE_DUMPMEMORY_IDX].paramflags &  PARAMFLAG_PARAMSET) != 0) mode = rx_dump_frame;
634 635
      
      if ( downlink_frequency[0][0] > 0) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
636 637 638 639 640
	printf("Downlink frequency set to %u\n", downlink_frequency[0][0]);
	for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
	  frame_parms[CC_id]->dl_CarrierFreq = downlink_frequency[0][0];
	}
	UE_scan=0;
641 642
      } 

oai's avatar
oai committed
643 644 645 646
      if (tddflag > 0) {
         for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
	     frame_parms[CC_id]->frame_type = TDD;
      }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
647

648
      if (n_rb_dl !=0) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
649
	printf("NB_RB set to %d\n",n_rb_dl);
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
	if ( n_rb_dl < 6 ) {
	  n_rb_dl = 6;
	  printf ( "%i: Invalid number of ressource blocks, adjusted to 6\n",n_rb_dl);
	}
	if ( n_rb_dl > 100 ) {
	  n_rb_dl = 100;
	  printf ( "%i: Invalid number of ressource blocks, adjusted to 100\n",n_rb_dl);
	}
	if ( n_rb_dl > 50 && n_rb_dl < 100 ) {
	  n_rb_dl = 50;
	  printf ( "%i: Invalid number of ressource blocks, adjusted to 50\n",n_rb_dl);
	}
	if ( n_rb_dl > 25 && n_rb_dl < 50 ) {
	  n_rb_dl = 25;
	  printf ( "%i: Invalid number of ressource blocks, adjusted to 25\n",n_rb_dl);
	}
	UE_scan = 0;
	for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
	  frame_parms[CC_id]->N_RB_DL=n_rb_dl;
	  frame_parms[CC_id]->N_RB_UL=n_rb_dl;
	}
671 672
      }

673 674 675 676
      for (CC_id=0;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];
677 678
      }
  } /* UE_flag > 0 */
679

680 681 682 683 684
#if T_TRACER
  paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ;
  config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL);   
#endif

685 686 687 688
  if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) {
    if (UE_flag == 0) {
      memset((void*)&RC,0,sizeof(RC));
      /* Read RC configuration file */
689
      RCConfig();
690 691
      NB_eNB_INST = RC.nb_inst;
      NB_RU	  = RC.nb_RU;
692
      printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,NB_RU);
693
    }
694
  } else if (UE_flag == 1 && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) {
695 696
    // Here the configuration file is the XER encoded UE capabilities
    // Read it in and store in asn1c data structures
Florian Kaltenberger's avatar
Florian Kaltenberger committed
697 698
    sprintf(uecap_xer,"%stargets/PROJECTS/GENERIC-LTE-EPC/CONF/UE_config.xml",getenv("OPENAIR_HOME"));
    printf("%s\n",uecap_xer);
699 700
    uecap_xer_in=1;
  } /* UE with config file  */
701 702 703
}


704
#if T_TRACER
705
int T_nowait = 0;     /* by default we wait for the tracer */
706
int T_port = 2021;    /* default port to listen to to wait for the tracer */
707
int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
708 709
#endif

710

711

knopp's avatar
knopp committed
712
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
knopp's avatar
knopp committed
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727

  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;
728
    frame_parms[CC_id]->nb_antenna_ports_eNB  = 1;
knopp's avatar
knopp committed
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747
    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;

748 749 750 751
//    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];
knopp's avatar
knopp committed
752
    //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
753
    frame_parms[CC_id]->dl_CarrierFreq=downlink_frequency[CC_id][0];
oai's avatar
oai committed
754

knopp's avatar
knopp committed
755 756 757 758
  }

}

knopp's avatar
knopp committed
759 760
void init_openair0(void);

knopp's avatar
knopp committed
761 762 763 764 765 766 767 768 769 770 771 772 773
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;
774
	openair0_cfg[card].samples_per_frame = 230400;
knopp's avatar
knopp committed
775 776
	openair0_cfg[card].tx_bw = 10e6;
	openair0_cfg[card].rx_bw = 10e6;
777
      } else {
knopp's avatar
knopp committed
778
	openair0_cfg[card].sample_rate=30.72e6;
779
	openair0_cfg[card].samples_per_frame = 307200;
knopp's avatar
knopp committed
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808
	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,
809 810
	   ((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));
knopp's avatar
knopp committed
811 812 813
    openair0_cfg[card].Mod_id = 0;

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

815
    openair0_cfg[card].clock_source = clock_source;
816

817

818 819
    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));
820

knopp's avatar
knopp committed
821
    for (i=0; i<4; i++) {
822

knopp's avatar
knopp committed
823 824 825 826
      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;
827

knopp's avatar
knopp committed
828 829 830 831 832 833 834 835
      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) {
836
	openair0_cfg[card].rx_gain[i] = RC.eNB[0][0]->rx_total_gain_dB;
knopp's avatar
knopp committed
837 838
      }
      else {
839
	openair0_cfg[card].rx_gain[i] = PHY_vars_UE_g[0][0]->rx_total_gain_dB - rx_gain_off;
knopp's avatar
knopp committed
840 841
      }

842
      openair0_cfg[card].configFilename = rf_config_file;
843
      printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
844 845 846 847
	     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]);
848
    }
knopp's avatar
knopp committed
849
  }
knopp's avatar
knopp committed
850
}
851

852

853
void wait_RUs(void) {
854

855
  LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask);
856 857 858 859 860

  // 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);
861
    printf("RC.ru_mask:%02lx\n", RC.ru_mask);
862
  }
863
  pthread_mutex_unlock(&RC.ru_mutex);
864 865 866 867

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

868
void wait_eNBs(void) {
869 870 871 872 873 874

  int i,j;
  int waiting=1;


  while (waiting==1) {
Cedric Roux's avatar
Cedric Roux committed
875 876
    printf("Waiting for eNB L1 instances to all get configured ... sleeping 50ms (nb_L1_inst %d)\n",RC.nb_L1_inst);
    usleep(50*1000);
877
    waiting=0;
878 879 880 881 882
    for (i=0;i<RC.nb_L1_inst;i++) {

      printf("RC.nb_L1_CC[%d]:%d\n", i, RC.nb_L1_CC[i]);

      for (j=0;j<RC.nb_L1_CC[i];j++) {
883 884 885
	if (RC.eNB[i][j]->configured==0) {
	  waiting=1;
	  break;
886 887 888
        } 
      }
    }
889 890 891
  }
  printf("eNB L1 are configured\n");
}
892

893
#if defined(ENABLE_ITTI)
894 895
/*
 * helper function to terminate a certain ITTI task
896
 */
897
void terminate_task(task_id_t task_id, module_id_t mod_id)
898
{
899 900 901 902 903 904
  LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id);
  MessageDef *msg;
  msg = itti_alloc_new_message (ENB_APP, TERMINATE_MESSAGE);
  itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg);
}

905
extern void  free_transport(PHY_VARS_eNB *);
906 907
extern void  phy_free_RU(RU_t*);

908
int stop_L1L2(module_id_t enb_id)
909 910
{
  LOG_W(ENB_APP, "stopping lte-softmodem\n");
911
  oai_exit = 1;
912

913 914 915 916 917 918 919 920 921 922 923 924
  if (!RC.ru) {
    LOG_F(ENB_APP, "no RU configured\n");
    return -1;
  }

  /* stop trx devices, multiple carrier currently not supported by RU */
  if (RC.ru[enb_id]) {
    if (RC.ru[enb_id]->rfdevice.trx_stop_func) {
      RC.ru[enb_id]->rfdevice.trx_stop_func(&RC.ru[enb_id]->rfdevice);
      LOG_I(ENB_APP, "turned off RU rfdevice\n");
    } else {
      LOG_W(ENB_APP, "can not turn off rfdevice due to missing trx_stop_func callback, proceding anyway!\n");
925
    }
926 927 928 929 930
    if (RC.ru[enb_id]->ifdevice.trx_stop_func) {
      RC.ru[enb_id]->ifdevice.trx_stop_func(&RC.ru[enb_id]->ifdevice);
      LOG_I(ENB_APP, "turned off RU ifdevice\n");
    } else {
      LOG_W(ENB_APP, "can not turn off ifdevice due to missing trx_stop_func callback, proceding anyway!\n");
931
    }
932 933 934
  } else {
    LOG_W(ENB_APP, "no RU found for index %d\n", enb_id);
    return -1;
935 936 937 938 939
  }

  /* these tasks need to pick up new configuration */
  terminate_task(TASK_RRC_ENB, enb_id);
  terminate_task(TASK_L2L1, enb_id);
940
  LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id);
941
  kill_eNB_proc(enb_id);
942 943
  LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id);
  kill_RU_proc(enb_id);
944
  oai_exit = 0;
945 946 947 948
  for (int cc_id = 0; cc_id < RC.nb_CC[enb_id]; cc_id++) {
    free_transport(RC.eNB[enb_id][cc_id]);
    phy_free_lte_eNB(RC.eNB[enb_id][cc_id]);
  }
949
  phy_free_RU(RC.ru[enb_id]);
950
  free_lte_top();
951 952 953 954
  return 0;
}

/*
955
 * Restart the lte-softmodem after it has been soft-stopped with stop_L1L2()
956
 */
957
int restart_L1L2(module_id_t enb_id)
958
{
959 960 961
  RU_t *ru = RC.ru[enb_id];
  int cc_id;
  MessageDef *msg_p = NULL;
962 963 964 965 966 967

  LOG_W(ENB_APP, "restarting lte-softmodem\n");

  /* block threads */
  sync_var = -1;

968 969
  for (cc_id = 0; cc_id < RC.nb_L1_CC[enb_id]; cc_id++) {
    RC.eNB[enb_id][cc_id]->configured = 0;
970 971
  }

972 973 974 975 976
  RC.ru_mask |= (1 << ru->idx);
  /* copy the changed frame parameters to the RU */
  /* TODO this should be done for all RUs associated to this eNB */
  memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS));
  set_function_spec_param(RC.ru[enb_id]);
977 978 979 980 981 982 983 984 985 986 987 988 989 990 991

  LOG_I(ENB_APP, "attempting to create ITTI tasks\n");
  if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
    LOG_E(RRC, "Create task for RRC eNB failed\n");
    return -1;
  } else {
    LOG_I(RRC, "Re-created task for RRC eNB successfully\n");
  }
  if (itti_create_task (TASK_L2L1, l2l1_task, NULL) < 0) {
    LOG_E(PDCP, "Create task for L2L1 failed\n");
    return -1;
  } else {
    LOG_I(PDCP, "Re-created task for L2L1 successfully\n");
  }

992 993 994 995 996
  /* pass a reconfiguration request which will configure everything down to
   * RC.eNB[i][j]->frame_parms, too */
  msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ);
  RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration;
  itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
997

998 999
  /* TODO XForms might need to be restarted, but it is currently (09/02/18)
   * broken, so we cannot test it */
1000

1001 1002 1003 1004 1005 1006
  wait_eNBs();
  init_RU_proc(ru);
  ru->rf_map.card = 0;
  ru->rf_map.chain = 0; /* CC_id + chain_offset;*/
  wait_RUs();
  init_eNB_afterRU();
1007 1008 1009 1010 1011 1012 1013 1014

  printf("Sending sync to all threads\n");
  pthread_mutex_lock(&sync_mutex);
  sync_var=0;
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);

  return 0;
1015
}
1016
#endif
1017

1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030
static inline void wait_nfapi_init(char *thread_name) {

  printf( "waiting for NFAPI PNF connection and population of global structure (%s)\n",thread_name);
  pthread_mutex_lock( &nfapi_sync_mutex );
  
  while (nfapi_sync_var<0)
    pthread_cond_wait( &nfapi_sync_cond, &nfapi_sync_mutex );
  
  pthread_mutex_unlock(&nfapi_sync_mutex);
  
  printf( "NFAPI: got sync (%s)\n", thread_name);
}

1031 1032
int main( int argc, char **argv )
{
1033
  int i;
1034
#if defined (XFORMS)
knopp's avatar
knopp committed
1035
  void *status;
1036
#endif
1037

knopp's avatar
knopp committed
1038
  int CC_id;
1039
  int ru_id;
knopp's avatar
knopp committed
1040
  uint8_t  abstraction_flag=0;
knopp's avatar
knopp committed
1041
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
1042

knopp's avatar
knopp committed
1043
#if defined (XFORMS)
1044 1045
  int ret;
#endif
1046

1047
  start_background_system();
1048 1049 1050 1051
  if ( load_configmodule(argc,argv) == NULL) {
    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
  } 
      
1052 1053 1054 1055 1056
#ifdef DEBUG_CONSOLE
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);
#endif

1057 1058 1059
  PHY_VARS_UE *UE[MAX_NUM_CCs];

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

1062
  memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
1063

knopp's avatar
knopp committed
1064
  set_latency_target();
1065 1066


knopp's avatar
knopp committed
1067
  // set default parameters
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1068
  //if (UE_flag == 1) set_default_frame_parms(frame_parms);
1069

1070
  logInit();
knopp's avatar
knopp committed
1071

1072
  printf("Reading in command-line options\n");
1073

1074
  get_options (); 
1075
  if (CONFIG_ISFLAGSET(CONFIG_ABORT) && UE_flag == 0) {
1076 1077
      fprintf(stderr,"Getting configuration failed\n");
      exit(-1);
1078
  }
knopp's avatar
knopp committed
1079 1080


1081
#if T_TRACER
1082
  T_init(T_port, 1-T_nowait, T_dont_fork);
1083 1084
#endif

1085

1086

1087 1088
  //randominit (0);
  set_taus_seed (0);
knopp's avatar
knopp committed
1089

1090 1091
  if (UE_flag==1) {
    printf("configuring for UE\n");
1092

1093
    set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
1094
    set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
1095
    set_comp_log(MAC,     LOG_INFO,   LOG_HIGH, 1);
1096
    set_comp_log(RLC,     LOG_INFO,   LOG_HIGH | FLAG_THREAD, 1);
1097 1098 1099
    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);
1100
#if defined(ENABLE_ITTI)
1101
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
1102
# if defined(ENABLE_USE_MME)
1103
    set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
1104 1105
# endif
#endif
1106

1107
  } else {
1108
    printf("configuring for RAU/RRU\n");
1109

1110
  }
1111

knopp's avatar
knopp committed
1112 1113
  if (ouput_vcd) {
    if (UE_flag==1)
gauthier's avatar
gauthier committed
1114
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd");
knopp's avatar
knopp committed
1115
    else
gauthier's avatar
gauthier committed
1116
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd");
knopp's avatar
knopp committed
1117
  }
1118

1119
  if (opp_enabled ==1) {
1120
    reset_opp_meas();
1121 1122
  }
  cpuf=get_cpu_freq_GHz();
1123

1124
#if defined(ENABLE_ITTI)
1125

knopp's avatar
knopp committed
1126 1127
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
1128
  } else {
knopp's avatar
knopp committed
1129 1130
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
1131

1132
  printf("ITTI init\n");
knopp's avatar
knopp committed
1133
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
1134

1135 1136
  // initialize mscgen log after ITTI
  MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
1137