lte-softmodem.c 42.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
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

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
Raymond Knopp's avatar
 
Raymond 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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
60
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
61 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"
Navid Nikaein's avatar
Navid Nikaein 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"
Navid Nikaein's avatar
Navid Nikaein 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 105
static char *in_ip_xx = in_ip;

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

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

121
uint8_t nfapi_mode = 2;
122

123 124
uint16_t sf_ahead=4;

125 126
char emul_iface[100];

Raymond Knopp's avatar
 
Raymond Knopp committed
127 128
pthread_cond_t sync_cond;
pthread_mutex_t sync_mutex;
129
int sync_var=-1; //!< protected by mutex \ref sync_mutex.
130
int config_sync_var=-1;
131

132 133
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
134

135
#if defined(ENABLE_ITTI)
136 137
volatile int             start_eNB = 0;
volatile int             start_UE = 0;
138
#endif
Raymond Knopp's avatar
Raymond Knopp committed
139
volatile int             oai_exit = 0;
140

141
static clock_source_t clock_source = internal;
142
static int wait_for_sync = 0;
Raymond Knopp's avatar
 
Raymond Knopp committed
143

Raymond Knopp's avatar
Raymond Knopp committed
144
static char              UE_flag=0;
145
unsigned int                    mmapped_dma=0;
146
int                             single_thread_flag=1;
147

148
static char                     threequarter_fs=0;
149

150
uint32_t                 downlink_frequency[MAX_NUM_CCs][4];
151
int32_t                  uplink_frequency_offset[MAX_NUM_CCs][4];
Lionel Gauthier's avatar
Lionel Gauthier committed
152

153

154

155
#if defined(ENABLE_ITTI)
156
static char                    *itti_dump_file = NULL;
Raymond Knopp's avatar
 
Raymond Knopp committed
157 158
#endif

159
int UE_scan = 1;
160
int UE_scan_carrier = 0;
161 162
runmode_t mode = normal_txrx;

163 164
FILE *input_fd=NULL;

165

166 167
#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
168 169
double tx_gain[MAX_NUM_CCs][4] = {{20,0,0,0}};
double rx_gain[MAX_NUM_CCs][4] = {{110,0,0,0}};
170 171 172 173
#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
174
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
175

176
double rx_gain_off = 0.0;
177

Raymond Knopp's avatar
 
Raymond Knopp committed
178
double sample_rate=30.72e6;
179
double bw = 10.0e6;
180

181
static int                      tx_max_power[MAX_NUM_CCs]; /* =  {0,0}*/;
182

183 184
char   rf_config_file[1024];

Florian Kaltenberger's avatar
Florian Kaltenberger committed
185
int chain_offset=0;
186
int phy_test = 0;
187
uint8_t usim_test = 0;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
188

189 190 191
uint8_t dci_Format = 0;
uint8_t agregation_Level =0xFF;

192 193
uint8_t nb_antenna_tx = 1;
uint8_t nb_antenna_rx = 1;
194

Raymond Knopp's avatar
 
Raymond Knopp committed
195 196 197
char ref[128] = "internal";
char channels[128] = "0";

198
int                      rx_input_level_dBm;
199

200
#ifdef XFORMS
201
extern int                      otg_enabled;
202
static char                     do_forms=0;
203
#else
204
int                             otg_enabled;
205
#endif
Raymond Knopp's avatar
 
Raymond Knopp committed
206
//int                             number_of_cards =   1;
207

208 209

static LTE_DL_FRAME_PARMS      *frame_parms[MAX_NUM_CCs];
Florian Kaltenberger's avatar
Florian Kaltenberger committed
210
uint32_t target_dl_mcs = 28; //maximum allowed mcs
211
uint32_t target_ul_mcs = 20;
212
uint32_t timing_advance = 0;
213 214
uint8_t exit_missed_slots=1;
uint64_t num_missed_slots=0; // counter for the number of missed slots
215

216

217 218
extern void reset_opp_meas(void);
extern void print_opp_meas(void);
219

220 221 222 223 224 225
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);

226
int transmission_mode=1;
Raymond Knopp's avatar
 
Raymond Knopp committed
227

228

229

230 231 232
/* struct for ethernet specific parameters given in eNB conf file */
eth_params_t *eth_params;

233 234 235 236
openair0_config_t openair0_cfg[MAX_CARDS];

double cpuf;

237 238
extern char uecap_xer[1024];
char uecap_xer_in=0;
239

240
int oaisim_flag=0;
241
threads_t threads= {-1,-1,-1,-1,-1,-1,-1};
Raymond Knopp's avatar
 
Raymond Knopp committed
242

Cedric Roux's avatar
Cedric Roux committed
243 244 245 246
/* 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
247

248 249 250
/* forward declarations */
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]);

251 252 253 254 255
/*---------------------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 };

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

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

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

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

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

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

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

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

327

Raymond Knopp's avatar
Raymond Knopp committed
328

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

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

  oai_exit = 1;
339 340 341 342 343 344 345 346 347 348

  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
349
  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
350 351 352 353

    oai_exit = 1;

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

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

366
  }
367

368
}
369

370
#ifdef XFORMS
371

372

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

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

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


391 392 393
      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;
394 395 396 397
    }
  }
}

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

407
  sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO)+1;
Raymond Knopp's avatar
 
Raymond Knopp committed
408
  sched_setscheduler(0, SCHED_FIFO,&sched_param);
409

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

412
# ifdef ENABLE_XFORMS_WRITE_STATS
413 414

  if (UE_flag==1)
Raymond Knopp's avatar
 
Raymond Knopp committed
415
    UE_stats  = fopen("UE_stats.txt", "w");
416
  else
Raymond Knopp's avatar
 
Raymond Knopp committed
417
    eNB_stats = fopen("eNB_stats.txt", "w");
418

419
#endif
420

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

428
      phy_scope_UE(form_ue[0],
429 430 431 432
		   PHY_vars_UE_g[0][0],
		   0,
		   0,7);

433

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

444 445
	if (MAX_NUM_CCs>1)
	len += dump_eNB_stats (RC.eNB[0][1], &stats_buffer[len], 0);
446

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

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

471
  //  printf("%s",stats_buffer);
472

473
# ifdef ENABLE_XFORMS_WRITE_STATS
474

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

489
# endif
490

Raymond Knopp's avatar
 
Raymond Knopp committed
491
  pthread_exit((void*)arg);
492 493 494
}
#endif

495

496

497

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

  itti_set_task_real_time(TASK_L2L1);
  itti_mark_task_ready(TASK_L2L1);
505

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

515 516 517
      itti_receive_msg (TASK_L2L1, &message_p);

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

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

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

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

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

Raymond Knopp's avatar
 
Raymond Knopp committed
571
  return NULL;
572 573 574
}
#endif

Raymond Knopp's avatar
 
Raymond Knopp committed
575

576
static void get_options(void) {
577
  int CC_id;
578 579 580
  int tddflag;
  char *loopfile=NULL;
  int dumpframe;
581 582
  uint32_t online_log_messages;
  uint32_t glog_level, glog_verbosity;
oai's avatar
oai committed
583
  uint32_t start_telnetsrv;
Raymond Knopp's avatar
 
Raymond Knopp committed
584

585
  paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ;
586
  paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ;
Raymond Knopp's avatar
 
Raymond Knopp committed
587

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

590 591 592 593 594 595
  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) {
596 597 598
      opt_enabled=1;
      opt_type = OPT_WIRESHARK;
      printf("Enabling OPT for wireshark for local interface");
599
  }
600

601 602 603 604 605 606 607
  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);
  }
608
  if(config_isparamset(cmdline_logparams,CMDLINE_GLOGVERBO_IDX)) {
609 610
      set_glog(-1, glog_verbosity);
  }
oai's avatar
oai committed
611
  if (start_telnetsrv) {
612
     load_module_shlib("telnetsrv",NULL,0);
oai's avatar
oai committed
613
  }
614

615
  
616
  if (UE_flag > 0) {
617 618
     uint8_t n_rb_dl;
     nfapi_mode=0;
619

620

621
     paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC;
622 623

     paramdef_t cmdline_ueparams[] = CMDLINE_UEPARAMS_DESC;
624

625
     set_default_frame_parms(frame_parms);
626 627


628 629 630 631 632 633 634
     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");
Raymond Knopp's avatar
 
Raymond Knopp committed
635
      }
oai's avatar
oai committed
636

637 638 639
      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;
640 641
      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
642 643
      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;
644
      //if (dumpframe  > 0)  mode = rx_dump_frame;
645 646
      
      if ( downlink_frequency[0][0] > 0) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
647 648 649 650 651
	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;
652
      } 
653

oai's avatar
oai committed
654 655 656 657
      if (tddflag > 0) {
         for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) 
	     frame_parms[CC_id]->frame_type = TDD;
      }
658

659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
      if (n_rb_dl !=0) {
        printf("NB_RB set to %d\n",n_rb_dl);
        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;
        }
682
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
683

684 685 686 687
      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];
Raymond Knopp's avatar
 
Raymond Knopp committed
688
      }
689
  } /* UE_flag > 0 */
690

691 692 693
#if T_TRACER
  paramdef_t cmdline_ttraceparams[] =CMDLINE_TTRACEPARAMS_DESC ;
  config_process_cmdline( cmdline_ttraceparams,sizeof(cmdline_ttraceparams)/sizeof(paramdef_t),NULL);   
Raymond Knopp's avatar
 
Raymond Knopp committed
694
#endif
695

696 697 698 699
  if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) {
    if (UE_flag == 0) {
      memset((void*)&RC,0,sizeof(RC));
      /* Read RC configuration file */
700
      RCConfig();
701 702
      NB_eNB_INST = RC.nb_inst;
      NB_RU	  = RC.nb_RU;
703
      printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,NB_RU);
704
    }
705
  } else if (UE_flag == 1 && (!(CONFIG_ISFLAGSET(CONFIG_NOOOPT))) ) {
706 707 708
    // Here the configuration file is the XER encoded UE capabilities
    // Read it in and store in asn1c data structures
    strcpy(uecap_xer,CONFIG_GETCONFFILE);
709
    //    uecap_xer_in=1;
710

711
  } /* UE with config file  */
712
}
713 714


715
#if T_TRACER
716
int T_nowait = 0;     /* by default we wait for the tracer */
717
int T_port = 2021;    /* default port to listen to to wait for the tracer */
718
int T_dont_fork = 0;  /* default is to fork, see 'T_init' to understand */
719 720
#endif

721

722

723
void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) {
Raymond Knopp's avatar
Raymond Knopp committed
724 725 726 727 728 729 730 731 732 733 734 735 736 737 738

  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;
739
    frame_parms[CC_id]->nb_antenna_ports_eNB  = 1;
Raymond Knopp's avatar
Raymond Knopp committed
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758
    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;

759 760 761 762
//    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];
Raymond Knopp's avatar
Raymond Knopp committed
763
    //printf("Downlink for CC_id %d frequency set to %u\n", CC_id, downlink_frequency[CC_id][0]);
764
    frame_parms[CC_id]->dl_CarrierFreq=downlink_frequency[CC_id][0];
Raymond Knopp's avatar
Raymond Knopp committed
765 766 767 768 769

  }

}

770 771
void init_openair0(void);

Raymond Knopp's avatar
Raymond Knopp committed
772 773 774 775 776 777 778 779 780 781 782 783 784
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;
785
	openair0_cfg[card].samples_per_frame = 230400;
Raymond Knopp's avatar
Raymond Knopp committed
786 787
	openair0_cfg[card].tx_bw = 10e6;
	openair0_cfg[card].rx_bw = 10e6;
788
      } else {
Raymond Knopp's avatar
Raymond Knopp committed
789
	openair0_cfg[card].sample_rate=30.72e6;
790
	openair0_cfg[card].samples_per_frame = 307200;
Raymond Knopp's avatar
Raymond Knopp committed
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819
	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,
820 821
	   ((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
822 823 824
    openair0_cfg[card].Mod_id = 0;

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

826
    openair0_cfg[card].clock_source = clock_source;
827

828

829 830
    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));
831

Raymond Knopp's avatar
Raymond Knopp committed
832
    for (i=0; i<4; i++) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
833

Raymond Knopp's avatar
Raymond Knopp committed
834 835 836 837
      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;
838

Raymond Knopp's avatar
Raymond Knopp committed
839 840 841 842 843 844 845 846
      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) {
847
	openair0_cfg[card].rx_gain[i] = RC.eNB[0][0]->rx_total_gain_dB;
Raymond Knopp's avatar
Raymond Knopp committed
848 849
      }
      else {
850
	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
851 852
      }

853
      openair0_cfg[card].configFilename = rf_config_file;
854
      printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n",
855 856 857 858
	     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]);
859
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
860
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
861
}
862

863

864
void wait_RUs(void) {
865

866
  LOG_I(PHY,"Waiting for RUs to be configured ... RC.ru_mask:%02lx\n", RC.ru_mask);
867 868 869 870 871 872 873 874

  // 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);
875
    printf("RC.ru_mask:%02lx\n", RC.ru_mask);
876 877 878 879 880
  }

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

881
void wait_eNBs(void) {
882 883 884 885 886 887

  int i,j;
  int waiting=1;


  while (waiting==1) {
Cedric Roux's avatar
Cedric Roux committed
888 889
    printf("Waiting for eNB L1 instances to all get configured ... sleeping 50ms (nb_L1_inst %d)\n",RC.nb_L1_inst);
    usleep(50*1000);
890 891
    //usleep(5000000);

892
    waiting=0;
893 894 895 896 897
    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++) {
898 899 900
	if (RC.eNB[i][j]->configured==0) {
	  waiting=1;
	  break;
901 902 903
        } 
      }
    }
904 905 906
  }
  printf("eNB L1 are configured\n");
}
907

908 909 910 911 912 913 914 915 916 917 918 919 920
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);
}

921 922
int main( int argc, char **argv )
{
923
  int i;
924
#if defined (XFORMS)
Raymond Knopp's avatar
 
Raymond Knopp committed
925
  void *status;
926
#endif
927

Raymond Knopp's avatar
 
Raymond Knopp committed
928
  int CC_id;
929
  int ru_id;
Raymond Knopp's avatar
Raymond Knopp committed
930
  uint8_t  abstraction_flag=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
931
  uint8_t beta_ACK=0,beta_RI=0,beta_CQI=2;
932

Raymond Knopp's avatar
 
Raymond Knopp committed
933
#if defined (XFORMS)
934 935
  int ret;
#endif
936

937
  start_background_system();
938 939 940 941
  if ( load_configmodule(argc,argv) == NULL) {
    exit_fun("[SOFTMODEM] Error, configuration module init failed\n");
  } 
      
942 943 944 945 946
#ifdef DEBUG_CONSOLE
  setvbuf(stdout, NULL, _IONBF, 0);
  setvbuf(stderr, NULL, _IONBF, 0);
#endif

947 948 949
  PHY_VARS_UE *UE[MAX_NUM_CCs];

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

952
  memset(tx_max_power,0,sizeof(int)*MAX_NUM_CCs);
953

Raymond Knopp's avatar
 
Raymond Knopp committed
954
  set_latency_target();
955 956


Raymond Knopp's avatar
Raymond Knopp committed
957
  // set default parameters
958
  //if (UE_flag == 1) set_default_frame_parms(frame_parms);
959

960
  logInit();
Raymond Knopp's avatar
Raymond Knopp committed
961

962
  printf("Reading in command-line options\n");
Raymond Knopp's avatar
Raymond Knopp committed
963

964
  get_options (); 
965
  if (CONFIG_ISFLAGSET(CONFIG_ABORT) && UE_flag == 0) {
966 967
      fprintf(stderr,"Getting configuration failed\n");
      exit(-1);
968
  }
Raymond Knopp's avatar
Raymond Knopp committed
969 970


971
#if T_TRACER
972
  T_init(T_port, 1-T_nowait, T_dont_fork);
973 974
#endif

975

Florian Kaltenberger's avatar
Florian Kaltenberger committed
976

977 978
  //randominit (0);
  set_taus_seed (0);
Raymond Knopp's avatar
 
Raymond Knopp committed
979

980 981
  if (UE_flag==1) {
    printf("configuring for UE\n");
982

983
    set_comp_log(HW,      LOG_DEBUG,  LOG_HIGH, 1);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
984
    set_comp_log(PHY,     LOG_INFO,   LOG_HIGH, 1);
985
    set_comp_log(MAC,     LOG_INFO,   LOG_HIGH, 1);
986
    set_comp_log(RLC,     LOG_INFO,   LOG_HIGH | FLAG_THREAD, 1);
987 988 989
    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);
990
#if defined(ENABLE_ITTI)
991
    set_comp_log(EMU,     LOG_INFO,   LOG_MED, 1);
992
# if defined(ENABLE_USE_MME)
993
    set_comp_log(NAS,     LOG_INFO,   LOG_HIGH, 1);
994 995
# endif
#endif
996

997
  } else {
998
    printf("configuring for RAU/RRU\n");
999

1000
  }
1001

Raymond Knopp's avatar
 
Raymond Knopp committed
1002 1003
  if (ouput_vcd) {
    if (UE_flag==1)
1004
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_UE.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1005
    else
1006
      VCD_SIGNAL_DUMPER_INIT("/tmp/openair_dump_eNB.vcd");
Raymond Knopp's avatar
 
Raymond Knopp committed
1007
  }
1008

1009
  if (opp_enabled ==1) {
1010
    reset_opp_meas();
1011 1012
  }
  cpuf=get_cpu_freq_GHz();
1013

1014
#if defined(ENABLE_ITTI)
1015

Raymond Knopp's avatar
 
Raymond Knopp committed
1016 1017
  if (UE_flag == 1) {
    log_set_instance_type (LOG_INSTANCE_UE);
1018
  } else {
Raymond Knopp's avatar
 
Raymond Knopp committed
1019 1020
    log_set_instance_type (LOG_INSTANCE_ENB);
  }
1021

1022
  printf("ITTI init\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1023
  itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, itti_dump_file);
1024

1025 1026
  // initialize mscgen log after ITTI
  MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX);
1027
#endif
1028

1029 1030
  if (opt_type != OPT_NONE) {
    radio_type_t radio_type;
1031

1032 1033
    if (frame_parms[0]->frame_type == FDD)
      radio_type = RADIO_TYPE_FDD;
1034
    else
1035
      radio_type = RADIO_TYPE_TDD;
1036

1037 1038 1039
    if (init_opt(in_path, in_ip, NULL, radio_type) == -1)
      LOG_E(OPT,"failed to run OPT \n");
  }
1040

1041
#ifdef PDCP_USE_NETLINK
1042
  printf("PDCP netlink\n");
Raymond Knopp's avatar
 
Raymond Knopp committed
1043
  netlink_init();
1044 1045 1046
#if defined(PDCP_USE_NETLINK_QUEUES)
  pdcp_netlink_init();
#endif
1047 1048
#endif

1049
#if !defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1050 1051 1052
  // to make a graceful exit when ctrl-c is pressed
  signal(SIGSEGV, signal_handler);
  signal(SIGINT, signal_handler);
1053
#endif
1054

1055

Raymond Knopp's avatar
 
Raymond Knopp committed
1056 1057
  check_clock();

1058 1059 1060 1061 1062 1063
#ifndef PACKAGE_VERSION
#  define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL"
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1064
  // init the parameters
1065 1066
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

Raymond Knopp's avatar
Raymond Knopp committed
1067
    if (UE_flag==1) {
1068 1069
      frame_parms[CC_id]->nb_antennas_tx     = nb_antenna_tx;
      frame_parms[CC_id]->nb_antennas_rx     = nb_antenna_rx;
1070
      frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later
1071
    }
Raymond Knopp's avatar
 
Raymond Knopp committed
1072 1073 1074
  }


Raymond Knopp's avatar
 
Raymond Knopp committed
1075

1076
  printf("Before CC \n");
1077

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

1080

1081 1082 1083 1084 1085 1086 1087 1088
    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);
      
      
      
1089
      PHY_vars_UE_g[0][CC_id] = init_ue_vars(frame_parms[CC_id], 0,abstraction_flag);
1090 1091
      UE[CC_id] = PHY_vars_UE_g[0][CC_id];
      printf("PHY_vars_UE_g[0][%d] = %p\n",CC_id,UE[CC_id]);
1092
      
1093 1094 1095 1096
      if (phy_test==1)
	UE[CC_id]->mac_enabled = 0;
      else 
	UE[CC_id]->mac_enabled = 1;
1097
      
1098
      if (UE[CC_id]->mac_enabled == 0) {  //set default UL parameters for testing mode
1099 1100 1101 1102 1103 1104 1105 1106 1107
	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
1108
      }
1109
      
1110
      UE[CC_id]->UE_scan = UE_scan;
1111
      UE[CC_id]->UE_scan_carrier = UE_scan_carrier;
1112
      UE[CC_id]->mode    = mode;
Rohit Gupta's avatar
Rohit Gupta committed
1113
      printf("UE[%d]->mode = %d\n",CC_id,mode);
1114 1115 1116 1117 1118 1119 1120 1121
      
      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;
      }
1122
      UE[CC_id]->rx_total_gain_dB =  (int)rx_gain[CC_id][0] + rx_gain_off;
1123
      UE[CC_id]->tx_power_max_dBm = tx_max_power[CC_id];
1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134
      
      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;
1135
      }
1136
    init_openair0();      
Raymond Knopp's avatar
 
Raymond Knopp committed
1137
    }
1138

Raymond Knopp's avatar
 
Raymond Knopp committed
1139
  }
1140

1141
  printf("Runtime table\n");
1142 1143
  fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx);
  cpuf=get_cpu_freq_GHz();
1144 1145 1146
  
  
  
laurent's avatar
laurent committed
1147
#ifndef DEADLINE_SCHEDULER
1148
  
1149
  printf("NO deadline scheduler\n");
1150
  /* Currently we set affinity for UHD to CPU 0 for eNB/UE and only if number of CPUS >2 */
1151 1152 1153 1154 1155
  
  cpu_set_t cpuset;
  int s;
  char cpu_affinity[1024];
  CPU_ZERO(&cpuset);
1156
#ifdef CPU_AFFINITY
1157 1158 1159
  if (get_nprocs() > 2) {
    CPU_SET(0, &cpuset);
    s = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
1160
    if (s != 0) {
1161 1162
      perror( "pthread_setaffinity_np");
      exit_fun("Error setting processor affinity");
1163
    }
1164 1165
    LOG_I(HW, "Setting the affinity of main function to CPU 0, for device library to use CPU 0 only!\n");
  }
1166
#endif
1167
  
1168 1169
  /* Check the actual affinity mask assigned to the thread */
  s = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
1170 1171 1172 1173
  if (s != 0) {
    perror( "pthread_getaffinity_np");
    exit_fun("Error getting processor affinity ");
  }
1174
  memset(cpu_affinity, 0 , sizeof(cpu_affinity));
1175 1176 1177 1178 1179
  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);
1180
    }
1181
  }
1182
  LOG_I(HW, "CPU Affinity of main() function is... %s\n", cpu_affinity);
1183
#endif
1184
  
1185

1186
  
1187
  
winckel's avatar
winckel committed
1188
#if defined(ENABLE_ITTI)
1189

Raymond Knopp's avatar
Raymond Knopp committed
1190
  if ((UE_flag == 1)||
1191
      (RC.nb_inst > 0))  {
1192
    
Raymond Knopp's avatar
Raymond Knopp committed
1193
    // don't create if node doesn't connect to RRC/S1/GTP
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204
    if (UE_flag == 0) {
      if (create_tasks(1) < 0) {
        printf("cannot create ITTI tasks\n");
        exit(-1); // need a softer mode
      }
    }
    else {
      if (create_tasks_ue(1) < 0) {
        printf("cannot create ITTI tasks\n");
        exit(-1); // need a softer mode
      }
Raymond Knopp's avatar
Raymond Knopp committed
1205
    }
1206 1207 1208
    printf("ITTI tasks created\n");
  }
  else {
1209 1210
    printf("No ITTI, Initializing L1\n");
    RCconfig_L1();
1211
  }
winckel's avatar
winckel committed
1212
#endif
1213

1214

1215 1216 1217
    // init UE_PF_PO and mutex lock
    pthread_mutex_init(&ue_pf_po_mutex, NULL);
    memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs);
1218 1219
  
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1220
  mlockall(MCL_CURRENT | MCL_FUTURE);
1221
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1222 1223
  pthread_cond_init(&sync_cond,NULL);
  pthread_mutex_init(&sync_mutex, NULL);
1224
  
1225
#ifdef XFORMS
1226
  int UE_id;
1227
  
1228 1229
  printf("XFORMS\n");

Raymond Knopp's avatar
 
Raymond Knopp committed
1230 1231
  if (do_forms==1) {
    fl_initialize (&argc, argv, NULL, 0, 0);
1232
    
1233
    if (UE_flag==0) {
1234
      form_stats_l2 = create_form_stats_form();
1235 1236 1237
      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");
1238
      
1239
      for(UE_id=0; UE_id<scope_enb_num_ue; UE_id++) {
1240 1241 1242 1243
	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);
1244
	  
1245 1246 1247 1248 1249 1250 1251
	  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");
	  }
1252 1253
	} // CC_id
      } // UE_id
1254
    } else {
1255 1256 1257 1258 1259 1260
      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);
1261
      
1262
      /*
1263
	if (openair_daq_vars.use_ia_receiver) {
1264 1265
	fl_set_button(form_ue[UE_id]->button_0,1);
	fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver ON");
1266
	} else {
1267 1268
	fl_set_button(form_ue[UE_id]->button_0,0);
	fl_set_object_label(form_ue[UE_id]->button_0, "IA Receiver OFF");
1269
	}*/
1270 1271
      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
1272
    }
1273
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1274
    ret = pthread_create(&forms_thread, NULL, scope_thread, NULL);
1275
    
1276 1277
    if (ret == 0)
      pthread_setname_np( forms_thread, "xforms" );
1278
    
Raymond Knopp's avatar
 
Raymond Knopp committed
1279 1280
    printf("Scope thread created, ret=%d\n",ret);
  }
1281
  
1282
#endif
1283
  
1284
  rt_sleep_ns(10*100000000ULL);
Cedric Roux's avatar
Cedric Roux committed
1285

1286 1287 1288 1289 1290 1291
  if (nfapi_mode) {

    printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
    pthread_cond_init(&sync_cond,NULL);
    pthread_mutex_init(&sync_mutex, NULL);
  }
1292
  
1293
  if (nfapi_mode)
1294 1295 1296 1297 1298
  {
    printf("NFAPI*** - mutex and cond created - will block shortly for completion of PNF connection\n");
    pthread_cond_init(&sync_cond,NULL);
    pthread_mutex_init(&sync_mutex, NULL);
  }
1299
  
1300 1301
  const char *nfapi_mode_str = "<UNKNOWN>";

1302
  switch(nfapi_mode)
1303 1304 1305
  {
    case 0:
      nfapi_mode_str = "MONOLITHIC";
1306
      break;
1307 1308 1309 1310 1311 1312
    case 1:
      nfapi_mode_str = "PNF";
      break;
    case 2:
      nfapi_mode_str = "VNF";
      break;
1313 1314 1315
    default:
      nfapi_mode_str = "<UNKNOWN NFAPI MODE>";
      break;
1316
  }
1317
  printf("NFAPI MODE:%s\n", nfapi_mode_str);
1318

1319
  if (nfapi_mode==2) // VNF
1320
    wait_nfapi_init("main?");
1321

1322
  printf("START MAIN THREADS\n");
1323
  
1324
  // start the main threads
Raymond Knopp's avatar
 
Raymond Knopp committed
1325
  if (UE_flag == 1) {
1326
    int eMBMS_active = 0;
1327
    init_UE(1,eMBMS_active,uecap_xer_in,0);
1328

1329 1330 1331 1332 1333 1334
    if (phy_test==0) {
      printf("Filling UE band info\n");
      fill_ue_band_info();
      dl_phy_sync_success (0, 0, 0, 1);
    }

1335 1336 1337 1338
    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
1339
    }
1340
  }
Raymond Knopp's avatar
Raymond Knopp committed
1341
  else { 
1342
    number_of_cards = 1;    
1343
    printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst);
1344
    if (RC.nb_L1_inst > 0) {
1345
      printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", single_thread_flag,wait_for_sync);
1346
      init_eNB(single_thread_flag,wait_for_sync);
1347 1348
      //      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
1349
    }
1350

1351
    printf("wait_eNBs()\n");
1352 1353
    wait_eNBs();

1354
    printf("About to Init RU threads RC.nb_RU:%d\n", RC.nb_RU);
1355 1356 1357 1358 1359 1360 1361 1362
    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;
      }
    }
1363

1364 1365
    config_sync_var=0;

1366
    if (nfapi_mode==1) { // PNF
1367
      wait_nfapi_init("main?");
1368
    }
1369

1370
    printf("wait RUs\n");
1371
    wait_RUs();
1372 1373
    printf("ALL RUs READY!\n");
    printf("RC.nb_RU:%d\n", RC.nb_RU);
1374
    // once all RUs are ready intiailize the rest of the eNBs ((dependence on final RU parameters after configuration)
1375
    printf("ALL RUs ready - init eNBs\n");
1376

1377
    if (nfapi_mode != 1 && nfapi_mode != 2)
1378 1379 1380 1381 1382 1383 1384 1385
    {
      printf("Not NFAPI mode - call init_eNB_afterRU()\n");
      init_eNB_afterRU();
    }
    else
    {
      printf("NFAPI mode - DO NOT call init_eNB_afterRU()\n");
    }
1386
    
1387
    printf("ALL RUs ready - ALL eNBs ready\n");
1388
  }
1389 1390
  
  
1391 1392 1393
  // connect the TX/RX buffers
  if (UE_flag==1) {
    
1394 1395 1396
    for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
      
      
1397 1398 1399 1400
#ifdef OAI_USRP
      UE[CC_id]->hw_timing_advance = timing_advance;
#else
      UE[CC_id]->hw_timing_advance = 160;
1401
#endif
1402 1403 1404 1405
    }
    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
1406
    }
1407 1408 1409
    
    
    
1410 1411 1412
    if (input_fd) {
      printf("Reading in from file to antenna buffer %d\n",0);
      if (fread(UE[0]->common_vars.rxdata[0],
1413 1414 1415 1416
		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");
1417 1418 1419
    }
    //p_exmimo_config->framing.tdd_config = TXRXSWITCH_TESTRX;
  } else {
1420
    
1421
    printf("eNB mode\n");
1422
    
1423
  }
1424
  
1425
  printf("Sending sync to all threads\n");
1426
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1427
  pthread_mutex_lock(&sync_mutex);
1428
  sync_var=0;
Raymond Knopp's avatar
 
Raymond Knopp committed
1429 1430
  pthread_cond_broadcast(&sync_cond);
  pthread_mutex_unlock(&sync_mutex);
1431
  printf("About to call end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
1432
  end_configmodule();
1433
  printf("Called end_configmodule() from %s() %s:%d\n", __FUNCTION__, __FILE__, __LINE__);
1434

1435
  // wait for end of program
Raymond Knopp's avatar
 
Raymond Knopp committed
1436 1437
  printf("TYPE <CTRL-C> TO TERMINATE\n");
  //getchar();
1438 1439

#if defined(ENABLE_ITTI)
Raymond Knopp's avatar
 
Raymond Knopp committed
1440 1441
  printf("Entering ITTI signals handler\n");
  itti_wait_tasks_end();
1442
  printf("Returned from ITTI signal handler\n");
1443
  oai_exit=1;
1444
  printf("oai_exit=%d\n",oai_exit);
1445
#else
1446

Raymond Knopp's avatar
 
Raymond Knopp committed
1447
  while (oai_exit==0)
1448
    rt_sleep_ns(100000000ULL);
1449
  printf("Terminating application - oai_exit=%d\n",oai_exit);
1450

1451
#endif
1452

Raymond Knopp's avatar
 
Raymond Knopp committed
1453
  // stop threads
1454
#ifdef XFORMS
Raymond Knopp's avatar
 
Raymond Knopp committed
1455
  printf("waiting for XFORMS thread\n");
1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469

  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++) {
1470 1471 1472 1473
	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
1474
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1475
    }
1476 1477
  }

1478 1479
#endif

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

Raymond Knopp's avatar
 
Raymond Knopp committed
1482 1483
  // cleanup
  if (UE_flag == 1) {
1484
  } else {
1485
    stop_eNB(1);
Raymond Knopp's avatar
 
Raymond Knopp committed
1486
  }
1487

1488

Raymond Knopp's avatar
 
Raymond Knopp committed
1489 1490
  pthread_cond_destroy(&sync_cond);
  pthread_mutex_destroy(&sync_mutex);
1491

1492 1493 1494
  pthread_cond_destroy(&nfapi_sync_cond);
  pthread_mutex_destroy(&nfapi_sync_mutex);

1495

1496
  pthread_mutex_destroy(&ue_pf_po_mutex);
1497

Raymond Knopp's avatar
Raymond Knopp committed
1498
  // *** Handle per CC_id openair0
Raymond Knopp's avatar
Raymond Knopp committed
1499 1500 1501 1502 1503
  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 {
1504 1505 1506 1507 1508
    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);  
1509

Raymond Knopp's avatar
Raymond Knopp committed
1510
    }
1511
  }
Raymond Knopp's avatar
 
Raymond Knopp committed
1512
  if (ouput_vcd)
1513
    VCD_SIGNAL_DUMPER_CLOSE();
1514
  
1515
  if (opt_enabled == 1)
1516
    terminate_opt();
1517
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1518
  logClean();
1519
  
Raymond Knopp's avatar
 
Raymond Knopp committed
1520 1521
  return 0;
}